diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..d1766d515 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.DS_Store +node_modules +artifacts +.*.swp +*~ +.svn diff --git a/DEPRECATIONS.md b/DEPRECATIONS.md new file mode 100644 index 000000000..53d64baae --- /dev/null +++ b/DEPRECATIONS.md @@ -0,0 +1,79 @@ + +As Mojito matures, there are a number of changes/cleanups that we want to make +that break backwards-compatilibity. However, we don't want to prevent you from +upgrading in a timely fashion, so that you can use the latest and greatest +version of mojito. + +To enable both our needs and yours, we need a clear, predictable path into the +future. + + + +Currently Deprecated +==================== + + +### Deprecated but Available + +* (2012-04-23) The `autoload/` directory is going away in favor of +`yui_modules/`, which better reflects its contents. Everthing else about it is +the same, only the name has changed. You can start using `yui_modules/` today. + +* (2012-04-23) The `.guid` member of Mojito metadata (such as binder metadata) +is going away. Often there's an associated member which more specifically +expresses the intent of the unique ID (for example `.viewId` or `.instanceId`). + +* (2012-04-23) `ac.dispatch()` will be going away. (This already emits a +warning.) Currently the best alternative is `ac._dispatch()`. + + +### Deprecated with Warnings +nothing for mojito 0.3 + + +### Removed +nothing for mojito 0.3 + + + +Deprecation Process +=================== +A feature will move through the following phases, at a well-defined pace. + + +### "Deprecated but Available" Phase + +* The documentation is updated to mark the feature as "deprecated". +* The feature will be in this phase until the end of the quarter year. +(It's possible that a feature won't spend much time in this phase, if it is +deprecated near the end of the quarter.) + + +### "Deprecated with Warning" Phase + +* The feature is removed from the documentation. +* Mojito emits a warning (if possible) if the feature is used. +* The feature will spend a full quarter in this phase. + + +### "Removed" Phase + +* The feature (and warning) is removed from Mojito. + + +### Example + +* On 2012-04-19 (Q2), Mojito deprecates the "foo" feature by saying so in the +documentation. This event is also mentioned in an email and/or blog post for +the next release. It's also added to this DEPRECATIONS.md document. + +* On the next release after 2012-06-30 (end of Q2), Mojito removes +documentation for feature "foo" and adds a warning if someone tries to use +feature "foo". It is still documented in this DEPRECATIONS.md document. + +* On the next releaes after 2012-09-30 (end of Q3), Mojito removes feature +"foo" (and the associated warnings). It is mentioned as "removed" in this +DEPRECATIONS.md document. + + + diff --git a/docs/api/ActionContext.html b/docs/api/ActionContext.html new file mode 100644 index 000000000..ab732e9a3 --- /dev/null +++ b/docs/api/ActionContext.html @@ -0,0 +1,661 @@ + + + + + Mojito API: ActionContext + + + + + + + + + + +
+
+

mojito

+

ActionContext  0.3.0

+ mojito + > ActionContext + > ActionContext + +
+
+ Search: +
+   +
+
+
+
+ +
+
+
+
+
+ Filters + + + +
+
+ +

+ + + + + Class ActionContext + + + +

+ + + + + +
+ The main point of entry for all mojits into Mojito. The Action Context is +passed to every mojit action during execution, either on the client or +server. This object is the API into Mojito, can can have many plugins +attached the provide extra functionality. +
+ + +
+ +
+ +
+
+

Methods

+
+
+

+ destroy

+
+ + + + + void + destroy + ( + ) + + +
+ Called by the bean registry whenever this bean is reinitialized +
+ +
+ + +
+
Returns: + + void +
+
+
+ + + + +
+ +
+
+
+
+

+ disable

+
+ + + + + void + disable + ( + + + queue + + + ) + + +
+ Disables all Ajax requests for the application. +
+ +
+ +
+
Parameters:
+
+ queue + <Boolean> + + (Optional) When set to true, queues all requests while disabled. +
+
+ +
+
Returns: + + void +
+
+
+ + + + +
+ +
+
+
+
+

+ dispatch

+
+ + + + + + dispatch + ( + + + command + + + , + adapter + + + ) + + +
+ This dispatch function is called one time per Mojito execution. It creates a +contextualized Y instance for all further internal dispatches to use. It also +creates the ActionContext for the mojit. +The command has three main parts: the "instance", the "context", and the "params". +
+command: {
+instance: ...see below...
+context: ...see below...
+params: ...see below...
+}
+
+The "instance" is a partial instance with details of the mojit instance. +See `ServerStore.expandInstance()` for details of the structure and which fields +are required. +The "context" is the request context. It is built by the "contextualizer" +middleware. +The "params" is a structured set of parameters to pass to the mojit. +
+params: {
+route: {},
+url: {},
+body: {},
+file: {},
+...
+}
+
+
+adapter: {
+flush: function(data, meta){},
+done: function(data, meta){},
+error: function(err){}
+}
+
+
+ +
+ +
+
Parameters:
+
+ command + <map> + + the "command" describing how to dispatch the mojit. see above +
+
+ adapter + <object> + + the output adapter to pass to the mojit. see above +
+
+ + + + + +
+ +
+
+
+
+

+ done

+
+ + + + + void + done + ( + + + data + + + , + meta + + + ) + + +
+ Returns data and closes the request. +
+ +
+ +
+
Parameters:
+
+ data + <object|string> + + The data you want return by the request +
+
+ meta + <object> + + Any meta-data required to service the request +
+
+ +
+
Returns: + + void +
+
+
+ + + + +
+ +
+
+
+
+

+ enable

+
+ + + static + + void + enable + ( + ) + + +
+ Enables sending of requests. +
+ +
+ + +
+
Returns: + + void +
+
+
+ + + + +
+ +
+
+
+
+

+ error

+
+ + + + + void + error + ( + + + err + + + ) + + +
+ Programatically report an error to Mojito, which will handle it gracefully. +
+ +
+ +
+
Parameters:
+
+ err + <Error> + + A normal JavaScript Error object is expected, but you may add a "code" property to the error +if you want the framework to report a certain HTTP status code for the error. For example, if the status code +is 404, Mojito will generate a 404 page. +
+
+ +
+
Returns: + + void +
+
+
+ + + + +
+ +
+
+
+
+

+ flush

+
+ + + + + void + flush + ( + + + data + + + , + meta + + + ) + + +
+ Returns data in the request and allows you to carry on execution. +
+ +
+ +
+
Parameters:
+
+ data + <object|string> + + The data you want return by the request +
+
+ meta + <object> + + Any meta-data required to service the request +
+
+ +
+
Returns: + + void +
+
+
+ + + + +
+ +
+
+
+
+

+ setRequestFormatter

+
+ + + + + void + setRequestFormatter + ( + + + requestType + + + , + formatter + + + ) + + +
+ Sets the request formatter function for a given request type. +
+ +
+ +
+
Parameters:
+
+ requestType + <String> + + The type of request that the formatter should handle. +
+
+ formatter + <Function> + + The function to call to format the request. +
+
+ +
+
Returns: + + void +
+
+
+ + + + +
+ +
+
+
+
+

+ setResponseFormatter

+
+ + + + + void + setResponseFormatter + ( + + + formatter + + + ) + + +
+ Sets the response formatter function for all responses. +
+ +
+ +
+
Parameters:
+
+ formatter + <Function> + + The function to call to format the response object. +
+
+ +
+
Returns: + + void +
+
+
+ + + + +
+ +
+
+
+
+
+ +
+ +
+ + +
+ +
+ +
+ +
+
+
+ +
+
+
+
+ Copyright © 2012 Yahoo! Inc. All rights reserved. +
+
+ + + diff --git a/docs/api/Analytics.common.html b/docs/api/Analytics.common.html index 6309c90d3..41192dac0 100644 --- a/docs/api/Analytics.common.html +++ b/docs/api/Analytics.common.html @@ -2,21 +2,21 @@ - API: ActionContextAddon Analytics.common (YUI Library) + Mojito API: ActionContextAddon Analytics.common ( - - + + - - + +
-

mojito

-

ActionContextAddon  0.1.0

+

mojito

+

ActionContextAddon  0.3.0

mojito > ActionContextAddon > Analytics.common @@ -101,8 +101,9 @@

To retrieve analytics data that has been stored by child mojits, call -this function and provide a function, which will be called once the children -have been dispatched and all their analytics data has been merged. +this function and provide a function, which will be called once the +children have been dispatched and all their analytics data has been +merged.
@@ -113,13 +114,13 @@

cb <function> - callback will be called with the analytics object + callback invoked with the analytics object.
[optional] <object> - scope scope of the callback + scope scope of the callback.
@@ -160,9 +161,10 @@

Allows a way for addons mixed in after this one to set an alternate -data merge function when analytics from multiple children are combined. -The default merge function is the same one used internally by Mojito -to merge meta data, and will be sufficient for most use cases. +data merge function when analytics from multiple children are +combined. The default merge function is the same one used internally +by Mojito to merge meta data, and will be sufficient for most use +cases.
@@ -174,8 +176,8 @@

<function> user-defined merge function, which should accept -two objects, the first is "to", and the second is "from". this function -should return the merged object. +two objects, the first is "to", and the second is "from". this +function should return the merged object. @@ -227,7 +229,7 @@

val <object> - should be an object bag full of whatever you wish + An object bag full of whatever you wish. @@ -283,10 +285,19 @@

Classes

  • Analytics.common
  • Assets.common
  • Carrier.common
  • +
  • Composite.common
  • +
  • Config.common
  • +
  • Cookie.client
  • +
  • Cookie.server
  • Deploy.server
  • Device.common
  • +
  • Http.server
  • I13n.server
  • +
  • Intl.common
  • Meta.common
  • +
  • Params.common
  • +
  • Partial.common
  • +
  • Url.common
  • @@ -294,14 +305,25 @@

    Classes

    --> diff --git a/docs/api/Assets.common.html b/docs/api/Assets.common.html index 174e11e4c..5edc57000 100644 --- a/docs/api/Assets.common.html +++ b/docs/api/Assets.common.html @@ -2,21 +2,21 @@ - API: ActionContextAddon Assets.common (YUI Library) + Mojito API: ActionContextAddon Assets.common ( - - + + - - + +
    -

    mojito

    -

    ActionContextAddon  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito > ActionContextAddon > Assets.common @@ -72,6 +72,80 @@

    Methods

    +
    +

    + addAsset

    +
    + + + + + void + addAsset + ( + ) + + +
    + +
    + +
    + + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + addAssets

    +
    + + + + + void + addAssets + ( + ) + + +
    + +
    + +
    + + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +

    addBlob

    @@ -108,13 +182,13 @@

    content <string> - A string of data + A string of data.
    location <string> - Either "top" or "bottom" + Either "top" or "bottom".
    @@ -169,13 +243,14 @@

    link <string> - A URL (./local.css converts to /static/mojit_type/assets/local.css) + A URL (./local.css converts to +/static/mojit_type/assets/local.css).
    location <string> - Either "top" or "bottom" + Either "top" or "bottom".
    @@ -230,13 +305,14 @@

    link <string> - A URL (./local.css converts to /static/mojit_type/assets/local.css) + A URL (./local.css converts to +/static/mojit_type/assets/local.css).
    location <string> - Either "top" or "bottom" + Either "top" or "bottom".
    @@ -251,6 +327,228 @@

    +

    + +
    +
    +
    +
    +

    + getAssets

    +
    + + + + + void + getAssets + ( + ) + + +
    + +
    + +
    + + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getUrl

    +
    + + + + + void + getUrl + ( + ) + + +
    + +
    + +
    + + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + mergeMetaInto

    +
    + + + + + void + mergeMetaInto + ( + ) + + +
    + +
    + +
    + + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + mixAssets

    +
    + + + + + void + mixAssets + ( + ) + + +
    + +
    + +
    + + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + preLoadImage

    +
    + + + + + void + preLoadImage + ( + ) + + +
    + +
    + +
    + + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + preLoadImages

    +
    + + + + + void + preLoadImages + ( + ) + + +
    + +
    + +
    + + +
    +
    Returns: + + void +
    +
    +
    + + + +
    @@ -292,10 +590,19 @@

    Classes

  • Analytics.common
  • Assets.common
  • Carrier.common
  • +
  • Composite.common
  • +
  • Config.common
  • +
  • Cookie.client
  • +
  • Cookie.server
  • Deploy.server
  • Device.common
  • +
  • Http.server
  • I13n.server
  • +
  • Intl.common
  • Meta.common
  • +
  • Params.common
  • +
  • Partial.common
  • +
  • Url.common
  • @@ -303,14 +610,25 @@

    Classes

    --> @@ -319,9 +637,17 @@

    Files

    @@ -336,7 +662,7 @@

    Methods

    diff --git a/docs/api/Carrier.common.html b/docs/api/Carrier.common.html index 5c56c748f..71e1ce94a 100644 --- a/docs/api/Carrier.common.html +++ b/docs/api/Carrier.common.html @@ -2,21 +2,21 @@ - API: ActionContextAddon Carrier.common (YUI Library) + Mojito API: ActionContextAddon Carrier.common ( - - + + - - + +
    -

    mojito

    -

    ActionContextAddon  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito > ActionContextAddon > Carrier.common @@ -80,7 +80,7 @@

    - void + object get ( @@ -102,18 +102,19 @@

    Parameters:
    attribute - <String> + <string> - - The name of the catalog attribute e.g "ticker". + The name of the catalog attribute e.g +"ticker".
    Returns: - void + object
    -
    +
    The catalog attribute value.
    @@ -160,10 +161,19 @@

    Classes

  • Analytics.common
  • Assets.common
  • Carrier.common
  • +
  • Composite.common
  • +
  • Config.common
  • +
  • Cookie.client
  • +
  • Cookie.server
  • Deploy.server
  • Device.common
  • +
  • Http.server
  • I13n.server
  • +
  • Intl.common
  • Meta.common
  • +
  • Params.common
  • +
  • Partial.common
  • +
  • Url.common
  • @@ -171,14 +181,25 @@

    Classes

    --> @@ -202,7 +223,7 @@

    Methods

    diff --git a/docs/api/Composite.common.html b/docs/api/Composite.common.html index 772c03fd7..162f7c273 100644 --- a/docs/api/Composite.common.html +++ b/docs/api/Composite.common.html @@ -2,23 +2,23 @@ - API: MojitoServer Composite.common (YUI Library) + Mojito API: ActionContextAddon Composite.common ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > Composite.common
    @@ -92,8 +92,10 @@

    - Automatically dispatches all the children of this mojit and collects their executed values into the view -template, keyed by the child's name within the mojit's configuration. For example, given the mojit spec: + Automatically dispatches all the children of this mojit and collects +their executed values into the view template, keyed by the child's +name within the mojit's configuration. For example, given the mojit +spec:
     "specs": {
     "parent": {
    @@ -113,7 +115,7 @@ 

    And given the view template:
    -<div id="{{mojit_uuid}}">
    +<div id="{{mojit_view_id}}">
     <h1>{{title}}</h1>
     <div class="fooslot">
     {{{foo}}}
    @@ -133,8 +135,9 @@ 

    } };

    -This will execute the child intances of the "FooMojit" and "BarMojit", returning their rendered values into -the parent's view template, thus rendering the full parent view including the children. +This will execute the child intances of the "FooMojit" and +"BarMojit", returning their rendered values into the parent's view +template, thus rendering the full parent view including the children. All the parent parameters are passed along to children.
    @@ -146,7 +149,8 @@

    opts <object> - The configuration object to be used. template can be used to provide additional + The configuration object to be used. +template can be used to provide additional view template values. @@ -236,13 +240,13 @@

    cfg <object> - The configuration object to be used + The configuration object to be used.
    cb <function> - The callback that will be called + The callback that will be called.
    @@ -285,23 +289,29 @@

    Modules

    diff --git a/docs/api/Config.common.html b/docs/api/Config.common.html index 8e60326d0..f076c0646 100644 --- a/docs/api/Config.common.html +++ b/docs/api/Config.common.html @@ -2,23 +2,23 @@ - API: MojitoServer Config.common (YUI Library) + Mojito API: ActionContextAddon Config.common ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > Config.common @@ -107,13 +107,15 @@

    key <String> - A period separated key path to look for i.e. "get.my.value" + A period separated key path to look for i.e. +"get.my.value".
    def <Object|Array|String> - The default value to use if no match was found + The default value to use if no match +was found.
    @@ -122,7 +124,7 @@

    Object|Array|String -
    +
    The requested configuration value.
    @@ -168,13 +170,15 @@

    key <String> - A period separated key path to look for i.e. "get.my.value" + A period separated key path to look for i.e. +"get.my.value".
    def <Object|Array|String> - The default value to use if no match was found + The default value to use if no match +was found.
    @@ -183,7 +187,7 @@

    Object|Array|String -
    +
    The requested definition values.
    @@ -217,23 +221,29 @@

    Modules

    diff --git a/docs/api/Cookie.client.html b/docs/api/Cookie.client.html index 57a936d6b..1d21ba607 100644 --- a/docs/api/Cookie.client.html +++ b/docs/api/Cookie.client.html @@ -2,23 +2,23 @@ - API: MojitoServer Cookie.client (YUI Library) + Mojito API: ActionContextAddon Cookie.client ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > Cookie.client @@ -60,8 +60,9 @@

    Access point: ac.cookie.* -This client-side cookie add-on allows you to easily use cookies. This API matches the YUI Cookie API exactly. -http://developer.yahoo.com/yui/3/api/Cookie.html +This client-side cookie add-on allows you to easily use cookies. This API +matches the YUI Cookie API exactly. +http://developer.yahoo.com/cocktails/mojito/3/api/Cookie.html
    @@ -91,23 +92,29 @@

    Modules

    diff --git a/docs/api/Cookie.server.html b/docs/api/Cookie.server.html index bcb6c84ef..4c045c1e2 100644 --- a/docs/api/Cookie.server.html +++ b/docs/api/Cookie.server.html @@ -2,23 +2,23 @@ - API: MojitoServer Cookie.server (YUI Library) + Mojito API: ActionContextAddon Cookie.server ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > Cookie.server @@ -80,7 +80,7 @@

    - void + String|Object get ( @@ -92,7 +92,8 @@

    - Returns the cookie for the given key, or all cookies if the key is not specified + Returns the cookie for the given key, or all cookies if the key is +not specified.
    @@ -103,16 +104,18 @@

    [optional] <string> - key The key to look for + key The key to look for.
    -
    Returns: - - void -
    -
    + Returns: +
    + String +
    +
    The value of the cookie for the given key.
    +
    Object
    +
    Contains the key-value pairs for all of the cookies.
    @@ -158,13 +161,13 @@

    key <string> - The key to use + The key to use.
    val <string> - The value that will be set + The value that will be set.
    @@ -207,23 +210,29 @@

    Modules

    diff --git a/docs/api/Deploy.server.html b/docs/api/Deploy.server.html index 90313b093..7319b1fd7 100644 --- a/docs/api/Deploy.server.html +++ b/docs/api/Deploy.server.html @@ -2,21 +2,21 @@ - API: ActionContextAddon Deploy.server (YUI Library) + Mojito API: ActionContextAddon Deploy.server ( - - + + - - + +
    -

    mojito

    -

    ActionContextAddon  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito > ActionContextAddon > Deploy.server @@ -107,13 +107,15 @@

    assetHandler <AssetHandler> - asset handler used to add scripts to the DOM under construction + asset handler used to add scripts +to the DOM under construction.
    binderMap <object> - information about the binders that will be deployed to the client + information about the binders that will be +deployed to the client.
    @@ -169,10 +171,19 @@

    Classes

  • Analytics.common
  • Assets.common
  • Carrier.common
  • +
  • Composite.common
  • +
  • Config.common
  • +
  • Cookie.client
  • +
  • Cookie.server
  • Deploy.server
  • Device.common
  • +
  • Http.server
  • I13n.server
  • +
  • Intl.common
  • Meta.common
  • +
  • Params.common
  • +
  • Partial.common
  • +
  • Url.common
  • @@ -180,14 +191,25 @@

    Classes

    --> @@ -211,7 +233,7 @@

    Methods

    diff --git a/docs/api/Device.common.html b/docs/api/Device.common.html index 46d597a63..4a5d0d3de 100644 --- a/docs/api/Device.common.html +++ b/docs/api/Device.common.html @@ -2,21 +2,21 @@ - API: ActionContextAddon Device.common (YUI Library) + Mojito API: ActionContextAddon Device.common ( - - + + - - + +
    -

    mojito

    -

    ActionContextAddon  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito > ActionContextAddon > Device.common @@ -80,7 +80,7 @@

    - void + object get ( @@ -102,18 +102,19 @@

    Parameters:
    attribute - <String> + <string> - - The name of the catalog attribute e.g "make" or "model". + The name of the catalog attribute e.g +"make" or "model".
    Returns: - void + object
    -
    +
    The value of the named attribute.
    @@ -160,10 +161,19 @@

    Classes

  • Analytics.common
  • Assets.common
  • Carrier.common
  • +
  • Composite.common
  • +
  • Config.common
  • +
  • Cookie.client
  • +
  • Cookie.server
  • Deploy.server
  • Device.common
  • +
  • Http.server
  • I13n.server
  • +
  • Intl.common
  • Meta.common
  • +
  • Params.common
  • +
  • Partial.common
  • +
  • Url.common
  • @@ -171,14 +181,25 @@

    Classes

    --> @@ -202,7 +223,7 @@

    Methods

    diff --git a/docs/api/Http.server.html b/docs/api/Http.server.html index c0566e6ca..e6e531e21 100644 --- a/docs/api/Http.server.html +++ b/docs/api/Http.server.html @@ -2,23 +2,23 @@ - API: MojitoServer Http.server (YUI Library) + Mojito API: ActionContextAddon Http.server ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > Http.server @@ -108,13 +108,13 @@

    key <String> - header name + header name.
    val <String> - header value + header value.
    @@ -165,7 +165,7 @@

    hdrs <object> - header values to add + header values to add. @@ -216,7 +216,7 @@

    name <string> - header name + header name. @@ -225,7 +225,7 @@

    object -
    header value
    +
    header value.
    @@ -262,7 +262,7 @@

    object -
    all headers
    +
    all headers.
    @@ -299,7 +299,7 @@

    ServerRequest -
    http://nodejs.org/docs/v0.4.7/api/http.html#http.ServerRequest
    +
    The node.js http.ServerRequest instance.
    @@ -325,7 +325,7 @@

    - + Returns the HTTP response object from the request.
    @@ -336,7 +336,7 @@

    ServerResponse -
    http://nodejs.org/docs/v0.4.7/api/http.html#http.ServerResponse
    +
    The node.js http.ServerResponse instance.
    @@ -374,7 +374,8 @@

    boolean -
    +
    True if the receiver is associated with an XHR +request.
    @@ -421,13 +422,13 @@

    uri <string> - + the URI to redirect to.
    code <Number> - [optional] if not specifed, 301 + [optional] if not specifed, 301.
    @@ -482,13 +483,13 @@

    key <string> - header name + header name.
    val <string> - header value + header value.
    @@ -539,7 +540,7 @@

    hdrs <object> - header values to set + header values to set. @@ -582,23 +583,29 @@

    Modules

    diff --git a/docs/api/I13n.server.html b/docs/api/I13n.server.html index 09da44e88..814d44c7d 100644 --- a/docs/api/I13n.server.html +++ b/docs/api/I13n.server.html @@ -2,21 +2,21 @@ - API: ActionContextAddon I13n.server (YUI Library) + Mojito API: ActionContextAddon I13n.server ( - - + + - - + +
    -

    mojito

    -

    ActionContextAddon  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito > ActionContextAddon > I13n.server @@ -80,19 +80,27 @@

    - + object getSpaceid ( )
    - Retrurn spaceid used for this request. + Return spaceid used for this request.
    +
    +
    Returns: + + object +
    +
    the spaceid previously set through stampPageView() +or configuration.
    +
    @@ -115,7 +123,7 @@

    ( - id + base , @@ -151,40 +159,43 @@

    Parameters:
    - id + base <string> - it to a mojit defined at the root level of the Mojito application configuration + Reference to a mojit defined at the root +level of the Mojito application configuration.
    action <string> - + The action to associate with the base.
    routeParams <object> - used to lookup the route in the routing table + used to lookup the route in the routing +table.
    verb <string> - GET, POST, PUT, DELETE (case insensitive) + GET, POST, PUT, DELETE (case insensitive).
    urlParams <object> - added to the looked up route as query params + added to the looked up route as query +params.
    i13nParams <object> - parameters to be used for link tracking. + parameters to be used for link tracking.
    @@ -235,7 +246,7 @@

    spaceid <number> - The spaceid to be used. + The spaceid to be used. @@ -283,8 +294,8 @@

    - Instrument links for tracking of the link clicks by gemerating the URL -with the hash token appended to it. + Instrument links for tracking of the link clicks by gemerating the +URL with the hash token appended to it.
    @@ -295,19 +306,19 @@

    url <string> - - The link to be instrumented. + The link to be instrumented.
    link_params <object> - - parameteres + The link parameters.
    ult_args <object> - - Optional + Optional.
    @@ -370,25 +381,25 @@

    is_post_method <boolean> - - true, if the method is POST + True, if the method is POST.
    action_url <string> - - the form action link to be instrumented. + The form action link to be instrumented.
    link_params <object> - - Tracking parameters. + Tracking parameters.
    ult_args <object> - - Optional + Optional.
    @@ -440,8 +451,8 @@

    - Tracks the link view and gemerates the URL -with the hash token appended to it. + Tracks the link view and generates the URL with the hash token +appended to it.
    @@ -452,25 +463,25 @@

    url <string> - - The link to be instrumented. + The link to be instrumented.
    link_params <object> - - parameteres + The link parameters.
    local_groups <object> - - Optional + - Optional.
    ult_args <object> - - Optional + - Optional.
    @@ -507,7 +518,7 @@

    , - vlaue + value ) @@ -525,13 +536,13 @@

    key <string> - - The page parameter name + The page parameter name.
    - vlaue + value <string> - -The page parameter value + The page parameter value.
    @@ -583,8 +594,9 @@

    - Tracks the link view for the links taken from the user generated content -and hence need to be signed by B-cookie to prevent the security problems. + Tracks the link view for the links taken from the user generated +content and hence need to be signed by B-cookie to prevent the +security problems.
    @@ -595,25 +607,25 @@

    url <string> - - The link to be instrumented. + The link to be instrumented.
    link_params <object> - - parameteres + The link parameters.
    local_groups <object> - - Optional + Optional.
    ult_args <object> - - Optional + Optional.
    @@ -669,10 +681,19 @@

    Classes

  • Analytics.common
  • Assets.common
  • Carrier.common
  • +
  • Composite.common
  • +
  • Config.common
  • +
  • Cookie.client
  • +
  • Cookie.server
  • Deploy.server
  • Device.common
  • +
  • Http.server
  • I13n.server
  • +
  • Intl.common
  • Meta.common
  • +
  • Params.common
  • +
  • Partial.common
  • +
  • Url.common
  • @@ -680,14 +701,25 @@

    Classes

    --> @@ -718,7 +750,7 @@

    Methods

    diff --git a/docs/api/Intl.common.html b/docs/api/Intl.common.html index 6a3d34112..0b92de5f6 100644 --- a/docs/api/Intl.common.html +++ b/docs/api/Intl.common.html @@ -2,23 +2,23 @@ - API: MojitoServer Intl.common (YUI Library) + Mojito API: ActionContextAddon Intl.common ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > Intl.common @@ -92,7 +92,7 @@

    - returns local-specified date + Returns local-specified date.
    @@ -103,7 +103,7 @@

    date <Date> - + The initial date to be formatted. @@ -112,7 +112,7 @@

    string -
    formated data for language
    +
    formatted data for language.
    @@ -139,11 +139,15 @@

    label + , + args + + )
    - Returns translated string + Returns translated string.
    @@ -154,7 +158,13 @@

    label <string> - + The initial label to be translated. + +
    + args + <string|Array|Object> + + optional parameters for the string
    @@ -163,7 +173,7 @@

    string -
    translated string for label
    +
    translated string for label.
    @@ -197,23 +207,29 @@

    Modules

    diff --git a/docs/api/Meta.common.html b/docs/api/Meta.common.html index 5f6a73c5a..a37eff612 100644 --- a/docs/api/Meta.common.html +++ b/docs/api/Meta.common.html @@ -2,21 +2,21 @@ - API: ActionContextAddon Meta.common (YUI Library) + Mojito API: ActionContextAddon Meta.common ( - - + + - - + +
    -

    mojito

    -

    ActionContextAddon  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito > ActionContextAddon > Meta.common @@ -60,8 +60,8 @@

    Access point: ac.meta.* -Allows the usage of the "meta" object as a storage device, which can pass data from -child mojits up towards parents. +Allows the usage of the "meta" object as a storage device, which can pass +data from child mojits up towards parents.
    @@ -98,8 +98,9 @@

    To retrieve stashed data that has been stored by child mojits, call -this function and provide a function, which will be called once the children -have been dispatched and all their meta data has been merged. +this function and provide a function, which will be called once the +children have been dispatched and all their meta data has been +merged.
    @@ -110,13 +111,14 @@

    cb <function> - callback will be called with the stored merged object + callback will be called with the stored merged +object.
    [optional] <object> - scope scope of the callback + scope scope of the callback.
    @@ -162,9 +164,9 @@

    Stores a keyed value within the meta object of the current mojit execution. You can call this as many times as you like, but -if you use the same key, you'll override previous data. Call this within -child mojits when you have some data you want to make available for -some reason to any parents up your hierarchy. +if you use the same key, you'll override previous data. Call this +within child mojits when you have some data you want to make +available for some reason to any parents up your hierarchy.
    @@ -175,13 +177,13 @@

    key <string> - + The key used as the index value.
    val <object> - + The value to store.
    @@ -237,10 +239,19 @@

    Classes

  • Analytics.common
  • Assets.common
  • Carrier.common
  • +
  • Composite.common
  • +
  • Config.common
  • +
  • Cookie.client
  • +
  • Cookie.server
  • Deploy.server
  • Device.common
  • +
  • Http.server
  • I13n.server
  • +
  • Intl.common
  • Meta.common
  • +
  • Params.common
  • +
  • Partial.common
  • +
  • Url.common
  • @@ -248,14 +259,25 @@

    Classes

    --> @@ -280,7 +302,7 @@

    Methods

    diff --git a/docs/api/MojitProxy.html b/docs/api/MojitProxy.html new file mode 100644 index 000000000..f89dff669 --- /dev/null +++ b/docs/api/MojitProxy.html @@ -0,0 +1,906 @@ + + + + + Mojito API: MojitoClient MojitProxy ( + + + + + + + + + + +
    +
    +

    mojito

    +

    MojitoClient  0.3.0

    + mojito + > MojitoClient + > MojitProxy + + +
    + Search: +
    +   +
    +
    + +
    + +
    +
    +
    +
    +
    + Filters + + + +
    +
    + +

    + + + + + Class MojitProxy + + + +

    + + + + + +
    + The object that is given to each mojit binder to be used to interact with +other mojits and the mojito framework. +
    + + +
    +
    +

    Properties

    +
    +
    +

    _mojito + - {Object} +

    +
    +
    + The top-level Mojito namespace. +
    +
    + + + + +
    +
    +
    +

    config + - {object} +

    +
    +
    + The mojit configuration for this binder +
    +
    + + + + +
    +
    +
    +

    context + - {object} +

    +
    +
    + The context used to generate this page +
    +
    + + + + +
    +
    +
    +

    type + - {string} +

    +
    +
    + The mojit type +
    +
    + + + + +
    +
    +
    +
    + +
    + +
    +
    +

    Methods

    +
    +
    +

    + broadcast

    +
    + + + + + void + broadcast + ( + + + name + + + , + payload + + + , + options + + + ) + + +
    + Used by mojit binders to broadcast a message between mojits. +
    + +
    + +
    +
    Parameters:
    +
    + name + <String> + + event name. +
    +
    + payload + <Object> + + the payload for the event. +
    +
    + options + <Object> currently only used to specify target for +broadcast. For example, to target only one child mojit for +broadcast, use: +{target: {slot: 'slot name', viewId: 'DOM view id'}> + + +
    +
    + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + destroyChild

    +
    + + + + + void + destroyChild + ( + + + id + + + , + retainNode + + + ) + + +
    + Clears out a child's view, calling the appropriate life cycle +functions, then destroy's its binder and dereferences it. Will also +dereference the child from this mojit's children. +
    + +
    + +
    +
    Parameters:
    +
    + id + <string> + + Either the slot key of the child, or the DOM +view id of the child. +
    +
    + retainNode + <boolean> + + if true, the binder's node will remain in +the dom. +
    +
    + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + destroyChildren

    +
    + + + + + void + destroyChildren + ( + + + retainNode + + + ) + + +
    + Destroys all children. (Calls destroyChild() for each child.) +
    + +
    + +
    +
    Parameters:
    +
    + retainNode + <boolean> + + if true, the binder's node will remain in +the dom. +
    +
    + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + destroySelf

    +
    + + + + + void + destroySelf + ( + + + retainNode + + + ) + + +
    + Allows a binder to destroy itself and be removed from Mojito client +runtime entirely. +
    + +
    + +
    +
    Parameters:
    +
    + retainNode + <boolean> + + if true, the binder's node will remain in +the dom. +
    +
    + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getChildren

    +
    + + + + + object + getChildren + ( + ) + + +
    + Helper function to gather up details about a mojit's children from +the Mojito Client. +
    + +
    + + +
    +
    Returns: + + object +
    +
    slot <String&rt; --> child information <Object&rt;
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getFromUrl

    +
    + + + + + string|object + getFromUrl + ( + + + key + + + ) + + +
    + Gets URL parameters +
    + +
    + +
    +
    Parameters:
    +
    + key + <string> + + The name of the parameter required. +
    +
    + +
    +
    Returns: + + string|object +
    +
    param value, or all params if no key +specified.
    +
    + + + + +
    + +
    +
    +
    +
    +

    + invoke

    +
    + + + + + void + invoke + ( + + + action + + + , + options + + + , + cb + + + ) + + +
    + Used by the mojit binders to invoke actions on themselves within +Mojito. +The options parameter is optional and may contain: +
    +
    params
    <object> must be broken out explicitly: +
    +
    route
    <object> Map of key/value pairs.
    +
    url
    <object> Map of key/value pairs.
    +
    body
    <object> Map of key/value pairs.
    +
    file
    <object> Map of key/value pairs.
    +
    +
    rpc
    <boolean> Means that we are immediately +sending the request to the server to answer the invocation.
    +
    +
    + +
    + +
    +
    Parameters:
    +
    + action + <string> + + name of the action to invoke. +
    +
    + options + <Object> + + see above. +
    +
    + cb + <function> + + function to be called on completion. +
    +
    + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + listen

    +
    + + + + + void + listen + ( + + + name + + + , + callback + + + ) + + +
    + Allows mojit binders to register to listen to other mojit events +
    + +
    + +
    +
    Parameters:
    +
    + name + <String> + + event name. +
    +
    + callback + <Function> + + called when an event is broadcast with +the event data. +
    +
    + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + refreshView

    +
    + + + + + void + refreshView + ( + + + opts + + + , + cb + + + ) + + +
    + Refreshes the current DOM view for this binder without recreating the +binder instance. Will call the binder's onRefreshView() function when +complete with the new Y.Node and HTMLElement objects. +
    + +
    + +
    +
    Parameters:
    +
    + opts + <object> + + same as the options for invoke(). +
    +
    + cb + <function> + + Called after replacement and onRefreshView have +been called, sends data/meta. +
    +
    + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + render

    +
    + + + + + void + render + ( + + + data + + + , + view + + + , + cb + + + ) + + +
    + This method renders the "data" provided into the "View" specified. +The "view" must be the name of one of the files in the current +Mojits "views" folder. Returns via the callback. +
    + +
    + +
    +
    Parameters:
    +
    + data + <object> + + The data to render. +
    +
    + view + <string> + + The view name to use for rendering. +
    +
    + cb + <function(err,str)> + + The callback function. +
    +
    + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + unlisten

    +
    + + + + + void + unlisten + ( + + + [optional] + + + ) + + +
    + The opposite of the "listen" function. Deletes all callback functions +from the listener queue associated with this binder and event type. +If event name is not specified, all callbacks associated with this +binder are deleted. +
    + +
    + +
    +
    Parameters:
    +
    + [optional] + <String> + + name event name. +
    +
    + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +
    + +
    + +
    + + +
    + +
    + +
    + +
    +
    +
    + +
    +
    +
    +
    + Copyright © 2012 Yahoo! Inc. All rights reserved. +
    +
    + + + diff --git a/docs/api/MojitoServer.html b/docs/api/MojitoServer.html index 129b37188..865127fd4 100644 --- a/docs/api/MojitoServer.html +++ b/docs/api/MojitoServer.html @@ -2,21 +2,21 @@ - API: MojitoServer MojitoServer (YUI Library) + Mojito API: MojitoServer MojitoServer ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    MojitoServer  0.3.0

    mojito > MojitoServer > MojitoServer @@ -80,6 +80,56 @@

    Constructor

    +
    +

    Properties

    +
    +
    +

    _mojito + - object +

    +
    +
    + +
    +
    + + + + +
    +
    +
    +

    constructor + - object +

    +
    +
    + +
    +
    + + + + +
    +
    +
    +

    exports + - object +

    +
    +
    + +
    +
    + + + + +
    +
    +
    +
    @@ -124,15 +174,15 @@

    Parameters:
    app - <object> + <Object> - Express application + Express application.
    options - <object> + <Object> - The directory to start the application in + The directory to start the application in.
    @@ -160,7 +210,7 @@

    - object + Object createServer ( @@ -181,18 +231,69 @@

    Parameters:
    options - <object> + <Object> + + Options for starting the app. +
    + + +
    +
    Returns: + + Object +
    +
    Express application.
    +
    + + + + +

    + +
    +
    +

    +
    +

    + include

    +
    + + + + + void + include + ( + + + path + + + ) + + +
    + Surfaces the CLI. +
    + + --> +
    +

    Properties

    + +
    @@ -299,7 +386,7 @@

    Methods

    diff --git a/docs/api/OutputHandler.html b/docs/api/OutputHandler.html new file mode 100644 index 000000000..af4ba3338 --- /dev/null +++ b/docs/api/OutputHandler.html @@ -0,0 +1,216 @@ + + + + + Mojito API: MojitoServer OutputHandler ( + + + + + + + + + + +
    +
    +

    mojito

    +

    MojitoServer  0.3.0

    + mojito + > MojitoServer + > OutputHandler + +
    +
    + Search: +
    +   +
    +
    +
    +
    + +
    +
    +
    +
    +
    + Filters + + + +
    +
    + +

    + + + + + Class OutputHandler + + + +

    + + + + + +
    + This is an object used as the single pathway for data to leave a mojit +action execution. It is used as a component of the ActionContext object, +which uses it to call done and flush in order to complete. +There are two versions of this object, one for the client, and one for the +server. This is the server version, which is more complex than the client +version. +
    + +
    +

    Constructor

    +
    +
    + OutputHandler + + ( + + + + req + + , + res + + , + next + ) + +
    +
    +
    Parameters:
    +
    + req + <Object> + + The Request object. +
    +
    + res + <Object> + + The Response object. +
    +
    + next + <Function> + + The next function, which should be invokable. +
    +
    + + +
    +
    +
    +
    + +
    +
    +

    Properties

    +
    +
    +

    exports + - object +

    +
    +
    + +
    +
    + + + + +
    +
    +
    +
    + +
    + +
    + +
    + +
    + + +
    + +
    + +
    + +
    +
    +
    + +
    +
    +
    +
    + Copyright © 2012 Yahoo! Inc. All rights reserved. +
    +
    + + + diff --git a/docs/api/Params.common.html b/docs/api/Params.common.html index e1b2c9a9d..3a3bf714d 100644 --- a/docs/api/Params.common.html +++ b/docs/api/Params.common.html @@ -2,23 +2,23 @@ - API: MojitoServer Params.common (YUI Library) + Mojito API: ActionContextAddon Params.common ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > Params.common
    @@ -98,7 +98,7 @@

    object -
    all params
    +
    all params.
    @@ -140,7 +140,7 @@

    key <string> - The name of the parameter required + The name of the parameter required. @@ -149,7 +149,8 @@

    string|object -
    param value, or all params if no key specified
    +
    param value, or all params if no key +specified.
    @@ -191,7 +192,7 @@

    key <string> - The name of the parameter required + The name of the parameter required. @@ -200,7 +201,8 @@

    string|object -
    param value, or all params if no key specified
    +
    param value, or all params if no key +specified.
    @@ -237,7 +239,7 @@

    object -
    all params
    +
    all params.
    @@ -279,7 +281,7 @@

    key <string> - The name of the parameter required + The name of the parameter required. @@ -288,7 +290,8 @@

    string|object -
    param value, or all params if no key specified
    +
    param value, or all params if no key +specified.
    @@ -319,7 +322,8 @@

    - Gets all params merged into one object. Route -> URL -> Body precedence. + Gets all params merged into one object. Route -> URL -> Body +precedence.
    @@ -330,7 +334,7 @@

    key <string> - The name of the parameter required + The name of the parameter required. @@ -339,7 +343,8 @@

    string|object -
    param value, or all params if no key specified
    +
    param value, or all params if no key +specified.
    @@ -381,7 +386,7 @@

    key <string> - The name of the parameter + The name of the parameter. @@ -390,7 +395,8 @@

    string|object -
    param value, or all params if no key specified
    +
    param value, or all params if no key +specified.
    @@ -432,7 +438,7 @@

    key <string> - The name of the parameter required + The name of the parameter required. @@ -441,7 +447,8 @@

    string|object -
    param value, or all params if no key specified
    +
    param value, or all params if no key +specified.
    @@ -483,7 +490,7 @@

    key <string> - The name of the parameter required + The name of the parameter required. @@ -492,7 +499,8 @@

    string|object -
    param value, or all params if no key specified
    +
    param value, or all params if no key +specified.
    @@ -534,7 +542,7 @@

    key <string> - The name of the parameter required + The name of the parameter required. @@ -543,7 +551,8 @@

    string|object -
    param value, or all params if no key specified
    +
    param value, or all params if no key +specified.
    @@ -585,7 +594,7 @@

    key <string> - The name of the parameter required + The name of the parameter required. @@ -594,7 +603,8 @@

    string|object -
    param value, or all params if no key specified
    +
    param value, or all params if no key +specified.
    @@ -628,23 +638,29 @@

    Modules

    diff --git a/docs/api/Partial.common.html b/docs/api/Partial.common.html index 22e360caa..3d39fb041 100644 --- a/docs/api/Partial.common.html +++ b/docs/api/Partial.common.html @@ -2,23 +2,23 @@ - API: MojitoServer Partial.common (YUI Library) + Mojito API: ActionContextAddon Partial.common ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > Partial.common @@ -60,7 +60,8 @@

    Access point: ac.partial.* -Provides methods for working with "actions" and "views" on the current Mojits. +Provides methods for working with "actions" and "views" on the current +Mojits.
    @@ -122,19 +123,19 @@

    action <string> - name of the action to invoke + name of the action to invoke.
    options <object> - see above + see above.
    cb <function> - callback function to be called on completion + callback function to be called on completion.
    @@ -195,19 +196,19 @@

    data <object> - + The object to be rendered.
    view <string> - + The view name to be used for rendering.
    cb <function> - callback signature is function(error, result) + callback signature is function(error, result).
    @@ -250,23 +251,29 @@

    Modules

    diff --git a/docs/api/ResourceStore.server.html b/docs/api/ResourceStore.server.html new file mode 100644 index 000000000..c7ec67441 --- /dev/null +++ b/docs/api/ResourceStore.server.html @@ -0,0 +1,1533 @@ + + + + + Mojito API: MojitoServer ResourceStore.server ( + + + + + + + + + + +
    +
    +

    mojito

    +

    MojitoServer  0.3.0

    + mojito + > MojitoServer + > ResourceStore.server + + +
    + Search: +
    +   +
    +
    + +
    + +
    +
    +
    +
    +
    + Filters + + + +
    +
    + +

    + + + + + Class ResourceStore.server + + + +

    + + + + + +
    + The Resource Store manages information about the "resources" in a Mojito +application. These resources are things that have representation on the +filesystem. +Each resource can have many different versions. This is not talking about +revisions, which is how the resource changes over time. It is instead +talking about how there can be a version of the resource just for iphones, +one just for android, a fallback, etc. +There are various types of resources: +
    +config      -- a piece of configuration, sometimes for another resource
    +controller  -- the controller for a mojit
    +model       -- a model for a mojit
    +view        -- a view for a mojit
    +binder      -- a binder for a mojit
    +action      -- an action to augment the controller
    +asset       -- an asset (css, js, image, etc)
    +addon       -- an addon to the mojito system
    +spec        -- the configuration for a mojit instance
    +yui-lang    -- a YUI3 language bundle
    +yui-module  -- a YUI3 module (that isn't one of the above)
    +
    +The metadata kept about each resource is "normalized" to the follow keys: +(not all resources will have all keys) +(some types will have additional keys) +(not all combinations of type:source are valid) +
    +- id
    +context-insensitive ID of the resource
    +said another way, all versions of a resource have the same ID
    +- type
    +see above
    +- source
    +`fw`, `app` or `mojit`
    +where the resource is defined
    +- fsPath
    +the path on the filesystem
    +- staticHandlerURL
    +the URL that will cause the asset handler to serve the resource
    +for resources that can be deployed by reference to the client
    +- name
    +specific to type
    +- configType
    +for type=config
    +the type of the configuration
    +- viewEngine
    +for type=view
    +`mu`, `dust`, etc
    +- viewOutputFormat
    +for type=view
    +output format that the view will generate
    +`xml`, `html`, etc
    +- assetType
    +for type=asset
    +`css`, `js`, `png`, `swf`, etc
    +- addonType
    +for type=addon
    +the mojito subsystem to which the addon should be added
    +- yuiModuleName
    +for any resource delivered as a YUI3 module
    +the YUI3 module name
    +- yuiModuleVersion
    +for any resource delivered as a YUI3 module
    +the YUI3 module version
    +- yuiModuleMeta
    +for any resource delivered as a YUI3 module
    +the YUI3 module metadata
    +(requires, langs, etc)
    +- yuiSortedPaths
    +for any resource delivered as a YUI3 module
    +a list of YUI modules required by the module,
    +with transitive dependencies resolved
    +format:  { yui-module-name: URL-to-load-yui-module }
    +
    +
    + +
    +

    Constructor

    +
    +
    + ResourceStore.server + + ( + + + + root + + , + libs + ) + +
    +
    +
    Parameters:
    +
    + root + <string> + + directory where application is found +
    +
    + libs + <object> + + dependent libraries -- this param is mainly used +during unit testing +
    +
    + + +
    +
    +
    +
    + +
    + +
    + +
    +
    +

    Methods

    +
    +
    +

    + expandInstance

    +
    + + + + + nothing + expandInstance + ( + + + instance + + + , + ctx + + + , + cb + + + ) + + +
    + This just calls expandInstanceForEnv() with `env` set to `server`. +
    + +
    + +
    +
    Parameters:
    +
    + instance + <map> + + Partial instance to expand. +
    +
    + ctx + <object> + + The request context. +
    +
    + cb + <function(err,instance)> + + callback used to return the results (or error) +
    +
    + +
    +
    Returns: + + nothing +
    +
    results returned via the callback parameter
    +
    + + + + +
    + +
    +
    +
    +
    +

    + expandInstanceForEnv

    +
    + + + + + nothing + expandInstanceForEnv + ( + + + env + + + , + instance + + + , + ctx + + + , + cb + + + ) + + +
    + This method takes a partial instance and expands it to all details needed +to run the mojit. +Only `base` or `type` fields are required. You should only specify one. +
    +instance: {
    +base: string
    +// specifies a "base" instance which this instance will extend
    +// the value refers to a key of `specs` in `application.json`
    +type: string
    +// specifies the mojit type
    +action: "",
    +// specifies a default action if the instance isn't dispatched
    +// with a specific one.
    +config: object
    +// the config for the mojit
    +// this will be augmented (appropriately) with the mojit type
    +// defaults found in the type's `defaults.json`
    +appConfig: object
    +// the application config (appropriate for the context)
    +assetRoot: "",
    +// path to directory containing assets
    +// the path will be a URL if `env` is `client` otherwise it's a
    +// filesystem path
    +definition: object
    +// the body of the `defintion.json` for the mojit type
    +defaults: object
    +// the body of the `defaults.json` for the mojit type
    +yui: {
    +// details for generating a YUI sandbox for this instance
    +config: {
    +// configuration details for the YUI.GlobalConfig.groups (or
    +// an equivalent).
    +// The module paths are given as `fullpath` and contain
    +// either a URL if `env' is `client` or a filesystem path if
    +// `env` is `server`
    +},
    +requires: []
    +// list of YUI modules that this instance requires
    +}
    +actions: array
    +// list of paths to the YUI modules containing actions
    +controller: string
    +// path to controller
    +// the path will be a URL if `env` is `client` otherwise it's a
    +// filesystem path
    +lang:
    +// path to YUI module of the language bundle
    +// the path will be a URL if `env` is `client` otherwise it's a
    +// filesystem path
    +models: object
    +// list of models used by the mojit type
    +// the key is the model name, and the value is the path to the
    +// model file
    +// the path will be a URL if `env` is `client` otherwise it's a
    +// filesystem path
    +views: {
    +// list of views in the mojit type
    +// the key is the view name, and the value is details about the
    +// view
    +view-name: {
    +"content-path": "",
    +// the path to use to load the body of the view
    +// the path will be a URL if `env` is `client` otherwise
    +// it's a filesystem path
    +"engine": "",
    +// which engine is used to render the view
    +"binder-path": "",
    +// the path to the binder
    +// the path will be a URL if `env` is `client` otherwise
    +// it's a filesystem path
    +"binder-module": ""
    +// the YUI module name of the binder
    +}
    +}
    +}
    +
    +
    + +
    + +
    +
    Parameters:
    +
    + env + <string> + + "client" or "server" +
    +
    + instance + <object> + + partial instance to expand +
    +
    + ctx + <object> + + the runtime context for the instance +
    +
    + cb + <function(err,instance)> + + callback used to return the results (or error) +
    +
    + +
    +
    Returns: + + nothing +
    +
    results returned via the callback parameter
    +
    + + + + +
    + +
    +
    +
    +
    +

    + fileFromStaticHandlerURL

    +
    + + + + + string + fileFromStaticHandlerURL + ( + + + url + + + ) + + +
    + Returns the filesystem location of the static URL. +Returns undefined if given URL isn't part of the app. +
    + +
    + +
    +
    Parameters:
    +
    + url + <string> + + static URL +
    +
    + +
    +
    Returns: + + string +
    +
    path on filesystem of specified URL, or undefined
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getAllMojits

    +
    + + + + + object + getAllMojits + ( + + + env + + + , + ctx + + + ) + + +
    + Returns details about all mojits in the application. +
    + +
    + +
    +
    Parameters:
    +
    + env + <string> + + "client" or "server" +
    +
    + ctx + <object> + + runtime context +
    +
    + +
    +
    Returns: + + object +
    +
    keys are mojit type names, values are details about each mojit
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getAppConfig

    +
    + + + + + object + getAppConfig + ( + + + ctx + + + , + name + + + ) + + +
    + gets application configuration +
    + +
    + +
    +
    Parameters:
    +
    + ctx + <object> + + the runtime context under which to load the config +
    +
    + name + <string> + + type of config to read: +- definition: reads ./application.json +- package: reads ./package.json +- routes: reads ./routes.json (or whatever was configured in +appConfig('definition').routesFiles) +
    +
    + +
    +
    Returns: + + object +
    +
    config object
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getInlineCssMojits

    +
    + + + + + array + getInlineCssMojits + ( + + + env + + + , + ctxFilter + + + ) + + +
    + Returns details on how to make inline CSS for mojits. +This example comes from (a modified) GSG5. +[ { +context: { device: 'iphone' }, +mojitName: 'FlickrDetail', +yuiModuleName: 'inlinecss/FlickrDetail', +dest: '/blah/mojits/FlickrDetail/autoload/compiled' + +'/css.iphone.client.js', +srcs: { +'/static/FlickrDetail/assets/index.css': +' /blah/mojits/FlickrDetail/assets/index.iphone.css', +'/static/FlickrDetail/assets/message.css': +' /blah/mojits/FlickrDetail/assets/message.css' +} +] +
    + +
    + +
    +
    Parameters:
    +
    + env + <string> + + "client" or "server" +
    +
    + ctxFilter + <object> + + (optional) runtime context to restrict results to +
    +
    + +
    +
    Returns: + + array +
    +
    object describing where to put the inline CSS file and what it should contain
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getMojitTypeDetails

    +
    + + + + + object + getMojitTypeDetails + ( + + + env + + + , + ctx + + + , + mojitType + + + , + dest + + + ) + + +
    + Returns details about a mojit type. +
    + +
    + +
    +
    Parameters:
    +
    + env + <string> + + "client" or "server" +
    +
    + ctx + <object> + + runtime context +
    +
    + mojitType + <string> + + mojit type +
    +
    + dest + <object> + + object in which to place the results +
    +
    + +
    +
    Returns: + + object +
    +
    returns the "dest" parameter, which has had details added to it
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getRollupsApp

    +
    + + + + + object + getRollupsApp + ( + + + env + + + , + ctx + + + ) + + +
    + Returns details on how to make rollups for app-level resources. +
    + +
    + +
    +
    Parameters:
    +
    + env + <string> + + "client" or "server" +
    +
    + ctx + <object> + + runtime context +
    +
    + +
    +
    Returns: + + object +
    +
    object describing where to put the rollup and what it should contain
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getRollupsMojits

    +
    + + + + + object + getRollupsMojits + ( + + + env + + + , + ctx + + + ) + + +
    + Returns details on how to make rollups for mojit-level resources. +This example comes from GSG5. +{ FlickrDetail: +dest: '/blah/blah/mojits/FlickrDetail/rollup.client.js' +srcs: [ +'/blah/blah/mojits/FlickrDetail/controller.common.js', +'/blah/blah/mojits/FlickrDetail/binders/index.js', +'/blah/blah/mojits/FlickrDetail/lang/FlickrDetail_de.js', +'/blah/blah/mojits/FlickrDetail/lang/FlickrDetail_en-US.js' +] +} +
    + +
    + +
    +
    Parameters:
    +
    + env + <string> + + "client" or "server" +
    +
    + ctx + <object> + + runtime context +
    +
    + +
    +
    Returns: + + object +
    +
    object describing where to put the rollup and what it should contain
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getRoutes

    +
    + + + + + object + getRoutes + ( + + + ctx + + + ) + + +
    + Returns the routes configured in the application. +
    + +
    + +
    +
    Parameters:
    +
    + ctx + <object> + + runtime context under which to load the routes +
    +
    + +
    +
    Returns: + + object +
    +
    routes
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getSpec

    +
    + + + + + nothing + getSpec + ( + + + env + + + , + id + + + , + context + + + , + callback + + + ) + + +
    + Returns, via callback, the fully expanded mojit instance specification. +
    + +
    + +
    +
    Parameters:
    +
    + env + <string> + + either "client" or "server" +
    +
    + id + <string> + + the ID of the spec to return +
    +
    + context + <object> + + the runtime context for the spec +
    +
    + callback + <function(err,spec)> + + callback used to return the results (or error) +
    +
    + +
    +
    Returns: + + nothing +
    +
    results returned via the callback parameter
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getType

    +
    + + + + + nothing + getType + ( + + + env + + + , + type + + + , + context + + + , + callback + + + ) + + +
    + Returns, via callback, the details of the mojit type. +
    + +
    + +
    +
    Parameters:
    +
    + env + <string> + + either "client" or "server" +
    +
    + type + <string> + + the mojit type +
    +
    + context + <object> + + the runtime context for the spec +
    +
    + callback + <function(err,spec)> + + callback used to return the results (or error) +
    +
    + +
    +
    Returns: + + nothing +
    +
    results returned via the callback parameter
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getYuiConfigAllMojits

    +
    + + + + + object + getYuiConfigAllMojits + ( + + + env + + + , + ctx + + + ) + + +
    + Returns the YUI configuration object which tells YUI about the +YUI modules in all the mojits. +
    + +
    + +
    +
    Parameters:
    +
    + env + <string> + + "client" or "server" +
    +
    + ctx + <object> + + runtime context for YUI configuration +
    +
    + +
    +
    Returns: + + object +
    +
    YUI configuration for all mojits
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getYuiConfigApp

    +
    + + + + + object + getYuiConfigApp + ( + + + env + + + , + ctx + + + ) + + +
    + Returns the YUI configuration object which tells YUI about the +YUI modules in the application (which aren't part of a mojit). +
    + +
    + +
    +
    Parameters:
    +
    + env + <string> + + "client" or "server" +
    +
    + ctx + <object> + + runtime context for YUI configuration +
    +
    + +
    +
    Returns: + + object +
    +
    YUI configuration for the app-level modules
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getYuiConfigFw

    +
    + + + + + object + getYuiConfigFw + ( + + + env + + + , + ctx + + + ) + + +
    + Returns the YUI configuration object which tells YUI about the +YUI modules in the Mojito framework. +
    + +
    + +
    +
    Parameters:
    +
    + env + <string> + + "client" or "server" +
    +
    + ctx + <object> + + runtime context for YUI configuration +
    +
    + +
    +
    Returns: + + object +
    +
    YUI configuration for Mojito framework
    +
    + + + + +
    + +
    +
    +
    +
    +

    + listAllMojits

    +
    + + + + + array + listAllMojits + ( + + + env + + + ) + + +
    + Returns a list of all mojit types in the application. +
    + +
    + +
    +
    Parameters:
    +
    + env + <string> + + "client" or "server" +
    +
    + +
    +
    Returns: + + array +
    +
    list of mojit types
    +
    + + + + +
    + +
    +
    +
    +
    +

    + preload

    +
    + + + + + nothing + preload + ( + + + appContext + + + , + appConfig + + + ) + + +
    + Preloads everything in the app, and as well pertinent parts of +the framework. +
    + +
    + +
    +
    Parameters:
    +
    + appContext + <object> + + the base context for reading configuration. +
    +
    + appConfig + <object> + + overrides for the app config. +
    +
    + +
    +
    Returns: + + nothing +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + setLogger

    +
    + + + + + nothing + setLogger + ( + + + l + + + ) + + +
    + Sets the logger object. +
    + +
    + +
    +
    Parameters:
    +
    + l + <object> + + object containing a log(message,level,source) function +
    +
    + +
    +
    Returns: + + nothing +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +
    + +
    + +
    + + +
    + +
    + +
    + +
    +
    + +
    +
    +
    + Copyright © 2012 Yahoo! Inc. All rights reserved. +
    +
    + + + diff --git a/docs/api/Url.common.html b/docs/api/Url.common.html index a4c637743..d59936d62 100644 --- a/docs/api/Url.common.html +++ b/docs/api/Url.common.html @@ -2,23 +2,23 @@ - API: MojitoServer Url.common (YUI Library) + Mojito API: ActionContextAddon Url.common ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > Url.common
    @@ -107,13 +107,13 @@

    url <string> - the URL to find a route for + the URL to find a route for.
    verb <string> - the HTTP method + the HTTP method.
    @@ -146,7 +146,7 @@

    ( - id + base , @@ -158,7 +158,7 @@

    , - verb + varb , @@ -177,34 +177,38 @@

    Parameters:
    - id + base <string> - it to a mojit defined at the root level of the Mojito application configuration + Base mojit defined at the root level of the +Mojito application configuration.
    action <string> - + Action reference, concatenated to the base +using a period (.) separator.
    routeParams <object> - used to lookup the route in the routing table + used to lookup the route in the routing +table.
    - verb + varb <string> - GET, POST, PUT, DELETE (case insensitive) + GET, POST, PUT, DELETE (case insensitive).
    urlParams <object> - added to the looked up route as query params + added to the looked up route as query +params.
    @@ -247,23 +251,29 @@

    Modules

    diff --git a/docs/api/Y.mojito.ActionContext.html b/docs/api/Y.mojito.ActionContext.html index 9cf6bdc93..ab732e9a3 100644 --- a/docs/api/Y.mojito.ActionContext.html +++ b/docs/api/Y.mojito.ActionContext.html @@ -1,25 +1,25 @@ - + - API: ActionContext Y.mojito.ActionContext (YUI Library) + Mojito API: ActionContext - - + + - - + +
    -

    mojito

    -

    ActionContext  0.1.0

    +

    mojito

    +

    ActionContext  0.3.0

    mojito > ActionContext - > Y.mojito.ActionContext + > ActionContext
    @@ -48,7 +48,7 @@

    - Class Y.mojito.ActionContext + Class ActionContext @@ -605,7 +605,7 @@

    Modules

    @@ -655,7 +655,7 @@

    Methods

    diff --git a/docs/api/Y.mojito.Client.html b/docs/api/Y.mojito.Client.html index fd9dd9c43..38fa4575e 100644 --- a/docs/api/Y.mojito.Client.html +++ b/docs/api/Y.mojito.Client.html @@ -2,21 +2,21 @@ - API: MojitoClient Y.mojito.Client (YUI Library) + Mojito API: MojitoClient Y.mojito.Client ( - - + + - - + +
    -

    mojito

    -

    MojitoClient  0.1.0

    +

    mojito

    +

    MojitoClient  0.3.0

    mojito > MojitoClient > Y.mojito.Client @@ -59,8 +59,9 @@

    - The starting point for mojito to run in the browser. You can access one instance of the Mojito Client running -within the browser environment through window.YMojito.client. + The starting point for mojito to run in the browser. You can access one +instance of the Mojito Client running within the browser environment +through window.YMojito.client.
    @@ -83,8 +84,8 @@

    Constructor

    config <Object> - The entire configuration object written by the server -to start up mojito. + The entire configuration object written by the +server to start up mojito. @@ -95,6 +96,26 @@

    Constructor

    +
    +

    Properties

    +
    +
    +

    prototype + - object +

    +
    +
    + Fired after the binders are attached to the page. +
    +
    + + + + +
    +
    +
    +
    @@ -102,50 +123,32 @@

    Constructor

    Methods

    -
    +

    - find

    + pause

    void - find + pause ( - - - url - - - , - verb - - )
    - Finds a route for a given method+URL + Pause the Mojito Client and all mojits that are running. This will +notify all binders that they have been paused by calling their +onPause() functions. It will prevent the immediate execution of +several mojit proxy operations that might cause a long process to +begin (especially things that might go to the server). +To resume, simply call .resume(). This will immediately execute all +actions that occurred while Mojito was paused.
    -
    -
    Parameters:
    -
    - url - <string> - - the URL to find a route for -
    -
    - verb - <string> - - the HTTP method -
    -
    Returns: @@ -163,64 +166,26 @@


    -
    -

    - getComputedRoutes

    -
    - - - - - object - getComputedRoutes - ( - ) - - -
    - For optimization. Call this to get the computed routes that can be -passed to the constructor to avoid recomputing the routes. -
    - -
    - - -
    -
    Returns: - - object -
    -
    computed routes
    -
    - - - - -
    - -
    -
    -
    -
    +

    void - pause + resume ( )
    - Pause the Mojito Client and all mojits that are running. This will notify all binders that they have been -paused by calling their onPause() functions. It will prevent the immediate execution of several mojit proxy -operations that might cause a long process to begin (especially things that might go to the server). -To resume, simply call .resume(). This will immediately execute all actions that occurred while Mojito was -paused. + Resumes the Mojito client after it has been paused (see method +"pause"). If there are any queued actions that were executed and +cached during the pause, calling resume() will immediately execute +them. All binders are notified through their onResume() function that +they are been resumed.
    @@ -242,28 +207,50 @@


    -

    void - resume + subscribe ( + + + evt + + + , + cb + + )
    - Resumes the Mojito client after it has been paused (see method "pause"). If there are any queued actions that -were executed and cached during the pause, calling resume() will immediately execute them. All binders are -notified through their onResume() function that they are been resumed. + Subscribe to a MojitoClient lifecycle event.
    +
    +
    Parameters:
    +
    + evt + <string> + + name of event to subscribe to. +
    +
    + cb + <function(data)> + + callback called when the event fires. +
    +
    Returns: @@ -314,8 +301,8 @@

    Modules

    @@ -323,30 +310,31 @@

    Classes

    --> +
    +

    Properties

    + +
    @@ -361,7 +349,7 @@

    Methods

    diff --git a/docs/api/Y.mojito.MojitProxy.html b/docs/api/Y.mojito.MojitProxy.html index 931031010..87786dfe4 100644 --- a/docs/api/Y.mojito.MojitProxy.html +++ b/docs/api/Y.mojito.MojitProxy.html @@ -2,7 +2,7 @@ - API: MojitoClient Y.mojito.MojitProxy (YUI Library) + Mojito API: MojitoClient Y.mojito.MojitProxy ( @@ -15,8 +15,8 @@
    -

    mojito

    -

    MojitoClient  0.1.0

    +

    mojito

    +

    MojitoClient  0.3.0

    mojito > MojitoClient > Y.mojito.MojitProxy diff --git a/docs/api/Y.mojito.lib.REST.html b/docs/api/Y.mojito.lib.REST.html index 177949e13..df226df52 100644 --- a/docs/api/Y.mojito.lib.REST.html +++ b/docs/api/Y.mojito.lib.REST.html @@ -2,21 +2,21 @@ - API: CommonLibs Y.mojito.lib.REST (YUI Library) + Mojito API: CommonLibs Y.mojito.lib.REST ( - - + + - - + +
    -

    mojito

    -

    CommonLibs  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito > CommonLibs > Y.mojito.lib.REST @@ -46,7 +46,7 @@

    CommonLibs  0.1.0

    - static + Class Y.mojito.lib.REST @@ -59,8 +59,8 @@

    - The Rest module for Mojito provides an easy way to make RESTful calls to URLs -without messing about with Y.io. + The Rest module for Mojito provides an easy way to make RESTful calls to +URLs without messing about with Y.io.
    @@ -115,25 +115,212 @@

    url <String> - RESTful URL to hit + RESTful URL to hit.
    params <Object> - parameters to add to the request + parameters to add to the request.
    config <Object> - may contain 'headers' or 'timeout' values + may contain 'headers' or 'timeout' values.
    callback <Function> - called with response or error + called with response or error. +
    + + +
    +
    Returns: + + void +
    +
    +
    + + + + +

    + +
    +
    +
    +
    +

    + destroy

    +
    + + + + + void + destroy + ( + ) + + +
    + Called by the bean registry whenever this bean is reinitialized +
    + +
    + + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + disable

    +
    + + + + + void + disable + ( + + + queue + + + ) + + +
    + Disables all Ajax requests for the application. +
    + +
    + +
    +
    Parameters:
    +
    + queue + <Boolean> + + (Optional) When set to true, queues all +requests while disabled. +
    +
    + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + enable

    +
    + + + + + void + enable + ( + ) + + +
    + Enables sending of requests. +
    + +
    + + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + find

    +
    + + + + + void + find + ( + + + url + + + , + verb + + + ) + + +
    + Finds a route for a given method+URL +
    + +
    + +
    +
    Parameters:
    +
    + url + <string> + + the URL to find a route for. +
    +
    + verb + <string> + + the HTTP method.
    @@ -196,25 +383,25 @@

    url <String> - RESTful URL to hit + RESTful URL to hit.
    params <Object> - parameters to add to the request + parameters to add to the request.
    config <Object> - may contain 'headers' or 'timeout' values + may contain 'headers' or 'timeout' values.
    callback <Function> - called with response or error + called with response or error.
    @@ -229,6 +416,160 @@

    +

    + +
    +
    +
    +
    +

    + getBean

    +
    + + + + + Object + getBean + ( + ) + + +
    + If the bean system has not been instatiated yet, this will +instantiate all beans! Then one bean instance is returned by name. +
    + +
    + + +
    +
    Returns: + + Object +
    +
    the bean instance, or undefined if it is not +registered.
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getBeans

    +
    + + + + + Object + getBeans + ( + ) + + +
    + If the bean system has not been instatiated yet, this will +instantiate all beans! +
    + +
    + + +
    +
    Returns: + + Object +
    +
    contains all beans, each bean is accessible by bean +name.
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getComputedRoutes

    +
    + + + + + object + getComputedRoutes + ( + ) + + +
    + For optimization. Call this to get the computed routes that can be +passed to the constructor to avoid recomputing the routes. +
    + +
    + + +
    +
    Returns: + + object +
    +
    computed routes.
    +
    + + + + +
    + +
    +
    +
    +
    +

    + getName

    +
    + + + + + String + getName + ( + ) + + +
    + Given an instance of a bean, returns the String name +
    + +
    + + +
    +
    Returns: + + String +
    +
    name of the registered bean, or undefined if it is +not a registered bean.
    +
    + + + +
    @@ -277,25 +618,97 @@

    url <String> - RESTful URL to hit + RESTful URL to hit.
    params <Object> - parameters to add to the request + parameters to add to the request.
    config <Object> - may contain 'headers' or 'timeout' values + may contain 'headers' or 'timeout' values.
    callback <Function> - called with response or error + called with response or error. +
    + + +
    +
    Returns: + + void +
    +
    +
    + + + + +

    + +
    +
    +
    +
    +

    + mergeRecursive

    +
    + + + + + void + mergeRecursive + ( + + + dest + + + , + src + + + , + typeMatch + + + ) + + +
    + Recursively merge properties of two objects +
    + +
    + +
    +
    Parameters:
    +
    + dest + <object> + + The destination object. +
    +
    + src + <object> + + The source object. +
    +
    + typeMatch + <boolean> + + Only replace if src and dest types are +the same type if true.
    @@ -358,25 +771,25 @@

    url <String> - RESTful URL to hit + RESTful URL to hit.
    params <Object> - parameters to add to the request + parameters to add to the request.
    config <Object> - may contain 'headers' or 'timeout' values + may contain 'headers' or 'timeout' values.
    callback <Function> - called with response or error + called with response or error.
    @@ -439,25 +852,204 @@

    url <String> - RESTful URL to hit + RESTful URL to hit.
    params <Object> - parameters to add to the request + parameters to add to the request.
    config <Object> - may contain 'headers' or 'timeout' values + may contain 'headers' or 'timeout' values.
    callback <Function> - called with response or error + called with response or error. +
    + + +
    +
    Returns: + + void +
    +
    +
    + + + + +

    + +
    +
    +
    +
    +

    + registerBean

    +
    + + + + + void + registerBean + ( + + + name + + + , + bean + + + ) + + +
    + Called to register a bean or bean constructor with the bean registry. +If this method is called twice with the same bean, the last bean +wins. Only one type of bean can be in the system at a time. +
    + +
    + +
    +
    Parameters:
    +
    + name + <string> + + Required identifier of this bean. +
    +
    + bean + <Object> + + Either a constructor Function or an instance +object of a bean. +
    +
    + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + setRequestFormatter

    +
    + + + + + void + setRequestFormatter + ( + + + requestType + + + , + formatter + + + ) + + +
    + Sets the request formatter function for a given request type. +
    + +
    + +
    +
    Parameters:
    +
    + requestType + <String> + + The type of request that the +formatter should handle. +
    +
    + formatter + <Function> + + The function to call to format the +request. +
    +
    + +
    +
    Returns: + + void +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +

    + setResponseFormatter

    +
    diff --git a/docs/api/action-context.common.js.html b/docs/api/action-context.common.js.html index 853671e7a..26f36f350 100644 --- a/docs/api/action-context.common.js.html +++ b/docs/api/action-context.common.js.html @@ -2,23 +2,23 @@ - API: MojitoClient action-context.common.js (YUI Library) + Mojito API: ActionContextAddon action-context.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoClient  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoClient + > ActionContextAddon > action-context.common.js (source view) @@ -48,134 +48,61 @@

    MojitoClient  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
     
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
    - * The Action Context is a key part of the Mojito framework. The <em>ac</em>, for short, gives you access
    - * to the frameworks features from within a controller function. The ac is an abstraction that
    - * allows you to execute mojit actions within either a server or client context.
    - *
    + * The Action Context is a key part of the Mojito framework. The <em>ac</em>,
    + * for short, gives you access to the frameworks features from within a
    + * controller function. The ac is an abstraction that allows you to execute
    + * mojit actions within either a server or client context.
      * @module ActionContext
      */
    -
     YUI.add('mojito-action-context', function(Y, NAME) {
     
         var CACHE;
     
    -    /**
    -     * The main point of entry for all mojits into Mojito. The Action Context is
    -     * passed to every mojit action during execution, either on the client or
    -     * server. This object is the API into Mojito, can can have many plugins
    -     * attached the provide extra functionality.
    -     * @submodule ActionContext
    -     * @class ActionContext
    -     */
    -    function ActionContext(opts) {
    -        Y.log('constructing action context', 'mojito', 'qeperf');
    -
    -        var self = this,
    -            command = opts.command,
    -            instance = command.instance,
    -            controller = opts.controller,
    -            models = opts.models,
    -            dispatch = opts.dispatch,
    -            adapter = opts.adapter,
    -            store = opts.store,
    -            actionFunction,
    -            error;
    -
    -        // "init" is not an action
    -        if (command.action === 'init') {
    -            throw new Error("Cannot execute action 'init' on any mojit. This name is "
    -                    + "reserved by the Mojito framework.");
    -        }
     
    -        // we want to make these easily accessible to any functions that addons attach directly to the ac object
    -        this.command = command;
    -        this.instance = instance;
    -        this.action = command.action;
    -        this.type = instance.type;
    -        this.context = command.context;
    -        this.models = models;
    -
    -        // identify this as internal... users probably won't want to use it, but addons might need
    -        this._dispatch = dispatch;
    -        this._adapter = adapter;
    -
    -        // deprecated this function for current users
    -        this.dispatch = function() {
    -            Y.log('ac.dispatch() will soon be deprecated to discourage it\'s usage from within controllers. If you want to dispatch a command from within an ActionContext addon, please use ac._dispatch().', 'warn', NAME);
    -            self._dispatch.apply(self, arguments);
    -        };
    -
    -        this.app = {
    -            config: store.getAppConfig(this.context, 'definition'),
    -            routes: store.getRoutes(this.context)
    -        };
    -
    -
    -        attachActionContextAddons(Y.mojito.addons.ac, command, adapter, this);
    -
    -        // There is only one addon that requires the store so check for it here
    -        if(this.deploy){
    -            this.deploy.setStore(store);
    -        }
    -
    -        Y.log('ActionContext created for "'+(instance.id || '@'+instance.type)+'/'+command.action+'"', 'mojito', NAME);
    -
    -        // Grab the action here as me may change it
    -        actionFunction = command.action;
    -
    -        // Check if the controller has the requested action
    -        if (! Y.Lang.isFunction(controller[actionFunction])) {
    -            // If the action is not found try the '__call' function
    -            if(Y.Lang.isFunction(controller.__call)){
    -                actionFunction = '__call';
    -            }else{
    -                // If there is still no joy then die
    -                error = new Error("No method '" + command.action + "' on controller type '" + instance.type + "'");
    -                error.code = 404;
    -                throw error;
    -            }
    -        }
    -
    -        // Time marker
    -        Y.mojito.perf.mark('mojito', 'core_action_start['+instance.type+':'+command.action+']', 'Calling the Mojit "'+instance.type+'" with action "'+command.action+'"');
    -
    -        Y.log('action context created, executing action "' + actionFunction + '"', 'mojito', 'qeperf');
    -
    -        controller[actionFunction](this);
    -    }
    +    // -------------------------------------------------------------------------
    +    // Comments below are so generated comments for flush, done, etc. are found
    +    // on ActionContext even though they're not really done here.
    +    // -------------------------------------------------------------------------
     
         /**
          * Returns data in the request and allows you to carry on execution.
    -     * @method flush
    -     * @param {object|string} data The data you want return by the request
    -     * @param {object} meta Any meta-data required to service the request
    +     * @param {object|string} data The data you want return by the request.
    +     * @param {object} meta Any meta-data required to service the request.
          */
     
         /**
          * Returns data and closes the request.
    -     * @method done
    -     * @param {object|string} data The data you want return by the request
    -     * @param {object} meta Any meta-data required to service the request
    +     * @param {object|string} data The data you want return by the request.
    +     * @param {object} meta Any meta-data required to service the request.
          */
     
         /**
    -     * Programatically report an error to Mojito, which will handle it gracefully.
    -     * @method error
    -     * @param err {Error} A normal JavaScript Error object is expected, but you may add a "code" property to the error
    -     * if you want the framework to report a certain HTTP status code for the error. For example, if the status code
    -     * is 404, Mojito will generate a 404 page.
    +     * Programatically report an error to Mojito, which will handle it
    +     * gracefully.
    +     * @param {Error} err A normal JavaScript Error object is expected, but you
    +     *     may add a "code" property to the error if you want the framework to
    +     *     report a certain HTTP status code for the error. For example, if the
    +     *     status code is 404, Mojito will generate a 404 page.
          */
     
         /**
    -     * This dispatch function is called one time per Mojito execution. It creates a
    -     * contextualized Y instance for all further internal dispatches to use. It also
    -     * creates the ActionContext for the mojit.
    +     * This dispatch function is called one time per Mojito execution. It
    +     * creates a contextualized Y instance for all further internal dispatches
    +     * to use. It also creates the ActionContext for the mojit.
          *
    -     * The command has three main parts:  the "instance", the "context", and the "params".
    +     * The command has three main parts:  the "instance", the "context", and the
    +     * "params".
          * <pre>
          *  command: {
          *      instance: ...see below...
    @@ -185,11 +112,11 @@ 

    MojitoClient  0.1.0

    * </pre> * * The "instance" is a partial instance with details of the mojit instance. - * See `ServerStore.expandInstance()` for details of the structure and which fields - * are required. + * See `ServerStore.expandInstance()` for details of the structure and which + * fields are required. * - * The "context" is the request context. It is built by the "contextualizer" - * middleware. + * The "context" is the request context. It is built by the + * "contextualizer" middleware. * * The "params" is a structured set of parameters to pass to the mojit. * <pre> @@ -209,107 +136,71 @@

    MojitoClient  0.1.0

    * error: function(err){} * } * </pre> - * - * @method dispatch - * @param command {map} the "command" describing how to dispatch the mojit. see above - * @param adapter {object} the output adapter to pass to the mojit. see above - * @return nothing. results are passed via the adapter + * @param {map} command the "command" describing how to dispatch the mojit. + * See above. + * @param {object} adapter the output adapter to pass to the mojit. See + * above. */ - /** - * Mixes all the Action Context addons into the Action Context - * @param ac {Y.mojito.ActionContext} - * @param acAddons {Array} the action context addons - * @param store {object} - * @param command {object} - * @param adapter {object} - * / - function attachActionContextAddons(ac, acAddons, store, command, adapter) { - - var mixed = {}, - processDependencies, - createAddon, - addonName; - - // This inner function is used to process the dependencies of on action context addon. - // An AC addon declares its dependencies by attaching a "dependsOn" property to its - // constructor function that points to an array of strings, which are the names of all - // the addon namespaces that are require to be plugged before it. - processDependencies = function(addon, name, cb) { - - var i, dep, Dependee, - dependsOn = addon.dependsOn; - - if (Y.Lang.isArray(dependsOn)) { - for(i in dependsOn){ - dep = dependsOn[i]; - if (!mixed[dep]) { - Dependee = acAddons[dep]; - if (!Dependee) { - throw new Error("Cannot process action-context addon '" + name + "', missing dependency: '" + dep + "'"); - } - processDependencies(Dependee, dep, function() { - createAddon(dep, Dependee, ac); - }); - } - } - } - cb(); - }; - - createAddon = function(name, Ctor, ac) { - - var addon = new Ctor(command, adapter, ac); - // if this is the 'deploy' addon , and it requires the resource store, - // deliver it - if (addon.namespace === 'deploy' && Y.Lang.isFunction(addon.setStore)) { - addon.setStore(store); - } - - if (addon.namespace) { - ac[addon.namespace] = addon; - } - - mixed[name] = true; - }; - - for(addonName in acAddons){ - if (!mixed[addonName]) { - processDependencies(acAddons[addonName], addonName, function() { - createAddon(addonName, acAddons[addonName], ac); - }); - } - } - }*/ - - if(!YUI._mojito){ + // TODO: probably should move to mojito.common.js (namespace definitions). + if (!YUI._mojito) { YUI._mojito = {}; } - if(!YUI._mojito._cache){ + if (!YUI._mojito._cache) { YUI._mojito._cache = {}; } - if(!YUI._mojito._cache.addons){ + if (!YUI._mojito._cache.addons) { YUI._mojito._cache.addons = {}; } CACHE = YUI._mojito._cache.addons; - function attachActionContextAddons(addons, command, adapter, ac){ + function calculateAddonDependencies(addon, addons, dependencies) { + var dep, + dependsOn = addon.dependsOn, + i; + + if (!Y.Lang.isArray(dependsOn)) { + return; + } + + for (i = 0; i < dependsOn.length; i += 1) { + dep = dependsOn[i]; + if (!dependencies[dep]) { + if (!addons[dep]) { + throw new Error(addon.prototype.namespace + + " addon has invalid dependency: '" + dep + "'"); + } + calculateAddonDependencies(addons[dep], addons, dependencies); + } + dependencies[dep] = true; + } + } + + + /** + * Mixes all the Action Context addons into the Action Context + * @param {Array} addons The action context addons. + * @param {object} command The command object. + * @param {object} adapter The output adapter. + * @param {Y.mojito.ActionContext} ac The action context. + */ + function attachActionContextAddons(addons, command, adapter, ac) { var addonName, addon, dependencies = {}; - if(CACHE[ac.type]){ + if (CACHE[ac.type]) { dependencies = CACHE[ac.type]; - } - else{ - for(addonName in addons){ - if(addons.hasOwnProperty(addonName)) { - if(!dependencies[addonName]) { - calculateAddonDependencies(addons[addonName], addons, dependencies); + } else { + for (addonName in addons) { + if (addons.hasOwnProperty(addonName)) { + if (!dependencies[addonName]) { + calculateAddonDependencies(addons[addonName], addons, + dependencies); } dependencies[addonName] = true; } @@ -317,41 +208,121 @@

    MojitoClient  0.1.0

    CACHE[ac.type] = dependencies; } - for(addonName in dependencies){ - if(dependencies.hasOwnProperty(addonName)) { + for (addonName in dependencies) { + if (dependencies.hasOwnProperty(addonName)) { addon = new addons[addonName](command, adapter, ac); - if(addon.namespace) { + if (addon.namespace) { ac[addon.namespace] = addon; } } } } - function calculateAddonDependencies(addon, addons, dependencies){ - var dep, - dependsOn = addon.dependsOn, - i; + /** + * The main point of entry for all mojits into Mojito. The Action Context is + * passed to every mojit action during execution, either on the client or + * server. This object is the API into Mojito, can can have many plugins + * attached the provide extra functionality. + * @class ActionContext + */ + function ActionContext(opts) { + Y.log('constructing action context', 'mojito', 'qeperf'); - if(!Y.Lang.isArray(dependsOn)) { - return; + var self = this, + command = opts.command, + instance = command.instance, + controller = opts.controller, + models = opts.models, + dispatch = opts.dispatch, + adapter = opts.adapter, + store = opts.store, + actionFunction, + error; + + // "init" is not an action + if (command.action === 'init') { + throw new Error('Cannot execute action \'init\' on any mojit.' + + ' This name is reserved by the Mojito framework.'); } - for(i=0; i < dependsOn.length; i++){ - dep = dependsOn[i]; - if(! dependencies[dep]) { - if (! addons[dep]) { - throw new Error(addon.prototype.namespace + " addon has invalid dependency: '" + dep + "'"); - } - calculateAddonDependencies(addons[dep], addons, dependencies); + // we want to make these easily accessible to any functions that addons + // attach directly to the ac object. + // TODO: These properties should be hidden behind accessor functions. + this.command = command; + this.instance = instance; + this.action = command.action; + this.type = instance.type; + this.context = command.context; + this.models = models; + + // identify this as internal... users probably won't want to use it, but + // addons might need + this._dispatch = dispatch; + this._adapter = adapter; + + // deprecated this function for current users + this.dispatch = function() { + Y.log('ac.dispatch() will soon be deprecated to discourage' + + ' usage from within controllers. If you want to dispatch' + + ' a command from within an ActionContext addon, please use' + + ' ac._dispatch().', 'warn', NAME); + self._dispatch.apply(self, arguments); + }; + + // TODO: should rework to be 'getAppConfig()' and 'getAppRoutes()' and + // not property access through a hash. + this.app = { + config: store.getAppConfig(this.context, 'definition'), + routes: store.getRoutes(this.context) + }; + + // this is where the addons list is injected onto the action + // context...yay! + attachActionContextAddons(Y.mojito.addons.ac, command, adapter, this); + + // There is only one addon that requires the store so check for it here. + // TODO: how can we generalize this so it's not hard-coded to only the + // deploy add-on. Oh, and note we don't make sure that setStore is a + // callable function ;). + if (this.deploy) { + this.deploy.setStore(store); + } + + Y.log('ActionContext created for "' + (instance.id || '@' + + instance.type) + '/' + command.action + '"', 'mojito', NAME); + + // Grab the action here as me may change it + actionFunction = command.action; + + // Check if the controller has the requested action + if (!Y.Lang.isFunction(controller[actionFunction])) { + // If the action is not found try the '__call' function + if (Y.Lang.isFunction(controller.__call)) { + actionFunction = '__call'; + } else { + // If there is still no joy then die + error = new Error("No method '" + command.action + + "' on controller type '" + instance.type + "'"); + error.code = 404; + throw error; } - dependencies[dep] = true; } + + // Time marker + Y.mojito.perf.mark('mojito', 'core_action_start[' + instance.type + + ':' + command.action + ']', 'Calling the Mojit "' + instance.type + + '" with action "' + command.action + '"'); + + Y.log('action context created, executing action "' + actionFunction + + '"', 'mojito', 'qeperf'); + + controller[actionFunction](this); } Y.mojito.ActionContext = ActionContext; -}, '0.1.0', {requires: [ +}, '0.3.0', {requires: [ // following are ACPs are always available 'mojito-config-addon', 'mojito-output-adapter-addon', @@ -372,9 +343,9 @@

    MojitoClient  0.1.0

    Modules

    @@ -382,8 +353,22 @@

    Modules

    @@ -392,17 +377,24 @@

    Classes

    Files

    --> @@ -420,7 +412,7 @@

    Files

    diff --git a/docs/api/analytics.common.js.html b/docs/api/analytics.common.js.html index 96a1f7a18..3a83b1d08 100644 --- a/docs/api/analytics.common.js.html +++ b/docs/api/analytics.common.js.html @@ -2,21 +2,21 @@ - API: MojitoServer analytics.common.js (YUI Library) + Mojito API: MojitoServer analytics.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    MojitoServer  0.3.0

    mojito > MojitoServer @@ -48,21 +48,32 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true*/
    +/*global YUI*/
    +
    +
     /**
    - * The <strong>Action Context</strong> uses a mechanism called <strong><em>Addons</em></strong>
    - * to provide functionality that lives both
    - * on the server and/or client. Each Addon provides additional functions through a namespace
    - * that is attached directly to the ac argument available in every controller function.
    + * The <strong>Action Context</strong> uses a mechanism called
    + * <strong><em>Addons</em></strong> to provide functionality that lives both on
    + * the server and/or client. Each Addon provides additional functions through a
    + * namespace that is attached directly to the ac argument available in every
    + * controller function.
      * @module ActionContextAddon
      */
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-analytics-addon', function(Y, NAME) {
     
    -    var ANALYTICS = 'anal'; // I saved 5 keystrokes!
    +    var ANALYTICS = 'analytics';
     
         /**
          * <strong>Access point:</strong> <em>ac.analytics.*</em>
    @@ -81,31 +92,30 @@ 

    MojitoServer  0.1.0

    this.mergeFunction = Y.mojito.util.metaMerge; } + AnalyticsAddon.prototype = { namespace: 'analytics', /** * Allows a way for addons mixed in after this one to set an alternate - * data merge function when analytics from multiple children are combined. - * The default merge function is the same one used internally by Mojito - * to merge meta data, and will be sufficient for most use cases. - * - * @method setMergeFunction + * data merge function when analytics from multiple children are + * combined. The default merge function is the same one used internally + * by Mojito to merge meta data, and will be sufficient for most use + * cases. * @param {function} fn user-defined merge function, which should accept - * two objects, the first is "to", and the second is "from". this function - * should return the merged object. + * two objects, the first is "to", and the second is "from". this + * function should return the merged object. */ setMergeFunction: function(fn) { this.mergeFunction = fn; }, + /** * Store an analytic value. This function can be called multiple times * within a mojit, and uses a merging function to combine objects. - * - * @method store - * @param {object} val should be an object bag full of whatever you wish + * @param {object} val An object bag full of whatever you wish. */ store: function(val) { // if you don't like using our internal meta merge function, @@ -115,30 +125,32 @@

    MojitoServer  0.1.0

    this.ac.meta.store(ANALYTICS, this[ANALYTICS]); }, + /** * To retrieve analytics data that has been stored by child mojits, call - * this function and provide a function, which will be called once the children - * have been dispatched and all their analytics data has been merged. - * - * @method retrieve - * @param {function} cb callback will be called with the analytics object - * @param {object} [optional] scope scope of the callback + * this function and provide a function, which will be called once the + * children have been dispatched and all their analytics data has been + * merged. + * @param {function} cb callback invoked with the analytics object. + * @param {object} [optional] scope scope of the callback. */ retrieve: function(cb, scope) { - // mostly just deferring to the meta addon, but specifying that we only want the - // ANALYTICS stuff off the meta + // mostly just deferring to the meta addon, but specifying that we + // only want the ANALYTICS stuff off the meta this.ac.meta.retrieve(function(metaStash) { - cb.call(this, metaStash[ANALYTICS]); }, scope); } }; AnalyticsAddon.dependsOn = ['meta']; - + Y.mojito.addons.ac.analytics = AnalyticsAddon; -}, '0.1.0', {requires: ['mojito-util', 'mojito-meta-addon']}); +}, '0.3.0', {requires: [ + 'mojito-util', + 'mojito-meta-addon' +]});
    @@ -160,16 +172,9 @@

    Modules

    @@ -178,27 +183,11 @@

    Classes

    Files

    --> @@ -216,7 +205,7 @@

    Files

    diff --git a/docs/api/assets.common.js.html b/docs/api/assets.common.js.html index 8659362f6..d4bbde963 100644 --- a/docs/api/assets.common.js.html +++ b/docs/api/assets.common.js.html @@ -2,21 +2,21 @@ - API: ActionContextAddon assets.common.js (YUI Library) + Mojito API: ActionContextAddon assets.common.js ( - - + + - - + +
    -

    mojito

    -

    ActionContextAddon  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito > ActionContextAddon @@ -48,14 +48,29 @@

    ActionContextAddon  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI,Image*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-assets-addon', function(Y, NAME) {
     
    -    var isInline;
    +    var isInline = function(id) {
    +        return YUI._mojito._cache &&
    +            YUI._mojito._cache.compiled &&
    +            YUI._mojito._cache.compiled.css &&
    +            YUI._mojito._cache.compiled.css.inline &&
    +            YUI._mojito._cache.compiled.css.inline[id];
    +    };
    +
     
         /**
          * <strong>Access point:</strong> <em>ac.assets.*</em>
    @@ -67,79 +82,101 @@ 

    ActionContextAddon  0.1.0

    this.assets = {}; this.added = {}; // content: boolean this.mojitType = command.instance.type; + this.context = command.context; // Add "assets" if they are found in the config. - if(command.instance && command.instance.config && command.instance.config.assets){ + if (command.instance && command.instance.config && + command.instance.config.assets) { this.addAssets(command.instance.config.assets); } } + AssetsAcAddon.prototype = { namespace: 'assets', /** * Method for adding a JS file to the page. - * @method addCss - * @param {string} link A URL (./local.css converts to /static/mojit_type/assets/local.css) - * @param {string} location Either "top" or "bottom" + * @param {string} link A URL (./local.css converts to + * /static/mojit_type/assets/local.css). + * @param {string} location Either "top" or "bottom". */ - addCss: function(link, location){ + addCss: function(link, location) { this.addAsset('css', (location || 'top'), link); }, + /** * Method for adding a JS file to the page. - * @method addJs - * @param {string} link A URL (./local.css converts to /static/mojit_type/assets/local.css) - * @param {string} location Either "top" or "bottom" + * @param {string} link A URL (./local.css converts to + * /static/mojit_type/assets/local.css). + * @param {string} location Either "top" or "bottom". */ - addJs: function(link, location){ + addJs: function(link, location) { this.addAsset('js', (location || 'bottom'), link); }, + /** * Method for adding a Blob of data to the page. This can be used * for adding custom "script" or "style" blocks. - * @method addBlob - * @param {string} content A string of data - * @param {string} location Either "top" or "bottom" + * @param {string} content A string of data. + * @param {string} location Either "top" or "bottom". */ - addBlob: function(content, location){ + addBlob: function(content, location) { this.addAsset('blob', (location || 'bottom'), content); }, - + + + /** + * + */ addAsset: function(type, location, content) { - if(!content){ + if (!content) { return; } - if(content.indexOf('./')===0){ + + if (content.indexOf('./') === 0) { content = this.getUrl(content.slice(2)); } + if (this.added[content]) { return; } + this.added[content] = true; + // If we have not added the files for this mojit, we should add + // them inline now. if (('css' === type) && isInline(content)) { - if (! YUI._mojito._cache.compiled.css.inline.added) { - // If we have not added the files for this mojit, we should add them inline now. - // Create an empty object - YUI._mojito._cache.compiled.css.inline.added = {}; - } + // We can't do this on the server, because YUI._mojito._cache is + // a server-lifetime global, so it "tunnels" between requests. + if ('client' === this.context.runtime) { + if (!YUI._mojito._cache.compiled.css.inline.added) { + YUI._mojito._cache.compiled.css.inline.added = {}; + } - if (YUI._mojito._cache.compiled.css.inline.added[content]) { - // Looks like we've already added this to the DOM - return; + if (YUI._mojito._cache.compiled.css.inline.added[content]) { + // Looks like we've already added this to the DOM + return; + } + + YUI._mojito._cache.compiled.css.inline.added[ + content + ] = true; } - YUI._mojito._cache.compiled.css.inline.added[content] = true; - // Y.log('Inlining css for mojitType for the first time' + content, 'debug' , NAME); + // Y.log('Inlining css for mojitType for the first time' + + // content, 'debug' , NAME); type = 'blob'; - content = '<style type="text/css">\n' + YUI._mojito._cache.compiled.css.inline[content] + '</style>\n'; + content = '<style type="text/css">\n' + + YUI._mojito._cache.compiled.css.inline[content] + + '</style>\n'; - // Beware! "content" changes here. This is the actual CSS and not the URI of the CSS resource!!! + // Beware! "content" changes here. This is the actual CSS and + // not the URI of the CSS resource!!! if (this.added[content]) { return; } @@ -148,23 +185,32 @@

    ActionContextAddon  0.1.0

    if (!this.assets[location]) { this.assets[location] = {}; } + if (!this.assets[location][type]) { this.assets[location][type] = []; } + this.assets[location][type].push(content); }, - addAssets: function(assets) { - var location, type, content; - for(location in assets){ - if(assets.hasOwnProperty(location)){ - - for(type in assets[location]){ - if(assets[location].hasOwnProperty(type)){ - for(content in assets[location][type]){ - if(assets[location][type].hasOwnProperty(content)){ - this.addAsset(type, location, assets[location][type][content]); + /** + * + */ + addAssets: function(assets) { + var location, + type, + content; + + for (location in assets) { + if (assets.hasOwnProperty(location)) { + for (type in assets[location]) { + if (assets[location].hasOwnProperty(type)) { + for (content in assets[location][type]) { + if (assets[location][type]. + hasOwnProperty(content)) { + this.addAsset(type, location, + assets[location][type][content]); } } } @@ -173,52 +219,72 @@

    ActionContextAddon  0.1.0

    } }, + + /** + * + */ preLoadImage: function(url) { var img; - if(typeof document !== 'undefined'){ + + if (typeof document !== 'undefined') { img = new Image(); img.src = url; } }, + + /** + * + */ preLoadImages: function(urls) { var i; - for(i in urls) { + + for (i in urls) { if (urls.hasOwnProperty(i)) { this.preLoadImage(urls[i]); } } }, - - getUrl: function(path){ - return this.assetsRoot+'/'+path; + + + /** + * + */ + getUrl: function(path) { + return this.assetsRoot + '/' + path; }, + + /** + * + */ mixAssets: function(to, from) { return Y.mojito.util.metaMerge(to, from); }, - getAssets: function(){ + + /** + * + */ + getAssets: function() { // MUST have some dedup code here return this.assets; }, - mergeMetaInto: function(meta){ + + /** + * + */ + mergeMetaInto: function(meta) { this.mixAssets(meta.assets, this.assets); } }; - isInline = function(id) { - return YUI._mojito._cache - && YUI._mojito._cache.compiled - && YUI._mojito._cache.compiled.css - && YUI._mojito._cache.compiled.css.inline - && YUI._mojito._cache.compiled.css.inline[id]; - }; - Y.mojito.addons.ac.assets = AssetsAcAddon; -}, '0.1.0', {requires: ['mojito-util']}); +}, '0.3.0', {requires: [ + 'mojito-util' +]});
    @@ -243,10 +309,19 @@

    Classes

  • Analytics.common
  • Assets.common
  • Carrier.common
  • +
  • Composite.common
  • +
  • Config.common
  • +
  • Cookie.client
  • +
  • Cookie.server
  • Deploy.server
  • Device.common
  • +
  • Http.server
  • I13n.server
  • +
  • Intl.common
  • Meta.common
  • +
  • Params.common
  • +
  • Partial.common
  • +
  • Url.common
  • @@ -254,14 +329,25 @@

    Classes

    --> @@ -279,7 +365,7 @@

    Files

    diff --git a/docs/api/assets/api.css b/docs/api/assets/api.css index 5468b2a41..477da2d22 100644 --- a/docs/api/assets/api.css +++ b/docs/api/assets/api.css @@ -7,9 +7,10 @@ a:link { color: #003399; } a:visited { color: #003399;} #doc3 #hd { margin-bottom:1em; position: relative; zoom: 1; } -#doc3 #hd h1 { color: #545454; font-size: 170%; padding: 0px 0 8px 150px; background: url(yui.png) 15px 9px no-repeat; height: 60px; font-weight: bold; } -#doc3 #hd h1 a { position: relative; top: 14px; } -#doc3 #hd a { text-decoration: none; color: black; } +#doc3 #hd h1 { color: #545454; font-size: 170%; padding: 0px 0 8px 150px; background: url(mojito-logo-white-bkg.png) 15px 9px no-repeat; height: 60px; font-weight: bold;} +#doc3 #hd h1 a { position: relative; top: 20px; } +#doc3 #hd a { text-decoration: none; } +#doc3 #hd h1 a { text-decoration: none; color: white; opacity: 0.0; } #doc3 #hd h3 { background: #98AAB1; background-image: url(bg_hd.gif); color: #000; font-size: 100%; padding: 4px 10px; margin: 0 0 7px 0; border: 1px solid #98AAB1; diff --git a/docs/api/assets/mojito-logo-white-bkg.png b/docs/api/assets/mojito-logo-white-bkg.png new file mode 100644 index 000000000..4050cc1fb Binary files /dev/null and b/docs/api/assets/mojito-logo-white-bkg.png differ diff --git a/docs/api/carrier.server.js.html b/docs/api/carrier.server.js.html index 3ac6fd5a6..eaead8a8a 100644 --- a/docs/api/carrier.server.js.html +++ b/docs/api/carrier.server.js.html @@ -2,21 +2,21 @@ - API: ActionContextAddon carrier.server.js (YUI Library) + Mojito API: ActionContextAddon carrier.server.js ( - - + + - - + +
    -

    mojito

    -

    ActionContextAddon  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito > ActionContextAddon @@ -48,10 +48,18 @@

    ActionContextAddon  0.1.0

    #doc3 .classopts { display:none; }
    /*
    -* Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    -*/
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
    + */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-carrier-addon', function(Y, NAME) {
     
    @@ -61,9 +69,8 @@ 

    ActionContextAddon  0.1.0

    * @class Carrier.common */ function CarrierAddon(command, adapter, ac) { - var req, - self = this; + my = this; this._ac = ac; this.command = command; @@ -73,16 +80,15 @@

    ActionContextAddon  0.1.0

    if (req) { // Set carrier accessor - Object.defineProperty(ac, "carrier", - { - get : function() { + Object.defineProperty(ac, 'carrier', { + get: function() { if (req.carrier) { return req.carrier; } else { - return self; + return my; } }, - set : function() { + set: function() { }, configurable: true }); @@ -92,18 +98,17 @@

    ActionContextAddon  0.1.0

    CarrierAddon.prototype = { - // Intentionally commented out in order to make it instantiable on demand + // Intentionally commented out make it instantiable on demand. //namespace: 'carrier' /** * Returns the attribute of the catalog for the current carrier used for * this request. - * - * @method get - * @param attribute {String} - The name of the catalog attribute e.g "ticker". - * @returns value + * @param {string} attribute The name of the catalog attribute e.g + * "ticker". + * @return {object} The catalog attribute value. */ - get : function() { + get: function() { //TODO: make an RPC call. } }; @@ -112,7 +117,9 @@

    ActionContextAddon  0.1.0

    Y.mojito.addons.ac.carrier = CarrierAddon; -}, '0.1.0', {requires: [ 'mojito' ]}); +}, '0.3.0', {requires: [ + 'mojito' +]});
    @@ -137,10 +144,19 @@

    Classes

  • Analytics.common
  • Assets.common
  • Carrier.common
  • +
  • Composite.common
  • +
  • Config.common
  • +
  • Cookie.client
  • +
  • Cookie.server
  • Deploy.server
  • Device.common
  • +
  • Http.server
  • I13n.server
  • +
  • Intl.common
  • Meta.common
  • +
  • Params.common
  • +
  • Partial.common
  • +
  • Url.common
  • @@ -148,14 +164,25 @@

    Classes

    --> @@ -173,7 +200,7 @@

    Files

    diff --git a/docs/api/classmap.js b/docs/api/classmap.js index 516d749bf..f07792127 100644 --- a/docs/api/classmap.js +++ b/docs/api/classmap.js @@ -1,4 +1,4 @@ -YAHOO.env.classMap = {"Partial.common": "MojitoServer", "Meta.common": "ActionContextAddon", "OutputHandler": "MojitoServer", "I13n.server": "ActionContextAddon", "OutputAdapter.common": "ActionContextAddon", "Url.common": "MojitoServer", "Y.mojito.MojitProxy": "MojitoClient", "Y.mojito.MojitoDispatcher": "MojitoClient", "Intl.common": "MojitoServer", "Deploy.server": "ActionContextAddon", "Cookie.client": "MojitoServer", "MojitoServer": "MojitoServer", "Y.mojito.ActionContext": "ActionContext", "Y.mojito.lib.REST": "CommonLibs", "Http.server": "MojitoServer", "MuAdapterClient": "MojitoServer", "Y.mojito.Client": "MojitoClient", "Cookie.server": "MojitoServer", "Y.mojito.lib.MojitoDispatcher": "CommonLibs", "Device.common": "ActionContextAddon", "Params.common": "MojitoServer", "Composite.common": "MojitoServer", "Config.common": "MojitoServer", "Assets.common": "ActionContextAddon", "Carrier.common": "ActionContextAddon", "Analytics.common": "ActionContextAddon", "ServerStore": "MojitoServer", "MuAdapterServer": "MojitoServer"}; +YAHOO.env.classMap = {"Partial.common": "ActionContextAddon", "Meta.common": "ActionContextAddon", "OutputHandler": "MojitoServer", "I13n.server": "ActionContextAddon", "OutputAdapter.common": "ActionContextAddon", "Url.common": "ActionContextAddon", "Y.mojito.MojitoDispatcher": "MojitoClient", "MojitProxy": "MojitoClient", "Intl.common": "ActionContextAddon", "ResourceStore.server": "MojitoServer", "Deploy.server": "ActionContextAddon", "Composite.common": "ActionContextAddon", "Cookie.client": "ActionContextAddon", "MojitoServer": "MojitoServer", "Y.mojito.lib.REST": "CommonLibs", "Http.server": "ActionContextAddon", "MuAdapterClient": "ActionContextAddon", "Y.mojito.Client": "MojitoClient", "Cookie.server": "ActionContextAddon", "Device.common": "ActionContextAddon", "MojitoDispatcher": "ActionContext", "Params.common": "ActionContextAddon", "ActionContext": "ActionContext", "Config.common": "ActionContextAddon", "Assets.common": "ActionContextAddon", "Carrier.common": "ActionContextAddon", "Analytics.common": "ActionContextAddon", "MuAdapterServer": "ActionContextAddon"}; YAHOO.env.resolveClass = function(className) { var a=className.split('.'), ns=YAHOO.env.classMap; diff --git a/docs/api/composite.common.js.html b/docs/api/composite.common.js.html index e69d64aef..b18f46062 100644 --- a/docs/api/composite.common.js.html +++ b/docs/api/composite.common.js.html @@ -2,23 +2,23 @@ - API: MojitoServer composite.common.js (YUI Library) + Mojito API: ActionContextAddon composite.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > composite.common.js (source view) @@ -48,14 +48,66 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-composite-addon', function(Y, NAME) {
     
    -   /**
    +    function AdapterBuffer(buffer, id, callback) {
    +        this.buffer = buffer;
    +        this.id = id;
    +        this.callback = callback;
    +        this.__meta = [];
    +    }
    +
    +
    +    AdapterBuffer.prototype = {
    +
    +        done: function(data, meta) {
    +            this.buffer[this.id].meta = meta;
    +            this.buffer[this.id].data += data;
    +            this.buffer.__counter__ -= 1;
    +            if (this.buffer.__counter__ === 0) {
    +                // TODO: Check why this can be called more than once.
    +                this.callback();
    +            }
    +        },
    +
    +
    +        flush: function(data, meta) {
    +            this.buffer[this.id].meta = meta;
    +            this.buffer[this.id].data += data;
    +        },
    +
    +
    +        error: function(err) {
    +            Y.log("Error executing child mojit at '" + this.id + "':", 'error',
    +                    NAME);
    +            if (err.message) {
    +                Y.log(err.message, 'error', NAME);
    +            } else {
    +                Y.log(err, 'error', NAME);
    +            }
    +            if (err.stack) {
    +                Y.log(err.stack, 'error', NAME);
    +            }
    +            // Pass back some empty data so we don't fail the composite
    +            this.done('');
    +        }
    +    };
    +
    +
    +    /**
         * <strong>Access point:</strong> <em>ac.composite.*</em>
         * Provides methods for working with many Mojits.
         * @class Composite.common
    @@ -67,13 +119,16 @@ 

    MojitoServer  0.1.0

    this.adapter = adapter; } + Addon.prototype = { namespace: 'composite', /** - * Automatically dispatches all the children of this mojit and collects their executed values into the view - * template, keyed by the child's name within the mojit's configuration. For example, given the mojit spec: + * Automatically dispatches all the children of this mojit and collects + * their executed values into the view template, keyed by the child's + * name within the mojit's configuration. For example, given the mojit + * spec: * * <pre> @@ -91,11 +146,11 @@

    MojitoServer  0.1.0

    } } } -} + } </pre> * And given the view template: <pre> -&lt;div id=&quot;{{mojit_uuid}}&quot;&gt; +&lt;div id=&quot;{{mojit_view_id}}&quot;&gt; &lt;h1&gt;{{title}}&lt;/h1&gt; &lt;div class=&quot;fooslot&quot;&gt; {{{foo}}} @@ -113,15 +168,14 @@

    MojitoServer  0.1.0

    template: { title: 'Hello there' } // for the view only }); } -}; + }; </pre> - * This will execute the child intances of the "FooMojit" and "BarMojit", returning their rendered values into - * the parent's view template, thus rendering the full parent view including the children. - * + * This will execute the child intances of the "FooMojit" and + * "BarMojit", returning their rendered values into the parent's view + * template, thus rendering the full parent view including the children. * All the parent parameters are passed along to children. - * - * @method done - * @param {object} opts The configuration object to be used. <em>template<em> can be used to provide additional + * @param {object} opts The configuration object to be used. + * <em>template<em> can be used to provide additional * view template values. */ done: function(opts) { @@ -135,16 +189,19 @@

    MojitoServer  0.1.0

    template = opts.template || {}; if (!children || Y.Object.size(children) === 0) { - throw new Error("Cannot run composite mojit children because there are no children defined in the composite mojit spec."); + throw new Error('Cannot run composite mojit children because' + + ' there are no children defined in the' + + ' composite mojit spec.'); } - this.execute(cfg, function(data, meta){ + this.execute(cfg, function(data, meta) { var merged = Y.merge(template, data); ac.done(merged, meta); }, this); }, + /** * This method requires an explicit config object and returns * a RMP compliant object via a callback. @@ -168,7 +225,7 @@

    MojitoServer  0.1.0

    } }, assets: {} -} + } </pre> * * The "callback" is an object containg the child slots with its @@ -178,18 +235,17 @@

    MojitoServer  0.1.0

    callback({ slot-1: <string>, slot-2: <string> -}, -{ + }, + { http: {} assets: {} -}) + }) </pre> * - * @method execute - * @param {object} cfg The configuration object to be used - * @param {function} cb The callback that will be called + * @param {object} cfg The configuration object to be used. + * @param {function} cb The callback that will be called. */ - execute: function(cfg, cb){ + execute: function(cfg, cb) { var ac = this.ac, buffer = {}, @@ -200,84 +256,98 @@

    MojitoServer  0.1.0

    // check to ensure children is an Object, not an array if (Y.Lang.isArray(cfg.children)) { - throw new Error("Cannot process children in the format of an array. 'children' must be an object."); + throw new Error('Cannot process children in the format of an' + + ' array. \'children\' must be an object.'); } meta.children = cfg.children; - - buffer.__counter__ = Y.Object.size(cfg.children); - - this._dispatchChildren(cfg.children, this.command, buffer, function() { - var name; - // Reference the data we want from the "buffer" into our "content" obj - // Also merge the meta we collected - for(name in buffer){ - if(buffer.hasOwnProperty(name) && name !== '__counter__'){ - content[name] = buffer[name].data || ''; + buffer.__counter__ = Y.Object.size(cfg.children); - if (buffer[name].meta) { - meta = Y.mojito.util.metaMerge(meta, buffer[name].meta); + this._dispatchChildren(cfg.children, this.command, buffer, + function() { + var name; + // Reference the data we want from the "buffer" into our + // "content" obj Also merge the meta we collected. + for (name in buffer) { + if (buffer.hasOwnProperty(name) && + name !== '__counter__') { + content[name] = buffer[name].data || ''; + + if (buffer[name].meta) { + meta = Y.mojito.util.metaMerge(meta, + buffer[name].meta); + } } } - } - // Mix in the assets given via the config - if(cfg.assets){ - if (! meta.assets) { - meta.assets = {}; + // Mix in the assets given via the config + if (cfg.assets) { + if (!meta.assets) { + meta.assets = {}; + } + ac.assets.mixAssets(meta.assets, cfg.assets); } - ac.assets.mixAssets(meta.assets, cfg.assets); - } - cb(content, meta); - }); + cb(content, meta); + }); }, - _dispatchChildren: function(children, command, buffer, callback){ + + _dispatchChildren: function(children, command, buffer, callback) { //Y.log('_dispatchChildren()', 'debug', NAME); var childName, child, - childAdapter; + childAdapter, + newCommand; // Process deferred children before dispatching Y.Object.each(children, function(child, name) { - // first off, check to see if this child's execution should be deferred + // first off, check to see if this child's execution should be + // deferred if (child.defer) { - // it doesn't make sense to have a deferred child with a proxy, because the defer means to proxy it + // it doesn't make sense to have a deferred child with a + // proxy, because the defer means to proxy it // through the LazyLoad mojit if (Y.Lang.isObject(child.proxy)) { - throw new Error("Cannot specify a child mojit spec with both 'defer' and 'proxy' configurations, because 'defer' assumes a 'proxy' to the LazyLoad mojit."); + throw new Error('Cannot specify a child mojit spec' + + ' with both \'defer\' and \'proxy\'' + + ' configurations, because \'defer\'' + + ' assumes a \'proxy\' to the LazyLoad' + + ' mojit.'); } - // aha! that means we will give it a proxy to the LazyLoad mojit, which will handle its - // lazy execution on the client. + // aha! that means we will give it a proxy to the LazyLoad + // mojit, which will handle lazy execution on the client. child.proxy = { type: 'LazyLoad' }; } if (Y.Lang.isObject(child.proxy)) { - // found a proxy, replace the child with the proxy and shove the child to proxy into it + // found a proxy, replace the child with the proxy and shove + // the child to proxy into it children[name] = child.proxy; delete child.proxy; - if (! children[name].config) { + if (!children[name].config) { children[name].config = {}; } - // remove any defer or proxy flags so it doesn't reload infinitely + // remove any defer or proxy flags so it doesn't reload + // infinitely child.proxy = undefined; child.defer = false; children[name].config.proxied = child; } }); - for(childName in children){ + for (childName in children) { if (children.hasOwnProperty(childName)) { child = children[childName]; // Create a buffer for the child buffer[childName] = {name: childName, data: '', meta: {}}; - // Make a new "command" that works in the context of this composite - var newCommand = { + // Make a new "command" that works in the context of this + // composite + newCommand = { instance: child, // use action in child spec or default to index action: child.action || 'index', @@ -285,7 +355,8 @@

    MojitoServer  0.1.0

    params: child.params || command.params }; - childAdapter = new AdapterBuffer(buffer, childName, callback); + childAdapter = new AdapterBuffer(buffer, childName, + callback); childAdapter = Y.mix(childAdapter, this.adapter); this.dispatch(newCommand, childAdapter); @@ -294,46 +365,12 @@

    MojitoServer  0.1.0

    } }; - function AdapterBuffer(buffer, id, callback){ - this.buffer = buffer; - this.id = id; - this.callback = callback; - this.__meta = []; - } - - AdapterBuffer.prototype = { - - done: function(data, meta) { - this.buffer[this.id].meta = meta; - this.buffer[this.id].data+= data; - if(--this.buffer.__counter__ === 0){ - this.callback(); // TODO MATT LOWER-PRIORITY: Check why this can be called more than once - } - }, - - flush: function(data, meta) { - this.buffer[this.id].meta = meta; - this.buffer[this.id].data+= data; - }, - - error: function(err) { - Y.log("Error executing child mojit at '" + this.id + "':", 'error', NAME); - if (err.message) { - Y.log(err.message, 'error', NAME); - } else { - Y.log(err, 'error', NAME); - } - if (err.stack) { - Y.log(err.stack, 'error', NAME); - } - // Pass back some empty data so we don't fail the composite - this.done(''); - } - }; - Y.mojito.addons.ac.composite = Addon; -}, '0.1.0', {requires: ['mojito-util', 'mojito-params-addon']}); +}, '0.3.0', {requires: [ + 'mojito-util', + 'mojito-params-addon' +]});
    @@ -345,23 +382,29 @@

    MojitoServer  0.1.0

    Modules

    diff --git a/docs/api/config.common.js.html b/docs/api/config.common.js.html index 0ed3734ed..b87bdb1d6 100644 --- a/docs/api/config.common.js.html +++ b/docs/api/config.common.js.html @@ -2,23 +2,23 @@ - API: MojitoServer config.common.js (YUI Library) + Mojito API: ActionContextAddon config.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > config.common.js (source view) @@ -48,13 +48,42 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-config-addon', function(Y, NAME) {
     
    +    function extract(bag, key, def) {
    +        if (!key) {
    +            return bag || {};
    +        }
    +
    +        var keys = key.split('.'),
    +            cur = bag,
    +            i;
    +
    +        for (i = 0; i < keys.length; i += 1) {
    +            if (cur[keys[i]]) {
    +                cur = cur[keys[i]];
    +            } else {
    +                return def;
    +            }
    +        }
    +
    +        return cur;
    +    }
    +
    +
         /**
          * <strong>Access point:</strong> <em>ac.config.*</em>
          * Provides access to the Mojits configuration
    @@ -65,56 +94,42 @@ 

    MojitoServer  0.1.0

    this._def = command.instance.definition; } + Addon.prototype = { namespace: 'config', /** * Access config values. - * @method get - * @param {String} key A period separated key path to look for i.e. "get.my.value" - * @param {Object|Array|String} def The default value to use if no match was found - * @return {Object|Array|String} + * @param {String} key A period separated key path to look for i.e. + * "get.my.value". + * @param {Object|Array|String} def The default value to use if no match + * was found. + * @return {Object|Array|String} The requested configuration value. */ get: function(key, def) { return extract(this._config, key, def); }, + /** * Access definition values. - * @param {String} key A period separated key path to look for i.e. "get.my.value" - * @param {Object|Array|String} def The default value to use if no match was found - * @return {Object|Array|String} + * @param {String} key A period separated key path to look for i.e. + * "get.my.value". + * @param {Object|Array|String} def The default value to use if no match + * was found. + * @return {Object|Array|String} The requested definition values. */ getDefinition: function(key, def) { return extract(this._def, key, def); } - }; - function extract(bag, key, def) { - if(!key){ - return bag || {}; - } - - var keys = key.split('.'), - cur = bag, - i; - - for(i=0; i < keys.length; i++){ - if(cur[keys[i]]){ - cur = cur[keys[i]]; - }else{ - return def; - } - } - - return cur; - } - Y.mojito.addons.ac.config = Addon; -}, '0.1.0', {requires: ['mojito']}); +}, '0.3.0', {requires: [ + 'mojito' +]});
    @@ -126,23 +141,29 @@

    MojitoServer  0.1.0

    Modules

    diff --git a/docs/api/controller-context.common.js.html b/docs/api/controller-context.common.js.html index 6b680b0b2..8a668ba4d 100644 --- a/docs/api/controller-context.common.js.html +++ b/docs/api/controller-context.common.js.html @@ -2,23 +2,23 @@ - API: MojitoClient controller-context.common.js (YUI Library) + Mojito API: ActionContext controller-context.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoClient  0.1.0

    +

    mojito

    +

    ActionContext  0.3.0

    mojito - > MojitoClient + > ActionContext > controller-context.common.js (source view) @@ -48,94 +48,128 @@

    MojitoClient  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     YUI.add('mojito-controller-context', function(Y, NAME) {
     
    -    function ControllerContext (opts) {
    +    function ControllerContext(opts) {
             this.instance = opts.instance;
             this.dispatch = opts.dispatch;
             this.store = opts.store;
             this.Y = opts.Y;
    -        this.shareYUIInstance = opts.appShareYUIInstance && this.instance.shareYUIInstance; 
    +        this.shareYUIInstance = opts.appShareYUIInstance &&
    +            this.instance.shareYUIInstance;
             this.init();
         }
     
    +
         ControllerContext.prototype = {
     
             init: function() {
                 var error,
    +                // Not really an instance...more like constructor options...see
    +                // controller.init() call below.
                     instance = this.instance,
                     controller,
                     shareYUIInstance = this.shareYUIInstance,
    -
    -                // Y.mojito.controller for legacy, multi-instance. Y.mojito.controllers for shared instance
    -                c = this.Y.mojito.controller || this.Y.mojito.controllers[instance.controllerModuleName];
    +                // Y.mojito.controller for legacy, multi-instance.
    +                // Y.mojito.controllers for shared instance
    +                c = this.Y.mojito.controller ||
    +                    this.Y.mojito.controllers[instance.controllerModuleName];
     
                 if (!Y.Lang.isObject(c)) {
    -                error = new Error("Mojit controller prototype is not an object! (mojit id:'" + instance.id + "')");
    +                error = new Error('Mojit controller prototype is not an' +
    +                    ' object! (mojit id: \'' + instance.id + '\')');
    +
    +                // TODO: change this to a more appropriate error code.
                     error.code = 404;
                     throw error;
                 }
     
    -            // we make a controller instance by using the heir() function, this gives us proper
    -            // function scope within the controller actions
    +            // we make a controller instance by using the heir() function, this
    +            // gives us proper function scope within the controller actions
                 controller = this.controller = Y.mojito.util.heir(c);
     
                 if (Y.Lang.isFunction(controller.init)) {
    +                // Use the instance data which isn't really an instance to
    +                // provide construction parameters for the controller init().
                     controller.init(instance.config);
                 }
     
    -            // mix in any (new) actions
    +            // mix in any (new) actions (the actions namespace here would be
    +            // populated by the resource store...but currently unused? Could
    +            // this be replaced by light inheritance to the controllers here).
                 Y.Object.each(this.Y.mojito.actions, function(action, actionName) {
    -                this.Y.log('mixing action "' + actionName + '" into controller...', 'debug', NAME);
    +                this.Y.log('mixing action \'' + actionName +
    +                    '\' into controller...', 'debug', NAME);
                     controller[actionName] = function() {
                         action.apply(controller, arguments);
                     };
                 });
     
    -            // stash the models this controller has available to be later attache to the
    -            // ActionContext
    +            // stash the models this controller has available to be later
    +            // attached to the ActionContext
                 this.models = {};
     
                 Y.Object.each(this.Y.mojito.models, function(model, modelName) {
     
    -                if (!shareYUIInstance || (instance.modelYUIModuleNames && instance.modelYUIModuleNames[modelName])) {
    +                if (!shareYUIInstance || (instance.modelYUIModuleNames &&
    +                        instance.modelYUIModuleNames[modelName])) {
     
    +                    // TODO: Why? There's no particular reason to inherit here.
                         var modelInstance = Y.mojito.util.heir(model);
    -    
    +
                         if (Y.Lang.isFunction(modelInstance.init)) {
    +                        // NOTE that we use the same config here that we use to
    +                        // config the controller...so the 'instance.config' data
    +                        // is feeding both types.
                             modelInstance.init(instance.config);
                         }
    -
                         this.models[modelName] = modelInstance;
                     }
    -
                 }, this);
    -
             },
     
    +
             invoke: function(command, adapter) {
     
    -            this.Y.log('controller context invoke() for ' + this.instance.guid, 'mojito', 'qeperf');
    +            this.Y.log('controller context invoke() for ' +
    +                this.instance.instanceId, 'mojito', 'qeperf');
     
                 var instance = this.instance,
    +                config = command.instance.config,
                     // this is the action that will be executed
                     action = command.action,
                     ac;
    -            // replace the non-expanded command instance with the proper instance, that was already
    -            // expanded when the controller context was created
    +
    +            // replace the non-expanded command instance with the proper
    +            // instance, that was already expanded when the controller context
    +            // was created
    +
    +            // TODO: This may not be necessary...we did this in dispatch().
                 command.instance = instance;
     
    +            // however! we want to use the most recent config, not the cached
    +            // config, because that can change between action executions!
    +            command.instance.config = config;
    +
                 // if there is no action, make 'index' the default
    -            if (! command.action) {
    +            // TODO: This may not be necessary...we did this in dispatch().
    +            if (!command.action) {
                     // use instance config for default action or 'index'
                     command.action = instance.action || 'index';
                 }
     
                 try {
    -                // TODO ac var is here to appease jslint. Should AC not
    -                // self-execute in constructor?
    +                // Note: ac var is here to appease jslint.
                     ac = new this.Y.mojito.ActionContext({
                         command: command,
                         controller: this.controller,
    @@ -144,26 +178,35 @@ 

    MojitoClient  0.1.0

    adapter: adapter, store: this.store }); - } - catch(err) { + + // TODO: uncomment once above issue is repaired. + // ac.invoke(command, adapter); // do it this way ;) + } catch (err) { if (adapter.error) { adapter.error(err); - } - else { - this.Y.log('WARNING!! Uncaught error from dispatch on instance "' + (instance.id || '@'+instance.type) + '"', 'error', NAME); + } else { + this.Y.log('WARNING!! Uncaught error from dispatch on' + + ' instance \'' + (instance.id || '@' + instance.type) + + '\'', 'error', NAME); this.Y.log(err.message, 'error', NAME); this.Y.log(err.stack, 'error', NAME); } + // TODO: should we be rethrowing the error here? We log but we + // don't ensure callers know...but then again dispatch() may + // need this level of isolation. } - this.Y.mojito.perf.mark('mojito', 'core_dispatch_end['+(instance.id || '@'+instance.type)+':'+action+']'); + this.Y.mojito.perf.mark('mojito', 'core_dispatch_end[' + + (instance.id || '@' + instance.type) + ':' + action + ']'); } - }; Y.mojito.ControllerContext = ControllerContext; -}, '0.1.0', {requires: ['mojito-action-context', 'mojito-util']}); +}, '0.3.0', {requires: [ + 'mojito-action-context', + 'mojito-util' +]});
    @@ -174,10 +217,10 @@

    MojitoClient  0.1.0

    @@ -185,8 +228,7 @@

    Modules

    @@ -194,18 +236,11 @@

    Classes

    --> @@ -223,7 +258,7 @@

    Files

    diff --git a/docs/api/controller.common.js.html b/docs/api/controller.common.js.html index 157f2126b..30493bf95 100644 --- a/docs/api/controller.common.js.html +++ b/docs/api/controller.common.js.html @@ -2,23 +2,23 @@ - API: MojitoServer controller.common.js (YUI Library) + Mojito API: CommonLibs controller.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > MojitoServer + > CommonLibs > controller.common.js (source view) @@ -48,8 +48,16 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true*/
    +/*global YUI*/
    +
    +
     YUI.add('LazyLoad', function(Y) {
     
         Y.mojito.controller = {
    @@ -58,10 +66,11 @@ 

    MojitoServer  0.1.0

    * Initially, renders a bar node */ index: function(ac) { - // TODO: allow users to provide the loading content + // TODO: allow users to provide the loading content. ac.done({content: 'Loading...'}); }, + /* * binder calls this to execute the lazy-mojit */ @@ -77,13 +86,15 @@

    MojitoServer  0.1.0

    meta.http.headers['content-type'] = 'application/json'; // and we don't want the children delete meta.children; - ac.done(JSON.stringify(data), meta); + ac.done(Y.JSON.stringify(data), meta); }); } - }; -}, '0.0.1', {requires: ['mojito']}); +}, '0.0.1', {requires: [ + 'mojito', + 'json' +]});
    @@ -96,25 +107,16 @@

    Modules

    @@ -122,28 +124,27 @@

    Classes

    --> @@ -161,7 +162,7 @@

    Files

    diff --git a/docs/api/controller.server.js.html b/docs/api/controller.server.js.html index 9f0e70153..cc156aa39 100644 --- a/docs/api/controller.server.js.html +++ b/docs/api/controller.server.js.html @@ -2,23 +2,23 @@ - API: MojitoServer controller.server.js (YUI Library) + Mojito API: CommonLibs controller.server.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > MojitoServer + > CommonLibs > controller.server.js (source view) @@ -48,82 +48,120 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    -YUI.add('DaliProxy', function(Y, NAME) {
     
    -    Y.mojito.controllers[NAME] = {
     
    -        init: function(config) {
    -            this.config = config;
    -        },
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
     
    -        index: function(ac) {
    -            var proxyCommand = ac.params.body('proxyCommand'),
    -                txId = ac.params.body('txId');
     
    -            if (! proxyCommand) {
    -                ac.error("Cannot execute DaliProxy mojit without a proxy command.");
    -                return;
    -            }
    +YUI.add('HTMLFrameMojit', function(Y, NAME) {
     
    -            if (txId === null || txId === undefined) { // can't use falsey cause txId might be 0
    -                ac.error("Cannot execute DaliProxy mojit without a transaction ID.");
    -                return;
    -            }
    +    var renderListAsHtmlAssets = function(list, type) {
    +        var i,
    +            data = '';
     
    -            // dispatch the command as the proxy
    -            ac._dispatch(proxyCommand, new RpcAdapter(ac, txId));
    +        if ('js' === type) {
    +            for (i = 0; i < list.length; i += 1) {
    +                data += '<script type="text/javascript" src="' +
    +                    list[i] + '"></script>\n';
    +            }
    +        } else if ('css' === type) {
    +            for (i = 0; i < list.length; i += 1) {
    +                data += '<link rel="stylesheet" type="text/css" href="' +
    +                    list[i] + '"/>\n';
    +            }
    +        } else if ('blob' === type) {
    +            for (i = 0; i < list.length; i += 1) {
    +                data += list[i] + '\n';
    +            }
    +        } else {
    +            Y.log('Unknown asset type "' + type + '". Skipped.', 'warn', NAME);
             }
     
    +        return data;
         };
     
    -    function RpcAdapter(ac, txId) {
    -        this.ac = ac;
    -        this.txId = txId;
    -        this.buffer = {
    -            data: '',
    -            meta: {}
    -        };
    -    }
     
    -    RpcAdapter.prototype = {
    +    Y.mojito.controllers[NAME] = {
     
    -        _updateBuffer: function(data, meta) {
    -            this.buffer.data = this.buffer.data + data;
    -            this.buffer.meta = Y.mojito.util.metaMerge(this.buffer.meta, meta);
    +        index: function(ac) {
    +            this.__call(ac);
             },
     
    -        flush: function (data, meta) {
    -            this._updateBuffer(data, meta);
    -        },
     
    -        done: function (data, meta) {
    -            var out, buffer = this.buffer;
    -            this._updateBuffer(data, meta);
    -            out = {
    -                resps: [{
    -                    txId: this.txId,
    -                    status: meta.http.code,
    -                    data: {
    -                        html: buffer.data,
    -                        // including the meta data for resolution on the client
    -                        meta: buffer.meta
    -                    }
    -                }]
    +        __call: function(ac) {
    +
    +            // Grab the "child" from the config an add it as the
    +            // only item in the "children" map.
    +            var child = ac.config.get('child'),
    +                cfg;
    +
    +            // Map the action to the child
    +            child.action = ac.action;
    +
    +            // Create a config object for the composite addon
    +            cfg = {
    +                children: {
    +                    child: child
    +                },
    +                assets: ac.config.get('assets')
                 };
    -            this.ac.done(out, 'json');
    -        },
     
    -        error: function(err) {
    -            this.ac.error(err);
    -        }
    +            Y.log('executing HTMLFrameMojit child', 'mojito', 'qeperf');
     
    -    };
    +            // Now execute the child as a composite
    +            ac.composite.execute(cfg, function(data, meta) {
    +
    +                // Make sure we have meta
    +                meta.http = meta.http || {};
    +                meta.http.headers = meta.http.headers || {};
    +
    +                // Make sure our Content-type is HTML
    +                meta.http.headers['content-type'] =
    +                    'text/html; charset="utf-8"';
    +
    +                // Set the default data
    +                data.title = ac.config.get('title') ||
    +                    'Powered by Mojito ' + Y.mojito.version;
    +                data.mojito_version = Y.mojito.version;
    +
    +                // Add all the assets we have been given to our local store
    +                ac.assets.addAssets(meta.assets);
     
    +                // If we are deploying to the client get all the assets required
    +                if (ac.config.get('deploy') === true) {
    +                    ac.deploy.constructMojitoClientRuntime(ac.assets,
    +                        meta.binders);
    +                }
     
    +                // Attach assets found in the "meta" to the page
    +                Y.Object.each(ac.assets.getAssets(), function(types, location) {
    +                    if (!data[location]) {
    +                        data[location] = '';
    +                    }
    +                    Y.Object.each(types, function(assets, type) {
    +                        data[location] += renderListAsHtmlAssets(assets, type);
    +                    });
    +                });
    +
    +                meta.view = {name: 'index'};
     
    -}, '0.1.0', {requires: ['mojito-http-addon', 'mojito-util']});
    +                Y.log('HTMLFrameMojit done()', 'mojito', 'qeperf');
    +
    +                ac.done(data, meta);
    +            });
    +        }
    +    };
    +
    +}, '0.3.0', {requires: [
    +    'mojito-assets-addon',
    +    'mojito-deploy-addon',
    +    'mojito-config-addon'
    +]});
     
    @@ -136,25 +174,16 @@

    Modules

    @@ -162,28 +191,27 @@

    Classes

    --> @@ -201,7 +229,7 @@

    Files

    diff --git a/docs/api/cookie.client.js.html b/docs/api/cookie.client.js.html index 33776cd47..74bd6b4d5 100644 --- a/docs/api/cookie.client.js.html +++ b/docs/api/cookie.client.js.html @@ -2,23 +2,23 @@ - API: MojitoServer cookie.client.js (YUI Library) + Mojito API: ActionContextAddon cookie.client.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > cookie.client.js (source view) @@ -48,17 +48,26 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true*/
    +/*global YUI*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-cookie-addon', function(Y, NAME) {
     
         /**
          * <strong>Access point:</strong> <em>ac.cookie.*</em>
    -     * This client-side cookie add-on allows you to easily use cookies. This API matches the YUI Cookie API exactly.
    -     * http://developer.yahoo.com/yui/3/api/Cookie.html
    +     * This client-side cookie add-on allows you to easily use cookies. This API
    +     * matches the YUI Cookie API exactly.
    +     * http://developer.yahoo.com/cocktails/mojito/3/api/Cookie.html
          * @class Cookie.client
          */
         function Addon(command, adapter, ac) {
    @@ -73,6 +82,7 @@ 

    MojitoServer  0.1.0

    'setSub', 'setSubs' ]; + Y.Array.each(cookieFns, function(fn) { this[fn] = function() { return Y.Cookie[fn].apply(Y.Cookie, arguments); @@ -80,15 +90,17 @@

    MojitoServer  0.1.0

    }, this); } - Addon.prototype = { + Addon.prototype = { namespace: 'cookie' - }; Y.mojito.addons.ac.cookie = Addon; -}, '0.1.0', {requires: ['cookie', 'mojito']}); +}, '0.3.0', {requires: [ + 'cookie', + 'mojito' +]});
    @@ -100,23 +112,29 @@

    MojitoServer  0.1.0

    Modules

    diff --git a/docs/api/cookie.server.js.html b/docs/api/cookie.server.js.html index 41d1929fa..d7b9f8961 100644 --- a/docs/api/cookie.server.js.html +++ b/docs/api/cookie.server.js.html @@ -2,23 +2,23 @@ - API: MojitoServer cookie.server.js (YUI Library) + Mojito API: ActionContextAddon cookie.server.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > cookie.server.js (source view) @@ -48,10 +48,18 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true*/
    +/*global YUI*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-cookie-addon', function(Y, NAME) {
     
    @@ -66,14 +74,15 @@ 

    MojitoServer  0.1.0

    this.ac = ac; } + Addon.prototype = { namespace: 'cookie', /** - * Returns the cookie for the given key, or all cookies if the key is not specified - * @method get - * @param {string} [optional] key The key to look for + * Returns the cookie value for the given key, or all cookies if the key is + * not specified. + * @param {string} [optional] key The key to look for. */ get: function(key) { if (key) { @@ -82,29 +91,30 @@

    MojitoServer  0.1.0

    return this.req.cookies; }, + /** * Set a cookie on the given key with the given value - * @method set - * @param {string} key The key to use - * @param {string} val The value that will be set + * @param {string} key The key to use. + * @param {string} val The value that will be set. */ set: function(key, val, opts) { var c = key + '=' + val; + opts = opts || {}; if (opts.expires) { - c = c + "; Expires=" + (new Date(opts.expires)).toUTCString(); + c = c + '; Expires=' + (new Date(opts.expires)).toUTCString(); } if (opts.path) { - c = c + "; Path=" + opts.path; + c = c + '; Path=' + opts.path; } if (opts.domain) { - c = c + "; Domain=" + opts.domain; + c = c + '; Domain=' + opts.domain; } if (opts.secure) { - c = c + "; Secure;"; + c = c + '; Secure;'; } if (opts.httpOnly) { - c = c + "; HttpOnly"; + c = c + '; HttpOnly'; } this.http.addHeader('Set-Cookie', c); } @@ -114,7 +124,10 @@

    MojitoServer  0.1.0

    Y.mojito.addons.ac.cookie = Addon; -}, '0.1.0', {requires: ['mojito', 'mojito-http-addon']}); +}, '0.3.0', {requires: [ + 'mojito', + 'mojito-http-addon' +]});
    @@ -126,23 +139,29 @@

    MojitoServer  0.1.0

    Modules

    diff --git a/docs/api/dali_bean.client-optional.js.html b/docs/api/dali_bean.client-optional.js.html index d0dcb73bc..b2d9d837a 100644 --- a/docs/api/dali_bean.client-optional.js.html +++ b/docs/api/dali_bean.client-optional.js.html @@ -2,23 +2,23 @@ - API: ActionContext dali_bean.client-optional.js (YUI Library) + Mojito API: CommonLibs dali_bean.client-optional.js ( - - + + - - + +
    -

    mojito

    -

    ActionContext  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > ActionContext + > CommonLibs > dali_bean.client-optional.js (source view) @@ -47,31 +47,46 @@

    ActionContext  0.1.0

    -
    YUI.add('dali-bean', function(Y) {
    -	
    -	function DaliBean(obj) {
    -
    -		DaliBean.superclass.constructor.call(this, {
    -			bubbles: true,
    -			emitFacade: true
    -		});
    -		
    -		Y.mix(this, obj);
    -		
    -		// make sure all events are published so parents that add themselves as targets
    -		// get called with the firing of the event. This prevents users of this class
    -		// having to manually call publish for each event they want to fire
    -		Y.Do.before(function() {
    -			this.publish(arguments[0].type || arguments[0]);
    -		}, this, "fire");
    -	}
    -	
    -	Y.extend(DaliBean, Y.EventTarget);
    -	
    -	Y.namespace('Dali');
    -	Y.Dali.Bean = DaliBean;
    -	
    -}, '1.6.3', {requires:['breg', 'oop', 'event-custom']});
    +
    /*
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
    + */
    +
    +
    +/*jslint anon:true, sloppy:true*/
    +/*global YUI*/
    +
    +
    +YUI.add('dali-bean', function(Y) {
    +
    +    function DaliBean(obj) {
    +        DaliBean.superclass.constructor.call(this, {
    +            bubbles: true,
    +            emitFacade: true
    +        });
    +
    +        Y.mix(this, obj);
    +
    +        // make sure all events are published so parents that add themselves as
    +        // targets get called with the firing of the event. This prevents users
    +        // of this class having to manually call publish for each event they
    +        // want to fire
    +        Y.Do.before(function(x) {
    +            this.publish(x.type || x);
    +        }, this, 'fire');
    +    }
    +
    +    Y.extend(DaliBean, Y.EventTarget);
    +
    +    Y.namespace('Dali');
    +    Y.Dali.Bean = DaliBean;
    +
    +}, '1.6.3', {requires: [
    +    'breg',
    +    'oop',
    +    'event-custom'
    +]});
     
    @@ -82,9 +97,9 @@

    ActionContext  0.1.0

    diff --git a/docs/api/deploy.server.js.html b/docs/api/deploy.server.js.html index abeb68fb1..58ce88427 100644 --- a/docs/api/deploy.server.js.html +++ b/docs/api/deploy.server.js.html @@ -2,21 +2,21 @@ - API: ActionContextAddon deploy.server.js (YUI Library) + Mojito API: ActionContextAddon deploy.server.js ( - - + + - - + +
    -

    mojito

    -

    ActionContextAddon  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito > ActionContextAddon @@ -48,20 +48,43 @@

    ActionContextAddon  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-deploy-addon', function(Y, NAME) {
     
         var fs = require('fs'),
    -        yuiFilter = 'min';
    +        yuiFilter = 'min',
    +        minify;
    +
     
    -    if(YUI._mojito && YUI._mojito.DEBUG){
    +    if (YUI._mojito && YUI._mojito.DEBUG) {
             yuiFilter = 'debug';
         }
     
    +
    +    // TODO: [Issue 64] improve this, it's a poor man's minify.
    +    // a. build minification into static handler?
    +    // b. build minification into prod-build script ?
    +    // c. build minification into server-start?
    +    minify = function(str) {
    +        // Remove comment blocks /* ... */ and
    +        // remove white space at the start of lines
    +        return str.replace(/\/\*[\s\S]*?\*\//g, '').
    +            replace(/^[ \t\r\n]+/gm, '');
    +    };
    +
    +
         /**
          * <strong>Access point:</strong> <em>ac.deploy.*</em>
          * Provides ability to create client runtime deployment HTML
    @@ -73,6 +96,7 @@ 

    ActionContextAddon  0.1.0

    this.ac = ac; } + Addon.prototype = { namespace: 'deploy', @@ -80,88 +104,156 @@

    ActionContextAddon  0.1.0

    /** * Declaration of store requirement. * @private - * @param rs {ResourceStore} + * @param {ResourceStore} rs The resource store instance. */ setStore: function(rs) { this.rs = rs; if (rs) { - Y.log('Initialized and activated with Resource Store', 'info', NAME); + Y.log('Initialized and activated with Resource Store', 'info', + NAME); } }, + /** * Builds up the browser Mojito runtime. - * @param assetHandler {AssetHandler} asset handler used to add scripts to the DOM under construction - * @param binderMap {object} information about the binders that will be deployed to the client + * @param {AssetHandler} assetHandler asset handler used to add scripts + * to the DOM under construction. + * @param {object} binderMap information about the binders that will be + * deployed to the client. */ constructMojitoClientRuntime: function(assetHandler, binderMap) { //Y.log('Constructing Mojito client runtime', 'debug', NAME); - + var store = this.rs, - context = this.ac.context, - appConfig = store.getAppConfig(context, 'definition'), - yuiConfig = { - lang: context.lang, - core: ['get', 'features', 'intl-base', 'yui-log', 'mojito', 'yui-later'], - bootstrap: false - }, - yuiModules, loader, yuiCombo, yuiJsUrl, yuiCssUrl, yuiJsUrlContains = {}, - guid, binder, - i, id, instances = {}, - clientConfig = { - context: context - }, + contextServer = this.ac.context, + appConfigServer = store.getAppConfig(contextServer, + 'definition'), + contextClient, + appConfigClient, + yuiConfig = {}, + yuiModules, + loader, + yuiCombo, + yuiJsUrls = [], + yuiCssUrls = [], + yuiJsUrlContains = {}, + viewId, + binder, + i, + id, + instances = {}, + clientConfig = {}, + usePrecomputed, + useOnDemand, + initialModuleList, initializer, // script for YUI initialization routeMaker, - type, module, path; + type, + module, + path, + pathToRoot; + + contextClient = Y.mojito.util.copy(contextServer); + contextClient.runtime = 'client'; + appConfigClient = store.getAppConfig(contextClient, 'definition'); + clientConfig.context = contextClient; + + if (appConfigClient.yui && appConfigClient.yui.config) { + yuiConfig = appConfigClient.yui.config; + } + yuiConfig.lang = contextServer.lang; // same as contextClient.lang + yuiConfig.core = yuiConfig.core || []; + yuiConfig.core = yuiConfig.core.concat( + ['get', 'features', 'intl-base', 'yui-log', 'mojito', + 'yui-later'] + ); // If we have a "base" for YUI use it - if (appConfig.yui && appConfig.yui.base) { - yuiConfig.base = appConfig.yui.base; + if (appConfigClient.yui && appConfigClient.yui.base) { + yuiConfig.base = appConfigClient.yui.base; yuiConfig.combine = false; } // If we know where yui "Loader" is tell YUI - if (appConfig.yui && appConfig.yui.loader) { - yuiConfig.loaderPath = appConfig.yui.loader; + if (appConfigClient.yui && appConfigClient.yui.loader) { + yuiConfig.loaderPath = appConfigClient.yui.loader; } - clientConfig.store = store.serializeClientStore(context, instances); + clientConfig.store = store.serializeClientStore(contextClient, + instances); + + usePrecomputed = appConfigServer.yui && + appConfigServer.yui.dependencyCalculations && (-1 !== + appConfigServer.yui.dependencyCalculations.indexOf( + 'precomputed' + )); + useOnDemand = appConfigServer.yui && + appConfigServer.yui.dependencyCalculations && (-1 !== + appConfigServer.yui.dependencyCalculations.indexOf( + 'ondemand' + )); + if (!usePrecomputed) { + useOnDemand = true; + } // Set the YUI URL to use on the client (This has to be done // before any other scripts are added) - if (appConfig.yui && appConfig.yui.url) { - yuiJsUrl = appConfig.yui.url; - // Since the user has given their own rollup of YUI library modules, we - // need some way of knowing which YUI library modules went into that rollup. - if (Y.Lang.isArray(appConfig.yui.urlContains)) { - for (i=0; i<appConfig.yui.urlContains.length; i++) { - yuiJsUrlContains[ appConfig.yui.urlContains[i] ] = true; + if (appConfigClient.yui && appConfigClient.yui.url) { + yuiJsUrls.push(appConfigClient.yui.url); + // Since the user has given their own rollup of YUI library + // modules, we need some way of knowing which YUI library + // modules went into that rollup. + if (Y.Lang.isArray(appConfigClient.yui.urlContains)) { + for (i = 0; i < appConfigClient.yui.urlContains.length; + i += 1) { + yuiJsUrlContains[appConfigClient.yui.urlContains[i]] = + true; } } - } - else { - yuiModules = [ 'yui' ]; + } else { + // YUI 3.4.1 doesn't have actual rollup files, so we need to + // specify all the parts directly. + yuiModules = ['yui-base']; + yuiJsUrlContains['yui-base'] = true; + yuiModules = ['yui']; yuiJsUrlContains.yui = true; - if (appConfig.yui && ('precomputed' !== appConfig.yui.dependencyCalculations)) { - yuiModules.push('loader'); - yuiJsUrlContains.loader = true; + if (useOnDemand) { + yuiModules.push('get'); + yuiJsUrlContains.get = true; + yuiModules.push('loader-base'); + yuiJsUrlContains['loader-base'] = true; + yuiModules.push('loader-rollup'); + yuiJsUrlContains['loader-rollup'] = true; + yuiModules.push('loader-yui3'); + yuiJsUrlContains['loader-yui3'] = true; + for (i = 0; i < store.store._fwConfig. + ondemandBaseYuiModules.length; i += 1) { + module = + store.store._fwConfig.ondemandBaseYuiModules[i]; + yuiModules.push(module); + yuiJsUrlContains[module] = true; + } } - if (appConfig.yui && appConfig.yui.extraModules) { - for (i=0; i<appConfig.yui.extraModules.length; i++) { - yuiModules.push(appConfig.yui.extraModules[i]); - yuiJsUrlContains[ appConfig.yui.extraModules[i] ] = true; + if (appConfigClient.yui && appConfigClient.yui.extraModules) { + for (i = 0; i < appConfigClient.yui.extraModules.length; + i += 1) { + yuiModules.push(appConfigClient.yui.extraModules[i]); + yuiJsUrlContains[ + appConfigClient.yui.extraModules[i] + ] = true; } } - for (guid in binderMap) { - if (binderMap.hasOwnProperty(guid)) { - binder = binderMap[guid]; + for (viewId in binderMap) { + if (binderMap.hasOwnProperty(viewId)) { + binder = binderMap[viewId]; for (module in binder.needs) { if (binder.needs.hasOwnProperty(module)) { path = binder.needs[module]; - // Anything we don't know about we'll assume is a YUI library module. - if (! store.fileFromStaticHandlerURL(path)) { + // Anything we don't know about we'll assume is + // a YUI library module. + if (!store.fileFromStaticHandlerURL(path)) { yuiModules.push(module); yuiJsUrlContains[module] = true; } @@ -170,22 +262,41 @@

    ActionContextAddon  0.1.0

    } } - loader = new Y.mojito.Loader(appConfig); + loader = new Y.mojito.Loader(appConfigClient); yuiCombo = loader.createYuiLibComboUrl(yuiModules, yuiFilter); - yuiJsUrl = yuiCombo.js; - yuiCssUrl = yuiCombo.css; + yuiJsUrls = yuiCombo.js; + yuiCssUrls = yuiCombo.css; } - this.addScript('top', yuiJsUrl); - if (yuiCssUrl) { - assetHandler.addCss(yuiCssUrl, 'top'); + for (i = 0; i < yuiJsUrls.length; i += 1) { + this.addScript('top', yuiJsUrls[i]); + } + // defaults to true if missing + if (!yuiConfig.hasOwnProperty('fetchCSS') || yuiConfig.fetchCSS) { + for (i = 0; i < yuiCssUrls.length; i += 1) { + assetHandler.addCss(yuiCssUrls[i], 'top'); + } } - for (guid in binderMap) { - if (binderMap.hasOwnProperty(guid)) { - binder = binderMap[guid]; + // add mojito bootstrap + // With "precomputed" the scripts are listed as binder dependencies + // and thus loaded that way. However, with "ondemand" we'll use + // the YUI loader which we haven't (yet) taught where to find the + // fw & app scripts. + if (useOnDemand) { + // add all framework-level and app-level code + this.addScripts('bottom', store.getYuiConfigFw('client', + contextClient).modules); + this.addScripts('bottom', store.getYuiConfigApp('client', + contextClient).modules); + } + + // add binders' dependencies + for (viewId in binderMap) { + if (binderMap.hasOwnProperty(viewId)) { + binder = binderMap[viewId]; for (module in binder.needs) { if (binder.needs.hasOwnProperty(module)) { - if (! yuiJsUrlContains[module]) { + if (!yuiJsUrlContains[module]) { this.addScript('bottom', binder.needs[module]); } } @@ -195,46 +306,61 @@

    ActionContextAddon  0.1.0

    clientConfig.binderMap = binderMap; - // TODO: [bug 4647802] Split the app config in to server client sections. + // TODO: [Issue 65] Split the app config in to server client + // sections. // we need the app config on the client for log levels (at least) clientConfig.appConfig = clientConfig.store.appConfig; - // TODO DREW -- decide if this is necessary, since clientConfig.store.mojits - // is currently unpopulated + // this is mainly used by html5app + pathToRoot = this.ac.http.getHeader('x-mojito-build-path-to-root'); + if (pathToRoot) { + clientConfig.pathToRoot = pathToRoot; + } + + // TODO -- decide if this is necessary, since + // clientConfig.store.mojits is currently unpopulated /* for (type in clientConfig.store.mojits) { for (i in clientConfig.store.mojits[type].yui.sorted) { module = clientConfig.store.mojits[type].yui.sorted[i]; - path = clientConfig.store.mojits[type].yui.sortedPaths[module]; + path = clientConfig.store.mojits[type].yui.sortedPaths[ + module]; this.scripts[path] = 'bottom'; } } */ - // HACK - /* Removed as fixed in store on 6/1 HACK(clientConfig); */ routeMaker = new Y.mojito.RouteMaker(clientConfig.store.routes); clientConfig.routes = routeMaker.getComputedRoutes(); delete clientConfig.store; - // HACK - initializer = "<script type=\"text/javascript\" >\n" - + " YUI_config = "+JSON.stringify(yuiConfig)+";\n" - + " YUI().use('*', function(Y) {\n" - + " window.YMojito = { client: new Y.mojito.Client(" + JSON.stringify(clientConfig, null, 2) + ") };\n" - + " });\n" - + "</script>\n"; + initialModuleList = "'*'"; + if (useOnDemand) { + initialModuleList = "'mojito-client'"; + } - // Add all the scripts we have collectged - assetHandler.addAssets(this.getScripts(appConfig.embedJsFilesInHtmlFrame)); + initializer = '<script type=\"text/javascript\" >\n' + + ' YUI_config = ' + JSON.stringify(yuiConfig) + ';\n' + + ' YUI().use(' + initialModuleList + ', function(Y) {\n' + + ' window.YMojito = { client: new Y.mojito.Client(' + + JSON.stringify(clientConfig, null, 2) + ') };\n' + + ' });\n' + + '</script>\n'; + + // Add all the scripts we have collected + assetHandler.addAssets( + this.getScripts(appConfigServer.embedJsFilesInHtmlFrame) + ); // Add the boot script assetHandler.addAsset('blob', 'bottom', initializer); }, - addScript: function(position, path){ + + addScript: function(position, path) { this.scripts[path] = position; }, + addScripts: function(position, modules) { var i; for (i in modules) { @@ -244,38 +370,43 @@

    ActionContextAddon  0.1.0

    } }, + /** - * TODO RIC: [bug 4647806] This can be made faster with a single for loop and caching + * TODO: [Issue 66] This can be made faster with a single for + * loop and caching. * * Note: A single SCRIPT tag containing all the JS on the pages is * slower than many SCRIPT tags (checked on iPad only). - * * @private - * @method getScripts - * @param {bool} embed - * @return {object} + * @param {bool} embed Should returned scripts be embedded in script + * tags. + * @return {object} An object containing script descriptors. */ - getScripts: function(embed){ - var i, x, assets = {}; - - var blob = { - type: 'blob', - position: 'bottom', - content: '' - }; + getScripts: function(embed) { + var i, + x, + assets = {}, + blob = { + type: 'blob', + position: 'bottom', + content: '' + }; // Walk over the scripts and check what we can do - for(i in this.scripts){ - if(this.scripts.hasOwnProperty(i)){ - if(embed && this.rs._staticURLs[i]){ - //blob.content+= fs.readFileSync(this.rs._staticURLs[i], 'utf8'); + for (i in this.scripts) { + if (this.scripts.hasOwnProperty(i)) { + if (embed && this.rs._staticURLs[i]) { + //blob.content+= fs.readFileSync(this.rs._staticURLs[i], + // 'utf8'); //delete this.scripts[i]; this.scripts[i] = { type: 'blob', position: 'bottom', - content: '<script type="text/javascript">'+HACK2(fs.readFileSync(this.rs._staticURLs[i], 'utf8'))+'</script>' + content: '<script type="text/javascript">' + + minify(fs.readFileSync(this.rs._staticURLs[i], + 'utf8')) + '</script>' }; - }else{ + } else { this.scripts[i] = { type: 'js', position: this.scripts[i], @@ -284,20 +415,22 @@

    ActionContextAddon  0.1.0

    } } } - - //blob.content = '<script type="text/javascript">'+blob.content+'</script>'; - //this.scripts[Y.guid()] = blob; + // Convert the scripts to the Assets format - for(x in this.scripts){ - if(this.scripts.hasOwnProperty(x)){ - if(!assets[this.scripts[x].position]){ + for (x in this.scripts) { + if (this.scripts.hasOwnProperty(x)) { + if (!assets[this.scripts[x].position]) { assets[this.scripts[x].position] = {}; } - if(!assets[this.scripts[x].position][this.scripts[x].type]){ - assets[this.scripts[x].position][this.scripts[x].type] = []; + if (!assets[this.scripts[x].position][this.scripts[x]. + type]) { + assets[this.scripts[x].position][this.scripts[x]. + type] = []; } - assets[this.scripts[x].position][this.scripts[x].type].push(this.scripts[x].content); + assets[this.scripts[x].position][this.scripts[x].type].push( + this.scripts[x].content + ); } } @@ -305,38 +438,13 @@

    ActionContextAddon  0.1.0

    } }; -/* Removed as fixed in store on 6/1 - // TODO DREW THINK ABOUT THIS: Remove all YUI3 refs from the config sent to the client - var HACK = function(conf){ - var name; - Y.Object.each(conf.store.mojits, function(mojit){ - for(name in mojit.views){ - if(name.indexOf('js/yui3')>=0){ - delete mojit.views[name]; - } - } - for(name in mojit.assets){ - if(name.indexOf('js/yui3')>=0){ - delete mojit.assets[name]; - } - } - }); - }; -*/ - // TODO [bug 4647810] unhack this: This is a poor man's minify - // a. build minification into static handler? - // b. build minification into prod-build script ? - // c. build minification into server-start? - var HACK2 = function(str){ - return str.replace(/\/\*[\s\S]*?\*\//g, '') // Remove comment blocks /* ... */ - .replace(/^[ \t\r\n]+/gm, ''); // Remove white space at the start of lines - }; - Y.mojito.addons.ac.deploy = Addon; -}, '0.1.0', { requires: [ - 'mojito-loader' -]} ); +}, '0.3.0', {requires: [ + 'mojito-loader', + 'mojito-util', + 'mojito-http-addon' +]});
    @@ -361,10 +469,19 @@

    Classes

  • Analytics.common
  • Assets.common
  • Carrier.common
  • +
  • Composite.common
  • +
  • Config.common
  • +
  • Cookie.client
  • +
  • Cookie.server
  • Deploy.server
  • Device.common
  • +
  • Http.server
  • I13n.server
  • +
  • Intl.common
  • Meta.common
  • +
  • Params.common
  • +
  • Partial.common
  • +
  • Url.common
  • @@ -372,14 +489,25 @@

    Classes

    --> @@ -397,7 +525,7 @@

    Files

    diff --git a/docs/api/device.server.js.html b/docs/api/device.server.js.html index 0a4d8b411..a23ffc5be 100644 --- a/docs/api/device.server.js.html +++ b/docs/api/device.server.js.html @@ -2,21 +2,21 @@ - API: ActionContextAddon device.server.js (YUI Library) + Mojito API: ActionContextAddon device.server.js ( - - + + - - + +
    -

    mojito

    -

    ActionContextAddon  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito > ActionContextAddon @@ -48,10 +48,18 @@

    ActionContextAddon  0.1.0

    #doc3 .classopts { display:none; }
    /*
    -* Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    -*/
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
    + */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-device-addon', function(Y, NAME) {
     
    @@ -61,9 +69,8 @@ 

    ActionContextAddon  0.1.0

    * @class Device.common */ function DeviceAddon(command, adapter, ac) { - var req, - self = this; + my = this; this._ac = ac; this.command = command; @@ -71,36 +78,32 @@

    ActionContextAddon  0.1.0

    req = ac.http.getRequest(); // Set device accessor - Object.defineProperty(ac, "device", - { - get : function() { + Object.defineProperty(ac, 'device', { + get: function() { if (req.device) { return req.device; } else { - return self; + return my; } }, - set : function() { + set: function() { }, configurable: true }); - } DeviceAddon.prototype = { - - // Intentionally commented out in order to make it instantiable on demand -// namespace: 'device', + // Intentionally commented out to make it instantiable on demand. + // namespace: 'device', /** * Returns the attribute of the catalog for the device * this request was intiated from. - * - * @method get - * @param attribute {String} - The name of the catalog attribute e.g "make" or "model". - * @returns value + * @param {string} attribute The name of the catalog attribute e.g + * "make" or "model". + * @return {object} The value of the named attribute. */ - get : function(attribute) { + get: function(attribute) { //TODO: make an RPC call. } }; @@ -109,7 +112,9 @@

    ActionContextAddon  0.1.0

    Y.mojito.addons.ac.device = DeviceAddon; -}, '0.1.0', {requires: ['mojito']}); +}, '0.3.0', {requires: [ + 'mojito' +]});
    @@ -134,10 +139,19 @@

    Classes

  • Analytics.common
  • Assets.common
  • Carrier.common
  • +
  • Composite.common
  • +
  • Config.common
  • +
  • Cookie.client
  • +
  • Cookie.server
  • Deploy.server
  • Device.common
  • +
  • Http.server
  • I13n.server
  • +
  • Intl.common
  • Meta.common
  • +
  • Params.common
  • +
  • Partial.common
  • +
  • Url.common
  • @@ -145,14 +159,25 @@

    Classes

    --> @@ -170,7 +195,7 @@

    Files

    diff --git a/docs/api/dispatch.common.js.html b/docs/api/dispatch.common.js.html index e5d459e4d..4588054d3 100644 --- a/docs/api/dispatch.common.js.html +++ b/docs/api/dispatch.common.js.html @@ -2,23 +2,23 @@ - API: MojitoClient dispatch.common.js (YUI Library) + Mojito API: ActionContext dispatch.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoClient  0.1.0

    +

    mojito

    +

    ActionContext  0.3.0

    mojito - > MojitoClient + > ActionContext > dispatch.common.js (source view) @@ -48,236 +48,392 @@

    MojitoClient  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
      * This object is responsible for running mojits.
      * @class MojitoDispatcher
      * @constructor
    - * @param resourceStore {ServerStore} the store to use
    + * @param {ServerStore} resourceStore the store to use.
      * @private
      */
    -YUI.add('mojito-dispatcher', function(Y, NAME){
    +YUI.add('mojito-dispatcher', function(Y, NAME) {
     
    -    var loader, logger, store, 
    +    var loader,
    +        logger,
    +        store,
             CACHE = {
                 YUI: {},
                 controllerContexts: {}
             },
    -        // TODO remove client detection hack (bug #4809613)
    +        // TODO: [Issue 112] remove client detection logic
             cacheControllerContext = (typeof window !== 'undefined'),
             coreYuiModules = [],
             usePrecomputed,
    +        useOnDemand,
             appShareYUIInstance;
     
    -    /* Optimization methods from Satyen:
     
    -    ============ 1). YUI({bootstrap:false}).use("*")
    +    /**
    +     * Modifies the YUI modules in the instance to point to the correct
    +     * language.
    +     *
    +     * @param {string} lang target language.
    +     * @param {Object} instance mojit instance (results of expandInstance()).
    +     * @private
    +     */
    +    function fixupInstanceLang(type, lang, instance) {
    +        var fixedSorted = [],
    +            fixedSortedPaths = {},
    +            bestLang = Y.Intl.lookupBestLang(lang,
    +                Y.Object.keys(instance.yui.langs)),
    +            suffix = (bestLang) ? '_' + bestLang : '',
    +            OK = {},
    +            fixedMod,
    +            fixedPath;
    +
    +        // hard fallbacks if no "root" bundle
    +        if (!bestLang && !instance.yui.langs['']) {
    +            if (instance.yui.langs.en) {
    +                bestLang = 'en';
    +                suffix = '_en';
    +            }
    +            if (!bestLang && instance.yui.langs['en-US']) {
    +                bestLang = 'en-US';
    +                suffix = '_en-US';
    +            }
    +        }
    +
    +        OK['lang/' + type + suffix] = true;
    +        if (suffix) {
    +            OK['lang/datatype-date-format' + suffix] = true;
    +        } else {
    +            // The "root" (no lang) version doesn't contain aggregates like %x.
    +            OK['lang/datatype-date-format_en'] = true;
    +        }
    +
    +        Y.Array.each(instance.yui.sorted, function(mod) {
    +            if ('lang/' === mod.substring(0, 5)) {
    +                if (OK[mod]) {
    +                    fixedSorted.push(mod);
    +                }
    +            } else {
    +                fixedSorted.push(mod);
    +            }
    +        });
    +        Y.Object.each(instance.yui.sortedPaths, function(path, mod) {
    +            if ('lang/' === mod.substring(0, 5)) {
    +                if (OK[mod]) {
    +                    fixedSortedPaths[mod] = path;
    +                }
    +            } else {
    +                fixedSortedPaths[mod] = path;
    +            }
    +        });
    +
    +        instance.yui.sorted = fixedSorted;
    +        instance.yui.sortedPaths = fixedSortedPaths;
    +    }
    +
    +
    +    /* Optimization methods:
    +
    +    ============ 1). YUI({bootstrap:false}).use('*')
     
    -    You'll get optimal performance by adding the js files (in order) to the page, and using YUI({bootstrap:false}).use("*") instead of Y.use(moduleList).
    +    You'll get optimal performance by adding the js files (in order) to the
    +    page, and using YUI({bootstrap:false}).use('*') instead of
    +    Y.use(moduleList).
     
    -    This will stop loader from calculating dependencies and assume everything which is required is already on the page.
    -    Additionally adding the scripts in order will mean there's less re-sorting which needs to be done as each module gets attached.
    +    This will stop loader from calculating dependencies and assume everything
    +    which is required is already on the page.
    +    Additionally adding the scripts in order will mean there's less re-sorting
    +    which needs to be done as each module gets attached.
     
         POTENTIAL ISSUE:
    -    For mojito, since you have multiple Y instances, Y.use("*") may be a concern - since it's saying "use everything currently on the page", so all your mojit instances will have all your modules attached.
    -    However, you could still use this for the global mojito framework Y instance, or for the shared modules (modules common to all mojits) and then use Y.use(additionalModules) for the rest.
    +    For mojito, since you have multiple Y instances, Y.use('*') may be a
    +    concern - since it's saying use everything currently on the page, so all
    +    your mojit instances will have all your modules attached.
    +    However, you could still use this for the global mojito framework Y
    +    instance, or for the shared modules (modules common to all mojits) and then
    +    use Y.use(additionalModules) for the rest.
     
         ============ 2). YUI({bootstrap:false}).use(sortedModuleList)
    -    The next step down in terms of performance would be to use YUI({bootstrap:false}).use(sortedModuleList) instead of Y.use("*"), so you still have instances with separate modules, but there's less (re)sorting required while attaching.
    +    The next step down in terms of performance would be to use
    +    YUI({bootstrap:false}).use(sortedModuleList) instead of Y.use('*'), so you
    +    still have instances with separate modules, but there's less (re)sorting
    +    required while attaching.
     
         ============ 3).
    -    You could also set the sorted list of shared modules (modules common to all mojits) as the core modules required for *ALL* your Y instances, using the "core" config property:
    +    You could also set the sorted list of shared modules (modules common to all
    +    mojits) as the core modules required for *ALL* your Y instances, using the
    +    core config property:
     
    -    http://developer.yahoo.com/yui/3/api/config.html#property_core
    +    http://developer.yahoo.com/cocktails/mojito/3/api/config.html#property_core
     
    -    It seems like 3 would be the easiest first optimization step to get in place to see if it provides benefits.
    +    It seems like 3 would be the easiest first optimization step to get in
    +    place to see if it provides benefits.
         */
     
         /* See docs for the dispatch function in action-context.common.js */
         function dispatch(command, adapter) {
    -        logger.log('dispatching command for ' + (command.instance.base || '@' + command.instance.type) + '.' + command.action, 'mojito', 'qeperf');
    +        logger.log('dispatching command for ' +
    +            (command.instance.base || '@' + command.instance.type) + '.' +
    +            command.action, 'mojito', 'qeperf');
             var instance = command.instance,
    -            cc = cacheControllerContext ? CACHE.controllerContexts[instance.guid] : null;
    +            cc = cacheControllerContext ?
    +                    CACHE.controllerContexts[instance.instanceId] :
    +                    null;
     
             if (cc) {
    -            logger.log('using cached controller context: ' + instance.guid, 'info', NAME);
    +            logger.log('using cached controller context: ' +
    +                instance.instanceId, 'info', NAME);
                 cc.invoke(command, adapter);
                 return;
             }
     
             logger.log('expanding partial mojit instance', 'mojito', 'qeperf');
     
    -        // Convert the command partial instance to a full instance
    -        store.expandInstance(command.instance, command.context, function(err, instance) {
    -
    -            // if there is no action, make 'index' the default
    -            if (! command.action) {
    -                // use instance config for default action or 'index'
    -                command.action = instance.action || 'index';
    -            }
    +        // Convert the command partial instance to a full instance. Note
    +        // instance here means dictionary that's either fully populated or
    +        // not. When it's expanded it contains all the data from the resource
    +        // store which is needed to ensure it can be invoked/dispatched.
    +        store.expandInstance(command.instance, command.context,
    +            function(err, instance) {
    +
    +                // if there is no action, make 'index' the default
    +                if (!command.action) {
    +                    // use instance config for default action or 'index'
    +                    command.action = instance.action || 'index';
    +                }
     
    -            var instanceYuiCacheKey, instanceYuiCacheObj, ctxKey;
    +                var instanceYuiCacheKey,
    +                    instanceYuiCacheObj,
    +                    ctxKey;
     
    -            if (err) {
    -                if (adapter.error) {
    -                    adapter.error(err);
    -                }
    -                else {
    -                    logger.log('WARNING!! Uncaught error from dispatch on instance "' + (command.instance.id || '@'+command.instance.type) + '"', 'error', NAME);
    -                    logger.log(err.message, 'error', NAME);
    -                    logger.log(err.stack, 'error', NAME);
    -                    // TODO 2011-06-20: [bug 4649669] adapter.done() so the request doesn't hang open
    +                if (err) {
    +                    if (adapter.error) {
    +                        adapter.error(err);
    +                    } else {
    +                        logger.log('WARNING!! Uncaught error from dispatch' +
    +                            ' on instance \'' + (command.instance.id || '@' +
    +                            command.instance.type) + '\'', 'error', NAME);
    +                        logger.log(err.message, 'error', NAME);
    +                        logger.log(err.stack, 'error', NAME);
    +                        // TODO: [Issue 67] adapter.done() so the
    +                        // request doesn't hang open.
    +                    }
    +                    return;
                     }
    -                return;
    -            }
     
    -            logger.log('mojit instance expansion complete: ' + instance.guid, 'mojito', 'qeperf');
    +                logger.log('mojit instance expansion complete: ' +
    +                    instance.instanceId, 'mojito', 'qeperf');
     
    -            // We replace the given instance with the expanded instance
    -            command.instance = instance;
    +                // We replace the given instance with the expanded instance
    +                command.instance = instance;
     
    -            if (appShareYUIInstance && instance.shareYUIInstance) {
    -                instanceYuiCacheKey = "singleton";
    -            } else {
    -                // Generate a cache key
    -                // TODO 2011-06-20: [bug 4649670] Can we create this key faster? from the request contextualizer?
    -                instanceYuiCacheKey = [];
    -                for (ctxKey in command.context) {
    -                    if (command.context.hasOwnProperty(ctxKey) && command.context[ctxKey]) {
    -                        instanceYuiCacheKey.push(ctxKey+'='+command.context[ctxKey]);
    +                if (appShareYUIInstance && instance.shareYUIInstance) {
    +                    instanceYuiCacheKey = 'singleton';
    +                } else {
    +                    // Generate a cache key
    +                    // TODO: [Issue 68] Can we create this key
    +                    // faster? from the request contextualizer?
    +                    instanceYuiCacheKey = [];
    +                    for (ctxKey in command.context) {
    +                        if (command.context.hasOwnProperty(ctxKey) &&
    +                                command.context[ctxKey]) {
    +                            instanceYuiCacheKey.push(ctxKey + '=' +
    +                                command.context[ctxKey]);
    +                        }
                         }
    +                    instanceYuiCacheKey = instance.type + '?' +
    +                        instanceYuiCacheKey.join('&');
                     }
    -                instanceYuiCacheKey = instance.type+'?'+instanceYuiCacheKey.join('&');
    -            }
     
    -            function runMojit() {
     
    -                var moduleList = (usePrecomputed ? instance.yui.sorted : instance.yui.requires),
    -                    // gotta copy this or else it pollutes the client runtime
    -                    mojitYuiModules = Y.mojito.util.copy(moduleList);
    +                function runMojit() {
    +                    var moduleList,
    +                        mojitYuiModules;
     
    -                // We are set so log our final list and use() it
    -                logger.log('Dispatching an instance of "'+(instance.id || '@'+instance.type)+'/'+command.action+'" with the modules: ['+ mojitYuiModules.join(', ')+']', 'info', NAME);
    +                    fixupInstanceLang(command.instance.type, command.context.lang, instance);
     
    -                logger.log('dispatching instance of "'+ instance.guid +'/'+command.action+'"', 'mojito', 'qeperf');
    +                    moduleList = (usePrecomputed ?
    +                            instance.yui.sorted :
    +                            instance.yui.requires);
    +                    // gotta copy this or else it pollutes the client runtime
    +                    mojitYuiModules = Y.mojito.util.copy(moduleList);
     
    -                // Create the function that will be called in YUI().use()
    -                // pushing the runner function onto the tail of the YUI module listing
    -                mojitYuiModules.push(function(MOJIT_Y) {
    -                    logger.log('YUI used: ' + instance.guid, 'mojito', 'qeperf');
    +                    // We are set so log our final list and use() it
    +                    logger.log('Dispatching an instance of \'' +
    +                        (instance.id || '@' + instance.type) + '/' +
    +                        command.action + '\' with the modules: [' +
    +                        mojitYuiModules.join(', ') + ']', 'info', NAME);
    +
    +                    logger.log('dispatching instance of \'' +
    +                        instance.instanceId + '/' + command.action + '\'',
    +                        'mojito',
    +                        'qeperf'
    +                        );
    +
    +                    // Create the function that will be called in YUI().use()
    +                    // pushing the runner function onto the tail of the YUI
    +                    // module listing
    +                    mojitYuiModules.push(function(MOJIT_Y) {
    +                        logger.log('YUI used: ' + instance.instanceId,
    +                            'mojito',
    +                            'qeperf');
    +
    +                        logger.log('Creating controller context', 'info',
    +                            NAME);
    +                        cc = new Y.mojito.ControllerContext({
    +                            instance: instance,
    +                            Y: MOJIT_Y,
    +                            store: store,
    +                            appShareYUIInstance: appShareYUIInstance,
    +                            dispatch: dispatch
    +                        });
    +                        logger.log('caching controller context: ' +
    +                            instance.instanceId, 'info', NAME);
    +                        if (cacheControllerContext) {
    +                            CACHE.controllerContexts[instance.instanceId] = cc;
    +                        }
    +
    +                        cc.invoke(command, adapter);
     
    -                    logger.log("Creating controller context", 'info', NAME);
    -                    cc = new Y.mojito.ControllerContext({
    -                        instance: instance,
    -                        Y: MOJIT_Y,
    -                        store: store,
    -                        appShareYUIInstance : appShareYUIInstance, 
    -                        dispatch: dispatch
                         });
    -                    logger.log('caching controller context: ' + instance.guid, 'info', NAME);
    -                    if (cacheControllerContext) {
    -                        CACHE.controllerContexts[instance.guid] = cc;
    -                    }
     
    -                    cc.invoke(command, adapter);
    +                    // Time marker
    +                    Y.mojito.perf.mark('mojito', 'core_dispatch_start[' +
    +                        (instance.id || '@' + instance.type) + ':' +
    +                        command.action + ']', 'Dispatching an instance of \'' +
    +                        (instance.id || '@' + instance.type) + '/' +
    +                        command.action + '\'');
     
    -                });
    +                    // Now we call YUI use() with our modules array
    +                    // This is the same as doing; YUI().use(arrayOfModules,
    +                    // function(Y){});
     
    -                // Time marker
    -                Y.mojito.perf.mark('mojito', 'core_dispatch_start['+(instance.id || '@'+instance.type)+':'+command.action+']', 'Dispatching an instance of "'+(instance.id || '@'+instance.type)+'/'+command.action+'"');
    +                    // Although Y.use should be asynch, it is not entirely
    +                    // asynch. The files are read asynch, but the loader
    +                    // calculations are not.
     
    -                // Now we call YUI "use()" with our "modules" array
    -                // This is the same as doing; YUI().use(arrayOfModules, function(Y){});
    +                    // Putting this use statement within setTimeout apparently
    +                    // prevents it from blocking the event loop, but it can
    +                    // also execute the runner function against a different
    +                    // request.
     
    -                // Although Y.use should be asynch, it is not entirely asynch. The files are read asynch, but the loader calculations are not.
    -                // Putting this use statement within a setTimeout apparently prevents it from blocking the event loop,
    -                // but it can also execute the runner function against a different request.
    +                    logger.log('YUI use: ' + instance.instanceId, 'mojito',
    +                        'qeperf');
     
    -                logger.log('YUI use: ' + instance.guid, 'mojito', 'qeperf');
    +                    instanceYuiCacheObj.use.apply(instanceYuiCacheObj,
    +                        mojitYuiModules);
    +                }
     
    -                instanceYuiCacheObj.use.apply(instanceYuiCacheObj, mojitYuiModules);
    -            }
     
    -            function modulesLoaded(cb) {
    +                function modulesLoaded(cb) {
     
    -                var groups = {},
    -                    groupKey = 'mojit-' + instance.type,
    -                    instanceYuiConfig;
    +                    var groups = {},
    +                        groupKey = 'mojit-' + instance.type,
    +                        instanceYuiConfig;
     
    -                // TODO 2011-06-20: [bug 4649674] Replace the mojit groups defined in index.js's configureYUI() function with this?
    +                    // TODO: [Issue 69] Replace the mojit groups
    +                    // defined in index.js's configureYUI() function with
    +                    // this?
     
    -                //logger.log('YUI instance creation: ' + instance.guid, 'mojito', 'qeperf');
    +                    //logger.log('YUI instance creation: ' +
    +                    //    instance.instanceId, mojito', 'qeperf');
     
    -                instanceYuiCacheObj = CACHE.YUI[instanceYuiCacheKey];
    +                    instanceYuiCacheObj = CACHE.YUI[instanceYuiCacheKey];
     
    -                if (!instanceYuiCacheObj) {
    +                    if (!instanceYuiCacheObj) {
     
    -                    instanceYuiConfig = {
    -                        //debug: true,
    -                        //filter: 'debug',
    -                        bootstrap: (usePrecomputed ? false : true),
    -                        lang: command.context.langs, // This is a list of prefered "langs"
    -                        core: coreYuiModules
    -                    };                    
    +                        instanceYuiConfig = {
    +                            //debug: true,
    +                            //filter: 'debug',
    +                            bootstrap: useOnDemand,
    +                            // This is a list of preferred langs
    +                            lang: command.context.langs,
    +                            core: coreYuiModules
    +                        };
     
    -                    instanceYuiCacheObj = CACHE.YUI[instanceYuiCacheKey] = YUI(instanceYuiConfig);
    +                        instanceYuiCacheObj = CACHE.YUI[instanceYuiCacheKey] =
    +                            YUI(instanceYuiConfig);
     
    -                    logger.log('YUI instance created: ' + instance.guid, 'mojito', 'qeperf');
    -                    logger.log('Cached a YUI instance with key: "'+instanceYuiCacheKey+'"', 'mojito', NAME);
    -                } else {
    -                    logger.log('Using cached YUI instance from key:' + instanceYuiCacheKey, 'mojito', 'qeperf');
    -                }
    +                        logger.log('YUI instance created: ' +
    +                            instance.instanceId,
    +                            'mojito',
    +                            'qeperf'
    +                            );
    +                        logger.log('Cached a YUI instance with key: \'' +
    +                            instanceYuiCacheKey + '\'', 'mojito', NAME);
    +                    } else {
    +                        logger.log('Using cached YUI instance from key:' +
    +                            instanceYuiCacheKey, 'mojito', 'qeperf');
    +                    }
     
    -                // To handle both shared and new instance instead of having if/elses.
    -                groups[groupKey] = instance.yui.config;
    -                instanceYuiCacheObj.applyConfig({groups:groups});
    +                    // To handle both shared and new instance instead of having
    +                    // if/elses.
    +                    groups[groupKey] = instance.yui.config;
    +                    instanceYuiCacheObj.applyConfig({groups: groups});
     
    -                cb();
    -            }
    +                    cb();
    +                }
     
    -            // Get the cached YUI instance (if there is one)
    -            if (!(appShareYUIInstance && instance.shareYUIInstance)) {
    -                instanceYuiCacheObj = CACHE.YUI[instanceYuiCacheKey];
    -            }
    +                // Get the cached YUI instance (if there is one)
    +                if (!(appShareYUIInstance && instance.shareYUIInstance)) {
    +                    instanceYuiCacheObj = CACHE.YUI[instanceYuiCacheKey];
    +                }
     
    -            /*
    -             * We cache a YUI instance for each Mojit "type" requested.
    -             * Doing this gives a huge performance benefit at the
    -             * cost of a larger memory foot print.
    -             */
    -            if (instanceYuiCacheObj) {
    -                runMojit();
    -            } else if (! usePrecomputed) {
    -                modulesLoaded(runMojit);
    -            } else {
    +                /*
    +                 * We cache a YUI instance for each Mojit type requested.
    +                 * Doing this gives a huge performance benefit at the
    +                 * cost of a larger memory foot print.
    +                 */
    +                if (instanceYuiCacheObj) {
    +                    runMojit();
    +                } else if (!usePrecomputed) {
    +                    modulesLoaded(runMojit);
    +                } else {
     
    -                logger.log('loading YUI modules for YUI instantiation: ' + instance.guid, 'mojito', 'qeperf');
    +                    logger.log('loading YUI modules for YUI instantiation: ' +
    +                        instance.instanceId, 'mojito', 'qeperf');
     
    -                loader.load(instance.yui.sortedPaths, function(err) {
    -                    if (err) {
    -                        logger.log(err.message, 'error', NAME);
    -                        adapter.error(err);
    -                        return;
    -                    }
    -                    modulesLoaded(runMojit);
    -                });
    -            }
    -        });
    +                    loader.load(instance.yui.sortedPaths, function(err) {
    +                        if (err) {
    +                            logger.log(err.message, 'error', NAME);
    +                            adapter.error(err);
    +                            return;
    +                        }
    +                        modulesLoaded(runMojit);
    +                    });
    +                }
    +            });
         }
     
    +
         /*
    -     * the dispatcher must receive the global logger up front, because it is loaded within a
    -     * Y instance that has the original Y.log function, so in order to have consistent logging,
    -     * the Mojito logger is passed in and we use it.
    +     * the dispatcher must receive the global logger up front, because it is
    +     * loaded within a Y instance that has the original Y.log function, so in
    +     * order to have consistent logging, the Mojito logger is passed in and we
    +     * use it.
          */
         Y.mojito.Dispatcher = {
     
    -        init: function(resourceStore, coreMojitoYuiModules, globalLogger, globalLoader) {
    -            var appConfigNC;
    +        init: function(resourceStore, coreMojitoYuiModules, globalLogger,
    +                globalLoader) {
    +            var appConfigStatic;
     
                 if (!resourceStore) {
    -                throw new Error("Mojito cannot instantiate without a resource store");
    +                throw new Error(
    +                    'Mojito cannot instantiate without a resource store'
    +                );
                 }
     
                 store = resourceStore;
    @@ -287,22 +443,35 @@ 

    MojitoClient  0.1.0

    logger.log('Dispatcher created', 'debug', NAME); - appConfigNC = store.getAppConfig({}, 'definition'); + appConfigStatic = store.getAppConfig({}, 'definition'); - appShareYUIInstance = (false !== appConfigNC.shareYUIInstance); - usePrecomputed = (appConfigNC.yui && 'precomputed' === appConfigNC.yui.dependencyCalculations); + appShareYUIInstance = (false !== appConfigStatic.shareYUIInstance); + usePrecomputed = appConfigStatic.yui && (-1 !== + appConfigStatic.yui.dependencyCalculations.indexOf('precomputed')); + useOnDemand = appConfigStatic.yui && (-1 !== + appConfigStatic.yui.dependencyCalculations.indexOf('ondemand')); + if (!usePrecomputed) { + useOnDemand = true; + } - if (! usePrecomputed) { - coreYuiModules.push("loader"); + if (useOnDemand) { + coreYuiModules.push('loader'); } return this; }, + + // Assign outer function here. dispatch: dispatch }; -}, '0.1.0', { requires:['mojito-controller-context', 'mojito-util', 'mojito-resource-store-adapter']}); +}, '0.3.0', {requires: [ + 'mojito-controller-context', + 'mojito-util', + 'mojito-resource-store-adapter', + 'intl' +]});
    @@ -313,10 +482,10 @@

    MojitoClient  0.1.0

    @@ -324,8 +493,7 @@

    Modules

    @@ -333,18 +501,11 @@

    Classes

    --> @@ -362,7 +523,7 @@

    Files

    diff --git a/docs/api/glob.js.html b/docs/api/glob.js.html index 258f7ea61..fb7e29f55 100644 --- a/docs/api/glob.js.html +++ b/docs/api/glob.js.html @@ -2,21 +2,21 @@ - API: MojitoServer glob.js (YUI Library) + Mojito API: MojitoServer glob.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    MojitoServer  0.3.0

    mojito > MojitoServer @@ -48,10 +48,13 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
     
     
    +/*jslint anon:true, sloppy:true*/
     
     var libfs = require('fs'),
         libpath = require('path');
    @@ -65,7 +68,7 @@ 

    MojitoServer  0.1.0

    * <li>a single star (<code>*</code>) for a whole directory segment * </ul> * - * The list of matches doesn't include files that begin with a dot (<code>.</code>). + * The list doesn't include files that begin with dot (<code>.</code>). * * [1] http://en.wikipedia.org/wiki/Glob_%28programming%29 * @@ -78,8 +81,15 @@

    MojitoServer  0.1.0

    * @private */ function globSync(pattern, flags, list) { - var todo = [ pattern ], current, done = {}, - parts, base, subs, i, sub, stat; + var todo = [pattern], + current, + done = {}, + parts, + base, + subs, + i, + sub, + stat; // double-dots not supported if (-1 !== pattern.indexOf('**')) { @@ -88,54 +98,52 @@

    MojitoServer  0.1.0

    while (todo.length) { current = todo.shift(); - if (done[current]) { - continue; - } - done[current] = true; - - parts = current.split('*'); - if (parts.length === 1) { - list.push(current); - continue; - } - - base = parts.shift(); - try { - subs = libfs.readdirSync(base); - } - catch (e) { - continue; - } - for (i=0; i<subs.length; i++) { - sub = subs[i]; - if ('.' === sub.charAt(0)) { - continue; - } - if (parts.length) { + if (!done[current]) { + done[current] = true; + + parts = current.split('*'); + if (parts.length === 1) { + list.push(current); + } else { + base = parts.shift(); try { - stat = libfs.statSync(base + sub); - } - catch (ex) { - continue; - } - if (stat.isDirectory()) { - if ((parts.length === 1) && (! libpath.existsSync(base + sub + parts[0]))) { - continue; + subs = libfs.readdirSync(base); + for (i = 0; i < subs.length; i += 1) { + sub = subs[i]; + if ('.' !== sub.charAt(0)) { + if (parts.length) { + try { + stat = libfs.statSync(base + sub); + if (stat.isDirectory()) { + if ((parts.length !== 1) || + (libpath.existsSync( + base + sub + parts[0] + ))) { + todo.push(base + + sub + parts.join('*')); + } + } else if (parts[0] === '') { + todo.push(base + sub); + } + } catch (ex) { + // no-op. + } + } else { + todo.push(base + sub); + } + } } - todo.push(base + sub + parts.join('*')); - } - else if (parts[0] === '') { - todo.push(base + sub); + } catch (e) { + // no-op. } } - else { - todo.push(base + sub); - } } } } - +/* + * Returns an object with a globSync slot and matcher function reference. + */ module.exports = { globSync: globSync }; @@ -160,16 +168,9 @@

    Modules

    @@ -178,27 +179,11 @@

    Classes

    Files

    --> @@ -216,7 +201,7 @@

    Files

    diff --git a/docs/api/http.server.js.html b/docs/api/http.server.js.html index 7bb56cf78..a85fb6484 100644 --- a/docs/api/http.server.js.html +++ b/docs/api/http.server.js.html @@ -2,23 +2,23 @@ - API: MojitoServer http.server.js (YUI Library) + Mojito API: ActionContextAddon http.server.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > http.server.js (source view) @@ -48,16 +48,25 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-http-addon', function(Y, NAME) {
    -    
    +
         var XHR_HDR = 'x-requested-with',
             XHR_HDR_REGEX = /^XMLHttpRequest$/i;
     
    +
         /**
          * <strong>Access point:</strong> <em>ac.http.*</em>
          * This is a server-only utility plugin that makes many server side
    @@ -70,40 +79,42 @@ 

    MojitoServer  0.1.0

    this._respHeaders = {}; } + Addon.prototype = { namespace: 'http', /** * Returns the HTTP request. - * @method getRequest - * @return {ServerRequest} http://nodejs.org/docs/v0.4.7/api/http.html#http.ServerRequest + * @return {ServerRequest} The node.js http.ServerRequest instance. */ getRequest: function() { return this.adapter.req; }, + /** - * - * @method getResponse - * @return {ServerResponse} http://nodejs.org/docs/v0.4.7/api/http.html#http.ServerResponse + * Returns the HTTP response object from the request. + * @return {ServerResponse} The node.js http.ServerResponse instance. */ getResponse: function() { return this.adapter.res; }, + /** * Adds a header to the response without overriding previous values - * @method addHeader - * @param {String} key header name - * @param {String} val header value + * @param {String} key header name. + * @param {String} val header value. */ - addHeader: function(k, val){ - var key = k.toLowerCase(), + addHeader: function(k, v) { + // multiline values are against HTTP spec, and a SECURITY RISK + var key = (k || '').split('\n')[0].toLowerCase(), + val = (v || '').split('\n')[0], dup = false, hdrs = this._respHeaders; - if (! hdrs[key]) { + if (!hdrs[key]) { hdrs[key] = []; } hdrs[key].forEach(function(i) { @@ -111,14 +122,15 @@

    MojitoServer  0.1.0

    dup = true; } }); - if (! dup) { + if (!dup) { hdrs[key].push(val); } }, + /** * Adds a object of headers all at once, adding to previous values - * @param hdrs {object} header values to add + * @param {object} hdrs header values to add. */ addHeaders: function(hdrs) { Y.Object.each(hdrs, function(val, key) { @@ -126,18 +138,20 @@

    MojitoServer  0.1.0

    }, this); }, + /** * Sets a header by key, overriding previous values - * @param key {string} header name - * @param val {string} header value + * @param {string} key header name. + * @param {string} val header value. */ setHeader: function(key, val) { this._respHeaders[key.toLowerCase()] = [val]; }, + /** * Sets a object full of headers all at once, overriding previous values - * @param hdrs {object} header values to set + * @param {object} hdrs header values to set. */ setHeaders: function(hdrs) { Y.Object.each(hdrs, function(val, key) { @@ -145,15 +159,17 @@

    MojitoServer  0.1.0

    }, this); }, + /** * Returns one request header value - * @param name {string} header name - * @return {object} header value + * @param {string} name header name. + * @return {object} header value. */ - getHeader: function(name){ + getHeader: function(name) { var n = name.toLowerCase(), val; - // have to loop through these because the header keys must be case insensitive + // have to loop through these because the header keys must be case + // insensitive Y.Object.some(this.getHeaders(), function(v, k) { if (k.toLowerCase() === n) { val = v; @@ -163,31 +179,32 @@

    MojitoServer  0.1.0

    return val; }, + /** * Returns all request headers - * @method getHeaders - * @return {object} all headers + * @return {object} all headers. */ getHeaders: function() { return this.adapter.req.headers; }, + /** * Helper to tell you if this is an XHR request. Checks specifically * for the 'x-requested-with' header. - * @method isXhr - * @return {boolean} + * @return {boolean} True if the receiver is associated with an XHR + * request. */ isXhr: function() { return XHR_HDR_REGEX.test(this.getHeader(XHR_HDR)); }, + /** * This redirect is an external redirect. It causes an HTTP * status code 301 by default. - * @method redirect - * @param uri {string} - * @param code {Number} [optional] if not specifed, 301 + * @param {string} uri the URI to redirect to. + * @param {Number} code [optional] if not specifed, 301. */ redirect: function(uri, code) { code = code || 301; @@ -196,39 +213,39 @@

    MojitoServer  0.1.0

    code: code } }; -// Y.log('redirect(' + uri + ', '+code+')', 'warn', NAME); + Y.log('redirect(' + uri + ', ' + code + ')', 'debug', NAME); this._statusCode = code; - this.addHeaders({ - 'location': uri, - 'content-type': 'text/html' - }); - meta.http.headers = this._respHeaders; + this.addHeader('location', uri); + this.addHeader('content-type', 'text/html'); this.ac.done(null, meta); }, + mergeMetaInto: function(meta) { if (Object.keys(this._respHeaders).length === 0) { return meta; } - if (! meta.http) { + if (!meta.http) { meta.http = {}; } - if (! meta.http.headers) { + if (!meta.http.headers) { meta.http.headers = {}; } Y.mojito.util.metaMerge(meta.http.headers, this._respHeaders); return meta; }, + getGlobal: function() { return global._mojito; } - }; Y.mojito.addons.ac.http = Addon; - -}, '0.1.0', {requires: ['mojito-util']}); + +}, '0.3.0', {requires: [ + 'mojito-util' +]});
    @@ -240,23 +257,29 @@

    MojitoServer  0.1.0

    Modules

    diff --git a/docs/api/i13n.common.js.html b/docs/api/i13n.common.js.html index 24de42fb1..ce1be090f 100644 --- a/docs/api/i13n.common.js.html +++ b/docs/api/i13n.common.js.html @@ -2,21 +2,21 @@ - API: ActionContextAddon i13n.common.js (YUI Library) + Mojito API: ActionContextAddon i13n.common.js ( - - + + - - + +
    -

    mojito

    -

    ActionContextAddon  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito > ActionContextAddon @@ -48,76 +48,49 @@

    ActionContextAddon  0.1.0

    #doc3 .classopts { display:none; }
    /*
    -* Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    -*/
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
    + */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-i13n-addon', function(Y, NAME) {
     
         /**
          * Processes the following part of the mojit's config:
    -     *
          * <code>
          * "i13n" : {
          *      "spaceid" : 12345,
          *      "page"    : { "val1" : "param1"}
          * }
          * </code>
    -     *
    -     * @method initFromConfig
    +     * @param {object} command The comment object providing configuration data.
    +     * @param {ActionContext} ac The action context.
    +     * @param {object} i13n The localization object.
          * @private
    -     *
          */
         function initFromConfig(command, ac, i13n) {
    -        var config, page, name;
    +        var config,
    +            page,
    +            name;
     
             if (this.initialized) {
                 return;
             }
    -        
    -        /*
    -        function getI13n(node) {
    -            var entry, children, result;
    -
    -            if (typeof node.config === 'object') {
    -
    -                // return the i13n config
    -                if (typeof node.config.i13n === 'object') {
    -                    return  node.config.i13n;
    -                }
    -
    -                // traverse the configs tree
    -                if (typeof node.config.child === 'object') {
    -                    return get13n(node.config.child);
    -                } else if (typeof node.config.children === 'object') {
    -                    children = node.config.children
    -                    for (entry in children) {
    -                        if (children.hasOwnProperty(entry)) {
    -
    -                            // quick pre-check to speed up the traversing
    -                            if (children[entry].config) {
    -
    -                                // check if we have found the i13n
    -                                result = get13n(children[entry]);
    -                                if (result) {
    -                                    return result;
    -                                }
    -                            }
    -                        }
    -                    }
    -                }
    -            }
    -        }
    -        */
    -        
    +
             // get the i13n
    -        //config = getI13n(ac.app.config.specs["???"]);
             config = command.instance.config.i13n || null;
             if (config) {
                 this.initialized = true;
                 if (typeof config.spaceid === 'number' ||
    -            typeof config.spaceid === 'string') {
    +                    typeof config.spaceid === 'string') {
     
                     // stamp spaceid
                     i13n.stamp.stampPageView(config.spaceid);
    @@ -125,9 +98,10 @@ 

    ActionContextAddon  0.1.0

    // track page params if (typeof config.page === 'object') { page = config.page; - for(name in page) { + for (name in page) { if (page.hasOwnProperty(name)) { - i13n.trackPageParams(name, page[name], i13n.ULT.ULT_PRECEDENCE_DEFAULT); + i13n.trackPageParams(name, page[name], + i13n.ULT.ULT_PRECEDENCE_DEFAULT); } } } @@ -135,14 +109,14 @@

    ActionContextAddon  0.1.0

    } } + /** * <strong>Access point:</strong> <em>ac.i13n.*</em> * Instrumentation addon for link tracking and page views. * @class I13n.server */ function I13nAddon(command, adapter, ac) { - var req, - self = this; + var req; this._ac = ac; this.command = command; @@ -164,129 +138,139 @@

    ActionContextAddon  0.1.0

    ac.i13n = this; } - I13nAddon.prototype = { - // intentionally not setting the namespace here, - // because we will add an object manually. - //namespace: 'i13n', + I13nAddon.prototype = { /** * Provides facility to create an URL to other * mojits with a link tracking instrumentation. - * - * @method make - * @param id {string} it to a mojit defined at the root level of the Mojito application configuration - * @param action {string} - * @param routeParams {object} used to lookup the route in the routing table - * @param verb {string} GET, POST, PUT, DELETE (case insensitive) - * @param urlParams {object} added to the looked up route as query params - * @param i13nParams {object} parameters to be used for link tracking. + * @param {string} base Reference to a mojit defined at the root + * level of the Mojito application configuration. + * @param {string} action The action to associate with the base. + * @param {object} routeParams used to lookup the route in the routing + * table. + * @param {string} verb GET, POST, PUT, DELETE (case insensitive). + * @param {object} urlParams added to the looked up route as query + * params. + * @param {object} i13nParams parameters to be used for link tracking. */ make: function(base, action, routeParams, verb, urlParams, i13nParams) { - - var result = this._ac.url.make(base, action, routeParams, verb, urlParams); + var result = this._ac.url.make(base, action, routeParams, verb, + urlParams); if (result) { result = this.trackLink(result, i13nParams); } return result; }, + + /** * Stamps the page view event. - * - * @method stampPageView - * @param spaceid {number} The spaceid to be used. + * @param {number} spaceid The spaceid to be used. */ - stampPageView : function() { + stampPageView: function(spaceid) { + // TODO: implement this. }, + + /** * Tracks a pair of page parameters as (key, value) for this request. - * - * @param key {string} - The page parameter name - * @param vlaue {string} -The page parameter value + * @param {string} key The page parameter name. + * @param {string} value The page parameter value. */ - trackPageParams : function() { + trackPageParams: function(key, value) { + // TODO: implement this. }, + + /** - * Tracks the link view and gemerates the URL - * with the hash token appended to it. - * - * - * @method trackLink - * @param url {string} - The link to be instrumented. - * @param link_params {object} - parameteres - * @param local_groups - Optional - * @param ult_args - Optional - * + * Tracks the link view and generates the URL with the hash token + * appended to it. + * @param {string} url The link to be instrumented. + * @param {object} link_params The link parameters. + * @param {object} local_groups - Optional. + * @param {object} ult_args - Optional. * @return {string} url with the hash appended to it. */ - trackLink : function() { + trackLink: function(url, link_params, local_groups, ult_args) { + // TODO: implement this. }, + + /** - * Tracks the link view for the links taken from the user generated content - * and hence need to be signed by B-cookie to prevent the security problems. - * - * - * @method trackUserLink - * @param url {string} - The link to be instrumented. - * @param link_params {object} - parameteres - * @param local_groups - Optional - * @param ult_args - Optional - * + * Tracks the link view for the links taken from the user generated + * content and hence need to be signed by B-cookie to prevent the + * security problems. + * @param {string} url The link to be instrumented. + * @param {object} link_params The link parameters. + * @param {object} local_groups Optional. + * @param {object} ult_args Optional. * @return {string} url with the hash appended to it. */ - trackUserLink : function() { + trackUserLink: function(url, link_params, local_groups, ult_args) { + // TODO: implement this. }, + + /** * , , [, ult_args [, return_code]] - * - * - * @method trackForm - * @param is_post_method {boolean} - true, if the method is POST - * @param action_url {string} - the form action link to be instrumented. - * @param link_params - {object} Tracking parameters. - * @param ult_args - Optional - * + * @param {boolean} is_post_method True, if the method is POST. + * @param {string} action_url The form action link to be instrumented. + * @param {object} link_params Tracking parameters. + * @param {object} ult_args Optional. * @return {string} form action url with the hash appended to it. */ - trackForm : function() { + trackForm: function(is_post_method, action_url, link_params, ult_args) { + // TODO: implement this. }, + + /** - * Instrument links for tracking of the link clicks by gemerating the URL - * with the hash token appended to it. - * - * - * @method trackClickOnly - * @param url {string} - The link to be instrumented. - * @param link_params {object} - parameteres - * @param ult_args - Optional - * + * Instrument links for tracking of the link clicks by gemerating the + * URL with the hash token appended to it. + * @param {string} url The link to be instrumented. + * @param {object} link_params The link parameters. + * @param {object} ult_args Optional. * @return {string} url with the hash appended to it. */ - trackClickOnly : function() { + trackClickOnly: function(url, link_params, ult_args) { + // TODO: implement this. }, + + /** - * Retrurn spaceid used for this request. - * - * @return spaceid previously set through stampPageView() or configuration. + * Return spaceid used for this request. + * @return {object} the spaceid previously set through stampPageView() + * or configuration. */ - getSpaceid : function() { + getSpaceid: function() { + // TODO: implement this. }, - // not documented - stampNonClassified : function() { + + + stampNonClassified: function() { + // TODO: implement this. }, - stampIgnore : function() { + + + stampIgnore: function() { + // TODO: implement this. }, - isStamped : function() { + + + isStamped: function() { + // TODO: implement this. } }; I13nAddon.dependsOn = ['config', 'http', 'url']; + Y.mojito.addons.ac.i13n = I13nAddon; -}, '0.1.0', {requires: [ +}, '0.3.0', {requires: [ 'mojito' - ]}); +]});
    @@ -311,10 +295,19 @@

    Classes

  • Analytics.common
  • Assets.common
  • Carrier.common
  • +
  • Composite.common
  • +
  • Config.common
  • +
  • Cookie.client
  • +
  • Cookie.server
  • Deploy.server
  • Device.common
  • +
  • Http.server
  • I13n.server
  • +
  • Intl.common
  • Meta.common
  • +
  • Params.common
  • +
  • Partial.common
  • +
  • Url.common
  • @@ -322,14 +315,25 @@

    Classes

    --> @@ -347,7 +351,7 @@

    Files

    diff --git a/docs/api/index.html b/docs/api/index.html index 54e96ea9f..852f6a9e8 100644 --- a/docs/api/index.html +++ b/docs/api/index.html @@ -1,22 +1,22 @@ - + - API: (YUI Library) + Mojito API - - + + - - + +
    diff --git a/docs/api/index.js.html b/docs/api/index.js.html index 98df3ece7..5884b991c 100644 --- a/docs/api/index.js.html +++ b/docs/api/index.js.html @@ -2,23 +2,23 @@ - API: MojitoServer index.js (YUI Library) + Mojito API: CommonLibs index.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > MojitoServer + > CommonLibs > index.js (source view) @@ -48,8 +48,16 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true*/
    +/*global YUI*/
    +
    +
     YUI.add('LazyLoadBinderIndex', function(Y, NAME) {
     
         Y.namespace('mojito.binders')[NAME] = {
    @@ -58,8 +66,10 @@ 

    MojitoServer  0.1.0

    this.mp = mojitProxy; }, + bind: function(node) { - var me = this; + var my = this; + // immediately load the lazy mojit in my config this.mp.invoke('load', { params: { @@ -69,22 +79,33 @@

    MojitoServer  0.1.0

    } }, function(err, data) { if (err) { - me.broadcast('lazy-load-error', {error: err, proxied: me.mp.config.proxied}); + my.broadcast('lazy-load-error', + { + error: err, + proxied: my.mp.config.proxied + }); } else { // replace node completely var markup = Y.JSON.parse(data).lazy; node.replace(markup); // notify - me.mp.broadcast('lazy-load-complete', {mojit: me.mp.config.proxied}); + my.mp.broadcast('lazy-load-complete', + { + mojit: my.mp.config.proxied + }); + // SEPPUKU!! (but leave the node on the DOM) - me.mp.destroySelf(true); + my.mp.destroySelf(true); } }); } - }; -}, '0.0.1', {requires: ['mojito-client', 'node', 'json']}); +}, '0.0.1', {requires: [ + 'mojito-client', + 'node', + 'json' +]});
    @@ -97,25 +118,16 @@

    Modules

    @@ -123,28 +135,27 @@

    Classes

    --> @@ -162,7 +173,7 @@

    Files

    diff --git a/docs/api/index.json b/docs/api/index.json index c5248c298..98fb9447d 100644 --- a/docs/api/index.json +++ b/docs/api/index.json @@ -1 +1 @@ -[{"url": "Assets.common.html#method_addBlob", "access": "", "host": "Assets.common", "type": "method", "name": "addBlob"}, {"url": "Assets.common.html#method_addCss", "access": "", "host": "Assets.common", "type": "method", "name": "addCss"}, {"url": "Http.server.html#method_addHeader", "access": "", "host": "Http.server", "type": "method", "name": "addHeader"}, {"url": "Http.server.html#method_addHeaders", "access": "", "host": "Http.server", "type": "method", "name": "addHeaders"}, {"url": "Assets.common.html#method_addJs", "access": "", "host": "Assets.common", "type": "method", "name": "addJs"}, {"url": "MojitoServer.html#method_addMojitoToExpressApp", "access": "", "host": "MojitoServer", "type": "method", "name": "addMojitoToExpressApp"}, {"url": "Params.common.html#method_all", "access": "", "host": "Params.common", "type": "method", "name": "all"}, {"url": "Params.common.html#method_body", "access": "", "host": "Params.common", "type": "method", "name": "body"}, {"url": "Y.mojito.MojitProxy.html#method_broadcast", "access": "", "host": "Y.mojito.MojitProxy", "type": "method", "name": "broadcast"}, {"url": "Y.mojito.MojitProxy.html#property_children", "access": "", "host": "Y.mojito.MojitProxy", "type": "property", "name": "children"}, {"url": "Y.mojito.MojitProxy.html#property_config", "access": "", "host": "Y.mojito.MojitProxy", "type": "property", "name": "config"}, {"url": "Deploy.server.html#method_constructMojitoClientRuntime", "access": "", "host": "Deploy.server", "type": "method", "name": "constructMojitoClientRuntime"}, {"url": "Y.mojito.MojitProxy.html#property_context", "access": "", "host": "Y.mojito.MojitProxy", "type": "property", "name": "context"}, {"url": "MojitoServer.html#method_createServer", "access": "", "host": "MojitoServer", "type": "method", "name": "createServer"}, {"url": "Y.mojito.lib.REST.html#method_DELETE", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "DELETE"}, {"url": "Y.mojito.ActionContext.html#method_destroy", "access": "", "host": "Y.mojito.ActionContext", "type": "method", "name": "destroy"}, {"url": "Y.mojito.MojitProxy.html#method_destroyChild", "access": "", "host": "Y.mojito.MojitProxy", "type": "method", "name": "destroyChild"}, {"url": "Y.mojito.MojitProxy.html#method_destroySelf", "access": "", "host": "Y.mojito.MojitProxy", "type": "method", "name": "destroySelf"}, {"url": "Y.mojito.ActionContext.html#method_disable", "access": "", "host": "Y.mojito.ActionContext", "type": "method", "name": "disable"}, {"url": "Y.mojito.ActionContext.html#method_dispatch", "access": "", "host": "Y.mojito.ActionContext", "type": "method", "name": "dispatch"}, {"url": "Composite.common.html#method_done", "access": "", "host": "Composite.common", "type": "method", "name": "done"}, {"url": "Y.mojito.ActionContext.html#method_done", "access": "", "host": "Y.mojito.ActionContext", "type": "method", "name": "done"}, {"url": "Y.mojito.ActionContext.html#method_enable", "access": "", "host": "Y.mojito.ActionContext", "type": "method", "name": "enable"}, {"url": "Y.mojito.ActionContext.html#method_error", "access": "", "host": "Y.mojito.ActionContext", "type": "method", "name": "error"}, {"url": "Composite.common.html#method_execute", "access": "", "host": "Composite.common", "type": "method", "name": "execute"}, {"url": "Params.common.html#method_files", "access": "", "host": "Params.common", "type": "method", "name": "files"}, {"url": "Url.common.html#method_find", "access": "", "host": "Url.common", "type": "method", "name": "find"}, {"url": "Y.mojito.Client.html#method_find", "access": "", "host": "Y.mojito.Client", "type": "method", "name": "find"}, {"url": "Y.mojito.ActionContext.html#method_flush", "access": "", "host": "Y.mojito.ActionContext", "type": "method", "name": "flush"}, {"url": "Intl.common.html#method_formatDate", "access": "", "host": "Intl.common", "type": "method", "name": "formatDate"}, {"url": "Cookie.server.html#method_get", "access": "", "host": "Cookie.server", "type": "method", "name": "get"}, {"url": "Config.common.html#method_get", "access": "", "host": "Config.common", "type": "method", "name": "get"}, {"url": "Y.mojito.lib.REST.html#method_GET", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "GET"}, {"url": "Device.common.html#method_get", "access": "", "host": "Device.common", "type": "method", "name": "get"}, {"url": "Carrier.common.html#method_get", "access": "", "host": "Carrier.common", "type": "method", "name": "get"}, {"url": "Params.common.html#method_getAll", "access": "", "host": "Params.common", "type": "method", "name": "getAll"}, {"url": "Y.mojito.MojitProxy.html#method_getChildren", "access": "", "host": "Y.mojito.MojitProxy", "type": "method", "name": "getChildren"}, {"url": "Y.mojito.Client.html#method_getComputedRoutes", "access": "", "host": "Y.mojito.Client", "type": "method", "name": "getComputedRoutes"}, {"url": "Config.common.html#method_getDefinition", "access": "", "host": "Config.common", "type": "method", "name": "getDefinition"}, {"url": "Params.common.html#method_getFromBody", "access": "", "host": "Params.common", "type": "method", "name": "getFromBody"}, {"url": "Params.common.html#method_getFromMerged", "access": "", "host": "Params.common", "type": "method", "name": "getFromMerged"}, {"url": "Params.common.html#method_getFromRoute", "access": "", "host": "Params.common", "type": "method", "name": "getFromRoute"}, {"url": "Params.common.html#method_getFromUrl", "access": "", "host": "Params.common", "type": "method", "name": "getFromUrl"}, {"url": "Y.mojito.MojitProxy.html#method_getFromUrl", "access": "", "host": "Y.mojito.MojitProxy", "type": "method", "name": "getFromUrl"}, {"url": "Http.server.html#method_getHeader", "access": "", "host": "Http.server", "type": "method", "name": "getHeader"}, {"url": "Http.server.html#method_getHeaders", "access": "", "host": "Http.server", "type": "method", "name": "getHeaders"}, {"url": "Http.server.html#method_getRequest", "access": "", "host": "Http.server", "type": "method", "name": "getRequest"}, {"url": "Http.server.html#method_getResponse", "access": "", "host": "Http.server", "type": "method", "name": "getResponse"}, {"url": "I13n.server.html#method_getSpaceid", "access": "", "host": "I13n.server", "type": "method", "name": "getSpaceid"}, {"url": "Y.mojito.lib.REST.html#method_HEAD", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "HEAD"}, {"url": "Partial.common.html#method_invoke", "access": "", "host": "Partial.common", "type": "method", "name": "invoke"}, {"url": "Y.mojito.MojitProxy.html#method_invoke", "access": "", "host": "Y.mojito.MojitProxy", "type": "method", "name": "invoke"}, {"url": "Http.server.html#method_isXhr", "access": "", "host": "Http.server", "type": "method", "name": "isXhr"}, {"url": "Intl.common.html#method_lang", "access": "", "host": "Intl.common", "type": "method", "name": "lang"}, {"url": "Y.mojito.MojitProxy.html#method_listen", "access": "", "host": "Y.mojito.MojitProxy", "type": "method", "name": "listen"}, {"url": "Url.common.html#method_make", "access": "", "host": "Url.common", "type": "method", "name": "make"}, {"url": "I13n.server.html#method_make", "access": "", "host": "I13n.server", "type": "method", "name": "make"}, {"url": "Params.common.html#method_merged", "access": "", "host": "Params.common", "type": "method", "name": "merged"}, {"url": "Y.mojito.Client.html#method_pause", "access": "", "host": "Y.mojito.Client", "type": "method", "name": "pause"}, {"url": "Y.mojito.lib.REST.html#method_POST", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "POST"}, {"url": "Y.mojito.lib.REST.html#method_PUT", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "PUT"}, {"url": "Http.server.html#method_redirect", "access": "", "host": "Http.server", "type": "method", "name": "redirect"}, {"url": "Y.mojito.MojitProxy.html#method_refreshView", "access": "", "host": "Y.mojito.MojitProxy", "type": "method", "name": "refreshView"}, {"url": "Partial.common.html#method_render", "access": "", "host": "Partial.common", "type": "method", "name": "render"}, {"url": "Y.mojito.MojitProxy.html#method_render", "access": "", "host": "Y.mojito.MojitProxy", "type": "method", "name": "render"}, {"url": "Y.mojito.Client.html#method_resume", "access": "", "host": "Y.mojito.Client", "type": "method", "name": "resume"}, {"url": "Analytics.common.html#method_retrieve", "access": "", "host": "Analytics.common", "type": "method", "name": "retrieve"}, {"url": "Meta.common.html#method_retrieve", "access": "", "host": "Meta.common", "type": "method", "name": "retrieve"}, {"url": "Params.common.html#method_route", "access": "", "host": "Params.common", "type": "method", "name": "route"}, {"url": "Cookie.server.html#method_set", "access": "", "host": "Cookie.server", "type": "method", "name": "set"}, {"url": "Http.server.html#method_setHeader", "access": "", "host": "Http.server", "type": "method", "name": "setHeader"}, {"url": "Http.server.html#method_setHeaders", "access": "", "host": "Http.server", "type": "method", "name": "setHeaders"}, {"url": "Analytics.common.html#method_setMergeFunction", "access": "", "host": "Analytics.common", "type": "method", "name": "setMergeFunction"}, {"url": "Y.mojito.ActionContext.html#method_setRequestFormatter", "access": "", "host": "Y.mojito.ActionContext", "type": "method", "name": "setRequestFormatter"}, {"url": "Y.mojito.ActionContext.html#method_setResponseFormatter", "access": "", "host": "Y.mojito.ActionContext", "type": "method", "name": "setResponseFormatter"}, {"url": "I13n.server.html#method_stampPageView", "access": "", "host": "I13n.server", "type": "method", "name": "stampPageView"}, {"url": "Analytics.common.html#method_store", "access": "", "host": "Analytics.common", "type": "method", "name": "store"}, {"url": "Meta.common.html#method_store", "access": "", "host": "Meta.common", "type": "method", "name": "store"}, {"url": "I13n.server.html#method_trackClickOnly", "access": "", "host": "I13n.server", "type": "method", "name": "trackClickOnly"}, {"url": "I13n.server.html#method_trackForm", "access": "", "host": "I13n.server", "type": "method", "name": "trackForm"}, {"url": "I13n.server.html#method_trackLink", "access": "", "host": "I13n.server", "type": "method", "name": "trackLink"}, {"url": "I13n.server.html#method_trackPageParams", "access": "", "host": "I13n.server", "type": "method", "name": "trackPageParams"}, {"url": "I13n.server.html#method_trackUserLink", "access": "", "host": "I13n.server", "type": "method", "name": "trackUserLink"}, {"url": "Y.mojito.MojitProxy.html#property_type", "access": "", "host": "Y.mojito.MojitProxy", "type": "property", "name": "type"}, {"url": "Y.mojito.MojitProxy.html#method_unlisten", "access": "", "host": "Y.mojito.MojitProxy", "type": "method", "name": "unlisten"}, {"url": "Params.common.html#method_url", "access": "", "host": "Params.common", "type": "method", "name": "url"}] +[{"url": "Assets.common.html#method_addAsset", "access": "", "host": "Assets.common", "type": "method", "name": "addAsset"}, {"url": "Assets.common.html#method_addAssets", "access": "", "host": "Assets.common", "type": "method", "name": "addAssets"}, {"url": "Assets.common.html#method_addBlob", "access": "", "host": "Assets.common", "type": "method", "name": "addBlob"}, {"url": "Assets.common.html#method_addCss", "access": "", "host": "Assets.common", "type": "method", "name": "addCss"}, {"url": "Http.server.html#method_addHeader", "access": "", "host": "Http.server", "type": "method", "name": "addHeader"}, {"url": "Http.server.html#method_addHeaders", "access": "", "host": "Http.server", "type": "method", "name": "addHeaders"}, {"url": "Assets.common.html#method_addJs", "access": "", "host": "Assets.common", "type": "method", "name": "addJs"}, {"url": "MojitoServer.html#method_addMojitoToExpressApp", "access": "", "host": "MojitoServer", "type": "method", "name": "addMojitoToExpressApp"}, {"url": "Params.common.html#method_all", "access": "", "host": "Params.common", "type": "method", "name": "all"}, {"url": "Params.common.html#method_body", "access": "", "host": "Params.common", "type": "method", "name": "body"}, {"url": "MojitProxy.html#method_broadcast", "access": "", "host": "MojitProxy", "type": "method", "name": "broadcast"}, {"url": "MojitProxy.html#property_config", "access": "", "host": "MojitProxy", "type": "property", "name": "config"}, {"url": "Deploy.server.html#method_constructMojitoClientRuntime", "access": "", "host": "Deploy.server", "type": "method", "name": "constructMojitoClientRuntime"}, {"url": "MojitoServer.html#property_constructor", "access": "", "host": "MojitoServer", "type": "property", "name": "constructor"}, {"url": "MojitProxy.html#property_context", "access": "", "host": "MojitProxy", "type": "property", "name": "context"}, {"url": "MojitoServer.html#method_createServer", "access": "", "host": "MojitoServer", "type": "method", "name": "createServer"}, {"url": "Y.mojito.lib.REST.html#method_DELETE", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "DELETE"}, {"url": "Y.mojito.lib.REST.html#method_destroy", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "destroy"}, {"url": "MojitProxy.html#method_destroyChild", "access": "", "host": "MojitProxy", "type": "method", "name": "destroyChild"}, {"url": "MojitProxy.html#method_destroyChildren", "access": "", "host": "MojitProxy", "type": "method", "name": "destroyChildren"}, {"url": "MojitProxy.html#method_destroySelf", "access": "", "host": "MojitProxy", "type": "method", "name": "destroySelf"}, {"url": "Y.mojito.lib.REST.html#method_disable", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "disable"}, {"url": "Composite.common.html#method_done", "access": "", "host": "Composite.common", "type": "method", "name": "done"}, {"url": "Y.mojito.lib.REST.html#method_enable", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "enable"}, {"url": "Composite.common.html#method_execute", "access": "", "host": "Composite.common", "type": "method", "name": "execute"}, {"url": "ResourceStore.server.html#method_expandInstance", "access": "", "host": "ResourceStore.server", "type": "method", "name": "expandInstance"}, {"url": "ResourceStore.server.html#method_expandInstanceForEnv", "access": "", "host": "ResourceStore.server", "type": "method", "name": "expandInstanceForEnv"}, {"url": "MojitoServer.html#property_exports", "access": "", "host": "MojitoServer", "type": "property", "name": "exports"}, {"url": "OutputHandler.html#property_exports", "access": "", "host": "OutputHandler", "type": "property", "name": "exports"}, {"url": "ResourceStore.server.html#method_fileFromStaticHandlerURL", "access": "", "host": "ResourceStore.server", "type": "method", "name": "fileFromStaticHandlerURL"}, {"url": "Params.common.html#method_files", "access": "", "host": "Params.common", "type": "method", "name": "files"}, {"url": "Url.common.html#method_find", "access": "", "host": "Url.common", "type": "method", "name": "find"}, {"url": "Y.mojito.lib.REST.html#method_find", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "find"}, {"url": "Intl.common.html#method_formatDate", "access": "", "host": "Intl.common", "type": "method", "name": "formatDate"}, {"url": "Carrier.common.html#method_get", "access": "", "host": "Carrier.common", "type": "method", "name": "get"}, {"url": "Config.common.html#method_get", "access": "", "host": "Config.common", "type": "method", "name": "get"}, {"url": "Cookie.server.html#method_get", "access": "", "host": "Cookie.server", "type": "method", "name": "get"}, {"url": "Device.common.html#method_get", "access": "", "host": "Device.common", "type": "method", "name": "get"}, {"url": "Y.mojito.lib.REST.html#method_GET", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "GET"}, {"url": "Params.common.html#method_getAll", "access": "", "host": "Params.common", "type": "method", "name": "getAll"}, {"url": "ResourceStore.server.html#method_getAllMojits", "access": "", "host": "ResourceStore.server", "type": "method", "name": "getAllMojits"}, {"url": "ResourceStore.server.html#method_getAppConfig", "access": "", "host": "ResourceStore.server", "type": "method", "name": "getAppConfig"}, {"url": "Assets.common.html#method_getAssets", "access": "", "host": "Assets.common", "type": "method", "name": "getAssets"}, {"url": "Y.mojito.lib.REST.html#method_getBean", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "getBean"}, {"url": "Y.mojito.lib.REST.html#method_getBeans", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "getBeans"}, {"url": "MojitProxy.html#method_getChildren", "access": "", "host": "MojitProxy", "type": "method", "name": "getChildren"}, {"url": "Y.mojito.lib.REST.html#method_getComputedRoutes", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "getComputedRoutes"}, {"url": "Config.common.html#method_getDefinition", "access": "", "host": "Config.common", "type": "method", "name": "getDefinition"}, {"url": "Params.common.html#method_getFromBody", "access": "", "host": "Params.common", "type": "method", "name": "getFromBody"}, {"url": "Params.common.html#method_getFromMerged", "access": "", "host": "Params.common", "type": "method", "name": "getFromMerged"}, {"url": "Params.common.html#method_getFromRoute", "access": "", "host": "Params.common", "type": "method", "name": "getFromRoute"}, {"url": "MojitProxy.html#method_getFromUrl", "access": "", "host": "MojitProxy", "type": "method", "name": "getFromUrl"}, {"url": "Params.common.html#method_getFromUrl", "access": "", "host": "Params.common", "type": "method", "name": "getFromUrl"}, {"url": "Http.server.html#method_getHeader", "access": "", "host": "Http.server", "type": "method", "name": "getHeader"}, {"url": "Http.server.html#method_getHeaders", "access": "", "host": "Http.server", "type": "method", "name": "getHeaders"}, {"url": "ResourceStore.server.html#method_getInlineCssMojits", "access": "", "host": "ResourceStore.server", "type": "method", "name": "getInlineCssMojits"}, {"url": "ResourceStore.server.html#method_getMojitTypeDetails", "access": "", "host": "ResourceStore.server", "type": "method", "name": "getMojitTypeDetails"}, {"url": "Y.mojito.lib.REST.html#method_getName", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "getName"}, {"url": "Http.server.html#method_getRequest", "access": "", "host": "Http.server", "type": "method", "name": "getRequest"}, {"url": "Http.server.html#method_getResponse", "access": "", "host": "Http.server", "type": "method", "name": "getResponse"}, {"url": "ResourceStore.server.html#method_getRollupsApp", "access": "", "host": "ResourceStore.server", "type": "method", "name": "getRollupsApp"}, {"url": "ResourceStore.server.html#method_getRollupsMojits", "access": "", "host": "ResourceStore.server", "type": "method", "name": "getRollupsMojits"}, {"url": "ResourceStore.server.html#method_getRoutes", "access": "", "host": "ResourceStore.server", "type": "method", "name": "getRoutes"}, {"url": "I13n.server.html#method_getSpaceid", "access": "", "host": "I13n.server", "type": "method", "name": "getSpaceid"}, {"url": "ResourceStore.server.html#method_getSpec", "access": "", "host": "ResourceStore.server", "type": "method", "name": "getSpec"}, {"url": "ResourceStore.server.html#method_getType", "access": "", "host": "ResourceStore.server", "type": "method", "name": "getType"}, {"url": "Assets.common.html#method_getUrl", "access": "", "host": "Assets.common", "type": "method", "name": "getUrl"}, {"url": "ResourceStore.server.html#method_getYuiConfigAllMojits", "access": "", "host": "ResourceStore.server", "type": "method", "name": "getYuiConfigAllMojits"}, {"url": "ResourceStore.server.html#method_getYuiConfigApp", "access": "", "host": "ResourceStore.server", "type": "method", "name": "getYuiConfigApp"}, {"url": "ResourceStore.server.html#method_getYuiConfigFw", "access": "", "host": "ResourceStore.server", "type": "method", "name": "getYuiConfigFw"}, {"url": "Y.mojito.lib.REST.html#method_HEAD", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "HEAD"}, {"url": "MojitoServer.html#method_include", "access": "", "host": "MojitoServer", "type": "method", "name": "include"}, {"url": "MojitProxy.html#method_invoke", "access": "", "host": "MojitProxy", "type": "method", "name": "invoke"}, {"url": "Partial.common.html#method_invoke", "access": "", "host": "Partial.common", "type": "method", "name": "invoke"}, {"url": "Http.server.html#method_isXhr", "access": "", "host": "Http.server", "type": "method", "name": "isXhr"}, {"url": "Intl.common.html#method_lang", "access": "", "host": "Intl.common", "type": "method", "name": "lang"}, {"url": "ResourceStore.server.html#method_listAllMojits", "access": "", "host": "ResourceStore.server", "type": "method", "name": "listAllMojits"}, {"url": "MojitProxy.html#method_listen", "access": "", "host": "MojitProxy", "type": "method", "name": "listen"}, {"url": "I13n.server.html#method_make", "access": "", "host": "I13n.server", "type": "method", "name": "make"}, {"url": "Url.common.html#method_make", "access": "", "host": "Url.common", "type": "method", "name": "make"}, {"url": "Params.common.html#method_merged", "access": "", "host": "Params.common", "type": "method", "name": "merged"}, {"url": "Assets.common.html#method_mergeMetaInto", "access": "", "host": "Assets.common", "type": "method", "name": "mergeMetaInto"}, {"url": "Y.mojito.lib.REST.html#method_mergeRecursive", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "mergeRecursive"}, {"url": "Assets.common.html#method_mixAssets", "access": "", "host": "Assets.common", "type": "method", "name": "mixAssets"}, {"url": "MojitoServer.html#property__mojito", "access": "", "host": "MojitoServer", "type": "property", "name": "_mojito"}, {"url": "MojitProxy.html#property__mojito", "access": "", "host": "MojitProxy", "type": "property", "name": "_mojito"}, {"url": "Y.mojito.Client.html#method_pause", "access": "", "host": "Y.mojito.Client", "type": "method", "name": "pause"}, {"url": "Y.mojito.lib.REST.html#method_POST", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "POST"}, {"url": "ResourceStore.server.html#method_preload", "access": "", "host": "ResourceStore.server", "type": "method", "name": "preload"}, {"url": "Assets.common.html#method_preLoadImage", "access": "", "host": "Assets.common", "type": "method", "name": "preLoadImage"}, {"url": "Assets.common.html#method_preLoadImages", "access": "", "host": "Assets.common", "type": "method", "name": "preLoadImages"}, {"url": "Y.mojito.Client.html#property_prototype", "access": "", "host": "Y.mojito.Client", "type": "property", "name": "prototype"}, {"url": "Y.mojito.lib.REST.html#method_PUT", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "PUT"}, {"url": "Http.server.html#method_redirect", "access": "", "host": "Http.server", "type": "method", "name": "redirect"}, {"url": "MojitProxy.html#method_refreshView", "access": "", "host": "MojitProxy", "type": "method", "name": "refreshView"}, {"url": "Y.mojito.lib.REST.html#method_registerBean", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "registerBean"}, {"url": "MojitProxy.html#method_render", "access": "", "host": "MojitProxy", "type": "method", "name": "render"}, {"url": "Partial.common.html#method_render", "access": "", "host": "Partial.common", "type": "method", "name": "render"}, {"url": "Y.mojito.Client.html#method_resume", "access": "", "host": "Y.mojito.Client", "type": "method", "name": "resume"}, {"url": "Analytics.common.html#method_retrieve", "access": "", "host": "Analytics.common", "type": "method", "name": "retrieve"}, {"url": "Meta.common.html#method_retrieve", "access": "", "host": "Meta.common", "type": "method", "name": "retrieve"}, {"url": "Params.common.html#method_route", "access": "", "host": "Params.common", "type": "method", "name": "route"}, {"url": "Cookie.server.html#method_set", "access": "", "host": "Cookie.server", "type": "method", "name": "set"}, {"url": "Http.server.html#method_setHeader", "access": "", "host": "Http.server", "type": "method", "name": "setHeader"}, {"url": "Http.server.html#method_setHeaders", "access": "", "host": "Http.server", "type": "method", "name": "setHeaders"}, {"url": "ResourceStore.server.html#method_setLogger", "access": "", "host": "ResourceStore.server", "type": "method", "name": "setLogger"}, {"url": "Analytics.common.html#method_setMergeFunction", "access": "", "host": "Analytics.common", "type": "method", "name": "setMergeFunction"}, {"url": "Y.mojito.lib.REST.html#method_setRequestFormatter", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "setRequestFormatter"}, {"url": "Y.mojito.lib.REST.html#method_setResponseFormatter", "access": "", "host": "Y.mojito.lib.REST", "type": "method", "name": "setResponseFormatter"}, {"url": "I13n.server.html#method_stampPageView", "access": "", "host": "I13n.server", "type": "method", "name": "stampPageView"}, {"url": "Analytics.common.html#method_store", "access": "", "host": "Analytics.common", "type": "method", "name": "store"}, {"url": "Meta.common.html#method_store", "access": "", "host": "Meta.common", "type": "method", "name": "store"}, {"url": "Y.mojito.Client.html#method_subscribe", "access": "", "host": "Y.mojito.Client", "type": "method", "name": "subscribe"}, {"url": "I13n.server.html#method_trackClickOnly", "access": "", "host": "I13n.server", "type": "method", "name": "trackClickOnly"}, {"url": "I13n.server.html#method_trackForm", "access": "", "host": "I13n.server", "type": "method", "name": "trackForm"}, {"url": "I13n.server.html#method_trackLink", "access": "", "host": "I13n.server", "type": "method", "name": "trackLink"}, {"url": "I13n.server.html#method_trackPageParams", "access": "", "host": "I13n.server", "type": "method", "name": "trackPageParams"}, {"url": "I13n.server.html#method_trackUserLink", "access": "", "host": "I13n.server", "type": "method", "name": "trackUserLink"}, {"url": "MojitProxy.html#property_type", "access": "", "host": "MojitProxy", "type": "property", "name": "type"}, {"url": "MojitProxy.html#method_unlisten", "access": "", "host": "MojitProxy", "type": "method", "name": "unlisten"}, {"url": "Params.common.html#method_url", "access": "", "host": "Params.common", "type": "method", "name": "url"}] \ No newline at end of file diff --git a/docs/api/intl.common.js.html b/docs/api/intl.common.js.html index dbfad0ce5..7d509724b 100644 --- a/docs/api/intl.common.js.html +++ b/docs/api/intl.common.js.html @@ -2,23 +2,23 @@ - API: MojitoServer intl.common.js (YUI Library) + Mojito API: ActionContextAddon intl.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > intl.common.js (source view) @@ -48,10 +48,18 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true*/
    +/*global YUI*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-intl-addon', function(Y, NAME) {
     
    @@ -64,39 +72,46 @@ 

    MojitoServer  0.1.0

    this.ac = ac; } + IntlAddon.prototype = { namespace: 'intl', /** - * Returns translated string - * @method lang - * @param label {string} - * @return {string} translated string for label + * Returns translated string. + * @param label {string} The initial label to be translated. + * @param args {string|Array|Object} optional parameters for the string + * @return {string} translated string for label. */ - lang: function(label) { - //Y.log('lang(' + label + ') for ' + this.ac.type, 'debug', NAME); - return Y.Intl.get(this.ac.type, label); + lang: function(label, args) { + //Y.log('lang(' + label + ', ' + Y.JSON.stringify(args) + ') for ' + this.ac.type, 'debug', NAME); + Y.Intl.setLang(this.ac.type, this.ac.context.lang); + var string = Y.Intl.get(this.ac.type, label); + if (string && args) { + // simple string substitution + return Y.Lang.sub(string, Y.Lang.isString(args) ? [args] : args); + } + return string; }, + /** - * returns local-specified date - * @method formatDate - * @param date {Date} - * @return {string} formated data for language + * Returns local-specified date. + * @param {Date} date The initial date to be formatted. + * @return {string} formatted data for language. */ formatDate: function(date) { - //Y.log('Formatting date (' + date + ') in lang "' + this.language + '"', 'debug', NAME); - return Y.DataType.Date.format(date, {format: "%x"}); + //Y.log('Formatting date (' + date + ') in lang "' + + // this.ac.context.lang + '"', 'debug', NAME); + return Y.DataType.Date.format(date, {format: '%x'}); } - }; IntlAddon.dependsOn = ['config']; Y.mojito.addons.ac.intl = IntlAddon; -}, '0.1.0', {requires: [ +}, '0.3.0', {requires: [ 'intl', 'datatype-date', 'mojito', @@ -113,23 +128,29 @@

    MojitoServer  0.1.0

    Modules

    diff --git a/docs/api/io_facade.client-optional.js.html b/docs/api/io_facade.client-optional.js.html index 606656f18..cbe7f6077 100644 --- a/docs/api/io_facade.client-optional.js.html +++ b/docs/api/io_facade.client-optional.js.html @@ -2,23 +2,23 @@ - API: ActionContext io_facade.client-optional.js (YUI Library) + Mojito API: CommonLibs io_facade.client-optional.js ( - - + + - - + +
    -

    mojito

    -

    ActionContext  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > ActionContext + > CommonLibs > io_facade.client-optional.js (source view) @@ -47,138 +47,160 @@

    ActionContext  0.1.0

    -
    YUI.add('io-facade', function(Y) {
    +
    /*
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
    + */
     
    -	var NAME = 'ioFacade',
    -		Lang         = Y.Lang,
    -        isUndefined  = Lang.isUndefined,
     
    -        GET                 = "GET",
    -        PROXY_DATA_PARAM    = 'post',
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
    +YUI.add('io-facade', function(Y) {
    +
    +    var NAME = 'ioFacade',
    +        Lang = Y.Lang,
    +        isUndefined = Lang.isUndefined,
    +        GET = 'GET',
    +        PROXY_DATA_PARAM = 'post',
             DEFAULT_PROXY_TIMEOUT = 15000,
             _proxyTimeout = null,
    +        txTimes = {},
    +        cbs = {},   // keyed by txid
    +        // dependencies
    +        _configProvider,
    +        _transportUtils,
    +        DefaultIoFacade;
     
    -		txTimes = {},
     
    -        cbs = {},   // keyed by txid
    +    function _startClock(o) {
    +        txTimes[o] = new Date();
    +        // Y.log('Beginning request timer.', 'debug', NAME);
    +    }
     
    -        // dependencies
    -		_configProvider,
    -        _transportUtils;
    -
    -	function _startClock(o){
    -		txTimes[o] = new Date();
    -		// Y.log('Beginning request timer.', 'debug', NAME);
    -	}
    -	
    -   
    -	var DefaultIoFacade = function() {
    -		var inst = {
    -			
    -			setTransportUtils: function(utils) {
    -				_transportUtils = utils;
    -			},
    -			
    -			setConfigProvider: function(cfgProvider) {
    -				_configProvider = cfgProvider;
    -			},
    -			
    -	          /**
    -	           * Executes an io request
    -	           * @method execute
    -	           * @param {String} url Url to access
    -	           * @param {Object} data The data to send
    -	           * @param {String} method GET or POST
    -	           * @private
    -	           */
    -	          execute:function(txid, url, data, method, cb){
    -                  cbs[txid] = cb;
    -                  data.txid = txid;
    -
    -				  if (!_proxyTimeout) {
    -				  	  _proxyTimeout = _configProvider.getProxyTimeout() || DEFAULT_PROXY_TIMEOUT;
    -				  }
    -
    -	              url = (method == GET) ? _transportUtils.formatUrl(url,'&__r=' +  new Date().getTime()) : url;
    -	
    -	              var cfg = {
    -	                  method:method,
    -	                  data: data,
    -	                  on:{
    -	                      success:this.handleResponse,
    -	                      failure:this.handleResponse,
    -	                      start:_startClock,
    -						  scope:this
    -	                  },
    -					  context: this,
    -	                  timeout:_proxyTimeout,
    -                      
    -                      // TODO: Refactor Dali to pass through the params instead
    -                      // of doing this here
    -                      headers : {'Content-Type' : 'application/json'}
    -	              };
    -	
    -	              
    -	
    -	             // Y.log('Handing off request to YUI io.', 'info', NAME);
    -	             //var start = timer();
    -	
    -	             var req = Y.io(url, cfg);
    -	             //save start time for profiling.
    -	
    -	             return req;
    -	          },
    -	  
    -		     /**
    -	          * simulate a server response
    -	          * @private
    -	          * @method simulateResponse
    -	          * @param {Number} id the id of the transaction
    -	          * @param {Object} details the details of the response
    -	          * @param {Boolean} badcookie Optional. If true simulate cookies turned off
    -	          * @private
    -	          */
    -	         _simulateResponse:function(id, details, badcookie){
    -	             
    -	             //this is needed, because this method should always be present,
    -	             //testing for it will fail in IE6 because of the COM+ bridge
    -	             details.getResponseHeader = function(){ return '';};
    -	             
    -	             if(badcookie){
    -	                 this.handleResponse(id, details, true);
    -	             }else{
    -	                 this.handleResponse(id, details, false);
    -	             }
    -	             
    -	         },
    -
    -		    handleResponse : function(id, o, badcookie){
    -		        var time = (new Date()) - txTimes[id],
    +
    +    DefaultIoFacade = function() {
    +        var inst = {
    +
    +            setTransportUtils: function(utils) {
    +                _transportUtils = utils;
    +            },
    +
    +
    +            setConfigProvider: function(cfgProvider) {
    +                _configProvider = cfgProvider;
    +            },
    +
    +
    +            /**
    +             * Executes an io request.
    +             * @param {String} url Url to access.
    +             * @param {Object} data The data to send.
    +             * @param {String} method GET or POST.
    +             * @private
    +             */
    +            execute: function(txid, url, data, method, cb) {
    +                var cfg,
    +                    start,
    +                    req;
    +
    +                cbs[txid] = cb;
    +                data.txid = txid;
    +
    +                if (!_proxyTimeout) {
    +                    _proxyTimeout = _configProvider.getProxyTimeout() ||
    +                        DEFAULT_PROXY_TIMEOUT;
    +                }
    +
    +                // TODO: Don't assign to a parameter.
    +                url = (method === GET) ?
    +                        _transportUtils.formatUrl(url, '&__r=' +
    +                            new Date().getTime()) :
    +                        url;
    +
    +                cfg = {
    +                    method: method,
    +                    data: data,
    +                    on: {
    +                        success: this.handleResponse,
    +                        failure: this.handleResponse,
    +                        start: _startClock,
    +                        scope: this
    +                    },
    +                    context: this,
    +                    timeout: _proxyTimeout,
    +
    +                    // TODO: Refactor Dali to pass through the params instead
    +                    // of doing this here.
    +                    headers: {'Content-Type' : 'application/json'}
    +                };
    +
    +                // Y.log('Handing off request to YUI io.', 'info', NAME);
    +                // start = timer();
    +
    +                req = Y.io(url, cfg);
    +
    +                //save start time for profiling.
    +                return req;
    +            },
    +
    +
    +            /**
    +             * Simulate a server response
    +             * @param {Number} id the id of the transaction.
    +             * @param {Object} details the details of the response.
    +             * @param {Boolean} badcookie Optional. If true simulate cookies
    +             *     turned off.
    +             * @private
    +             */
    +            _simulateResponse: function(id, details, badcookie) {
    +                //this is needed, because this method should always be present,
    +                //testing for it will fail in IE6 because of the COM+ bridge
    +                details.getResponseHeader = function() { return ''; };
    +
    +                if (badcookie) {
    +                    this.handleResponse(id, details, true);
    +                } else {
    +                    this.handleResponse(id, details, false);
    +                }
    +            },
    +
    +
    +            handleResponse: function(id, o, badcookie) {
    +                var time = (new Date()) - txTimes[id],
                         respData = Y.JSON.parse(o.responseText),
                         txId = respData.resps[0].txId,
    -				    callback = cbs[txId];
    +                    callback = cbs[txId];
    +
                     delete cbs[txId];
    -		        this.fire('transactionResponse', {
    -		            type: 'transactionResponse',
    -		            id: id,
    -		            resp: o,
    +                this.fire('transactionResponse', {
    +                    type: 'transactionResponse',
    +                    id: id,
    +                    resp: o,
                         responseData: respData,
    -		            badcookie: badcookie,
    -		            cb: callback,
    -		            time: time
    -		        }, NAME);
    -		        // Y.log('Request success received, stopping timer. Length: ' + time + 'ms', 'debug', NAME);
    -		    }
    -		};
    -		
    -		return new Y.Dali.Bean(inst);
    -	};
    -	
    -	DefaultIoFacade.NAME = NAME;
    -	
    -	Y.Dali.beanRegistry.registerBean(NAME, DefaultIoFacade);
    -	
    -}, '1.6.3', {requires:['breg', 'dali-bean']});
    +                    badcookie: badcookie,
    +                    cb: callback,
    +                    time: time
    +                },
    +                    NAME);
    +                // Y.log('Request success received, stopping timer. Length: ' +
    +                //     time + 'ms', 'debug', NAME);
    +            }
    +        };
    +
    +        return new Y.Dali.Bean(inst);
    +    };
    +
    +    DefaultIoFacade.NAME = NAME;
    +
    +    Y.Dali.beanRegistry.registerBean(NAME, DefaultIoFacade);
    +
    +}, '1.6.3', {requires: [
    +    'breg',
    +    'dali-bean'
    +]});
     
    @@ -189,9 +211,9 @@

    ActionContext  0.1.0

    diff --git a/docs/api/loader.common.js.html b/docs/api/loader.common.js.html index 1233480f6..4dfd2de57 100644 --- a/docs/api/loader.common.js.html +++ b/docs/api/loader.common.js.html @@ -2,23 +2,23 @@ - API: MojitoClient loader.common.js (YUI Library) + Mojito API: ActionContext loader.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoClient  0.1.0

    +

    mojito

    +

    ActionContext  0.3.0

    mojito - > MojitoClient + > ActionContext > loader.common.js (source view) @@ -48,133 +48,190 @@

    MojitoClient  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
     YUI.add('mojito-loader', function(Y, NAME) {
     
    +    // IE has a limit of 2048-character long URLs.
    +    var MAX_URL_LENGTH = 2000;
     
    -    function Loader(appConfig) {
    +    function Loader(appConfig, prefix) {
             // Y.log('ctor()', 'mojito', NAME);
             this.appConfig = appConfig;
    +        this.prefix = prefix || ''; // optional
         }
     
     
         Loader.prototype = {
     
             load: function(paths, cb) {
    -            //Y.log('load(' + Y.Object.keys(paths).join(', ') + ')', 'mojito', NAME);
                 var self = this,
    -                mod, scriptsToLoad = {}, loaded = 0;
    +                mod,
    +                script,
    +                scriptsToLoad = {},
    +                loaded = 0;
     
                 paths = paths || {};
    -            if (! Y.Object.size(paths)) {
    +            if (!Y.Object.size(paths)) {
                     cb(null);
                     return;
                 }
     
                 for (mod in paths) {
                     if (paths.hasOwnProperty(mod)) {
    -                    if (YUI.Env.mods[mod]) {
    -                        continue;
    -                    }
    -                    script = paths[mod];
    -                    if (script) {
    -                        if ('.js' !== script.substr(-3).toLowerCase()) {
    -                            continue;
    +                    if (!YUI.Env.mods[mod]) {
    +                        script = paths[mod];
    +                        if (script) {
    +                            if ('.js' === script.substr(-3).toLowerCase()) {
    +                                if ('/' === script.charAt(0)) {
    +                                    script = this.prefix + script;
    +                                }
    +                                scriptsToLoad[script] = true;
    +                            }
                             }
    -                        scriptsToLoad[script] = true;
                         }
                     }
                 }
                 scriptsToLoad = Y.Object.keys(scriptsToLoad);
    -            if (! scriptsToLoad.length) {
    +            if (!scriptsToLoad.length) {
                     return cb(null);
                 }
    +
                 Y.log('loading ' + scriptsToLoad.join(', '), 'mojito', NAME);
    +
                 Y.Get.script(scriptsToLoad, {
                     async: true,
    +
                     onSuccess: function() {
                         var done = false;
    -                    // --- ON CLIENT
    +
                         if (typeof window !== 'undefined') {
    +                        // --- ON CLIENT
                             done = true;
    -                    }
    -                    // --- ON SERVER
    -                    else {
    -                        loaded++;
    +                    } else {
    +                        // --- ON SERVER
    +                        loaded += 1;
                             if (loaded === scriptsToLoad.length) {
                                 done = true;
                             }
                         }
    +
                         if (done) {
                             Y.log('SUCCESS', 'mojito', NAME);
                             cb(null);
                         }
                     },
    +
                     onFailure: function() {
                         Y.log('FAILURE', 'warn', NAME);
    -                    var err = new Error('Failed to load URLs:  ' + scriptsToLoad.join(', '));
    +                    var err = new Error('Failed to load URLs:  ' +
    +                            scriptsToLoad.join(', '));
                         cb(err);
                     }
                 });
    +        },
     
    +
    +        _createURLlist: function(base, list) {
    +            var url, urls = [],
    +                newPart, newLength;
    +            if (!list.length) {
    +                return [];
    +            }
    +            url = base + list.shift();
    +            while (list.length) {
    +                newPart = list.shift();
    +                newLength = url.length + 1 + newPart.length;
    +                if (newLength > MAX_URL_LENGTH) {
    +                    urls.push(url);
    +                    url = base + newPart;
    +                } else {
    +                    url += '&' + newPart;
    +                }
    +            }
    +            urls.push(url);
    +            return urls;
             },
     
     
    +
             // this also pulls in dependencies
             createYuiLibComboUrl: function(modules, filter) {
    -            var required = {}, comboJsParts = [], comboCssParts = [],
    -                loader, filterDef, filterDefSearchExp,
    -                i, name, info, filteredPath, combo = {};
    +            var required = {},
    +                comboJsParts = [],
    +                comboCssParts = [],
    +                loader,
    +                filterDef,
    +                filterDefSearchExp,
    +                i,
    +                name,
    +                info,
    +                filteredPath,
    +                combo = { js: [], css: [] };
    +
                 filter = filter || 'min';
     
                 loader = new Y.Loader({});
    -            for (i=0; i<modules.length; i++) {
    +            for (i = 0; i < modules.length; i += 1) {
                     name = modules[i];
                     required[name] = true;
                 }
                 loader.ignoreRegistered = true;
    -            loader.calculate({required:required});
    +            loader.calculate({required: required});
    +
    +            // workaround for a bug fixed in yui-3.5.0
    +            Object.keys(loader.moduleInfo).forEach(function(module) {
    +                var m = loader.moduleInfo[module];
    +                YUI.Env._renderedMods[module] = m;
    +            });
     
                 filterDef = loader.FILTER_DEFS[filter.toUpperCase()];
                 if (filterDef) {
                     filterDefSearchExp = new RegExp(filterDef.searchExp);
                 }
     
    -            for (i=0; i<loader.sorted.length; i++) {
    +            for (i = 0; i < loader.sorted.length; i += 1) {
                     name = loader.sorted[i];
    -                if (('parallel' === name) || (name.indexOf('nodejs') > -1)) {
    -                    // not appropriate for client environment
    -                    continue;
    -                }
    -                info = loader.moduleInfo[name];
    -                if (info) {
    -                    filteredPath = (filterDef) ? info.path.replace(filterDefSearchExp, filterDef.replaceStr) : info.path;
    -                    if ('lang/datatype-date' === name) {
    -                        // this one is messed up
    -                        filteredPath = 'datatype/lang/datatype-date.js';
    -                    }
    -                    if ('js' === info.type) {
    -                        comboJsParts.push(loader.root + filteredPath);
    -                    }
    -                    else if ('css' === info.type) {
    -                        comboCssParts.push(loader.root + filteredPath);
    +                if (('parallel' !== name) && (name.indexOf('nodejs') === -1)) {
    +                    info = loader.moduleInfo[name];
    +                    if (info) {
    +                        filteredPath = (filterDef) ?
    +                                info.path.replace(filterDefSearchExp,
    +                                    filterDef.replaceStr) :
    +                                info.path;
    +
    +                        if ('lang/datatype-date' === name) {
    +                            // this one is messed up
    +                            filteredPath = 'datatype/lang/datatype-date.js';
    +                        }
    +
    +                        if ('js' === info.type) {
    +                            comboJsParts.push(loader.root + filteredPath);
    +                        } else if ('css' === info.type) {
    +                            comboCssParts.push(loader.root + filteredPath);
    +                        }
                         }
                     }
                 }
    -            combo.js = loader.comboBase + comboJsParts.join('&');
    -            if (comboCssParts.length) {
    -                combo.css = loader.comboBase + comboCssParts.join('&');
    -            }
    +            combo.js = this._createURLlist(loader.comboBase, comboJsParts);
    +            combo.css = this._createURLlist(loader.comboBase, comboCssParts);
                 return combo;
             }
    -
    -
         };
     
         Y.mojito.Loader = Loader;
     
    -}, '0.1.0', {requires: ['get', 'mojito']});
    +}, '0.3.0', {requires: [
    +    'get',
    +    'mojito'
    +]});
     
    @@ -185,10 +242,10 @@

    MojitoClient  0.1.0

    @@ -196,8 +253,7 @@

    Modules

    @@ -205,18 +261,11 @@

    Classes

    --> @@ -234,7 +283,7 @@

    Files

    diff --git a/docs/api/logger.common.js.html b/docs/api/logger.common.js.html index eef4db707..621a8d20d 100644 --- a/docs/api/logger.common.js.html +++ b/docs/api/logger.common.js.html @@ -2,23 +2,23 @@ - API: MojitoClient logger.common.js (YUI Library) + Mojito API: ActionContext logger.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoClient  0.1.0

    +

    mojito

    +

    ActionContext  0.3.0

    mojito - > MojitoClient + > ActionContext > logger.common.js (source view) @@ -48,11 +48,19 @@

    MojitoClient  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     YUI.add('mojito-logger', function(Y, NAME) {
     
    -    // TODO MATT 2011-06-20: [bug 4647494] Clean up the logger implementation
    +    // TODO: [Issue 70] Clean up the logger implementation.
     
         var isYuiLog = /^yui/,
             LOG_LEVEL = 'info',
    @@ -67,7 +75,7 @@ 

    MojitoClient  0.1.0

    buffer: false, maxBufferSize: 1024, order: [ - 'DEBUG','MOJITO','INFO','WARN','ERROR','NONE' + 'DEBUG', 'MOJITO', 'INFO', 'WARN', 'ERROR', 'NONE' ], filter: { DEBUG: true, @@ -79,15 +87,16 @@

    MojitoClient  0.1.0

    } }; + defaults.writer = function(data) { - var i=0; + var i = 0; if (!console || !console.log) { // not much to do if I can't console.log. Sorry, IE6 return; } if (Y.Lang.isArray(data)) { // this is a flush of many logs - for (; i<data.length; i++) { + for (i = 0; i < data.length; i += 1) { console.log(data[i]); } } else { @@ -95,9 +104,12 @@

    MojitoClient  0.1.0

    } }; + defaults.formatter = function(msg, lvl, source, timestamp, opts, id) { - var ts = opts.timestamp ? '('+timestamp+') ' : '', - code = '', stack = ''; + var ts = opts.timestamp ? '(' + timestamp + ') ' : '', + code = '', + stack = ''; + if (msg instanceof Error) { if (msg.code) { code = ' ' + msg.code; @@ -113,8 +125,10 @@

    MojitoClient  0.1.0

    return '[' + lvl.toUpperCase() + '] ' + ts + source + msg; }; + function Logger(opts, id) { - var cnt = 0, order, + var cnt = 0, + order, lvl; this._opts = Y.merge(defaults, opts); @@ -127,7 +141,7 @@

    MojitoClient  0.1.0

    order = this._opts.order || []; lvl = this._opts.level.toLowerCase(); - for (; cnt<order.length; cnt++) { + for (cnt = 0; cnt < order.length; cnt += 1) { this._opts.filter[order[cnt]] = true; } cnt = 0; @@ -137,22 +151,23 @@

    MojitoClient  0.1.0

    } else { break; } - cnt++; + cnt += 1; } //Hmm... If the count is the same length as the order list we mean NONE - if(cnt === order.length){ + if (cnt === order.length) { logNothingAtAllEver = true; } - if(this._opts.filter.DEBUG){ - if(!YUI._mojito){ + if (this._opts.filter.DEBUG) { + if (!YUI._mojito) { YUI._mojito = {}; } YUI._mojito.DEBUG = true; } } + Logger.prototype = { log: function(msg, lvl, source) { @@ -162,7 +177,7 @@

    MojitoClient  0.1.0

    baseLevel, now; - if(logNothingAtAllEver){ + if (logNothingAtAllEver) { return; } @@ -178,12 +193,12 @@

    MojitoClient  0.1.0

    baseLevel = isYui ? level.split('-').pop() : level; // the fat filter strips out log calls below current base log level - if (! this._opts.filter[baseLevel.toUpperCase()]) { + if (!this._opts.filter[baseLevel.toUpperCase()]) { return; } // this strips out all YUI logs if the 'showYui' option is false - if (isYui && ! this._opts.yui) { + if (isYui && !this._opts.yui) { return; } @@ -198,6 +213,7 @@

    MojitoClient  0.1.0

    } }, + flush: function() { var log, logs = []; if (this._opts.publisher) { @@ -205,37 +221,47 @@

    MojitoClient  0.1.0

    } else { while (this._buffer.length) { log = this._buffer.shift(); - logs.push(this._opts.formatter(log[0], log[1], log[2], log[3], this._opts, this._id)); + logs.push(this._opts.formatter(log[0], log[1], log[2], + log[3], this._opts, this._id)); } this._opts.writer(logs); } this._buffer = []; }, + setFormatter: function(f) { this._opts.formatter = f; }, + + setWriter: function(w) { this._opts.writer = w; }, + + setPublisher: function(p) { console.log('publisher set: ' + p.toString()); this._opts.publisher = p; }, + _publish: function(msg, lvl, src, ts) { //console.log('default publisher'); if (this._opts.publisher) { this._opts.publisher(msg, lvl, src, ts, this._id); } else { - this._opts.writer(this._opts.formatter(msg, lvl, src, ts, this._opts, this._id)); + this._opts.writer(this._opts.formatter(msg, lvl, src, ts, + this._opts, this._id)); } } }; Y.mojito.Logger = Logger; -}, '0.1.0', {requires: ['mojito']}); +}, '0.3.0', {requires: [ + 'mojito' +]});
    @@ -246,10 +272,10 @@

    MojitoClient  0.1.0

    @@ -257,8 +283,7 @@

    Modules

    @@ -266,18 +291,11 @@

    Classes

    --> @@ -295,7 +313,7 @@

    Files

    diff --git a/docs/api/meta.common.js.html b/docs/api/meta.common.js.html index 6614223af..bd6f34fe9 100644 --- a/docs/api/meta.common.js.html +++ b/docs/api/meta.common.js.html @@ -2,21 +2,21 @@ - API: ActionContextAddon meta.common.js (YUI Library) + Mojito API: ActionContextAddon meta.common.js ( - - + + - - + +
    -

    mojito

    -

    ActionContextAddon  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito > ActionContextAddon @@ -48,19 +48,28 @@

    ActionContextAddon  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-meta-addon', function(Y, NAME) {
     
         var COMMON = 'common';
     
    +
         /**
          * <strong>Access point:</strong> <em>ac.meta.*</em>
    -     * Allows the usage of the "meta" object as a storage device, which can pass data from
    -     * child mojits up towards parents.
    +     * Allows the usage of the "meta" object as a storage device, which can pass
    +     * data from child mojits up towards parents.
          * @class Meta.common
          */
         function MetaAddon(command, adapter, ac) {
    @@ -68,6 +77,7 @@ 

    ActionContextAddon  0.1.0

    this[COMMON] = {}; } + MetaAddon.prototype = { namespace: 'meta', @@ -75,39 +85,39 @@

    ActionContextAddon  0.1.0

    /** * Stores a keyed value within the meta object of the current mojit * execution. You can call this as many times as you like, but - * if you use the same key, you'll override previous data. Call this within - * child mojits when you have some data you want to make available for - * some reason to any parents up your hierarchy. - * - * @method store - * @param {string} key - * @param {object} val + * if you use the same key, you'll override previous data. Call this + * within child mojits when you have some data you want to make + * available for some reason to any parents up your hierarchy. + * @param {string} key The key used as the index value. + * @param {object} val The value to store. */ store: function(key, val) { this[COMMON][key] = val; }, + /** * To retrieve stashed data that has been stored by child mojits, call - * this function and provide a function, which will be called once the children - * have been dispatched and all their meta data has been merged. - * - * @method retrieve - * @param {function} cb callback will be called with the stored merged object - * @param {object} [optional] scope scope of the callback + * this function and provide a function, which will be called once the + * children have been dispatched and all their meta data has been + * merged. + * @param {function} cb callback will be called with the stored merged + * object. + * @param {object} [optional] scope scope of the callback. */ retrieve: function(cb, scope) { this._callback = cb; this._cbScope = scope; }, - // internal to Mojito + mergeMetaInto: function(meta) { var scope = this._cbScope || this; - if (! meta[COMMON]) { + if (!meta[COMMON]) { meta[COMMON] = this[COMMON]; } else { - meta[COMMON] = Y.mojito.util.metaMerge(meta[COMMON], this[COMMON]); + meta[COMMON] = Y.mojito.util.metaMerge(meta[COMMON], + this[COMMON]); } if (this._callback) { this._callback.call(scope, meta[COMMON]); @@ -117,10 +127,13 @@

    ActionContextAddon  0.1.0

    }; MetaAddon.dependsOn = ['core']; - + Y.mojito.addons.ac.meta = MetaAddon; -}, '0.1.0', {requires: ['mojito-util', 'mojito-output-adapter-addon']}); +}, '0.3.0', {requires: [ + 'mojito-util', + 'mojito-output-adapter-addon' +]});
    @@ -145,10 +158,19 @@

    Classes

  • Analytics.common
  • Assets.common
  • Carrier.common
  • +
  • Composite.common
  • +
  • Config.common
  • +
  • Cookie.client
  • +
  • Cookie.server
  • Deploy.server
  • Device.common
  • +
  • Http.server
  • I13n.server
  • +
  • Intl.common
  • Meta.common
  • +
  • Params.common
  • +
  • Partial.common
  • +
  • Url.common
  • @@ -156,14 +178,25 @@

    Classes

    --> @@ -181,7 +214,7 @@

    Files

    diff --git a/docs/api/module_ActionContext.html b/docs/api/module_ActionContext.html index 592f92194..abc0491c1 100644 --- a/docs/api/module_ActionContext.html +++ b/docs/api/module_ActionContext.html @@ -2,21 +2,21 @@ - API: ActionContext (YUI Library) + Mojito API: ActionContext ( - - + + - - + +
    -

    mojito

    -

    ActionContext  0.1.0

    +

    mojito

    +

    ActionContext  0.3.0

    mojito > ActionContext @@ -50,9 +50,10 @@

    Module: ActionContext

    - The Action Context is a key part of the Mojito framework. The ac, for short, gives you access -to the frameworks features from within a controller function. The ac is an abstraction that -allows you to execute mojit actions within either a server or client context. + The Action Context is a key part of the Mojito framework. The ac, +for short, gives you access to the frameworks features from within a +controller function. The ac is an abstraction that allows you to execute +mojit actions within either a server or client context.
    @@ -62,11 +63,11 @@

    Module: ActionContext

    This module contains the following classes:

    @@ -94,7 +95,7 @@

    Modules

    @@ -102,17 +103,11 @@

    Classes

    --> @@ -130,7 +125,7 @@

    Files

    diff --git a/docs/api/module_ActionContextAddon.html b/docs/api/module_ActionContextAddon.html index 2302d46cc..9e6a3cc9b 100644 --- a/docs/api/module_ActionContextAddon.html +++ b/docs/api/module_ActionContextAddon.html @@ -2,21 +2,21 @@ - API: ActionContextAddon (YUI Library) + Mojito API: ActionContextAddon ( - - + + - - + +
    -

    mojito

    -

    ActionContextAddon  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito > ActionContextAddon @@ -50,10 +50,11 @@

    Module: ActionContextAddon

    - The Action Context uses a mechanism called Addons -to provide functionality that lives both -on the server and/or client. Each Addon provides additional functions through a namespace -that is attached directly to the ac argument available in every controller function. + The Action Context uses a mechanism called +Addons to provide functionality that lives both on +the server and/or client. Each Addon provides additional functions through a +namespace that is attached directly to the ac argument available in every +controller function.
    @@ -63,18 +64,26 @@

    Module: ActionContextAddon

    This module contains the following classes:

    @@ -105,10 +114,19 @@

    Classes

  • Analytics.common
  • Assets.common
  • Carrier.common
  • +
  • Composite.common
  • +
  • Config.common
  • +
  • Cookie.client
  • +
  • Cookie.server
  • Deploy.server
  • Device.common
  • +
  • Http.server
  • I13n.server
  • +
  • Intl.common
  • Meta.common
  • +
  • Params.common
  • +
  • Partial.common
  • +
  • Url.common
  • @@ -116,14 +134,25 @@

    Classes

    --> @@ -141,7 +170,7 @@

    Files

    diff --git a/docs/api/module_CommonLibs.html b/docs/api/module_CommonLibs.html index 7d6b2884a..469f7f9fc 100644 --- a/docs/api/module_CommonLibs.html +++ b/docs/api/module_CommonLibs.html @@ -2,21 +2,21 @@ - API: CommonLibs (YUI Library) + Mojito API: CommonLibs ( - - + + - - + +
    -

    mojito

    -

    CommonLibs  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito > CommonLibs @@ -60,7 +60,7 @@

    Module: CommonLibs

    This module contains the following classes:

    diff --git a/docs/api/module_MojitoClient.html b/docs/api/module_MojitoClient.html index eb1d72362..2fe822ff2 100644 --- a/docs/api/module_MojitoClient.html +++ b/docs/api/module_MojitoClient.html @@ -2,21 +2,21 @@ - API: MojitoClient (YUI Library) + Mojito API: MojitoClient ( - - + + - - + +
    -

    mojito

    -

    MojitoClient  0.1.0

    +

    mojito

    +

    MojitoClient  0.3.0

    mojito > MojitoClient @@ -50,7 +50,9 @@

    Module: MojitoClient

    - Client side Mojito runtime + The starting point for mojito to run in the browser. You can access one +instance of the Mojito Client running within the browser environment +through window.YMojito.client.
    @@ -60,12 +62,12 @@

    Module: MojitoClient

    This module contains the following classes:

    @@ -93,8 +95,8 @@

    Modules

    @@ -102,18 +104,14 @@

    Classes

    --> @@ -131,7 +129,7 @@

    Files

    diff --git a/docs/api/module_MojitoServer.html b/docs/api/module_MojitoServer.html index 45f9169b7..35fee05d3 100644 --- a/docs/api/module_MojitoServer.html +++ b/docs/api/module_MojitoServer.html @@ -2,21 +2,21 @@ - API: MojitoServer (YUI Library) + Mojito API: MojitoServer ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    MojitoServer  0.3.0

    mojito > MojitoServer @@ -50,7 +50,79 @@

    Module: MojitoServer

    - The Mojito Server bootstrap + The Resource Store manages information about the "resources" in a Mojito +application. These resources are things that have representation on the +filesystem. +Each resource can have many different versions. This is not talking about +revisions, which is how the resource changes over time. It is instead +talking about how there can be a version of the resource just for iphones, +one just for android, a fallback, etc. +There are various types of resources: +
    +config      -- a piece of configuration, sometimes for another resource
    +controller  -- the controller for a mojit
    +model       -- a model for a mojit
    +view        -- a view for a mojit
    +binder      -- a binder for a mojit
    +action      -- an action to augment the controller
    +asset       -- an asset (css, js, image, etc)
    +addon       -- an addon to the mojito system
    +spec        -- the configuration for a mojit instance
    +yui-lang    -- a YUI3 language bundle
    +yui-module  -- a YUI3 module (that isn't one of the above)
    +
    +The metadata kept about each resource is "normalized" to the follow keys: +(not all resources will have all keys) +(some types will have additional keys) +(not all combinations of type:source are valid) +
    +- id
    +context-insensitive ID of the resource
    +said another way, all versions of a resource have the same ID
    +- type
    +see above
    +- source
    +`fw`, `app` or `mojit`
    +where the resource is defined
    +- fsPath
    +the path on the filesystem
    +- staticHandlerURL
    +the URL that will cause the asset handler to serve the resource
    +for resources that can be deployed by reference to the client
    +- name
    +specific to type
    +- configType
    +for type=config
    +the type of the configuration
    +- viewEngine
    +for type=view
    +`mu`, `dust`, etc
    +- viewOutputFormat
    +for type=view
    +output format that the view will generate
    +`xml`, `html`, etc
    +- assetType
    +for type=asset
    +`css`, `js`, `png`, `swf`, etc
    +- addonType
    +for type=addon
    +the mojito subsystem to which the addon should be added
    +- yuiModuleName
    +for any resource delivered as a YUI3 module
    +the YUI3 module name
    +- yuiModuleVersion
    +for any resource delivered as a YUI3 module
    +the YUI3 module version
    +- yuiModuleMeta
    +for any resource delivered as a YUI3 module
    +the YUI3 module metadata
    +(requires, langs, etc)
    +- yuiSortedPaths
    +for any resource delivered as a YUI3 module
    +a list of YUI modules required by the module,
    +with transitive dependencies resolved
    +format:  { yui-module-name: URL-to-load-yui-module }
    +
    @@ -60,20 +132,13 @@

    Module: MojitoServer

    This module contains the following classes:

    @@ -101,16 +166,9 @@

    Modules

    @@ -119,27 +177,11 @@

    Classes

    Files

    --> @@ -157,7 +199,7 @@

    Files

    diff --git a/docs/api/mojit-proxy.client.js.html b/docs/api/mojit-proxy.client.js.html index c7c26b10e..047654892 100644 --- a/docs/api/mojit-proxy.client.js.html +++ b/docs/api/mojit-proxy.client.js.html @@ -2,23 +2,23 @@ - API: MojitoClient mojit-proxy.client.js (YUI Library) + Mojito API: ActionContext mojit-proxy.client.js ( - - + + - - + +
    -

    mojito

    -

    MojitoClient  0.1.0

    +

    mojito

    +

    ActionContext  0.3.0

    mojito - > MojitoClient + > ActionContext > mojit-proxy.client.js (source view) @@ -48,35 +48,40 @@

    MojitoClient  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
     
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
      * Client side Mojito runtime
      * @module MojitoClient
      */
    -
    -/**
    - * @submodule MojitoClient
    - */
    -
     YUI.add('mojito-mojit-proxy', function(Y, NAME) {
     
    -    var MJT_EVT_PRFX = 'mojit:';
    +    var MJT_EVT_PRFX = 'mojit:',
    +        DALI_API_METHODS;
    +
     
    -    // TODO MATT: [bug 4649682] Implement all these damn Dali API functions on the mojit proxy
    -    // (but only when as need them :-)
    -    var DALI_API_METHODS = [
    -        "broadcast", "listen", "unlisten", "closeView", "getViewNode",
    -        "getViewDirection", "isViewOpen", "navigate", "openView", "makeRequest",
    -        "refreshView", "setView", "abortRequest", "error", "getContextData",
    -        "getId", "getPref", "getService", "isRequestPending", "setContextData",
    -        "setPref"
    +    // TODO: [Issue 71] Implement all these Dali API functions on the
    +    // mojit proxy (but only when as need them :-)
    +    DALI_API_METHODS = [
    +        'broadcast', 'listen', 'unlisten', 'closeView', 'getViewNode',
    +        'getViewDirection', 'isViewOpen', 'navigate', 'openView', 'makeRequest',
    +        'refreshView', 'setView', 'abortRequest', 'error', 'getContextData',
    +        'getId', 'getPref', 'getService', 'isRequestPending', 'setContextData',
    +        'setPref'
         ];
     
    +
         /**
    -     * The object that is given to each mojit binder to be used to interact with other mojits
    -     * and the mojito framework.
    +     * The object that is given to each mojit binder to be used to interact with
    +     * other mojits and the mojito framework.
          * @class MojitProxy
          */
         function MojitProxy(opts) {
    @@ -91,38 +96,34 @@ 

    MojitoClient  0.1.0

    this._client = opts.client; this._store = opts.store; - /** - * An object that contains information about the children used to generate this DOM node associted with this - * binder. This should identify what mojits may exist as children within this binder's domain. You can use it - * to broadcast messages directly to certain children as explained in the topical documentation. - * @property children - * @type {object} - */ - this.children = opts.children; + /** * The mojit type - * @property type * @type {string} */ + + this.type = opts.type; /** * The mojit configuration for this binder - * @property config * @type {object} */ this.config = opts.config; + + /** * The context used to generate this page - * @property context * @type {object} */ this.context = opts.context; + Y.Array.each(DALI_API_METHODS, function(m) { - if (! this[m]) { + if (!this[m]) { //Y.log('Stubbing Dali platform method: ' + m, 'debug', NAME); this[m] = function() { - throw new Error("Function not implemented: " + m); + // Mojito is not DALI + throw new Error('Function not implemented: ' + m); }; } }, this); @@ -133,60 +134,67 @@

    MojitoClient  0.1.0

    /** * Used by mojit binders to broadcast a message between mojits. - * @method broadcast - * @param {String} name event name - * @param {Object} payload the payload for the event + * @param {String} name event name. + * @param {Object} payload the payload for the event. * @param {object} options currently only used to specify target for - * broadcast. For example, to target only one child mojit for broadcast, - * use: {target: {slot: 'slot name', viewId: 'DOM view id'}} + * broadcast. For example, to target only one child mojit for + * broadcast, use: + * {target: {slot: 'slot name', viewId: 'DOM view id'}}. */ broadcast: function(name, payload, options) { - this._client.doBroadcast(MJT_EVT_PRFX + name, this._viewId, payload, options); + this._client.doBroadcast(MJT_EVT_PRFX + name, + this._viewId, + payload, + options); }, + /** * Allows mojit binders to register to listen to other mojit events - * @method listen - * @param {String} name event name - * @param {Function} callback called when an event is broadcastd with the event data + * @param {String} name event name. + * @param {Function} callback called when an event is broadcast with + * the event data. */ listen: function(name, callback) { - this._client.doListen(MJT_EVT_PRFX+name, this._viewId, function(evt) { - // prevent mojits from listening to their own events - if (evt.source !== this.id) { - callback(evt); - } - }); + this._client.doListen(MJT_EVT_PRFX + name, this._viewId, + function(evt) { + // prevent mojits from listening to their own events + if (evt.source !== this.id) { + callback(evt); + } + }); }, + /** - * The opposite of the "listen" function. Deletes all callback functions from the - * listener queue associated with this binder and event type. If event name is not - * specified, all callbacks associated with this binder are deleted. - * @param {String} [optional] name event name + * The opposite of the "listen" function. Deletes all callback functions + * from the listener queue associated with this binder and event type. + * If event name is not specified, all callbacks associated with this + * binder are deleted. + * @param {String} [optional] name event name. */ unlisten: function(name) { var eventName = name ? MJT_EVT_PRFX + name : null; this._client.doUnlisten(this._viewId, eventName); }, + /** * This method renders the "data" provided into the "View" specified. * The "view" must be the name of one of the files in the current * Mojits "views" folder. Returns via the callback. - * - * @method render - * @param {object} data - * @param {string} view - * @param {function(err,str)} cb + * @param {object} data The data to render. + * @param {string} view The view name to use for rendering. + * @param {function(err,str)} cb The callback function. */ render: function(data, view, cb) { this._client.doRender(this, data, view, cb); }, + /** - * - * Used by the mojit binders to invoke actions on themselves within Mojito. + * Used by the mojit binders to invoke actions on themselves within + * Mojito. * The <em>options</em> parameter is optional and may contain: * <dl> * <dt>params</dt><dd>&lt;object&gt; must be broken out explicitly: @@ -199,35 +207,39 @@

    MojitoClient  0.1.0

    * <dt>rpc</dt><dd>&lt;boolean&gt; Means that we are immediately * sending the request to the server to answer the invocation.</dd> * </dl> - * - * @method invoke - * @param {string} action name of the action to invoke - * @param {Object} options see above - * @param {function} cb function to be called on completion + * @param {string} action name of the action to invoke. + * @param {Object} options see above. + * @param {function} cb function to be called on completion. */ invoke: function(action, options, cb) { var callback, command, instance; // If there are no options use it as the callback - if('function' === typeof options){ + if ('function' === typeof options) { callback = options; - options = {}; + options = {}; } else { callback = cb; } // If we don't have a callback set an empty one - if('function' !== typeof callback){ - callback = function(){}; + if ('function' !== typeof callback) { + // TODO: this can be a constant function...not created on each + // invoke call. + callback = function() {}; } // Make sure we have a "params" key in our "options" object options.params = options.params || {}; + // This is the "partial instance" which isn't an "Object instance" + // :). At least one of base or type must be defined. + // TODO: we don't check base vs. type here... instance = { base: this._base, type: this.type, - guid: this._instanceId, + guid: this._instanceId, // DEPRECATED, use instanceId instead + instanceId: this._instanceId, config: Y.mojito.util.copy(this.config) }; @@ -237,21 +249,31 @@

    MojitoClient  0.1.0

    action: action, params: { // Explicitly map the params to there keys route: options.params.route || {}, + // NOTE the defaulting here to drive from URL if no explicit + // params are provided. + // TODO: we should have an explicit override option here and + // merge... url: options.params.url || this.getFromUrl(), body: options.params.body || {}, file: options.params.file || {} }, + // NOTE this isn't a standard command option. + // TODO: not really "proper" to be part of command object, + // should really be somewhere else...but where? rpc: options.rpc || false }; - this._client.executeAction(command, callback); + this._client.executeAction(command, this.getId(), callback); }, + /** - * Refreshes the current DOM view for this binder without recreating the binder instance. Will call - * the binder's onRefreshView() function when complete with the new Y.Node and HTMLElement objects. - * @param opts [optional] <object> same as the options for invoke() - * @param cb [optional] called after replacement and onRefreshView have been called, sends data/meta + * Refreshes the current DOM view for this binder without recreating the + * binder instance. Will call the binder's onRefreshView() function when + * complete with the new Y.Node and HTMLElement objects. + * @param {object} opts same as the options for invoke(). + * @param {function} cb Called after replacement and onRefreshView have + * been called, sends data/meta. */ refreshView: function(opts, cb) { opts = opts || {}; @@ -262,103 +284,120 @@

    MojitoClient  0.1.0

    this._client.refreshMojitView(this, opts, cb); }, + /** * Gets URL parameters - * @method getFromUrl - * @param {string} key The name of the parameter required - * @return {string|object} param value, or all params if no key specified + * @param {string} key The name of the parameter required. + * @return {string|object} param value, or all params if no key + * specified. */ - getFromUrl: function(key){ - if(!this.query){ - this.query = Y.QueryString.parse(window.location.href.split('?').pop()); + getFromUrl: function(key) { + if (!this.query) { + this.query = Y.QueryString.parse( + window.location.href.split('?').pop() + ); } - if(key){ + if (key) { return this.query[key]; } - + return this.query; }, + /* * Returns the DOM Node ID for the current binder - * @method getId * @return {string} YUI GUID */ - getId: function(){ + getId: function() { return this._viewId; }, + /** - * Helper function to gather up details about a mojit's children from the Mojito Client - * @method getChildren - * @return <object> slot<string>-->child<object> + * Helper function to gather up details about a mojit's children from + * the Mojito Client. + * @return {object} slot<string>-->child information.<object> */ getChildren: function() { - var slot, child, childMojit, children = {}; - if (! this.children) { - return undefined; - } - for (slot in this.children) { - if (this.children.hasOwnProperty(slot)) { - child = this.children[slot]; - childMojit = this._client._mojits[child.viewId]; - if (childMojit) { - children[slot] = childMojit.proxy; - } - } - } - return children; + return this._client._mojits[this.getId()].children; }, + /** - * Clears out a child's view, calling the appropriate life cycle functions, then destroy's its binder and - * dereferences it. Will also dereference the child from this mojit's children. - * @method destroyChild - * @param id <string> *Either* the slot key of the child, or the DOM view id of the child + * Clears out a child's view, calling the appropriate life cycle + * functions, then destroy's its binder and dereferences it. Will also + * dereference the child from this mojit's children. + * @param {string} id Either the slot key of the child, or the DOM + * view id of the child. + * @param {boolean} retainNode if true, the binder's node will remain in + * the dom. */ - destroyChild: function(id) { - var slot, doomed; - if (this.children[id]) { - doomed = this.children[id].viewId; + destroyChild: function(id, retainNode) { + var slot, doomed, children = this.getChildren(); + if (children[id]) { + doomed = children[id].viewId; } else { - for (slot in this.children) { - if (this.children.hasOwnProperty(slot) && this.children[slot].viewId === id) { + for (slot in children) { + if (children.hasOwnProperty(slot) && + children[slot].viewId === id) { doomed = id; } } } - if (! doomed) { - throw new Error("Cannot detroy a child mojit with id '" + id + "'. Are you sure this is your child?"); + if (!doomed) { + throw new Error("Cannot destroy a child mojit with id '" + + id + "'. Are you sure this is your child?"); + } + this._client.destroyMojitProxy(doomed, retainNode); + delete children[id]; + if (this.config.children) { + delete this.config.children[id]; } - this._client.destroyMojitProxy(doomed); - delete this.children[id]; - delete this.config.children[id]; }, + /** - * Allows a binder to destroy itself and be removed from Mojito client runtime entirely. - * @method destroySelf - * @param retainNode <boolean> if true, the binder's node will remain in the dom + * Destroys all children. (Calls destroyChild() for each child.) + * @param {boolean} retainNode if true, the binder's node will remain in + * the dom. + */ + destroyChildren: function(retainNode) { + var my = this; + Y.Object.each(this.getChildren(), function(child, childId) { + my.destroyChild(childId, retainNode); + }); + }, + + + /** + * Allows a binder to destroy itself and be removed from Mojito client + * runtime entirely. + * @param {boolean} retainNode if true, the binder's node will remain in + * the dom. */ destroySelf: function(retainNode) { this._client.destroyMojitProxy(this.getId(), retainNode); }, + _destroy: function(retainNode) { var binder = this._binder; Y.log('destroying binder ' + this._viewId, 'debug', NAME); + this.destroyChildren(retainNode); if (Y.Lang.isFunction(binder.destroy)) { // this will de-register all this binder's callbacks from any // listener queues binder.destroy.call(binder); } - if (! retainNode) { + if (!retainNode) { this._node.remove(true); } this._client.doUnlisten(this._viewId); }, + _pause: function() { var binder = this._binder; if (Y.Lang.isFunction(binder.onPause)) { @@ -366,6 +405,7 @@

    MojitoClient  0.1.0

    } }, + _resume: function() { var binder = this._binder; if (Y.Lang.isFunction(binder.onResume)) { @@ -377,7 +417,9 @@

    MojitoClient  0.1.0

    Y.mojito.MojitProxy = MojitProxy; -}, '0.1.0', {requires: ['mojito-util']}); +}, '0.3.0', {requires: [ + 'mojito-util' +]});
    @@ -388,10 +430,10 @@

    MojitoClient  0.1.0

    @@ -399,8 +441,7 @@

    Modules

    @@ -408,18 +449,11 @@

    Classes

    --> @@ -437,7 +471,7 @@

    Files

    diff --git a/docs/api/mojito-client.client.js.html b/docs/api/mojito-client.client.js.html index c5b32ee04..afd14b6d0 100644 --- a/docs/api/mojito-client.client.js.html +++ b/docs/api/mojito-client.client.js.html @@ -2,23 +2,23 @@ - API: CommonLibs mojito-client.client.js (YUI Library) + Mojito API: MojitoClient mojito-client.client.js ( - - + + - - + +
    -

    mojito

    -

    CommonLibs  0.1.0

    +

    mojito

    +

    MojitoClient  0.3.0

    mojito - > CommonLibs + > MojitoClient > mojito-client.client.js (source view) @@ -48,18 +48,31 @@

    CommonLibs  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
     
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     // Set up a global client-side Mojito namespace
    -if (! YUI._mojito) {
    +if (!YUI._mojito) {
    +
    +    /**
    +     * The top-level Mojito namespace.
    +     * @type {Object}
    +     */
         YUI._mojito = {
    -        // this is initially a dummy logger object so that client code can set mutator functions
    -        // before the logger has actually been instantiated
    +        // this is initially a dummy logger object so that client code can set
    +        // mutator functions before the logger has actually been instantiated
             logger: {
                 _logMutatorCache: {
                     publisher: function() {
    -                    YUI._mojito._clientYlog.apply(YUI._mojito._clientY, arguments);
    +                    YUI._mojito._clientYlog.apply(YUI._mojito._clientY,
    +                        arguments);
                     }
                 },
                 set: function(k, v) {
    @@ -73,12 +86,15 @@ 

    CommonLibs  0.1.0

    }; } + YUI.add('mojito-client', function(Y, NAME) { - // These methods are methods that potentially make XHR calls to retrieve data from the server. When the Mojito - // client is "paused" by calling the pause() function, all the methods below are queued as they are executed - // instead of being fully executed. When the resume() function is called, the pause queue is flushed and all - // the intercepted actions are taken at that time. + // These methods are methods that potentially make XHR calls to retrieve + // data from the server. When the Mojito client is "paused" by calling the + // pause() function, all the methods below are queued as they are executed + // instead of being fully executed. When the resume() function is called, + // the pause queue is flushed and all the intercepted actions are taken at + // that time. var PAUSEABLE = [ 'executeAction', 'doRender', @@ -86,16 +102,21 @@

    CommonLibs  0.1.0

    'doListen', 'doUnlisten' ], - + log, + lifecycleEvents, State = { PAUSED: 'paused', ACTIVE: 'active' }; + // because there is a moment during startup when we need it, cache the // original Y instance for use as the log platform - YUI._mojito._clientY = Y; - var log = function () { + // And don't clobber the global + if (!YUI._mojito._clientY) { + YUI._mojito._clientY = Y; + } + log = function() { if (YUI._mojito.logger && YUI._mojito.logger.log) { YUI._mojito.logger.log.apply(YUI._mojito.logger, arguments); } else { @@ -103,16 +124,150 @@

    CommonLibs  0.1.0

    } }; + + // this is the heart of mojitProxy.render(), but it needs to be a separate + // function called once we have mojit type details + function privateRender(mp, data, view, cb) { + var mojitView, + renderer; + + if (!mp._views || !mp._views[view]) { + cb(new Error('View "' + view + '" not found')); + return; + } + + data = data || {}; + // this is presumed to be useful enough that we'll set it up for them + data.mojit_assets = data.mojit_assets || mp._assetsRoot; + + mojitView = mp._views[view]; + renderer = new Y.mojito.ViewRenderer(mojitView.engine); + Y.log('Rendering "' + view + '" in Binder', 'debug', NAME); + renderer.render(data, mp.type, mojitView['content-path'], { + buffer: '', + flush: function(data) { + this.buffer += data; + }, + done: function(data) { + this.buffer += data; + cb(null, this.buffer); + } + }); + } + + + function setNewMojitView(viewData, mp) { + + Y.log('setting new view on mojit ' + mp._instanceId, 'debug', NAME); + + var newNode = Y.Node.create(viewData); + mp._node.replace(newNode); + mp._element = document.getElementById(mp._viewId); + mp._node = new Y.Node(mp._element); + + if (Y.Lang.isFunction(mp._binder.onRefreshView)) { + mp._binder.onRefreshView(mp._node, mp._element); + } + } + + // we have to match the children by instanceId to identify them and replace + // their viewId with the actual viewId for the binder that should be + // attached. + function processChildren(children, binderMap) { + var name, + viewId, + found; + + for (name in children) { + if (children.hasOwnProperty(name)) { + for (viewId in binderMap) { + if (binderMap.hasOwnProperty(viewId) && !found) { + if (binderMap[viewId].instanceId === + children[name].instanceId) { + children[name].viewId = viewId; + found = true; + } + } + } + found = false; + } + } + return children; + } + + + function bindNode(binder, node, element) { + var handles = []; + + if (Y.Lang.isFunction(binder.bind)) { + // Pass the "node" to the bind method + binder.bind(node, element); + } + // all automatic event delegation + if (Y.Lang.isFunction(binder.handleClick)) { + // This code should be deferred till after the page has visibly + // loaded + handles.push(Y.delegate('click', binder.handleClick, node, + function() { return true; }, + binder)); + } + + // TODO: add all the event delegation majic here. + Y.log('Attached ' + handles.length + ' event delegates', 'debug', NAME); + return handles; + } + + + // TODO: complete work to call this in the destroyMojitProxy function(). + function unbindNode(binder, handles) { + var retainBinder = false; + + if (Y.Lang.isFunction(binder.unbind)) { + // let the binder decide whether it wants to stick around in case + // its node is reattached at some point in the future + retainBinder = binder.unbind.call(binder); + } + + if (handles) { + Y.Array.each(handles, function(handle) { + Y.log('Detaching event handle from binder', 'debug', NAME); + handle.detach(); + }); + } + return retainBinder; + } + + + function findParentProxy(mojits, childId) { + var p; + + // TODO: convert to "some" instead of each for performance. We're doing + // a "detect" here. + Y.Object.each(mojits, function(mojit) { + Y.Object.each(mojit.children, function(child) { + if (child.viewId === childId) { + p = mojit.proxy; + return true; + } + }); + if (p) { + return true; + } + }); + return p; + } + + /** - * The starting point for mojito to run in the browser. You can access one instance of the Mojito Client running - * within the browser environment through window.YMojito.client. - * + * The starting point for mojito to run in the browser. You can access one + * instance of the Mojito Client running within the browser environment + * through window.YMojito.client. * @module MojitoClient * @class Client * @constructor * @namespace Y.mojito - * @param {Object} config The entire configuration object written by the server - * to start up mojito. + * @param {Object} config The entire configuration object written by the + * server to start up mojito. */ function MojitoClient(config) { this.timeLogStack = []; @@ -123,21 +278,107 @@

    CommonLibs  0.1.0

    } } + + lifecycleEvents = {}; + + + /** + * Subscribe to a MojitoClient lifecycle event. + * + * @param {string} evt name of event to subscribe to. + * @param {function(data)} cb callback called when the event fires. + */ + MojitoClient.subscribe = function(evt, cb) { + // Subscribe works only in appLevel + if (Y && YUI._mojito._clientY && + (Y._yuid !== YUI._mojito._clientY._yuid)) { + // Y.log('Applevel subscribe ? ' + Y._yuid + " ==== " + + // YUI._mojito._clientY._yuid, 'error', NAME); + return; + } + if (!lifecycleEvents[evt]) { + lifecycleEvents[evt] = []; + } + lifecycleEvents[evt].push(cb); + }; + + + /** + * Fires a lifecycle event. + * + * @param {string} evt The name of event to fire. + * @param {Object} data The data to pass to listeners. + * @private + */ + function fireLifecycle(evt, data) { + var cbs = lifecycleEvents[evt], + c; + if (!cbs || !cbs.length) { + return; + } + for (c = 0; c < cbs.length; c += 1) { + cbs[c](data); + } + } + + + /** + * Fired at the beginning of the startup of MojitoClient. + * + * The data contains the following: + * <dl> + * <dt><code>config</code></dt> + * <dd>the config object used to initialize the MojitoClient</dd> + * </dl> + * + * Any change to the config will be picked up and used by MojitoClient. + * @param {Object} data The data for the event. + */ + + /** + * Fired at the end of the startup of MojitoClient. + * @param {Object} data The data for the event. (Empty in this case). + */ + + /** + * Fired before the binders are attached to the page. + * + * The data contains the following: + * <dl> + * <dt><code>binderMap</code></dt> + * <dd>the details of the binders to attach to the page</dd> + * <dt><code>parentId</code></dt> + * <dd>[optional] the parent binder view id to attach any children</dd> + * <dt><code>topLevelMojitViewId</code></dt> + * <dd>[optional] the topmost (root) binder view id to attach as a child to + * the parent</dd> + * </dl> + * + * Any change to the data will be picked up and used by MojitoClient. + * @param {Object} data The data for the event. + */ + + /** + * Fired after the binders are attached to the page. + * @param {Object} data The data for the event. (Empty in this case). + */ + MojitoClient.prototype = { init: function(config) { + fireLifecycle('pre-init', {config: config}); Y.mojito.perf.mark('mojito', 'core_client_start'); var that = this, logConfig = {}, - appConfig = config.appConfig, - context = config.context; + appConfig = config.appConfig; // YUI Console - if(appConfig && appConfig.yui && appConfig.yui.showConsoleInClient && !that.yuiConsole){ - YUI().use('console-filters', function(Y){ + if (appConfig && appConfig.yui && + appConfig.yui.showConsoleInClient && !that.yuiConsole) { + YUI().use('console-filters', function(Y) { Y.one('body').addClass('yui3-skin-sam'); that.yuiConsole = new Y.Console({ - plugins: [ Y.Plugin.ConsoleFilters ], + plugins: [Y.Plugin.ConsoleFilters], logSource: Y.Global, height: 600 }); @@ -150,16 +391,29 @@

    CommonLibs  0.1.0

    if (appConfig && appConfig.log && appConfig.log.client) { logConfig = appConfig.log.client; } - // to allow any client code to provide global log mutators before mojito starts... - Y.Array.each(['formatter', 'writer', 'publisher'], function(logMutator) { - if (YUI._mojito.logger._logMutatorCache[logMutator]) { - logConfig[logMutator] = YUI._mojito.logger._logMutatorCache[logMutator]; - } - }); - YUI._mojito.logger = new Y.mojito.Logger(logConfig); - YUI._mojito.loader = new Y.mojito.Loader(appConfig); + + // to allow any client code to provide global log mutators before + // mojito starts... + Y.Array.each(['formatter', 'writer', 'publisher'], + function(logMutator) { + if (YUI._mojito.logger._logMutatorCache[logMutator]) { + logConfig[logMutator] = + YUI._mojito.logger._logMutatorCache[logMutator]; + } + }); + + // Don't clobber globals + if (!YUI._mojito.logger.log) { + YUI._mojito.logger = new Y.mojito.Logger(logConfig); + } + if (!YUI._mojito.loader) { + YUI._mojito.loader = new Y.mojito.Loader(appConfig, + config.pathToRoot); + } // push all client logs through our logger - YUI._mojito._clientYlog = Y.log; + if (!YUI._mojito._clientYlog) { + YUI._mojito._clientYlog = Y.log; + } Y.log = log; if (Y.mojito.TunnelClient) { @@ -169,22 +423,40 @@

    CommonLibs  0.1.0

    // Make the "Resource Store" by wrapping it with the adapter this.resourceStore = new Y.mojito.ResourceStore(config); - // the resource store adapter and the dispatcher must be passed the mojito logger object, - // because they were created within a Y scope that still has reference to the original Y.log - // function - this.resourceStore = Y.mojito.ResourceStoreAdapter.init('client', this.resourceStore, YUI._mojito.logger); - this.dispatcher = Y.mojito.Dispatcher.init(this.resourceStore, null, YUI._mojito.logger, YUI._mojito.loader); + // the resource store adapter and the dispatcher must be passed the + // mojito logger object, because they were created within a Y scope + // that still has reference to the original Y.log function + this.resourceStore = Y.mojito.ResourceStoreAdapter.init('client', + this.resourceStore, YUI._mojito.logger); + this.dispatcher = Y.mojito.Dispatcher.init(this.resourceStore, + null, YUI._mojito.logger, YUI._mojito.loader); + // request context from server - this.context = context; + this.context = config.context; // application configuration this.config = config; // create listener bag for mojit comms this._listeners = {}; - // the mojits represented in the current DOM, keyed by DOM element id + // the mojits represented in the current DOM, keyed by DOM element + // id this._mojits = {}; - Y.mojito.perf.mark('mojito', 'core_client_end', 'Mojito client library loaded'); + Y.mojito.perf.mark('mojito', + 'core_client_end', 'Mojito client library loaded'); + /* FUTURE -- perhaps only do this once a user needs it + var singletons; + singletons = { + tunnel: this.tunnel, + resourceStore: this.resourceStore, + dispatcher: this.dispatcher + } + fireLifecycle('made-singletons', singletons); + // allow the event listeners to modify the singletons + this.tunnel = singletons.tunnel; + this.resourceStore = singletons.resourceStore; + this.dispatcher = singletons.dispatcher; + */ this.attachBinders(config.binderMap); @@ -192,12 +464,17 @@

    CommonLibs  0.1.0

    Y.Array.each(PAUSEABLE, function(mName) { var me = this, originalMethod = me[mName]; + this[mName] = function() { - // during execution of these pauseable function, we'll check to see if the client is in a paused - // state + // during execution of these pauseable function, we'll check + // to see if the client is in a paused state if (me._state === State.PAUSED) { - // now just queue the method call with original function and args for execution on resume() - me._pauseQueue.push({fn: originalMethod, args: arguments}); + // now just queue the method call with original function + // and args for execution on resume() + me._pauseQueue.push({ + fn: originalMethod, + args: arguments + }); } else { // not paused, so go ahead and apply the function originalMethod.apply(me, arguments); @@ -206,117 +483,138 @@

    CommonLibs  0.1.0

    }, this); this._state = State.ACTIVE; + fireLifecycle('post-init', {}); }, - cleanupBinders: function() { - //log('cleaning up binders: ' + JSON.stringify(Object.keys(this._mojits), null, 2), 'debug', NAME); - var doomed = [], - mojits = this._mojits; - // for each mojit, we need to query the DOM and see if it its binder needs to be cleaned - // up or not - Y.Object.each(mojits, function(mojit, viewId) { - var proxy = mojit.proxy, - binder = proxy._binder, - cachedNode = proxy._node, - element = document.getElementById(viewId), - node; - // if there is no node on the page corresponding to this binder - // and this binder is not being manually retained by the user, - // we can destroy the binder - if (! element && ! binder._retained) { - doomed.push(viewId); - return; - } - - if (element) { - node = new Y.Node(element); - } - - // if the node on the page is a different node object than the one that existed previous, we should - // set the new node into the binder - if (element && Y.Node.getDOMNode(cachedNode) !== Y.Node.getDOMNode(node)) { - Y.log('rebinding binder ' + viewId + ' to node', 'info', NAME); - unbindNode(binder, mojit.handles); - mojit.handles = bindNode(binder, node); - binder._retained = false; - // update the cached node - proxy._node = node; - proxy._element = element; - } - }); - // the 'doomed' binders will be destroyed if specified - Y.Array.each(doomed, function(viewId) { - var binder = mojits[viewId].proxy._binder, - retainBinder; - retainBinder = unbindNode(binder); + /** + * Given a set of binder information, initialize binder instances and + * bind them to the page. + * @private + * @param {Object} binderMap viewId ==> binder data, contains all we + * need from the mojit dispatch's meta object about all the binders + * that were executed to create the DOM addition recently added to + * the document. + * @param {string} parentId the parent binder view id to attach any + * children. + * @param {string} topLevelMojitViewId the topmost (root) binder view + * id to attach as a child to the parent. + */ + attachBinders: function(binderMap, parentId, topLevelMojitViewId) { + var context = this.context, + me = this, + newMojitProxies = [], + parent, + topLevelMojitObj, + totalBinders = Y.Object.size(binderMap), + bindersComplete = 0, + onBinderComplete, + // Note: This here so we can get access view meta data for + // each binder + store = this.resourceStore, + eventData = { + binderMap: binderMap, + parentId: parentId, + topLevelMojitViewId: topLevelMojitViewId + }; - // if the binder should be retained and live on, we'll mark it as such so it doesn't get - // cleaned up ever again (until the user explicitly destroys it) - if (retainBinder) { - binder._retained = true; - } - // if the binder should not live on, DESTROY IT! - else { - this.destroyMojitProxy(viewId); - } - }, this); - }, - - attachBinders: function(binders) { + fireLifecycle('pre-attach-binders', eventData); + this.pause(); + binderMap = eventData.binderMap; + parentId = eventData.parentId; + topLevelMojitViewId = eventData.topLevelMojitViewId; Y.mojito.perf.mark('mojito', 'core_binders_start'); - var context = this.context, - bindersInitialized = 0, - bindersCompleted = 0, - binderLength = Y.Object.size(binders), - bindAllMojits, - self = this, - newMojitProxies = [], - // Note: This here so we can get access view meta data for each binder - store = this.resourceStore; + if (!totalBinders) { + Y.mojito.perf.mark('mojito', 'core_binders_resume'); + me.resume(); + Y.mojito.perf.mark('mojito', 'core_binders_end'); + fireLifecycle('post-attach-binders', {}); + return; + } + + onBinderComplete = function() { + // only run the function when all binders have completed + bindersComplete += 1; + if (bindersComplete < totalBinders) { + return; + } - bindAllMojits = function(mojitProxies) { - Y.Array.each(mojitProxies, function(proxy) { + // now that all binders have been initialized and accounted + // for... - var delegateHandles = bindNode(proxy._binder, proxy._node, proxy._element); + // first, we must create the MojitClient's state of the binders + // before binding, in case the binders' bind() function tries to + // do anything that includes children + Y.Array.each(newMojitProxies, function(item) { + var proxy = item.proxy, + children = item.children; - self._mojits[proxy._viewId] = { + // 'me' here is the MojitoClient instance. + me._mojits[proxy._viewId] = { proxy: proxy, - handles: delegateHandles + children: children }; + }); - if (++bindersCompleted === binderLength) { - Y.mojito.perf.mark('mojito', 'core_binders_end'); - } + // now we'll loop through again and do the binding, saving the + // handles + Y.Array.each(newMojitProxies, function(item) { + var mojit = me._mojits[item.proxy.getId()], + proxy = item.proxy; + mojit.handles = bindNode(proxy._binder, proxy._node, + proxy._element); }); + + // if there is a parent to add a child to (and a topmost child + // to add to the parent), add new top level child to parent that + // dispatched it + if (parentId && topLevelMojitViewId) { + parent = me._mojits[parentId]; + topLevelMojitObj = binderMap[topLevelMojitViewId]; + // this is just a shallow representation of the child, not + // the proxy object itself. but it is enough to look up the + // proxy when necessary. + if (parent && topLevelMojitObj) { + if (!parent.children) { + parent.children = {}; + } + parent.children[topLevelMojitViewId] = { + type: topLevelMojitObj.type, + viewId: topLevelMojitViewId + }; + } + } + Y.mojito.perf.mark('mojito', 'core_binders_resume'); + me.resume(); + Y.mojito.perf.mark('mojito', 'core_binders_end'); + fireLifecycle('post-attach-binders', {}); }; - Y.Object.each(binders, function(binderData, viewId) { + // loop over the binder map, load, use, and instantiate them + Y.Object.each(binderMap, function(binderData, viewId) { // Make sure viewIds's are not bound to more than once - if (self._mojits[viewId]) { + if (me._mojits[viewId]) { return; } - if (! binderData.name) { - Y.log('No binder for ' + binderData.type + '.' + binderData.action, 'info', NAME); - if (++bindersInitialized === binderLength) { - bindAllMojits(newMojitProxies); - } + if (!binderData.name) { + Y.log('No binder for ' + binderData.type + '.' + + binderData.action, 'info', NAME); + onBinderComplete(); return; } - //Y.log('loading prereqs for binder ' + Y.Object.keys(binderData.needs), 'mojito', NAME); YUI._mojito.loader.load(binderData.needs, function(err) { var config, type = binderData.type, base = binderData.base, binderName = binderData.name, - instanceId = binderData.guid, + instanceId = binderData.instanceId, mojitProxy, binderClass, children, @@ -325,38 +623,48 @@

    CommonLibs  0.1.0

    element; if (err) { - Y.log('failed to load prerequisites for binder ' + binderName, 'error', NAME); - bindersInitialized++; + Y.log('failed to load prerequisites for binder ' + + binderName, 'error', NAME); + onBinderComplete(); return; } - // "Y.mojito.binders" is blind to all new "binders" added to the page - // we have to "use()" any binder name we are given to have access to it. + // "Y.mojito.binders" is blind to all new "binders" added to + // the page we have to "use()" any binder name we are given + // to have access to it. Y.use(binderData.name, function(BY) { config = Y.mojito.util.copy(binderData.config); element = document.getElementById(viewId); - if (! element) { - Y.log('Did not find DOM node "'+viewId+'" for binder "' - + binderName + '"', 'warn', NAME); - bindersInitialized++; + if (!element) { + Y.log('Did not find DOM node "' + viewId + + '" for binder "' + binderName + '"', + 'warn', NAME); + onBinderComplete(); return; } mojitNode = new Y.Node(element); + // BY reference here is the 'use()' return value...the + // Binder class we need to access. binderClass = BY.mojito.binders[binderName]; binder = Y.mojito.util.heir(binderClass); - Y.log('Created binder "' + binderName + '" for DOM node "' + viewId + '"', 'info', NAME); + Y.log('Created binder "' + binderName + + '" for DOM node "' + viewId + '"', 'info', NAME); if (binderData.children) { - children = processChildren(binderData.children, binders); + children = processChildren(binderData.children, + binderMap); } + // One mojitProxy per binder. The mp is how client code + // gets to the binder...they don't hold refs to anything + // but the mp. (close enough). mojitProxy = new Y.mojito.MojitProxy({ // private action: binderData.action, @@ -366,24 +674,28 @@

    CommonLibs  0.1.0

    element: element, viewId: viewId, instanceId: instanceId, - client: self, + client: me, store: store, // public - children: children, type: type, config: config, context: context }); + // If client is paused, proxy must be paused + if (me._state === State.PAUSED) { + mojitProxy._pause(); + } - newMojitProxies.push(mojitProxy); + newMojitProxies.push({ + proxy: mojitProxy, + children: children + }); if (Y.Lang.isFunction(binder.init)) { binder.init(mojitProxy); } - if (++bindersInitialized === binderLength) { - bindAllMojits(newMojitProxies); - } + onBinderComplete(); }); @@ -393,65 +705,79 @@

    CommonLibs  0.1.0

    }, + /** - * Used for binders to execute their actions through the Mojito framework through their - * proxies. - * @method executeAction - * @param {Object} command must contain mojit id and action to execute - * @param {Function} cb callback to run when complete + * Used for binders to execute their actions through the Mojito + * framework through their proxies. + * @param {Object} command must contain mojit id and action to execute. + * @param {String} viewId the view id of the current mojit, which is + * executing the action. + * @param {Function} cb callback to run when complete. * @private */ - executeAction: function(command, cb) { - - var self = this; + executeAction: function(command, viewId, cb) { + var my = this; // Sending a command to dispatcher that defines our action execution - Y.log('Executing "'+(command.instance.base||'@'+command.instance.type)+'/'+command.instance.action+'" on the client.', 'mojito', NAME); - - self.resourceStore.expandInstanceForEnv('client', command.instance, self.context, function(err, details) { - - // if there is a controller in the client type details, that means the controller exists here - var existsOnClient = Boolean(details.controller); - - command.context = self.context; - - // if this controller does not exist here, or we have been instructed to force an - // RPC call, we'll go to the server - if (! existsOnClient || command.rpc){ - // Make the call via a fixed RPC channel - self.tunnel.rpc(command, new Y.mojito.OutputHandler(cb, self)); - } else{ - // Dispatch locally - self.dispatcher.dispatch(command, new Y.mojito.OutputHandler(cb, self)); - } - - }); - + Y.log('Executing "' + (command.instance.base || '@' + + command.instance.type) + '/' + command.instance.action + + '" on the client.', 'mojito', NAME); + + this.resourceStore.expandInstanceForEnv('client', + command.instance, this.context, function(err, details) { + + // if there is a controller in the client type details, that + // means the controller exists here "cast details.controller + // to Boolean" ;) + var existsOnClient = Boolean(details.controller); + + command.context = my.context; + + // if this controller does not exist here, or we have been + // instructed to force an RPC call, we'll go to the server + if (!existsOnClient || command.rpc) { + // Make the call via a fixed RPC channel + my.tunnel.rpc(command, + new Y.mojito.OutputHandler(viewId, cb, my)); + } else { + // Dispatch locally + my.dispatcher.dispatch(command, + new Y.mojito.OutputHandler(viewId, cb, my)); + } + }); }, + doRender: function(mp, data, view, cb) { - if (! mp._views || ! mp._assetsRoot) { - this.resourceStore.getType('client', mp.type, mp.context, function(err, typeInfo) { - if (err) { - cb(new Error('Failed to load mojit information for ' + mp.type)); - return; - } - mp._views = typeInfo.views; - mp._assetsRoot = typeInfo.assetsRoot; - privateRender(mp, data, view, cb); - }); - } - else { + if (!mp._views || !mp._assetsRoot) { + this.resourceStore.getType('client', mp.type, mp.context, + function(err, typeInfo) { + if (err) { + cb(new Error( + 'Failed to load mojit information for ' + + mp.type + )); + return; + } + mp._views = typeInfo.views; + mp._assetsRoot = typeInfo.assetsRoot; + privateRender(mp, data, view, cb); + }); + } else { privateRender(mp, data, view, cb); } - }, - doBroadcast: function(evtId, source, payload, opts){ - var tgtInstId, tgtViewId; + + doBroadcast: function(eventId, source, payload, opts) { + opts = opts || {}; + var tgtInstId, + tgtViewId, + child = opts.target ? + this._mojits[source].children[opts.target.slot] : null; if (opts && opts.target) { - if (opts.target.slot) { - tgtInstId = this._mojits[source].proxy.config.children[opts.target.slot].guid; + if (opts.target.slot && child) { + tgtInstId = child.instanceId; // find the target of the message Y.Object.each(this._mojits, function(v, k) { if (v.proxy._instanceId === tgtInstId) { @@ -459,17 +785,18 @@

    CommonLibs  0.1.0

    } }); // if there was no target found, give an error and return - if (! tgtViewId) { - Y.log('No broadcast target found for ' + opts.target.slot + ':' + tgtInstId, 'warn', NAME); + if (!tgtViewId) { + Y.log('No broadcast target found for ' + + opts.target.slot + ':' + tgtInstId, 'warn', NAME); return; } } else if (opts.target.viewId) { tgtViewId = opts.target.viewId; } } - if (this._listeners[evtId]) { - Y.Array.each(this._listeners[evtId], function(listener) { - if (! tgtViewId || tgtViewId === listener.guid) { + if (this._listeners[eventId]) { + Y.Array.each(this._listeners[eventId], function(listener) { + if (!tgtViewId || tgtViewId === listener.viewId) { listener.cb({ data: payload, source: source @@ -479,25 +806,32 @@

    CommonLibs  0.1.0

    } }, - doListen: function(eventId, guid, callback) { - if (! this._listeners[eventId]) { + + doListen: function(eventId, viewId, callback) { + if (!this._listeners[eventId]) { this._listeners[eventId] = []; } - this._listeners[eventId].push({guid: guid, cb: callback}); + this._listeners[eventId].push({ + guid: viewId, // DEPRECATED, use viewId instead + viewId: viewId, + cb: callback + }); }, - doUnlisten: function(guid, needleEvent) { + + doUnlisten: function(viewId, needleEvent) { var listeners = this._listeners, eventType; function processListenerArray(arr, id) { var i = 0; + while (i < arr.length) { - if (arr[i].guid === id) { + if (arr[i].viewId === id) { arr.splice(i, 1); // no increment. i is now the "next" index } else { - i++; + i += 1; } } return arr; @@ -505,48 +839,57 @@

    CommonLibs  0.1.0

    // if there is only one event to unlisten, do it quickly if (needleEvent) { - processListenerArray(listeners[needleEvent], guid); - } - // but if we need to unlisten to all callbacks registered by this binder, - // we must loop over the entire listener object - else { + processListenerArray(listeners[needleEvent], viewId); + } else { + // but if we need to unlisten to all callbacks registered by + // this binder, we must loop over the entire listener object for (eventType in listeners) { if (listeners.hasOwnProperty(eventType)) { - processListenerArray(listeners[eventType], guid); + processListenerArray(listeners[eventType], viewId); } } } }, + destroyMojitProxy: function(id, retainNode) { var parent; + if (this._mojits[id]) { + // TODO: activate call to unbindNode below: + // unbindNode(this._mojits[id].proxy._binder, + // this._mojits[id].handles); this._mojits[id].proxy._destroy(retainNode); delete this._mojits[id]; - // We don't manage binder children automatically, but any time a new child is added - // or removed, we should at least give the application code a chance to stay up to - // date if they want to. The only gap is when a mojit destroys itself. onChildDestroyed - // is called whenever a binder is destroyed so any parents can be notified. + // We don't manage binder children automatically, but any time a + // new child is added or removed, we should at least give the + // application code a chance to stay up to date if they want to. + // The only gap is when a mojit destroys itself. + // onChildDestroyed is called whenever a binder is destroyed so + // any parents can be notified. parent = findParentProxy(this._mojits, id); - if (parent && parent._binder.onChildDestroyed && Y.Lang.isFunction(parent._binder.onChildDestroyed)) { + if (parent && parent._binder.onChildDestroyed && + Y.Lang.isFunction(parent._binder.onChildDestroyed)) { parent._binder.onChildDestroyed({ id: id }); } } }, + /** - * Pause the Mojito Client and all mojits that are running. This will notify all binders that they have been - * paused by calling their onPause() functions. It will prevent the immediate execution of several mojit proxy - * operations that might cause a long process to begin (especially things that might go to the server). + * Pause the Mojito Client and all mojits that are running. This will + * notify all binders that they have been paused by calling their + * onPause() functions. It will prevent the immediate execution of + * several mojit proxy operations that might cause a long process to + * begin (especially things that might go to the server). * - * To resume, simply call .resume(). This will immediately execute all actions that occurred while Mojito was - * paused. - * - * @method pause + * To resume, simply call .resume(). This will immediately execute all + * actions that occurred while Mojito was paused. */ pause: function() { if (this._state === State.PAUSED) { - Y.log('Cannot "pause" the mojito client because it has already been paused.', 'warn', NAME); + Y.log('Cannot "pause" the mojito client because it has' + + ' already been paused.', 'warn', NAME); return; } this._state = State.PAUSED; @@ -556,33 +899,37 @@

    CommonLibs  0.1.0

    Y.log('Mojito Client state: ' + this._state + '.', 'info', NAME); }, + /** - * Resumes the Mojito client after it has been paused (see method "pause"). If there are any queued actions that - * were executed and cached during the pause, calling resume() will immediately execute them. All binders are - * notified through their onResume() function that they are been resumed. - * - * @resume + * Resumes the Mojito client after it has been paused (see method + * "pause"). If there are any queued actions that were executed and + * cached during the pause, calling resume() will immediately execute + * them. All binders are notified through their onResume() function that + * they are been resumed. */ resume: function() { if (this._state !== State.PAUSED) { - Y.log('Cannot "resume" the mojito client because it was never paused.', 'warn', NAME); + Y.log('Cannot "resume" the mojito client because it was' + + ' never paused.', 'warn', NAME); return; } + this._state = State.ACTIVE; + Y.Object.each(this._mojits, function(moj) { + moj.proxy._resume(); + }); Y.Array.each(this._pauseQueue, function(queuedItem) { var fn = queuedItem.fn, args = queuedItem.args; + fn.apply(this, args); }, this); this._pauseQueue = []; - this._state = State.ACTIVE; - Y.Object.each(this._mojits, function(moj) { - moj.proxy._resume(); - }); Y.log('Mojito Client state: ' + this._state + '.', 'info', NAME); }, + refreshMojitView: function(mp, opts, cb) { - var me = this; + var my = this; mp.invoke(mp._action, opts, function(err, data, meta) { @@ -591,79 +938,119 @@

    CommonLibs  0.1.0

    } /* - * The new markup returned from the server has all new DOM ids within it, but - * we don't want to use them. Before doing any DOM stuff, we are going to replace - * all the new view ids with our current view ids for this mojit view as well - * as any children that have come along for the ride. + * The new markup returned from the server has all new DOM ids + * within it, but we don't want to use them. Before doing any + * DOM stuff, we are going to replace all the new view ids with + * our current view ids for this mojit view as well as any + * children that have come along for the ride. */ var idReplacements = {}, // from: to - metaBinderViewId, mBinder, freshBinders = {}, - clientMojitViewId, clientMojit, + metaBinderViewId, + mBinder, + freshBinders = {}, + clientMojitViewId, + clientMojit, processMojitChildrenForIdReplacements; /* - * Recursive function used to walk down the heirarchy of children in order to replace every view id within - * the meta data + * Recursive function used to walk down the hierarchy of + * children in order to replace every view id within the meta + * data */ - processMojitChildrenForIdReplacements = function(clientChildren, metaChildren, idRepls) { - var metaChild, childMojit, metaSubChildren, slot; - if (! metaChildren || ! clientChildren) { - return; - } - for (slot in metaChildren) { - if (metaChildren.hasOwnProperty(slot)) { - metaChild = metaChildren[slot]; - childMojit = clientChildren[slot]; - if (childMojit) { - metaSubChildren = meta.binders[metaChild.viewId].children; - idRepls[metaChild.viewId] = childMojit.getId(); - if (metaSubChildren) { - processMojitChildrenForIdReplacements(childMojit.getChildren(), metaSubChildren, idRepls); + processMojitChildrenForIdReplacements = + function(clientChildren, metaChildren, idRepls) { + var metaChild, + childMojitProxy, + metaSubChildren, + slot; + + if (!metaChildren || !clientChildren) { + return; + } + for (slot in metaChildren) { + if (metaChildren.hasOwnProperty(slot)) { + metaChild = metaChildren[slot]; + if (clientChildren && clientChildren[slot]) { + childMojitProxy = + clientChildren[slot].proxy; + } + if (childMojitProxy) { + metaSubChildren = meta.binders[ + metaChild.viewId + ].config.children; + idRepls[metaChild.viewId] = + childMojitProxy.getId(); + if (metaSubChildren) { + processMojitChildrenForIdReplacements( + my.mojits[childMojitProxy.getId()]. + children, + metaSubChildren, + idRepls + ); + } } } } - } - }; + }; - for (clientMojitViewId in me._mojits) { - if (me._mojits.hasOwnProperty(clientMojitViewId)) { - clientMojit = me._mojits[clientMojitViewId]; + for (clientMojitViewId in my._mojits) { + if (my._mojits.hasOwnProperty(clientMojitViewId)) { + clientMojit = my._mojits[clientMojitViewId]; for (metaBinderViewId in meta.binders) { if (meta.binders.hasOwnProperty(metaBinderViewId)) { mBinder = meta.binders[metaBinderViewId]; - if (mBinder.guid === clientMojit.proxy._instanceId) { - Y.log('matched guid ' + mBinder.guid, 'warn', NAME); - idReplacements[metaBinderViewId] = clientMojitViewId; - processMojitChildrenForIdReplacements(clientMojit.proxy.getChildren(), mBinder.children, idReplacements); + if (mBinder.instanceId === + clientMojit.proxy._instanceId) { + Y.log('matched instanceId ' + + mBinder.instanceId, + 'debug', + NAME + ); + idReplacements[metaBinderViewId] = + clientMojitViewId; + processMojitChildrenForIdReplacements( + my._mojits[clientMojit.proxy.getId()]. + children, + mBinder.children, + idReplacements + ); } } } } - } Y.Object.each(idReplacements, function(to, from) { var regex = new RegExp(from, 'g'); + data = data.replace(regex, to); }); setNewMojitView(data, mp); + // Do a "light bind" for each child, keeping track of any + // binders that need a "full bind". We'll bind those in the + // attachBinders call below this loop. Y.Object.each(meta.children, function(child, slot) { var childViewId = idReplacements[child.viewId], - childMojit = me._mojits[childViewId], - childProxy, childNode, childElement, childBinder; - - // may not be a binder for this mojit child, so there would be no mojit proxy yet + childMojit = my._mojits[childViewId], + childProxy, + childNode, + childElement, + childBinder; + + // may not be a binder for this mojit child, so there would + // be no mojit proxy yet if (!childMojit) { - // this must be a new binder instance that we need to instantiate + // this must be a new binder instance that we need to + // instantiate freshBinders[child.viewId] = meta.binders[child.viewId]; return; } - childProxy = me._mojits[childViewId].proxy; + childProxy = my._mojits[childViewId].proxy; childNode = mp._node.one('#' + childViewId); childElement = childNode._node; childBinder = childProxy._binder; @@ -679,129 +1066,21 @@

    CommonLibs  0.1.0

    } }); - me.attachBinders(freshBinders); + // Do a "full bind" on the new binders we tracked in the loop + // above. These need the full treatment. + my.attachBinders(freshBinders); if (cb) { cb(data, meta); } }); } - }; - - // this is the heart of mojitProxy.render(), but it needs to be a separate function - // called once we have mojit type details - function privateRender(mp, data, view, cb) { - var mojitView, renderer; - - if (!mp._views || !mp._views[view]) { - cb(new Error('View "'+view+'" not found')); - return; - } - data = data || {}; - // this is presumed to be useful enough that we'll set it up for them - data.mojit_assets = data.mojit_assets || mp._assetsRoot; - - mojitView = mp._views[view]; - renderer = new Y.mojito.ViewRenderer(mojitView.engine); - Y.log('Rendering "' + view + '" in Binder', 'debug', NAME); - renderer.render(data, mp.type, mojitView['content-path'], { - buffer: '', - flush: function(data){ - this.buffer+=data; - }, - done: function(data){ - this.buffer+=data; - cb(null, this.buffer); - } - }); - } - - function setNewMojitView(viewData, mp) { - - Y.log('setting new view on mojit ' + mp._instanceId, 'debug', NAME); - - var newNode = Y.Node.create(viewData); - - mp._node.replace(newNode); - - mp._element = document.getElementById(mp._viewId); - mp._node = new Y.Node(mp._element); - - if (Y.Lang.isFunction(mp._binder.onRefreshView)) { - mp._binder.onRefreshView(mp._node, mp._element); - } - } - - function processChildren(children, binders) { - var name, viewId, found; - for (name in children) { - if (children.hasOwnProperty(name)) { - for (viewId in binders) { - if (binders.hasOwnProperty(viewId) && ! found) { - if (binders[viewId].guid === children[name].guid) { - children[name].viewId = viewId; - found = true; - } - } - } - found = false; - } - } - return children; - } - - function bindNode(binder, node, element) { - var handles = []; - if (Y.Lang.isFunction(binder.bind)) { - // Pass the "node" to the bind method - binder.bind(node, element); - } - // all automatic event delegation - if (Y.Lang.isFunction(binder.handleClick)) { - // This code should be deferred till after the page has visibly loaded - handles.push(Y.delegate('click', binder.handleClick, node, function(){return true;}, binder)); - } - // TODO: add all the event delegation majic here - Y.log('Attached ' + handles.length + ' event delegates', 'debug', NAME); - return handles; - } - - function unbindNode(binder, handles) { - var retainBinder = false; - if (Y.Lang.isFunction(binder.unbind)) { - // let the binder decide whether it wants to stick around in case its node is reattached at some - // point in the future - retainBinder = binder.unbind.call(binder); - } - if (handles) { - Y.Array.each(handles, function(handle) { - Y.log('Detaching event handle from binder', 'debug', NAME); - handle.detach(); - }); - } - return retainBinder; - } - - function findParentProxy(mojits, childId) { - var p; - Y.Object.each(mojits, function(mojit) { - Y.Object.each(mojit.proxy.children, function(child) { - if (child.viewId === childId) { - p = mojit.proxy; - return true; - } - }); - if (p) { - return true; - } - }); - return p; - } + }; Y.mojito.Client = MojitoClient; - -}, '0.1.0', {requires: [ + +}, '0.3.0', {requires: [ 'io-base', 'event-delegate', 'node-base', @@ -830,8 +1109,8 @@

    Modules

    @@ -839,7 +1118,8 @@

    Modules

    @@ -848,11 +1128,13 @@

    Classes

    Files

    --> @@ -870,7 +1152,7 @@

    Files

    diff --git a/docs/api/mojito-test.common.js.html b/docs/api/mojito-test.common.js.html index 04de82965..c93ec5f63 100644 --- a/docs/api/mojito-test.common.js.html +++ b/docs/api/mojito-test.common.js.html @@ -2,21 +2,21 @@ - API: MojitoClient mojito-test.common.js (YUI Library) + Mojito API: MojitoClient mojito-test.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoClient  0.1.0

    +

    mojito

    +

    MojitoClient  0.3.0

    mojito > MojitoClient @@ -48,19 +48,24 @@

    MojitoClient  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
     
     
    -/*
    - * This is not production code. It is here to assist with user Mojit testing.
    - */
    +/*jslint anon:true, sloppy:true, nomen:true, node:true*/
    +/*global YUI,YUITest*/
     
     
    +/*
    + * Utilities to help with creating Mocks for user mojit testing.
    + */
     YUI.add('mojito-test', function(Y, NAME) {
     
         function EasyMock() {
             var mock = YUITest.Mock();
    +
             mock.expect = function() {
                 Y.Array.each(arguments, function(expectation) {
                     YUITest.Mock.expect(mock, expectation);
    @@ -73,29 +78,35 @@ 

    MojitoClient  0.1.0

    return mock; } + function createMockAddon(source, name) { source._addons.push(name); source[name] = new EasyMock(); } + function createMockModel(source, name) { source.models[name] = new EasyMock(); } + function createMockExtra(source, ns, name) { var mock = new EasyMock(); - if (! source[ns]) { + + if (!source[ns]) { source[ns] = {}; } - if (! source._extras[ns]) { + if (!source._extras[ns]) { source._extras[ns] = {}; } source._extras[ns][name] = mock; source[ns][name] = mock; } + function MockActionContext(opts) { var mock = YUITest.Mock(); + opts = opts || {}; mock._addons = []; mock.models = {}; @@ -130,9 +141,12 @@

    MojitoClient  0.1.0

    return mock; }; mock.verify = function() { - var i, j, mockAddon; + var i, + j, + mockAddon; + YUITest.Mock.verify(mock); - for (i=0; i<mock._addons.length; i++) { + for (i = 0; i < mock._addons.length; i += 1) { mockAddon = mock[mock._addons[i]]; mockAddon.verify(); } @@ -156,8 +170,10 @@

    MojitoClient  0.1.0

    Y.mojito.MockActionContext = MockActionContext; Y.mojito.EasyMock = EasyMock; - -}, '0.1.0', {requires: ['mojito']}); + +}, '0.3.0', {requires: [ + 'mojito' +]});
    @@ -179,8 +195,8 @@

    Modules

    @@ -188,18 +204,14 @@

    Classes

    --> @@ -217,7 +229,7 @@

    Files

    diff --git a/docs/api/mojito.common.js.html b/docs/api/mojito.common.js.html index a22d01459..25dbbdeb2 100644 --- a/docs/api/mojito.common.js.html +++ b/docs/api/mojito.common.js.html @@ -2,23 +2,23 @@ - API: CommonLibs mojito.common.js (YUI Library) + Mojito API: MojitoClient mojito.common.js ( - - + + - - + +
    -

    mojito

    -

    CommonLibs  0.1.0

    +

    mojito

    +

    MojitoClient  0.3.0

    mojito - > CommonLibs + > MojitoClient > mojito.common.js (source view) @@ -48,8 +48,16 @@

    CommonLibs  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true*/
    +/*global YUI*/
    +
    +
     YUI.add('mojito', function(Y, NAME) {
     
         Y.namespace('mojito');
    @@ -63,7 +71,9 @@ 

    CommonLibs  0.1.0

    Y.namespace('mojito.addons.ac'); Y.namespace('mojito.addons.viewEngines'); -}, '0.1.0', {requires: ['mojito-perf']}); +}, '0.3.0', {requires: [ + 'mojito-perf' +]});
    @@ -76,8 +86,8 @@

    Modules

    @@ -85,7 +95,8 @@

    Modules

    @@ -94,11 +105,13 @@

    Classes

    Files

    --> @@ -116,7 +129,7 @@

    Files

    diff --git a/docs/api/mu.client.js.html b/docs/api/mu.client.js.html index 1b0b2a2b5..1b5a2180f 100644 --- a/docs/api/mu.client.js.html +++ b/docs/api/mu.client.js.html @@ -2,23 +2,23 @@ - API: MojitoServer mu.client.js (YUI Library) + Mojito API: ActionContextAddon mu.client.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > mu.client.js (source view) @@ -48,13 +48,356 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    -YUI.add('mojito-mu', function(Y, NAME){
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
    +YUI.add('mojito-mu', function(Y, NAME) {
    +
         var CACHE = {},
    -        QUEUE_POOL = {}, // hash URL: contents
    -        // private functions
    -        isCached;
    +        QUEUE_POOL = {}, // hash URL: contents private functions
    +        isCached,
    +        Mustache;
    +
    +
    +    Mustache = (function() {
    +        var sRE,
    +            Renderer = function() {};
    +
    +        Renderer.prototype = {
    +            otag: '{{',
    +            ctag: '}}',
    +            pragmas: {},
    +            buffer: [],
    +            pragmas_implemented: {
    +                'IMPLICIT-ITERATOR': true
    +            },
    +            context: {},
    +
    +
    +            render: function(template, context, partials, in_recursion) {
    +                var html;
    +
    +                if (!in_recursion) {
    +                    this.context = context;
    +                    this.buffer = [];
    +                }
    +
    +                if (!this.includes('', template)) {
    +                    if (in_recursion) {
    +                        return template;
    +                    } else {
    +                        this.send(template);
    +                        return;
    +                    }
    +                }
    +
    +                template = this.render_pragmas(template);
    +                html = this.render_section(template, context, partials);
    +
    +                if (in_recursion) {
    +                    return this.render_tags(html, context, partials,
    +                        in_recursion);
    +                }
    +
    +                this.render_tags(html, context, partials, in_recursion);
    +            },
    +
    +
    +            send: function(line) {
    +                if (line) {
    +                    this.buffer.push(line);
    +                }
    +            },
    +
    +
    +            render_pragmas: function(template) {
    +                var my,
    +                    regex;
    +
    +                if (!this.includes('%', template)) {
    +                    return template;
    +                }
    +
    +                my = this;
    +                regex = new RegExp(this.otag + '%([\\w-]+) ?([\\w]+=[\\w]+)?' +
    +                    this.ctag);
    +
    +                return template.replace(regex,
    +                    function(match, pragma, options) {
    +                        var opts;
    +                        if (!my.pragmas_implemented[pragma]) {
    +                            throw ({message:
    +                                'This implementation of mustache ' +
    +                                'doesn\'t understand the ' +
    +                                pragma + '\' pragma'});
    +                        }
    +
    +                        my.pragmas[pragma] = {};
    +                        if (options) {
    +                            opts = options.split('=');
    +                            my.pragmas[pragma][opts[0]] = opts[1];
    +                        }
    +                        return '';
    +                    });
    +            },
    +
    +
    +            render_partial: function(name, context, partials) {
    +                name = this.trim(name);
    +                if (!partials || partials[name] === undefined) {
    +                    throw ({message: 'unknown_partial \'' + name + '\''});
    +                }
    +                if (typeof context[name] !== 'object') {
    +                    return this.render(partials[name], context, partials, true);
    +                }
    +                return this.render(partials[name], context[name], partials,
    +                    true);
    +            },
    +
    +
    +            render_section: function(template, context, partials) {
    +                var my,
    +                    regex;
    +
    +                if (!this.includes('#', template) &&
    +                        !this.includes('^', template)) {
    +                    return template;
    +                }
    +
    +                my = this;
    +                regex = new RegExp(this.otag + '(\\^|\\#)\\s*(.+)\\s*' +
    +                      this.ctag + '\n*([\\s\\S]+?)' +
    +                      this.otag + '\\/\\s*\\2\\s*' +
    +                      this.ctag + '\\s*', 'mg');
    +
    +                return template.replace(regex,
    +                    function(match, type, name, content) {
    +                        var value = my.find(name, context);
    +                        if (type === '^') {
    +                            if (!value || (my.is_array(value) &&
    +                                    value.length === 0)) {
    +                                return my.render(content, context, partials,
    +                                    true);
    +                            } else {
    +                                return '';
    +                            }
    +                        } else if (type === '#') { // normal section
    +                            if (my.is_array(value)) {
    +                                // Enumerable, Let's loop!
    +                                return my.map(value,
    +                                    function(row) {
    +                                        return my.render(content,
    +                                            my.create_context(row),
    +                                            partials, true);
    +                                    }).join('');
    +                            } else if (my.is_object(value)) {
    +                                // Object, Use it as subcontext!
    +                                return my.render(content,
    +                                    my.create_context(value), partials, true);
    +                            } else if (typeof value === 'function') {
    +                                // higher order section
    +                                return value.call(context, content,
    +                                    function(text) {
    +                                        return my.render(text, context,
    +                                            partials, true);
    +                                    });
    +                            } else if (value) {
    +                                // boolean section
    +                                return my.render(content, context, partials,
    +                                    true);
    +                            } else {
    +                                return '';
    +                            }
    +                        }
    +                    });
    +            },
    +
    +
    +            render_tags: function(template, context, partials, in_recursion) {
    +                var my = this,
    +                    new_regex = function() {
    +                        return new RegExp(my.otag +
    +                            '(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?' +
    +                            my.ctag + '+', 'g');
    +                    },
    +                    regex = new_regex(),
    +                    tag_replace_callback = function(match, operator, name) {
    +                        switch (operator) {
    +                        case '!': // ignore comments
    +                            return '';
    +                        case '=': // set new delimiters, rebuild replace regexp
    +                            my.set_delimiters(name);
    +                            regex = new_regex();
    +                            return '';
    +                        case '>': // render partial
    +                            return my.render_partial(name, context, partials);
    +                        case '{': // the triple mustache is unescaped
    +                            return my.find(name, context);
    +                        default: // escape the value
    +                            return my.escape(my.find(name, context));
    +                        }
    +                    },
    +                    lines = template.split('\n'),
    +                    i;
    +
    +                for (i = 0; i < lines.length; i += 1) {
    +                    lines[i] = lines[i].replace(regex, tag_replace_callback,
    +                        this);
    +                    if (!in_recursion) {
    +                        this.send(lines[i]);
    +                    }
    +                }
    +
    +                if (in_recursion) {
    +                    return lines.join('\n');
    +                }
    +            },
    +
    +
    +            set_delimiters: function(delimiters) {
    +                var dels = delimiters.split(' ');
    +                this.otag = this.escape_regex(dels[0]);
    +                this.ctag = this.escape_regex(dels[1]);
    +            },
    +
    +
    +            escape_regex: function(text) {
    +                // thank you Simon Willison
    +                if (!sRE) {
    +                    var specials = [
    +                        '/', '.', '*', '+', '?', '|',
    +                        '(', ')', '[', ']', '{', '}', '\\'
    +                    ];
    +                    sRE = new RegExp(
    +                        '(\\' + specials.join('|\\') + ')',
    +                        'g'
    +                    );
    +                }
    +                return text.replace(sRE, '\\$1');
    +            },
    +
    +
    +            find: function(name, context) {
    +                var value;
    +
    +                // TODO: don't assign to a parameter.
    +                name = this.trim(name);
    +
    +                // TODO: make this a utility function.
    +                // Checks whether a value is thruthy or false or 0.
    +                function is_kinda_truthy(bool) {
    +                    return bool === false || bool === 0 || bool;
    +                }
    +
    +                if (is_kinda_truthy(context[name])) {
    +                    value = context[name];
    +                } else if (is_kinda_truthy(this.context[name])) {
    +                    value = this.context[name];
    +                }
    +
    +                if (typeof value === 'function') {
    +                    return value.apply(context);
    +                }
    +                if (value !== undefined) {
    +                    return value;
    +                }
    +                return '';
    +            },
    +
    +
    +            includes: function(needle, haystack) {
    +                return haystack.indexOf(this.otag + needle) !== -1;
    +            },
    +
    +
    +            escape: function(s) {
    +                s = String(s === null ? '' : s);
    +                return s.replace(/&(?!\w+;)|["'<>\\]/g,
    +                    function(s) {
    +                        switch (s) {
    +                        case '&': return '&amp;';
    +                        case '\\': return '\\\\';
    +                        case '"': return '&quot;';
    +                        case '\'': return '&#39;';
    +                        case '<': return '&lt;';
    +                        case '>': return '&gt;';
    +                        default: return s;
    +                        }
    +                    });
    +            },
    +
    +
    +            create_context: function(_context) {
    +                var iterator,
    +                    ctx;
    +                if (this.is_object(_context)) {
    +                    return _context;
    +                } else {
    +                    iterator = '.';
    +                    if (this.pragmas['IMPLICIT-ITERATOR']) {
    +                        iterator = this.pragmas['IMPLICIT-ITERATOR'].iterator;
    +                    }
    +                    ctx = {};
    +                    ctx[iterator] = _context;
    +                    return ctx;
    +                }
    +            },
    +
    +
    +            is_object: function(a) {
    +                return a && typeof a === 'object';
    +            },
    +
    +
    +            is_array: function(a) {
    +                return Object.prototype.toString.call(a) === '[object Array]';
    +            },
    +
    +
    +            trim: function(s) {
    +                return s.replace(/^\s*|\s*$/g, '');
    +            },
    +
    +
    +            map: function(array, fn) {
    +                var r, l, i;
    +                if (typeof array.map === 'function') {
    +                    return array.map(fn);
    +                } else {
    +                    r = [];
    +                    l = array.length;
    +                    for (i = 0; i < l; i += 1) {
    +                        r.push(fn(array[i]));
    +                    }
    +                    return r;
    +                }
    +            }
    +        };  // End of Renderer.prototype definition.
    +
    +        return {
    +            name: 'mustache.js',
    +            version: '0.3.1-dev',
    +
    +            to_html: function(template, view, partials, send_fun) {
    +                var renderer = new Renderer();
    +                if (send_fun) {
    +                    renderer.send = send_fun;
    +                }
    +                renderer.render(template, view, partials);
    +                if (!send_fun) {
    +                    return renderer.buffer.join('\n');
    +                }
    +            }
    +        };
    +    }());   // End of Mustache definition.
    +
     
         /**
          * Class text.
    @@ -63,16 +406,18 @@ 

    MojitoServer  0.1.0

    */ function MuAdapter() {} + /** - * TODO DOCS - * @method render - * @param {object} data TODO - * @param {string} tmpl TODO - * @param {object} adapter TODO - * @param {object} meta TODO - * @param {bool} more TODO + * Renders the mustache template using the data provided. + * @param {object} data The data to render. + * @param {string} mojitType The name of the mojit type. + * @param {string} tmpl The name of the template to render. + * @param {object} adapter The output adapter to use. + * @param {object} meta Optional metadata. + * @param {boolean} more Whether there will be more content later. */ - MuAdapter.prototype.render = function(data, mojitType, tmpl, adapter, meta, more) { + MuAdapter.prototype.render = function(data, + mojitType, tmpl, adapter, meta, more) { var handler, useCompiled = true, @@ -80,64 +425,83 @@

    MojitoServer  0.1.0

    ns = mojitType.replace(/\./g, '_'); handler = function(id, obj) { - var i, iC, queue = [], - myAdapter, myMore, myData, myMeta; + var i, + iC, + queue = [], + myAdapter, + myMore, + myData, + myMeta; + CACHE[tmpl] = obj.responseText; - queue = QUEUE_POOL[tmpl].splice(0); - delete QUEUE_POOL[tmpl]; + queue = QUEUE_POOL[tmpl].splice(0); + delete QUEUE_POOL[tmpl]; - for (i = 0, iC = queue.length; i < iC; i += 1) { + for (i = 0, iC = queue.length; i < iC; i += 1) { myAdapter = queue[i].adapter; myMore = queue[i].more; myData = queue[i].data; myMeta = queue[i].meta; if (myMore) { - myAdapter.flush(Mustache.to_html(obj.responseText, myData), myMeta); + myAdapter.flush( + Mustache.to_html(obj.responseText, myData), + myMeta + ); } else { - myAdapter.done(Mustache.to_html(obj.responseText, myData), myMeta); + myAdapter.done( + Mustache.to_html(obj.responseText, myData), + myMeta + ); } } }; - if(meta && meta.view && meta.view['content-path']){ - // in this case, the view name doesn't necessarily relate to the contents + if (meta && meta.view && meta.view['content-path']) { + // in this case, the view name doesn't necessarily relate to the + // contents useCompiled = false; } handlerArgs = { - data: data, - adapter: adapter, - meta: meta, - more: more - }; - if (! QUEUE_POOL[tmpl]) { - QUEUE_POOL[tmpl] = [handlerArgs]; - } else { - QUEUE_POOL[tmpl].push(handlerArgs); - return; - } + data: data, + adapter: adapter, + meta: meta, + more: more + }; + + if (!QUEUE_POOL[tmpl]) { + QUEUE_POOL[tmpl] = [handlerArgs]; + } else { + QUEUE_POOL[tmpl].push(handlerArgs); + return; + } // Do we have a compiled template? - if(useCompiled && isCached(meta, ns)){ + if (useCompiled && isCached(meta, ns)) { // Log we are using a compiled view - Y.log('Using a compiled view for file "'+tmpl+'"', 'mojito', NAME); - // If we do just hand it to the "handler" - handler(null, {responseText: YUI._mojito._cache.compiled[ns].views[meta.view.name]}); - // We don't need to do an "io" call now so return. + Y.log('Using a compiled view for file "' + tmpl + '"', 'mojito', + NAME); + // If we do just hand it to the handler. + handler(null, { + responseText: + YUI._mojito._cache.compiled[ns].views[meta.view.name] + }); + // We don't need to do an IO call now so return. return; } - // Now we do some bad shit for iOS - if(typeof window !== 'undefined'){ + // Now we do some bad stuff for iOS + if (typeof window !== 'undefined') { tmpl = Y.mojito.util.iOSUrl(tmpl); } /* - * YUI has a bug that returns "failure" on "success" with "file://" calls. + * YUI has a bug that returns failure on success with file://. + * calls. */ - if (! CACHE[tmpl]) { + if (!CACHE[tmpl]) { Y.io(tmpl, { on: { complete: handler @@ -148,8 +512,20 @@

    MojitoServer  0.1.0

    } }; - // TODO 2011-08-01 refactor this into app/autoload/view-renderer.common.js? (so that each view engine doesn't need to implement it itself) + + // TODO: refactor this into app/autoload/view-renderer.common.js? + // (so that each view engine doesn't need to implement it itself) isCached = function(meta, ns) { + + // TODO: would a simple try/catch on the final one here be faster? It's + // either there (and no error) or not (error) and we return accordingly. + // try { + // return YUI._mojito._cache.compiled[ns].views[meta.view.name] !== + // 'undefined'; + // } catch { + // return false; + // } + // wow, what a checklist! return meta && meta.view && @@ -163,292 +539,10 @@

    MojitoServer  0.1.0

    Y.mojito.addons.viewEngines.mu = MuAdapter; - var Mustache = (function() { - var sRE; - - var Renderer = function() {}; - - Renderer.prototype = { - otag: "{{", - ctag: "}}", - pragmas: {}, - buffer: [], - pragmas_implemented: { - "IMPLICIT-ITERATOR": true - }, - context: {}, - - render: function(template, context, partials, in_recursion) { - - if(!in_recursion) { - this.context = context; - this.buffer = []; - } - - if(!this.includes("", template)) { - if(in_recursion) { - return template; - } else { - this.send(template); - return; - } - } - - template = this.render_pragmas(template); - var html = this.render_section(template, context, partials); - if(in_recursion) { - return this.render_tags(html, context, partials, in_recursion); - } - - this.render_tags(html, context, partials, in_recursion); - }, - - send: function(line) { - if(line) { - this.buffer.push(line); - } - }, - - render_pragmas: function(template) { - if(!this.includes("%", template)) { - return template; - } - - var that = this; - var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" + - this.ctag); - return template.replace(regex, function(match, pragma, options) { - if(!that.pragmas_implemented[pragma]) { - throw({message: - "This implementation of mustache doesn't understand the '" + - pragma + "' pragma"}); - } - that.pragmas[pragma] = {}; - if(options) { - var opts = options.split("="); - that.pragmas[pragma][opts[0]] = opts[1]; - } - return ""; - }); - }, - - render_partial: function(name, context, partials) { - name = this.trim(name); - if(!partials || partials[name] === undefined) { - throw({message: "unknown_partial '" + name + "'"}); - } - if(typeof(context[name]) !== "object") { - return this.render(partials[name], context, partials, true); - } - return this.render(partials[name], context[name], partials, true); - }, - - render_section: function(template, context, partials) { - if(!this.includes("#", template) && !this.includes("^", template)) { - return template; - } - - var that = this; - - var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag + - "\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag + - "\\s*", "mg"); - - - return template.replace(regex, function(match, type, name, content) { - var value = that.find(name, context); - if(type === "^") { - if(!value || (that.is_array(value) && value.length === 0)) { - - return that.render(content, context, partials, true); - } else { - return ""; - } - } else if(type === "#") { // normal section - if(that.is_array(value)) { // Enumerable, Let's loop! - return that.map(value, function(row) { - return that.render(content, that.create_context(row), - partials, true); - }).join(""); - } else if(that.is_object(value)) { // Object, Use it as subcontext! - return that.render(content, that.create_context(value), - partials, true); - } else if(typeof value === "function") { - // higher order section - return value.call(context, content, function(text) { - return that.render(text, context, partials, true); - }); - } else if(value) { // boolean section - return that.render(content, context, partials, true); - } else { - return ""; - } - } - }); - }, - - render_tags: function(template, context, partials, in_recursion) { - // tit for tat - var that = this; - - var new_regex = function() { - return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" + - that.ctag + "+", "g"); - }; - - var regex = new_regex(); - var tag_replace_callback = function(match, operator, name) { - switch(operator) { - case "!": // ignore comments - return ""; - case "=": // set new delimiters, rebuild the replace regexp - that.set_delimiters(name); - regex = new_regex(); - return ""; - case ">": // render partial - return that.render_partial(name, context, partials); - case "{": // the triple mustache is unescaped - return that.find(name, context); - default: // escape the value - return that.escape(that.find(name, context)); - } - }; - var lines = template.split("\n"); - var i; - for(i = 0; i < lines.length; i++) { - lines[i] = lines[i].replace(regex, tag_replace_callback, this); - if(!in_recursion) { - this.send(lines[i]); - } - } - - if(in_recursion) { - return lines.join("\n"); - } - }, - - set_delimiters: function(delimiters) { - var dels = delimiters.split(" "); - this.otag = this.escape_regex(dels[0]); - this.ctag = this.escape_regex(dels[1]); - }, - - escape_regex: function(text) { - // thank you Simon Willison - if(!sRE) { - var specials = [ - '/', '.', '*', '+', '?', '|', - '(', ')', '[', ']', '{', '}', '\\' - ]; - sRE = new RegExp( - '(\\' + specials.join('|\\') + ')', 'g' - ); - } - return text.replace(sRE, '\\$1'); - }, - - find: function(name, context) { - name = this.trim(name); - - // Checks whether a value is thruthy or false or 0 - function is_kinda_truthy(bool) { - return bool === false || bool === 0 || bool; - } - - var value; - if(is_kinda_truthy(context[name])) { - value = context[name]; - } else if(is_kinda_truthy(this.context[name])) { - value = this.context[name]; - } - - if(typeof value === "function") { - return value.apply(context); - } - if(value !== undefined) { - return value; - } - return ""; - }, - - includes: function(needle, haystack) { - return haystack.indexOf(this.otag + needle) !== -1; - }, - - escape: function(s) { - s = String(s === null ? "" : s); - return s.replace(/&(?!\w+;)|["'<>\\]/g, function(s) { - switch(s) { - case "&": return "&amp;"; - case "\\": return "\\\\"; - case '"': return '&quot;'; - case "'": return '&#39;'; - case "<": return "&lt;"; - case ">": return "&gt;"; - default: return s; - } - }); - }, - - create_context: function(_context) { - if(this.is_object(_context)) { - return _context; - } else { - var iterator = "."; - if(this.pragmas["IMPLICIT-ITERATOR"]) { - iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator; - } - var ctx = {}; - ctx[iterator] = _context; - return ctx; - } - }, - - is_object: function(a) { - return a && typeof a === "object"; - }, - - is_array: function(a) { - return Object.prototype.toString.call(a) === '[object Array]'; - }, - - trim: function(s) { - return s.replace(/^\s*|\s*$/g, ""); - }, - - map: function(array, fn) { - if (typeof array.map === "function") { - return array.map(fn); - } else { - var r = []; - var l = array.length; - var i; - for(i = 0; i < l; i++) { - r.push(fn(array[i])); - } - return r; - } - } - }; - - return({ - name: "mustache.js", - version: "0.3.1-dev", - - to_html: function(template, view, partials, send_fun) { - var renderer = new Renderer(); - if(send_fun) { - renderer.send = send_fun; - } - renderer.render(template, view, partials); - if(!send_fun) { - return renderer.buffer.join("\n"); - } - } - }); - }()); - -}, '0.1.0', {requires: ['mojito-util', 'io-base']}); +}, '0.3.0', {requires: [ + 'mojito-util', + 'io-base' +]});
    @@ -460,23 +554,29 @@

    MojitoServer  0.1.0

    Modules

    diff --git a/docs/api/mu.server.js.html b/docs/api/mu.server.js.html index d5e08c58e..6ffe7d937 100644 --- a/docs/api/mu.server.js.html +++ b/docs/api/mu.server.js.html @@ -2,23 +2,23 @@ - API: MojitoServer mu.server.js (YUI Library) + Mojito API: ActionContextAddon mu.server.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > mu.server.js (source view) @@ -48,44 +48,59 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true, node:true*/
    +/*global YUI*/
    +
    +
     YUI.add('mojito-mu', function(Y, NAME) {
     
         var mu = YUI.require(__dirname + '/../../libs/Mulib/Mu'),
             fs = require('fs');
     
    +
         /**
          * Class text.
          * @class MuAdapterServer
          * @private
          */
    -    function MuAdapter(id) {
    -        this.id = id;
    +    function MuAdapter(viewId) {
    +        this.viewId = viewId;
         }
    -    
    +
    +
         MuAdapter.prototype = {
     
             /**
    -         * TODO DOCS
    -         * @method render
    -         * @param {object} data TODO
    -         * @param {string} mojitType TODO
    -         * @param {string} tmpl TODO
    -         * @param {object} adapter TODO
    -         * @param {object} meta TODO
    -         * @param {bool} more TODO
    +         * Renders the mustache template using the data provided.
    +         * @param {object} data The data to render.
    +         * @param {string} mojitType The name of the mojit type.
    +         * @param {string} tmpl The name of the template to render.
    +         * @param {object} adapter The output adapter to use.
    +         * @param {object} meta Optional metadata.
    +         * @param {boolean} more Whether there will be more content later.
              */
             render: function(data, mojitType, tmpl, adapter, meta, more) {
    -            var self = this,
    -                handleRender = function (err, output) {
    -                    if (err) { throw err; }
    +            var me = this,
    +                handleRender = function(err, output) {
    +                    if (err) {
    +                        throw err;
    +                    }
    +
                         output.addListener('data', function(c) {
                             adapter.flush(c, meta);
                         });
    +
                         output.addListener('end', function() {
    -                        if(!more){
    -                            Y.log('render complete for ' + self.id, 'mojito', 'qeperf');
    +                        if (!more) {
    +                            Y.log('render complete for view "' +
    +                                me.viewId + '"',
    +                                'mojito', 'qeperf');
                                 adapter.done('', meta);
                             }
                         });
    @@ -97,18 +112,19 @@ 

    MojitoServer  0.1.0

    // If we don't have a compliled template, make one. Y.log('Rendering template "' + tmpl + '"', 'mojito', NAME); - mu.render(tmpl, data, {cached: meta.view.cacheTemplates}, handleRender); + mu.render(tmpl, data, {cached: meta.view.cacheTemplates}, + handleRender); }, - compiler: function(tmpl){ + compiler: function(tmpl) { return JSON.stringify(fs.readFileSync(tmpl, 'utf8')); } }; Y.namespace('mojito.addons.viewEngines').mu = MuAdapter; -}, '0.1.0', {requires: []}); +}, '0.3.0', {requires: []});
    @@ -120,23 +136,29 @@

    MojitoServer  0.1.0

    Modules

    diff --git a/docs/api/output-adapter.common.js.html b/docs/api/output-adapter.common.js.html index c8c8f6890..098c353a0 100644 --- a/docs/api/output-adapter.common.js.html +++ b/docs/api/output-adapter.common.js.html @@ -2,21 +2,21 @@ - API: ActionContextAddon output-adapter.common.js (YUI Library) + Mojito API: ActionContextAddon output-adapter.common.js ( - - + + - - + +
    -

    mojito

    -

    ActionContextAddon  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito > ActionContextAddon @@ -48,16 +48,24 @@

    ActionContextAddon  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-output-adapter-addon', function(Y, NAME) {
     
         var CHARSET = 'charset="utf-8"',
    -
    -        // the functions this core addon is going to attach to the ActionContext
    +        // the functions this core addon is going to attach to the
    +        // ActionContext
             flush,
             done,
             error,
    @@ -71,51 +79,33 @@ 

    ActionContextAddon  0.1.0

    sanitizeChildren, attachChildViewIdsToMetaChildren; - /** - * <strong>Access point:</strong> <em>ac.*</em> - * The main API point for developers in a Controller. This addon provides the core functions - * of the ActionContext: <em>flush</em>, <em>done</em>, and <em>error</em>. - * @class OutputAdapter.common - * @private - */ - function Addon(command, adapter, ac) { - /* - * This plugin doesn't act the same way as the others. It attaches its functions directly onto the ActionContext. - * Each functions is assumed that 'this' will be the actual instance of ActionContext, not the object this - * constructor is creating, which is irrelevant in this case. - */ - ac.flush = flush; - ac.done = done; - ac.error = error; - } /* see action-context.common.js for docs */ flush = function(data, meta) { // NOTE: 'this' is the ActionContext instance return this.done(data, meta, true); }; - + + /* see action-context.common.js for docs */ done = function(data, meta, more) { // NOTE: 'this' is the ActionContext instance - var guid = Y.guid(), //this.instance.guid, - // the name function to use on the callback - callbackFunc = more ? 'flush' : 'done', + var callbackFunc = more ? 'flush' : 'done', instance = this.command.instance, adapter = this._adapter, action = this.command.action, - viewName, binderId, mojitView, + mojitView, renderer = null, - contentType; + contentType, + contentPath; - //Y.log('done', 'info', NAME); - if(Y.Lang.isString(meta)){ + if (Y.Lang.isString(meta)) { // If the meta string is a serializer set it - if(serializer[meta]){ + if (serializer[meta]) { meta = { serialize: meta }; - }else{// Otherwise we think it is a template name + } else {// Otherwise we think it is a template name meta = { view: {name: meta} }; @@ -134,37 +124,46 @@

    ActionContextAddon  0.1.0

    // Cache all tempates by default meta.view.cacheTemplates = true; - if(this.app && this.app.config && this.app.config.cacheViewTemplates){ - meta.view.cacheTemplates = this.app.config.cacheViewTemplates || false; + if (this.app && this.app.config && this.app.config.cacheViewTemplates) { + meta.view.cacheTemplates = this.app.config.cacheViewTemplates || + false; } // Check to see we need to serialize the data - if(meta.serialize && serializer[meta.serialize]){ + if (meta.serialize && serializer[meta.serialize]) { // Warning: this metod can change the "meta" object data = serializer[meta.serialize].apply(this, [data, meta]); - // Once we are done remove the "serialize" option so others don't use it by mistake + // Once we are done remove the "serialize" option so others don't + // use it by mistake delete meta.serialize; } - // We want to know the "view" and "binder" used later so make sure "meta" is up-to-date + // We want to know the view name, id, and binder used later so make sure + // "meta" is up-to-date meta.view.name = meta.view.name || action; - meta.view.binder = meta.view.binder || meta.view.name; // TODO: Use a different binder - viewName = meta.view.name; - binderId = guid; - //DEBUGGING binderId = [guid, instance.type, meta.view.name].join('-'); - mojitView = instance.views[viewName]; - - // If we are given "meta.view['content-path']" use it over what we got from "instance.views" - if(mojitView && meta.view['content-path']){ + // TODO: Use a different binder + meta.view.binder = meta.view.binder || meta.view.name; + mojitView = instance.views[meta.view.name]; + if (!meta.view.id) { + meta.view.id = Y.guid(); + //DEBUGGING: meta.view.id += '-viewId-' + + // this.command.instance.type + '-' + this.command.action; + } + + // If we are given "meta.view['content-path']" use it over what we got + // from "instance.views" + if (mojitView && meta.view['content-path']) { mojitView['content-path'] = meta.view['content-path']; } - // If we are given "meta.view['engine']" use it over what we got from "instance.views" - if(mojitView && meta.view.engine){ + // If we are given "meta.view['engine']" use it over what we got from + // "instance.views" + if (mojitView && meta.view.engine) { mojitView.engine = meta.view.engine; } - // Here we ask each "thing" attached to the AC if it wants to add view "meta" + // Here we ask each "thing" attached to the AC if it wants to add view + // "meta" Y.Object.each(this, function(item) { if (item && Y.Lang.isFunction(item.mergeMetaInto)) { item.mergeMetaInto(meta); @@ -175,80 +174,108 @@

    ActionContextAddon  0.1.0

    attachChildViewIdsToMetaChildren(meta.children, meta.binders); + if (!meta.binders) { + meta.binders = {}; + } + + // Don't clobber an existing meta.binders[meta.view.id] entry + if (!meta.binders[meta.view.id]) { + meta.binders[meta.view.id] = { + base: instance.base, + action: action, + config: sanitizeConfigCopy(instance.config), + type: instance.type, + viewId: meta.view.id, + guid: instance.instanceId, // DEPRECATED, use instanceId + instanceId: instance.instanceId, + // We don't use the actual config's children object, because + // that might not have been what was actually dispatched. We get + // the actual children config that was dispatched through the + // meta object. + children: sanitizeChildren(meta.children) + }; + } + /* * Here we provide an easy way to return a string * data == 'a string of chars' */ if (Y.Lang.isString(data)) { - // if the user didn't provided a content type, we'll make it plain text - if (! contentType) { + // if the user didn't provided a content type, we'll make it plain + // text + if (!contentType) { meta.http.headers['content-type'] = ['text/plain; ' + CHARSET]; } //Y.log('pushing to native adapter', 'info', NAME); adapter[callbackFunc](data, meta); - Y.log('dispatch complete for ' + instance.guid, 'mojito', 'qeperf'); + Y.log('dispatch complete for ' + instance.instanceId, 'mojito', + 'qeperf'); return; } - - if (! meta.binders) { - meta.binders = {}; - } - meta.binders[binderId] = { - base: instance.base, - action: action, - config: sanitizeConfigCopy(instance.config), - type: instance.type, - guid: instance.guid, - children: sanitizeChildren(meta.children) - }; - // there may not be a view if this is running on the client if (mojitView) { data = data || {}; // default null data to empty view template // Get the YUI Module name of the Binder if we can. - if (meta.binders[binderId]) { - meta.binders[binderId].name = mojitView['binder-module']; - meta.binders[binderId].needs = mojitView['binder-yui-sorted']; + if (meta.binders[meta.view.id]) { + meta.binders[meta.view.id].name = mojitView['binder-module']; + meta.binders[meta.view.id].needs = + mojitView['binder-yui-sorted']; } - if (! contentType) { + if (!contentType) { meta.http.headers['content-type'] = ['text/html; ' + CHARSET]; } - data.mojit_guid = binderId; - data.mojit_view_id = binderId; + data.mojit_guid = instance.instanceId; + data.mojit_view_id = meta.view.id; data.mojit_assets = this.command.instance.assetsRoot; // Use engine to compile template view - Y.log('Rendering "' + viewName + '" view for "' + (instance.id || '@'+instance.type) + '"', 'info', NAME); + Y.log('Rendering "' + meta.view.name + '" view for "' + + (instance.id || '@' + instance.type) + '"', 'info', NAME); + + contentPath = mojitView['content-path']; + // this is mainly used by html5app + if (this.app.config.pathToRoot) { + contentPath = this.app.config.pathToRoot + contentPath; + } - renderer = new Y.mojito.ViewRenderer(mojitView.engine, guid); - renderer.render(data, instance.type, mojitView['content-path'], adapter, meta, more); + renderer = new Y.mojito.ViewRenderer( + mojitView.engine, + meta.view.id + ); + renderer.render(data, instance.type, contentPath, adapter, + meta, more); } else { if (Y.Lang.isObject(data)) { - throw new Error("Missing view template: '" + viewName + "'"); + throw new Error("Missing view template: '" + meta.view.name + + "'"); } adapter[callbackFunc](data, meta); } // Time marker - Y.mojito.perf.mark('mojito', 'core_action_end['+instance.type+':'+action+"]", 'ac.done() completed for Mojit "'+instance.type+'" with action "'+action+'"'); + Y.mojito.perf.mark('mojito', 'core_action_end[' + instance.type + + ':' + action + ']', 'ac.done() completed for Mojit "' + + instance.type + '" with action "' + action + '"'); }; + /* see action-context.common.js for docs */ error = function(err) { // NOTE: 'this' is the ActionContext instance this._adapter.error(err); }; + sanitizeConfigCopy = function(cfg) { var copy; - if (! Y.Lang.isObject(cfg)) { + if (!Y.Lang.isObject(cfg)) { return cfg; } copy = Y.mojito.util.copy(cfg); @@ -256,66 +283,73 @@

    ActionContextAddon  0.1.0

    return copy; }; + sanitizeChildren = function(children) { - if (! Y.Lang.isObject(children)) { + if (!Y.Lang.isObject(children)) { return children; } Y.Object.each(children, function(v, k) { - // We don't want child params to be included within a mojit's configuration, because it can leak implemenation - // details out to other execution environments. For example, the client runtime does not need to have the - // parameters of the mojits that were used to construct the initial client DOM. + // We don't want child params to be included within a mojit's + // configuration, because it can leak implemenation details out to + // other execution environments. For example, the client runtime + // does not need to have the parameters of the mojits that were used + // to construct the initial client DOM. delete children[k].params; }); return children; }; + attachChildViewIdsToMetaChildren = function(children, binders) { - if (! children) { + if (!children) { return; } Y.Object.each(binders, function(binderData, viewId) { - Y.Object.each(children, function(childData, childSlot) { - if (binderData.guid === childData.guid) { + Y.Object.each(children, function(childData) { + if (binderData.instanceId === childData.instanceId) { childData.viewId = viewId; } }); }); }; + /* * @private - * @method serialize_json * @param {object} data * @param {object} meta * @return {string} */ - serialize_json = function(data, meta){ + serialize_json = function(data, meta) { meta.http.headers['content-type'] = ['application/json; ' + CHARSET]; - + try { return Y.JSON.stringify(data); } catch (err) { - throw new Error("Expected JSON data, but there was a parse error on the string: \"" + data); + throw new Error('Expected JSON data, but there was a parse error' + + ' on the string: \"' + data); } - + }; + /* * @private - * @method serialize_xml * @param {object} data * @param {object} meta * @return {string} */ - serialize_xml = function(data, meta){ + serialize_xml = function(data, meta) { // A dirty XML function I found on the interwebs - function simpleXml(js, wraptag){ - if(js instanceof Object){ - return simpleXml(Object.keys(js).map(function(key){ + function simpleXml(js, wraptag) { + if (js instanceof Object) { + return simpleXml(Object.keys(js).map(function(key) { return simpleXml(js[key], key); }).join('\n'), wraptag); - }else{ - return ((wraptag)?'<'+ wraptag+'>' : '' )+js+((wraptag)?'</'+ wraptag+'>' : '' ); + } else { + return ((wraptag) ? '<' + wraptag + '>' : '') + js + + ((wraptag) ? '</' + wraptag + '>' : '' + ); } } @@ -324,21 +358,49 @@

    ActionContextAddon  0.1.0

    try { return simpleXml(data, 'xml'); } catch (err) { - throw new Error("Expected XML data, but there was a parse error on the string: \"" + data); + throw new Error('Expected XML data, but there was a parse' + + ' error on the string: \"' + data); } } return ''; }; + serializer = { json: serialize_json, xml: serialize_xml }; + + /** + * <strong>Access point:</strong> <em>ac.*</em> + * The main API point for developers in a Controller. This addon provides + * the core functions + * of the ActionContext: <em>flush</em>, <em>done</em>, and <em>error</em>. + * @class OutputAdapter.common + * @private + */ + function Addon(command, adapter, ac) { + /* + * This plugin doesn't act the same way as the others. It attaches its + * functions directly onto the ActionContext. Each functions is assumed + * that 'this' will be the actual instance of ActionContext, not the + * object this constructor is creating. + */ + ac.flush = flush; + ac.done = done; + ac.error = error; + } + Y.mojito.addons.ac.core = Addon; -}, '0.1.0', {requires: ['json-stringify', 'event-custom-base', 'mojito-view-renderer', 'mojito-util']}); +}, '0.3.0', {requires: [ + 'json-stringify', + 'event-custom-base', + 'mojito-view-renderer', + 'mojito-util' +]});
    @@ -363,10 +425,19 @@

    Classes

  • Analytics.common
  • Assets.common
  • Carrier.common
  • +
  • Composite.common
  • +
  • Config.common
  • +
  • Cookie.client
  • +
  • Cookie.server
  • Deploy.server
  • Device.common
  • +
  • Http.server
  • I13n.server
  • +
  • Intl.common
  • Meta.common
  • +
  • Params.common
  • +
  • Partial.common
  • +
  • Url.common
  • @@ -374,14 +445,25 @@

    Classes

    --> @@ -399,7 +481,7 @@

    Files

    diff --git a/docs/api/output-handler.client.js.html b/docs/api/output-handler.client.js.html index 8c6adf504..a0b5e7c90 100644 --- a/docs/api/output-handler.client.js.html +++ b/docs/api/output-handler.client.js.html @@ -2,21 +2,21 @@ - API: MojitoClient output-handler.client.js (YUI Library) + Mojito API: MojitoClient output-handler.client.js ( - - + + - - + +
    -

    mojito

    -

    MojitoClient  0.1.0

    +

    mojito

    +

    MojitoClient  0.3.0

    mojito > MojitoClient @@ -48,75 +48,32 @@

    MojitoClient  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    -YUI.add('mojito-output-handler', function(Y, NAME) {
    -
    -    var attachAssets, complete,
    -        loaded = {js: {}, css: {}};
     
    -    /*
    -     * This is an object used as the single pathway for data to leave a mojit
    -     * action execution. It is used as a component of the ActionContext object,
    -     * which uses it to call <em>done</em> and <em>flush</em> in order to complete.
    -     *
    -     * There are two versions of this object, one for the client, and one for the
    -     * server. This is the client version, which is much simpler than the server
    -     * version.
    -     *
    -     * @class OutputHandler
    -     * @constructor
    -     * @param {Function} cb
    -     * @param {Object} mojitoClient
    -     */
    -    function OutputHandler(cb, mojitoClient) {
    -        this.callback = cb;
    -        this.buffer = '';
    -        this.mojitoClient = mojitoClient;
    -    }
     
    -    OutputHandler.prototype = {
    +/*jslint anon:true, sloppy:true, browser:true*/
    +/*global YUI*/
     
    -        /*
    -         * @method flush
    -         * @param data
    -         * @param meta
    -         */
    -        flush: function(data, meta) {
    -            this.done(data, meta);
    -        },
     
    -        /*
    -         * @method done
    -         * @param data
    -         * @param meta
    -         */
    -        done: function(data, meta) {
    -            var client = this.mojitoClient,
    -                callback = this.callback;
    -            // Add meta to the page before going on
    -            if (meta && meta.assets) {
    -                attachAssets(meta.assets, function() {
    -                    complete(data, meta, client, callback);
    -                });
    -            } else {
    -                complete(data, meta, client, callback);
    -            }
    +YUI.add('mojito-output-handler', function(Y, NAME) {
     
    -        },
    -        
    -        error: function(err) {
    -            this.callback(err);
    -        }
    +    var attachAssets,
    +        complete,
    +        loaded = {
    +            js: {},
    +            css: {}
    +        };
     
    -    };
     
         // Attach assets found in the "assets" to the page
    -    attachAssets = function(assets, cb){
    +    attachAssets = function(assets, cb) {
             var toLoad = {
    -                css: [],
    -                js: []
    -            },
    +            css: [],
    +            js: []
    +        },
                 done = {},
                 blobNode = '',
                 doneChecker;
    @@ -124,13 +81,14 @@ 

    MojitoClient  0.1.0

    Y.Object.each(assets, function(types, location) { Y.Object.each(types, function(list, type) { var i; - if(type === 'blob') { - for(i=0; i<list.length; i++){ + + if (type === 'blob') { + for (i = 0; i < list.length; i += 1) { blobNode += list[i]; } } else { - for (i=0; i<list.length; i++) { - if (! loaded[type][list[i]]) { + for (i = 0; i < list.length; i += 1) { + if (!loaded[type][list[i]]) { toLoad[type].push(list[i]); } loaded[type][list[i]] = true; @@ -144,7 +102,6 @@

    MojitoClient  0.1.0

    } doneChecker = function(type) { - //Y.log('doneChecker('+type+') -- css? ' + done.css + ' -- js? ' + done.js, 'debug', NAME); if (type) { done[type] = true; } @@ -154,52 +111,118 @@

    MojitoClient  0.1.0

    }; if (toLoad.css.length > 0) { - // TODO 2011-07-21: better error detection/handling + // TODO: better error detection/handling. Y.Get.css(toLoad.css, { onEnd: function() { doneChecker('css'); } }); - } - else { + } else { done.css = true; } if (toLoad.js.length > 0) { - // TODO 2011-07-21: better error detection/handling + // TODO: better error detection/handling. Y.Get.script(toLoad.js, { onEnd: function() { doneChecker('js'); } }); - } - else { + } else { done.js = true; } // in case we have neither (or either Y.Get calls return really fast) doneChecker(); }; - complete = function(data, meta, client, callback) { + + /* + * Handles final processing for done(). + * @param {string} data The data to pass to the callback. Usually markup or + * JSON. + * @param {Object} meta The meta object from the dispatch() call. + * @param {MojitoClient} client The client instance. + * @param {string} viewId An optional view ID for the mojit. + * @param {Function} callback The callback function to invoke. + */ + complete = function(data, meta, client, viewId, callback) { // If we get some JSON decode it - if(meta.http.headers['content-type'] - && meta.http.headers['content-type'][0].indexOf('application/json') === 0){ - data = JSON.parse(data); + if (meta.http.headers['content-type'] && + meta.http.headers['content-type'][0].indexOf( + 'application/json' + ) === 0) { + data = Y.JSON.parse(data); } callback(null, data, meta); - client.cleanupBinders(); - - if(meta && meta.binders) { - setTimeout(function() { - client.attachBinders(meta.binders); + if (meta && meta.binders) { + // DOM needs to render and return to main event loop before + // attaching. + window.setTimeout(function() { + client.attachBinders(meta.binders, viewId, meta.view.id); }); } }; + + /* + * This is an object used as the single pathway for data to leave a mojit + * action execution. It is used as a component of the ActionContext object, + * which uses it to call <em>done</em> and <em>flush</em> in order to + * complete. + * + * There are two versions of this object, one for the client, and one for + * the server. This is the client version, which is much simpler than the + * server version. + * + * @class OutputHandler + * @constructor + * @param {String} viewId The view id of the current mojit binder + * responsible for this action execution + * @param {Function} cb + * @param {Object} mojitoClient + */ + function OutputHandler(viewId, cb, mojitoClient) { + this.viewId = viewId; + this.callback = cb; + this.buffer = ''; + this.mojitoClient = mojitoClient; + } + + + OutputHandler.prototype = { + + flush: function(data, meta) { + this.done(data, meta); + }, + + done: function(data, meta) { + var client = this.mojitoClient, + viewId = this.viewId, + callback = this.callback; + + // Add meta to the page before going on + if (meta && meta.assets) { + attachAssets(meta.assets, function() { + complete(data, meta, client, viewId, callback); + }); + } else { + complete(data, meta, client, viewId, callback); + } + + }, + + error: function(err) { + this.callback(err); + } + }; + Y.mojito.OutputHandler = OutputHandler; -}, '0.1.0', {requires: ['mojito']}); +}, '0.3.0', {requires: [ + 'mojito', + 'json' +]});
    @@ -221,8 +244,8 @@

    Modules

    @@ -230,18 +253,14 @@

    Classes

    --> @@ -259,7 +278,7 @@

    Files

    diff --git a/docs/api/output-handler.server.js.html b/docs/api/output-handler.server.js.html index 5847cfb62..925778a35 100644 --- a/docs/api/output-handler.server.js.html +++ b/docs/api/output-handler.server.js.html @@ -2,21 +2,21 @@ - API: MojitoServer output-handler.server.js (YUI Library) + Mojito API: MojitoServer output-handler.server.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    MojitoServer  0.3.0

    mojito > MojitoServer @@ -48,9 +48,15 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
     
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +
    +
     /**
      * This is an object used as the single pathway for data to leave a mojit
      * action execution. It is used as a component of the ActionContext object,
    @@ -61,10 +67,10 @@ 

    MojitoServer  0.1.0

    * version. * * @class OutputHandler + * @param {Object} req The Request object. + * @param {Object} res The Response object. + * @param {Function} next The next function, which should be invokable. * @constructor - * @param {Object} req - * @param {Object} res - * @private */ var OutputHandler = function(req, res, next) { this.req = req; @@ -73,23 +79,27 @@

    MojitoServer  0.1.0

    this.headers = {}; }; + OutputHandler.prototype = { setLogger: function(logger) { this.logger = logger; }, + flush: function(data, meta) { this._readMeta(meta); this._writeHeaders(); this.res.write(data); }, + done: function(data, meta) { this.logger.log('done', 'info', 'server output adapter'); this._readMeta(meta); this._writeHeaders(); - if (!data || (typeof data !== 'string' && Object.keys(data).length === 0)) { + if (!data || + (typeof data !== 'string' && Object.keys(data).length === 0)) { data = ''; } this.res.end(data); @@ -97,6 +107,7 @@

    MojitoServer  0.1.0

    this.logger.log('request closed', 'mojito', 'qeperf'); }, + error: function(err) { err = err || new Error('Unknown error occurred'); if (!err.code) { @@ -104,20 +115,27 @@

    MojitoServer  0.1.0

    } if (err.code === 404) { - + // FUTURE: [Issue 96] default Mojito 404 page this.logger.log(err, 'warn', 'Server OutputHandler'); } else { this.logger.log(err, 'error', 'Server OutputHandler'); } - var out = "<html>" + - "<body><h1>Error: " + err.code + "</h1>" + + var out = '<html>' + + '<body><h1>Error: ' + err.code + '</h1>' + + // The following line that includes the error message has been + // removed because the Paranoids don't want this data to be + // revealed in production environments. Once the bug having + // to do with different development environments has been + // fixed, we will be able to conditionally display the error + // details. -// "<p>" + err.message + "</p>" + - "<p>Error details are not available.</p>" + + // "<p>" + err.message + "</p>" + + '<p>Error details are not available.</p>' + - "</body>" + - "</html>"; + '</body>' + + '</html>'; + // TODO: [Issue 96] If YUI._mojito.DEBUG, add stack. this.done(out, { http: { @@ -127,15 +145,15 @@

    MojitoServer  0.1.0

    } } }); - }, - _readMeta: function(meta){ - if(!meta || !meta.http) { return; } + + _readMeta: function(meta) { + if (!meta || !meta.http) { return; } var header; - for(header in meta.http.headers){ - if(meta.http.headers.hasOwnProperty(header)){ + for (header in meta.http.headers) { + if (meta.http.headers.hasOwnProperty(header)) { this.headers[header] = meta.http.headers[header]; } } @@ -143,14 +161,18 @@

    MojitoServer  0.1.0

    this.statusCode = meta.http.code; }, - _writeHeaders: function(){ - if(!this.headersSent){ + + _writeHeaders: function() { + if (!this.headersSent) { this.res.writeHead(this.statusCode || 200, this.headers); this.headersSent = true; } } }; + +/** + */ module.exports = OutputHandler;
    @@ -173,16 +195,9 @@

    Modules

    @@ -191,27 +206,11 @@

    Classes

    Files

    --> @@ -229,7 +228,7 @@

    Files

    diff --git a/docs/api/params.common.js.html b/docs/api/params.common.js.html index b620aabcb..f39624171 100644 --- a/docs/api/params.common.js.html +++ b/docs/api/params.common.js.html @@ -2,23 +2,23 @@ - API: MojitoServer params.common.js (YUI Library) + Mojito API: ActionContextAddon params.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > params.common.js (source view) @@ -48,13 +48,22 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-params-addon', function(Y, NAME) {
     
    +
         /**
          * <strong>Access point:</strong> <em>ac.params.*</em>
          * Addon that provides access to any parameters given to the system
    @@ -64,17 +73,17 @@ 

    MojitoServer  0.1.0

    this.params = command.params || {}; } + Addon.prototype = { namespace: 'params', /** * Gets all params, keyed by 'route', 'url', 'body', and 'file'. - * @method getAll - * @return {object} all params + * @return {object} all params. */ - getAll: function(){ - + getAll: function() { + return { route: this.getFromRoute(), url: this.getFromUrl(), @@ -82,25 +91,32 @@

    MojitoServer  0.1.0

    file: {} //this.getFromFiles() }; }, + + /** * Alias for 'getAll'. - * @method all - * @return {object} all params + * @return {object} all params. */ all: function() { return this.getAll.apply(this, arguments); }, + /** - * Gets all params merged into one object. Route -> URL -> Body precedence. - * @method getFromMerged - * @param {string} key The name of the parameter required - * @return {string|object} param value, or all params if no key specified + * Gets all params merged into one object. Route -> URL -> Body + * precedence. + * @param {string} key The name of the parameter required. + * @return {string|object} param value, or all params if no key + * specified. */ - getFromMerged: function(key){ + getFromMerged: function(key) { if (!this._merged) { - this._merged = Y.merge(/*this.getFromFiles(),*/ this.getFromBody(), this.getFromUrl(), this.getFromRoute()); + this._merged = Y.merge(/*this.getFromFiles(),*/ + this.getFromBody(), + this.getFromUrl(), + this.getFromRoute() + ); } if (key) { @@ -109,23 +125,26 @@

    MojitoServer  0.1.0

    return this._merged; }, + + /** * Alias for 'getFromMerged'. - * @method merged - * @param {string} key The name of the parameter required - * @return {string|object} param value, or all params if no key specified + * @param {string} key The name of the parameter required. + * @return {string|object} param value, or all params if no key + * specified. */ merged: function() { return this.getFromMerged.apply(this, arguments); }, + /** * Gets route parameters - * @method getFromRoute - * @param {string} key The name of the parameter - * @return {string|object} param value, or all params if no key specified + * @param {string} key The name of the parameter. + * @return {string|object} param value, or all params if no key + * specified. */ - getFromRoute: function(key){ + getFromRoute: function(key) { if (!this._route) { this._route = Y.merge(this.params.route || {}); @@ -137,11 +156,13 @@

    MojitoServer  0.1.0

    return this._route; }, + + /** * Alias for 'getFromRoute'. - * @method route - * @param {string} key The name of the parameter required - * @return {string|object} param value, or all params if no key specified + * @param {string} key The name of the parameter required. + * @return {string|object} param value, or all params if no key + * specified. */ route: function() { return this.getFromRoute.apply(this, arguments); @@ -150,11 +171,11 @@

    MojitoServer  0.1.0

    /** * Gets URL parameters - * @method getFromUrl - * @param {string} key The name of the parameter required - * @return {string|object} param value, or all params if no key specified + * @param {string} key The name of the parameter required. + * @return {string|object} param value, or all params if no key + * specified. */ - getFromUrl: function(key){ + getFromUrl: function(key) { if (!this._url) { this._url = Y.merge(this.params.url || {}); @@ -166,23 +187,26 @@

    MojitoServer  0.1.0

    return this._url; }, + + /** * Alias for 'getFromUrl'. - * @method url - * @param {string} key The name of the parameter required - * @return {string|object} param value, or all params if no key specified + * @param {string} key The name of the parameter required. + * @return {string|object} param value, or all params if no key + * specified. */ url: function() { return this.getFromUrl.apply(this, arguments); }, + /** * Gets body parameters - * @method getFromBody - * @param {string} key The name of the parameter required - * @return {string|object} param value, or all params if no key specified + * @param {string} key The name of the parameter required. + * @return {string|object} param value, or all params if no key + * specified. */ - getFromBody: function(key){ + getFromBody: function(key) { if (!this._body) { this._body = Y.merge(this.params.body || {}); @@ -194,31 +218,37 @@

    MojitoServer  0.1.0

    return this._body; }, + + /** * Alias for 'getFromBody'. - * @method body - * @param {string} key The name of the parameter required - * @return {string|object} param value, or all params if no key specified + * @param {string} key The name of the parameter required. + * @return {string|object} param value, or all params if no key + * specified. */ body: function() { return this.getFromBody.apply(this, arguments); }, + /** * Gets file parameters * @private - * @method getFromFiles - * @param {string} key The name of the parameter required - * @return {string|object} param value, or all params if no key specified + * @param {string} key The name of the parameter required. + * @return {string|object} param value, or all params if no key + * specified. */ - getFromFiles: function(){ - throw new Error('The method "api.params.getFromFiles()" is not implemented yet.'); + getFromFiles: function() { + throw new Error('The method \'api.params.getFromFiles()\' is not' + + ' implemented yet.'); }, + + /** * Alias for 'getFromFiles'. - * @method files - * @param {string} key The name of the parameter required - * @return {string|object} param value, or all params if no key specified + * @param {string} key The name of the parameter required. + * @return {string|object} param value, or all params if no key + * specified. */ files: function() { return this.getFromFiles.apply(this, arguments); @@ -227,7 +257,9 @@

    MojitoServer  0.1.0

    Y.mojito.addons.ac.params = Addon; -}, '0.1.0', {requires: ['mojito']}); +}, '0.3.0', {requires: [ + 'mojito' +]});
    @@ -239,23 +271,29 @@

    MojitoServer  0.1.0

    Modules

    diff --git a/docs/api/partial.common.js.html b/docs/api/partial.common.js.html index 5919d9a9b..3a86cef45 100644 --- a/docs/api/partial.common.js.html +++ b/docs/api/partial.common.js.html @@ -2,23 +2,23 @@ - API: MojitoServer partial.common.js (YUI Library) + Mojito API: ActionContextAddon partial.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > partial.common.js (source view) @@ -48,16 +48,25 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-partial-addon', function(Y, NAME) {
     
    -   /**
    +    /**
         * <strong>Access point:</strong> <em>ac.partial.*</em>
    -    * Provides methods for working with "actions" and "views" on the current Mojits.
    +    * Provides methods for working with "actions" and "views" on the current
    +    * Mojits.
         * @class Partial.common
         */
         function Addon(command, adapter, ac) {
    @@ -67,6 +76,7 @@ 

    MojitoServer  0.1.0

    this.adapter = adapter; } + Addon.prototype = { namespace: 'partial', @@ -75,43 +85,43 @@

    MojitoServer  0.1.0

    * This method renders the "data" provided into the "view" specified. * The "view" must be the name of one of the files in the current * Mojits "views" folder. Returns via the callback. - * - * @method render - * @param {object} data - * @param {string} view - * @param {function} cb callback signature is function(error, result) - * @return {void} + * @param {object} data The object to be rendered. + * @param {string} view The view name to be used for rendering. + * @param {function} cb callback signature is function(error, result). */ - render: function(data, view, cb){ - + render: function(data, view, cb) { var renderer, mojitView, instance = this.command.instance, meta = {view: {}}; - if(!instance.views[view]){ - cb('View "'+view+'" not found'); + if (!instance.views[view]) { + cb('View "' + view + '" not found'); return; } mojitView = instance.views[view]; - data = data || {}; // default null data to empty view template - renderer = new Y.mojito.ViewRenderer(mojitView.engine); - Y.log('Rendering "' + view + '" view for "' + (instance.id || '@'+instance.type) + '"', 'debug', NAME); + + Y.log('Rendering "' + view + '" view for "' + (instance.id || '@' + + instance.type) + '"', 'debug', NAME); + renderer.render(data, instance.type, mojitView['content-path'], { buffer: '', - flush: function(data){ - this.buffer+=data; + + flush: function(data) { + this.buffer += data; }, - done: function(data){ - this.buffer+=data; + + done: function(data) { + this.buffer += data; cb(null, this.buffer); } }, meta); }, + /** * This method calls the current mojit's controller with the "action" * given and returns its output via the callback. @@ -126,23 +136,19 @@

    MojitoServer  0.1.0

    * <dt>file</dt><dd>&lt;object&gt; Map of key/value pairs.</dd> * </dl></dd> * </dl> - * - * @method invoke - * @param {string} action name of the action to invoke - * @param {object} options see above - * @param {function} cb callback function to be called on completion - * @return {void} + * @param {string} action name of the action to invoke. + * @param {object} options see above. + * @param {function} cb callback function to be called on completion. */ - invoke: function(action, options, cb){ - + invoke: function(action, options, cb) { var command; // If there are no options use it as the callback - if('function' === typeof options){ + if ('function' === typeof options) { cb = options; - options = {}; + options = {}; } - + command = { instance: { base: this.command.instance.base, @@ -156,22 +162,25 @@

    MojitoServer  0.1.0

    this.dispatch(command, { data: '', + meta: {}, - done: function(data, meta, more){ + + done: function(data, meta, more) { Y.mojito.util.metaMerge(this.meta, meta); - this.data+= data; + this.data += data; // Remove whatever "content-type" was set delete meta.http.headers['content-type']; // Remove whatever "view" was set - delete meta.view ; + delete meta.view; - if(!more){ + if (!more) { cb(null, this.data, this.meta); } }, - flush: function(data, meta){ + + flush: function(data, meta) { this.done(data, meta, true); } }); @@ -180,7 +189,11 @@

    MojitoServer  0.1.0

    Y.mojito.addons.ac.partial = Addon; -}, '0.1.0', {requires: ['mojito-util', 'mojito-params-addon', 'mojito-view-renderer']}); +}, '0.3.0', {requires: [ + 'mojito-util', + 'mojito-params-addon', + 'mojito-view-renderer' +]});
    @@ -192,23 +205,29 @@

    MojitoServer  0.1.0

    Modules

    diff --git a/docs/api/perf.client.js.html b/docs/api/perf.client.js.html index addf140a2..d268aea88 100644 --- a/docs/api/perf.client.js.html +++ b/docs/api/perf.client.js.html @@ -2,23 +2,23 @@ - API: CommonLibs perf.client.js (YUI Library) + Mojito API: MojitoClient perf.client.js ( - - + + - - + +
    -

    mojito

    -

    CommonLibs  0.1.0

    +

    mojito

    +

    MojitoClient  0.3.0

    mojito - > CommonLibs + > MojitoClient > perf.client.js (source view) @@ -48,47 +48,61 @@

    CommonLibs  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI,MOJITO_INIT*/
    +
    +
     YUI.add('mojito-perf', function(Y, NAME) {
     
    -    if(!YUI._mojito){
    +    if (!YUI._mojito) {
             YUI._mojito = {};
         }
     
    -    if(!YUI._mojito._perf){
    +    if (!YUI._mojito._perf) {
             YUI._mojito._perf = {};
             YUI._mojito._perf.mojito = {};
             YUI._mojito._perf.mojito.core = {};
             YUI._mojito._perf.mojito.core.msg = 'Framework start time';
    -        YUI._mojito._perf.mojito.core.time = typeof MOJITO_INIT !== 'undefined' ? MOJITO_INIT : new Date().getTime();
    +        YUI._mojito._perf.mojito.core.time =
    +            typeof MOJITO_INIT !== 'undefined' ?
    +                    MOJITO_INIT :
    +                    new Date().getTime();
         }
     
         var store = YUI._mojito._perf,
             perfEnabled = false;
     
    -    function print(group, label){
    -        // Logging has a big impact on performance :)
    -        Y.log(group+':'+label+' '+(store[group][label].time - store.mojito.core.time)+'ms', 'mojito', NAME);
    +
    +    function print(group, label) {
    +        Y.log(group + ':' + label + ' ' +
    +            (store[group][label].time - store.mojito.core.time) +
    +            'ms', 'mojito', NAME);
         }
     
    +
         Y.namespace('mojito').perf = {
     
    -        mark: function(group, label, msg){
    +        mark: function(group, label, msg) {
     
    -            if(!perfEnabled){ // Global prod flag
    +            if (!perfEnabled) { // Global prod flag
                     return;
                 }
     
    -            if(!group || !label){
    +            if (!group || !label) {
                     return;
                 }
     
    -            if(!store[group]){
    +            if (!store[group]) {
                     store[group] = {};
                 }
     
    -            if(!msg){
    +            if (!msg) {
                     msg = '';
                 }
     
    @@ -99,16 +113,18 @@ 

    CommonLibs  0.1.0

    print(group, label); }, - dump: function(){ - var group, label; + dump: function() { + + var group, + label; //MOJITO_INIT; - for(group in store){ - if(store.hasOwnProperty(group)){ - for(label in store[group]){ - if(store[group].hasOwnProperty(label)){ + for (group in store) { + if (store.hasOwnProperty(group)) { + for (label in store[group]) { + if (store[group].hasOwnProperty(label)) { print(group, label); } } @@ -116,7 +132,6 @@

    CommonLibs  0.1.0

    } } }; - });
    @@ -130,8 +145,8 @@

    Modules

    @@ -139,7 +154,8 @@

    Modules

    @@ -148,11 +164,13 @@

    Classes

    Files

    --> @@ -170,7 +188,7 @@

    Files

    diff --git a/docs/api/perf.server.js.html b/docs/api/perf.server.js.html index 94d51aebd..273a01de5 100644 --- a/docs/api/perf.server.js.html +++ b/docs/api/perf.server.js.html @@ -2,21 +2,21 @@ - API: MojitoClient perf.server.js (YUI Library) + Mojito API: MojitoClient perf.server.js ( - - + + - - + +
    -

    mojito

    -

    MojitoClient  0.1.0

    +

    mojito

    +

    MojitoClient  0.3.0

    mojito > MojitoClient @@ -48,105 +48,129 @@

    MojitoClient  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     (function() {
     
         //a single shared message buffer
         var buffer = [];
     
    -YUI.add('mojito-perf', function(Y, NAME) {
    -
    -    var perfEnabled = false,
    -        requestId = 0,
    -        microtime;
    -
    -    try {
    -        microtime = require("microtime");
    -    } catch (e) {
    -        Y.log('microtime not found. Recorded times will not have microsecond accuracy', 'warn', NAME);
    -    }
    -
    -    //internal. abstracts where timestamps come from
    -    function timestamp() {
    -        return microtime ? microtime.now() : new Date().getTime();
    -    }
    -
    -    //internal. controls the format of performance marks
    -    function format(group, label, message, id, timestamp) {
    -        if (typeof id === 'number') {
    -            id = 'req:' + id + ' ';
    -        } else {
    -            id = '';
    -        }
     
    -        if (timestamp) {
    -            timestamp = timestamp + ' ';
    -        } else {
    -            timestamp = '';
    +    YUI.add('mojito-perf', function(Y, NAME) {
    +
    +        var perfEnabled = false,
    +            requestId = 0,
    +            microtime;
    +
    +        try {
    +            microtime = require('microtime');
    +        } catch (e) {
    +            Y.log('microtime not found. Recorded times will not have' +
    +                ' microsecond accuracy', 'warn', NAME);
             }
     
    -        return id + timestamp + group + ':' + label;
    -    }
    -
    -    function mark(request, group, label, message) {
    -        if (request.connection && request.connection.mojitoPerfMark) {
    -            request.connection.mojitoPerfMark(group, label, message);
    -        } else if (typeof request === "string") {
    -            message = label;
    -            label = group;
    -            group = request;
    -            s = format(group, label, message, null, timestamp());
    -            buffer.push(s);
    -        } else {
    -            Y.log('Invalid request object', 'warn', NAME);
    -            Y.log('mark(): invalid argument', 'warn', NAME);
    +
    +        //internal. abstracts where timestamps come from
    +        function timestamp() {
    +            return microtime ? microtime.now() : new Date().getTime();
             }
    -    }
     
    -    function dump() {
    -        var len = buffer.length;
    -        for (i = 0; i < len; i++) {
    -            Y.log(buffer[i], 'mojito', NAME);
    +
    +        //internal. controls the format of performance marks
    +        function format(group, label, message, id, timestamp) {
    +            if (typeof id === 'number') {
    +                id = 'req:' + id + ' ';
    +            } else {
    +                id = '';
    +            }
    +
    +            if (timestamp) {
    +                timestamp = timestamp + ' ';
    +            } else {
    +                timestamp = '';
    +            }
    +
    +            return id + timestamp + group + ':' + label;
             }
    -        buffer = [];
    -    }
     
    -    function instrumentConnectApp(app) {
    -        app.on('connection', function(conn) {
    -            var id = requestId++;
     
    -            conn.mojitoPerfMark = function(group, label, message) {
    -                var s = format(group, label, message, id, timestamp());
    +        function mark(request, group, label, message) {
    +            var s;
    +
    +            if (request.connection && request.connection.mojitoPerfMark) {
    +                request.connection.mojitoPerfMark(group, label, message);
    +            } else if (typeof request === 'string') {
    +                message = label;
    +                label = group;
    +                group = request;
    +                s = format(group, label, message, null, timestamp());
                     buffer.push(s);
    -            };
    +            } else {
    +                Y.log('Invalid request object', 'warn', NAME);
    +                Y.log('mark(): invalid argument', 'warn', NAME);
    +            }
    +        }
     
    -            conn.on('close', function() {
    -                conn.mojitoPerfMark('mojito', NAME+':connection_end');
    -                dump();
    -            });
     
    -            conn.mojitoPerfMark('mojito', NAME+':connection');
    -        });
    +        function dump() {
    +            var len = buffer.length,
    +                i;
    +            for (i = 0; i < len; i += 1) {
    +                Y.log(buffer[i], 'mojito', NAME);
    +            }
    +            buffer = [];
    +        }
    +
    +
    +        function instrumentConnectApp(app) {
    +            app.on('connection', function(conn) {
    +                var id = (requestId += 1);
    +
    +                conn.mojitoPerfMark = function(group, label, message) {
    +                    var s = format(group, label, message, id, timestamp());
    +                    buffer.push(s);
    +                };
     
    -        app.use(function(req, res, next) {
    -            req.connection.mojitoPerfMark('mojito', NAME+':request');
    -            next();
    -        });
    -    }
    +                conn.on('close', function() {
    +                    conn.mojitoPerfMark('mojito', NAME + ':connection_end');
    +                    dump();
    +                });
    +
    +                conn.mojitoPerfMark('mojito', NAME + ':connection');
    +            });
    +
    +            app.use(function(req, res, next) {
    +                req.connection.mojitoPerfMark('mojito', NAME + ':request');
    +                next();
    +            });
    +        }
     
    -    Y.namespace('mojito').perf = {
     
    -        instrumentConnectApp: perfEnabled ? instrumentConnectApp : function() {},
    +        Y.namespace('mojito').perf = {
     
    -        mark: perfEnabled ? mark : function() {},
    +            instrumentConnectApp: perfEnabled ?
    +                    instrumentConnectApp :
    +                    function() {},
     
    -        dump: perfEnabled ? dump : function() {}
     
    -    };
    +            mark: perfEnabled ?
    +                    mark :
    +                    function() {},
     
    -});
     
    +            dump: perfEnabled ?
    +                    dump :
    +                    function() {}
    +        };
    +    });
     }());
     
    @@ -169,8 +193,8 @@

    Modules

    @@ -178,18 +202,14 @@

    Classes

    --> @@ -207,7 +227,7 @@

    Files

    diff --git a/docs/api/performance_monitor.client-optional.js.html b/docs/api/performance_monitor.client-optional.js.html index 99bab60f3..e89a65be3 100644 --- a/docs/api/performance_monitor.client-optional.js.html +++ b/docs/api/performance_monitor.client-optional.js.html @@ -2,23 +2,23 @@ - API: ActionContext performance_monitor.client-optional.js (YUI Library) + Mojito API: CommonLibs performance_monitor.client-optional.js ( - - + + - - + +
    -

    mojito

    -

    ActionContext  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > ActionContext + > CommonLibs > performance_monitor.client-optional.js (source view) @@ -47,84 +47,118 @@

    ActionContext  0.1.0

    -
    YUI.add('bean-performance-watcher', function(Y) {
    -
    -	var NAME = 'Bean Performance Monitor',
    -		b = Y.Dali.beanRegistry,
    -		BEAN_REGISTRY_STARTED 		= 'rstart',
    -        REGISTRATION_COMPLETE 		= 'rdone',
    -        REINITIALIZING_BEAN 		= 'reinits',
    -        REINITIALIZED_BEAN 			= 'reinitd',
    -		INITIALIZATION_COMPLETE 	= 'initd',
    -		INJECTION_COMPLETE 			= 'injd',
    -		t = {};
    -
    -	var PerformanceMonitor = function() {
    -		
    -		function watcher(e) {
    -			var key = e.type.split(':')[1];
    -			var stamp = new Date().getTime();
    -			if (key === REINITIALIZING_BEAN) {
    -				t[key] = {};
    -				t[key][e.bean] = stamp;
    -			} else {
    -				t[key] = stamp;
    -			}
    -			if (key === REINITIALIZED_BEAN) {
    -				delete t[REINITIALIZING_BEAN][e.bean];
    -			}
    -		}
    -		
    -		function countObjectProperties(o) {
    -			var count = 0, k;
    -			for (k in o) {
    -				if (o.hasOwnProperty(k)) {
    -					count++;
    -				}
    -			} 
    -			return count;
    -		}
    -		
    -		function report() {
    -			var total = t[INJECTION_COMPLETE] - t[BEAN_REGISTRY_STARTED],
    -				registration = t[REGISTRATION_COMPLETE] - t[BEAN_REGISTRY_STARTED],
    -				initialization = t[INITIALIZATION_COMPLETE] - t[REGISTRATION_COMPLETE],
    -				injection = t[INJECTION_COMPLETE] - t[INITIALIZATION_COMPLETE];
    -			// Y.log('Registration time: ' + registration + ' ms', 'info', NAME);
    -			// Y.log('Initialization time: ' + initialization + ' ms', 'info', NAME);
    -			// Y.log('Injection time: ' + injection + ' ms (' + (injection / b._getNumberOfInjections()) + ' per injection for ' + b._getNumberOfInjections() + ' injections)', 'info', NAME);
    -			// Y.log('== > Total bean startup time: ' + total + ' ms', 'info', '***' + NAME + '***');
    -			t.total = total;
    -			var numBeans = countObjectProperties(b.getBeans());
    -			// Y.log((total / numBeans) + 'ms per bean for ' + numBeans + ' beans', 'info', NAME);
    -		}
    -		
    -		watcher({
    -			type: 'blah:' + BEAN_REGISTRY_STARTED
    -		});
    -		
    -		b.on(REGISTRATION_COMPLETE, watcher);
    -		b.on(INITIALIZATION_COMPLETE, watcher);
    -		b.on(INJECTION_COMPLETE, watcher);
    -		b.on(REINITIALIZING_BEAN, watcher);
    -		b.on(REINITIALIZED_BEAN, watcher);
    -		b.on(INJECTION_COMPLETE, report);
    -		
    -		return {
    -			getTime: function(name) {
    -				return t[name];
    -			},
    -			destroy: function() {
    -				b.detach();
    -			}
    -		};
    -	};
    -	PerformanceMonitor.NAME = NAME;
    -	
    -	Y.namespace('Dali.beans');
    -	Y.Dali.beans.PerformanceMonitor = PerformanceMonitor;
    -			
    -}, '1.6.3', {requires:['breg']});
    +
    /*
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
    + */
    +
    +
    +/*jslint anon:true, sloppy:true*/
    +/*global YUI*/
    +
    +
    +YUI.add('bean-performance-watcher', function(Y) {
    +
    +    var NAME = 'Bean Performance Monitor',
    +        b = Y.Dali.beanRegistry,
    +        BEAN_REGISTRY_STARTED = 'rstart',
    +        REGISTRATION_COMPLETE = 'rdone',
    +        REINITIALIZING_BEAN = 'reinits',
    +        REINITIALIZED_BEAN = 'reinitd',
    +        INITIALIZATION_COMPLETE = 'initd',
    +        INJECTION_COMPLETE = 'injd',
    +        t = {},
    +        PerformanceMonitor;
    +
    +
    +    PerformanceMonitor = function() {
    +
    +        function watcher(e) {
    +            var key = e.type.split(':')[1],
    +                stamp = new Date().getTime();
    +
    +            if (key === REINITIALIZING_BEAN) {
    +                t[key] = {};
    +                t[key][e.bean] = stamp;
    +            } else {
    +                t[key] = stamp;
    +            }
    +            if (key === REINITIALIZED_BEAN) {
    +                delete t[REINITIALIZING_BEAN][e.bean];
    +            }
    +        }
    +
    +
    +        function countObjectProperties(o) {
    +            var count = 0,
    +                k;
    +
    +            for (k in o) {
    +                if (o.hasOwnProperty(k)) {
    +                    count += 1;
    +                }
    +            }
    +            return count;
    +        }
    +
    +
    +        function report() {
    +            var total = t[INJECTION_COMPLETE] - t[BEAN_REGISTRY_STARTED],
    +                registration = t[REGISTRATION_COMPLETE] -
    +                    t[BEAN_REGISTRY_STARTED],
    +                initialization = t[INITIALIZATION_COMPLETE] -
    +                    t[REGISTRATION_COMPLETE],
    +                injection = t[INJECTION_COMPLETE] -
    +                    t[INITIALIZATION_COMPLETE],
    +                numBeans;
    +            // Y.log('Registration time: ' + registration + ' ms',
    +            //     'info', NAME);
    +            // Y.log('Initialization time: ' + initialization + ' ms',
    +            //     'info', NAME);
    +            // Y.log('Injection time: ' + injection + ' ms (' +
    +            //     (injection / b._getNumberOfInjections()) +
    +            //     ' per injection for ' + b._getNumberOfInjections() +
    +            //     ' injections)', 'info', NAME);
    +            // Y.log('== > Total bean startup time: ' + total + ' ms',
    +            //     'info', '***' + NAME + '***');
    +            t.total = total;
    +            numBeans = countObjectProperties(b.getBeans());
    +            // Y.log((total / numBeans) + 'ms per bean for ' + numBeans +
    +            //     ' beans', 'info', NAME);
    +        }
    +
    +        watcher({
    +            type: 'blah:' + BEAN_REGISTRY_STARTED
    +        });
    +
    +        b.on(REGISTRATION_COMPLETE, watcher);
    +        b.on(INITIALIZATION_COMPLETE, watcher);
    +        b.on(INJECTION_COMPLETE, watcher);
    +        b.on(REINITIALIZING_BEAN, watcher);
    +        b.on(REINITIALIZED_BEAN, watcher);
    +        b.on(INJECTION_COMPLETE, report);
    +
    +        return {
    +
    +            getTime: function(name) {
    +                return t[name];
    +            },
    +
    +            destroy: function() {
    +                b.detach();
    +            }
    +        };
    +    };
    +
    +    PerformanceMonitor.NAME = NAME;
    +
    +    Y.namespace('Dali.beans');
    +    Y.Dali.beans.PerformanceMonitor = PerformanceMonitor;
    +
    +}, '1.6.3', {requires: [
    +    'breg'
    +]});
     
    @@ -135,9 +169,9 @@

    ActionContext  0.1.0

    diff --git a/docs/api/raw.json b/docs/api/raw.json index 631976f29..e28173539 100644 --- a/docs/api/raw.json +++ b/docs/api/raw.json @@ -1,10 +1 @@ -{"majorversion": 3, "filemap": {"glob.js": {"classlist": [], "name": "glob.js", "module": "MojitoServer"}, "deploy.server.js": {"classlist": ["Deploy.server"], "name": "deploy.server.js", "module": "ActionContextAddon"}, "action-context.common.js": {"classlist": ["Y.mojito.ActionContext"], "name": "action-context.common.js", "module": "MojitoClient"}, "output-handler.client.js": {"classlist": [], "name": "output-handler.client.js", "module": "MojitoClient"}, "performance_monitor.client-optional.js": {"classlist": [], "name": "performance_monitor.client-optional.js", "module": "ActionContext"}, "config.common.js": {"classlist": ["Config.common"], "name": "config.common.js", "module": "MojitoServer"}, "intl.common.js": {"classlist": ["Intl.common"], "name": "intl.common.js", "module": "MojitoServer"}, "mojito.common.js": {"classlist": [], "name": "mojito.common.js", "module": "CommonLibs"}, "loader.common.js": {"classlist": [], "name": "loader.common.js", "module": "MojitoClient"}, "carrier.server.js": {"classlist": ["Carrier.common"], "name": "carrier.server.js", "module": "ActionContextAddon"}, "device.server.js": {"classlist": ["Device.common"], "name": "device.server.js", "module": "ActionContextAddon"}, "response_processor.client-optional.js": {"classlist": [], "name": "response_processor.client-optional.js", "module": "ActionContext"}, "request_formatter.client-optional.js": {"classlist": [], "name": "request_formatter.client-optional.js", "module": "ActionContext"}, "mu.client.js": {"classlist": ["MuAdapterClient"], "name": "mu.client.js", "module": "MojitoServer"}, -"view-renderer.common.js": {"classlist": [], "name": "view-renderer.common.js", "module": "MojitoClient"}, "mojito-test.common.js": {"classlist": [], "name": "mojito-test.common.js", "module": "MojitoClient"}, "controller.common.js": {"classlist": [], "name": "controller.common.js", "module": "MojitoServer"}, "transport_utils.client-optional.js": {"classlist": [], "name": "transport_utils.client-optional.js", "module": "ActionContext"}, "output-handler.server.js": {"classlist": ["OutputHandler"], "name": "output-handler.server.js", "module": "MojitoServer"}, "mojit-proxy.client.js": {"classlist": ["Y.mojito.MojitProxy"], "name": "mojit-proxy.client.js", "module": "MojitoClient"}, -"store-provider.server.js": {"classlist": [], "name": "store-provider.server.js", "module": "MojitoServer"}, "store.client.js": {"classlist": [], "name": "store.client.js", "module": "CommonLibs"}, "assets.common.js": {"classlist": ["Assets.common"], "name": "assets.common.js", "module": "ActionContextAddon"}, "rest.common.js": {"classlist": ["Y.mojito.lib.REST"], "name": "rest.common.js", "module": "ActionContextAddon"}, "dispatch.common.js": {"classlist": ["Y.mojito.MojitoDispatcher"], "name": "dispatch.common.js", "module": "MojitoClient"}, "cookie.server.js": {"classlist": ["Cookie.server"], "name": "cookie.server.js", "module": "MojitoServer"}, "meta.common.js": {"classlist": ["Meta.common"], "name": "meta.common.js", "module": "ActionContextAddon"}, "params.common.js": {"classlist": ["Params.common"], "name": "params.common.js", "module": "MojitoServer"}, -"tunnel.client-optional.js": {"classlist": [], "name": "tunnel.client-optional.js", "module": "CommonLibs"}, "output-adapter.common.js": {"classlist": ["OutputAdapter.common"], "name": "output-adapter.common.js", "module": "ActionContextAddon"}, "request_handler.client-optional.js": {"classlist": [], "name": "request_handler.client-optional.js", "module": "ActionContext"}, "util.common.js": {"classlist": [], "name": "util.common.js", "module": "MojitoClient"}, "response_formatter.client-optional.js": {"classlist": [], "name": "response_formatter.client-optional.js", "module": "ActionContext"}, "transport.client-optional.js": {"classlist": [], "name": "transport.client-optional.js", "module": "ActionContext"}, "controller.server.js": {"classlist": [], "name": "controller.server.js", "module": "MojitoServer"}, "requestor.client-optional.js": {"classlist": [], "name": "requestor.client-optional.js", "module": "ActionContext"}, "logger.common.js": {"classlist": [], "name": "logger.common.js", "module": "MojitoClient"}, "controller-context.common.js": {"classlist": [], "name": "controller-context.common.js", "module": "MojitoClient"}, "partial.common.js": {"classlist": ["Partial.common"], "name": "partial.common.js", "module": "MojitoServer"}, "cookie.client.js": {"classlist": ["Cookie.client"], "name": "cookie.client.js", "module": "MojitoServer"}, "resource-store-adapter.common.js": {"classlist": ["Y.mojito.lib.MojitoDispatcher"], "name": "resource-store-adapter.common.js", "module": "CommonLibs"}, "perf.client.js": {"classlist": [], "name": "perf.client.js", "module": "CommonLibs"}, "server-log.js": {"classlist": [], "name": "server-log.js", "module": "MojitoServer"}, "dali_bean.client-optional.js": {"classlist": [], "name": "dali_bean.client-optional.js", "module": "ActionContext"}, "route-maker.common.js": {"classlist": [], "name": "route-maker.common.js", "module": "MojitoClient"}, "i13n.common.js": {"classlist": ["I13n.server"], "name": "i13n.common.js", "module": "ActionContextAddon"}, "composite.common.js": {"classlist": ["Composite.common"], "name": "composite.common.js", "module": "MojitoServer"}, "analytics.common.js": {"classlist": ["Analytics.common"], "name": "analytics.common.js", "module": "MojitoServer"}, "io_facade.client-optional.js": {"classlist": [], "name": "io_facade.client-optional.js", "module": "ActionContext"}, "http.server.js": {"classlist": ["Http.server"], "name": "http.server.js", "module": "MojitoServer"}, "mu.server.js": {"classlist": ["MuAdapterServer"], "name": "mu.server.js", "module": "MojitoServer"}, "perf.server.js": {"classlist": [], "name": "perf.server.js", "module": "MojitoClient"}, "url.common.js": {"classlist": ["Url.common"], "name": "url.common.js", "module": "MojitoServer"}, "registry.client-optional.js": {"classlist": [], "name": "registry.client-optional.js", "module": "ActionContext"}, "mojito-client.client.js": {"classlist": ["Y.mojito.Client"], "name": "mojito-client.client.js", "module": "CommonLibs"}, "store.server.js": {"classlist": ["ServerStore"], "name": "store.server.js", "module": "MojitoServer"}, "index.js": {"classlist": [], "name": "index.js", "module": "MojitoServer"}}, "modules": {"MojitoServer": {"description": "The Mojito Server bootstrap", "submodules": [], "classlist": ["OutputHandler", "ServerStore", "MojitoServer", "MuAdapterServer", "MuAdapterClient", "Http.server", "Intl.common", "Partial.common", "Params.common", "Composite.common", "Url.common", "Cookie.server", "Config.common", "Cookie.client"], "filelist": ["server-log.js", "glob.js", "output-handler.server.js", "store.server.js", "index.js", "controller.server.js", "controller.common.js", "index.js", "controller.server.js", "store-provider.server.js", "mu.server.js", "mu.client.js", "http.server.js", "intl.common.js", "partial.common.js", "params.common.js", "composite.common.js", "url.common.js", "cookie.server.js", "config.common.js", "cookie.client.js", "analytics.common.js"], "subdata": {}, "name": "MojitoServer"}, "ActionContext": {"description": "The Action Context is a key part of the Mojito framework. The ac, for short, gives you access\nto the frameworks features from within a controller function. The ac is an abstraction that\nallows you to execute mojit actions within either a server or client context.", "submodules": [], "classlist": ["Y.mojito.ActionContext"], "filelist": ["transport.client-optional.js", "io_facade.client-optional.js", "response_processor.client-optional.js", "request_handler.client-optional.js", "requestor.client-optional.js", "transport_utils.client-optional.js", "response_formatter.client-optional.js", "request_formatter.client-optional.js", "dali_bean.client-optional.js", "registry.client-optional.js", "performance_monitor.client-optional.js"], "subdata": {}, "name": "ActionContext"}, "MojitoClient": {"description": "Client side Mojito runtime", "submodules": [], "classlist": ["Y.mojito.Client", "Y.mojito.MojitoDispatcher", "Y.mojito.MojitProxy"], "filelist": ["route-maker.common.js", "perf.server.js", "dispatch.common.js", "controller-context.common.js", "util.common.js", "loader.common.js", "output-handler.client.js", "logger.common.js", "mojit-proxy.client.js", "view-renderer.common.js", "mojito-test.common.js", "action-context.common.js"], "subdata": {}, "name": "MojitoClient"}, "ActionContextAddon": {"description": "The Action Context uses a mechanism called Addons\nto provide functionality that lives both\non the server and/or client. Each Addon provides additional functions through a namespace\nthat is attached directly to the ac argument available in every controller function.", "submodules": [], "classlist": ["Analytics.common", "Meta.common", "Assets.common", "Deploy.server", "OutputAdapter.common", "I13n.server", "Device.common", "Carrier.common", "filelist": ["meta.common.js", "assets.common.js", "deploy.server.js", "output-adapter.common.js", "i13n.common.js", "device.server.js", "carrier.server.js", "rest.common.js"], "subdata": {}, "name": "ActionContextAddon"}, "CommonLibs": {"description": "Common Library", "submodules": [], "classlist": ["Y.mojito.lib.REST", "Y.mojito.lib.MojitoDispatcher"], "filelist": ["mojito.common.js", "store.client.js", "perf.client.js", "resource-store-adapter.common.js", "tunnel.client-optional.js", "mojito-client.client.js"], "subdata": {}, "name": "CommonLibs"}}, "classmap": {"Partial.common": {"name": "Partial.common", "namespace": "", "module": "MojitoServer", "methods": {"invoke": {"return": {"type": "void", "description": ""}, "params": [{"type": "string", "name": "action", "description": " name of the action to invoke"}, {"type": "object", "name": "options", "description": " see above"}, {"type": "function", "name": "cb", "description": " callback function to be called on completion"}], "description": "This method calls the current mojit's controller with the \"action\"\ngiven and returns its output via the callback.\nThe options parameter is optional and may contain:\n
    \n
    params
    <object> must be broken out explicitly:\n
    \n
    route
    <object> Map of key/value pairs.
    \n
    url
    <object> Map of key/value pairs.
    \n
    body
    <object> Map of key/value pairs.
    \n
    file
    <object> Map of key/value pairs.
    \n
    \n
    ", "guessedname": "invoke", "guessedtype": "function"}, "render": {"return": {"type": "void", "description": ""}, "params": [{"type": "object", "name": "data", "description": ""}, {"type": "string", "name": "view", "description": ""}, {"type": "function", "name": "cb", "description": " callback signature is function(error, result)"}], "description": "This method renders the \"data\" provided into the \"view\" specified.\nThe \"view\" must be the name of one of the files in the current\nMojits \"views\" folder. Returns via the callback.", "guessedname": "render", "guessedtype": "function"}}, "file": "partial.common.js", "shortname": "Partial.common", "description": "Access point: ac.partial.*\nProvides methods for working with \"actions\" and \"views\" on the current Mojits."}, "Meta.common": {"name": "Meta.common", "namespace": "", "module": "ActionContextAddon", "methods": {"retrieve": {"params": [{"type": "function", "name": "cb", "description": " callback will be called with the stored merged object"}, {"type": "object", "name": "[optional]", "description": " scope scope of the callback"}], "description": "To retrieve stashed data that has been stored by child mojits, call\nthis function and provide a function, which will be called once the children\nhave been dispatched and all their meta data has been merged.", "guessedname": "retrieve", "guessedtype": "function"}, "store": {"params": [{"type": "string", "name": "key", "description": ""}, {"type": "object", "name": "val", "description": ""}], "description": "Stores a keyed value within the meta object of the current mojit\nexecution. You can call this as many times as you like, but\nif you use the same key, you'll override previous data. Call this within\nchild mojits when you have some data you want to make available for\nsome reason to any parents up your hierarchy.", "guessedname": "store", "guessedtype": "function"}}, "file": "meta.common.js", "shortname": "Meta.common", "description": "Access point: ac.meta.*\nAllows the usage of the \"meta\" object as a storage device, which can pass data from\nchild mojits up towards parents."}, "OutputHandler": {"name": "OutputHandler", "constructors": [{"params": [{"type": "Object", "name": "req", "description": ""}, {"type": "Object", "name": "res", "description": ""}], "description": "This is an object used as the single pathway for data to leave a mojit\naction execution. It is used as a component of the ActionContext object,\nwhich uses it to call done and flush in order to complete.\nThere are two versions of this object, one for the client, and one for the\nserver. This is the server version, which is more complex than the client\nversion."}], "namespace": "", "private": "", "guessedname": "OutputHandler", "module": "MojitoServer", "file": "output-handler.server.js", "guessedtype": "function", "shortname": "OutputHandler", "description": "This is an object used as the single pathway for data to leave a mojit\naction execution. It is used as a component of the ActionContext object,\nwhich uses it to call done and flush in order to complete.\nThere are two versions of this object, one for the client, and one for the\nserver. This is the server version, which is more complex than the client\nversion."}, "I13n.server": {"name": "I13n.server", "namespace": "", "module": "ActionContextAddon", "methods": {"trackLink": {"return": {"type": "string", "description": "url with the hash appended to it."}, "description": "Tracks the link view and gemerates the URL\nwith the hash token appended to it.", "guessedname": "trackLink", "guessedtype": "function", "params": [{"type": "string", "name": "url", "description": " - The link to be instrumented."}, {"type": "object", "name": "link_params", "description": " - parameteres"}, {"type": "", "name": "local_groups", "description": " - Optional"}, {"type": "", "name": "ult_args", "description": " - Optional"}]}, "trackPageParams": {"params": [{"type": "string", "name": "key", "description": " - The page parameter name"}, {"type": "string", "name": "vlaue", "description": " -The page parameter value"}], "description": "Tracks a pair of page parameters as (key, value) for this request.", "guessedname": "trackPageParams", "guessedtype": "function"}, "trackForm": {"return": {"type": "string", "description": "form action url with the hash appended to it."}, "description": ", , [, ult_args [, return_code]]", "guessedname": "trackForm", "guessedtype": "function", "params": [{"type": "boolean", "name": "is_post_method", "description": " - true, if the method is POST"}, {"type": "string", "name": "action_url", "description": " - the form action link to be instrumented."}, {"type": "object", "name": "link_params", "description": " - Tracking parameters."}, {"type": "", "name": "ult_args", "description": " - Optional"}]}, "make": {"params": [{"type": "string", "name": "id", "description": " it to a mojit defined at the root level of the Mojito application configuration"}, {"type": "string", "name": "action", "description": ""}, {"type": "object", "name": "routeParams", "description": " used to lookup the route in the routing table"}, {"type": "string", "name": "verb", "description": " GET, POST, PUT, DELETE (case insensitive)"}, {"type": "object", "name": "urlParams", "description": " added to the looked up route as query params"}, {"type": "object", "name": "i13nParams", "description": " parameters to be used for link tracking."}], "description": "Provides facility to create an URL to other\nmojits with a link tracking instrumentation.", "guessedname": "make", "guessedtype": "function"}, "getSpaceid": {"return": {"type": "", "description": "spaceid previously set through stampPageView() or configuration."}, "description": "Retrurn spaceid used for this request.", "guessedname": "getSpaceid", "guessedtype": "function"}, "trackUserLink": {"return": {"type": "string", "description": "url with the hash appended to it."}, "description": "Tracks the link view for the links taken from the user generated content\nand hence need to be signed by B-cookie to prevent the security problems.", "guessedname": "trackUserLink", "guessedtype": "function", "params": [{"type": "string", "name": "url", "description": " - The link to be instrumented."}, {"type": "object", "name": "link_params", "description": " - parameteres"}, {"type": "", "name": "local_groups", "description": " - Optional"}, {"type": "", "name": "ult_args", "description": " - Optional"}]}, "stampPageView": {"params": [{"type": "number", "name": "spaceid", "description": " The spaceid to be used."}], "description": "Stamps the page view event.", "guessedname": "stampPageView", "guessedtype": "function"}, "trackClickOnly": {"return": {"type": "string", "description": "url with the hash appended to it."}, "description": "Instrument links for tracking of the link clicks by gemerating the URL\nwith the hash token appended to it.", "guessedname": "trackClickOnly", "guessedtype": "function", "params": [{"type": "string", "name": "url", "description": " - The link to be instrumented."}, {"type": "object", "name": "link_params", "description": " - parameteres"}, {"type": "", "name": "ult_args", "description": " - Optional"}]}}, "file": "i13n.common.js", "shortname": "I13n.server", "description": "Access point: ac.i13n.*\nInstrumentation addon for link tracking and page views."}, "MojitoServer": {"name": "MojitoServer", "constructors": [{"description": "The Mojito Server bootstrap"}], "namespace": "", "module": "MojitoServer", "guessedname": "MOJITO_INIT", "methods": {"createServer": {"return": {"type": "object", "description": "app Express application"}, "params": [{"type": "object", "name": "options", "description": " Options for starting the app"}], "description": "Creates an Express application with the Mojito framework already added.", "guessedname": "createServer", "guessedtype": "function"}, "addMojitoToExpressApp": {"params": [{"type": "object", "name": "app", "description": " Express application"}, {"type": "object", "name": "options", "description": " The directory to start the application in"}], "description": "Adds the Mojito framework to the Express application.\nYou only need to call one of addMojitoToExpressApp() or createServer().\nIf you want to create your own Express app do that then use\naddMojitoToExpressApp(). Otherwise Mojito can create an app for you\nif you use createServer().", "guessedname": "addMojitoToExpressApp", "guessedtype": "function"}, "setStore": {"guessedname": "setStore", "params": [{"type": "ResourceStore", "name": "rs", "description": ""}], "description": "Declaration of store requirement.", "private": "", "guessedtype": "function"}}, "file": "index.js", "guessedtype": "property", "shortname": "MojitoServer", "description": "The Mojito Server bootstrap"}, "Url.common": {"name": "Url.common", "namespace": "", "module": "MojitoServer", "methods": {"make": {"params": [{"type": "string", "name": "id", "description": " it to a mojit defined at the root level of the Mojito application configuration"}, {"type": "string", "name": "action", "description": ""}, {"type": "object", "name": "routeParams", "description": " used to lookup the route in the routing table"}, {"type": "string", "name": "verb", "description": " GET, POST, PUT, DELETE (case insensitive)"}, {"type": "object", "name": "urlParams", "description": " added to the looked up route as query params"}], "description": "Generates a URL from the given parameters", "guessedname": "make", "guessedtype": "function"}, "find": {"params": [{"type": "string", "name": "url", "description": " the URL to find a route for"}, {"type": "string", "name": "verb", "description": " the HTTP method"}], "description": "Finds the first matching route from the given URL", "guessedname": "find", "guessedtype": "function"}}, "file": "url.common.js", "shortname": "Url.common", "description": "Access point: ac.url.*\nGenerates URL's based on the applictions routing configuration"}, - -"Y.mojito.MojitProxy": {"name": "Y.mojito.MojitProxy", "namespace": "Y.mojito", "module": "MojitoClient", "methods": {"render": {"params": [{"type": "object", "name": "data", "description": ""}, {"type": "string", "name": "view", "description": ""}, {"type": "function(err,str)", "name": "cb", "description": ""}], "description": "This method renders the \"data\" provided into the \"View\" specified.\nThe \"view\" must be the name of one of the files in the current\nMojits \"views\" folder. Returns via the callback.", "guessedname": "render", "guessedtype": "function"}, "invoke": {"params": [{"type": "string", "name": "action", "description": " name of the action to invoke"}, {"type": "Object", "name": "options", "description": " see above"}, {"type": "function", "name": "cb", "description": " function to be called on completion"}], "description": "Used by the mojit binders to invoke actions on themselves within Mojito.\nThe options parameter is optional and may contain:\n
    \n
    params
    <object> must be broken out explicitly:\n
    \n
    route
    <object> Map of key/value pairs.
    \n
    url
    <object> Map of key/value pairs.
    \n
    body
    <object> Map of key/value pairs.
    \n
    file
    <object> Map of key/value pairs.
    \n
    \n
    rpc
    <boolean> Means that we are immediately\nsending the request to the server to answer the invocation.
    \n
    ", "guessedname": "invoke", "guessedtype": "function"}, "destroyChild": {"params": [{"type": "", "name": "id", "description": " *Either* the slot key of the child, or the DOM view id of the child"}], "description": "Clears out a child's view, calling the appropriate life cycle functions, then destroy's its binder and\ndereferences it. Will also dereference the child from this mojit's children.", "guessedname": "destroyChild", "guessedtype": "function"}, "unlisten": {"params": [{"type": "String", "name": "[optional]", "description": " name event name"}], "description": "The opposite of the \"listen\" function. Deletes all callback functions from the\nlistener queue associated with this binder and event type. If event name is not\nspecified, all callbacks associated with this binder are deleted.", "guessedname": "unlisten", "guessedtype": "function"}, "destroySelf": {"params": [{"type": "", "name": "retainNode", "description": " if true, the binder's node will remain in the dom"}], "description": "Allows a binder to destroy itself and be removed from Mojito client runtime entirely.", "guessedname": "destroySelf", "guessedtype": "function"}, "broadcast": {"params": [{"type": "String", "name": "name", "description": " event name"}, {"type": "Object", "name": "payload", "description": " the payload for the event"}], "description": "Used by mojit binders to broadcast a message between mojits.", "guessedname": "broadcast", "guessedtype": "function"}, "refreshView": {"params": [{"type": "", "name": "opts", "description": " [optional] same as the options for invoke()"}, {"type": "", "name": "cb", "description": " [optional] called after replacement and onRefreshView have been called, sends data/meta"}], "description": "Refreshes the current DOM view for this binder without recreating the binder instance. Will call\nthe binder's onRefreshView() function when complete with the new Y.Node and HTMLElement objects.", "guessedname": "refreshView", "guessedtype": "function"}, "getChildren": {"return": {"type": "", "description": ""}, "description": "Helper function to gather up details about a mojit's children from the Mojito Client", "guessedname": "getChildren", "guessedtype": "function"}, "getFromUrl": {"return": {"type": "string|object", "description": "param value, or all params if no key specified"}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required"}], "description": "Gets URL parameters", "guessedname": "getFromUrl", "guessedtype": "function"}, "listen": {"params": [{"type": "String", "name": "name", "description": " event name"}, {"type": "Function", "name": "callback", "description": " called when an event is broadcastd with the event data"}], "description": "Allows mojit binders to register to listen to other mojit events", "guessedname": "listen", "guessedtype": "function"}}, "file": "mojit-proxy.client.js", "shortname": "MojitProxy", "properties": {"config": {"type": "{object}", "description": "The mojit configuration for this binder", "guessedname": "config", "guessedtype": "property"}, "type": {"type": "{string}", "description": "The mojit type", "guessedname": "type", "guessedtype": "property"}, "children": {"type": "{object}", "description": "An object that contains information about the children used to generate this DOM node associted with this\nbinder. This should identify what mojits may exist as children within this binder's domain. You can use it\nto broadcast messages directly to certain children as explained in the topical documentation.", "guessedname": "children", "guessedtype": "property"}, "context": {"type": "{object}", "description": "The context used to generate this page", "guessedname": "context", "guessedtype": "property"}}, "description": "The object that is given to each mojit binder to be used to interact with other mojits\nand the mojito framework."}, "Y.mojito.MojitoDispatcher": {"name": "Y.mojito.MojitoDispatcher", "constructors": [{"params": [{"type": "ServerStore", "name": "resourceStore", "description": " the store to use"}], "description": "This object is responsible for running mojits."}], "namespace": "Y.mojito", "module": "MojitoClient", "methods": {"metaMerge": {"guessedname": "metaMerge", "params": [{"type": "", "name": "to", "description": ""}, {"type": "", "name": "from", "description": ""}, {"type": "", "name": "clobber", "description": ""}], "description": "Used to merge meta objects into each other. Special consideration for certain headers values\nlike 'content-type'.", "private": "", "guessedtype": "function"}}, "private": "", "file": "dispatch.common.js", "shortname": "MojitoDispatcher", "description": "This object is responsible for running mojits."}, "Intl.common": {"name": "Intl.common", "namespace": "", "module": "MojitoServer", "methods": {"lang": {"return": {"type": "string", "description": "translated string for label"}, "params": [{"type": "string", "name": "label", "description": ""}], "description": "Returns translated string", "guessedname": "lang", "guessedtype": "function"}, "formatDate": {"return": {"type": "string", "description": "formated data for language"}, "params": [{"type": "Date", "name": "date", "description": ""}], "description": "returns local-specified date", "guessedname": "formatDate", "guessedtype": "function"}}, "file": "intl.common.js", "shortname": "Intl.common", "description": "Access point: ac.intl.*\nInternationalization addon"}, "Deploy.server": {"name": "Deploy.server", "namespace": "", "module": "ActionContextAddon", "methods": {"setStore": {"guessedname": "setStore", "params": [{"type": "ResourceStore", "name": "rs", "description": ""}], "description": "Declaration of store requirement.", "private": "", "guessedtype": "function"}, "getScripts": {"return": {"type": "object", "description": ""}, "description": "TODO RIC: [bug 4647806] This can be made faster with a single for loop and caching\nNote: A single SCRIPT tag containing all the JS on the pages is\nslower than many SCRIPT tags (checked on iPad only).", "private": "", "params": [{"type": "bool", "name": "embed", "description": ""}], "guessedname": "getScripts", "guessedtype": "function"}, "constructMojitoClientRuntime": {"params": [{"type": "AssetHandler", "name": "assetHandler", "description": " asset handler used to add scripts to the DOM under construction"}, {"type": "object", "name": "binderMap", "description": " information about the binders that will be deployed to the client"}], "description": "Builds up the browser Mojito runtime.", "guessedname": "constructMojitoClientRuntime", "guessedtype": "function"}}, "file": "deploy.server.js", "shortname": "Deploy.server", "description": "Access point: ac.deploy.*\nProvides ability to create client runtime deployment HTML"}, - -"Cookie.client": {"name": "Cookie.client", "namespace": "", "module": "MojitoServer", "file": "cookie.client.js", "shortname": "Cookie.client", "description": "Access point: ac.cookie.*\nThis client-side cookie add-on allows you to easily use cookies. This API matches the YUI Cookie API exactly.\nhttp://developer.yahoo.com/yui/3/api/Cookie.html"}, "OutputAdapter.common": {"name": "OutputAdapter.common", "namespace": "", "module": "ActionContextAddon", "private": "", "file": "output-adapter.common.js", "shortname": "OutputAdapter.common", "description": "Access point: ac.*\nThe main API point for developers in a Controller. This addon provides the core functions\nof the ActionContext: flush, done, and error."}, "Y.mojito.ActionContext": {"submodule": "ActionContext", "name": "Y.mojito.ActionContext", "namespace": "Y.mojito", "module": "ActionContext", "methods": {"execute": {"guessedname": "execute", "params": [{"type": "String", "name": "url", "description": " Url to access"}, {"type": "Object", "name": "data", "description": " The data to send"}, {"type": "String", "name": "method", "description": " GET or POST"}], "description": "Executes an io request", "private": "", "guessedtype": "function"}, "enable": {"static": "", "description": "Enables sending of requests.", "guessedname": "enable", "guessedtype": "function"}, "flush": {"params": [{"type": "object|string", "name": "data", "description": " The data you want return by the request"}, {"type": "object", "name": "meta", "description": " Any meta-data required to service the request"}], "description": "Returns data in the request and allows you to carry on execution."}, "dispatch": {"return": {"type": "", "description": "nothing. results are passed via the adapter"}, "params": [{"type": "map", "name": "command", "description": " the \"command\" describing how to dispatch the mojit. see above"}, {"type": "object", "name": "adapter", "description": " the output adapter to pass to the mojit. see above"}], "description": "This dispatch function is called one time per Mojito execution. It creates a\ncontextualized Y instance for all further internal dispatches to use. It also\ncreates the ActionContext for the mojit.\nThe command has three main parts: the \"instance\", the \"context\", and the \"params\".\n
    \ncommand: {\ninstance: ...see below...\ncontext: ...see below...\nparams: ...see below...\n}\n
    \nThe \"instance\" is a partial instance with details of the mojit instance.\nSee `ServerStore.expandInstance()` for details of the structure and which fields\nare required.\nThe \"context\" is the request context. It is built by the \"contextualizer\"\nmiddleware.\nThe \"params\" is a structured set of parameters to pass to the mojit.\n
    \nparams: {\nroute: {},\nurl: {},\nbody: {},\nfile: {},\n...\n}\n
    \n
    \nadapter: {\nflush: function(data, meta){},\ndone: function(data, meta){},\nerror: function(err){}\n}\n
    "}, "doRequest": {"return": {"type": "Object", "description": "the transactionObject from io"}, "params": [{"type": "Array", "name": "request", "description": " the request or requests to be sent to the server"}, {"type": "Boolean", "name": "forcepost", "description": " if true the request will be sent as a post, \nregardless of length"}], "description": "finally prepares the request (stringify) and sends it\nto ioFacade to be sent to the server", "private": ""}, "setRequestFormatter": {"params": [{"type": "String", "name": "requestType", "description": " The type of request that the formatter should handle."}, {"type": "Function", "name": "formatter", "description": " The function to call to format the request."}], "description": "Sets the request formatter function for a given request type.", "guessedname": "setRequestFormatter", "guessedtype": "function"}, "processTransactionResponse": {"params": [{"type": "Number", "name": "transactionId", "description": " the IO transaction id"}, {"type": "Object", "name": "ioResponseObj", "description": " the IO response object"}], "description": "Proccess an complete transaction", "private": ""}, "disable": {"params": [{"type": "Boolean", "name": "queue", "description": " (Optional) When set to true, queues all requests while disabled."}], "description": "Disables all Ajax requests for the application.", "guessedname": "disable", "guessedtype": "function"}, "done": {"params": [{"type": "object|string", "name": "data", "description": " The data you want return by the request"}, {"type": "object", "name": "meta", "description": " Any meta-data required to service the request"}], "description": "Returns data and closes the request."}, "setResponseFormatter": {"params": [{"type": "Function", "name": "formatter", "description": " The function to call to format the response object."}], "description": "Sets the response formatter function for all responses.", "guessedname": "setResponseFormatter", "guessedtype": "function"}, "error": {"params": [{"type": "Error", "name": "err", "description": " A normal JavaScript Error object is expected, but you may add a \"code\" property to the error\nif you want the framework to report a certain HTTP status code for the error. For example, if the status code\nis 404, Mojito will generate a 404 page."}], "description": "Programatically report an error to Mojito, which will handle it gracefully."}, "completeRequest": {"params": [{"type": "Number", "name": "txId", "description": " the id of the request"}, {"type": "String", "name": "method", "description": " the type of callback to call (error, success)"}, {"type": "String", "name": "result", "description": " the result of the request: error, abort, ok"}, {"type": "String", "name": "resultDetail", "description": " the resultDetails as defined in the interfaces (badcookie, badcrumb, etc)"}], "description": "once a request has been finished (either complete or aborted)\nthis method handles the final tasks of firing events, formatting responses\nregistering any modules found, and calling callbacks", "private": ""}, "destroy": {"description": "Called by the bean registry whenever this bean is reinitialized", "guessedname": "destroy", "guessedtype": "function"}, "_processRequest": {"return": {"type": "Number", "description": "the id of the request for tracking"}, "params": [{"type": "Object", "name": "requestObject", "description": " the request Id"}, {"type": "Object", "name": "cb", "description": " callback object"}, {"type": "Number", "name": "id", "description": " the id of the module making the request"}], "description": "Adds the request to the queue for processing", "private": ""}, "createWebServiceResponseObject": {"return": {"type": "Object", "description": "formated response object"}, "params": [{"type": "DaliResponseWs", "name": "response", "description": " the response from the daliProxy"}], "description": "creates a mimic of the yui response object\nfor use in web service calls", "private": ""}, "simulateResponse": {"guessedname": "_simulateResponse", "params": [{"type": "Number", "name": "id", "description": " the id of the transaction"}, {"type": "Object", "name": "details", "description": " the details of the response"}, {"type": "Boolean", "name": "badcookie", "description": " Optional. If true simulate cookies turned off"}], "description": "simulate a server response", "private": "", "guessedtype": "function"}}, "file": "action-context.common.js", "shortname": "ActionContext", "description": "The main point of entry for all mojits into Mojito. The Action Context is\npassed to every mojit action during execution, either on the client or\nserver. This object is the API into Mojito, can can have many plugins\nattached the provide extra functionality."}, "Y.mojito.lib.REST": {"name": "Y.mojito.lib.REST", "namespace": "Y.mojito.lib", "module": "CommonLibs", "guessedname": "REST", "methods": {"HEAD": {"params": [{"type": "String", "name": "url", "description": " RESTful URL to hit"}, {"type": "Object", "name": "params", "description": " parameters to add to the request"}, {"type": "Object", "name": "config", "description": " may contain 'headers' or 'timeout' values"}, {"type": "Function", "name": "callback", "description": " called with response or error"}], "description": "Makes a RESTful HEAD request to specified URL", "guessedname": "HEAD", "guessedtype": "function"}, "GET": {"params": [{"type": "String", "name": "url", "description": " RESTful URL to hit"}, {"type": "Object", "name": "params", "description": " parameters to add to the request"}, {"type": "Object", "name": "config", "description": " may contain 'headers' or 'timeout' values"}, {"type": "Function", "name": "callback", "description": " called with response or error"}], "description": "Makes a RESTful GET request to specified URL", "guessedname": "GET", "guessedtype": "function"}, "_doRequest": {"private": "", "guessedname": "_doRequest", "guessedtype": "function"}, "PUT": {"params": [{"type": "String", "name": "url", "description": " RESTful URL to hit"}, {"type": "Object", "name": "params", "description": " parameters to add to the request"}, {"type": "Object", "name": "config", "description": " may contain 'headers' or 'timeout' values"}, {"type": "Function", "name": "callback", "description": " called with response or error"}], "description": "Makes a RESTful PUT request to specified URL", "guessedname": "PUT", "guessedtype": "function"}, "POST": {"params": [{"type": "String", "name": "url", "description": " RESTful URL to hit"}, {"type": "Object", "name": "params", "description": " parameters to add to the request"}, {"type": "Object", "name": "config", "description": " may contain 'headers' or 'timeout' values"}, {"type": "Function", "name": "callback", "description": " called with response or error"}], "description": "Makes a RESTful POST request to specified URL", "guessedname": "POST", "guessedtype": "function"}, "DELETE": {"params": [{"type": "String", "name": "url", "description": " RESTful URL to hit"}, {"type": "Object", "name": "params", "description": " parameters to add to the request"}, {"type": "Object", "name": "config", "description": " may contain 'headers' or 'timeout' values"}, {"type": "Function", "name": "callback", "description": " called with response or error"}], "description": "Makes a RESTful DELETE request to specified URL", "guessedname": "DELETE", "guessedtype": "function"}}, "static": "", "file": "rest.common.js", "guessedtype": "property", "shortname": "REST", "description": "The Rest module for Mojito provides an easy way to make RESTful calls to URLs\nwithout messing about with Y.io."}, "Http.server": {"name": "Http.server", "namespace": "", "module": "MojitoServer", "methods": {"redirect": {"params": [{"type": "string", "name": "uri", "description": ""}, {"type": "Number", "name": "code", "description": " [optional] if not specifed, 301"}], "description": "This redirect is an external redirect. It causes an HTTP\nstatus code 301 by default.", "guessedname": "redirect", "guessedtype": "function"}, "getHeader": {"return": {"type": "object", "description": "header value"}, "params": [{"type": "string", "name": "name", "description": " header name"}], "description": "Returns one request header value", "guessedname": "getHeader", "guessedtype": "function"}, "addHeaders": {"params": [{"type": "object", "name": "hdrs", "description": " header values to add"}], "description": "Adds a object of headers all at once, adding to previous values", "guessedname": "addHeaders", "guessedtype": "function"}, "getRequest": {"return": {"type": "ServerRequest", "description": "http://nodejs.org/docs/v0.4.7/api/http.html#http.ServerRequest"}, "description": "Returns the HTTP request.", "guessedname": "getRequest", "guessedtype": "function"}, "addHeader": {"params": [{"type": "String", "name": "key", "description": " header name"}, {"type": "String", "name": "val", "description": " header value"}], "description": "Adds a header to the response without overriding previous values", "guessedname": "addHeader", "guessedtype": "function"}, "getHeaders": {"return": {"type": "object", "description": "all headers"}, "description": "Returns all request headers", "guessedname": "getHeaders", "guessedtype": "function"}, "getResponse": {"return": {"type": "ServerResponse", "description": "http://nodejs.org/docs/v0.4.7/api/http.html#http.ServerResponse"}, "guessedname": "getResponse", "guessedtype": "function"}, "isXhr": {"return": {"type": "boolean", "description": ""}, "description": "Helper to tell you if this is an XHR request. Checks specifically\nfor the 'x-requested-with' header.", "guessedname": "isXhr", "guessedtype": "function"}, "setHeaders": {"params": [{"type": "object", "name": "hdrs", "description": " header values to set"}], "description": "Sets a object full of headers all at once, overriding previous values", "guessedname": "setHeaders", "guessedtype": "function"}, "setHeader": {"params": [{"type": "string", "name": "key", "description": " header name"}, {"type": "string", "name": "val", "description": " header value"}], "description": "Sets a header by key, overriding previous values", "guessedname": "setHeader", "guessedtype": "function"}}, "file": "http.server.js", "shortname": "Http.server", "description": "Access point: ac.http.*\nThis is a server-only utility plugin that makes many server side\nresources available for mojit code that will never run on the client."}, "MuAdapterClient": {"name": "MuAdapterClient", "namespace": "", "module": "MojitoServer", "methods": {"render": {"params": [{"type": "object", "name": "data", "description": " TODO"}, {"type": "string", "name": "tmpl", "description": " TODO"}, {"type": "object", "name": "adapter", "description": " TODO"}, {"type": "object", "name": "meta", "description": " TODO"}, {"type": "bool", "name": "more", "description": " TODO"}], "description": "TODO DOCS", "guessedname": "render", "guessedtype": "function"}}, "private": "", "file": "mu.client.js", "shortname": "MuAdapterClient", "description": "Class text."}, "Y.mojito.Client": {"name": "Y.mojito.Client", "constructors": [{"params": [{"type": "Object", "name": "config", "description": " The entire configuration object written by the server\nto start up mojito."}], "description": "The starting point for mojito to run in the browser. You can access one instance of the Mojito Client running\nwithin the browser environment through window.YMojito.client."}], "namespace": "Y.mojito", "module": "MojitoClient", "methods": {"executeAction": {"guessedname": "executeAction", "params": [{"type": "Object", "name": "command", "description": " must contain mojit id and action to execute"}, {"type": "Function", "name": "cb", "description": " callback to run when complete"}], "description": "Used for binders to execute their actions through the Mojito framework through their\nproxies.", "private": "", "guessedtype": "function"}, "pause": {"description": "Pause the Mojito Client and all mojits that are running. This will notify all binders that they have been\npaused by calling their onPause() functions. It will prevent the immediate execution of several mojit proxy\noperations that might cause a long process to begin (especially things that might go to the server).\nTo resume, simply call .resume(). This will immediately execute all actions that occurred while Mojito was\npaused.", "guessedname": "pause", "guessedtype": "function"}, "find": {"params": [{"type": "string", "name": "url", "description": " the URL to find a route for"}, {"type": "string", "name": "verb", "description": " the HTTP method"}], "description": "Finds a route for a given method+URL", "guessedname": "find", "guessedtype": "function"}, "getComputedRoutes": {"return": {"type": "object", "description": "computed routes"}, "description": "For optimization. Call this to get the computed routes that can be\npassed to the constructor to avoid recomputing the routes.", "guessedname": "getComputedRoutes", "guessedtype": "function"}, "resume": {"resume": "", "description": "Resumes the Mojito client after it has been paused (see method \"pause\"). If there are any queued actions that\nwere executed and cached during the pause, calling resume() will immediately execute them. All binders are\nnotified through their onResume() function that they are been resumed.", "guessedname": "resume", "guessedtype": "function"}}, "file": "mojito-client.client.js", "shortname": "Client", "description": "The starting point for mojito to run in the browser. You can access one instance of the Mojito Client running\nwithin the browser environment through window.YMojito.client."}, "Cookie.server": {"name": "Cookie.server", "namespace": "", "module": "MojitoServer", "methods": {"set": {"params": [{"type": "string", "name": "key", "description": " The key to use"}, {"type": "string", "name": "val", "description": " The value that will be set"}], "description": "Set a cookie on the given key with the given value", "guessedname": "set", "guessedtype": "function"}, "get": {"params": [{"type": "string", "name": "[optional]", "description": " key The key to look for"}], "description": "Returns the cookie for the given key, or all cookies if the key is not specified", "guessedname": "get", "guessedtype": "function"}}, "file": "cookie.server.js", "shortname": "Cookie.server", "description": "Access point: ac.cookie.*\nThis server-side cookie add-on allows you to easily use cookies."}, "Y.mojito.lib.MojitoDispatcher": {"name": "Y.mojito.lib.MojitoDispatcher", "constructors": [{"params": [{"type": "ServerStore", "name": "resourceStore", "description": " the store to use"}], "description": "This object is responsible for running mojits."}], "namespace": "Y.mojito.lib", "module": "CommonLibs", "private": "", "file": "resource-store-adapter.common.js", "shortname": "MojitoDispatcher", "description": "This object is responsible for running mojits."}, "Device.common": {"name": "Device.common", "namespace": "", "module": "ActionContextAddon", "methods": {"get": {"returns": "value", "params": [{"type": "String", "name": "attribute", "description": " - The name of the catalog attribute e.g \"make\" or \"model\"."}], "description": "Returns the attribute of the catalog for the device\nthis request was intiated from.", "guessedname": "get", "guessedtype": "function"}}, "file": "device.server.js", "shortname": "Device.common", "description": "Access point: ac.device.get()\nDevice catalog addon"}, "Params.common": {"name": "Params.common", "namespace": "", "module": "MojitoServer", "methods": {"body": {"return": {"type": "string|object", "description": "param value, or all params if no key specified"}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required"}], "description": "Alias for 'getFromBody'.", "guessedname": "body", "guessedtype": "function"}, "getFromMerged": {"return": {"type": "string|object", "description": "param value, or all params if no key specified"}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required"}], "description": "Gets all params merged into one object. Route -> URL -> Body precedence.", "guessedname": "getFromMerged", "guessedtype": "function"}, "all": {"return": {"type": "object", "description": "all params"}, "description": "Alias for 'getAll'.", "guessedname": "all", "guessedtype": "function"}, "getFromBody": {"return": {"type": "string|object", "description": "param value, or all params if no key specified"}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required"}], "description": "Gets body parameters", "guessedname": "getFromBody", "guessedtype": "function"}, "getFromUrl": {"return": {"type": "string|object", "description": "param value, or all params if no key specified"}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required"}], "description": "Gets URL parameters", "guessedname": "getFromUrl", "guessedtype": "function"}, "url": {"return": {"type": "string|object", "description": "param value, or all params if no key specified"}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required"}], "description": "Alias for 'getFromUrl'.", "guessedname": "url", "guessedtype": "function"}, "route": {"return": {"type": "string|object", "description": "param value, or all params if no key specified"}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required"}], "description": "Alias for 'getFromRoute'.", "guessedname": "route", "guessedtype": "function"}, "getAll": {"return": {"type": "object", "description": "all params"}, "description": "Gets all params, keyed by 'route', 'url', 'body', and 'file'.", "guessedname": "getAll", "guessedtype": "function"}, "getFromFiles": {"return": {"type": "string|object", "description": "param value, or all params if no key specified"}, "description": "Gets file parameters", "private": "", "params": [{"type": "string", "name": "key", "description": " The name of the parameter required"}], "guessedname": "getFromFiles", "guessedtype": "function"}, "getFromRoute": {"return": {"type": "string|object", "description": "param value, or all params if no key specified"}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter"}], "description": "Gets route parameters", "guessedname": "getFromRoute", "guessedtype": "function"}, "files": {"return": {"type": "string|object", "description": "param value, or all params if no key specified"}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required"}], "description": "Alias for 'getFromFiles'.", "guessedname": "files", "guessedtype": "function"}, "merged": {"return": {"type": "string|object", "description": "param value, or all params if no key specified"}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required"}], "description": "Alias for 'getFromMerged'.", "guessedname": "merged", "guessedtype": "function"}}, "file": "params.common.js", "shortname": "Params.common", "description": "Access point: ac.params.*\nAddon that provides access to any parameters given to the system"}, "Y.mojito.Y.Transport": {"shortname": "Y.Transport", "namespace": "Y.mojito", "name": "Y.mojito.Y.Transport", "methods": {"getName": {"return": {"type": "String", "description": "name of the registered bean, or undefined if it is not a registered bean"}, "description": "Given an instance of a bean, returns the String name", "guessedname": "getName", "guessedtype": "function"}, "wsRequestFormatter": {"guessedname": "_wsRequestFormatter", "return": {"type": "Object", "description": "the formatted request"}, "description": "Format web service requests \nusing var foo = function() format\nso that reset is easier.", "private": "", "guessedtype": "function"}, "getBean": {"return": {"type": "Object", "description": "the bean instance, or undefined if it is not registered"}, "description": "If the bean system has not been instatiated yet, this will instantiate all beans! Then one bean \ninstance is returned by name.", "guessedname": "getBean", "guessedtype": "function"}, "registerBean": {"params": [{"type": "String", "name": "name", "description": " Required identifier of this bean"}, {"type": "Object", "name": "bean", "description": " Either a constructor Function or an instance object of a bean"}], "description": "Called to register a bean or bean constructor with the bean registry. If this method is called\ntwice with the same bean, the last bean wins. Only one type of bean can be in the system at a\ntime.", "guessedname": "registerBean", "guessedtype": "function"}, "getBeans": {"return": {"type": "Object", "description": "contains all beans, each bean is accessible by bean name"}, "description": "If the bean system has not been instatiated yet, this will instantiate all beans!", "guessedname": "getBeans", "guessedtype": "function"}}}, "Composite.common": {"name": "Composite.common", "namespace": "", "module": "MojitoServer", "methods": {"execute": {"params": [{"type": "object", "name": "cfg", "description": " The configuration object to be used"}, {"type": "function", "name": "cb", "description": " The callback that will be called"}], "description": "This method requires an explicit config object and returns\na RMP compliant object via a callback.\n
    \ncfg = {\nchildren: {\nslot-1: {\ntype: \"default\",\naction: \"index\"\n},\nslot-2: {\ntype: \"default\",\naction: \"index\",\nparams: {\nroute: {},\nurl: {},\nbody: {},\nfile: {}\n}\n}\n},\nassets: {}\n}\n
    \nThe \"callback\" is an object containg the child slots with its\nrendered data.\n
    \ncallback({\nslot-1: ,\nslot-2: \n},\n{\nhttp: {}\nassets: {}\n})\n
    ", "guessedname": "execute", "guessedtype": "function"}, "done": {"params": [{"type": "object", "name": "opts", "description": " The configuration object to be used. template can be used to provide additional\nview template values."}], "description": "Automatically dispatches all the children of this mojit and collects their executed values into the view\ntemplate, keyed by the child's name within the mojit's configuration. For example, given the mojit spec:\n
    \n\"specs\": {\n\"parent\": {\n\"type\": \"MyCompositeMojit\",\n\"config\": {\n\"children\": {\n\"foo\": {\n\"type\": \"FooMojit\"\n},\n\"bar\": {\n\"type\": \"BarMojit\"\n}\n}\n}\n}\n}\n
    \nAnd given the view template:\n
    \n<div id="{{mojit_uuid}}">\n<h1>{{title}}</h1>\n<div class="fooslot">\n{{{foo}}}\n</div>\n<div class="barslot">\n{{{bar}}}\n</div>\n</div>\n
    \nAnd the controller:\n
    \nY.mojito.controller = {\nindex: function(ac) {\nac.composite.done({\ntemplate: { title: 'Hello there' } // for the view only\n});\n}\n};\n
    \nThis will execute the child intances of the \"FooMojit\" and \"BarMojit\", returning their rendered values into\nthe parent's view template, thus rendering the full parent view including the children.\nAll the parent parameters are passed along to children.", "guessedname": "done", "guessedtype": "function"}}, "file": "composite.common.js", "shortname": "Composite.common", "description": "Access point: ac.composite.*\nProvides methods for working with many Mojits."}, "Config.common": {"name": "Config.common", "namespace": "", "module": "MojitoServer", "methods": {"getDefinition": {"return": {"type": "Object|Array|String", "description": ""}, "params": [{"type": "String", "name": "key", "description": " A period separated key path to look for i.e. \"get.my.value\""}, {"type": "Object|Array|String", "name": "def", "description": " The default value to use if no match was found"}], "description": "Access definition values.", "guessedname": "getDefinition", "guessedtype": "function"}, "get": {"return": {"type": "Object|Array|String", "description": ""}, "params": [{"type": "String", "name": "key", "description": " A period separated key path to look for i.e. \"get.my.value\""}, {"type": "Object|Array|String", "name": "def", "description": " The default value to use if no match was found"}], "description": "Access config values.", "guessedname": "get", "guessedtype": "function"}}, "file": "config.common.js", "shortname": "Config.common", "description": "Access point: ac.config.*\nProvides access to the Mojits configuration"}, "Assets.common": {"name": "Assets.common", "namespace": "", "module": "ActionContextAddon", "methods": {"addBlob": {"params": [{"type": "string", "name": "content", "description": " A string of data"}, {"type": "string", "name": "location", "description": " Either \"top\" or \"bottom\""}], "description": "Method for adding a Blob of data to the page. This can be used\nfor adding custom \"script\" or \"style\" blocks.", "guessedname": "addBlob", "guessedtype": "function"}, "addCss": {"params": [{"type": "string", "name": "link", "description": " A URL (./local.css converts to /static/mojit_type/assets/local.css)"}, {"type": "string", "name": "location", "description": " Either \"top\" or \"bottom\""}], "description": "Method for adding a JS file to the page.", "guessedname": "addCss", "guessedtype": "function"}, "addJs": {"params": [{"type": "string", "name": "link", "description": " A URL (./local.css converts to /static/mojit_type/assets/local.css)"}, {"type": "string", "name": "location", "description": " Either \"top\" or \"bottom\""}], "description": "Method for adding a JS file to the page.", "guessedname": "addJs", "guessedtype": "function"}}, "file": "assets.common.js", "shortname": "Assets.common", "description": "Access point: ac.assets.*\nProvides methods for adding HTML assets to a page."}, "Carrier.common": {"name": "Carrier.common", "namespace": "", "module": "ActionContextAddon", "methods": {"get": {"returns": "value", "params": [{"type": "String", "name": "attribute", "description": " - The name of the catalog attribute e.g \"ticker\"."}], "description": "Returns the attribute of the catalog for the current carrier used for\nthis request.", "guessedname": "get", "guessedtype": "function"}}, "file": "carrier.server.js", "shortname": "Carrier.common", "description": "Access point: ac.carrier.get()\nCarrier catalog addon"}, - -"Analytics.common": {"name": "Analytics.common", "namespace": "", "module": "ActionContextAddon", "methods": {"retrieve": {"params": [{"type": "function", "name": "cb", "description": " callback will be called with the analytics object"}, {"type": "object", "name": "[optional]", "description": " scope scope of the callback"}], "description": "To retrieve analytics data that has been stored by child mojits, call\nthis function and provide a function, which will be called once the children\nhave been dispatched and all their analytics data has been merged.", "guessedname": "retrieve", "guessedtype": "function"}, "setMergeFunction": {"params": [{"type": "function", "name": "fn", "description": " user-defined merge function, which should accept\ntwo objects, the first is \"to\", and the second is \"from\". this function\nshould return the merged object."}], "description": "Allows a way for addons mixed in after this one to set an alternate\ndata merge function when analytics from multiple children are combined.\nThe default merge function is the same one used internally by Mojito\nto merge meta data, and will be sufficient for most use cases.", "guessedname": "setMergeFunction", "guessedtype": "function"}, "store": {"params": [{"type": "object", "name": "val", "description": " should be an object bag full of whatever you wish"}], "description": "Store an analytic value. This function can be called multiple times\nwithin a mojit, and uses a merging function to combine objects.", "guessedname": "store", "guessedtype": "function"}}, "file": "analytics.common.js", "shortname": "Analytics.common", "description": "Access point: ac.analytics.*\nProvides an easy way to stash analytics information within child mojits\nand retrieve them within parent after the children have been executed.\nData handled by this addon, however, cannot be used to augment the\nnormal data flow. IE: you cannot retrieve analytics data and then call\nac.done()."}, "ServerStore": {"name": "ServerStore", "constructors": [{"params": [{"type": "", "name": "root", "description": ""}], "description": "A \"resource\" is the smallest-sized component in the mojito framework.\nIt has a representation on disk.\nSometimes a resource will be fully represented by a single file.\nSometimes multiple files together will comprise one resource.\nSometimes multiple resources will be defined in one file.\nIt is the job of the resource store to manage all this. \nRESOURCE TYPES\nconfig -- a piece of configuration, sometimes for another resource \ncontroller -- the controller for a mojit\nmodel -- a model for a mojit\nview -- a view for a mojit\nbinder -- a binder for a mojit\naction -- an action to augment the controller\nasset -- an asset (css, js, image, etc)\naddon -- an addon to the mojito system\nyui-lang -- a YUI3 language bundle\nyui-module -- a YUI3 module (that isn't one of the above)\nRESOURCE METADATA\n(not all resources will have all details)\n(not all combinations of type:source are valid)\n- id\ncontext-insensitive ID of the resource\n(type + 'app' + (details specific to type))\n(type + 'mojit' + mojit-type + (details specific to type))\n- type\nsee above\n- source\n`fw`, `app` or `mojit`\nwhere the resource is defined\n- fsPath\nthe path on the filesystem\n- staticHandlerURL\nfor resources that can be deployed by reference to the client\nthe URL that will cause the asset handler to serve the resource\n- name\nspecific to type\n- configType\nfor type=config\nthe type of the configuration\n- viewEngine\nfor type=view\n`mu`, `dust`, etc\n- viewOutputFormat\nfor type=view\noutput format that the view will generate\n`xml`, `html`, etc\n- assetType\nfor type=asset\n`css`, `js`, `png`, `swf`, etc\n- addonType\nfor type=addon\nthe mojito subsystem to which the addon should be added\n- yuiModuleName\nfor any resource delivered as a YUI3 module\nthe YUI3 module name\n- yuiModuleVersion\nfor any resource delivered as a YUI3 module\nthe YUI3 module version\n- yuiModuleMeta\nfor any resource delivered as a YUI3 module\nthe YUI3 module metadata\n(requires, langs, etc)\n- yuiSortedPaths\nfor any resource delivered as a YUI3 module\na list of YUI modules required by the module,\nwith transitive dependencies resolved\nformat: { yui-module-name: URL-to-load-yui-module }"}], "namespace": "", "private": "", "guessedname": "libfs", "methods": {"preload": {"return": {"type": "undefined", "description": ""}, "description": "Preloads everything in the app, and as well pertinent parts of\nthe framework.", "appconfig": "overrides for the app config", "guessedname": "preload", "guessedtype": "function", "applicationenvironment": "??"}, "expandInstanceForEnv": {"return": {"type": "", "description": "nothing. results passed back via the callback"}, "params": [{"type": "\"client\"|\"server\"", "name": "env", "description": " which environment to expand the instance for"}, {"type": "map", "name": "instance", "description": " partial instance to expand"}, {"type": "object", "name": "ctx", "description": " the request context"}, {"type": "function(err,instance)", "name": "cb", "description": " the callback to send the results to"}], "description": "This method takes a partial instance and expands it to all details needed to run the mojit.\nOnly a `base` or `type` fields are required. You should only specify one.\n
    \ninstance: {\nbase: \"\",\n// specifies a \"base\" instance which this instance will extend\n// the value refers to a key of `specs` found in `application.json`\ntype: \"\",\n// specifies the mojit type\naction: \"\",\n// specifies a default action if the instance isn't dispatched with a specific one\nconfig: {...},\n// the config for the mojit\n// this will be augmented (appropriately) with the mojit type defaults\n// found in the type's `defaults.json`\nappConfig: {...},\n// the application config (appropriate for the context)\nassetRoot: \"\",\n// path to directory containing assets\n// the path will be a URL if `env` is `client` otherwise it's a filesystem path\ndefinition: \"\",\n// the body of the `defintion.json` for the mojit type\ndefaults: \"\",\n// the body of the `defaults.json` for the mojit type\nyui: {\n// details for generating a YUI sandbox for this instance\nconfig: {\n// configuration details for the YUI.GlobalConfig.groups (or an equivalent).\n// the module paths are given as `fullpath` and contain either a URL if `env'\n// is `client` or a filesystem path if `env` is `server`\n},\nrequires: []\n// list of YUI modules that this instance requires\n},\nactions: [],\n// list of paths to the YUI modules containing actions\ncontroller: \"\",\n// path to controller\n// the path will be a URL if `env` is `client` otherwise it's a filesystem path\nlang:\n// path to YUI module of the language bundle\n// the path will be a URL if `env` is `client` otherwise it's a filesystem path\nmodels: {},\n// list of models used by the mojit type\n// the key is the model name, and the value is the path to the model file\n// the path will be a URL if `env` is `client` otherwise it's a filesystem path\nviews: {\n// list of views in the mojit type\n// the key is the view name, and the value is details about the view\nview-name: {\n\"content-path\": \"\",\n// the path to use to load the body of the view\n// the path will be a URL if `env` is `client` otherwise it's a filesystem path\n\"engine\": \"\",\n// which engine is used to render the view\n\"binder-path\": \"\",\n// the path to the binder\n// the path will be a URL if `env` is `client` otherwise it's a filesystem path\n\"binder-module\": \"\"\n// the YUI module name of the binder\n}\n}\n}\n
    ", "guessedname": "expandInstanceForEnv", "guessedtype": "function"}, "getAppConfig": {"return": {"type": "object", "description": "config object"}, "params": [{"type": "object", "name": "context", "description": " context under which to load the config"}, {"type": "string", "name": "name", "description": " type of config to read:\n- definition: reads ./application.json\n- package: reads ./package.json\n- routes: reads ./routes.json (or whatever was configured in appConfig('definition').routesFiles)"}], "description": "gets application configuration", "guessedname": "getAppConfig", "guessedtype": "function"}, "getRoutes": {"return": {"type": "object", "description": "routes"}, "params": [{"type": "object", "name": "ctx", "description": " context under which to load the routes"}], "description": "Returns the routes configured in the application.", "guessedname": "getRoutes", "guessedtype": "function"}, "expandInstance": {"return": {"type": "", "description": "nothing. results passed back via the callback"}, "params": [{"type": "map", "name": "instance", "description": " partial instance to expand"}, {"type": "object", "name": "ctx", "description": " the request context"}, {"type": "function(err,instance)", "name": "cb", "description": " the callback to send the results to"}], "description": "This just calls expandInstanceForEnv() with `env` set to `server`.", "guessedname": "expandInstance", "guessedtype": "function"}}, "module": "MojitoServer", "file": "store.server.js", "guessedtype": "property", "shortname": "ServerStore", "description": "A \"resource\" is the smallest-sized component in the mojito framework.\nIt has a representation on disk.\nSometimes a resource will be fully represented by a single file.\nSometimes multiple files together will comprise one resource.\nSometimes multiple resources will be defined in one file.\nIt is the job of the resource store to manage all this. \nRESOURCE TYPES\nconfig -- a piece of configuration, sometimes for another resource \ncontroller -- the controller for a mojit\nmodel -- a model for a mojit\nview -- a view for a mojit\nbinder -- a binder for a mojit\naction -- an action to augment the controller\nasset -- an asset (css, js, image, etc)\naddon -- an addon to the mojito system\nyui-lang -- a YUI3 language bundle\nyui-module -- a YUI3 module (that isn't one of the above)\nRESOURCE METADATA\n(not all resources will have all details)\n(not all combinations of type:source are valid)\n- id\ncontext-insensitive ID of the resource\n(type + 'app' + (details specific to type))\n(type + 'mojit' + mojit-type + (details specific to type))\n- type\nsee above\n- source\n`fw`, `app` or `mojit`\nwhere the resource is defined\n- fsPath\nthe path on the filesystem\n- staticHandlerURL\nfor resources that can be deployed by reference to the client\nthe URL that will cause the asset handler to serve the resource\n- name\nspecific to type\n- configType\nfor type=config\nthe type of the configuration\n- viewEngine\nfor type=view\n`mu`, `dust`, etc\n- viewOutputFormat\nfor type=view\noutput format that the view will generate\n`xml`, `html`, etc\n- assetType\nfor type=asset\n`css`, `js`, `png`, `swf`, etc\n- addonType\nfor type=addon\nthe mojito subsystem to which the addon should be added\n- yuiModuleName\nfor any resource delivered as a YUI3 module\nthe YUI3 module name\n- yuiModuleVersion\nfor any resource delivered as a YUI3 module\nthe YUI3 module version\n- yuiModuleMeta\nfor any resource delivered as a YUI3 module\nthe YUI3 module metadata\n(requires, langs, etc)\n- yuiSortedPaths\nfor any resource delivered as a YUI3 module\na list of YUI modules required by the module,\nwith transitive dependencies resolved\nformat: { yui-module-name: URL-to-load-yui-module }"}, "MuAdapterServer": {"name": "MuAdapterServer", "namespace": "", "module": "MojitoServer", "methods": {"render": {"params": [{"type": "object", "name": "data", "description": " TODO"}, {"type": "string", "name": "mojitType", "description": " TODO"}, {"type": "string", "name": "tmpl", "description": " TODO"}, {"type": "object", "name": "adapter", "description": " TODO"}, {"type": "object", "name": "meta", "description": " TODO"}, {"type": "bool", "name": "more", "description": " TODO"}], "description": "TODO DOCS", "guessedname": "render", "guessedtype": "function"}}, "private": "", "file": "mu.server.js", "shortname": "MuAdapterServer", "description": "Class text."}}, "version": "0.1.0", "namespaces": ["Y.mojito.lib", "Y.mojito"]} +{"majorversion": 3, "filemap": {"glob.js": {"classlist": [], "name": "glob.js", "module": "MojitoServer"}, "deploy.server.js": {"classlist": ["Deploy.server"], "name": "deploy.server.js", "module": "ActionContextAddon"}, "action-context.common.js": {"classlist": ["ActionContext"], "name": "action-context.common.js", "module": "ActionContextAddon"}, "output-handler.client.js": {"classlist": [], "name": "output-handler.client.js", "module": "MojitoClient"}, "config.common.js": {"classlist": ["Config.common"], "name": "config.common.js", "module": "ActionContextAddon"}, "intl.common.js": {"classlist": ["Intl.common"], "name": "intl.common.js", "module": "ActionContextAddon"}, "mojito.common.js": {"classlist": [], "name": "mojito.common.js", "module": "MojitoClient"}, "loader.common.js": {"classlist": [], "name": "loader.common.js", "module": "ActionContext"}, "carrier.server.js": {"classlist": ["Carrier.common"], "name": "carrier.server.js", "module": "ActionContextAddon"}, "device.server.js": {"classlist": ["Device.common"], "name": "device.server.js", "module": "ActionContextAddon"}, "response_processor.client-optional.js": {"classlist": [], "name": "response_processor.client-optional.js", "module": "CommonLibs"}, "request_formatter.client-optional.js": {"classlist": [], "name": "request_formatter.client-optional.js", "module": "CommonLibs"}, "mu.client.js": {"classlist": ["MuAdapterClient"], "name": "mu.client.js", "module": "ActionContextAddon"}, "view-renderer.common.js": {"classlist": [], "name": "view-renderer.common.js", "module": "CommonLibs"}, "mojito-test.common.js": {"classlist": [], "name": "mojito-test.common.js", "module": "MojitoClient"}, "io_facade.client-optional.js": {"classlist": [], "name": "io_facade.client-optional.js", "module": "CommonLibs"}, "transport_utils.client-optional.js": {"classlist": [], "name": "transport_utils.client-optional.js", "module": "CommonLibs"}, "output-handler.server.js": {"classlist": ["OutputHandler"], "name": "output-handler.server.js", "module": "MojitoServer"}, "mojit-proxy.client.js": {"classlist": ["MojitProxy"], "name": "mojit-proxy.client.js", "module": "ActionContext"}, "store-provider.server.js": {"classlist": [], "name": "store-provider.server.js", "module": "CommonLibs"}, "store.client.js": {"classlist": [], "name": "store.client.js", "module": "CommonLibs"}, "assets.common.js": {"classlist": ["Assets.common"], "name": "assets.common.js", "module": "ActionContextAddon"}, "rest.common.js": {"classlist": ["Y.mojito.lib.REST"], "name": "rest.common.js", "module": "MojitoClient"}, "dispatch.common.js": {"classlist": ["MojitoDispatcher"], "name": "dispatch.common.js", "module": "ActionContext"}, "cookie.server.js": {"classlist": ["Cookie.server"], "name": "cookie.server.js", "module": "ActionContextAddon"}, "meta.common.js": {"classlist": ["Meta.common"], "name": "meta.common.js", "module": "ActionContextAddon"}, "params.common.js": {"classlist": ["Params.common"], "name": "params.common.js", "module": "ActionContextAddon"}, "performance_monitor.client-optional.js": {"classlist": [], "name": "performance_monitor.client-optional.js", "module": "CommonLibs"}, "tunnel.client-optional.js": {"classlist": [], "name": "tunnel.client-optional.js", "module": "CommonLibs"}, "output-adapter.common.js": {"classlist": ["OutputAdapter.common"], "name": "output-adapter.common.js", "module": "ActionContextAddon"}, "request_handler.client-optional.js": {"classlist": [], "name": "request_handler.client-optional.js", "module": "CommonLibs"}, "util.common.js": {"classlist": [], "name": "util.common.js", "module": "CommonLibs"}, "response_formatter.client-optional.js": {"classlist": [], "name": "response_formatter.client-optional.js", "module": "CommonLibs"}, "transport.client-optional.js": {"classlist": [], "name": "transport.client-optional.js", "module": "CommonLibs"}, "controller.server.js": {"classlist": [], "name": "controller.server.js", "module": "CommonLibs"}, "requestor.client-optional.js": {"classlist": [], "name": "requestor.client-optional.js", "module": "CommonLibs"}, "logger.common.js": {"classlist": [], "name": "logger.common.js", "module": "ActionContext"}, "controller-context.common.js": {"classlist": [], "name": "controller-context.common.js", "module": "ActionContext"}, "partial.common.js": {"classlist": ["Partial.common"], "name": "partial.common.js", "module": "ActionContextAddon"}, "cookie.client.js": {"classlist": ["Cookie.client"], "name": "cookie.client.js", "module": "ActionContextAddon"}, "resource-store-adapter.common.js": {"classlist": ["Y.mojito.MojitoDispatcher"], "name": "resource-store-adapter.common.js", "module": "MojitoClient"}, "perf.client.js": {"classlist": [], "name": "perf.client.js", "module": "MojitoClient"}, "server-log.js": {"classlist": [], "name": "server-log.js", "module": "MojitoServer"}, "dali_bean.client-optional.js": {"classlist": [], "name": "dali_bean.client-optional.js", "module": "CommonLibs"}, "route-maker.common.js": {"classlist": [], "name": "route-maker.common.js", "module": "CommonLibs"}, "i13n.common.js": {"classlist": ["I13n.server"], "name": "i13n.common.js", "module": "ActionContextAddon"}, "composite.common.js": {"classlist": ["Composite.common"], "name": "composite.common.js", "module": "ActionContextAddon"}, "analytics.common.js": {"classlist": ["Analytics.common"], "name": "analytics.common.js", "module": "MojitoServer"}, "controller.common.js": {"classlist": [], "name": "controller.common.js", "module": "CommonLibs"}, "http.server.js": {"classlist": ["Http.server"], "name": "http.server.js", "module": "ActionContextAddon"}, "mu.server.js": {"classlist": ["MuAdapterServer"], "name": "mu.server.js", "module": "ActionContextAddon"}, "perf.server.js": {"classlist": [], "name": "perf.server.js", "module": "MojitoClient"}, "url.common.js": {"classlist": ["Url.common"], "name": "url.common.js", "module": "ActionContextAddon"}, "registry.client-optional.js": {"classlist": [], "name": "registry.client-optional.js", "module": "CommonLibs"}, "mojito-client.client.js": {"classlist": ["Y.mojito.Client"], "name": "mojito-client.client.js", "module": "MojitoClient"}, "store.server.js": {"classlist": ["ResourceStore.server"], "name": "store.server.js", "module": "MojitoServer"}, "index.js": {"classlist": [], "name": "index.js", "module": "CommonLibs"}}, "modules": {"MojitoServer": {"description": "The Resource Store manages information about the \"resources\" in a Mojito\napplication. These resources are things that have representation on the\nfilesystem.\nEach resource can have many different versions. This is not talking about\nrevisions, which is how the resource changes over time. It is instead\ntalking about how there can be a version of the resource just for iphones,\none just for android, a fallback, etc.\nThere are various types of resources:\n
    \nconfig      -- a piece of configuration, sometimes for another resource\ncontroller  -- the controller for a mojit\nmodel       -- a model for a mojit\nview        -- a view for a mojit\nbinder      -- a binder for a mojit\naction      -- an action to augment the controller\nasset       -- an asset (css, js, image, etc)\naddon       -- an addon to the mojito system\nspec        -- the configuration for a mojit instance\nyui-lang    -- a YUI3 language bundle\nyui-module  -- a YUI3 module (that isn't one of the above)\n
    \nThe metadata kept about each resource is \"normalized\" to the follow keys:\n(not all resources will have all keys)\n(some types will have additional keys)\n(not all combinations of type:source are valid)\n
    \n- id\ncontext-insensitive ID of the resource\nsaid another way, all versions of a resource have the same ID\n- type\nsee above\n- source\n`fw`, `app` or `mojit`\nwhere the resource is defined\n- fsPath\nthe path on the filesystem\n- staticHandlerURL\nthe URL that will cause the asset handler to serve the resource\nfor resources that can be deployed by reference to the client\n- name\nspecific to type\n- configType\nfor type=config\nthe type of the configuration\n- viewEngine\nfor type=view\n`mu`, `dust`, etc\n- viewOutputFormat\nfor type=view\noutput format that the view will generate\n`xml`, `html`, etc\n- assetType\nfor type=asset\n`css`, `js`, `png`, `swf`, etc\n- addonType\nfor type=addon\nthe mojito subsystem to which the addon should be added\n- yuiModuleName\nfor any resource delivered as a YUI3 module\nthe YUI3 module name\n- yuiModuleVersion\nfor any resource delivered as a YUI3 module\nthe YUI3 module version\n- yuiModuleMeta\nfor any resource delivered as a YUI3 module\nthe YUI3 module metadata\n(requires, langs, etc)\n- yuiSortedPaths\nfor any resource delivered as a YUI3 module\na list of YUI modules required by the module,\nwith transitive dependencies resolved\nformat:  { yui-module-name: URL-to-load-yui-module }\n
    ", "submodules": [], "classlist": ["MojitoServer", "OutputHandler", "ResourceStore.server"], "filelist": ["glob.js", "index.js", "output-handler.server.js", "server-log.js", "store.server.js", "analytics.common.js"], "subdata": {}, "name": "MojitoServer"}, "ActionContext": {"description": "The Action Context is a key part of the Mojito framework. The ac,\nfor short, gives you access to the frameworks features from within a\ncontroller function. The ac is an abstraction that allows you to execute\nmojit actions within either a server or client context.", "submodules": [], "classlist": ["ActionContext", "MojitoDispatcher"], "filelist": ["controller-context.common.js", "dispatch.common.js", "loader.common.js", "logger.common.js", "mojit-proxy.client.js"], "subdata": {}, "name": "ActionContext"}, "CommonLibs": {"description": "Common Library", "submodules": [], "classlist": ["Y.mojito.lib.REST"], "filelist": ["route-maker.common.js", "store.client.js", "tunnel.client-optional.js", "util.common.js", "view-renderer.common.js", "io_facade.client-optional.js", "request_formatter.client-optional.js", "request_handler.client-optional.js", "requestor.client-optional.js", "response_formatter.client-optional.js", "response_processor.client-optional.js", "transport.client-optional.js", "transport_utils.client-optional.js", "dali_bean.client-optional.js", "performance_monitor.client-optional.js", "registry.client-optional.js", "controller.server.js", "store-provider.server.js", "controller.server.js", "controller.common.js", "index.js"], "subdata": {}, "name": "CommonLibs"}, "ActionContextAddon": {"description": "The Action Context uses a mechanism called\nAddons to provide functionality that lives both on\nthe server and/or client. Each Addon provides additional functions through a\nnamespace that is attached directly to the ac argument available in every\ncontroller function.", "submodules": [], "classlist": ["Analytics.common", "Assets.common", "Carrier.common", "Composite.common", "Config.common", "Cookie.client", "Cookie.server", "Deploy.server", "Device.common", "Http.server", "I13n.server", "Intl.common", "Meta.common", "OutputAdapter.common", "Params.common", "Partial.common", "Url.common", "MuAdapterClient", "MuAdapterServer"], "filelist": ["assets.common.js", "carrier.server.js", "composite.common.js", "config.common.js", "cookie.client.js", "cookie.server.js", "deploy.server.js", "device.server.js", "http.server.js", "i13n.common.js", "intl.common.js", "meta.common.js", "output-adapter.common.js", "params.common.js", "partial.common.js", "url.common.js", "mu.client.js", "mu.server.js", "action-context.common.js"], "subdata": {}, "name": "ActionContextAddon"}, "MojitoClient": {"description": "The starting point for mojito to run in the browser. You can access one\ninstance of the Mojito Client running within the browser environment\nthrough window.YMojito.client.", "submodules": [], "classlist": ["MojitProxy", "Y.mojito.Client", "Y.mojito.MojitoDispatcher"], "filelist": ["mojito-client.client.js", "mojito-test.common.js", "mojito.common.js", "output-handler.client.js", "perf.client.js", "perf.server.js", "resource-store-adapter.common.js", "rest.common.js"], "subdata": {}, "name": "MojitoClient"}}, "classmap": {"Partial.common": {"name": "Partial.common", "namespace": "", "module": "ActionContextAddon", "methods": {"invoke": {"params": [{"type": "string", "name": "action", "description": " name of the action to invoke."}, {"type": "object", "name": "options", "description": " see above."}, {"type": "function", "name": "cb", "description": " callback function to be called on completion."}], "description": "This method calls the current mojit's controller with the \"action\"\ngiven and returns its output via the callback.\nThe options parameter is optional and may contain:\n
    \n
    params
    <object> must be broken out explicitly:\n
    \n
    route
    <object> Map of key/value pairs.
    \n
    url
    <object> Map of key/value pairs.
    \n
    body
    <object> Map of key/value pairs.
    \n
    file
    <object> Map of key/value pairs.
    \n
    \n
    ", "guessedname": "invoke", "guessedtype": "function"}, "render": {"params": [{"type": "object", "name": "data", "description": " The object to be rendered."}, {"type": "string", "name": "view", "description": " The view name to be used for rendering."}, {"type": "function", "name": "cb", "description": " callback signature is function(error, result)."}], "description": "This method renders the \"data\" provided into the \"view\" specified.\nThe \"view\" must be the name of one of the files in the current\nMojits \"views\" folder. Returns via the callback.", "guessedname": "render", "guessedtype": "function"}}, "file": "partial.common.js", "shortname": "Partial.common", "description": "Access point: ac.partial.*\nProvides methods for working with \"actions\" and \"views\" on the current\nMojits."}, "Meta.common": {"name": "Meta.common", "namespace": "", "module": "ActionContextAddon", "methods": {"retrieve": {"params": [{"type": "function", "name": "cb", "description": " callback will be called with the stored merged\nobject."}, {"type": "object", "name": "[optional]", "description": " scope scope of the callback."}], "description": "To retrieve stashed data that has been stored by child mojits, call\nthis function and provide a function, which will be called once the\nchildren have been dispatched and all their meta data has been\nmerged.", "guessedname": "retrieve", "guessedtype": "function"}, "store": {"params": [{"type": "string", "name": "key", "description": " The key used as the index value."}, {"type": "object", "name": "val", "description": " The value to store."}], "description": "Stores a keyed value within the meta object of the current mojit\nexecution. You can call this as many times as you like, but\nif you use the same key, you'll override previous data. Call this\nwithin child mojits when you have some data you want to make\navailable for some reason to any parents up your hierarchy.", "guessedname": "store", "guessedtype": "function"}}, "file": "meta.common.js", "shortname": "Meta.common", "description": "Access point: ac.meta.*\nAllows the usage of the \"meta\" object as a storage device, which can pass\ndata from child mojits up towards parents."}, "OutputHandler": {"name": "OutputHandler", "constructors": [{"params": [{"type": "Object", "name": "req", "description": " The Request object."}, {"type": "Object", "name": "res", "description": " The Response object."}, {"type": "Function", "name": "next", "description": " The next function, which should be invokable."}], "description": "This is an object used as the single pathway for data to leave a mojit\naction execution. It is used as a component of the ActionContext object,\nwhich uses it to call done and flush in order to complete.\nThere are two versions of this object, one for the client, and one for the\nserver. This is the server version, which is more complex than the client\nversion."}], "namespace": "", "module": "MojitoServer", "guessedname": "OutputHandler", "file": "output-handler.server.js", "guessedtype": "function", "shortname": "OutputHandler", "properties": {"exports": {"guessedname": "exports", "guessedtype": "property"}}, "description": "This is an object used as the single pathway for data to leave a mojit\naction execution. It is used as a component of the ActionContext object,\nwhich uses it to call done and flush in order to complete.\nThere are two versions of this object, one for the client, and one for the\nserver. This is the server version, which is more complex than the client\nversion."}, "I13n.server": {"name": "I13n.server", "namespace": "", "module": "ActionContextAddon", "methods": {"trackLink": {"return": {"type": "string", "description": "url with the hash appended to it."}, "params": [{"type": "string", "name": "url", "description": " The link to be instrumented."}, {"type": "object", "name": "link_params", "description": " The link parameters."}, {"type": "object", "name": "local_groups", "description": " - Optional."}, {"type": "object", "name": "ult_args", "description": " - Optional."}], "description": "Tracks the link view and generates the URL with the hash token\nappended to it.", "guessedname": "trackLink", "guessedtype": "function"}, "trackPageParams": {"params": [{"type": "string", "name": "key", "description": " The page parameter name."}, {"type": "string", "name": "value", "description": " The page parameter value."}], "description": "Tracks a pair of page parameters as (key, value) for this request.", "guessedname": "trackPageParams", "guessedtype": "function"}, "trackForm": {"return": {"type": "string", "description": "form action url with the hash appended to it."}, "params": [{"type": "boolean", "name": "is_post_method", "description": " True, if the method is POST."}, {"type": "string", "name": "action_url", "description": " The form action link to be instrumented."}, {"type": "object", "name": "link_params", "description": " Tracking parameters."}, {"type": "object", "name": "ult_args", "description": " Optional."}], "description": ", , [, ult_args [, return_code]]", "guessedname": "trackForm", "guessedtype": "function"}, "make": {"params": [{"type": "string", "name": "base", "description": " Reference to a mojit defined at the root\nlevel of the Mojito application configuration."}, {"type": "string", "name": "action", "description": " The action to associate with the base."}, {"type": "object", "name": "routeParams", "description": " used to lookup the route in the routing\ntable."}, {"type": "string", "name": "verb", "description": " GET, POST, PUT, DELETE (case insensitive)."}, {"type": "object", "name": "urlParams", "description": " added to the looked up route as query\nparams."}, {"type": "object", "name": "i13nParams", "description": " parameters to be used for link tracking."}], "description": "Provides facility to create an URL to other\nmojits with a link tracking instrumentation.", "guessedname": "make", "guessedtype": "function"}, "getSpaceid": {"return": {"type": "object", "description": "the spaceid previously set through stampPageView()\nor configuration."}, "description": "Return spaceid used for this request.", "guessedname": "getSpaceid", "guessedtype": "function"}, "trackUserLink": {"return": {"type": "string", "description": "url with the hash appended to it."}, "params": [{"type": "string", "name": "url", "description": " The link to be instrumented."}, {"type": "object", "name": "link_params", "description": " The link parameters."}, {"type": "object", "name": "local_groups", "description": " Optional."}, {"type": "object", "name": "ult_args", "description": " Optional."}], "description": "Tracks the link view for the links taken from the user generated\ncontent and hence need to be signed by B-cookie to prevent the\nsecurity problems.", "guessedname": "trackUserLink", "guessedtype": "function"}, "stampPageView": {"params": [{"type": "number", "name": "spaceid", "description": " The spaceid to be used."}], "description": "Stamps the page view event.", "guessedname": "stampPageView", "guessedtype": "function"}, "trackClickOnly": {"return": {"type": "string", "description": "url with the hash appended to it."}, "params": [{"type": "string", "name": "url", "description": " The link to be instrumented."}, {"type": "object", "name": "link_params", "description": " The link parameters."}, {"type": "object", "name": "ult_args", "description": " Optional."}], "description": "Instrument links for tracking of the link clicks by gemerating the\nURL with the hash token appended to it.", "guessedname": "trackClickOnly", "guessedtype": "function"}}, "file": "i13n.common.js", "shortname": "I13n.server", "description": "Access point: ac.i13n.*\nInstrumentation addon for link tracking and page views."}, "MojitoServer": {"name": "MojitoServer", "constructors": [{"description": "The Mojito Server bootstrap"}], "namespace": "", "module": "MojitoServer", "guessedname": "MOJITO_MIDDLEWARE", "methods": {"createServer": {"return": {"type": "Object", "description": "Express application."}, "params": [{"type": "Object", "name": "options", "description": " Options for starting the app."}], "description": "Creates an Express application with the Mojito framework already added.", "guessedname": "createServer", "guessedtype": "function"}, "addMojitoToExpressApp": {"params": [{"type": "Object", "name": "app", "description": " Express application."}, {"type": "Object", "name": "options", "description": " The directory to start the application in."}], "description": "Adds the Mojito framework to the Express application.\nYou only need to call one of addMojitoToExpressApp() or createServer().\nIf you want to create your own Express app do that then use\naddMojitoToExpressApp(). Otherwise Mojito can create an app for you\nif you use createServer().", "guessedname": "addMojitoToExpressApp", "guessedtype": "function"}, "include": {"params": [{"type": "string", "name": "path", "description": " The path used to locate resources."}], "description": "Surfaces the CLI.", "guessedname": "include", "guessedtype": "function"}}, "file": "index.js", "guessedtype": "property", "shortname": "MojitoServer", "properties": {"_mojito": {"guessedname": "_mojito", "guessedtype": "property"}, "exports": {"guessedname": "exports", "guessedtype": "property"}, "constructor": {"guessedname": "constructor", "guessedtype": "property"}}, "description": "The Mojito Server bootstrap"}, "Url.common": {"name": "Url.common", "namespace": "", "module": "ActionContextAddon", "methods": {"make": {"params": [{"type": "string", "name": "base", "description": " Base mojit defined at the root level of the\nMojito application configuration."}, {"type": "string", "name": "action", "description": " Action reference, concatenated to the base\nusing a period (.) separator."}, {"type": "object", "name": "routeParams", "description": " used to lookup the route in the routing\ntable."}, {"type": "string", "name": "varb", "description": " GET, POST, PUT, DELETE (case insensitive)."}, {"type": "object", "name": "urlParams", "description": " added to the looked up route as query\nparams."}], "description": "Generates a URL from the given parameters", "guessedname": "make", "guessedtype": "function"}, "find": {"params": [{"type": "string", "name": "url", "description": " the URL to find a route for."}, {"type": "string", "name": "verb", "description": " the HTTP method."}], "description": "Finds the first matching route from the given URL", "guessedname": "find", "guessedtype": "function"}}, "file": "url.common.js", "shortname": "Url.common", "description": "Access point: ac.url.*\nGenerates URL's based on the applictions routing configuration"}, "Y.mojito.MojitoDispatcher": {"name": "Y.mojito.MojitoDispatcher", "constructors": [{"params": [{"type": "ServerStore", "name": "resourceStore", "description": " the store to use."}], "description": "This object is responsible for running mojits."}], "namespace": "Y.mojito", "module": "MojitoClient", "private": "", "file": "resource-store-adapter.common.js", "shortname": "MojitoDispatcher", "description": "This object is responsible for running mojits."}, "ActionContext": {"name": "ActionContext", "namespace": "", "module": "ActionContext", "file": "action-context.common.js", "shortname": "ActionContext", "description": "The main point of entry for all mojits into Mojito. The Action Context is\npassed to every mojit action during execution, either on the client or\nserver. This object is the API into Mojito, can can have many plugins\nattached the provide extra functionality."}, "Intl.common": {"name": "Intl.common", "namespace": "", "module": "ActionContextAddon", "methods": {"lang": {"return": {"type": "string", "description": "translated string for label."}, "params": [{"type": "string", "name": "label", "description": " The initial label to be translated."}, {"type": "string|Array|Object", "name": "args", "description": " optional parameters for the string"}], "description": "Returns translated string.", "guessedname": "lang", "guessedtype": "function"}, "formatDate": {"return": {"type": "string", "description": "formatted data for language."}, "params": [{"type": "Date", "name": "date", "description": " The initial date to be formatted."}], "description": "Returns local-specified date.", "guessedname": "formatDate", "guessedtype": "function"}}, "file": "intl.common.js", "shortname": "Intl.common", "description": "Access point: ac.intl.*\nInternationalization addon"}, "ResourceStore.server": {"name": "ResourceStore.server", "constructors": [{"params": [{"type": "string", "name": "root", "description": " directory where application is found"}, {"type": "object", "name": "libs", "description": " dependent libraries -- this param is mainly used\nduring unit testing"}], "description": "The Resource Store manages information about the \"resources\" in a Mojito\napplication. These resources are things that have representation on the\nfilesystem.\nEach resource can have many different versions. This is not talking about\nrevisions, which is how the resource changes over time. It is instead\ntalking about how there can be a version of the resource just for iphones,\none just for android, a fallback, etc.\nThere are various types of resources:\n
    \nconfig      -- a piece of configuration, sometimes for another resource\ncontroller  -- the controller for a mojit\nmodel       -- a model for a mojit\nview        -- a view for a mojit\nbinder      -- a binder for a mojit\naction      -- an action to augment the controller\nasset       -- an asset (css, js, image, etc)\naddon       -- an addon to the mojito system\nspec        -- the configuration for a mojit instance\nyui-lang    -- a YUI3 language bundle\nyui-module  -- a YUI3 module (that isn't one of the above)\n
    \nThe metadata kept about each resource is \"normalized\" to the follow keys:\n(not all resources will have all keys)\n(some types will have additional keys)\n(not all combinations of type:source are valid)\n
    \n- id\ncontext-insensitive ID of the resource\nsaid another way, all versions of a resource have the same ID\n- type\nsee above\n- source\n`fw`, `app` or `mojit`\nwhere the resource is defined\n- fsPath\nthe path on the filesystem\n- staticHandlerURL\nthe URL that will cause the asset handler to serve the resource\nfor resources that can be deployed by reference to the client\n- name\nspecific to type\n- configType\nfor type=config\nthe type of the configuration\n- viewEngine\nfor type=view\n`mu`, `dust`, etc\n- viewOutputFormat\nfor type=view\noutput format that the view will generate\n`xml`, `html`, etc\n- assetType\nfor type=asset\n`css`, `js`, `png`, `swf`, etc\n- addonType\nfor type=addon\nthe mojito subsystem to which the addon should be added\n- yuiModuleName\nfor any resource delivered as a YUI3 module\nthe YUI3 module name\n- yuiModuleVersion\nfor any resource delivered as a YUI3 module\nthe YUI3 module version\n- yuiModuleMeta\nfor any resource delivered as a YUI3 module\nthe YUI3 module metadata\n(requires, langs, etc)\n- yuiSortedPaths\nfor any resource delivered as a YUI3 module\na list of YUI modules required by the module,\nwith transitive dependencies resolved\nformat:  { yui-module-name: URL-to-load-yui-module }\n
    "}], "namespace": "", "module": "MojitoServer", "methods": {"preload": {"return": {"type": "nothing", "description": ""}, "params": [{"type": "object", "name": "appContext", "description": " the base context for reading configuration."}, {"type": "object", "name": "appConfig", "description": " overrides for the app config."}], "description": "Preloads everything in the app, and as well pertinent parts of\nthe framework.", "guessedname": "preload", "guessedtype": "function"}, "getSpec": {"return": {"type": "nothing", "description": "results returned via the callback parameter"}, "params": [{"type": "string", "name": "env", "description": " either \"client\" or \"server\""}, {"type": "string", "name": "id", "description": " the ID of the spec to return"}, {"type": "object", "name": "context", "description": " the runtime context for the spec"}, {"type": "function(err,spec)", "name": "callback", "description": " callback used to return the results (or error)"}], "description": "Returns, via callback, the fully expanded mojit instance specification.", "guessedname": "getSpec", "guessedtype": "function"}, "getAppConfig": {"return": {"type": "object", "description": "config object"}, "params": [{"type": "object", "name": "ctx", "description": " the runtime context under which to load the config"}, {"type": "string", "name": "name", "description": " type of config to read:\n- definition: reads ./application.json\n- package: reads ./package.json\n- routes: reads ./routes.json (or whatever was configured in\nappConfig('definition').routesFiles)"}], "description": "gets application configuration", "guessedname": "getAppConfig", "guessedtype": "function"}, "getInlineCssMojits": {"return": {"type": "array", "description": "object describing where to put the inline CSS file and what it should contain"}, "params": [{"type": "string", "name": "env", "description": " \"client\" or \"server\""}, {"type": "object", "name": "ctxFilter", "description": " (optional) runtime context to restrict results to"}], "description": "Returns details on how to make inline CSS for mojits.\nThis example comes from (a modified) GSG5.\n[ {\ncontext: { device: 'iphone' },\nmojitName: 'FlickrDetail',\nyuiModuleName: 'inlinecss/FlickrDetail',\ndest: '/blah/mojits/FlickrDetail/autoload/compiled' +\n'/css.iphone.client.js',\nsrcs: {\n'/static/FlickrDetail/assets/index.css':\n' /blah/mojits/FlickrDetail/assets/index.iphone.css',\n'/static/FlickrDetail/assets/message.css':\n' /blah/mojits/FlickrDetail/assets/message.css'\n}\n]", "guessedname": "getInlineCssMojits", "guessedtype": "function"}, "getRoutes": {"return": {"type": "object", "description": "routes"}, "params": [{"type": "object", "name": "ctx", "description": " runtime context under which to load the routes"}], "description": "Returns the routes configured in the application.", "guessedname": "getRoutes", "guessedtype": "function"}, "expandInstanceForEnv": {"return": {"type": "nothing", "description": "results returned via the callback parameter"}, "params": [{"type": "string", "name": "env", "description": " \"client\" or \"server\""}, {"type": "object", "name": "instance", "description": " partial instance to expand"}, {"type": "object", "name": "ctx", "description": " the runtime context for the instance"}, {"type": "function(err,instance)", "name": "cb", "description": " callback used to return the results (or error)"}], "description": "This method takes a partial instance and expands it to all details needed\nto run the mojit.\nOnly `base` or `type` fields are required. You should only specify one.\n
    \ninstance: {\nbase: string\n// specifies a \"base\" instance which this instance will extend\n// the value refers to a key of `specs` in `application.json`\ntype: string\n// specifies the mojit type\naction: \"\",\n// specifies a default action if the instance isn't dispatched\n// with a specific one.\nconfig: object\n// the config for the mojit\n// this will be augmented (appropriately) with the mojit type\n// defaults found in the type's `defaults.json`\nappConfig: object\n// the application config (appropriate for the context)\nassetRoot: \"\",\n// path to directory containing assets\n// the path will be a URL if `env` is `client` otherwise it's a\n// filesystem path\ndefinition: object\n// the body of the `defintion.json` for the mojit type\ndefaults: object\n// the body of the `defaults.json` for the mojit type\nyui: {\n// details for generating a YUI sandbox for this instance\nconfig: {\n// configuration details for the YUI.GlobalConfig.groups (or\n// an equivalent).\n// The module paths are given as `fullpath` and contain\n// either a URL if `env' is `client` or a filesystem path if\n// `env` is `server`\n},\nrequires: []\n// list of YUI modules that this instance requires\n}\nactions: array\n// list of paths to the YUI modules containing actions\ncontroller: string\n// path to controller\n// the path will be a URL if `env` is `client` otherwise it's a\n// filesystem path\nlang:\n// path to YUI module of the language bundle\n// the path will be a URL if `env` is `client` otherwise it's a\n// filesystem path\nmodels: object\n// list of models used by the mojit type\n// the key is the model name, and the value is the path to the\n// model file\n// the path will be a URL if `env` is `client` otherwise it's a\n// filesystem path\nviews: {\n// list of views in the mojit type\n// the key is the view name, and the value is details about the\n// view\nview-name: {\n\"content-path\": \"\",\n// the path to use to load the body of the view\n// the path will be a URL if `env` is `client` otherwise\n// it's a filesystem path\n\"engine\": \"\",\n// which engine is used to render the view\n\"binder-path\": \"\",\n// the path to the binder\n// the path will be a URL if `env` is `client` otherwise\n// it's a filesystem path\n\"binder-module\": \"\"\n// the YUI module name of the binder\n}\n}\n}\n
    ", "guessedname": "expandInstanceForEnv", "guessedtype": "function"}, "getAllMojits": {"return": {"type": "object", "description": "keys are mojit type names, values are details about each mojit"}, "params": [{"type": "string", "name": "env", "description": " \"client\" or \"server\""}, {"type": "object", "name": "ctx", "description": " runtime context"}], "description": "Returns details about all mojits in the application.", "guessedname": "getAllMojits", "guessedtype": "function"}, "getType": {"return": {"type": "nothing", "description": "results returned via the callback parameter"}, "params": [{"type": "string", "name": "env", "description": " either \"client\" or \"server\""}, {"type": "string", "name": "type", "description": " the mojit type"}, {"type": "object", "name": "context", "description": " the runtime context for the spec"}, {"type": "function(err,spec)", "name": "callback", "description": " callback used to return the results (or error)"}], "description": "Returns, via callback, the details of the mojit type.", "guessedname": "getType", "guessedtype": "function"}, "getMojitTypeDetails": {"return": {"type": "object", "description": "returns the \"dest\" parameter, which has had details added to it"}, "params": [{"type": "string", "name": "env", "description": " \"client\" or \"server\""}, {"type": "object", "name": "ctx", "description": " runtime context"}, {"type": "string", "name": "mojitType", "description": " mojit type"}, {"type": "object", "name": "dest", "description": " object in which to place the results"}], "description": "Returns details about a mojit type.", "guessedname": "getMojitTypeDetails", "guessedtype": "function"}, "expandInstance": {"return": {"type": "nothing", "description": "results returned via the callback parameter"}, "params": [{"type": "map", "name": "instance", "description": " Partial instance to expand."}, {"type": "object", "name": "ctx", "description": " The request context."}, {"type": "function(err,instance)", "name": "cb", "description": " callback used to return the results (or error)"}], "description": "This just calls expandInstanceForEnv() with `env` set to `server`.", "guessedname": "expandInstance", "guessedtype": "function"}, "listAllMojits": {"return": {"type": "array", "description": "list of mojit types"}, "params": [{"type": "string", "name": "env", "description": " \"client\" or \"server\""}], "description": "Returns a list of all mojit types in the application.", "guessedname": "listAllMojits", "guessedtype": "function"}, "setLogger": {"return": {"type": "nothing", "description": ""}, "params": [{"type": "object", "name": "l", "description": " object containing a log(message,level,source) function"}], "description": "Sets the logger object.", "guessedname": "setLogger", "guessedtype": "function"}, "getRollupsApp": {"return": {"type": "object", "description": "object describing where to put the rollup and what it should contain"}, "params": [{"type": "string", "name": "env", "description": " \"client\" or \"server\""}, {"type": "object", "name": "ctx", "description": " runtime context"}], "description": "Returns details on how to make rollups for app-level resources.", "guessedname": "getRollupsApp", "guessedtype": "function"}, "getYuiConfigApp": {"return": {"type": "object", "description": "YUI configuration for the app-level modules"}, "params": [{"type": "string", "name": "env", "description": " \"client\" or \"server\""}, {"type": "object", "name": "ctx", "description": " runtime context for YUI configuration"}], "description": "Returns the YUI configuration object which tells YUI about the\nYUI modules in the application (which aren't part of a mojit).", "guessedname": "getYuiConfigApp", "guessedtype": "function"}, "getYuiConfigFw": {"return": {"type": "object", "description": "YUI configuration for Mojito framework"}, "params": [{"type": "string", "name": "env", "description": " \"client\" or \"server\""}, {"type": "object", "name": "ctx", "description": " runtime context for YUI configuration"}], "description": "Returns the YUI configuration object which tells YUI about the\nYUI modules in the Mojito framework.", "guessedname": "getYuiConfigFw", "guessedtype": "function"}, "getYuiConfigAllMojits": {"return": {"type": "object", "description": "YUI configuration for all mojits"}, "params": [{"type": "string", "name": "env", "description": " \"client\" or \"server\""}, {"type": "object", "name": "ctx", "description": " runtime context for YUI configuration"}], "description": "Returns the YUI configuration object which tells YUI about the\nYUI modules in all the mojits.", "guessedname": "getYuiConfigAllMojits", "guessedtype": "function"}, "getRollupsMojits": {"return": {"type": "object", "description": "object describing where to put the rollup and what it should contain"}, "params": [{"type": "string", "name": "env", "description": " \"client\" or \"server\""}, {"type": "object", "name": "ctx", "description": " runtime context"}], "description": "Returns details on how to make rollups for mojit-level resources.\nThis example comes from GSG5.\n{ FlickrDetail:\ndest: '/blah/blah/mojits/FlickrDetail/rollup.client.js'\nsrcs: [\n'/blah/blah/mojits/FlickrDetail/controller.common.js',\n'/blah/blah/mojits/FlickrDetail/binders/index.js',\n'/blah/blah/mojits/FlickrDetail/lang/FlickrDetail_de.js',\n'/blah/blah/mojits/FlickrDetail/lang/FlickrDetail_en-US.js'\n]\n}", "guessedname": "getRollupsMojits", "guessedtype": "function"}, "fileFromStaticHandlerURL": {"return": {"type": "string", "description": "path on filesystem of specified URL, or undefined"}, "params": [{"type": "string", "name": "url", "description": " static URL"}], "description": "Returns the filesystem location of the static URL.\nReturns undefined if given URL isn't part of the app.", "guessedname": "fileFromStaticHandlerURL", "guessedtype": "function"}}, "file": "store.server.js", "shortname": "ResourceStore.server", "description": "The Resource Store manages information about the \"resources\" in a Mojito\napplication. These resources are things that have representation on the\nfilesystem.\nEach resource can have many different versions. This is not talking about\nrevisions, which is how the resource changes over time. It is instead\ntalking about how there can be a version of the resource just for iphones,\none just for android, a fallback, etc.\nThere are various types of resources:\n
    \nconfig      -- a piece of configuration, sometimes for another resource\ncontroller  -- the controller for a mojit\nmodel       -- a model for a mojit\nview        -- a view for a mojit\nbinder      -- a binder for a mojit\naction      -- an action to augment the controller\nasset       -- an asset (css, js, image, etc)\naddon       -- an addon to the mojito system\nspec        -- the configuration for a mojit instance\nyui-lang    -- a YUI3 language bundle\nyui-module  -- a YUI3 module (that isn't one of the above)\n
    \nThe metadata kept about each resource is \"normalized\" to the follow keys:\n(not all resources will have all keys)\n(some types will have additional keys)\n(not all combinations of type:source are valid)\n
    \n- id\ncontext-insensitive ID of the resource\nsaid another way, all versions of a resource have the same ID\n- type\nsee above\n- source\n`fw`, `app` or `mojit`\nwhere the resource is defined\n- fsPath\nthe path on the filesystem\n- staticHandlerURL\nthe URL that will cause the asset handler to serve the resource\nfor resources that can be deployed by reference to the client\n- name\nspecific to type\n- configType\nfor type=config\nthe type of the configuration\n- viewEngine\nfor type=view\n`mu`, `dust`, etc\n- viewOutputFormat\nfor type=view\noutput format that the view will generate\n`xml`, `html`, etc\n- assetType\nfor type=asset\n`css`, `js`, `png`, `swf`, etc\n- addonType\nfor type=addon\nthe mojito subsystem to which the addon should be added\n- yuiModuleName\nfor any resource delivered as a YUI3 module\nthe YUI3 module name\n- yuiModuleVersion\nfor any resource delivered as a YUI3 module\nthe YUI3 module version\n- yuiModuleMeta\nfor any resource delivered as a YUI3 module\nthe YUI3 module metadata\n(requires, langs, etc)\n- yuiSortedPaths\nfor any resource delivered as a YUI3 module\na list of YUI modules required by the module,\nwith transitive dependencies resolved\nformat:  { yui-module-name: URL-to-load-yui-module }\n
    "}, "Deploy.server": {"name": "Deploy.server", "namespace": "", "module": "ActionContextAddon", "methods": {"setStore": {"guessedname": "setStore", "params": [{"type": "ResourceStore", "name": "rs", "description": " The resource store instance."}], "description": "Declaration of store requirement.", "private": "", "guessedtype": "function"}, "getScripts": {"return": {"type": "object", "description": "An object containing script descriptors."}, "description": "TODO: [Issue 66] This can be made faster with a single for\nloop and caching.\nNote: A single SCRIPT tag containing all the JS on the pages is\nslower than many SCRIPT tags (checked on iPad only).", "private": "", "params": [{"type": "bool", "name": "embed", "description": " Should returned scripts be embedded in script\ntags."}], "guessedname": "getScripts", "guessedtype": "function"}, "constructMojitoClientRuntime": {"params": [{"type": "AssetHandler", "name": "assetHandler", "description": " asset handler used to add scripts\nto the DOM under construction."}, {"type": "object", "name": "binderMap", "description": " information about the binders that will be\ndeployed to the client."}], "description": "Builds up the browser Mojito runtime.", "guessedname": "constructMojitoClientRuntime", "guessedtype": "function"}}, "file": "deploy.server.js", "shortname": "Deploy.server", "description": "Access point: ac.deploy.*\nProvides ability to create client runtime deployment HTML"}, "MojitProxy": {"name": "MojitProxy", "namespace": "", "module": "MojitoClient", "methods": {"render": {"params": [{"type": "object", "name": "data", "description": " The data to render."}, {"type": "string", "name": "view", "description": " The view name to use for rendering."}, {"type": "function(err,str)", "name": "cb", "description": " The callback function."}], "description": "This method renders the \"data\" provided into the \"View\" specified.\nThe \"view\" must be the name of one of the files in the current\nMojits \"views\" folder. Returns via the callback.", "guessedname": "render", "guessedtype": "function"}, "invoke": {"params": [{"type": "string", "name": "action", "description": " name of the action to invoke."}, {"type": "Object", "name": "options", "description": " see above."}, {"type": "function", "name": "cb", "description": " function to be called on completion."}], "description": "Used by the mojit binders to invoke actions on themselves within\nMojito.\nThe options parameter is optional and may contain:\n
    \n
    params
    <object> must be broken out explicitly:\n
    \n
    route
    <object> Map of key/value pairs.
    \n
    url
    <object> Map of key/value pairs.
    \n
    body
    <object> Map of key/value pairs.
    \n
    file
    <object> Map of key/value pairs.
    \n
    \n
    rpc
    <boolean> Means that we are immediately\nsending the request to the server to answer the invocation.
    \n
    ", "guessedname": "invoke", "guessedtype": "function"}, "destroyChild": {"params": [{"type": "string", "name": "id", "description": " Either the slot key of the child, or the DOM\nview id of the child."}, {"type": "boolean", "name": "retainNode", "description": " if true, the binder's node will remain in\nthe dom."}], "description": "Clears out a child's view, calling the appropriate life cycle\nfunctions, then destroy's its binder and dereferences it. Will also\ndereference the child from this mojit's children.", "guessedname": "destroyChild", "guessedtype": "function"}, "unlisten": {"params": [{"type": "String", "name": "[optional]", "description": " name event name."}], "description": "The opposite of the \"listen\" function. Deletes all callback functions\nfrom the listener queue associated with this binder and event type.\nIf event name is not specified, all callbacks associated with this\nbinder are deleted.", "guessedname": "unlisten", "guessedtype": "function"}, "destroySelf": {"params": [{"type": "boolean", "name": "retainNode", "description": " if true, the binder's node will remain in\nthe dom."}], "description": "Allows a binder to destroy itself and be removed from Mojito client\nruntime entirely.", "guessedname": "destroySelf", "guessedtype": "function"}, "broadcast": {"params": [{"type": "String", "name": "name", "description": " event name."}, {"type": "Object", "name": "payload", "description": " the payload for the event."}, {"type": "object} options currently only used to specify target for\nbroadcast. For example, to target only one child mojit for\nbroadcast, use:\n{target: {slot: 'slot name', viewId: 'DOM view id'}", "name": ".", "description": ""}], "description": "Used by mojit binders to broadcast a message between mojits.", "guessedname": "broadcast", "guessedtype": "function"}, "refreshView": {"params": [{"type": "object", "name": "opts", "description": " same as the options for invoke()."}, {"type": "function", "name": "cb", "description": " Called after replacement and onRefreshView have\nbeen called, sends data/meta."}], "description": "Refreshes the current DOM view for this binder without recreating the\nbinder instance. Will call the binder's onRefreshView() function when\ncomplete with the new Y.Node and HTMLElement objects.", "guessedname": "refreshView", "guessedtype": "function"}, "getChildren": {"return": {"type": "object", "description": "slot-->child information."}, "description": "Helper function to gather up details about a mojit's children from\nthe Mojito Client.", "guessedname": "getChildren", "guessedtype": "function"}, "destroyChildren": {"params": [{"type": "boolean", "name": "retainNode", "description": " if true, the binder's node will remain in\nthe dom."}], "description": "Destroys all children. (Calls destroyChild() for each child.)", "guessedname": "destroyChildren", "guessedtype": "function"}, "getFromUrl": {"return": {"type": "string|object", "description": "param value, or all params if no key\nspecified."}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required."}], "description": "Gets URL parameters", "guessedname": "getFromUrl", "guessedtype": "function"}, "listen": {"params": [{"type": "String", "name": "name", "description": " event name."}, {"type": "Function", "name": "callback", "description": " called when an event is broadcast with\nthe event data."}], "description": "Allows mojit binders to register to listen to other mojit events", "guessedname": "listen", "guessedtype": "function"}}, "file": "mojit-proxy.client.js", "shortname": "MojitProxy", "properties": {"_mojito": {"type": "{Object}", "description": "The top-level Mojito namespace.", "guessedname": "_mojito", "guessedtype": "property"}, "config": {"type": "{object}", "description": "The mojit configuration for this binder", "guessedname": "config", "guessedtype": "property"}, "type": {"type": "{string}", "description": "The mojit type", "guessedname": "type", "guessedtype": "property"}, "context": {"type": "{object}", "description": "The context used to generate this page", "guessedname": "context", "guessedtype": "property"}}, "description": "The object that is given to each mojit binder to be used to interact with\nother mojits and the mojito framework."}, "Cookie.client": {"name": "Cookie.client", "namespace": "", "module": "ActionContextAddon", "file": "cookie.client.js", "shortname": "Cookie.client", "description": "Access point: ac.cookie.*\nThis client-side cookie add-on allows you to easily use cookies. This API\nmatches the YUI Cookie API exactly.\nhttp://developer.yahoo.com/yui/3/api/Cookie.html"}, "OutputAdapter.common": {"name": "OutputAdapter.common", "namespace": "", "module": "ActionContextAddon", "private": "", "file": "output-adapter.common.js", "shortname": "OutputAdapter.common", "description": "Access point: ac.*\nThe main API point for developers in a Controller. This addon provides\nthe core functions\nof the ActionContext: flush, done, and error."}, "Y.mojito.lib.REST": {"name": "Y.mojito.lib.REST", "namespace": "Y.mojito.lib", "module": "CommonLibs", "guessedname": "REST", "methods": {"getComputedRoutes": {"return": {"type": "object", "description": "computed routes."}, "description": "For optimization. Call this to get the computed routes that can be\npassed to the constructor to avoid recomputing the routes.", "guessedname": "getComputedRoutes", "guessedtype": "function"}, "registerBean": {"params": [{"type": "string", "name": "name", "description": " Required identifier of this bean."}, {"type": "Object", "name": "bean", "description": " Either a constructor Function or an instance\nobject of a bean."}], "description": "Called to register a bean or bean constructor with the bean registry.\nIf this method is called twice with the same bean, the last bean\nwins. Only one type of bean can be in the system at a time.", "guessedname": "registerBean", "guessedtype": "function"}, "mergeRecursive": {"params": [{"type": "object", "name": "dest", "description": " The destination object."}, {"type": "object", "name": "src", "description": " The source object."}, {"type": "boolean", "name": "typeMatch", "description": " Only replace if src and dest types are\nthe same type if true."}], "description": "Recursively merge properties of two objects", "guessedname": "mergeRecursive", "guessedtype": "function"}, "_wsRequestFormatter": {"guessedname": "_wsRequestFormatter", "return": {"type": "Object", "description": "the formatted request."}, "description": "Format web service requests using var foo = function() format\nso that reset is easier.", "private": "", "guessedtype": "function"}, "getBean": {"return": {"type": "Object", "description": "the bean instance, or undefined if it is not\nregistered."}, "description": "If the bean system has not been instatiated yet, this will\ninstantiate all beans! Then one bean instance is returned by name.", "guessedname": "getBean", "guessedtype": "function"}, "setStore": {"guessedname": "setStore", "params": [{"type": "ResourceStore", "name": "rs", "description": " The resource store."}], "description": "Declaration of store requirement.", "private": "", "guessedtype": "function"}, "metaMerge": {"guessedname": "metaMerge", "params": [{"type": "object", "name": "to", "description": " The target object."}, {"type": "object", "name": "from", "description": " The source object."}, {"type": "boolean", "name": "clobber", "description": " True to overwrite existing properties."}], "description": "Used to merge meta objects into each other. Special consideration for\ncertain headers values like 'content-type'.", "private": "", "guessedtype": "function"}, "_matchToInternal": {"guessedname": "_matchToInternal", "params": [{"type": "string", "name": "uri", "description": " The uri to find a route for."}, {"type": "string", "name": "verb.", "description": " The HTTP verb for the route."}], "description": "Returns a matching route for the given URI", "private": "", "guessedtype": "function"}, "find": {"params": [{"type": "string", "name": "url", "description": " the URL to find a route for."}, {"type": "string", "name": "verb", "description": " the HTTP method."}], "description": "Finds a route for a given method+URL", "guessedname": "find", "guessedtype": "function"}, "GET": {"params": [{"type": "String", "name": "url", "description": " RESTful URL to hit."}, {"type": "Object", "name": "params", "description": " parameters to add to the request."}, {"type": "Object", "name": "config", "description": " may contain 'headers' or 'timeout' values."}, {"type": "Function", "name": "callback", "description": " called with response or error."}], "description": "Makes a RESTful GET request to specified URL", "guessedname": "GET", "guessedtype": "function"}, "getName": {"return": {"type": "String", "description": "name of the registered bean, or undefined if it is\nnot a registered bean."}, "description": "Given an instance of a bean, returns the String name", "guessedname": "getName", "guessedtype": "function"}, "_doRequest": {"private": "", "guessedname": "_doRequest", "guessedtype": "function"}, "setRequestFormatter": {"params": [{"type": "String", "name": "requestType", "description": " The type of request that the\nformatter should handle."}, {"type": "Function", "name": "formatter", "description": " The function to call to format the\nrequest."}], "description": "Sets the request formatter function for a given request type.", "guessedname": "setRequestFormatter", "guessedtype": "function"}, "destroy": {"description": "Called by the bean registry whenever this bean is reinitialized", "guessedname": "destroy", "guessedtype": "function"}, "HEAD": {"params": [{"type": "String", "name": "url", "description": " RESTful URL to hit."}, {"type": "Object", "name": "params", "description": " parameters to add to the request."}, {"type": "Object", "name": "config", "description": " may contain 'headers' or 'timeout' values."}, {"type": "Function", "name": "callback", "description": " called with response or error."}], "description": "Makes a RESTful HEAD request to specified URL", "guessedname": "HEAD", "guessedtype": "function"}, "enable": {"description": "Enables sending of requests.", "guessedname": "enable", "guessedtype": "function"}, "disable": {"params": [{"type": "Boolean", "name": "queue", "description": " (Optional) When set to true, queues all\nrequests while disabled."}], "description": "Disables all Ajax requests for the application.", "guessedname": "disable", "guessedtype": "function"}, "POST": {"params": [{"type": "String", "name": "url", "description": " RESTful URL to hit."}, {"type": "Object", "name": "params", "description": " parameters to add to the request."}, {"type": "Object", "name": "config", "description": " may contain 'headers' or 'timeout' values."}, {"type": "Function", "name": "callback", "description": " called with response or error."}], "description": "Makes a RESTful POST request to specified URL", "guessedname": "POST", "guessedtype": "function"}, "execute": {"guessedname": "execute", "params": [{"type": "String", "name": "url", "description": " Url to access."}, {"type": "Object", "name": "data", "description": " The data to send."}, {"type": "String", "name": "method", "description": " GET or POST."}], "description": "Executes an io request.", "private": "", "guessedtype": "function"}, "getBeans": {"return": {"type": "Object", "description": "contains all beans, each bean is accessible by bean\nname."}, "description": "If the bean system has not been instatiated yet, this will\ninstantiate all beans!", "guessedname": "getBeans", "guessedtype": "function"}, "setResponseFormatter": {"params": [{"type": "Function", "name": "formatter", "description": " The function to call to format the\nresponse object."}], "description": "Sets the response formatter function for all responses.", "guessedname": "setResponseFormatter", "guessedtype": "function"}, "PUT": {"params": [{"type": "String", "name": "url", "description": " RESTful URL to hit."}, {"type": "Object", "name": "params", "description": " parameters to add to the request."}, {"type": "Object", "name": "config", "description": " may contain 'headers' or 'timeout' values."}, {"type": "Function", "name": "callback", "description": " called with response or error."}], "description": "Makes a RESTful PUT request to specified URL", "guessedname": "PUT", "guessedtype": "function"}, "_simulateResponse": {"guessedname": "_simulateResponse", "params": [{"type": "Number", "name": "id", "description": " the id of the transaction."}, {"type": "Object", "name": "details", "description": " the details of the response."}, {"type": "Boolean", "name": "badcookie", "description": " Optional. If true simulate cookies\nturned off."}], "description": "Simulate a server response", "private": "", "guessedtype": "function"}, "DELETE": {"params": [{"type": "String", "name": "url", "description": " RESTful URL to hit."}, {"type": "Object", "name": "params", "description": " parameters to add to the request."}, {"type": "Object", "name": "config", "description": " may contain 'headers' or 'timeout' values."}, {"type": "Function", "name": "callback", "description": " called with response or error."}], "description": "Makes a RESTful DELETE request to specified URL", "guessedname": "DELETE", "guessedtype": "function"}}, "file": "rest.common.js", "guessedtype": "property", "shortname": "REST", "description": "The Rest module for Mojito provides an easy way to make RESTful calls to\nURLs without messing about with Y.io."}, "Http.server": {"name": "Http.server", "namespace": "", "module": "ActionContextAddon", "methods": {"redirect": {"params": [{"type": "string", "name": "uri", "description": " the URI to redirect to."}, {"type": "Number", "name": "code", "description": " [optional] if not specifed, 301."}], "description": "This redirect is an external redirect. It causes an HTTP\nstatus code 301 by default.", "guessedname": "redirect", "guessedtype": "function"}, "getHeader": {"return": {"type": "object", "description": "header value."}, "params": [{"type": "string", "name": "name", "description": " header name."}], "description": "Returns one request header value", "guessedname": "getHeader", "guessedtype": "function"}, "addHeaders": {"params": [{"type": "object", "name": "hdrs", "description": " header values to add."}], "description": "Adds a object of headers all at once, adding to previous values", "guessedname": "addHeaders", "guessedtype": "function"}, "getRequest": {"return": {"type": "ServerRequest", "description": "The node.js http.ServerRequest instance."}, "description": "Returns the HTTP request.", "guessedname": "getRequest", "guessedtype": "function"}, "addHeader": {"params": [{"type": "String", "name": "key", "description": " header name."}, {"type": "String", "name": "val", "description": " header value."}], "description": "Adds a header to the response without overriding previous values", "guessedname": "addHeader", "guessedtype": "function"}, "getHeaders": {"return": {"type": "object", "description": "all headers."}, "description": "Returns all request headers", "guessedname": "getHeaders", "guessedtype": "function"}, "getResponse": {"return": {"type": "ServerResponse", "description": "The node.js http.ServerResponse instance."}, "description": "Returns the HTTP response object from the request.", "guessedname": "getResponse", "guessedtype": "function"}, "isXhr": {"return": {"type": "boolean", "description": "True if the receiver is associated with an XHR\nrequest."}, "description": "Helper to tell you if this is an XHR request. Checks specifically\nfor the 'x-requested-with' header.", "guessedname": "isXhr", "guessedtype": "function"}, "setHeaders": {"params": [{"type": "object", "name": "hdrs", "description": " header values to set."}], "description": "Sets a object full of headers all at once, overriding previous values", "guessedname": "setHeaders", "guessedtype": "function"}, "setHeader": {"params": [{"type": "string", "name": "key", "description": " header name."}, {"type": "string", "name": "val", "description": " header value."}], "description": "Sets a header by key, overriding previous values", "guessedname": "setHeader", "guessedtype": "function"}}, "file": "http.server.js", "shortname": "Http.server", "description": "Access point: ac.http.*\nThis is a server-only utility plugin that makes many server side\nresources available for mojit code that will never run on the client."}, "MuAdapterClient": {"name": "MuAdapterClient", "namespace": "", "module": "ActionContextAddon", "methods": {"render": {"params": [{"type": "object", "name": "data", "description": " The data to render."}, {"type": "string", "name": "mojitType", "description": " The name of the mojit type."}, {"type": "string", "name": "tmpl", "description": " The name of the template to render."}, {"type": "object", "name": "adapter", "description": " The output adapter to use."}, {"type": "object", "name": "meta", "description": " Optional metadata."}, {"type": "boolean", "name": "more", "description": " Whether there will be more content later."}], "description": "Renders the mustache template using the data provided.", "guessedname": "render", "guessedtype": "function"}}, "private": "", "file": "mu.client.js", "shortname": "MuAdapterClient", "description": "Class text."}, "Y.mojito.Client": {"name": "Y.mojito.Client", "constructors": [{"params": [{"type": "Object", "name": "config", "description": " The entire configuration object written by the\nserver to start up mojito."}], "description": "The starting point for mojito to run in the browser. You can access one\ninstance of the Mojito Client running within the browser environment\nthrough window.YMojito.client."}], "namespace": "Y.mojito", "module": "MojitoClient", "methods": {"subscribe": {"params": [{"type": "string", "name": "evt", "description": " name of event to subscribe to."}, {"type": "function(data)", "name": "cb", "description": " callback called when the event fires."}], "description": "Subscribe to a MojitoClient lifecycle event.", "guessedname": "subscribe", "guessedtype": "function"}, "executeAction": {"guessedname": "executeAction", "params": [{"type": "Object", "name": "command", "description": " must contain mojit id and action to execute."}, {"type": "String", "name": "viewId", "description": " the view id of the current mojit, which is\nexecuting the action."}, {"type": "Function", "name": "cb", "description": " callback to run when complete."}], "description": "Used for binders to execute their actions through the Mojito\nframework through their proxies.", "private": "", "guessedtype": "function"}, "pause": {"description": "Pause the Mojito Client and all mojits that are running. This will\nnotify all binders that they have been paused by calling their\nonPause() functions. It will prevent the immediate execution of\nseveral mojit proxy operations that might cause a long process to\nbegin (especially things that might go to the server).\nTo resume, simply call .resume(). This will immediately execute all\nactions that occurred while Mojito was paused.", "guessedname": "pause", "guessedtype": "function"}, "resume": {"description": "Resumes the Mojito client after it has been paused (see method\n\"pause\"). If there are any queued actions that were executed and\ncached during the pause, calling resume() will immediately execute\nthem. All binders are notified through their onResume() function that\nthey are been resumed.", "guessedname": "resume", "guessedtype": "function"}, "attachBinders": {"guessedname": "attachBinders", "params": [{"type": "Object", "name": "binderMap", "description": " viewId ==> binder data, contains all we\nneed from the mojit dispatch's meta object about all the binders\nthat were executed to create the DOM addition recently added to\nthe document."}, {"type": "string", "name": "parentId", "description": " the parent binder view id to attach any\nchildren."}, {"type": "string", "name": "topLevelMojitViewId", "description": " the topmost (root) binder view\nid to attach as a child to the parent."}], "description": "Given a set of binder information, initialize binder instances and\nbind them to the page.", "private": "", "guessedtype": "function"}}, "file": "mojito-client.client.js", "shortname": "Client", "properties": {"prototype": {"param": "{Object} data The data for the event. (Empty in this case).", "description": "Fired after the binders are attached to the page.", "guessedname": "prototype", "guessedtype": "property"}}, "description": "The starting point for mojito to run in the browser. You can access one\ninstance of the Mojito Client running within the browser environment\nthrough window.YMojito.client."}, "Cookie.server": {"name": "Cookie.server", "namespace": "", "module": "ActionContextAddon", "methods": {"set": {"params": [{"type": "string", "name": "key", "description": " The key to use."}, {"type": "string", "name": "val", "description": " The value that will be set."}], "description": "Set a cookie on the given key with the given value", "guessedname": "set", "guessedtype": "function"}, "get": {"params": [{"type": "string", "name": "[optional]", "description": " key The key to look for."}], "description": "Returns the cookie for the given key, or all cookies if the key is\nnot specified.", "guessedname": "get", "guessedtype": "function"}}, "file": "cookie.server.js", "shortname": "Cookie.server", "description": "Access point: ac.cookie.*\nThis server-side cookie add-on allows you to easily use cookies."}, "Device.common": {"name": "Device.common", "namespace": "", "module": "ActionContextAddon", "methods": {"get": {"return": {"type": "object", "description": "The value of the named attribute."}, "params": [{"type": "string", "name": "attribute", "description": " The name of the catalog attribute e.g\n\"make\" or \"model\"."}], "description": "Returns the attribute of the catalog for the device\nthis request was intiated from.", "guessedname": "get", "guessedtype": "function"}}, "file": "device.server.js", "shortname": "Device.common", "description": "Access point: ac.device.get()\nDevice catalog addon"}, "MojitoDispatcher": {"name": "MojitoDispatcher", "constructors": [{"params": [{"type": "ServerStore", "name": "resourceStore", "description": " the store to use."}], "description": "This object is responsible for running mojits."}], "namespace": "", "module": "ActionContext", "private": "", "file": "dispatch.common.js", "shortname": "MojitoDispatcher", "description": "This object is responsible for running mojits."}, "Params.common": {"name": "Params.common", "namespace": "", "module": "ActionContextAddon", "methods": {"body": {"return": {"type": "string|object", "description": "param value, or all params if no key\nspecified."}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required."}], "description": "Alias for 'getFromBody'.", "guessedname": "body", "guessedtype": "function"}, "getFromMerged": {"return": {"type": "string|object", "description": "param value, or all params if no key\nspecified."}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required."}], "description": "Gets all params merged into one object. Route -> URL -> Body\nprecedence.", "guessedname": "getFromMerged", "guessedtype": "function"}, "all": {"return": {"type": "object", "description": "all params."}, "description": "Alias for 'getAll'.", "guessedname": "all", "guessedtype": "function"}, "getFromBody": {"return": {"type": "string|object", "description": "param value, or all params if no key\nspecified."}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required."}], "description": "Gets body parameters", "guessedname": "getFromBody", "guessedtype": "function"}, "getFromUrl": {"return": {"type": "string|object", "description": "param value, or all params if no key\nspecified."}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required."}], "description": "Gets URL parameters", "guessedname": "getFromUrl", "guessedtype": "function"}, "url": {"return": {"type": "string|object", "description": "param value, or all params if no key\nspecified."}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required."}], "description": "Alias for 'getFromUrl'.", "guessedname": "url", "guessedtype": "function"}, "route": {"return": {"type": "string|object", "description": "param value, or all params if no key\nspecified."}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required."}], "description": "Alias for 'getFromRoute'.", "guessedname": "route", "guessedtype": "function"}, "getAll": {"return": {"type": "object", "description": "all params."}, "description": "Gets all params, keyed by 'route', 'url', 'body', and 'file'.", "guessedname": "getAll", "guessedtype": "function"}, "getFromFiles": {"return": {"type": "string|object", "description": "param value, or all params if no key\nspecified."}, "description": "Gets file parameters", "private": "", "params": [{"type": "string", "name": "key", "description": " The name of the parameter required."}], "guessedname": "getFromFiles", "guessedtype": "function"}, "getFromRoute": {"return": {"type": "string|object", "description": "param value, or all params if no key\nspecified."}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter."}], "description": "Gets route parameters", "guessedname": "getFromRoute", "guessedtype": "function"}, "files": {"return": {"type": "string|object", "description": "param value, or all params if no key\nspecified."}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required."}], "description": "Alias for 'getFromFiles'.", "guessedname": "files", "guessedtype": "function"}, "merged": {"return": {"type": "string|object", "description": "param value, or all params if no key\nspecified."}, "params": [{"type": "string", "name": "key", "description": " The name of the parameter required."}], "description": "Alias for 'getFromMerged'.", "guessedname": "merged", "guessedtype": "function"}}, "file": "params.common.js", "shortname": "Params.common", "description": "Access point: ac.params.*\nAddon that provides access to any parameters given to the system"}, "Composite.common": {"name": "Composite.common", "namespace": "", "module": "ActionContextAddon", "methods": {"execute": {"params": [{"type": "object", "name": "cfg", "description": " The configuration object to be used."}, {"type": "function", "name": "cb", "description": " The callback that will be called."}], "description": "This method requires an explicit config object and returns\na RMP compliant object via a callback.\n
    \ncfg = {\nchildren: {\nslot-1: {\ntype: \"default\",\naction: \"index\"\n},\nslot-2: {\ntype: \"default\",\naction: \"index\",\nparams: {\nroute: {},\nurl: {},\nbody: {},\nfile: {}\n}\n}\n},\nassets: {}\n}\n
    \nThe \"callback\" is an object containg the child slots with its\nrendered data.\n
    \ncallback({\nslot-1: ,\nslot-2: \n},\n{\nhttp: {}\nassets: {}\n})\n
    ", "guessedname": "execute", "guessedtype": "function"}, "done": {"params": [{"type": "object", "name": "opts", "description": " The configuration object to be used.\ntemplate can be used to provide additional\nview template values."}], "description": "Automatically dispatches all the children of this mojit and collects\ntheir executed values into the view template, keyed by the child's\nname within the mojit's configuration. For example, given the mojit\nspec:\n
    \n\"specs\": {\n\"parent\": {\n\"type\": \"MyCompositeMojit\",\n\"config\": {\n\"children\": {\n\"foo\": {\n\"type\": \"FooMojit\"\n},\n\"bar\": {\n\"type\": \"BarMojit\"\n}\n}\n}\n}\n}\n
    \nAnd given the view template:\n
    \n<div id="{{mojit_view_id}}">\n<h1>{{title}}</h1>\n<div class="fooslot">\n{{{foo}}}\n</div>\n<div class="barslot">\n{{{bar}}}\n</div>\n</div>\n
    \nAnd the controller:\n
    \nY.mojito.controller = {\nindex: function(ac) {\nac.composite.done({\ntemplate: { title: 'Hello there' } // for the view only\n});\n}\n};\n
    \nThis will execute the child intances of the \"FooMojit\" and\n\"BarMojit\", returning their rendered values into the parent's view\ntemplate, thus rendering the full parent view including the children.\nAll the parent parameters are passed along to children.", "guessedname": "done", "guessedtype": "function"}}, "file": "composite.common.js", "shortname": "Composite.common", "description": "Access point: ac.composite.*\nProvides methods for working with many Mojits."}, "Config.common": {"name": "Config.common", "namespace": "", "module": "ActionContextAddon", "methods": {"getDefinition": {"return": {"type": "Object|Array|String", "description": "The requested definition values."}, "params": [{"type": "String", "name": "key", "description": " A period separated key path to look for i.e.\n\"get.my.value\"."}, {"type": "Object|Array|String", "name": "def", "description": " The default value to use if no match\nwas found."}], "description": "Access definition values.", "guessedname": "getDefinition", "guessedtype": "function"}, "get": {"return": {"type": "Object|Array|String", "description": "The requested configuration value."}, "params": [{"type": "String", "name": "key", "description": " A period separated key path to look for i.e.\n\"get.my.value\"."}, {"type": "Object|Array|String", "name": "def", "description": " The default value to use if no match\nwas found."}], "description": "Access config values.", "guessedname": "get", "guessedtype": "function"}}, "file": "config.common.js", "shortname": "Config.common", "description": "Access point: ac.config.*\nProvides access to the Mojits configuration"}, "Assets.common": {"name": "Assets.common", "namespace": "", "module": "ActionContextAddon", "methods": {"getUrl": {"guessedname": "getUrl", "guessedtype": "function"}, "preLoadImage": {"guessedname": "preLoadImage", "guessedtype": "function"}, "addAssets": {"guessedname": "addAssets", "guessedtype": "function"}, "mergeMetaInto": {"guessedname": "mergeMetaInto", "guessedtype": "function"}, "addBlob": {"params": [{"type": "string", "name": "content", "description": " A string of data."}, {"type": "string", "name": "location", "description": " Either \"top\" or \"bottom\"."}], "description": "Method for adding a Blob of data to the page. This can be used\nfor adding custom \"script\" or \"style\" blocks.", "guessedname": "addBlob", "guessedtype": "function"}, "preLoadImages": {"guessedname": "preLoadImages", "guessedtype": "function"}, "mixAssets": {"guessedname": "mixAssets", "guessedtype": "function"}, "addAsset": {"guessedname": "addAsset", "guessedtype": "function"}, "addCss": {"params": [{"type": "string", "name": "link", "description": " A URL (./local.css converts to\n/static/mojit_type/assets/local.css)."}, {"type": "string", "name": "location", "description": " Either \"top\" or \"bottom\"."}], "description": "Method for adding a JS file to the page.", "guessedname": "addCss", "guessedtype": "function"}, "addJs": {"params": [{"type": "string", "name": "link", "description": " A URL (./local.css converts to\n/static/mojit_type/assets/local.css)."}, {"type": "string", "name": "location", "description": " Either \"top\" or \"bottom\"."}], "description": "Method for adding a JS file to the page.", "guessedname": "addJs", "guessedtype": "function"}, "getAssets": {"guessedname": "getAssets", "guessedtype": "function"}}, "file": "assets.common.js", "shortname": "Assets.common", "description": "Access point: ac.assets.*\nProvides methods for adding HTML assets to a page."}, "Carrier.common": {"name": "Carrier.common", "namespace": "", "module": "ActionContextAddon", "methods": {"get": {"return": {"type": "object", "description": "The catalog attribute value."}, "params": [{"type": "string", "name": "attribute", "description": " The name of the catalog attribute e.g\n\"ticker\"."}], "description": "Returns the attribute of the catalog for the current carrier used for\nthis request.", "guessedname": "get", "guessedtype": "function"}}, "file": "carrier.server.js", "shortname": "Carrier.common", "description": "Access point: ac.carrier.get()\nCarrier catalog addon"}, "Analytics.common": {"name": "Analytics.common", "namespace": "", "module": "ActionContextAddon", "methods": {"retrieve": {"params": [{"type": "function", "name": "cb", "description": " callback invoked with the analytics object."}, {"type": "object", "name": "[optional]", "description": " scope scope of the callback."}], "description": "To retrieve analytics data that has been stored by child mojits, call\nthis function and provide a function, which will be called once the\nchildren have been dispatched and all their analytics data has been\nmerged.", "guessedname": "retrieve", "guessedtype": "function"}, "setMergeFunction": {"params": [{"type": "function", "name": "fn", "description": " user-defined merge function, which should accept\ntwo objects, the first is \"to\", and the second is \"from\". this\nfunction should return the merged object."}], "description": "Allows a way for addons mixed in after this one to set an alternate\ndata merge function when analytics from multiple children are\ncombined. The default merge function is the same one used internally\nby Mojito to merge meta data, and will be sufficient for most use\ncases.", "guessedname": "setMergeFunction", "guessedtype": "function"}, "store": {"params": [{"type": "object", "name": "val", "description": " An object bag full of whatever you wish."}], "description": "Store an analytic value. This function can be called multiple times\nwithin a mojit, and uses a merging function to combine objects.", "guessedname": "store", "guessedtype": "function"}}, "file": "analytics.common.js", "shortname": "Analytics.common", "description": "Access point: ac.analytics.*\nProvides an easy way to stash analytics information within child mojits\nand retrieve them within parent after the children have been executed.\nData handled by this addon, however, cannot be used to augment the\nnormal data flow. IE: you cannot retrieve analytics data and then call\nac.done()."}, "MuAdapterServer": {"name": "MuAdapterServer", "namespace": "", "module": "ActionContextAddon", "methods": {"render": {"params": [{"type": "object", "name": "data", "description": " The data to render."}, {"type": "string", "name": "mojitType", "description": " The name of the mojit type."}, {"type": "string", "name": "tmpl", "description": " The name of the template to render."}, {"type": "object", "name": "adapter", "description": " The output adapter to use."}, {"type": "object", "name": "meta", "description": " Optional metadata."}, {"type": "boolean", "name": "more", "description": " Whether there will be more content later."}], "description": "Renders the mustache template using the data provided.", "guessedname": "render", "guessedtype": "function"}}, "private": "", "file": "mu.server.js", "shortname": "MuAdapterServer", "description": "Class text."}}, "version": "0.1.0", "namespaces": ["Y.mojito", "Y.mojito.lib"]} \ No newline at end of file diff --git a/docs/api/registry.client-optional.js.html b/docs/api/registry.client-optional.js.html index b97199bf0..89c666cb6 100644 --- a/docs/api/registry.client-optional.js.html +++ b/docs/api/registry.client-optional.js.html @@ -2,23 +2,23 @@ - API: ActionContext registry.client-optional.js (YUI Library) + Mojito API: CommonLibs registry.client-optional.js ( - - + + - - + +
    -

    mojito

    -

    ActionContext  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > ActionContext + > CommonLibs > registry.client-optional.js (source view) @@ -48,148 +48,194 @@

    ActionContext  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * The breg module is a place to register beans that will be injected by the 
    - * BeanInitilizer module. It provides static access to methods that register beans by 
    - * name, get beans, or get the name of a bean instance.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
    + */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
    +/*
    + * The breg module is a place to register beans that will be injected by the
    + * BeanInitilizer module. It provides static access to methods that register
    + * beans by name, get beans, or get the name of a bean instance.
      * @module breg
      * @private
      */
    -YUI.add("breg", function(Y){
    +YUI.add('breg', function(Y) {
     
         var NAME = 'beanRegistry',
    -		BEAN_REGISTRY_STARTED 		= 'rstart',
    -        REGISTRATION_COMPLETE 		= 'rdone',
    -        REINITIALIZING_BEAN 		= 'reinits',
    -        REINITIALIZED_BEAN 			= 'reinitd',
    -		INITIALIZATION_COMPLETE 	= 'initd',
    -		INJECTION_COMPLETE 			= 'injd',
    -		
    -		isFunction = Y.Lang.isFunction,
    -		
    -		_bInstantiated = false,
    -		_initialInjectionComplete = false,
    -		_c = {},
    +        BEAN_REGISTRY_STARTED = 'rstart',
    +        REGISTRATION_COMPLETE = 'rdone',
    +        REINITIALIZING_BEAN = 'reinits',
    +        REINITIALIZED_BEAN = 'reinitd',
    +        INITIALIZATION_COMPLETE = 'initd',
    +        INJECTION_COMPLETE = 'injd',
    +        isFunction = Y.Lang.isFunction,
    +        _bInstantiated = false,
    +        _initialInjectionComplete = false,
    +        _c = {},
             _b = {},
    -		_ni = 0;
    -		
    -	var DaliBeanRegistry = function() {
    -		DaliBeanRegistry.superclass.constructor.apply(this, arguments);
    -	};
    -	
    -	DaliBeanRegistry.NAME = NAME;
    -
    -	function _doInject(injection, name, into, intoName) {
    -        // if it is a Y.Base obj and there is a setter function that matches, it gets called with the injection
    -		if (into.getAttrs && into.getAttrs().hasOwnProperty(name)) {
    +        _ni = 0,
    +        DaliBeanRegistry;
    +
    +
    +    DaliBeanRegistry = function() {
    +        DaliBeanRegistry.superclass.constructor.apply(this, arguments);
    +    };
    +
    +
    +    DaliBeanRegistry.NAME = NAME;
    +
    +
    +    function _doInject(injection, name, into, intoName) {
    +        var setter;
    +
    +        // if it is a Y.Base obj and there is a setter function that matches, it
    +        // gets called with the injection
    +        if (into.getAttrs && into.getAttrs().hasOwnProperty(name)) {
                 // Y.log('setting ' + name + ' into ' + intoName, 'life', NAME);
                 into.set(name, injection);
    -			_ni++;
    -		} 
    -		// it might also be a normal object with a normal setter
    -		else {
    -			var setter = into['set' + name.substr(0,1).toUpperCase() + name.substr(1)];
    -			if (setter && isFunction(setter)) {
    -				// Y.log('setting ' + name + ' into ' + intoName, 'life', NAME);
    -				setter.call(into, injection);
    -				_ni++;
    -			}
    -		}
    -	}
    -	
    -	function _inject(injectionBean, injectionBeanName, subjects) {
    +            _ni += 1;
    +        } else {
    +            // it might also be a normal object with a normal setter
    +            setter = into['set' + name.substr(0, 1).toUpperCase() +
    +                name.substr(1)];
    +            if (setter && isFunction(setter)) {
    +                // Y.log('setting ' + name + ' into ' + intoName, 'life', NAME);
    +                setter.call(into, injection);
    +                _ni += 1;
    +            }
    +        }
    +    }
    +
    +
    +    function _inject(injectionBean, injectionBeanName, subjects) {
             var subject;
    -		if (injectionBean.inject === false) {
    -			// Y.log(injectionBeanName + " doesn't want to be injected, skipping", 'info', NAME);
    -			return; 
    -		} // ignore beans that don't want to be injected
    +
    +        // ignore beans that don't want to be injected
    +        if (injectionBean.inject === false) {
    +            // Y.log(injectionBeanName +
    +            //     " doesn't want to be injected, skipping", 'info', NAME);
    +            return;
    +        }
    +
             // inner loop is for the subjects of the injection
             for (subject in subjects) {
    -			if (subjects.hasOwnProperty(subject)) {
    -            	_doInject(injectionBean, injectionBeanName, subjects[subject], subject);
    -			}
    +            if (subjects.hasOwnProperty(subject)) {
    +                _doInject(injectionBean, injectionBeanName, subjects[subject],
    +                    subject);
    +            }
             }
         }
    -	
    -	function _getInjections(subjectBean, subjectName, injectionBeans) {
    -		var injectionName;
    -		for (injectionName in injectionBeans) {
    -			if (injectionBeans.hasOwnProperty(injectionName)) {
    -				_doInject(injectionBeans[injectionName], injectionName, subjectBean, subjectName);
    -			}
    -		}
    -	}
    -	
    -	Y.extend(DaliBeanRegistry, Y.EventTarget, {
    -		
    -		/*
    -         * Called to ensure all beans refer to an instance of the bean, not the bean constructor. Loops through all
    -         * registered beans, and if the reference is still a Function, not an Object, it will execute the constructor
    -         * and replace the reference with the resulting object. After ensuring this, a notification message is sent
    -         * to the newly created object so it can do any internal initialization it needs.
    +
    +    function _getInjections(subjectBean, subjectName, injectionBeans) {
    +        var injectionName;
    +
    +        for (injectionName in injectionBeans) {
    +            if (injectionBeans.hasOwnProperty(injectionName)) {
    +                _doInject(injectionBeans[injectionName], injectionName,
    +                    subjectBean, subjectName);
    +            }
    +        }
    +    }
    +
    +
    +    Y.extend(DaliBeanRegistry, Y.EventTarget, {
    +
    +        /*
    +         * Called to ensure all beans refer to an instance of the bean, not the
    +         * bean constructor. Loops through all registered beans, and if the
    +         * reference is still a Function, not an Object, it will execute the
    +         * constructor and replace the reference with the resulting object.
    +         * After ensuring this, a notification message is sent to the newly
    +         * created object so it can do any internal initialization it needs.
              */
             _instantiateBeans: function() {
                 var name;
    -			this.fire(REGISTRATION_COMPLETE);
    +
    +            this.fire(REGISTRATION_COMPLETE);
                 for (name in _c) {
                     if (_c.hasOwnProperty(name)) {
                         if (isFunction(_c[name])) {
                             _b[name] = new _c[name]();
    -                        // Y.log('created new instance of bean: ' + name, 'life', NAME);
    +                        // Y.log('created new instance of bean: ' + name,
    +                        //     'life', NAME);
                         } else {
    -                        // Y.log(name + ' was registered as a bean object and was used as-is', 'info', NAME);
    +                        // Y.log(name +
    +                        //     ' registered as a bean object and used as-is',
    +                        //     'info', NAME);
                             _b[name] = _c[name];
    -                    }                  
    +                    }
                     }
                 }
                 _bInstantiated = true;
                 // notify each bean that instantiation is complete
                 this.fire(INITIALIZATION_COMPLETE);
             },
    -		
    -		_getNumberOfInjections: function() {
    -			return _ni;
    -		},
    -		
    -		initializer: function() {
    -			this.fire(BEAN_REGISTRY_STARTED);
    -		},
    -		
    -		/**
    -         * Called to register a bean or bean constructor with the bean registry. If this method is called
    -         * twice with the same bean, the last bean wins. Only one type of bean can be in the system at a
    -         * time.
    -         * @param name {String} Required identifier of this bean
    -         * @param bean {Object} Either a constructor Function or an instance object of a bean
    +
    +
    +        _getNumberOfInjections: function() {
    +            return _ni;
    +        },
    +
    +
    +        initializer: function() {
    +            this.fire(BEAN_REGISTRY_STARTED);
    +        },
    +
    +
    +        /**
    +         * Called to register a bean or bean constructor with the bean registry.
    +         * If this method is called twice with the same bean, the last bean
    +         * wins. Only one type of bean can be in the system at a time.
    +         * @param {string} name Required identifier of this bean.
    +         * @param {Object} bean Either a constructor Function or an instance
    +         *     object of a bean.
              */
    -        registerBean: function(name, bean)  {
    +        registerBean: function(name, bean) {
                 // Y.log('registering bean: ' + name, 'info', NAME);
                 _c[name] = bean;
    -			// re-initialzie and inject bean if initial registration is complete
    -			if (_initialInjectionComplete) {
    -				this.reInitializeBean(name);
    -			}
    +            // re-initialzie and inject bean if initial registration is complete
    +            if (_initialInjectionComplete) {
    +                this.reInitializeBean(name);
    +            }
             },
    +
    +
             /**
    -         * If the bean system has not been instatiated yet, this will instantiate all beans! 
    -         * @return {Object} contains all beans, each bean is accessible by bean name
    +         * If the bean system has not been instatiated yet, this will
    +         * instantiate all beans!
    +         * @return {Object} contains all beans, each bean is accessible by bean
    +         *     name.
              */
             getBeans: function() {
                 return _b;
             },
    +
    +
             /**
    -         * If the bean system has not been instatiated yet, this will instantiate all beans! Then one bean 
    -         * instance is returned by name.
    -         * @return {Object} the bean instance, or undefined if it is not registered
    +         * If the bean system has not been instatiated yet, this will
    +         * instantiate all beans! Then one bean instance is returned by name.
    +         * @return {Object} the bean instance, or undefined if it is not
    +         *     registered.
              */
             getBean: function(name) {
                 return _b[name];
             },
    +
    +
             /**
              * Given an instance of a bean, returns the String name
    -         * @return {String} name of the registered bean, or undefined if it is not a registered bean
    +         * @return {String} name of the registered bean, or undefined if it is
    +         *     not a registered bean.
              */
             getName: function(inst) {
                 var name;
    +
                 for (name in _b) {
                     if (_b.hasOwnProperty(name)) {
                         if (inst === _b[name]) {
    @@ -198,68 +244,90 @@ 

    ActionContext  0.1.0

    } } }, - - reInitializeBean: function(name) { - var reinitChildBeans = false, prop, childBeanName, oldBean = _b[name]; - this.fire(REINITIALIZING_BEAN, {bean: name}); - if (oldBean && oldBean.destroy && isFunction(oldBean.destroy)) { - reinitChildBeans = oldBean.destroy() || false; - } - if (reinitChildBeans) { - for (prop in oldBean) { - if (oldBean[prop] instanceof Function && prop.substr(0,3) === 'set') { - childBeanName = prop.substr(3,1).toLowerCase() + prop.substr(4); - // only re-init beans that exist (prevents normal setters from triggering reinitialization - if (_b[childBeanName]) { - this.reInitializeBean(childBeanName); - } - } - } - } - delete _b[name]; - _b[name] = isFunction(_c[name]) ? new _c[name]() : _c[name]; - _getInjections(_b[name], name, _b); - _inject(_b[name], name, _b); - this.fire(REINITIALIZED_BEAN, {bean: name}); - }, - - doInjection: function() { - var injection, injectionBean, eventToFire; - if (!_initialInjectionComplete) { - this._instantiateBeans(); - eventToFire = INJECTION_COMPLETE; - } - for (injection in _b) { - if (_b.hasOwnProperty(injection)) { - injectionBean = _b[injection]; - _inject(injectionBean, injection, _b); - } - } - this.fire(eventToFire); - _initialInjectionComplete = true; - }, - - clear: function() { - var bname,b; - for (bname in _b) { - if (_b.hasOwnProperty(bname)) { - b = _b[bname]; - if (b.destroy && isFunction(b.destroy)) { b.destroy(); } - delete _b[bname]; - delete _c[bname]; - } - } - _initialInjectionComplete = false; - _bInstantiated = false; - _ni = 0; - } - - }); - - Y.namespace('Dali'); - Y.Dali.beanRegistry = new DaliBeanRegistry(); - -}, "1.6.3", {requires:['oop', 'event-custom']}); + + + reInitializeBean: function(name) { + var reinitChildBeans = false, + prop, + childBeanName, + oldBean = _b[name]; + + this.fire(REINITIALIZING_BEAN, {bean: name}); + if (oldBean && oldBean.destroy && isFunction(oldBean.destroy)) { + reinitChildBeans = oldBean.destroy() || false; + } + if (reinitChildBeans) { + for (prop in oldBean) { + if (oldBean.hasOwnProperty(prop)) { + if (oldBean[prop] instanceof Function && + prop.substr(0, 3) === 'set') { + childBeanName = prop.substr(3, 1).toLowerCase() + + prop.substr(4); + + // only re-init beans that exist (prevents normal + // setters from triggering reinitialization + if (_b[childBeanName]) { + this.reInitializeBean(childBeanName); + } + } + } + } + } + delete _b[name]; + _b[name] = isFunction(_c[name]) ? new _c[name]() : _c[name]; + _getInjections(_b[name], name, _b); + _inject(_b[name], name, _b); + this.fire(REINITIALIZED_BEAN, {bean: name}); + }, + + + doInjection: function() { + var injection, + injectionBean, + eventToFire; + + if (!_initialInjectionComplete) { + this._instantiateBeans(); + eventToFire = INJECTION_COMPLETE; + } + + for (injection in _b) { + if (_b.hasOwnProperty(injection)) { + injectionBean = _b[injection]; + _inject(injectionBean, injection, _b); + } + } + + this.fire(eventToFire); + _initialInjectionComplete = true; + }, + + + clear: function() { + var bname, + b; + + for (bname in _b) { + if (_b.hasOwnProperty(bname)) { + b = _b[bname]; + if (b.destroy && isFunction(b.destroy)) { b.destroy(); } + delete _b[bname]; + delete _c[bname]; + } + } + _initialInjectionComplete = false; + _bInstantiated = false; + _ni = 0; + } + }); + + Y.namespace('Dali'); + Y.Dali.beanRegistry = new DaliBeanRegistry(); + +}, '1.6.3', {requires: [ + 'oop', + 'event-custom' +]});
    @@ -270,9 +338,9 @@

    ActionContext  0.1.0

    diff --git a/docs/api/request_formatter.client-optional.js.html b/docs/api/request_formatter.client-optional.js.html index 721c072e0..01bcada01 100644 --- a/docs/api/request_formatter.client-optional.js.html +++ b/docs/api/request_formatter.client-optional.js.html @@ -2,23 +2,23 @@ - API: ActionContext request_formatter.client-optional.js (YUI Library) + Mojito API: CommonLibs request_formatter.client-optional.js ( - - + + - - + +
    -

    mojito

    -

    ActionContext  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > ActionContext + > CommonLibs > request_formatter.client-optional.js (source view) @@ -47,114 +47,130 @@

    ActionContext  0.1.0

    -
    YUI.add('simple-request-formatter', function(Y) {
    -	
    +
    /*
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
    + */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
    +YUI.add('simple-request-formatter', function(Y) {
    +
         var NAME = 'reqFormatter',
    -		Lang         = Y.Lang,
    -        isString     = Lang.isString,
    -        isUndefined  = Lang.isUndefined,
    -        
    -        POST                = "POST",
    -        GET                 = "GET",
    -        WEB_SERVICE_HANDLER = "cfg.dali.handler.ws",
    -        
    +        Lang = Y.Lang,
    +        isString = Lang.isString,
    +        isUndefined = Lang.isUndefined,
    +        POST = 'POST',
    +        GET = 'GET',
    +        WEB_SERVICE_HANDLER = 'cfg.dali.handler.ws',
             // required beans
    -		_errorReporter,
    +        _errorReporter,
             _transportUtils,
    -		
    -		// the request formatter itself
    -		SimpleRequestFormatter;
    -    
    +        // the request formatter itself
    +        SimpleRequestFormatter,
    +        _wsRequestFormatter,
    +        _requestTypes = {}; // TODO: Added during JSLint pass...verify.
    +
    +
         /**
    -     * Format web service requests 
    -     * using var foo = function() format
    +     * Format web service requests using var foo = function() format
          * so that reset is easier.
    -     * @method wsRequestFormatter
    -     * @for Y.Transport
    -     * @return {Object} the formatted request
    +     * @return {Object} the formatted request.
          * @private
          */
    -    var _wsRequestFormatter = function(reqData){
    -        var handler = WEB_SERVICE_HANDLER, batchable = reqData.batchable || false;
    +    _wsRequestFormatter = function(reqData) {
    +        var handler = WEB_SERVICE_HANDLER,
    +            batchable = reqData.batchable || false,
    +            forcePost = false,
    +            myData;
     
    -        if(isUndefined(reqData.method)){
    +        if (isUndefined(reqData.method)) {
                 //if no method is set for WS_TYPE default to GET
                 reqData.method = GET;
             }
     
    -        var forcePost = false;
    +        switch (reqData.method.toUpperCase()) {
    +        case POST:
    +            // Y.log('Formating POST data', 'info', NAME);
    +            forcePost = true;
    +            myData = reqData.data;
    +
    +            if (!isString(myData)) {
    +                _errorReporter.error(SimpleRequestFormatter.NAME,
    +                    'data must be a string');
    +            } else {
    +                reqData.data = myData;
    +            }
    +            break;
    +        case (GET || 'DELETE'):
    +            // Y.log('Formating query string for GET data', 'info', NAME);
    +            if (reqData.data !== undefined && isString(reqData.data)) {
    +                reqData.url = _transportUtils.formatUrl(reqData.url,
    +                    reqData.data);
    +            }
    +            break;
    +        default:
    +            // Y.log('passing' + reqData.method + ' request unmodified',
    +            //     'warn', NAME);
    +        }
     
    -        switch(reqData.method.toUpperCase()){
    -            case POST:
    -                // Y.log('Formating POST data', 'info', NAME);
    -                forcePost = true;
    -                var myData = reqData.data;
    +        return {
    +            handler: handler,
    +            data: reqData,
    +            batchable: batchable,
    +            forcepost: forcePost,
    +            targetId: reqData.url
    +        };
    +    };
     
    -                if(!isString(myData)){
    -                   _errorReporter.error(SimpleRequestFormatter.NAME, 'data must be a string');   
    -                }else{
    -                    reqData.data = myData;
    -                }
    -                break;
    -            case (GET || 'DELETE'):
    -                // Y.log('Formating query string for GET data', 'info', NAME);
     
    -                if(reqData.data !== undefined && isString(reqData.data)){
    +    SimpleRequestFormatter = function() {
    +        return {
    +
    +            setErrorReporter: function(it) {
    +                _errorReporter = it;
    +            },
    +
     
    -                    reqData.url = _transportUtils.formatUrl(reqData.url, reqData.data); 
    +            setTransportUtils: function(utils) {
    +                _transportUtils = utils;
    +            },
    +
    +
    +            replaceRequestFormatter: function(requestType, formatter) {
    +                // Y.log('Replacing request formatter to ' + formatter,
    +                //     'info', NAME);
    +                _requestTypes[requestType] = formatter;
    +            },
    +
    +
    +            formatRequest: function(txId, req) {
    +                var reqObj = req.requestObject;
    +
    +                reqObj = _wsRequestFormatter(reqObj, req.moduleId);
    +                reqObj.txId = txId;
    +
    +                if (isUndefined(req.targetId)) {
    +                    req.targetId = reqObj.targetId;
                     }
    -                break;
    -            default:
    -                // Y.log('passing' + reqData.method + ' request unmodified', 'warn', NAME);
    -        }
     
    -        return {
    -            handler:handler,
    -            data:reqData,
    -            batchable:batchable,
    -            forcepost:forcePost,
    -            targetId:reqData.url
    +                reqObj.handler = WEB_SERVICE_HANDLER;
    +                return reqObj;
    +            }
             };
    -
         };
    -	
    -	SimpleRequestFormatter = function() {
    -		return {
    -			setErrorReporter: function(it) {
    -				_errorReporter = it;
    -			},
    -			
    -			setTransportUtils: function(utils) {
    -				_transportUtils = utils;
    -			},
    -			
    -			replaceRequestFormatter: function(requestType, formatter) {
    -				// Y.log('Replacing request formatter to ' + formatter, 'info', NAME);
    -				_requestTypes[requestType] = formatter;
    -			},
    -			
    -			formatRequest: function(txId, req) {
    -	            var reqObj = req.requestObject;
    -	
    -	            reqObj = _wsRequestFormatter(reqObj, req.moduleId);
    -	
    -	            reqObj.txId = txId;
    -	
    -	            if(isUndefined(req.targetId)){
    -	                req.targetId = reqObj.targetId;
    -	            }
    -	
    -                reqObj.handler = WEB_SERVICE_HANDLER;
    -	
    -	            return reqObj;
    -	        }
    -		};
    -	};
    -	SimpleRequestFormatter.NAME = NAME;
    -	
    -	Y.Dali.beanRegistry.registerBean(NAME, SimpleRequestFormatter);
    -	    
    -}, '1.6.3', {requires:['breg']});
    +
    +    SimpleRequestFormatter.NAME = NAME;
    +
    +    Y.Dali.beanRegistry.registerBean(NAME, SimpleRequestFormatter);
    +
    +}, '1.6.3', {requires: [
    +    'breg'
    +]});
     
    @@ -165,9 +181,9 @@

    ActionContext  0.1.0

    diff --git a/docs/api/request_handler.client-optional.js.html b/docs/api/request_handler.client-optional.js.html index 5315d5a25..99d4bc067 100644 --- a/docs/api/request_handler.client-optional.js.html +++ b/docs/api/request_handler.client-optional.js.html @@ -2,23 +2,23 @@ - API: ActionContext request_handler.client-optional.js (YUI Library) + Mojito API: CommonLibs request_handler.client-optional.js ( - - + + - - + +
    -

    mojito

    -

    ActionContext  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > ActionContext + > CommonLibs > request_handler.client-optional.js (source view) @@ -47,309 +47,389 @@

    ActionContext  0.1.0

    -
    YUI.add("request-handler", function(Y){
    -    
    +
    /*
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
    + */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
    +YUI.add('request-handler', function(Y) {
    +
         var NAME = 'requestHandler',
    -		OK                  = 'ok',
    -        E_ABORT             = "abort",
    -        E_TIMEOUT           = "timeout",
    +        OK = 'ok',
    +        E_ABORT = 'abort',
    +        E_TIMEOUT = 'timeout',
             //disable types
    -        E_DISABLED_WITH_QUEUE   = 2,
    -        E_DISABLED_WITHOUT_QUEUE= 1,
    -        E_ENABLED               = 0,
    +        E_DISABLED_WITH_QUEUE = 2,
    +        E_DISABLED_WITHOUT_QUEUE = 1,
    +        E_ENABLED = 0,
             //error types
    -        E_SERVER            = 'server',
    +        E_SERVER = 'server',
             E_RESULT_BADFORMAT = 'badformat',
    -		E_UNSUPPORTED = 	'unsupported',
    -        E_GATEWAY_TIMEOUT     = "Gateway Timeout",
    -
    +        E_UNSUPPORTED = 'unsupported',
    +        E_GATEWAY_TIMEOUT = 'Gateway Timeout',
             //events
    -        REQUEST_EV          = 'request',
    -        RESPONSE_EV         = 'response',
    +        REQUEST_EV = 'request',
    +        RESPONSE_EV = 'response',
             //callback names
    -        FAILURE_CB          = "failure",
    -        ERROR               = "error",
    +        FAILURE_CB = 'failure',
    +        ERROR = 'error',
             //YUI method shortcuts
    -        Lang         = Y.Lang,
    -        isFunction   = Lang.isFunction,
    -        isObject     = Lang.isObject,
    -        isUndefined  = Lang.isUndefined,
    -        isNull       = Lang.isNull,
    -        
    -        _disabled      = E_ENABLED,
    +        Lang = Y.Lang,
    +        isFunction = Lang.isFunction,
    +        isObject = Lang.isObject,
    +        isUndefined = Lang.isUndefined,
    +        isNull = Lang.isNull,
    +        _disabled = E_ENABLED,
             _requestProps = null,
             txId = 0,
    -		
             // dependencies
    -		_requestor,
    -		_modulePlatform,
    +        _requestor,
    +        _modulePlatform,
             _requestFormatter,
             _serviceRegistry,
             _registrationProvider,
             _responseProcessor,
             _ioFacade,
    -		_errorReporter,
    -        _configProvider;
    -	
    -	function reportUnsupportedOperation(name) {
    -		_errorReporter.error(E_UNSUPPORTED, '"'+ NAME +'" does not support operation: '+ name);
    -	}
    -    
    +        _errorReporter,
    +        _configProvider,
    +        RequestHandler;
    +
    +
    +    function reportUnsupportedOperation(name) {
    +        _errorReporter.error(E_UNSUPPORTED, '"' + NAME +
    +            '" does not support operation: ' + name);
    +    }
    +
    +
         /**
          * Adds the request to the queue for processing
    -     * @method _processRequest
    -     * @param {Object} requestObject the request Id
    -     * @param {Object} cb callback object
    -     * @param {Number} id the id of the module making the request
    -     * @return {Number} the id of the request for tracking
    +     * @param {Object} requestObject the request Id.
    +     * @param {Object} cb callback object.
    +     * @param {Number} id the id of the module making the request.
    +     * @return {Number} the id of the request for tracking.
          * @private
          */
    -    function _processRequest(requestObject, cb, id){
    -        var request = {
    -            requestObject :requestObject,
    -            moduleId:id,
    -            originId:id
    -        };
    -    
    -        if(requestObject.moduleId){
    +    function _processRequest(requestObject, cb, id) {
    +        var r,
    +            request = {
    +                requestObject: requestObject,
    +                moduleId: id,
    +                originId: id
    +            };
    +
    +        if (requestObject.moduleId) {
                 request.targetId = requestObject.moduleId;
             }
    -        
    +
             // so the transport bean can fire through YUI3
    -        this.fire(REQUEST_EV, { type: REQUEST_EV, 
    -            request: request.requestObject, 
    -            originId: request.originId 
    +        this.fire(REQUEST_EV, {
    +            type: REQUEST_EV,
    +            request: request.requestObject,
    +            originId: request.originId
             }, NAME);
    -        
    -        var r = _requestFormatter.formatRequest(txId++, request);
    -        
    +
    +        r = _requestFormatter.formatRequest(txId += 1, request);
    +
             _requestor.doRequest({
    -			request: r,
    -			callback: cb,
    -			immediate: true,
    +            request: r,
    +            callback: cb,
    +            immediate: true,
                 forcepost: requestObject.forcepost
    -		});
    +        });
         }
     
    +
         /**
           * once a request has been finished (either complete or aborted)
    -      * this method handles the final tasks of firing events, formatting responses
    -      * registering any modules found, and calling callbacks
    -      * @method completeRequest
    -      * @param {Number} txId the id of the request
    -      * @param {String} method the type of callback to call (error, success)
    -      * @param {String} result the result of the request: error, abort, ok
    -      * @param {String} resultDetail the resultDetails as defined in the interfaces (badcookie, badcrumb, etc)
    +      * this method handles the final tasks of firing events, formatting
    +      * responses registering any modules found, and calling callbacks
           * @private
           */
    -    function completeRequest(){
    -		var response = arguments[0].response || {},
    -			method = arguments[0].method,
    -			result = arguments[0].result,
    -			cb = arguments[0].cb,
    -			resultDetail = arguments[0].resultDetail,
    -        	mods = null, 
    -			res = null,
    -			arg;
    -			
    -       	response.result = result || OK;
    +    function completeRequest(arg0) {
    +        var response = arg0.response || {},
    +            method = arg0.method,
    +            result = arg0.result,
    +            cb = arg0.cb,
    +            resultDetail = arg0.resultDetail,
    +            mods = null,
    +            res = null,
    +            arg,
    +            j,
    +            defaultCallbackWrapper,
    +            failureCallbackWrapper,
    +            mgr,
    +            mlen;
    +
    +        response.result = result || OK;
             response.resultDetail = resultDetail || '';
    -        
    +
             // Y.log('Firing response event.', 'debug', NAME);
    -         
    -        this.fire(RESPONSE_EV, {type:RESPONSE_EV, response:response}, NAME);
    -        
    -        if(isObject(response.data)){
    +
    +        this.fire(RESPONSE_EV, {type: RESPONSE_EV, response: response}, NAME);
    +
    +        if (isObject(response.data)) {
                 res = response.data.res;
                 mods = response.data.mods;
             }
    -        if(isObject(mods)){
    +
    +        if (isObject(mods)) {
                 // Y.log('Module found in response.', 'debug', NAME);
    -            
    -            if(mods[0].state && mods[0].state.defer){ //this is a multiple retry situation
    -                // Y.log('Module is marked defered, but this request handler does not handle defers.', 'warn', NAME);
    -                //gave up on retries, this is a timeout
    -                response.status=504;
    +
    +            if (mods[0].state && mods[0].state.defer) {
    +                // this is a multiple retry situation
    +                // Y.log('Module is marked defered, but this request handler ' +
    +                //     ' does not handle defers.', 'warn', NAME);
    +
    +                // gave up on retries, this is a timeout.
    +                response.status = 504;
                     response.statusText = E_GATEWAY_TIMEOUT;
    -				method = FAILURE_CB;
    +                method = FAILURE_CB;
                 }
    -            
    -            for(var j=0, mlen = mods.length; j < mlen; j++ ){
    -               if(mods[j].props && mods[j].props.id){ //make sure its a real module config
    -                   // Y.log('Registering module with platform. Not starting', 'debug', NAME);
    -                   _modulePlatform.registerModule(mods[j]);
    -               }
    -               
    +
    +            for (j = 0, mlen = mods.length; j < mlen; j) {
    +                if (mods[j].props && mods[j].props.id) {
    +                    // make sure its a real module config
    +                    // Y.log('Registering module with platform. Not starting',
    +                    //     'debug', NAME);
    +                    _modulePlatform.registerModule(mods[j]);
    +                }
                 }
             }
    -        
    +
             response = _responseProcessor.createResponseObject(response);
    -        
    +
             cb = response.cb || cb;
    -        
    -        if(!isUndefined(cb.argument)){
    -            response.argument = cb.argument; //this is to support existing code
    +
    +        if (!isUndefined(cb.argument)) {
    +            response.argument = cb.argument; // this is to support existing code
                 arg = cb.argument;
             }
    -        
    -        if(isFunction(cb[method])){
    -            
    +
    +        if (isFunction(cb[method])) {
                 // Y.log('Dispatching callbacks', 'debug', NAME);
    -            var defaultCallbackWrapper = Y.bind(cb[method], cb.scope || this, response, arg);
    -			var failureCallbackWrapper = Y.bind(cb[FAILURE_CB], cb.scope || this, response, arg);
    -			
    -            if(isObject(res)){
    -                
    -                var mgr = _serviceRegistry.getService('resourcemgr');
    +            defaultCallbackWrapper =
    +                Y.bind(cb[method], cb.scope || this, response, arg);
    +            failureCallbackWrapper =
    +                Y.bind(cb[FAILURE_CB], cb.scope || this, response, arg);
    +
    +            if (isObject(res)) {
    +                mgr = _serviceRegistry.getService('resourcemgr');
                     mgr.load(res, {
    -					success: defaultCallbackWrapper,
    -					failure: failureCallbackWrapper
    -				}, _configProvider.getProxyTimeout());
    -            }else{
    +                    success: defaultCallbackWrapper,
    +                    failure: failureCallbackWrapper
    +                }, _configProvider.getProxyTimeout());
    +            } else {
                     defaultCallbackWrapper();
                 }
    -            
             }
         }
    -	
    -	/**
    -     * Proccess an complete transaction
    +
    +
    +    /**
    +     * Process a complete transaction.
          * @private
    -     * @method processTransactionResponse
    -     * @param {Number} transactionId the IO transaction id
    -     * @param {Object} ioResponseObj the IO response object
          */
    -    function processTransactionResponse(){
    -        
    -        var bc = arguments[0].badcookie || false,
    -			ioResponseObj = arguments[0].resp,
    -            responseData = arguments[0].responseData,
    -			cb = arguments[0].cb,
    -			txId = arguments[0].id,
    -        	status = ioResponseObj.status,
    -        	rd = '', r = ERROR;
    -
    -        if(status != 200 && status != 201 && status != OK){ 
    -            
    -             // Y.log('Error response recieved from server.', 'warn', NAME);
    -             // this is an error case
    -            //server failure single '=' just in case we get a '200' string
    -            if(status === 0){
    -                r = (ioResponseObj.statusText == E_TIMEOUT) ? E_TIMEOUT : E_ABORT;
    -            }else{
    +    function processTransactionResponse(arg0) {
    +
    +        var bc = arg0.badcookie || false,
    +            ioResponseObj = arg0.resp,
    +            responseData = arg0.responseData,
    +            cb = arg0.cb,
    +            txId = arg0.id,
    +            status = ioResponseObj.status,
    +            rd = '',
    +            r = ERROR,
    +            responseText,
    +            contentType;
    +
    +        // TODO: What about 304 (Not changed) ?
    +        if (status !== 200 && status !== 201 && status !== OK) {
    +
    +            // Y.log('Error response received from server.', 'warn', NAME);
    +            // this is an error case
    +            // server failure single '=' just in case we get a '200' string
    +            if (status === 0) {
    +                r = (ioResponseObj.statusText === E_TIMEOUT) ?
    +                        E_TIMEOUT :
    +                        E_ABORT;
    +            } else {
                     rd = E_SERVER;
    -                _errorReporter.error(E_SERVER, 'A server error occured: ', {responseObject:ioResponseObj});
    +                _errorReporter.error(E_SERVER, 'A server error occurred: ',
    +                    { responseObject: ioResponseObj });
                 }
    -			completeRequest.call(this, {txId: txId, method: FAILURE_CB, result: r, resultDetail:rd + ' ' + status, cb: cb});
     
    +            completeRequest.call(this, {
    +                txId: txId,
    +                method: FAILURE_CB,
    +                result: r,
    +                resultDetail: rd + ' ' + status,
    +                cb: cb
    +            });
             } else {
                 //not an error
    -        
    -          // Y.log('Valid response received, processing...', 'warn', NAME);
    +            // Y.log('Valid response received, processing...', 'warn', NAME);
     
    -           var responseText = ioResponseObj.responseText;    
    -           //now to inspect headers, this test is to support unit test cases
    +            responseText = ioResponseObj.responseText;
    +            contentType = ioResponseObj.getResponseHeader('Content-Type');
     
    -           var contentType = ioResponseObj.getResponseHeader('Content-Type');
    -           
    -		   if(contentType.indexOf('Multipart/Related') !==  -1){ //faster than regex
    -               reportUnsupportedOperation('multi-part response');
    -			   completeRequest.call(this, {cb:cb, method: FAILURE_CB, result: ERROR, resultDetail: E_RESULT_BADFORMAT});
    -			   return;
    -           }
    +            // Test here is faster than regex.
    +            if (contentType.indexOf('Multipart/Related') !== -1) {
    +                reportUnsupportedOperation('multi-part response');
    +                completeRequest.call(this, {
    +                    cb: cb,
    +                    method: FAILURE_CB,
    +                    result: ERROR,
    +                    resultDetail: E_RESULT_BADFORMAT
    +                });
    +                return;
    +            }
     
    -           _responseProcessor.processResponse(responseData.resps[0], {cb:cb}, bc);
    +            _responseProcessor.processResponse(responseData.resps[0],
    +                { cb: cb }, bc);
             }
         }
    -    
    -    var RequestHandler = function() {
    -		var inst = {
    -			setRequestor: function(requestor) {
    -				_requestor = requestor;
    -			},
    -			setModulePlatform: function(platform) {
    -				_modulePlatform = platform;
    -			},
    -			setReqFormatter: function(formatter) {
    -				_requestFormatter = formatter;
    -			},
    -			getRequestFormatter: function() {
    -				return _requestFormatter;
    -			},
    -			setServiceRegistry: function(provider) {
    -				_serviceRegistry = provider;
    -			},
    -			setRegistrationProvider: function(provider) {
    -				_registrationProvider = provider;
    -			},
    -			setResponseProcessor: function(processor) {
    -				if (_responseProcessor) { _responseProcessor.detach(); }
    -				_responseProcessor = processor;
    -				_responseProcessor.on('responseProcessed', completeRequest, this);
    -			},
    -			getResponseProcessor: function() {
    -				return _responseProcessor;
    -			},
    -			setIoFacade: function(facade) {
    -				if (_ioFacade) { _ioFacade.detach(); }
    -				_ioFacade = facade;
    -				_ioFacade.on('transactionResponse', processTransactionResponse, this);
    -			},
    -			getIoFacade: function() {
    -				return _ioFacade;
    -			},
    -			setConfigProvider: function(provider) {
    -				_configProvider = provider;
    -			},
    -			getConfigProvider: function() {
    -				return _configProvider;
    -			},
    -			setErrorReporter: function(reporter) {
    -				_errorReporter = reporter;
    -			},
    -			replaceRequestFormatter: function(requestType, formatter) {
    -				_requestFormatter.replaceRequestFormatter(requestType, formatter);
    -			},
    -			replaceResponseFormatter: function(formatter) {
    -				_responseProcessor.replaceResponseFormatter(formatter);
    -			},
    -			disable: function(queue) {
    -	            // Y.log('Disabling transport. Queue state: '+ queue, 'debug', NAME);
    -	            _disabled = queue ?  E_DISABLED_WITH_QUEUE :  E_DISABLED_WITHOUT_QUEUE;
    -	        },
    -	        
    -	        enable: function(queue) {
    -	            // Y.log('Enabling transport', 'debug', NAME);
    -	            _disabled = E_ENABLED;
    -	        },
    -	        
    -	        isEnabled: function() {
    -	            return _disabled !== E_DISABLED_WITHOUT_QUEUE;
    -	        },
    -	        
    -	        processRequest: _processRequest,
    -			
    -			abortRequest: function (requestId, moduleId){
    -				reportUnsupportedOperation('abortRequest');
    -			},
    -			
    -			abortModuleRequests: function (moduleId){
    -				reportUnsupportedOperation('abortModuleRequests');
    -			},		 
    -			
    -			isRequestPending : function(requestId,moduleId){
    -				reportUnsupportedOperation('isRequestPending');
    -			}		
    -		};
    -		
    -		return new Y.Dali.Bean(inst);
    -	};
    -	
    -	RequestHandler.NAME = NAME;
    -	
    -	Y.Dali.beanRegistry.registerBean(NAME, RequestHandler);
    -	    
    -}, '1.6.3', {requires:['dali-bean', 'breg']});
    +
    +
    +    RequestHandler = function() {
    +        var inst = {
    +
    +            setRequestor: function(requestor) {
    +                _requestor = requestor;
    +            },
    +
    +
    +            setModulePlatform: function(platform) {
    +                _modulePlatform = platform;
    +            },
    +
    +
    +            setReqFormatter: function(formatter) {
    +                _requestFormatter = formatter;
    +            },
    +
    +
    +            getRequestFormatter: function() {
    +                return _requestFormatter;
    +            },
    +
    +
    +            setServiceRegistry: function(provider) {
    +                _serviceRegistry = provider;
    +            },
    +
    +
    +            setRegistrationProvider: function(provider) {
    +                _registrationProvider = provider;
    +            },
    +
    +
    +            setResponseProcessor: function(processor) {
    +                if (_responseProcessor) { _responseProcessor.detach(); }
    +                _responseProcessor = processor;
    +                _responseProcessor.on('responseProcessed', completeRequest,
    +                    this);
    +            },
    +
    +
    +            getResponseProcessor: function() {
    +                return _responseProcessor;
    +            },
    +
    +
    +            setIoFacade: function(facade) {
    +                if (_ioFacade) { _ioFacade.detach(); }
    +                _ioFacade = facade;
    +                _ioFacade.on('transactionResponse', processTransactionResponse,
    +                    this);
    +            },
    +
    +
    +            getIoFacade: function() {
    +                return _ioFacade;
    +            },
    +
    +
    +            setConfigProvider: function(provider) {
    +                _configProvider = provider;
    +            },
    +
    +
    +            getConfigProvider: function() {
    +                return _configProvider;
    +            },
    +
    +
    +            setErrorReporter: function(reporter) {
    +                _errorReporter = reporter;
    +            },
    +
    +
    +            replaceRequestFormatter: function(requestType, formatter) {
    +                _requestFormatter.replaceRequestFormatter(requestType,
    +                    formatter);
    +            },
    +
    +
    +            replaceResponseFormatter: function(formatter) {
    +                _responseProcessor.replaceResponseFormatter(formatter);
    +            },
    +
    +
    +            disable: function(queue) {
    +                // Y.log('Disabling transport. Queue state: '+ queue, 'debug',
    +                //     NAME);
    +                _disabled = queue ?
    +                        E_DISABLED_WITH_QUEUE :
    +                        E_DISABLED_WITHOUT_QUEUE;
    +            },
    +
    +
    +            enable: function(queue) {
    +                // Y.log('Enabling transport', 'debug', NAME);
    +                _disabled = E_ENABLED;
    +            },
    +
    +
    +            isEnabled: function() {
    +                return _disabled !== E_DISABLED_WITHOUT_QUEUE;
    +            },
    +
    +
    +            processRequest: _processRequest,
    +
    +
    +            abortRequest: function(requestId, moduleId) {
    +                reportUnsupportedOperation('abortRequest');
    +            },
    +
    +
    +            abortModuleRequests: function(moduleId) {
    +                reportUnsupportedOperation('abortModuleRequests');
    +            },
    +
    +
    +            isRequestPending: function(requestId, moduleId) {
    +                reportUnsupportedOperation('isRequestPending');
    +            }
    +        };
    +
    +        return new Y.Dali.Bean(inst);
    +    };
    +
    +    RequestHandler.NAME = NAME;
    +
    +    Y.Dali.beanRegistry.registerBean(NAME, RequestHandler);
    +
    +}, '1.6.3', {requires: [
    +    'dali-bean',
    +    'breg'
    +]});
     
    @@ -360,9 +440,9 @@

    ActionContext  0.1.0

    diff --git a/docs/api/requestor.client-optional.js.html b/docs/api/requestor.client-optional.js.html index cd9270d43..5f98c5e35 100644 --- a/docs/api/requestor.client-optional.js.html +++ b/docs/api/requestor.client-optional.js.html @@ -2,23 +2,23 @@ - API: ActionContext requestor.client-optional.js (YUI Library) + Mojito API: CommonLibs requestor.client-optional.js ( - - + + - - + +
    -

    mojito

    -

    ActionContext  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > ActionContext + > CommonLibs > requestor.client-optional.js (source view) @@ -47,118 +47,136 @@

    ActionContext  0.1.0

    -
    YUI.add('requestor', function(Y) {
    -	
    -	var NAME = 'requestor',
    -	
    -		POST                = "POST",
    -        GET                 = "GET",
    -        MAXIMUM_GET_LENGTH    = 1500,
    -		
    -		//YUI method shortcuts
    -        Lang         = Y.Lang,
    -        isNull       = Lang.isNull,
    -		isArray		 = Lang.isArray,
    -		
    -		_requestProps = null,
    -		_pendingTransactions = {},
    -		
    -		// bean dependencies
    -		_ioFacade,
    -		_configProvider;
    -		
    -	/**
    +
    /*
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
    + */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
    +YUI.add('requestor', function(Y) {
    +
    +    var NAME = 'requestor',
    +        POST = 'POST',
    +        GET = 'GET',
    +        MAXIMUM_GET_LENGTH = 1500,
    +
    +        //YUI method shortcuts
    +        Lang = Y.Lang,
    +        isNull = Lang.isNull,
    +        isArray = Lang.isArray,
    +
    +        _requestProps = null,
    +        _pendingTransactions = {},
    +
    +        // bean dependencies
    +        _ioFacade,
    +        _configProvider;
    +
    +
    +    /**
          * finally prepares the request (stringify) and sends it
          * to ioFacade to be sent to the server
    -     * @private 
    -     * @method doRequest
    -     * @param {Array} request the request or requests to be sent to the server
    -     * @param {Boolean} forcepost if true the request will be sent as a post, 
    -     *                            regardless of length
    -     * @return {Object} the transactionObject from io 
    +     * @private
    +     * @param {Array} request the request or requests to be sent to the server.
    +     * @param {Boolean} forcepost if true the request will be sent as a post,
    +     *                            regardless of length.
    +     * @return {Object} the transactionObject from io.
          */
    -    function doRequest(opts){
    +    function doRequest(opts) {
             var url = _configProvider.getProxyUrl(),
    -			request = opts.request,
    -			cb = opts.callback,
    -			forcepost = opts.forcepost,
    -			immediate = opts.immediate,
    -			req, rString, m;
    -
    -		if (typeof forcepost === 'undefined') {
    -			forcepost = false;
    -		}
    -		if (typeof immediate === 'undefined') {
    -			immediate = false;
    -		}
    -
    -        if(isNull(_requestProps)){
    +            request = opts.request,
    +            cb = opts.callback,
    +            forcepost = opts.forcepost,
    +            immediate = opts.immediate,
    +            req,
    +            rString,
    +            m;
    +
    +        if (typeof forcepost === 'undefined') {
    +            forcepost = false;
    +        }
    +        if (typeof immediate === 'undefined') {
    +            immediate = false;
    +        }
    +
    +        if (isNull(_requestProps)) {
                 _requestProps = {};
                 _requestProps.dali = _configProvider.getDaliProperties() || {};
             }
    -        
    -		if (!isArray(request)) {
    -			m = request.method ? request.method : GET;
    -			request = [request];
    -		} else {
    -	        m = GET;
    -		}
    -
    -        rString = Y.JSON.stringify({reqs:request, props:_requestProps});
    -        
    -        if((encodeURIComponent(rString).length > MAXIMUM_GET_LENGTH) || forcepost){
    +
    +        if (!isArray(request)) {
    +            m = request.method || GET;
    +            request = [request];
    +        } else {
    +            m = GET;
    +        }
    +
    +        rString = Y.JSON.stringify({reqs: request, props: _requestProps});
    +
    +        if ((encodeURIComponent(rString).length > MAXIMUM_GET_LENGTH) ||
    +                forcepost) {
                 m = POST;
             }
     
    -		if (immediate) {
    -			_ioFacade.execute(request[0].txId, url, rString, m, cb);
    -		} else {
    -	        req =  _ioFacade.execute(request[0].txId, url, rString, m);
    -	        _pendingTransactions[req.id] = {
    -	            ioObj : req,
    -	            cfg   : request,
    -	            forcepost:forcepost
    -	        };
    -	        return req;
    -		}
    +        if (immediate) {
    +            _ioFacade.execute(request[0].txId, url, rString, m, cb);
    +        } else {
    +            req = _ioFacade.execute(request[0].txId, url, rString, m);
    +            _pendingTransactions[req.id] = {
    +                ioObj: req,
    +                cfg: request,
    +                forcepost: forcepost
    +            };
    +            return req;
    +        }
         }
    -		
    -	function Requestor() {
    -		return {
    -			setIoFacade: function(facade) {
    -				_ioFacade = facade;
    -			},
    -/*
    -			getIoFacade: function() {
    -				return _ioFacade;
    -			},
    -
    -*/			setConfigProvider: function(provider) {
    -				_configProvider = provider;
    -			},
    -/*
    -			getConfigProvider: function() {
    -				return _configProvider;
    -			},
    -*/
    -			setDaliCrumb: function(crumb) {
    -				_requestProps.dali.crumb = crumb;
    -			},
    -			deletePending: function(txId) {
    -				delete(_pendingTransactions[txId]);
    -			},
    -			getPending: function(txId) {
    -				return _pendingTransactions[txId];
    -			},
    -			doRequest: doRequest
    -		};
    -	}
    -	
    -	Requestor.NAME = NAME;
    -	
    -	Y.Dali.beanRegistry.registerBean(NAME, Requestor);
    -	
    -}, '1.6.3', {requires:['json', 'breg']});
    +
    +
    +    function Requestor() {
    +        return {
    +
    +            setIoFacade: function(facade) {
    +                _ioFacade = facade;
    +            },
    +
    +
    +            setConfigProvider: function(provider) {
    +                _configProvider = provider;
    +            },
    +
    +
    +            setDaliCrumb: function(crumb) {
    +                _requestProps.dali.crumb = crumb;
    +            },
    +
    +
    +            deletePending: function(txId) {
    +                delete _pendingTransactions[txId];
    +            },
    +
    +
    +            getPending: function(txId) {
    +                return _pendingTransactions[txId];
    +            },
    +
    +
    +            doRequest: doRequest
    +        };
    +    }
    +
    +    Requestor.NAME = NAME;
    +
    +    Y.Dali.beanRegistry.registerBean(NAME, Requestor);
    +
    +}, '1.6.3', {requires: [
    +    'json',
    +    'breg'
    +]});
     
    @@ -169,9 +187,9 @@

    ActionContext  0.1.0

    diff --git a/docs/api/resource-store-adapter.common.js.html b/docs/api/resource-store-adapter.common.js.html index 842f33990..19edcb538 100644 --- a/docs/api/resource-store-adapter.common.js.html +++ b/docs/api/resource-store-adapter.common.js.html @@ -2,23 +2,23 @@ - API: CommonLibs resource-store-adapter.common.js (YUI Library) + Mojito API: MojitoClient resource-store-adapter.common.js ( - - + + - - + +
    -

    mojito

    -

    CommonLibs  0.1.0

    +

    mojito

    +

    MojitoClient  0.3.0

    mojito - > CommonLibs + > MojitoClient > resource-store-adapter.common.js (source view) @@ -48,32 +48,43 @@

    CommonLibs  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
      * This object is responsible for running mojits.
      * @class MojitoDispatcher
      * @constructor
    - * @param resourceStore {ServerStore} the store to use
    + * @param {ServerStore} resourceStore the store to use.
      * @private
      */
    -YUI.add('mojito-resource-store-adapter', function(Y, NAME){
    +YUI.add('mojito-resource-store-adapter', function(Y, NAME) {
     
         var APP_ROOT_PATH = '',
             logger;
     
    +
         Y.mojito.ResourceStoreAdapter = {
     
             ENV: '',
     
    -        init: function(env, resourceStore, globalLogger){
     
    -            // must be passed the Mojito logger and use it for consistent logging because the Y.log
    -            // within this scope has not been mutated yet
    +        init: function(env, resourceStore, globalLogger) {
    +
    +            // must be passed the Mojito logger and use it for consistent
    +            // logging because the Y.log within this scope has not been mutated
    +            // yet
                 logger = globalLogger;
     
                 logger.log('resource store adapter init', 'mojito', NAME);
    -            
    +
                 APP_ROOT_PATH = resourceStore._root;
     
                 this.ENV = env;
    @@ -85,175 +96,195 @@ 

    CommonLibs  0.1.0

    return this; }, + expandInstance: function(instance, ctx, cb) { //logger.log('expandInstance', 'mojito', NAME); return this.expandInstanceForEnv(this.ENV, instance, ctx, cb); }, - expandInstanceForEnv: function(env, instance, context, callback){ - - var base = {}, source = {}, self = this; - /* this doesn't do anything yet */ -// // If we have this cached return it -// if(this.isCached(env, instance, context)){ -// callback(this.getCached(env, instance, context)); -// return; -// } + expandInstanceForEnv: function(env, instance, context, callback) { + var base = {}, + source = {}, + my = this; - if (! instance.guid) { - instance.guid = Y.guid(); + if (!instance.instanceId) { + instance.instanceId = Y.guid(); + //DEBUGGING: instance.instanceId += '-instance-common-' + + // [instance.base||'', instance.type||''].join('-'); } + // DEPRECATED, but kept in case a user is using. + instance.guid = instance.instanceId; // What are being asked to expand? - if(instance.base){ + if (instance.base) { source.name = instance.base; source.func = this.getSpec; - } - else if(instance.type){ + } else if (instance.type) { source.name = instance.type; source.func = this.getType; - } - else{ + } else { // We don't have any inputs so fail throw new Error('There was no info in the "instance" object'); } // This contains the app "definition" and app config - self.getApp(env, context, function(app){ + my.getApp(env, context, function(app) { // Here we get either the a spec or a type - source.func(env, source.name, context, function(err, data){ + source.func(env, source.name, context, function(err, data) { if (err) { callback(err); return; } - // Merge the inputs from right to left (right most values win) - base = self.merge(app, data, instance); - - // Ensure the "instance" has been properly resolved. If there are no specs in the application.json file, - // there is an error below because the instance is invalid. We should check here for a valid instance object - // and throw an error if it is not. This happens because someone could create a routes.json file with routes - // that don't route to mojit instances, and the URI router creates invalid commands, which are passed into - // the dispatch. -- Matt - if(!self.validate(base)){ + // Merge the inputs from right to left (right most values + // win) + base = my.merge(app, data, instance); + + // Ensure the "instance" has been properly resolved. If + // there are no specs in the application.json file, there is + // an error below because the instance is invalid. We should + // check here for a valid instance object and throw an error + // if it is not. This happens because someone could create a + // routes.json file with routes that don't route to mojit + // instances, and the URI router creates invalid commands, + // which are passed into the dispatch. + if (!my.validate(base)) { callback({ message: 'Instance was not valid.', - stack: JSON.stringify(base,null,4) + stack: JSON.stringify(base, null, 4) }); return; } // Add the final "base" to the cache - self.cache(env, instance, context, base); + my.cache(env, instance, context, base); callback(null, base); - }, self); + }, my); }); }, - getApp: function(env, context, callback){ + getApp: function(env, context, callback) { var obj = {}; callback(obj); }, - getAppPath: function(){ + + getAppPath: function() { return APP_ROOT_PATH; }, - getAppConfig: function(context, name){ + + getAppConfig: function(context, name) { return this.store.getAppConfig(context, name); }, - getSpec: function(env, id, context, callback, scope){ - if(!scope){ + getSpec: function(env, id, context, callback, scope) { + + if (!scope) { scope = this; } scope.store.getSpec(env, id, context, callback); }, - getType: function(env, type, context, callback, scope){ - if(!scope){ + getType: function(env, type, context, callback, scope) { + + if (!scope) { scope = this; } scope.store.getType(env, type, context, callback); }, - merge: function(){ - var obj = {}, i; + merge: function() { + var obj = {}, + i; - for(i=0; i<arguments.length; i++){ + for (i = 0; i < arguments.length; i += 1) { obj = Y.mojito.util.mergeRecursive(obj, arguments[i]); } return obj; }, - validate: function(base){ - if(!base.type || !base.yui){ + validate: function(base) { + + if (!base.type || !base.yui) { return false; } return true; }, - isCached: function(env, instance, context){ + + isCached: function(env, instance, context) { return false; }, - getCached: function(env, instance, context){ + + getCached: function(env, instance, context) { return {}; }, - cache: function(env, instance, context, obj){ + + cache: function(env, instance, context, obj) { return false; }, - getYuiConfigAllMojits: function(env, ctx){ + + getYuiConfigAllMojits: function(env, ctx) { //logger.log('getYuiConfigAllMojits', 'warn', NAME); return this.store.getYuiConfigAllMojits(env, ctx); }, - getYuiConfigApp: function(env, ctx){ + + getYuiConfigApp: function(env, ctx) { //logger.log('getYuiConfigApp', 'warn', NAME); return this.store.getYuiConfigApp(env, ctx); }, - getYuiConfigFw: function(env, ctx){ + + getYuiConfigFw: function(env, ctx) { //logger.log('getYuiConfigFw', 'warn', NAME); return this.store.getYuiConfigFw(env, ctx); }, - serializeClientStore: function(ctx, instances){ + + serializeClientStore: function(ctx, instances) { //logger.log('serializeClientStore', 'warn', NAME); return this.store.serializeClientStore(ctx, instances); }, - getMojitTypeDetails: function(env, ctx, mojitType, dest){ + + getMojitTypeDetails: function(env, ctx, mojitType, dest) { //logger.log('getMojitTypeDetails', 'warn', NAME); return this.store.getMojitTypeDetails(env, ctx, mojitType, dest); }, - fileFromStaticHandlerURL: function(url){ + + fileFromStaticHandlerURL: function(url) { //logger.log('fileFromStaticHandlerURL', 'warn', NAME); return this.store.fileFromStaticHandlerURL(url); }, + getRoutes: function(ctx) { //logger.log('getRoutes', 'warn', NAME); return this.store.getRoutes(ctx); } }; -}, '0.1.0', {requires:['mojito-util']}); +}, '0.3.0', {requires: [ + 'mojito-util' +]});
    @@ -266,8 +297,8 @@

    Modules

    @@ -275,7 +306,8 @@

    Modules

    @@ -284,11 +316,13 @@

    Classes

    Files

    --> @@ -306,7 +340,7 @@

    Files

    diff --git a/docs/api/response_formatter.client-optional.js.html b/docs/api/response_formatter.client-optional.js.html index 7d766c9ab..1c3e07f04 100644 --- a/docs/api/response_formatter.client-optional.js.html +++ b/docs/api/response_formatter.client-optional.js.html @@ -2,23 +2,23 @@ - API: ActionContext response_formatter.client-optional.js (YUI Library) + Mojito API: CommonLibs response_formatter.client-optional.js ( - - + + - - + +
    -

    mojito

    -

    ActionContext  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > ActionContext + > CommonLibs > response_formatter.client-optional.js (source view) @@ -47,31 +47,45 @@

    ActionContext  0.1.0

    -
    YUI.add('response-formatter', function(Y) {
    -	var NAME = 'respFormatter';
    -	
    -	function _defaultFormatter(resp) {
    -		return resp;
    -	}
    -	
    -	function ResponseFormatter() {
    -		return {
    -			
    -			formatResponse: _defaultFormatter,
    -			
    -			replaceResponseFormatter: function(formatter) {
    -				// Y.log('Changing GLOBAL request formatter to ' + formatter, 'warn', NAME);
    -	            this.formatResponse = formatter;
    -			}
    -			
    -		};
    -	}
    -	
    -	ResponseFormatter.NAME = NAME;
    -	
    -	Y.Dali.beanRegistry.registerBean(NAME, ResponseFormatter);
    -
    -}, '1.6.3', {requires:['breg']});
    +
    /*
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
    + */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
    +YUI.add('response-formatter', function(Y) {
    +
    +    var NAME = 'respFormatter';
    +
    +
    +    function _defaultFormatter(resp) {
    +        return resp;
    +    }
    +
    +
    +    function ResponseFormatter() {
    +        return {
    +
    +            formatResponse: _defaultFormatter,
    +
    +            replaceResponseFormatter: function(formatter) {
    +                this.formatResponse = formatter;
    +            }
    +        };
    +    }
    +
    +    ResponseFormatter.NAME = NAME;
    +
    +    Y.Dali.beanRegistry.registerBean(NAME, ResponseFormatter);
    +
    +}, '1.6.3', {requires: [
    +    'breg'
    +]});
     
    @@ -82,9 +96,9 @@

    ActionContext  0.1.0

    diff --git a/docs/api/response_processor.client-optional.js.html b/docs/api/response_processor.client-optional.js.html index 59ddd396b..df85f879d 100644 --- a/docs/api/response_processor.client-optional.js.html +++ b/docs/api/response_processor.client-optional.js.html @@ -2,23 +2,23 @@ - API: ActionContext response_processor.client-optional.js (YUI Library) + Mojito API: CommonLibs response_processor.client-optional.js ( - - + + - - + +
    -

    mojito

    -

    ActionContext  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > ActionContext + > CommonLibs > response_processor.client-optional.js (source view) @@ -47,52 +47,73 @@

    ActionContext  0.1.0

    -
    YUI.add('response-processor', function(Y) {
    -	
    -	var NAME = 'responseProcessor',
    -		OK                  = 'ok',
    -        Lang         = Y.Lang,
    -        isUndefined  = Lang.isUndefined,
    -		ERROR = 'error',
    -		
    -		//error types
    -        E_BROWSER           = 'browser',
    -        E_CRUMB             = 'crumb',
    +
    /*
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
    + */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
    +YUI.add('response-processor', function(Y) {
    +
    +    var NAME = 'responseProcessor',
    +        OK = 'ok',
    +        Lang = Y.Lang,
    +        isUndefined = Lang.isUndefined,
    +        ERROR = 'error',
    +
    +        //error types
    +        E_BROWSER = 'browser',
    +        E_CRUMB = 'crumb',
             //result detail types
             E_RESULT_NOCOOKIES = 'nocookies',
    -        E_RESULT_BADCRUMB  = 'badcrumb',
    -    
    +        E_RESULT_BADCRUMB = 'badcrumb',
    +
             // beans
             _responseFormatter,
    -		_errorReporter,
    -        _configProvider;
    -		
    -	/**
    +        _errorReporter,
    +        _configProvider,
    +        ResponseProcessor;
    +
    +
    +    /**
          * creates a mimic of the yui response object
          * for use in web service calls
    -     * @method createWebServiceResponseObject
    -     * @param {DaliResponseWs} response the response from the daliProxy
    -     * @return {Object} formated response object
    +     * @param {DaliResponseWs} response the response from the daliProxy.
    +     * @return {Object} formated response object.
          * @private
    -     */   
    -    function _createWebServiceResponseObject( /* DaliResponseWS */  response ){
    +     */
    +    function _createWebServiceResponseObject(response) {
    +
             // Y.log('Building web service response object', 'info', NAME);
    -        var myData = Y.Object(response.data);
     
    -        var headerHash = false; //cache the header lookup for later after first time
    +        var myData = Y.Object(response.data),
    +            headerHash = false, // cache the header lookup for later after
    +                                // first time
    +            respHeaderFlag = false; //save string replace until needed
    +
     
    -        var respHeaderFlag = false; //save string replace until needed
    -        
    -        myData.getResponseHeader = function(header){
    +        myData.getResponseHeader = function(header) {
    +            var headerList,
    +                len,
    +                i,
    +                tmparr;
     
    -            if(!headerHash){ //don't bother processing this unless someone wants it.
    -                this.responseHeader = myData.responseHeader.replace('\r\n', '\n'); //to comply with yui io docs
    +            // don't bother processing this unless someone wants it.
    +            if (!headerHash) {
    +                // to comply with yui io docs.
    +                this.responseHeader =
    +                    myData.responseHeader.replace('\r\n', '\n');
                     respHeaderFlag = true;
    -                var headerList = myData.responseHeader.split('\n');
    -                var len = headerList.length;
    +                headerList = myData.responseHeader.split('\n');
    +                len = headerList.length;
                     headerHash = {};
    -                for (var i=0; i < len; i++) {
    -                    var tmparr = headerList[i].split(': ');
    +                for (i = 0; i < len; i += 1) {
    +                    tmparr = headerList[i].split(': ');
                         headerHash[tmparr[0]] = tmparr[1];
                     }
                 }
    @@ -100,127 +121,149 @@ 

    ActionContext  0.1.0

    return headerHash[header]; }; - myData.getAllResponseHeaders = function(){ - if(!respHeaderFlag){ - this.responseHeader = myData.responseHeader.replace('\r\n', '\n'); //to comply with yui io docs + + myData.getAllResponseHeaders = function() { + if (!respHeaderFlag) { + // to comply with yui io docs. + this.responseHeader = + myData.responseHeader.replace('\r\n', '\n'); } return this.responseHeader; }; - + return Y.mix(response, myData); } - - var ResponseProcessor = function() { - var inst = { - setConfigProvider: function(provider) { - _configProvider = provider; - }, - setRespFormatter: function(formatter) { - _responseFormatter = formatter; - }, - setErrorReporter: function(reporter) { - _errorReporter = reporter; - }, - replaceResponseFormatter: function(formatter) { - _responseFormatter.replaceResponseFormatter(formatter); - }, - - processResponse: function(o, metaData, badcookie){ - - var txId = o.txId; - - if(isUndefined(metaData)){ - //this will happen if the request was aborted before it was sent - return; - } - - var fail = true; - - var response = { - data:o.data - }; - - var result,resultDetail; - - response.cb = metaData.cb; - if(o.status == 200 || o.status == 201){ - response.status = OK; - response.result = OK; - result = OK; - fail = false; - }else{ - response.status = ERROR; - response.result = ERROR; - if(o.status == 400){ //double "=" to catch strings - - var errorType = E_CRUMB, - message = "Invalid crumb."; - resultDetail = E_RESULT_BADCRUMB; - result = ERROR; - if(!window.navigator.cookieEnabled || badcookie == 'badcookie'){ - errorType = E_BROWSER; - resultDetail = E_RESULT_NOCOOKIES; - message = "Cookies are disabled"; - } - - _errorReporter.error(errorType, message); - - } - - } - - this.fire('responseProcessed', { - type: 'responseProcessed', - txId:txId, - response: response, - method:(fail ? 'failure' : 'success'), - result:result, - resultDetail:resultDetail - }, NAME); - }, - - createResponseObject: function(response, platform){ - // Y.log('Building response object', 'debug', NAME); - - if(response.data && response.data.responseText){ //this will only happen for webservice responses - // Y.log('This looks like a proxied web service request, passing to WS formatter', 'debug', NAME); - return _createWebServiceResponseObject(response); - }else{ - //support a wrong implementation in old daliTransport - //porting the mistake forward. - - if(response.data){ - if(response.data.mods){ - response.mods = response.data.mods; //this is for backwards compatibility - response.mod = response.mods[0]; //this is the correct format - delete(response.data.mods); - } - - if(response.data.html){ - response.html = response.data.html; - delete(response.data.html); - } - - if(response.data.res){ - response.res = response.data.res; - delete(response.data.res); - } - } - - response = _responseFormatter.formatResponse(response); - return response; //no op. - } - } - - }; - return new Y.Dali.Bean(inst); - }; - - ResponseProcessor.NAME = NAME; - + + + ResponseProcessor = function() { + var inst = { + + setConfigProvider: function(provider) { + _configProvider = provider; + }, + + + setRespFormatter: function(formatter) { + _responseFormatter = formatter; + }, + + + setErrorReporter: function(reporter) { + _errorReporter = reporter; + }, + + + replaceResponseFormatter: function(formatter) { + _responseFormatter.replaceResponseFormatter(formatter); + }, + + + processResponse: function(o, metaData, badcookie) { + var txId = o.txId, + fail = true, + response, + result, + resultDetail, + errorType, + message; + + if (isUndefined(metaData)) { + // this will happen if the request was aborted before it was + // sent + return; + } + + response = { + data: o.data + }; + + response.cb = metaData.cb; + // TODO: replace with a "wasSuccessful()" call. Need to support + // 304 etc. + if (o.status === 200 || o.status === 201) { + response.status = OK; + response.result = OK; + result = OK; + fail = false; + } else { + response.status = ERROR; + response.result = ERROR; + if (o.status === 400) { + errorType = E_CRUMB; + message = 'Invalid crumb.'; + resultDetail = E_RESULT_BADCRUMB; + result = ERROR; + + if (!window.navigator.cookieEnabled || + badcookie === 'badcookie') { + errorType = E_BROWSER; + resultDetail = E_RESULT_NOCOOKIES; + message = 'Cookies are disabled'; + } + + _errorReporter.error(errorType, message); + } + } + + this.fire('responseProcessed', { + type: 'responseProcessed', + txId: txId, + response: response, + method: (fail ? 'failure' : 'success'), + result: result, + resultDetail: resultDetail + }, NAME); + }, + + + createResponseObject: function(response, platform) { + // Y.log('Building response object', 'debug', NAME); + + if (response.data && response.data.responseText) { + // this will only happen for webservice responses...sure... + // Y.log('This looks like a proxied web service request,' + + // ' passing to WS formatter', 'debug', NAME); + return _createWebServiceResponseObject(response); + } else { + // support a wrong implementation in old daliTransport + // porting the mistake forward. + if (response.data) { + if (response.data.mods) { + // this is for backwards compatibility + response.mods = response.data.mods; + // this is the correct format + response.mod = response.mods[0]; + delete response.data.mods; + } + + if (response.data.html) { + response.html = response.data.html; + delete response.data.html; + } + + if (response.data.res) { + response.res = response.data.res; + delete response.data.res; + } + } + + response = _responseFormatter.formatResponse(response); + // no op. + return response; + } + } + }; + return new Y.Dali.Bean(inst); + }; + + ResponseProcessor.NAME = NAME; + Y.Dali.beanRegistry.registerBean(NAME, ResponseProcessor); -}, '1.6.3', {requires:['dali-bean', 'breg']}); +}, '1.6.3', {requires: [ + 'dali-bean', + 'breg' +]});
    @@ -231,9 +274,9 @@

    ActionContext  0.1.0

    diff --git a/docs/api/rest.common.js.html b/docs/api/rest.common.js.html index 3bf680099..47427aaaa 100644 --- a/docs/api/rest.common.js.html +++ b/docs/api/rest.common.js.html @@ -2,23 +2,23 @@ - API: ActionContextAddon rest.common.js (YUI Library) + Mojito API: MojitoClient rest.common.js ( - - + + - - + +
    -

    mojito

    -

    ActionContextAddon  0.1.0

    +

    mojito

    +

    MojitoClient  0.3.0

    mojito - > ActionContextAddon + > MojitoClient > rest.common.js (source view) @@ -48,25 +48,56 @@

    ActionContextAddon  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     /**
      * Common Library
      * @module CommonLibs
      */
    -/**
    - * @submodule CommonLibs
    - */
     YUI.add('mojito-rest-lib', function(Y, NAME) {
     
         Y.namespace('mojito.lib');
     
         /**
    -     * The Rest module for Mojito provides an easy way to make RESTful calls to URLs
    -     * without messing about with Y.io.
    +     * @private
    +     */
    +    function ResponseObject(resp) {
    +        this._resp = resp;
    +    }
    +
    +
    +    ResponseObject.prototype = {
    +        getStatusCode: function() {
    +            return this._resp.status;
    +        },
    +        getStatusMessage: function() {
    +            return this._resp.statusText;
    +        },
    +        getHeader: function() {
    +            return this._resp.getResponseHeader.apply(this._resp, arguments);
    +        },
    +        getHeaders: function() {
    +            return this._resp.getAllResponseHeaders();
    +        },
    +        getBody: function() {
    +            return this._resp.responseText;
    +        }
    +    };
    +
    +
    +    /**
    +     * The Rest module for Mojito provides an easy way to make RESTful calls to
    +     * URLs without messing about with Y.io.
          * @class REST
          * @namespace Y.mojito.lib
    -     * @static
          */
         Y.mojito.lib.REST = {
     
    @@ -74,7 +105,8 @@ 

    ActionContextAddon  0.1.0

    * @private */ _doRequest: function(method, url, params, config, callback) { - // TODO: [bug 4416153] Figure out why 'params' values are attaching themselves to headers! + // TODO: [Issue 72] Figure out why 'params' values are attaching + // themselves to headers! var ioConfig = { method: method, data: params, @@ -97,98 +129,76 @@

    ActionContextAddon  0.1.0

    Y.io(url, ioConfig); }, + /** * Makes a RESTful GET request to specified URL - * @method GET - * @param {String} url RESTful URL to hit - * @param {Object} params parameters to add to the request - * @param {Object} config may contain 'headers' or 'timeout' values - * @param {Function} callback called with response or error + * @param {String} url RESTful URL to hit. + * @param {Object} params parameters to add to the request. + * @param {Object} config may contain 'headers' or 'timeout' values. + * @param {Function} callback called with response or error. */ GET: function() { var args = ['GET'].concat(Array.prototype.slice.call(arguments)); this._doRequest.apply(this, args); }, + /** * Makes a RESTful POST request to specified URL - * @method POST - * @param {String} url RESTful URL to hit - * @param {Object} params parameters to add to the request - * @param {Object} config may contain 'headers' or 'timeout' values - * @param {Function} callback called with response or error + * @param {String} url RESTful URL to hit. + * @param {Object} params parameters to add to the request. + * @param {Object} config may contain 'headers' or 'timeout' values. + * @param {Function} callback called with response or error. */ POST: function() { var args = ['POST'].concat(Array.prototype.slice.call(arguments)); this._doRequest.apply(this, args); }, + /** * Makes a RESTful PUT request to specified URL - * @method PUT - * @param {String} url RESTful URL to hit - * @param {Object} params parameters to add to the request - * @param {Object} config may contain 'headers' or 'timeout' values - * @param {Function} callback called with response or error + * @param {String} url RESTful URL to hit. + * @param {Object} params parameters to add to the request. + * @param {Object} config may contain 'headers' or 'timeout' values. + * @param {Function} callback called with response or error. */ PUT: function() { var args = ['PUT'].concat(Array.prototype.slice.call(arguments)); this._doRequest.apply(this, args); }, + /** * Makes a RESTful DELETE request to specified URL - * @method DELETE - * @param {String} url RESTful URL to hit - * @param {Object} params parameters to add to the request - * @param {Object} config may contain 'headers' or 'timeout' values - * @param {Function} callback called with response or error + * @param {String} url RESTful URL to hit. + * @param {Object} params parameters to add to the request. + * @param {Object} config may contain 'headers' or 'timeout' values. + * @param {Function} callback called with response or error. */ DELETE: function() { var args = ['DELETE'].concat(Array.prototype.slice.call(arguments)); this._doRequest.apply(this, args); }, + /** * Makes a RESTful HEAD request to specified URL - * @method HEAD - * @param {String} url RESTful URL to hit - * @param {Object} params parameters to add to the request - * @param {Object} config may contain 'headers' or 'timeout' values - * @param {Function} callback called with response or error + * @param {String} url RESTful URL to hit. + * @param {Object} params parameters to add to the request. + * @param {Object} config may contain 'headers' or 'timeout' values. + * @param {Function} callback called with response or error. */ HEAD: function() { var args = ['HEAD'].concat(Array.prototype.slice.call(arguments)); this._doRequest.apply(this, args); } - - }; - - /** - * @private - */ - function ResponseObject(resp) { - this._resp = resp; - } - ResponseObject.prototype = { - getStatusCode: function() { - return this._resp.status; - }, - getStatusMessage: function() { - return this._resp.statusText; - }, - getHeader: function() { - return this._resp.getResponseHeader.apply(this, arguments); - }, - getHeaders: function() { - return this._resp.getResponseHeaders(); - }, - getBody: function() { - return this._resp.responseText; - } }; -}, '0.1.0', {requires: ['io', 'mojito']}); +}, '0.3.0', {requires: [ + 'io', + 'mojito' +]});
    @@ -200,9 +210,9 @@

    ActionContextAddon  0.1.0

    Modules

    @@ -210,13 +220,8 @@

    Modules

    @@ -224,13 +229,13 @@

    Classes

    @@ -249,8 +254,7 @@

    Files

    diff --git a/docs/api/route-maker.common.js.html b/docs/api/route-maker.common.js.html index 1db83af81..9d367eeac 100644 --- a/docs/api/route-maker.common.js.html +++ b/docs/api/route-maker.common.js.html @@ -2,23 +2,23 @@ - API: MojitoClient route-maker.common.js (YUI Library) + Mojito API: CommonLibs route-maker.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoClient  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > MojitoClient + > CommonLibs > route-maker.common.js (source view) @@ -48,95 +48,308 @@

    MojitoClient  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, regexp: true, nomen:true*/
    +/*global YUI*/
    +
    +
     YUI.add('mojito-route-maker', function(Y, NAME) {
     
    +    var doCallReplacement,
    +        copy;
    +
    +
    +    function wild(it) {
    +        // if {it}, then it is a wildcard
    +        if (it.indexOf('{') === 0) {
    +            // so return the true value without the {}
    +            return it.substring(1, it.length - 1);
    +        }
    +    }
    +
    +
    +    function resolveParams(route, params) {
    +        // console.log('============= resolving params for route ' +
    +        //     route.name);
    +        // console.log(params);
    +        // console.log('requires: ' + JSON.stringify(route.requires));
    +        var tester = [];
    +
    +        // we don't need to do anything if this route requires no params
    +        if (Y.Object.size(route.requires) === 0) {
    +            return route;
    +        }
    +
    +        Y.Object.each(params, function(pval, pname) {
    +            if (route.requires && route.requires[pname]) {
    +                tester.push(pname + '=' + pval);
    +            }
    +        });
    +
    +        if (tester.length) {
    +            tester.sort();
    +            if (new RegExp(route.int_match).test(tester.join('&'))) {
    +                Y.Object.each(params, function(pval, pname) {
    +                    route.query[pname] = pval;
    +                });
    +                return route;
    +            }
    +        }
    +    }
    +
    +
    +    function buildRoute(name, route) {
    +
    +        var i,
    +            verbObj,
    +            path,
    +            matches,
    +            build,
    +            segment,
    +            key;
    +
    +        if (!route.name) {
    +            route.name = name;
    +        }
    +        if (!route.verbs) {
    +            route.verbs = ['GET'];
    +        }
    +
    +        // Checking route.verbs is changed from an array to an object by the
    +        // building process, so routes that have already been computed are
    +        // not recomputed.
    +
    +        if (route.verbs.length && route.path && route.call) {
    +            // FUTURE: [Issue 73] allow object params, not just string
    +            if (!route.params) {
    +                route.params = '';
    +            }
    +            if (!route.regex) {
    +                route.regex = {};
    +            }
    +            if (!route.query) {
    +                route.query = {};
    +            }
    +
    +            /*
    +             * Here we convert the verb array to a map for easy use later on
    +             **/
    +            verbObj = {};
    +            for (i in route.verbs) {
    +                if (route.verbs.hasOwnProperty(i)) {
    +                    verbObj[route.verbs[i].toUpperCase()] = true;
    +                }
    +            }
    +            route.verbs = verbObj;
    +
    +            path = route.path.split('/');
    +
    +            /*
    +             * Here we build the matching regex for external URI's
    +             */
    +            for (segment in path) {
    +                if (path.hasOwnProperty(segment)) {
    +                    if (path[segment][0] === ':') {
    +                        key = path[segment].substr(1);
    +                        route.query[key] = '';
    +                        path[segment] = route.regex[key] ?
    +                                '(' + route.regex[key] + ')' :
    +                                '([^\/]+)';
    +                    }
    +
    +                    if (path[segment][0] === '*') {
    +                        path[segment] = '(.*)';
    +                    }
    +                }
    +            }
    +
    +            /*
    +             * Here we build the matching regex for internal URI's
    +             */
    +            route.requires = {};
    +            matches = route.path.match(/:([^\/]+)/g);
    +            for (i in matches) {
    +                if (matches.hasOwnProperty(i)) {
    +                    route.requires[matches[i].substr(1)] = '[^&]+';
    +                }
    +            }
    +            for (i in route.regex) {
    +                if (route.regex.hasOwnProperty(i)) {
    +                    route.requires[i] = route.regex[i];
    +                }
    +            }
    +
    +            route.params = Y.QueryString.parse(route.params);
    +
    +            build = [];
    +            for (i in route.requires) {
    +                if (route.requires.hasOwnProperty(i)) {
    +                    build.push(i + '=' + route.requires[i]);
    +                }
    +            }
    +            build.sort();
    +
    +            /*
    +             * We are done so lets store the regex's for the route.
    +             */
    +            // TODO: [Issue 74] These Regexes are recreated on
    +            // every request because they need to be serialized and sent to the
    +            // client, need to figure out a way to prevent that
    +            route.ext_match = '^' + path.join('\/') + '$';
    +            route.int_match = '^' + build.join('&') + '$';
    +        }
    +
    +        return route;
    +    }
    +
    +
    +    doCallReplacement = function(route, uri) {
    +        var uriParts = uri.substr(1).split('\/'),
    +            pathParts = route.path.substr(1).split('\/'),
    +            template = {},
    +            cnt = 0;
    +
    +        pathParts.forEach(function(pathPart) {
    +            var key,
    +                val,
    +                regex;
    +
    +            // process only those keyed by ':'
    +            if (pathPart.indexOf(':') === 0) {
    +                key = pathPart.substr(1);
    +                val = uriParts[cnt];
    +                template[key] = val;
    +                regex = new RegExp('{' + key + '}', 'g');
    +                if (regex.test(route.call)) {
    +                    route.call = route.call.replace(regex, template[key]);
    +                } else {
    +                    route.params[key] = val;
    +                }
    +            }
    +            cnt += 1;
    +        });
    +        return route;
    +    };
    +
    +
    +    copy = function(obj) {
    +        var temp = null, key = '';
    +        if (!obj || typeof obj !== 'object') {
    +            return obj;
    +        }
    +        temp = new obj.constructor();
    +        for (key in obj) {
    +            if (obj.hasOwnProperty(key)) {
    +                temp[key] = copy(obj[key]);
    +            }
    +        }
    +        return temp;
    +    };
    +
    +
         /*
    -     * The route maker for reverse URL lookup
    -     * @class RouteMaker
    +     * The route maker for reverse URL lookup.
    +     * @class Maker
          * @namespace Y.mojito
          * @param {Object} routes key value store of all routes in the system
          */
         function Maker(routes) {
             var name;
             this._routes = {};
    -        // TODO 2011-06-20: [bug 4647729] Cache these computed routes so we don't have to do this on each request
    +        // TODO: [Issue 75] Cache these computed routes so we
    +        // don't have to do this on each request.
             for (name in routes) {
                 if (routes.hasOwnProperty(name)) {
                     this._routes[name] = buildRoute(name, routes[name]);
                 }
             }
         }
    -    
    +
    +
         Maker.prototype = {
     
             /*
    -         * generates a URL from a route query
    -         * @method make
    +         * Generates a URL from a route query
              * @param {String} query string to convert to a URL
              * @param {String} verb http method
              */
             make: function(query, verb) {
    -//            Y.log('make(' + query + ', ' + verb + ')', 'debug', NAME);
    +            // Y.log('make(' + query + ', ' + verb + ')', 'debug', NAME);
    +
    +            var parts = query.split('?'),
    +                call = parts[0],
    +                params = {},
    +                route,
    +                uri;
    +
    +            // TODO: don't assign to a parameter.
                 verb = verb || 'GET';
     
    -            var parts = query.split('?');
    -            var call = parts[0];
    -            var params = {};
                 if (parts[1]) {
    -                 params = Y.QueryString.parse(parts[1]);
    +                params = Y.QueryString.parse(parts[1]);
                 }
    -            var route = this._matchToExternal(call, params, verb, this._routes);
    +            route = this._matchToExternal(call, params, verb, this._routes);
     
                 if (!route) {
    -                throw new Error("No route match found for '" + query + "' (" + verb + ")");
    +                throw new Error(
    +                    "No route match found for '" + query + "' (" + verb + ')'
    +                );
                 }
     
    -            var uri = route.path;
    +            uri = route.path;
     
                 Y.Object.each(route.query, function(v, k) {
                     uri = uri.replace(':' + k, v);
                     delete params[k];
                 });
     
    -            if (! Y.Object.isEmpty(params)) {
    +            if (!Y.Object.isEmpty(params)) {
                     uri += '?' + Y.QueryString.stringify(params);
                 }
     
                 return uri;
             },
    -        
    +
    +
             /**
              * Finds a route for a given method+URL
    -         *
    -         * @method find
    -         * @param url {string} the URL to find a route for
    -         * @param verb {string} the HTTP method
    -         **/
    +         * @param {string} url the URL to find a route for.
    +         * @param {string} verb the HTTP method.
    +         */
             find: function(uri, verb) {
    -    //        logger.log('[UriRouter] find( ' + uri + ', ' + verb + ' )');
    +            // logger.log('[UriRouter] find( ' + uri + ', ' + verb + ' )');
     
    +            var route,
    +                match,
    +                ret,
    +                i,
    +                id;
    +
    +            // TODO: don't assign to parameter.
                 verb = verb || 'GET';
     
    -            var route = this._matchToInternal(uri, verb, this._routes);
    +            route = this._matchToInternal(uri, verb, this._routes);
                 if (!route) {
                     return null;
                 }
     
    -    //        logger.log('[UriRouter] found route: ' + JSON.stringify(route));
    +            // logger.log('[UriRouter] found route: ' + JSON.stringify(route));
     
    -            var match = copy(route);
    +            match = copy(route);
     
                 // Add the extracted URI params to the query obj
    -            var ret = new RegExp(route.ext_match).exec(uri),
    -                i = 1,
    -                id;
    +            ret = new RegExp(route.ext_match).exec(uri);
    +            i = 1;
     
                 for (id in match.query) {
                     if (match.query.hasOwnProperty(id)) {
                         match.query[id] = ret[i];
    -                    i++;
    +                    i += 1;
                     }
                 }
     
    @@ -147,64 +360,75 @@ 

    MojitoClient  0.1.0

    } } - // logger.log('[UriRouter] returning route: ' + JSON.stringify(match)); return match; }, + /** * For optimization. Call this to get the computed routes that can be * passed to the constructor to avoid recomputing the routes. - * @return {object} computed routes + * @return {object} computed routes. */ getComputedRoutes: function() { return this._routes; }, - + + /** * Returns a matching route for the given URI - * - * @param string uri - * @param string verb + * @param {string} uri The uri to find a route for. + * @param {string} verb. The HTTP verb for the route. * @private - **/ - // TODO RIC 2011-06-20: Change function name + */ _matchToInternal: function(uri, verb, routes) { var name; + + // TODO: don't assign to a parameter. if (!verb) { verb = 'GET'; } verb = verb.toUpperCase(); - // logger.log('[UriRouter] Start Matching ...'); + + // logger.log('[UriRouter] Start Matching ...'); for (name in routes) { if (routes.hasOwnProperty(name)) { - // logger.log('[UriRouter] testing ' + name); - // TODO 2011-06-20: [bug 4647732] See comment elsewhere about regexes being created... we need to stash these objects - // somewhere instead of creating them on every request - if (new RegExp(routes[name].ext_match).test(uri) - && routes[name].verbs - && routes[name].verbs.hasOwnProperty(verb)) { - - // TODO MATT 2011-06-20: [bug 4647732] Prevent more Regex creations for the love of god + // logger.log('[UriRouter] testing ' + name); + + // TODO: [Issue 74] See comment elsewhere + // about regexes being created... we need to stash these + // objects somewhere instead of creating them on every + // request + if (new RegExp(routes[name].ext_match).test(uri) && + routes[name].verbs && + routes[name].verbs.hasOwnProperty(verb)) { + + // TODO: [Issue 74] Prevent more Regex creations. return doCallReplacement(routes[name], uri); } - // logger.log('[UriRouter] ' + verb +' '+ uri +' '+ routes[name].ext_match); + // logger.log('[UriRouter] ' + verb + ' ' + uri + ' ' + + // routes[name].ext_match); } } - return false; }, + /* * @private - **/ + */ _matchToExternal: function(call, params, verb, routes) { - var match, callParts = call.split('.'), - callId = callParts[0], callAction = callParts[1]; + var match, + callParts = call.split('.'), + callId = callParts[0], + callAction = callParts[1]; Y.Object.some(routes, function(route) { - var routeCall, routeId, routeAction, - wildId, wildAction; + var routeCall, + routeId, + routeAction, + wildId, + wildAction; // it might be an exact match if (call === route.call && route.verbs[verb]) { @@ -238,203 +462,30 @@

    MojitoClient  0.1.0

    } // if action is wild, or action matches - if ((wildAction || ( callAction === routeAction)) - // if id is wild, or id matches - && ((wildId || ( callId === routeId))) - // and if the verb is correct - && route.verbs[verb]) { + if ((wildAction || (callAction === routeAction)) && + // and if id is wild, or id matches + ((wildId || (callId === routeId))) && + // and if the verb is correct + route.verbs[verb]) { // then we can try a param match match = resolveParams(route, params); if (match) { return true; } - } - - }); - return match; } - }; - function wild(it) { - // if {it}, then it is a wildcard - if (it.indexOf('{') === 0) { - // so return the tru value without the {} - return it.substring(1, it.length - 1); - } - } - - function resolveParams(route, params) { -// console.log('============= resolving params for route ' + route.name); -// console.log(params); -// console.log('requires: ' + JSON.stringify(route.requires)); - var tester = []; - - // we don't need to do anything if this route requires no params - if (Y.Object.size(route.requires) === 0) { - return route; - } - - Y.Object.each(params, function(pval, pname) { - if (route.requires && route.requires[pname]) { - tester.push(pname + '=' + pval); - } - }); - - if (tester.length) { - tester.sort(); - if (new RegExp(route.int_match).test(tester.join('&'))) { - Y.Object.each(params, function(pval, pname) { - route.query[pname] = pval; - }); - return route; - } - } - } - - function buildRoute(name, route) - { - var i; - if (!route.name) { route.name = name; } - if (!route.verbs) { route.verbs = ['GET']; } - - // Checking route.verbs is changed from an array to an object by the - // building process, so routes that have already been computed are - // not recomputed. - - if (route.verbs.length && route.path && route.call) { - // FUTURE: [bug 4647735] allow object params, not just string - if (!route.params) { route.params = ''; } - if (!route.regex) { route.regex = {}; } - if (!route.query) { route.query = {}; } - - /* - * Here we convert the verb array to a map for easy use later on - **/ - var verbObj = {}; - for (i in route.verbs) - { - if (route.verbs.hasOwnProperty(i)) - { - verbObj[route.verbs[i].toUpperCase()] = true; - } - } - route.verbs = verbObj; - - var path = route.path.split('/'), - segment, - key; - - /* - * Here we build the matching regex for external URI's - */ - for (segment in path) - { - if (path.hasOwnProperty(segment)) - { - if (path[segment][0] === ':') - { - key = path[segment].substr(1); - - route.query[key] = ''; - - path[segment] = route.regex[key] ? '(' + route.regex[key] + ')': '([^\/]+)'; - } - - if (path[segment][0] === '*') - { - path[segment] = '(.*)'; - } - } - } - - /* - * Here we build the matching regex for internal URI's - */ - route.requires = {}; - var matches = route.path.match(/:([^\/]+)/g); - for (i in matches) - { - if (matches.hasOwnProperty(i)) - { - route.requires[matches[i].substr(1)] = '[^&]+'; - } - } - for (i in route.regex) - { - if (route.regex.hasOwnProperty(i)) { - route.requires[i] = route.regex[i]; - } - } - - route.params = Y.QueryString.parse(route.params); - - var build = []; - for (i in route.requires) - { - if (route.requires.hasOwnProperty(i)) - { - build.push(i + '=' + route.requires[i]); - } - } - build.sort(); - - /* - * We are done so lets store the regex's for the route. - */ - // TODO 2011-06-20: [bug 4647732] These Regexes are recreated on every request because they need to be - // serialized and sent to the client, need to figure out a way to prevent that - route.ext_match = '^' + path.join('\/') + '$'; - route.int_match = '^' + build.join('&') + '$'; - } - - return route; - } - - var doCallReplacement = function(route, uri) { - var uriParts = uri.substr(1).split('\/'), - pathParts = route.path.substr(1).split('\/'), - template = {}, - cnt = 0; - - pathParts.forEach(function(pathPart) { - var key, val, regex; - // process only those keyed by ':' - if (pathPart.indexOf(':') === 0) { - key = pathPart.substr(1); - val = uriParts[cnt]; - template[key] = val; - regex = new RegExp("{" + key + "}", 'g'); - if (regex.test(route.call)) { - route.call = route.call.replace(regex, template[key]); - } else { - route.params[key] = val; - } - } - cnt++; - }); - return route; - }; - - var copy = function(obj) { - var temp = null, key = ''; - if (!obj || typeof(obj) !== 'object') { return obj; } - temp = new obj.constructor(); - for (key in obj) { - if (obj.hasOwnProperty(key)) { - temp[key] = copy(obj[key]); - } - } - return temp; - }; - Y.mojito.RouteMaker = Maker; - -}, '0.1.0', {requires: ['querystring-stringify-simple', 'querystring-parse', 'mojito-util']}); + +}, '0.3.0', {requires: [ + 'querystring-stringify-simple', + 'querystring-parse', + 'mojito-util' +]});
    @@ -447,8 +498,8 @@

    Modules

    @@ -456,8 +507,7 @@

    Modules

    @@ -465,16 +515,25 @@

    Classes

    diff --git a/docs/api/server-log.js.html b/docs/api/server-log.js.html index 9e0843469..64fbc7735 100644 --- a/docs/api/server-log.js.html +++ b/docs/api/server-log.js.html @@ -2,21 +2,21 @@ - API: MojitoServer server-log.js (YUI Library) + Mojito API: MojitoServer server-log.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    MojitoServer  0.3.0

    mojito > MojitoServer @@ -48,28 +48,42 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
     
    -// TODO: [bug 4647494] SIMPLIFY
     
    -// TODO: [bug 4647497] allow these options to be on config.json at the framework level
    -var LOG_LEVEL = 'debug';
    -var YUI_LOGS = true;
    -var blocking = process.binding('stdio').isStdoutBlocking();
    +/*jslint anon:true, sloppy:true*/
    +
    +
    +// TODO: [Issue 70] SIMPLIFY.
    +
    +// TODO: [Issue 97] allow options to be on config.json at the framework
    +// level.
    +var tty = require('tty'),
    +    LOG_LEVEL = 'debug',
    +    YUI_LOGS = true,
    +    isatty = tty.isatty(1) && tty.isatty(2),
    +    tests = {
    +        INFO: /INFO$/,
    +        DEBUG: /DEBUG$/,
    +        WARN: /WARN$/,
    +        ERROR: /ERROR$/
    +    },
    +    writer,
    +    colored,
    +    bland,
    +    formatter,
    +    options;
     
    -var tests = {
    -    INFO: /INFO$/,
    -    DEBUG: /DEBUG$/,
    -    WARN: /WARN$/,
    -    ERROR: /ERROR$/
    -};
     
    -var writer = function(data) {
    -    var i=0;
    +writer = function(data) {
    +    var i;
    +
         if (typeof data === 'object' && data.length) {
             // this is a flush of many logs
    -        for (; i<data.length; i++) {
    +        for (i = 0; i < data.length; i += 1) {
                 console.log(data[i]);
             }
         } else {
    @@ -77,9 +91,12 @@ 

    MojitoServer  0.1.0

    } }; -var colored = function(msg, lvl, source, timestamp, opts) { - var ts = opts.timestamp ? ('('+timestamp+') ').grey : '', - code = '', stack = ''; + +colored = function(msg, lvl, source, timestamp, opts) { + var ts = opts.timestamp ? ('(' + timestamp + ') ').grey : '', + code = '', + stack = ''; + if (msg === undefined) { msg = 'undefined'; } else if (msg === null) { @@ -118,9 +135,13 @@

    MojitoServer  0.1.0

    } return lvl + ts + source + msg; }; -var bland = function(msg, lvl, source, timestamp, opts) { - var ts = opts.timestamp ? ('('+timestamp+') ') : '', - code = '', stack = ''; + + +bland = function(msg, lvl, source, timestamp, opts) { + var ts = opts.timestamp ? ('(' + timestamp + ') ') : '', + code = '', + stack = ''; + if (msg instanceof Error) { if (msg.code) { code = ' ' + msg.code; @@ -141,12 +162,15 @@

    MojitoServer  0.1.0

    return lvl + ts + source + msg; }; -var formatter = function (msg, lvl, source, timestamp, opts) { - var myFormatter = (!blocking && ''.red) ? colored : bland; + +formatter = function(msg, lvl, source, timestamp, opts) { + var myFormatter = (isatty && ''.red) ? colored : bland; + return myFormatter(msg, lvl, source, timestamp, opts); }; -var options = { + +options = { writer: writer, formatter: formatter, timestamp: true, @@ -154,7 +178,7 @@

    MojitoServer  0.1.0

    defaultLevel: 'debug', yui: YUI_LOGS, order: [ - 'DEBUG','MOJITO','INFO','WARN','ERROR','NONE' + 'DEBUG', 'MOJITO', 'INFO', 'WARN', 'ERROR', 'NONE' ], filter: { DEBUG: true, @@ -166,6 +190,8 @@

    MojitoServer  0.1.0

    } }; +/** + */ module.exports = { options: options }; @@ -190,16 +216,9 @@

    Modules

    @@ -208,27 +227,11 @@

    Classes

    Files

    --> @@ -246,7 +249,7 @@

    Files

    diff --git a/docs/api/store-provider.server.js.html b/docs/api/store-provider.server.js.html index 88a8a8b9b..80829e9d8 100644 --- a/docs/api/store-provider.server.js.html +++ b/docs/api/store-provider.server.js.html @@ -2,23 +2,23 @@ - API: MojitoServer store-provider.server.js (YUI Library) + Mojito API: CommonLibs store-provider.server.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > MojitoServer + > CommonLibs > store-provider.server.js (source view) @@ -48,11 +48,16 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    - */
    -/**
    - * @submodule ActionContextAddon
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true*/
    +/*global YUI*/
    +
    +
     YUI.add('dali-store-provider-addon', function(Y, NAME) {
     
         function Addon(command, adapter, ac) {
    @@ -62,6 +67,7 @@ 

    MojitoServer  0.1.0

    this.dispatch = ac.dispatch; } + Addon.prototype = { namespace: 'store', @@ -69,15 +75,17 @@

    MojitoServer  0.1.0

    /** * Declaration of store requirement. * @private - * @param rs {ResourceStore} + * @param {ResourceStore} rs The resource store. */ setStore: function(rs) { this.rs = rs; if (rs) { - Y.log('Initialized and activated with Resource Store', 'info', NAME); + Y.log('Initialized and activated with Resource Store', 'info', + NAME); } }, + getStore: function() { return this.rs; } @@ -85,7 +93,7 @@

    MojitoServer  0.1.0

    Y.mojito.addons.ac.store = Addon; -}, '0.1.0'); +}, '0.3.0');
    @@ -98,25 +106,16 @@

    Modules

    @@ -124,28 +123,27 @@

    Classes

    --> @@ -163,7 +161,7 @@

    Files

    diff --git a/docs/api/store.client.js.html b/docs/api/store.client.js.html index 21e01ef82..37764b34e 100644 --- a/docs/api/store.client.js.html +++ b/docs/api/store.client.js.html @@ -2,21 +2,21 @@ - API: CommonLibs store.client.js (YUI Library) + Mojito API: CommonLibs store.client.js ( - - + + - - + +
    -

    mojito

    -

    CommonLibs  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito > CommonLibs @@ -48,8 +48,16 @@

    CommonLibs  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     YUI.add('mojito-client-store', function(Y, NAME) {
     
         var CACHE,
    @@ -57,115 +65,57 @@ 

    CommonLibs  0.1.0

    queue, flushQueue, retrieveFile, - isCompiled; + isCompiled, + trimSlash; - // TODO 2011-06-16: use YUI.namespace()? use generic caching instead? - if(!YUI._mojito){ + // TODO: use YUI.namespace()? use generic caching instead? + if (!YUI._mojito) { YUI._mojito = {}; } - if(!YUI._mojito._cache){ + if (!YUI._mojito._cache) { YUI._mojito._cache = {}; } - if(!YUI._mojito._cache.store){ + if (!YUI._mojito._cache.store) { YUI._mojito._cache.store = {}; } CACHE = YUI._mojito._cache.store; - function ClientStore(config) { - this.appConfig = config.appConfig; - this.routes = config.routes; - // TODO: The value below should be retrieved from the appConfig - this.staticPrefix = '/static'; - - // This is read from the "application.json" file. - // This value could be an empty string so we have to do a real check - if(config.appConfig && config.appConfig.staticHandling && typeof config.appConfig.staticHandling.prefix !== 'undefined'){ - this.staticPrefix = config.appConfig.staticHandling.prefix; - } - - // Now we do some bad shit for iOS - if(typeof window !== 'undefined'){ - this.staticPrefix = Y.mojito.util.iOSUrl(this.staticPrefix); - } - } - - ClientStore.prototype = { - - /* - * TODO REVIEW [bug 4647265] - */ - getSpec: function(env, id, context, callback){ - - var parts = id.split(':'), - ns = parts[0].replace(/\./g, '_'), - specName = parts[1] || 'default', - url = this.staticPrefix + '/' + parts[0] + '/specs/' + specName + '.json'; - - // use the compiled version if there was one built - if (isCompiled(ns, specName)) { - CACHE[url] = YUI._mojito._cache.compiled[ns].specs[specName]; - callback(null, CACHE[url]); - return; - } - - retrieveFile(url, callback); - }, - - /* - * TODO REVIEW [bug 4647330] - */ - getType: function(env, type, context, callback){ - - var url = this.staticPrefix+'/'+type+'/definition.json'; - - retrieveFile(url, callback); - }, - - /* - * TODO: [bug 4649703] - */ - getAppConfig: function(context, name){ - return this.appConfig; - }, - - /* - * TODO: [bug 4649703] - */ - getRoutes: function(){ - return this.routes; - } - }; queue = function(url, cb) { - if (! QUEUED[url]) { + if (!QUEUED[url]) { QUEUED[url] = []; } QUEUED[url].push(cb); }; + flushQueue = function(url, err, data) { - var i=0, q; + var i, + q; + if (QUEUED[url]) { - // copies cb array out into local var to prevent further flushes from - // looping over it again - q = QUEUED[url].splice(0); + // Copy cb array out into local var to prevent further flushes from + // looping over it again. (User-provided callbacks can take a long + // time to run, and while they are more callbacks can get queued.) + q = QUEUED[url].splice(0, QUEUED[url].length); delete QUEUED[url]; - for (i=0; i<q.length; i++) { + for (i = 0; i < q.length; i += 1) { q[i](err, data); } } }; + retrieveFile = function(url, callback) { // iOS has a bug that returns "failure" on "success". - var onComplete = function(id, obj){ + var onComplete = function(id, obj) { CACHE[url] = {}; - try{ + try { CACHE[url] = JSON.parse(obj.responseText); - } catch(err) { + } catch (err) { flushQueue(url, err); return; } @@ -173,12 +123,12 @@

    CommonLibs  0.1.0

    }; // use the cache first - if(CACHE[url]){ + if (CACHE[url]) { callback(null, CACHE[url]); return; } - if (! QUEUED[url]) { + if (!QUEUED[url]) { Y.io(url, { headers: { 'x-mojito-header': 'tunnel' @@ -191,16 +141,124 @@

    CommonLibs  0.1.0

    queue(url, callback); }; + isCompiled = function(ns, specName) { return YUI._mojito._cache.compiled && - YUI._mojito._cache.compiled[ns] && - YUI._mojito._cache.compiled[ns].specs && - YUI._mojito._cache.compiled[ns].specs[specName]; + YUI._mojito._cache.compiled[ns] && + YUI._mojito._cache.compiled[ns].specs && + YUI._mojito._cache.compiled[ns].specs[specName]; + }; + + + trimSlash = function(str) { + if ('/' === str.charAt(str.length - 1)) { + return str.substring(0, str.length - 1); + } + return str; + }; + + + function ClientStore(config) { + this.appConfig = config.appConfig; + this.routes = config.routes; + this.appConfig.pathToRoot = config.pathToRoot; + + // This value could be an empty string so we have to do a real check. + this.staticPrefix = '/static'; + if (this.appConfig && this.appConfig.staticHandling && + this.appConfig.staticHandling.hasOwnProperty('prefix')) { + this.staticPrefix = (this.appConfig.staticHandling.prefix ? '/' + + this.appConfig.staticHandling.prefix : ''); + } + + // Now we do some bad stuff for iOS + if (typeof window !== 'undefined') { + this.staticPrefix = Y.mojito.util.iOSUrl(this.staticPrefix) + '/'; + } + + this.staticPrefix = trimSlash(this.staticPrefix); + } + + ClientStore.prototype = { + + /* + * TODO: REVIEW RE [Issue 76]. + */ + getSpec: function(env, id, context, callback) { + + var parts = id.split(':'), + typeName = parts[0], + specName = parts[1] || 'default', + ns = typeName.replace(/\./g, '_'), + url; + + // This should really have the tunnelPrefix. However, that + // complicates offline apps (from `mojito build html5app`). + // The mojito-handler-tunnel will be able to handle this URL + // just fine. + url = this.staticPrefix + '/' + typeName + '/specs/' + specName + + '.json'; + url += '?' + Y.QueryString.stringify(context); + + // this is mainly used by html5app + if (this.appConfig.pathToRoot) { + url = this.appConfig.pathToRoot + url; + } + + // use the compiled version if there was one built + if (isCompiled(ns, specName)) { + CACHE[url] = YUI._mojito._cache.compiled[ns].specs[specName]; + callback(null, CACHE[url]); + return; + } + + retrieveFile(url, callback); + }, + + + /* + * TODO: REVIEW RE [Issue 77] + */ + getType: function(env, type, context, callback) { + + // This should really have the tunnelPrefix. However, that + // complicates offline apps (from `mojito build html5app`). + // The mojito-handler-tunnel will be able to handle this URL + // just fine. + var url = this.staticPrefix + '/' + type + '/definition.json'; + url += '?' + Y.QueryString.stringify(context); + + // this is mainly used by html5app + if (this.appConfig.pathToRoot) { + url = this.appConfig.pathToRoot + url; + } + + retrieveFile(url, callback); + }, + + + /* + * TODO: REVIEW RE [Issue 78] + */ + getAppConfig: function(context, name) { + return this.appConfig; + }, + + + /* + * TODO: REVIEW RE [Issue 78] + */ + getRoutes: function() { + return this.routes; + } }; Y.mojito.ResourceStore = ClientStore; -}, '0.1.0', {requires: ['mojito-util']}); +}, '0.3.0', {requires: [ + 'mojito-util', + 'querystring-stringify-simple' +]});
    @@ -230,12 +288,27 @@

    Classes

    --> @@ -253,7 +326,7 @@

    Files

    diff --git a/docs/api/store.server.js.html b/docs/api/store.server.js.html index 26ab76e24..f714d8535 100644 --- a/docs/api/store.server.js.html +++ b/docs/api/store.server.js.html @@ -2,21 +2,21 @@ - API: MojitoServer store.server.js (YUI Library) + Mojito API: MojitoServer store.server.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    MojitoServer  0.3.0

    mojito > MojitoServer @@ -48,20 +48,99 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint
    +    anon:true, sloppy:true, regexp: true, continue: true, nomen:true, node:true
    +*/
    +
    +
    +var libfs = require('fs'),
    +    libpath = require('path'),
    +    libqs = require('querystring'),
    +    libvm = require('vm'),
    +    libglob = require('./glob'),
    +    libycb = require('./libs/ycb'),
    +
    +    isPositiveInt = /^[0-9]+$/,
    +    isSpaceOpencurly = / \{/g,
    +    isSpaceClosecurly = / \}/g,
    +    isNotAlphaNum = /[^a-zA-Z0-9]/,
    +
    +    // fallback logger
    +    // This is the logger that is used until setLogger() is called.
    +    logger = {
    +        log: function(msg, lvl, who) {
    +            var log = console.log;
    +
    +            if (lvl === 'warn' || lvl === 'error') {
    +                // console.warn provides unbuffered output and avoids message
    +                // truncation when process.exit() is called after logging
    +                log = console.warn;
    +            }
    +            log('[' + lvl + '] ' + who + ': ' + msg);
    +        }
    +    },
    +
    +    // nodejs-yui3 has global state about which modules are loaded. Use
    +    // multiple require()'d instances as a wall to prevent cross-contamination
    +    // when using loader for dependency calculations.
    +    utilYUI = require('yui3').YUI,
    +    serverYUI = require('yui3').YUI,
    +    clientYUI = require('yui3').YUI,
    +
    +    Y = utilYUI().useSync('intl'),
    +
    +    mojitoRoot = __dirname,
    +
    +    NAME = 'MojitoServer';
    +
    +// TODO: move string constants here.
    +
    +
    +// The Affinity object is to manage the use of the affinity string in
    +// filenames.  Some files have affinities that have multiple parts
    +// (e.g. "server-tests").
    +function Affinity(affinity) {
    +    this._init(affinity);
    +}
    +
    +
    +Affinity.prototype = {
    +    _init: function(aff) {
    +        var parts;
    +
    +        if (aff.indexOf('-') === -1) {
    +            this.affinity = aff;
    +        } else {
    +            parts = aff.split('-');
    +            this.affinity = parts[0];
    +            this.type = parts[1];
    +        }
    +    },
    +    toString: function() {
    +        return this.affinity;
    +    }
    +};
    +
    +
     /**
    - * A "resource" is the smallest-sized component in the mojito framework.
    + * The Resource Store manages information about the "resources" in a Mojito
    + * application.  These resources are things that have representation on the
    + * filesystem.
      *
    - * It has a representation on disk.
    - * Sometimes a resource will be fully represented by a single file.
    - * Sometimes multiple files together will comprise one resource.
    - * Sometimes multiple resources will be defined in one file.
    - * It is the job of the resource store to manage all this. 
    + * Each resource can have many different versions.  This is not talking about
    + * revisions, which is how the resource changes over time.  It is instead
    + * talking about how there can be a version of the resource just for iphones,
    + * one just for android, a fallback, etc.
      *
    - *
    - * RESOURCE TYPES
    - *   config      -- a piece of configuration, sometimes for another resource 
    + * There are various types of resources:
    + * <pre>
    + *   config      -- a piece of configuration, sometimes for another resource
      *   controller  -- the controller for a mojit
      *   model       -- a model for a mojit
      *   view        -- a view for a mojit
    @@ -69,18 +148,20 @@ 

    MojitoServer  0.1.0

    * action -- an action to augment the controller * asset -- an asset (css, js, image, etc) * addon -- an addon to the mojito system + * spec -- the configuration for a mojit instance * yui-lang -- a YUI3 language bundle * yui-module -- a YUI3 module (that isn't one of the above) + * </pre> * - * - * RESOURCE METADATA - * (not all resources will have all details) + * The metadata kept about each resource is "normalized" to the follow keys: + * (not all resources will have all keys) + * (some types will have additional keys) * (not all combinations of type:source are valid) * + * <pre> * - id * context-insensitive ID of the resource - * (type + 'app' + (details specific to type)) - * (type + 'mojit' + mojit-type + (details specific to type)) + * said another way, all versions of a resource have the same ID * * - type * see above @@ -93,8 +174,8 @@

    MojitoServer  0.1.0

    * the path on the filesystem * * - staticHandlerURL - * for resources that can be deployed by reference to the client * the URL that will cause the asset handler to serve the resource + * for resources that can be deployed by reference to the client * * - name * specific to type @@ -138,134 +219,87 @@

    MojitoServer  0.1.0

    * a list of YUI modules required by the module, * with transitive dependencies resolved * format: { yui-module-name: URL-to-load-yui-module } - * + * </pre> * - * - * @class ServerStore + * @module MojitoServer + * @class ResourceStore.server * @constructor - * @param root - * @private - */ - -var libfs = require('fs'), - libpath = require('path'), - libqs = require('querystring'), - libvm = require('vm'), - libglob = require('./glob'), - libycb = require('./libs/ycb'), - - isPositiveInt = /^[0-9]+$/, - isSpaceOpencurly = / \{/g, - isSpaceClosecurly = / \}/g, - - - // fallback logger - logger = { - log: function(msg, lvl, who) { - var log = console.log; - if (lvl === "warn" || lvl === "error") { - // console.warn provides unbuffered output and avoids message - // truncation when process.exit() is called after logging - log = console.warn; - } - log('['+lvl+'] '+who+': '+msg); - } - }, - - YUI = require('yui3').YUI, - - // re-requiring seems to be necessary if useSync() will be called on both. - // if removed and YUI used instead an error is thrown on page load - YUI2 = require('yui3').YUI, - - mojitoRoot = __dirname, - - NAME = 'MojitoServer'; - -// TODO 2011-06-16: move string constants here - - -function Affinity(affinity) { - this._init(affinity); -} -Affinity.prototype = { - _init: function(aff) { - var parts; - if (aff.indexOf('-') === -1) { - this.affinity = aff; - } else { - parts = aff.split('-'); - this.affinity = parts[0]; - this.type = parts[1]; - } - }, - toString: function() { - return this.affinity; - } -}; - -/* - * * root string - * directory of the application - * * libs object - * set of libraries to use - * - ycb: YCB library to use, if available - * - fs: filesystem library to use during unittesting - * + * @param root {string} directory where application is found + * @param libs {object} dependent libraries -- this param is mainly used + * during unit testing */ function ServerStore(root, libs) { //logger.log('ctor(' + root + ')'); this._root = root; - this._version = '0.1.0'; + this._version = '0.3.0'; this._shortRoot = libpath.basename(root); this._libs = libs || {}; - // no-context version of the appConfig - this._appConfigNC = null; - - // each of these is [resid][affinity].contexts - // [resid][affinity][ctx] = { parts } - // mojits have [type] prefixed + // the static version of the appConfig (application.json) + // It's "static" because it's determined at server-start time, and doesn't + // change after that. + this._appConfigStatic = null; + + // Each of these is a complex datastructure, the first key of which is the + // resource ID ("resid"). (For mojitMeta, the first key is the mojit type + // and the second key is resid.) + // Under resid the next key is the affinity ("client", "server", or + // "common".) + // Under affinity is a datastructure that tracks all versions of the resource. + // There is a special key "contexts" which lists all the contexts that the + // resource has been specialized for. "contexts" is an object. The key is a + // string that identifies the context, and the value is a partial context that + // describes the specialization. (An example might be "device=iphone" for + // the key and { device:'iphone' } for the value.) + // The rest of the keys are the context strings (as found in "contexts"), and + // the values are the metadata about the resource versions. + // [resid][affinity].contexts + // [resid][affinity][ctxKey] = { metadata } + // (These are mostly populated by the _preloadSetDest() method.) this._preload = { fwMeta: {}, appMeta: {}, mojitMeta: {} }; + + // These are similar to the _preload above, except the affinity has been resolved + // down for each environment ("client" or "server"). Also, the ctxKey has been + // moved above resid to optimize lookup during runtime. + this._fwMeta = {}; // [env][ctxKey][resid] = { parts } + this._appMeta = {}; // [env][ctxKey][resid] = { parts } + this._mojitMeta = {}; // [env][type][ctxKey][resid] = { parts } + this._mojitYuiRequired = {}; // [env][type][ctxKey] = [ YUI module names ] + this._mojitYuiSorted = {}; // [env][type][ctxKey] = [ YUI module names ] + this._mojitYuiSortedPaths = {}; // [env][type][ctxKey][module] = path + + this._jsonCache = {}; // fullpath: contents as JSON object + this._ycbCache = {}; // fullpath: context: YCB config object + this._staticURLs = {}; // url => fullpath this._dynamicURLs = {}; // url => dynamic content this._mojitAssetRoots = {}; // mojitType => URL prefix this._mojitLangs = {}; // mojitType => [en-US,en-GB,en] this._mojitPaths = {}; // mojitType => filesystem directory of mojit - this._fwMeta = {}; // [env][ctx][resid] = { parts } - this._appMeta = {}; // [env][ctx][resid] = { parts } - this._mojitMeta = {}; // [env][type][ctx][resid] = { parts } - this._mojitYuiRequired = {}; // [env][type][ctx] = [ list of YUI module names ] - this._mojitYuiSorted = {}; // [env][type][ctx] = [ list of YUI module names ] - this._mojitYuiSortedPaths = {}; // [env][type][ctx][module] = path - this._configCache = {}; // fullpath: content - this._ycbCache = {}; // fullpath: ycb config object - this._expandInstanceCache = { // [env][cacheKey] = instance client: {}, server: {} }; - this._Y = YUI2().useSync('intl'); - - // TODO 2011-06-16: bake this into the refactor + // TODO: bake this into the refactoring work. // this stuff is mainly so that we can send mocks during testing - if (! this._libs.fs) { + if (!this._libs.fs) { this._libs.fs = libfs; } - if (! this._libs.path) { + if (!this._libs.path) { this._libs.path = libpath; } - if (libycb && (! this._libs.ycb)) { + if (libycb && (!this._libs.ycb)) { this._libs.ycb = libycb; } } + ServerStore.prototype = { // =========================================== @@ -275,49 +309,56 @@

    MojitoServer  0.1.0

    /** * Preloads everything in the app, and as well pertinent parts of * the framework. - * @method preload - * @applicationEnvironment ?? - * @appConfig overrides for the app config - * @return {undefined} + * + * @param {object} appContext the base context for reading configuration. + * @param {object} appConfig overrides for the app config. + * @return {nothing} */ - preload: function(applicationEnvironment, appConfig) { + preload: function(appContext, appConfig) { //logger.log('preload()'); - var type, ctxKey, resid, res, n; + var type, + ctxKey, + resid, + res, + n; - if (! this._preload) { + if (!this._preload) { // we've already been preloaded // This situation mainly happens in the commandline scripts. return; } - this._fwConfig = this._readConfigJSON(libpath.join(mojitoRoot, 'config.json')); + this._fwConfig = this._readConfigJSON(libpath.join(mojitoRoot, + 'config.json')); + this._ycbDims = this._readYcbDimensions(); + this._validYCBDims = this._precalcValidYCBDimensions( + this._ycbDims[0].dimensions + ); + this._defaultYCBContext = appContext || {}; + + // need to read the statically configured appConfig now so that values + // are available during generation of the static URLs + this._appConfigStatic = this._readAppConfigStatic(); - // TODO: use applicationEnvironment while reading, so that env=x - // contextualization in the application.json takes effect - // need to read the non-context appConfig now so that values are available during - // generation of the static URLs - this._appConfigNC = this._readAppConfigNC(); - // generates URL's about each spec in application.json this._urlsForAppSpecs(); - // TODO: [bug 4647260] allow the environment to be overridden within the app config - this._appConfigNC.env = applicationEnvironment || 'dev'; - // merge app configuration overrides if (appConfig) { for (n in appConfig) { if (appConfig.hasOwnProperty(n)) { - logger.log('overriding application config value: ' + n, 'warn'); - this._appConfigNC[n] = appConfig[n]; + logger.log('overriding application config value: ' + n, + 'warn'); + this._appConfigStatic[n] = appConfig[n]; } } } - // generates metadata about each file + // generates metadata about each resource this._preloadMeta(); - - // takes the preloaded info and resolves affinity, etc + + // takes the preloaded info about each resource and resolves + // version priority (.server. more specific that .common. etc) this._cookdown(); // preread configs @@ -328,11 +369,12 @@

    MojitoServer  0.1.0

    } } - if ('precomputed' === this._appConfigNC.yui.dependencyCalculations) { - this._precalcYuiDependencies(); - } + // We need to run this function even for "ondemand", since it calculates + // additional implied dependencies, such as a binder on MojitoClient, + // or a controller on the view-engine needed to render its views. + this._precalcYuiDependencies(); - // binders are client-side-only constructs, yet we need to know about + // binders are client-side-only resources, yet we need to know about // them when talking about the 'server' environment for (type in this._mojitMeta.client) { if (this._mojitMeta.client.hasOwnProperty(type)) { @@ -341,12 +383,15 @@

    MojitoServer  0.1.0

    if (this._mojitMeta.client[type].hasOwnProperty(ctxKey)) { for (resid in this._mojitMeta.client[type][ctxKey]) { - if (this._mojitMeta.client[type][ctxKey].hasOwnProperty(resid)) { - res = this._mojitMeta.client[type][ctxKey][resid]; + if (this._mojitMeta.client[type][ctxKey]. + hasOwnProperty(resid)) { + res = this._mojitMeta.client[type + ][ctxKey][resid]; if (res.type !== 'binder') { continue; } - this._mojitMeta.server[type][ctxKey][resid] = res; + this._mojitMeta.server[type + ][ctxKey][resid] = res; } } } @@ -355,22 +400,36 @@

    MojitoServer  0.1.0

    } }, + + /** + * Sets the logger object. + * + * @param l {object} object containing a log(message,level,source) function + * @return {nothing} + */ setLogger: function(l) { logger = l; }, - /* - * TODO: RIC [bug 4647265] + + /** + * Returns, via callback, the fully expanded mojit instance specification. + * + * @param env {string} either "client" or "server" + * @param id {string} the ID of the spec to return + * @param context {object} the runtime context for the spec + * @param callback {function(err,spec)} callback used to return the results (or error) + * @return {nothing} results returned via the callback parameter */ - getSpec: function(env, id, context, callback){ + getSpec: function(env, id, context, callback) { - this.expandInstanceForEnv(env, {base: id}, context, function(err, obj){ - if(err){ + this.expandInstanceForEnv(env, {base: id}, context, function(err, obj) { + if (err) { callback(err); return; } - if(env === 'client' && obj){ + if (env === 'client' && obj) { delete obj.assets; } @@ -378,18 +437,26 @@

    MojitoServer  0.1.0

    }); }, - /* - * TODO: RIC [bug 4647330] + + /** + * Returns, via callback, the details of the mojit type. + * + * @param env {string} either "client" or "server" + * @param type {string} the mojit type + * @param context {object} the runtime context for the spec + * @param callback {function(err,spec)} callback used to return the results (or error) + * @return {nothing} results returned via the callback parameter */ - getType: function(env, type, context, callback){ + getType: function(env, type, context, callback) { - this.expandInstanceForEnv(env, {type: type}, context, function(err, obj){ - if(err){ + this.expandInstanceForEnv(env, {type: type}, context, function(err, + obj) { + if (err) { callback(err); return; } - if(env === 'client' && obj){ + if (env === 'client' && obj) { delete obj.assets; } @@ -400,77 +467,90 @@

    MojitoServer  0.1.0

    /** * This just calls expandInstanceForEnv() with `env` set to `server`. * - * @method expandInstance - * @param instance {map} partial instance to expand - * @param ctx {object} the request context - * @param cb {function(err,instance)} the callback to send the results to - * @return nothing. results passed back via the callback + * @param instance {map} Partial instance to expand. + * @param ctx {object} The request context. + * @param cb {function(err,instance)} callback used to return the results (or error) + * @return {nothing} results returned via the callback parameter */ expandInstance: function(instance, ctx, cb) { - return this.expandInstanceForEnv('server', instance, ctx, cb); + this.expandInstanceForEnv('server', instance, ctx, cb); + return; }, + /** - * This method takes a partial instance and expands it to all details needed to run the mojit. + * This method takes a partial instance and expands it to all details needed + * to run the mojit. * - * Only a `base` or `type` fields are required. You should only specify one. + * Only `base` or `type` fields are required. You should only specify one. * * <pre> * instance: { - * base: "", + * base: string * // specifies a "base" instance which this instance will extend - * // the value refers to a key of `specs` found in `application.json` - * type: "", + * // the value refers to a key of `specs` in `application.json` + * type: string * // specifies the mojit type * action: "", - * // specifies a default action if the instance isn't dispatched with a specific one - * config: {...}, + * // specifies a default action if the instance isn't dispatched + * // with a specific one. + * config: object * // the config for the mojit - * // this will be augmented (appropriately) with the mojit type defaults - * // found in the type's `defaults.json` - * appConfig: {...}, + * // this will be augmented (appropriately) with the mojit type + * // defaults found in the type's `defaults.json` + * appConfig: object * // the application config (appropriate for the context) * assetRoot: "", * // path to directory containing assets - * // the path will be a URL if `env` is `client` otherwise it's a filesystem path - * definition: "", + * // the path will be a URL if `env` is `client` otherwise it's a + * // filesystem path + * definition: object * // the body of the `defintion.json` for the mojit type - * defaults: "", + * defaults: object * // the body of the `defaults.json` for the mojit type * yui: { * // details for generating a YUI sandbox for this instance * config: { - * // configuration details for the YUI.GlobalConfig.groups (or an equivalent). - * // the module paths are given as `fullpath` and contain either a URL if `env' - * // is `client` or a filesystem path if `env` is `server` + * // configuration details for the YUI.GlobalConfig.groups (or + * // an equivalent). + * // The module paths are given as `fullpath` and contain + * // either a URL if `env' is `client` or a filesystem path if + * // `env` is `server` * }, * requires: [] * // list of YUI modules that this instance requires - * }, - * actions: [], + * } + * actions: array * // list of paths to the YUI modules containing actions - * controller: "", + * controller: string * // path to controller - * // the path will be a URL if `env` is `client` otherwise it's a filesystem path + * // the path will be a URL if `env` is `client` otherwise it's a + * // filesystem path * lang: * // path to YUI module of the language bundle - * // the path will be a URL if `env` is `client` otherwise it's a filesystem path - * models: {}, + * // the path will be a URL if `env` is `client` otherwise it's a + * // filesystem path + * models: object * // list of models used by the mojit type - * // the key is the model name, and the value is the path to the model file - * // the path will be a URL if `env` is `client` otherwise it's a filesystem path + * // the key is the model name, and the value is the path to the + * // model file + * // the path will be a URL if `env` is `client` otherwise it's a + * // filesystem path * views: { * // list of views in the mojit type - * // the key is the view name, and the value is details about the view + * // the key is the view name, and the value is details about the + * // view * view-name: { * "content-path": "", * // the path to use to load the body of the view - * // the path will be a URL if `env` is `client` otherwise it's a filesystem path + * // the path will be a URL if `env` is `client` otherwise + * // it's a filesystem path * "engine": "", * // which engine is used to render the view * "binder-path": "", * // the path to the binder - * // the path will be a URL if `env` is `client` otherwise it's a filesystem path + * // the path will be a URL if `env` is `client` otherwise + * // it's a filesystem path * "binder-module": "" * // the YUI module name of the binder * } @@ -478,18 +558,20 @@

    MojitoServer  0.1.0

    * } * </pre> * - * @method expandInstanceForEnv - * @param env {"client"|"server"} which environment to expand the instance for - * @param instance {map} partial instance to expand - * @param ctx {object} the request context - * @param cb {function(err,instance)} the callback to send the results to - * @return nothing. results passed back via the callback + * @param env {string} "client" or "server" + * @param instance {object} partial instance to expand + * @param ctx {object} the runtime context for the instance + * @param cb {function(err,instance)} callback used to return the results (or error) + * @return {nothing} results returned via the callback parameter */ expandInstanceForEnv: function(env, instance, ctx, cb) { - //logger.log('expandInstanceForEnv(' + env + ',' + (instance.id||'@'+instance.type) + ')'); + //logger.log('expandInstanceForEnv(' + env + ',' + + // (instance.id||'@'+instance.type) + ')'); var self = this, base, appConfig = this.getAppConfig(ctx, 'definition'), - cacheKey = JSON.stringify(instance) + JSON.stringify(ctx), + cacheKey = JSON.stringify(instance) + JSON.stringify( + this._getValidYCBContext(ctx) + ), cacheValue = this._expandInstanceCache[env][cacheKey]; if (cacheValue) { @@ -513,7 +595,12 @@

    MojitoServer  0.1.0

    out.config = out.config || {}; out.action = out.action || 'index'; - out.guid = out.guid || self._Y.guid(); + if (!out.instanceId) { + out.instanceId = Y.guid(); + //DEBUGGING: out.instanceId += '-instance-server-' + out.type; + } + // DEPRECATED, kept in case a user is using it. + out.guid = out.instanceId; try { self.getMojitTypeDetails(env, ctx, out.type, out); @@ -522,13 +609,13 @@

    MojitoServer  0.1.0

    } // apply type defaults to config - if ((! fromBase) && out.defaults && out.defaults.config) { + if ((!fromBase) && out.defaults && out.defaults.config) { spec = self._cloneObj(out.defaults.config); self._mergeRecursive(spec, out.config); out.config = spec; } - if (! out.appConfig) { + if (!out.appConfig) { out.appConfig = appConfig; delete out.appConfig.specs; } @@ -540,12 +627,14 @@

    MojitoServer  0.1.0

    if (appConfig.specs) { base = appConfig.specs[instance.base]; } - if (! base) { - return cb(new Error('Unknown "base" of "' + instance.base + '"')); + if (!base) { + return cb(new Error('Unknown "base" of "' + instance.base + + '"')); } // The base will need to carry it's ID with it. base.id = instance.base; - this.expandInstanceForEnv(env, base, ctx, function(err, baseInstance) { + this.expandInstanceForEnv(env, base, ctx, function(err, + baseInstance) { if (err) { return cb(err); } @@ -553,8 +642,7 @@

    MojitoServer  0.1.0

    self._mergeRecursive(temp, instance); gotBase(temp, true); }); - } - else { + } else { gotBase(this._cloneObj(instance), false); } }, @@ -563,48 +651,57 @@

    MojitoServer  0.1.0

    /** * gets application configuration * - * @method getAppConfig - * @param context {object} context under which to load the config + * @param ctx {object} the runtime context under which to load the config * @param name {string} type of config to read: - * - definition: reads ./application.json - * - package: reads ./package.json - * - routes: reads ./routes.json (or whatever was configured in appConfig('definition').routesFiles) + * - definition: reads ./application.json + * - package: reads ./package.json + * - routes: reads ./routes.json (or whatever was configured in + * appConfig('definition').routesFiles) * @return {object} config object */ getAppConfig: function(ctx, name) { //logger.log('getAppConfig('+name+')'); - var resid, res; - if ('definition' === name && ((!ctx) || (!ctx.length))) { - return this._cloneObj(this._appConfigNC); + var resid, + res, + ycb; + + if ('definition' === name && (!ctx || !Object.keys(ctx).length)) { + return this._cloneObj(this._appConfigStatic); } + resid = 'config-' + name; res = this._getContextualizedResource(this._appMeta.server, ctx, resid); - if (! res) { + if (!res) { return {}; } - return this._readConfigYCB(ctx, res.fsPath); + ycb = this._readConfigYCB(ctx, res.fsPath, true); + return this._cloneObj(ycb); }, /** * Returns the routes configured in the application. - * @param ctx {object} context under which to load the routes + * + * @param ctx {object} runtime context under which to load the routes * @return {object} routes */ getRoutes: function(ctx) { //logger.log('getRoutes()'); - var ress, resid, res, - r, routes = {}; - - // TODO: [bug 4647333] trapped this error. It only appears when there is no application.json + var ress, + resid, + res, + r, + routes = {}; + + // TODO: [Issue 100] trapped this error. It only appears when there is + // no application.json try { ress = this._getResourceListForContext(this._appMeta.server, ctx); - } - catch(err) { + } catch (err) { //logger.log(err); ress = {}; } - + for (resid in ress) { if (ress.hasOwnProperty(resid)) { res = ress[resid]; @@ -615,40 +712,54 @@

    MojitoServer  0.1.0

    this._mergeRecursive(routes, r); } } - if (! Object.keys(routes).length) { + if (!Object.keys(routes).length) { routes = this._cloneObj(this._fwConfig.defaultRoutes); } return routes; }, - /* - * * url string - * asset URL - * * returns - * filesystemm path + /** + * Returns the filesystem location of the static URL. + * Returns undefined if given URL isn't part of the app. + * + * @param url {string} static URL + * @return {string} path on filesystem of specified URL, or undefined */ - // TODO DOCS [bug 4647336] fileFromStaticHandlerURL: function(url) { //logger.log('fileFromStaticHandlerURL('+url+')'); return this._staticURLs[url]; }, - // TODO DOCS [bug 4647349] + /** + * Returns the YUI configuration object which tells YUI about the + * YUI modules in all the mojits. + * + * @param env {string} "client" or "server" + * @param ctx {object} runtime context for YUI configuration + * @return {object} YUI configuration for all mojits + */ getYuiConfigAllMojits: function(env, ctx) { - // TODO DREW -- use getMojitTypeDetails() to generate this + // TODO: use getMojitTypeDetails() to generate this. //logger.log('getYuiConfigAllMojits('+env+')'); - var modules = {}, type, - ress, resid, res, ctxKey; + var modules = {}, + type, + ress, + resid, + res, + ctxKey; for (type in this._mojitMeta[env]) { if (this._mojitMeta[env].hasOwnProperty(type)) { - ress = this._getResourceListForContext(this._mojitMeta[env][type], ctx); + ress = this._getResourceListForContext( + this._mojitMeta[env][type], + ctx + ); for (resid in ress) { if (ress.hasOwnProperty(resid)) { res = ress[resid]; - if (! res.yuiModuleName) { + if (!res.yuiModuleName) { continue; } if ('fw' === res.source) { @@ -658,7 +769,9 @@

    MojitoServer  0.1.0

    continue; } modules[res.yuiModuleName] = { - fullpath: ('client' === env) ? res.staticHandlerURL : res.fsPath, + fullpath: ('client' === env) ? + res.staticHandlerURL : + res.fsPath, requires: res.yuiModuleMeta.requires }; } @@ -670,7 +783,9 @@

    MojitoServer  0.1.0

    if (ress.hasOwnProperty(resid)) { res = ress[resid]; modules[res.yuiModuleName] = { - fullpath: ('client' === env) ? res.staticHandlerURL : res.fsPath, + fullpath: ('client' === env) ? + res.staticHandlerURL : + res.fsPath, requires: res.yuiModuleMeta.requires }; } @@ -682,24 +797,35 @@

    MojitoServer  0.1.0

    }, - // TODO DOCS [bug 4647354] + /** + * Returns the YUI configuration object which tells YUI about the + * YUI modules in the Mojito framework. + * + * @param env {string} "client" or "server" + * @param ctx {object} runtime context for YUI configuration + * @return {object} YUI configuration for Mojito framework + */ getYuiConfigFw: function(env, ctx) { //logger.log('getYuiConfigFw('+env+')'); var modules = {}, - ress, resid, res; + ress, + resid, + res; - if (! this._fwMeta[env]) { + if (!this._fwMeta[env]) { return {modules: {}}; } ress = this._getResourceListForContext(this._fwMeta[env], ctx); for (resid in ress) { if (ress.hasOwnProperty(resid)) { res = ress[resid]; - if (! res.yuiModuleName) { + if (!res.yuiModuleName) { continue; } modules[res.yuiModuleName] = { - fullpath: ('client' === env) ? res.staticHandlerURL : res.fsPath, + fullpath: ('client' === env) ? + res.staticHandlerURL : + res.fsPath, requires: res.yuiModuleMeta.requires }; } @@ -708,24 +834,35 @@

    MojitoServer  0.1.0

    }, - // TODO DOCS [bug 4647357] + /** + * Returns the YUI configuration object which tells YUI about the + * YUI modules in the application (which aren't part of a mojit). + * + * @param env {string} "client" or "server" + * @param ctx {object} runtime context for YUI configuration + * @return {object} YUI configuration for the app-level modules + */ getYuiConfigApp: function(env, ctx) { //logger.log('getYuiConfigApp('+env+')'); var modules = {}, - ress, resid, res; + ress, + resid, + res; - if (! this._appMeta[env]) { + if (!this._appMeta[env]) { return {modules: {}}; } ress = this._getResourceListForContext(this._appMeta[env], ctx); for (resid in ress) { if (ress.hasOwnProperty(resid)) { res = ress[resid]; - if (! res.yuiModuleName) { + if (!res.yuiModuleName) { continue; } modules[res.yuiModuleName] = { - fullpath: ('client' === env) ? res.staticHandlerURL : res.fsPath, + fullpath: ('client' === env) ? + res.staticHandlerURL : + res.fsPath, requires: res.yuiModuleMeta.requires }; } @@ -735,18 +872,23 @@

    MojitoServer  0.1.0

    /* - * FUTURE: [bug 4647365] Cache the output of this function - * returns a serializeable object (for passing JSON) + * returns a serializeable object used to initialize Mojito on the client + * + * FUTURE: [Issue 105] Cache the output of this function * cache key: all of ctx * - * @method serializeClientStore - * @param context {object} - * @param instance {list} list of instances to deploy to the client + * @param context {object} runtime context + * @param instance {array} DEPRECATED: list of instances to deploy to the client * (only instances with IDs will be deployable) + * @return {object} object that should be serialized and used to initialize the MojitoClient */ serializeClientStore: function(ctx, instances) { //logger.log('serializeClientStore()'); - var i, id, instance, type, types = {}, + var i, + id, + instance, + type, + types = {}, out = { appConfig: {}, specs: {}, // instance details @@ -756,7 +898,7 @@

    MojitoServer  0.1.0

    out.appConfig = this.getAppConfig(ctx, 'definition'); - for (i=0; i<instances.length; i++) { + for (i = 0; i < instances.length; i += 1) { instance = instances[i]; types[instance.type] = true; id = instance.id; @@ -782,24 +924,40 @@

    MojitoServer  0.1.0

    return out; }, - listAllMojits: function(env){ - - var mojitType, list = []; + + /** + * Returns a list of all mojit types in the application. + * + * @param env {string} "client" or "server" + * @return {array} list of mojit types + */ + listAllMojits: function(env) { + var mojitType, + list = []; for (mojitType in this._mojitMeta[env]) { if (this._mojitMeta[env].hasOwnProperty(mojitType)) { list.push(mojitType); } } - return list; }, - getAllMojits: function(env, ctx){ - var mojits, mojit, list = {}; + /** + * Returns details about all mojits in the application. + * + * @param env {string} "client" or "server" + * @param ctx {object} runtime context + * @return {object} keys are mojit type names, values are details about each mojit + */ + getAllMojits: function(env, ctx) { + + var mojits, + mojit, + list = {}; - if(!ctx){ + if (!ctx) { ctx = {}; } @@ -807,7 +965,8 @@

    MojitoServer  0.1.0

    for (mojit in mojits) { if (mojits.hasOwnProperty(mojit)) { - list[mojits[mojit]] = this.getMojitTypeDetails(env, ctx, mojits[mojit]); + list[mojits[mojit]] = + this.getMojitTypeDetails(env, ctx, mojits[mojit]); } } @@ -816,11 +975,11 @@

    MojitoServer  0.1.0

    /* - * Find the best match for a context, considering context language. Falls - * back to the first match found if there is no suitable language. + * Given a set of known contexts, finds the best match for a runtime context. + * Gives special consideration to the "lang" key in the contexts. * - * @param {object} currentContext - * @param {object} contexts a mapping of context key to context + * @param currentContext {object} runtime context + * @param contexts {object} a mapping of context key to context * @return {string} null or the context key of the best match */ _findBestContext: function(currentContext, contexts) { @@ -834,7 +993,6 @@

    MojitoServer  0.1.0

    // Collect languages from matching contexts // We're done if we find an exact match - for (ctxKey in contexts) { if (contexts.hasOwnProperty(ctxKey)) { context = contexts[ctxKey]; @@ -852,11 +1010,12 @@

    MojitoServer  0.1.0

    } // If no exact match, find the next best language - - if (!bestCtxKey && availableLangs && availableLangs.length && currentContext && currentContext.lang) { - bestLang = this._Y.Intl.lookupBestLang(currentContext.lang, availableLangs); + if (!bestCtxKey && availableLangs && availableLangs.length && + currentContext && currentContext.lang) { + bestLang = Y.Intl.lookupBestLang(currentContext.lang, + availableLangs); if (bestLang) { - for (i = 0; i < matchingKeys.length; i++) { + for (i = 0; i < matchingKeys.length; i += 1) { if (contexts[matchingKeys[i]].lang === bestLang) { bestCtxKey = matchingKeys[i]; break; @@ -871,65 +1030,98 @@

    MojitoServer  0.1.0

    }, - // TODO DOCS [bug 4647368] + /** + * Returns details about a mojit type. + * + * @param env {string} "client" or "server" + * @param ctx {object} runtime context + * @param mojitType {string} mojit type + * @param dest {object} object in which to place the results + * @return {object} returns the "dest" parameter, which has had details added to it + */ getMojitTypeDetails: function(env, ctx, mojitType, dest) { //logger.log('getMojitTypeDetails('+env+',ctx,'+mojitType+')'); - var ress, resid, res, name, - engine, engines = {}, + var ress, + resid, + res, + name, + engine, + engines = {}, ctxKey, - assumeRollups = this._appConfigNC.assumeRollups, - module; + assumeRollups = this._appConfigStatic.assumeRollups, + usePrecomputed = -1 !== this._appConfigStatic.yui. + dependencyCalculations.indexOf('precomputed'), + useOnDemand = -1 !== this._appConfigStatic.yui. + dependencyCalculations.indexOf('ondemand'), + module, + lddf, // lang/datatype-date-format + lddfPath; + + if (!usePrecomputed) { + useOnDemand = true; + } - if(!dest){ + if (!dest) { dest = {}; } - if (! dest.actions) { + if (!dest.actions) { dest.actions = []; } - if (! dest.assets) { + if (!dest.assets) { dest.assets = {}; } - if (! dest.models) { + if (!dest.models) { dest.models = {}; } - if (! dest.modelYUIModuleNames) { + if (!dest.modelYUIModuleNames) { dest.modelYUIModuleNames = {}; } - if (! dest.views) { + if (!dest.views) { dest.views = {}; } - if (! dest.yui) { + if (!dest.yui) { dest.yui = {config: {}, requires: []}; } - if (! dest.yui.config) { + if (!dest.yui.config) { dest.yui.config = {modules: {}}; } - if (! dest.yui.config.modules) { + if (!dest.yui.config.modules) { dest.yui.config.modules = {}; } - if (! dest.yui.requires) { + if (!dest.yui.requires) { dest.yui.requires = []; } + if (!dest.yui.langs) { + dest.yui.langs = {}; + } - if ('precomputed' === this._appConfigNC.yui.dependencyCalculations) { - ctxKey = this._findBestContext(ctx, this._mojitYuiSorted[env][mojitType].contexts); - dest.yui.requires = this._mojitYuiRequired[env][mojitType][ctxKey]; - dest.yui.sorted = this._mojitYuiSorted[env][mojitType][ctxKey]; - dest.yui.sortedPaths = this._mojitYuiSortedPaths[env][mojitType][ctxKey]; + if (usePrecomputed) { + ctxKey = this._findBestContext(ctx, + this._mojitYuiSorted[env][mojitType].contexts); + dest.yui.requires = + this._mojitYuiRequired[env][mojitType][ctxKey] || []; + dest.yui.sorted = + this._cloneObj( + this._mojitYuiSorted[env][mojitType][ctxKey] || [] + ); + dest.yui.sortedPaths = + this._cloneObj( + this._mojitYuiSortedPaths[env][mojitType][ctxKey] || {} + ); } dest.assetsRoot = this._mojitAssetRoots[mojitType]; - dest.definition = this._getMojitConfig('server', ctx, mojitType, 'definition'); - dest.defaults = this._getMojitConfig('server', ctx, mojitType, 'defaults'); + dest.definition = this._getMojitConfig('server', ctx, mojitType, + 'definition'); + dest.defaults = this._getMojitConfig('server', ctx, mojitType, + 'defaults'); - ress = this._getResourceListForContext(this._mojitMeta[env][mojitType], ctx); + ress = this._getResourceListForContext(this._mojitMeta[env][mojitType], + ctx); for (resid in ress) { if (ress.hasOwnProperty(resid)) { - //console.log('>>>>>>>>>>>>>>>>>>>>>>>> ' + res.type +':'+res.yuiModuleName); - //console.log(res); - res = ress[resid]; if (res.type === 'action') { @@ -958,7 +1150,7 @@

    MojitoServer  0.1.0

    } if (res.type === 'binder') { - if (! dest.views[res.name]) { + if (!dest.views[res.name]) { dest.views[res.name] = {}; } dest.views[res.name]['binder-url'] = res.staticHandlerURL; @@ -966,22 +1158,25 @@

    MojitoServer  0.1.0

    if (assumeRollups) { dest.views[res.name]['binder-path'] = res.rollupURL; } else { - dest.views[res.name]['binder-path'] = res.staticHandlerURL; + dest.views[res.name]['binder-path'] = + res.staticHandlerURL; } } else { dest.views[res.name]['binder-path'] = res.fsPath; } dest.views[res.name]['binder-module'] = res.yuiModuleName; - dest.views[res.name]['binder-yui-sorted'] = res.yuiSortedPaths; + dest.views[res.name]['binder-yui-sorted'] = + res.yuiSortedPaths; if ('server' === env) { - // don't do any other type of server-side processing for the binder - // ESPECIALLY don't add it to dest.yui.* + // don't do any other type of server-side processing for + // the binder ESPECIALLY don't add it to dest.yui.* continue; } } if (res.type === 'controller') { - // We need the YUI Module name of the contoller so we can select a language for it + // We need the YUI Module name of the contoller so we can + // select a language for it dest.controllerModuleName = res.yuiModuleName; if (env === 'client') { if (assumeRollups) { @@ -994,11 +1189,6 @@

    MojitoServer  0.1.0

    } } - // TODO: why is this commented-out but not deleted? - //if (res.type === 'yui-lang') { - // dest.lang = ('client' === env) ? res.staticHandlerURL : res.fsPath; - //} - if (res.type === 'model') { if (env === 'client') { if (assumeRollups) { @@ -1011,19 +1201,22 @@

    MojitoServer  0.1.0

    } if (res.yuiModuleName) { dest.modelYUIModuleNames[res.yuiModuleName] = true; -// logger.log("Processing Models:" + res.name + ":" + res.yuiModuleName, 'mojito', NAME); + //logger.log("Processing Models:" + res.name + ":" + + // res.yuiModuleName, 'mojito', NAME); } } if (res.type === 'view') { - if (! dest.views[res.name]) { + if (!dest.views[res.name]) { dest.views[res.name] = {}; } if (env === 'client') { if (assumeRollups) { - dest.views[res.name]['content-path'] = res.rollupURL; + dest.views[res.name]['content-path'] = + res.rollupURL; } else { - dest.views[res.name]['content-path'] = res.staticHandlerURL; + dest.views[res.name]['content-path'] = + res.staticHandlerURL; } } else { dest.views[res.name]['content-path'] = res.fsPath; @@ -1032,11 +1225,18 @@

    MojitoServer  0.1.0

    engines[res.viewEngine] = true; } + if (res.type === 'yui-lang') { + dest.yui.langs[res.langCode] = res.yuiModuleName; + } + if (res.yuiModuleName) { if (res.addonType === 'view-engines') { // we'll only load the viewEngines that we need continue; } + if (useOnDemand) { + dest.yui.requires.push(res.yuiModuleName); + } if (('fw' === res.source) || ('app' === res.source)) { continue; } @@ -1046,18 +1246,22 @@

    MojitoServer  0.1.0

    }; if (env === 'client') { if (assumeRollups) { - dest.yui.config.modules[res.yuiModuleName].fullpath = res.rollupURL; + dest.yui.config.modules[res.yuiModuleName + ].fullpath = res.rollupURL; } else { - dest.yui.config.modules[res.yuiModuleName].fullpath = res.staticHandlerURL; + dest.yui.config.modules[res.yuiModuleName + ].fullpath = res.staticHandlerURL; } } else { - dest.yui.config.modules[res.yuiModuleName].fullpath = res.fsPath; + dest.yui.config.modules[res.yuiModuleName].fullpath = + res.fsPath; } // If we have "lang" use it if (this._mojitLangs[res.yuiModuleName]) { this._mojitLangs[res.yuiModuleName].sort(); - dest.yui.config.modules[res.yuiModuleName].lang = this._mojitLangs[res.yuiModuleName]; + dest.yui.config.modules[res.yuiModuleName].lang = + this._mojitLangs[res.yuiModuleName]; } } } @@ -1065,11 +1269,53 @@

    MojitoServer  0.1.0

    for (engine in engines) { if (engines.hasOwnProperty(engine)) { resid = 'addon-view-engines-' + engine; - res = this._getContextualizedResource(this._mojitMeta[env][mojitType], ctx, resid); + res = this._getContextualizedResource( + this._mojitMeta[env][mojitType], + ctx, + resid + ); dest.yui.config.modules[res.yuiModuleName] = { - fullpath: ('client' === env) ? res.staticHandlerURL : res.fsPath, + fullpath: ('client' === env) ? + res.staticHandlerURL : + res.fsPath, requires: res.yuiModuleMeta.requires || [] }; + if (useOnDemand) { + dest.yui.requires.push(res.yuiModuleName); + } + } + } + + // We need to include -all- the langs since we don't know which will + // actually be used. dispatch() will cull that down to the right one. + if (usePrecomputed) { + for (name in dest.yui.langs) { + if (dest.yui.langs.hasOwnProperty(name)) { + module = dest.yui.langs[name]; + lddf = 'lang/datatype-date-format_' + (name || 'en'); + if (dest.yui.sortedPaths[lddf]) { + lddfPath = dest.yui.sortedPaths[lddf].replace('_' + + name, '_MOJITOPLACEHOLDER'); + } + if (!dest.yui.sortedPaths[module]) { + dest.yui.sorted.push(module); + dest.yui.sortedPaths[module] = + dest.yui.config.modules[module].fullpath; + } + } + } + if (lddfPath) { + for (name in dest.yui.langs) { + if (dest.yui.langs.hasOwnProperty(name)) { + lddf = 'lang/datatype-date-format_' + (name || 'en'); + if (!dest.yui.sortedPaths[lddf]) { + dest.yui.sorted.push(lddf); + dest.yui.sortedPaths[lddf] = + lddfPath.replace('MOJITOPLACEHOLDER', + (name || 'en')); + } + } + } } } @@ -1077,16 +1323,25 @@

    MojitoServer  0.1.0

    }, - // TODO DOCS [bug 4647383] + /** + * Returns details on how to make rollups for app-level resources. + * + * @param env {string} "client" or "server" + * @param ctx {object} runtime context + * @return {object} object describing where to put the rollup and what it should contain + */ getRollupsApp: function(env, ctx) { - var dest = libpath.join(this._root, 'rollup.'+env+'.js'), + var dest = libpath.join(this._root, 'rollup.' + env + '.js'), srcs = [], - ress, resid, res; + ress, + resid, + res; + ress = this._getResourceListForContext(this._fwMeta[env], ctx); for (resid in ress) { if (ress.hasOwnProperty(resid)) { res = ress[resid]; - if (! res.yuiModuleName) { + if (!res.yuiModuleName) { continue; } srcs.push(res.fsPath); @@ -1097,7 +1352,7 @@

    MojitoServer  0.1.0

    for (resid in ress) { if (ress.hasOwnProperty(resid)) { res = ress[resid]; - if (! res.yuiModuleName) { + if (!res.yuiModuleName) { continue; } srcs.push(res.fsPath); @@ -1111,38 +1366,55 @@

    MojitoServer  0.1.0

    }, - // TODO DOCS [bug 4647385] - // This example comes from GSG5. - // { FlickrDetail: - // dest: '/blah/blah/mojits/FlickrDetail/rollup.client.js' - // srcs: [ - // '/blah/blah/mojits/FlickrDetail/controller.common.js', - // '/blah/blah/mojits/FlickrDetail/binders/index.js', - // '/blah/blah/mojits/FlickrDetail/lang/FlickrDetail_de.js', - // '/blah/blah/mojits/FlickrDetail/lang/FlickrDetail_en-US.js' - // ] - // } + /** + * Returns details on how to make rollups for mojit-level resources. + * + * This example comes from GSG5. + * { FlickrDetail: + * dest: '/blah/blah/mojits/FlickrDetail/rollup.client.js' + * srcs: [ + * '/blah/blah/mojits/FlickrDetail/controller.common.js', + * '/blah/blah/mojits/FlickrDetail/binders/index.js', + * '/blah/blah/mojits/FlickrDetail/lang/FlickrDetail_de.js', + * '/blah/blah/mojits/FlickrDetail/lang/FlickrDetail_en-US.js' + * ] + * } + * + * @param env {string} "client" or "server" + * @param ctx {object} runtime context + * @return {object} object describing where to put the rollup and what it should contain + */ getRollupsMojits: function(env, ctx) { - var mojitName, ress, resid, res, - dest, srcs, rollups = {}, + var mojitName, + ress, + resid, + res, + dest, + srcs, + rollups = {}, mojitoMojits = libpath.join(mojitoRoot, 'mojits'); + for (mojitName in this._mojitMeta[env]) { if (this._mojitMeta[env].hasOwnProperty(mojitName)) { srcs = []; - ress = this._getResourceListForContext(this._mojitMeta[env][mojitName], ctx); + ress = this._getResourceListForContext( + this._mojitMeta[env][mojitName], + ctx + ); for (resid in ress) { if (ress.hasOwnProperty(resid)) { res = ress[resid]; if (res.source !== 'mojit') { continue; } - if (! res.yuiModuleName) { + if (!res.yuiModuleName) { continue; } srcs.push(res.fsPath); } } - dest = libpath.join(this._mojitPaths[mojitName], 'rollup.'+env+'.js'); + dest = libpath.join(this._mojitPaths[mojitName], 'rollup.' + + env + '.js'); if (dest.indexOf(mojitoMojits) === 0) { // we shouldn't write to the mojits that ship with Mojito dest = false; @@ -1159,40 +1431,61 @@

    MojitoServer  0.1.0

    }, - // TODO DOCS 2011-07-21 - // This example comes from (a modified) GSG5. - // [ { - // context: { device: 'iphone' }, - // mojitName: 'FlickrDetail', - // yuiModuleName: 'inlinecss/FlickrDetail', - // dest: '/blah/blah/mojits/FlickrDetail/autoload/compiled/css.iphone.client.js', - // srcs: { - // '/static/FlickrDetail/assets/index.css': '/blah/blah/blah/mojits/FlickrDetail/assets/index.iphone.css', - // '/static/FlickrDetail/assets/message.css': '/blah/blah/blah/mojits/FlickrDetail/assets/message.css' - // } - // ] + /** + * Returns details on how to make inline CSS for mojits. + * + * This example comes from (a modified) GSG5. + * [ { + * context: { device: 'iphone' }, + * mojitName: 'FlickrDetail', + * yuiModuleName: 'inlinecss/FlickrDetail', + * dest: '/blah/mojits/FlickrDetail/autoload/compiled' + + * '/css.iphone.client.js', + * srcs: { + * '/static/FlickrDetail/assets/index.css': + * ' /blah/mojits/FlickrDetail/assets/index.iphone.css', + * '/static/FlickrDetail/assets/message.css': + * ' /blah/mojits/FlickrDetail/assets/message.css' + * } + * ] + * + * @param env {string} "client" or "server" + * @param ctxFilter {object} (optional) runtime context to restrict results to + * @return {array} object describing where to put the inline CSS file and what it should contain + */ getInlineCssMojits: function(env, ctxFilter) { - var mojitName, ctxKey, ctx, ress, resid, res, selector, - dest, srcs, inlines = []; + var mojitName, + ctxKey, + ctx, + ress, + resid, + res, + selector, + dest, + srcs, + inlines = [], mojitoMojits = libpath.join(mojitoRoot, 'mojits'); // This will make our test later a little easier. - if (typeof(ctxFilter) === "object" && !Object.keys(ctxFilter).length) { + if (typeof ctxFilter === 'object' && !Object.keys(ctxFilter).length) { ctxFilter = null; } for (mojitName in this._mojitMeta[env]) { if (this._mojitMeta[env].hasOwnProperty(mojitName)) { for (ctxKey in this._mojitMeta[env][mojitName].contexts) { - if (this._mojitMeta[env][mojitName].contexts.hasOwnProperty(ctxKey)) { + if (this._mojitMeta[env][mojitName + ].contexts.hasOwnProperty(ctxKey)) { ctx = this._mojitMeta[env][mojitName].contexts[ctxKey]; if (ctxFilter && !this._matchContext(ctx, ctxFilter)) { continue; } - ress = this._cloneObj(this._mojitMeta[env][mojitName]['*']); + ress = this._cloneObj(this._mojitMeta[env + ][mojitName]['*']); if ('*' !== ctxKey) { - ress = this._mergeRecursive(ress, this._mojitMeta[env][mojitName][ctxKey]); + ress = this._mergeRecursive(ress, + this._mojitMeta[env][mojitName][ctxKey]); } srcs = []; for (resid in ress) { @@ -1201,17 +1494,20 @@

    MojitoServer  0.1.0

    if (res.source !== 'mojit') { continue; } - if ((res.type !== 'asset') || (res.assetType !== 'css')) { + if ((res.type !== 'asset') || + (res.assetType !== 'css')) { continue; } srcs[res.staticHandlerURL] = res.fsPath; } } selector = this._selectorFromContext(ctx); - dest = 'autoload/compiled/inlinecss' + (selector ? '.'+selector : '') + '.common.js'; + dest = 'autoload/compiled/inlinecss' + (selector ? '.' + + selector : '') + '.common.js'; dest = libpath.join(this._mojitPaths[mojitName], dest); if (dest.indexOf(mojitoMojits) === 0) { - // we shouldn't write to the mojits that ship with Mojito + // we shouldn't write to the mojits that ship with + // Mojito continue; } if (Object.keys(srcs).length) { @@ -1235,7 +1531,11 @@

    MojitoServer  0.1.0

    // =========================================== // ================= PRIVATE ================= - _readAppConfigNC: function() { + /* + * the "static" version of the application.json is the version that has + * the context applied that was given at server-start time. + */ + _readAppConfigStatic: function() { var path = libpath.join(this._root, 'application.json'), config = this._cloneObj(this._fwConfig.appConfigBase), appConfig; @@ -1249,55 +1549,120 @@

    MojitoServer  0.1.0

    }, - // TODO DREW 2011-06-16: [bug 4647391] work out story for this stage + /* + * Read the application's dimensions.json file for YCB processing. If not + * available, fall back to the framework's default dimensions.json. + * + * @return {array} + */ + _readYcbDimensions: function() { + var libpath = this._libs.path, + path = libpath.join(this._root, 'dimensions.json'), + dims; + + if (!libpath.existsSync(path)) { + path = libpath.join(mojitoRoot, 'dimensions.json'); + } + + dims = this._readConfigJSON(path); + if (!this._isValidYcbDimensions(dims)) { + throw new Error('Invalid dimensions.json: ' + path); + } + return dims; + }, + + + /* + * Perform some light validation for YCB dimensions JSON objects. It should + * look something like this: + * [{ + * "dimensions": [ + * "dim1": {}, + * "dim2": {}, + * ... + * ] + * }] + * + * @param {array} dimensions + * @return {boolean} + */ + _isValidYcbDimensions: function(dims) { + var isArray = Y.Lang.isArray; + + return isArray(dims) && + dims.length === 1 && + isArray(dims[0].dimensions) && + dims[0].dimensions.length > 0; + }, + + + // TODO: [Issue 109] work out story for this stage. + /* + * preload metadata about all resources in the application (and Mojito framework) + */ _preloadMeta: function() { - var i, path, realDirs = []; + var i, + path, + realDirs = []; + + // All the contents of the app/ directory are "app-level" resource + // (resources for mojits which are applied to -all- mojits) + // (A better name might have been "global" instead of "app-level".) + this._preloadDirMojit('fw', false, libpath.join(mojitoRoot, 'app')); - this._preloadDirMojit('fw', false, libpath.join(mojitoRoot,'app')); - this._preloadDirMojits(false, libpath.join(mojitoRoot,'mojits')); + this._preloadDirMojits(false, libpath.join(mojitoRoot, 'mojits')); - this._preloadFileConfig(this._preload.appMeta, 'app', null, libpath.join(this._root,'application.json'), 'definition'); + this._preloadFileConfig(this._preload.appMeta, 'app', null, + libpath.join(this._root, 'application.json'), 'definition'); + // read app-level resources this._preloadDirMojit('app', false, this._root); - // TODO DREW 2011-06-16: [bug 4647391] split loops into separate functions (for readability) + // TODO: [Issue 109] split loops into separate functions (for readability). - for (i=0; i<this._appConfigNC.routesFiles.length; i++) { - path = this._appConfigNC.routesFiles[i]; + // load routes file(s) + for (i = 0; i < this._appConfigStatic.routesFiles.length; i += 1) { + path = this._appConfigStatic.routesFiles[i]; if ('/' !== path.charAt(0)) { path = libpath.join(this._root, path); } - this._preloadFileConfig(this._preload.appMeta, 'app', null, path, 'routes'); + this._preloadFileConfig(this._preload.appMeta, 'app', null, path, + 'routes'); } - for (i=0; i<this._appConfigNC.mojitsDirs.length; i++) { - path = this._appConfigNC.mojitsDirs[i]; + // load mojitsDirs + for (i = 0; i < this._appConfigStatic.mojitsDirs.length; i += 1) { + path = this._appConfigStatic.mojitsDirs[i]; if ('/' !== path.charAt(0)) { path = libpath.join(this._root, path); } libglob.globSync(path, {}, realDirs); } - if (! realDirs.length) { - throw new Error('Failed to find any mojitsDirs matching ' + this._appConfigNC.mojitsDirs.join(', ')); + if (!realDirs.length) { + throw new Error('Failed to find any mojitsDirs matching ' + + this._appConfigStatic.mojitsDirs.join(', ')); } - for (i=0; i<realDirs.length; i++) { + for (i = 0; i < realDirs.length; i += 1) { path = realDirs[i]; this._preloadDirMojits(true, path); } - if (this._appConfigNC.mojitDirs && this._appConfigNC.mojitDirs.length) { + // load mojitDirs + if (this._appConfigStatic.mojitDirs && + this._appConfigStatic.mojitDirs.length) { realDirs = []; - for (i=0; i<this._appConfigNC.mojitDirs.length; i++) { - path = this._appConfigNC.mojitDirs[i]; + for (i = 0; i < this._appConfigStatic.mojitDirs.length; i += 1) { + path = this._appConfigStatic.mojitDirs[i]; if ('/' !== path.charAt(0)) { path = libpath.join(this._root, path); } libglob.globSync(path, {}, realDirs); } - if (! realDirs.length) { - throw new Error('Failed to find any mojitDirs matching ' + this._appConfigNC.mojitDirs.join(', ')); + if (!realDirs.length) { + throw new Error('Failed to find any mojitDirs matching ' + + this._appConfigStatic.mojitDirs.join(', ')); } - for (i=0; i<realDirs.length; i++) { + for (i = 0; i < realDirs.length; i += 1) { path = realDirs[i]; this._preloadDirMojit('mojit', true, path); } @@ -1305,16 +1670,23 @@

    MojitoServer  0.1.0

    }, + /* + * preloads metadata for mojits in a directory + */ _preloadDirMojits: function(readConfig, fullpath) { - if (! this._libs.path.existsSync(fullpath)) { + if (!this._libs.path.existsSync(fullpath)) { return; } - //logger.log('----------------------- preloadDirMojits(' + readConfig + ') -- ' + fullpath); - var children = this._libs.fs.readdirSync(fullpath), - i, childName, childPath, mojitName; - for (i=0; i<children.length; i++) { + //logger.log('----------------------- preloadDirMojits(' + readConfig + + // ') -- ' + fullpath); + var children = this._sortedReaddirSync(fullpath), + i, + childName, + childPath; + + for (i = 0; i < children.length; i += 1) { childName = children[i]; - if ('.' === childName.substring(0,1)) { + if ('.' === childName.substring(0, 1)) { continue; } childPath = libpath.join(fullpath, childName); @@ -1323,78 +1695,114 @@

    MojitoServer  0.1.0

    }, + /* + * preloads metadata for resources in a directory which contains a single mojit + * + * @param source {string} "fw", "app" or "mojit" + * @param readConfig {boolean} whether to read the config files in the mojit + * @param fullpath {string} + * @return {nothing} results stored in this object + */ _preloadDirMojit: function(source, readConfig, fullpath) { - if (! this._libs.path.existsSync(fullpath)) { + if (!this._libs.path.existsSync(fullpath)) { return; } -// logger.log('----------------------- preloadDirMojit(' + source + ',' + readConfig + ') -- ' + fullpath); - var packageJson, definitionJson, mojitType, dest, - appConfig, urlPrefix, url; + //logger.log('----------------------- preloadDirMojit(' + + // source + ',' + readConfig + ') -- ' + fullpath); + var packageJson, + definitionJson, + mojitType, + dest, + appConfig, + urlPrefix, + url; if (readConfig && 'mojit' === source) { - packageJson = this._readMojitConfigFile(libpath.join(fullpath,'package.json'), false); + packageJson = this._readMojitConfigFile(libpath.join(fullpath, + 'package.json'), false); mojitType = packageJson.name; - definitionJson = this._readMojitConfigFile(libpath.join(fullpath,'definition.json'), true); + definitionJson = this._readMojitConfigFile(libpath.join(fullpath, + 'definition.json'), true); if (definitionJson.appLevel) { source = 'app'; } } - if (! mojitType) { + if (!mojitType) { mojitType = libpath.basename(fullpath); } this._mojitPaths[mojitType] = fullpath; switch (source) { - case 'fw': - dest = this._preload.fwMeta; - break; - case 'app': - dest = this._preload.appMeta; - break; - case 'mojit': - if (! this._preload.mojitMeta[mojitType]) { - this._preload.mojitMeta[mojitType] = {}; - } - dest = this._preload.mojitMeta[mojitType]; - break; + case 'fw': + dest = this._preload.fwMeta; + break; + case 'app': + dest = this._preload.appMeta; + break; + case 'mojit': + if (!this._preload.mojitMeta[mojitType]) { + this._preload.mojitMeta[mojitType] = {}; + } + dest = this._preload.mojitMeta[mojitType]; + break; } - // TODO DREW 2011-06-16: [bug 4647391] refactor to return semantics + // TODO: [Issue 109] refactor to return semantics. if (readConfig && 'fw' !== source) { - if (! this._mojitoVersionMatch(packageJson, this._version)) { - logger.log('Mojito version mismatch: mojit skipped in "' + fullpath + '"', 'warn', NAME); + if (!this._mojitoVersionMatch(packageJson, this._version)) { + logger.log('Mojito version mismatch: mojit skipped in "' + + fullpath + '"', 'warn', NAME); return; } + // TODO: this might benefit from passing mojitType to it this._mojitPackageAsAsset(packageJson, fullpath); } if ('mojit' === source) { - // TODO DREW 2011-06-16: [bug 4647391] make this more future-proof - this._preloadFileController(dest, source, mojitType, libpath.join(fullpath,'controller.common.js'), fullpath); - this._preloadFileController(dest, source, mojitType, libpath.join(fullpath,'controller.client.js'), fullpath); - this._preloadFileController(dest, source, mojitType, libpath.join(fullpath,'controller.server.js'), fullpath); + // TODO: [Issue 109] make this more future-proof. + this._preloadFileController(dest, source, mojitType, + libpath.join(fullpath, 'controller.common.js'), fullpath); + this._preloadFileController(dest, source, mojitType, + libpath.join(fullpath, 'controller.client.js'), fullpath); + this._preloadFileController(dest, source, mojitType, + libpath.join(fullpath, 'controller.server.js'), fullpath); } if (readConfig) { - this._preloadFileConfig(dest, source, mojitType, libpath.join(fullpath,'definition.json'), 'definition'); - this._preloadFileConfig(dest, source, mojitType, libpath.join(fullpath,'defaults.json'), 'defaults'); - } - - // TODO DREW 2011-06-16: [bug 4647391] pass actual functions (instead of function names) - // TODO DREW 2011-06-16: [bug 4647391] refactor: first, use a method that returns all files in dir (with ext), then call _preloadFileX on them - this._preloadDir(dest, source, mojitType, libpath.join(fullpath,'actions'), false, '_preloadFileAction'); - this._preloadDir(dest, source, mojitType, libpath.join(fullpath,'addons'), true, '_preloadFileAddon'); - this._preloadDir(dest, source, mojitType, libpath.join(fullpath,'assets'), true, '_preloadFileAsset'); - this._preloadDir(dest, source, mojitType, libpath.join(fullpath,'autoload'), true, '_preloadFileAutoload'); - this._preloadDir(dest, source, mojitType, libpath.join(fullpath,'binders'), true, '_preloadFileBinder'); - this._preloadDir(dest, source, mojitType, libpath.join(fullpath,'lang'), false, '_preloadFileLang'); - this._preloadDir(dest, source, mojitType, libpath.join(fullpath,'models'), false, '_preloadFileModel'); - this._preloadDir(dest, source, mojitType, libpath.join(fullpath,'views'), true, '_preloadFileView'); - this._preloadDir(dest, source, mojitType, libpath.join(fullpath,'specs'), false, '_preloadFileSpec'); - this._preloadDir(dest, source, mojitType, libpath.join(fullpath,'tests'), false, '_preloadFileAutoload'); - this._preloadDir(dest, source, mojitType, libpath.join(fullpath,'tests/models'), false, '_preloadFileAutoload'); - this._preloadDir(dest, source, mojitType, libpath.join(fullpath,'tests/binders'), false, '_preloadFileAutoload'); + this._preloadFileConfig(dest, source, mojitType, + libpath.join(fullpath, 'definition.json'), 'definition'); + this._preloadFileConfig(dest, source, mojitType, + libpath.join(fullpath, 'defaults.json'), 'defaults'); + } + + // TODO: [Issue 109] pass actual functions (instead of function names) + // TODO: [Issue 109] refactor: first, use a method that returns all + // files in dir (with ext), then call _preloadFileX on them + this._preloadDir(dest, source, mojitType, libpath.join(fullpath, + 'actions'), false, '_preloadFileAction'); + this._preloadDir(dest, source, mojitType, libpath.join(fullpath, + 'addons'), true, '_preloadFileAddon'); + this._preloadDir(dest, source, mojitType, libpath.join(fullpath, + 'assets'), true, '_preloadFileAsset'); + this._preloadDir(dest, source, mojitType, libpath.join(fullpath, + 'autoload'), true, '_preloadFileAutoload'); + this._preloadDir(dest, source, mojitType, libpath.join(fullpath, + 'binders'), true, '_preloadFileBinder'); + this._preloadDir(dest, source, mojitType, libpath.join(fullpath, + 'lang'), false, '_preloadFileLang'); + this._preloadDir(dest, source, mojitType, libpath.join(fullpath, + 'models'), false, '_preloadFileModel'); + this._preloadDir(dest, source, mojitType, libpath.join(fullpath, + 'views'), true, '_preloadFileView'); + this._preloadDir(dest, source, mojitType, libpath.join(fullpath, + 'specs'), false, '_preloadFileSpec'); + this._preloadDir(dest, source, mojitType, libpath.join(fullpath, + 'tests'), false, '_preloadFileAutoload'); + this._preloadDir(dest, source, mojitType, libpath.join(fullpath, + 'tests/models'), false, '_preloadFileAutoload'); + this._preloadDir(dest, source, mojitType, libpath.join(fullpath, + 'tests/binders'), false, '_preloadFileAutoload'); /* * Here we are making a URL for the expanded "definition.json" @@ -1403,12 +1811,14 @@

    MojitoServer  0.1.0

    */ if ('mojit' === source) { - // TODO 2011-06-16: [bug 4647391] re-use logic from _calcStaticHandlerURL() for prefix (so that all options are supported) + // TODO: [Issue 109] re-use logic from + // _calcStaticHandlerURL() for prefix (so that all options are + // supported) - appConfig = this._appConfigNC.staticHandling || {}; + appConfig = this._appConfigStatic.staticHandling || {}; urlPrefix = '/static'; if (typeof appConfig.prefix !== 'undefined') { - urlPrefix = appConfig.prefix ? '/'+appConfig.prefix : ''; + urlPrefix = appConfig.prefix ? '/' + appConfig.prefix : ''; } // Add our definition to the Dynamic URLs list @@ -1418,43 +1828,75 @@

    MojitoServer  0.1.0

    }, - _preloadDir: function(dest, source, mojitType, fullpath, recurse, fileHandler, root) { - if (! this._libs.path.existsSync(fullpath)) { + /* + * preloads metadata for resources in a directory + * + * @param dest {object} where results shoulg go (passed to fileHandler) + * @param source {string} where the resource is coming from (passed to fileHandler) + * @param mojitType {string} name of mojit type (passed to fileHandler) + * @param fullpath {string} path of directory + * @param recurse {boolean} whether to recurse into subdirectories + * @param fileHandler {string} name of method on this object to call on each file + * @param root {string} when recursing, fullpath of first call (passed to fileHandler) + * @return {nothing} calls fileHandler to do the actual insteresting work + */ + _preloadDir: function(dest, source, mojitType, fullpath, recurse, + fileHandler, root) { + if (!this._libs.path.existsSync(fullpath)) { return; } - //logger.log('----------------------- preloadDir(' + recurse + ',' + fileHandler + ') -- ' + fullpath); - var children = this._libs.fs.readdirSync(fullpath), - i, childName, childPath, childStat; - if (! root) { + //logger.log('----------------------- preloadDir(' + recurse + ',' + + // fileHandler + ') -- ' + fullpath); + var children = this._sortedReaddirSync(fullpath), + i, + childName, + childPath, + childStat; + + if (!root) { root = fullpath; } - for (i=0; i<children.length; i++) { + for (i = 0; i < children.length; i += 1) { childName = children[i]; - if ('.' === childName.substring(0,1)) { + if ('.' === childName.substring(0, 1)) { continue; } childPath = libpath.join(fullpath, childName); childStat = this._libs.fs.statSync(childPath); if (childStat.isFile()) { this[fileHandler](dest, source, mojitType, childPath, root); - } - else if (recurse && childStat.isDirectory()) { - this._preloadDir(dest, source, mojitType, childPath, recurse, fileHandler, root); + } else if (recurse && childStat.isDirectory()) { + this._preloadDir(dest, source, mojitType, childPath, recurse, + fileHandler, root); } } }, + /* + * preloads metadata for a resource which is an action + * + * @param dest {object} where to store the metadata of the resource + * @param source {string} "fw", "app", or "mojit" + * @param mojitType {string} name of mojit type, might be null + * @param fullpath {string} path to resource + * @param dir {string} base directory of resource type + * @return {nothing} results stored in this object + */ _preloadFileAction: function(dest, source, mojitType, fullpath, dir) { - if (! this._libs.path.existsSync(fullpath)) { + if (!this._libs.path.existsSync(fullpath)) { return; } if ('.js' !== libpath.extname(fullpath)) { return; } - //logger.log('----------------------- preloadFileActions -- ' + fullpath); + //logger.log('----------------------- preloadFileActions -- ' + + // fullpath); var resid, res = {}, pathParts = this._parsePath(fullpath, 'server', dir); + if (this._skipBadPath(pathParts)) { + return; + } res.type = 'action'; res.fsPath = fullpath; @@ -1468,16 +1910,30 @@

    MojitoServer  0.1.0

    }, + /* + * preloads metadata for a resource which is an addon + * + * @param dest {object} where to store the metadata of the resource + * @param source {string} "fw", "app", or "mojit" + * @param mojitType {string} name of mojit type, might be null + * @param fullpath {string} path to resource + * @param dir {string} base directory of resource type + * @return {nothing} results stored in this object + */ _preloadFileAddon: function(dest, source, mojitType, fullpath, dir) { - if (! this._libs.path.existsSync(fullpath)) { + if (!this._libs.path.existsSync(fullpath)) { return; } if ('.js' !== libpath.extname(fullpath)) { return; } //logger.log('----------------------- preloadFileAddon -- ' + fullpath); - var resid, res = {}, + var resid, + res = {}, pathParts = this._parsePath(fullpath, 'server', dir); + if (this._skipBadPath(pathParts)) { + return; + } res.type = 'addon'; res.addonType = libpath.dirname(pathParts.name); @@ -1492,16 +1948,31 @@

    MojitoServer  0.1.0

    }, + /* + * preloads metadata for a resource which is an asset + * + * @param dest {object} where to store the metadata of the resource + * @param source {string} "fw", "app", or "mojit" + * @param mojitType {string} name of mojit type, might be null + * @param fullpath {string} path to resource + * @param dir {string} base directory of resource type + * @return {nothing} results stored in this object + */ _preloadFileAsset: function(dest, source, mojitType, fullpath, dir) { - if (! this._libs.path.existsSync(fullpath)) { + if (!this._libs.path.existsSync(fullpath)) { return; } //logger.log('----------------------- preloadFileAsset -- ' + fullpath); - var resid, res = {}, + var resid, + res = {}, pathParts = this._parsePath(fullpath, 'common', dir); + // All assets are "common", and we want to support the // shortcut of "assets/foo.iphone.css". pathParts.affinity = 'common'; + if (this._skipBadPath(pathParts)) { + return; + } res.type = 'asset'; res.fsPath = fullpath; @@ -1516,39 +1987,56 @@

    MojitoServer  0.1.0

    }, - // This function process all subdirectories using the same logic, so that all files within - // an "autoload" directory will be processed. + /* + * preloads metadata for a resource which is an "autoload" + * + * @param dest {object} where to store the metadata of the resource + * @param source {string} "fw", "app", or "mojit" + * @param mojitType {string} name of mojit type, might be null + * @param fullpath {string} path to resource + * @param dir {string} base directory of resource type + * @return {nothing} results stored in this object + */ _preloadFileAutoload: function(dest, source, mojitType, fullpath, dir) { - if (! this._libs.path.existsSync(fullpath)) { + if (!this._libs.path.existsSync(fullpath)) { return; } if ('.js' !== libpath.extname(fullpath)) { return; } -// logger.log('----------------------- preloadFileAutoload -- ' + fullpath); - var resid, res = {}, + //logger.log('----------------------- preloadFileAutoload -- ' + + // fullpath); + var resid, + res = {}, pathParts = this._parsePath(fullpath, 'server', dir); + if (pathParts.affinity.type) { - // This allows the app config to specify that some "client" affinity code should not be deployed - // if it has an "optional" subtype - if (this._appConfigNC.deferAllOptionalAutoloads && pathParts.affinity.type === 'optional') { + // This allows the app config to specify that some "client" affinity + // code should not be deployed if it has an "optional" subtype + if (this._appConfigStatic.deferAllOptionalAutoloads && + pathParts.affinity.type === 'optional') { pathParts.affinity = 'none'; - } - // this filters tests from being included with deployed applications - else if (pathParts.affinity.type === 'tests' && this._appConfigNC.env !== 'test') { + } else if (pathParts.affinity.type === 'tests' && + this._appConfigStatic.env !== 'test') { + // this filters tests from being included with deployed + // applications pathParts.affinity = 'none'; } } if ('none' === pathParts.affinity) { return; } + if (this._skipBadPath(pathParts)) { + return; + } + res.type = 'yui-module'; res.fsPath = fullpath; res.source = source; this._precalcYuiModule(res); - if (! res.yuiModuleName) { + if (!res.yuiModuleName) { if ('.js' === pathParts.ext) { - throw new Error("Expected YUI3 module in " + fullpath); + throw new Error('Expected YUI3 module in ' + fullpath); } return; } @@ -1558,16 +2046,32 @@

    MojitoServer  0.1.0

    this._preloadSetDest(dest, resid, res, pathParts); }, + + /* + * preloads metadata for a resource which is a binder + * + * @param dest {object} where to store the metadata of the resource + * @param source {string} "fw", "app", or "mojit" + * @param mojitType {string} name of mojit type, might be null + * @param fullpath {string} path to resource + * @param dir {string} base directory of resource type + * @return {nothing} results stored in this object + */ _preloadFileBinder: function(dest, source, mojitType, fullpath, dir) { - if (! this._libs.path.existsSync(fullpath)) { + if (!this._libs.path.existsSync(fullpath)) { return; } if ('.js' !== libpath.extname(fullpath)) { return; } - //logger.log('----------------------- preloadFileBinder -- ' + fullpath); - var resid, res = {}, + //logger.log('----------------------- preloadFileBinder -- ' + + // fullpath); + var resid, + res = {}, pathParts = this._parsePath(fullpath, 'client', dir); + if (this._skipBadPath(pathParts)) { + return; + } res.type = 'binder'; res.fsPath = fullpath; @@ -1581,13 +2085,28 @@

    MojitoServer  0.1.0

    }, + /* + * preloads metadata for a resource which is a configuration file + * + * @param dest {object} where to store the metadata of the resource + * @param source {string} "fw", "app", or "mojit" + * @param mojitType {string} name of mojit type, might be null + * @param fullpath {string} path to resource + * @param dir {string} base directory of resource type + * @return {nothing} results stored in this object + */ _preloadFileConfig: function(dest, source, mojitType, fullpath, type) { - if (! this._libs.path.existsSync(fullpath)) { + if (!this._libs.path.existsSync(fullpath)) { return; } - //logger.log('----------------------- preloadFileConfig(' + type + ') -- ' + fullpath); - var resid, res = {}, + //logger.log('----------------------- preloadFileConfig(' + type + + // ') -- ' + fullpath); + var resid, + res = {}, pathParts = this._parsePath(fullpath, 'server', null); + if (this._skipBadPath(pathParts)) { + return; + } res.type = 'config'; res.configType = type; @@ -1602,16 +2121,31 @@

    MojitoServer  0.1.0

    }, + /* + * preloads metadata for a resource which is a controller + * + * @param dest {object} where to store the metadata of the resource + * @param source {string} "fw", "app", or "mojit" + * @param mojitType {string} name of mojit type, might be null + * @param fullpath {string} path to resource + * @param dir {string} base directory of resource type + * @return {nothing} results stored in this object + */ _preloadFileController: function(dest, source, mojitType, fullpath, dir) { - if (! this._libs.path.existsSync(fullpath)) { + if (!this._libs.path.existsSync(fullpath)) { return; } if ('.js' !== libpath.extname(fullpath)) { return; } - //logger.log('----------------------- preloadFileController -- ' + fullpath); - var resid, res = {}, + //logger.log('----------------------- preloadFileController -- ' + + // fullpath); + var resid, + res = {}, pathParts = this._parsePath(fullpath, 'server', dir); + if (this._skipBadPath(pathParts)) { + return; + } res.type = 'controller'; res.fsPath = fullpath; @@ -1624,47 +2158,63 @@

    MojitoServer  0.1.0

    }, + /* + * preloads metadata for a resource which is a language bundle + * + * @param dest {object} where to store the metadata of the resource + * @param source {string} "fw", "app", or "mojit" + * @param mojitType {string} name of mojit type, might be null + * @param fullpath {string} path to resource + * @param dir {string} base directory of resource type + * @return {nothing} results stored in this object + */ _preloadFileLang: function(dest, source, mojitType, fullpath, dir) { - if (! this._libs.path.existsSync(fullpath)) { + if (!this._libs.path.existsSync(fullpath)) { return; } if ('.js' !== libpath.extname(fullpath)) { return; } //logger.log('----------------------- preloadFileLang -- ' + fullpath); - var resid, res = {}, + var resid, + res = {}, pathParts = {}, - matches, code; + matches, + code; // YUI-intl doesn't support our ".affinity." filename syntax. pathParts.ext = libpath.extname(fullpath); pathParts.shortpath = libpath.basename(fullpath, pathParts.ext); + if (this._skipBadPath(pathParts)) { + return; + } // There is not a "lang" for the default language file matches = pathParts.shortpath.match(/^([^_]+)(?:_([^_.]+))?$/) || []; - // TODO: [bug 4647407] Check this as we could have names with underscores - // YUI-intl expects default language to have no code on the filename. - // (In practice it's 'en', but don't assume that here.) - code = matches[2] || ""; + // TODO: [Issue 10] Check this as we could have names with + // underscores YUI-intl expects default language to have no code on the + // filename. (In practice it's 'en', but don't assume that here.) + code = matches[2] || ''; res.type = 'yui-lang'; res.fsPath = fullpath; res.source = source; + res.langCode = code; this._precalcYuiModule(res); this._precalcStaticURL(res, mojitType); resid = 'yui-lang-' + pathParts.shortpath; // Check the mojitType has a "lang" entry - if(!this._mojitLangs[mojitType]){ + if (!this._mojitLangs[mojitType]) { this._mojitLangs[mojitType] = []; } // If we have a "lang" code add it to the list - if(code){ + if (code) { this._mojitLangs[mojitType].push(code); } - + pathParts.affinity = 'common'; pathParts.contextKey = 'lang=' + code; pathParts.contextParts = {lang: code}; @@ -1672,16 +2222,30 @@

    MojitoServer  0.1.0

    }, + /* + * preloads metadata for a resource which is a model + * + * @param dest {object} where to store the metadata of the resource + * @param source {string} "fw", "app", or "mojit" + * @param mojitType {string} name of mojit type, might be null + * @param fullpath {string} path to resource + * @param dir {string} base directory of resource type + * @return {nothing} results stored in this object + */ _preloadFileModel: function(dest, source, mojitType, fullpath, dir) { - if (! this._libs.path.existsSync(fullpath)) { + if (!this._libs.path.existsSync(fullpath)) { return; } if ('.js' !== libpath.extname(fullpath)) { return; } //logger.log('----------------------- preloadFileModel -- ' + fullpath); - var resid, res = {}, + var resid, + res = {}, pathParts = this._parsePath(fullpath, 'server', dir); + if (this._skipBadPath(pathParts)) { + return; + } res.type = 'model'; res.fsPath = fullpath; @@ -1695,13 +2259,81 @@

    MojitoServer  0.1.0

    }, + /* + * preloads metadata for a resource which is a mojit instance specification + * + * @param dest {object} where to store the metadata of the resource + * @param source {string} "fw", "app", or "mojit" + * @param mojitType {string} name of mojit type, might be null + * @param fullpath {string} path to resource + * @param dir {string} base directory of resource type + * @return {nothing} results stored in this object + */ + _preloadFileSpec: function(dest, source, mojitType, fullpath, dir) { + var name, + url, + config, + appConfig, + prefix; + + if (!this._libs.path.existsSync(fullpath)) { + return; + } + + appConfig = this._appConfigStatic.staticHandling || {}; + prefix = '/static'; + if (typeof appConfig.prefix !== 'undefined') { + prefix = appConfig.prefix ? '/' + appConfig.prefix : ''; + } + + // TODO: this might benefit from using _parsePath() + + // Set the URL of the spec + url = prefix + '/' + mojitType + '/specs/' + libpath.basename(fullpath); + + // Set the name to the mojit type (this is for namespacing) + name = mojitType; + + // If the filename is not "default" add it to the spec name + if (libpath.basename(fullpath) !== 'default.json') { + name += ':' + + libpath.basename(fullpath).split('.').slice(0, -1).join('.'); + } + + config = this._readConfigYCB({}, fullpath); + + // Just incase this has not been made + if (!this._appConfigStatic.specs) { + this._appConfigStatic.specs = {}; + } + + // Add our spec to the specs map + this._appConfigStatic.specs[name] = config; + + // Add our spec to the Dynamic URLs list + this._dynamicURLs[url] = fullpath; + }, + + + /* + * preloads metadata for a resource which is a view + * + * @param dest {object} where to store the metadata of the resource + * @param source {string} "fw", "app", or "mojit" + * @param mojitType {string} name of mojit type, might be null + * @param fullpath {string} path to resource + * @param dir {string} base directory of resource type + * @return {nothing} results stored in this object + */ _preloadFileView: function(dest, source, mojitType, fullpath, dir) { - if (! this._libs.path.existsSync(fullpath)) { + if (!this._libs.path.existsSync(fullpath)) { return; } //logger.log('----------------------- preloadFileView -- ' + fullpath); - var resid, res = {}, - parts, pathParts = {affinity: 'common', contextKey: '*', contextParts: {}}; + var resid, + res = {}, + parts, + pathParts = {affinity: 'common', contextKey: '*', contextParts: {}}; // views don't support our ".affinity." filename syntax. pathParts.ext = libpath.extname(fullpath); @@ -1710,15 +2342,20 @@

    MojitoServer  0.1.0

    pathParts.shortpath = libpath.basename(fullpath, pathParts.ext); parts = pathParts.shortpath.split('.'); pathParts.viewEngine = parts.pop(); - pathParts.name = libpath.join(libpath.dirname(pathParts.relpath), parts.shift()); + pathParts.name = libpath.join(libpath.dirname(pathParts.relpath), + parts.shift()); if (parts.length) { pathParts.contextParts.device = parts.join('.'); pathParts.contextKey = libqs.stringify(pathParts.contextParts); } - + if (this._skipBadPath(pathParts)) { + return; + } + // Catch if the view has no engine i.e. "index.html" not "index.mu.html" - if(!pathParts.name || pathParts.shortpath === pathParts.viewEngine){ - logger.log('Mojit view not loaded at "'+fullpath+'"', 'warn', NAME); + if (!pathParts.name || pathParts.shortpath === pathParts.viewEngine) { + logger.log('Mojit view not loaded at "' + fullpath + '"', 'warn', + NAME); return; } @@ -1734,81 +2371,47 @@

    MojitoServer  0.1.0

    this._preloadSetDest(dest, resid, res, pathParts); }, + /* - * TODO: Ric added this, needs review. - * * Note: this MUST be called before _preloadFileSpec() + * + * generates URL's about each spec in application.json */ - _urlsForAppSpecs: function(){ - - var specs = this._appConfigNC.specs || {}, - appConfig, prefix, id, url; - - appConfig = this._appConfigNC.staticHandling || {}; + _urlsForAppSpecs: function() { + var specs = this._appConfigStatic.specs || {}, + appConfig, + prefix, + id, + url; + + appConfig = this._appConfigStatic.staticHandling || {}; prefix = '/static'; - if(typeof appConfig.prefix !== 'undefined'){ - prefix = appConfig.prefix ? '/'+appConfig.prefix : ''; + if (typeof appConfig.prefix !== 'undefined') { + prefix = appConfig.prefix ? '/' + appConfig.prefix : ''; } - - for(id in specs){ + + for (id in specs) { if (specs.hasOwnProperty(id)) { // Set the URL of the spec - // TODO 2011-06-16: use appconfig.staticHandling.appName - url = prefix+'/'+id+'/specs/default.json'; + // TODO: use appconfig.staticHandling.appName + url = prefix + '/' + id + '/specs/default.json'; this._dynamicURLs[url] = 'application.json'; } } }, + /* - * TODO: Ric added this, needs review. + * prereads the configuration file, if possible + * (configuration files in YCB format cannot be preread) */ - _preloadFileSpec: function(dest, source, mojitType, fullpath, dir) { - - var name, url, config, appConfig, prefix; - - if (! this._libs.path.existsSync(fullpath)) { - return; - } - - appConfig = this._appConfigNC.staticHandling || {}; - prefix = '/static'; - - if(typeof appConfig.prefix !== 'undefined'){ - prefix = appConfig.prefix ? '/'+appConfig.prefix : ''; - } - - // Set the URL of the spec - url = prefix+'/'+mojitType+'/specs/'+libpath.basename(fullpath); - - // Set the name to the mojit type (this is for namespacing) - name = mojitType; - - // If the filename is not "default" add it to the spec name - if(libpath.basename(fullpath) !== 'default.json'){ - name+= ':'+libpath.basename(fullpath).split('.').slice(0,-1).join('.'); - } - - config = this._readConfigYCB({}, fullpath); - - // Just incase this has not been made - if(!this._appConfigNC.specs){ - this._appConfigNC.specs = {}; - } - - // Add our spec to the specs map - this._appConfigNC.specs[name] = config; - - // Add our spec to the Dynamic URLs list - this._dynamicURLs[url] = fullpath; - }, - - _prereadConfigs: function(src) { - var ctxKey, res, resid; + var ctxKey, + res, + resid; - if ((! src) || (! Object.keys(src))) { + if ((!src) || (!Object.keys(src))) { return; } for (ctxKey in src.contexts) { @@ -1816,9 +2419,12 @@

    MojitoServer  0.1.0

    for (resid in src[ctxKey]) { if (src[ctxKey].hasOwnProperty(resid)) { res = src[ctxKey][resid]; - if ('config' === res.type && !this._configCache[res.fsPath]) { - //logger.log('prereading ' + res.fsPath, 'info', NAME); - this._configCache[res.fsPath] = this._readConfigJSON(res.fsPath); + if ('config' === res.type && + !this._jsonCache[res.fsPath]) { + //logger.log('prereading ' + res.fsPath, 'info', + // NAME); + this._jsonCache[res.fsPath] = + this._readConfigJSON(res.fsPath); } } } @@ -1827,52 +2433,174 @@

    MojitoServer  0.1.0

    }, + /* + * reads and parses a JSON file + */ _readConfigJSON: function(fullpath) { //logger.log('_readConfigJSON(' + fullpath + ')'); - var json, contents = this._libs.fs.readFileSync(fullpath, 'utf-8'); + var json, + contents = this._libs.fs.readFileSync(fullpath, 'utf-8'); + try { json = JSON.parse(contents); - } - catch (e) { - logger.log(this._reportJavaScriptSyntaxErrors(contents, fullpath), 'warn', NAME); - throw new Error("Error parsing JSON file: " + fullpath); + } catch (e) { + logger.log(this._reportJavaScriptSyntaxErrors(contents, fullpath), + 'warn', NAME); + throw new Error('Error parsing JSON file: ' + fullpath); } return json; }, - _readConfigYCB: function(ctx, fullpath) { - var contents, + /* + * Create a lookup table for validating YCB dimensions and values. The + * table looks like this: + * + * <pre> + * { + * "dim1": { + * "val1": null, + * "val2": null, + * ... + * }, + * ... + * } + * </pre> + * + * @param dimensions {object} Top-level YCB "dimensions" object + * @return object + */ + _precalcValidYCBDimensions: function(dimensions) { + var validDims = {}, + name, + i; + + for (i = 0; i < dimensions.length; i += 1) { + for (name in dimensions[i]) { + if (dimensions[i].hasOwnProperty(name)) { + validDims[name] = {}; + this._flattenYCBDimension(validDims[name], + dimensions[i][name]); + } + } + } + + return validDims; + }, + + + /* + * Flatten the keys in a nested structure into a single object. The first + * argument is modified. All values are set to null. + * + * @param keys {object} The accumulator for keys. + * @param obj {object} + */ + _flattenYCBDimension: function(keys, obj) { + var name; + + for (name in obj) { + if (obj.hasOwnProperty(name)) { + keys[name] = null; + if (typeof obj[name] === 'object') { + this._flattenYCBDimension(keys, obj[name]); + } + } + } + }, + + + /* + * Return a context that contains only valid dimensions and values. + * + * @param ctx {object} runtime context + * @return {object} filtered runtime context + */ + _getValidYCBContext: function(ctx) { + var validDims = this._validYCBDims, + validCtx = {}, + name, + value; + + for (name in ctx) { + if (ctx.hasOwnProperty(name)) { + value = ctx[name]; + if (validDims[name] && validDims[name].hasOwnProperty(value)) { + validCtx[name] = value; + } + } + } + return validCtx; + }, + + + /* + * reads a configuration file that is in YCB format + * @param ctx {object} runtime context + * @param fullpath {string} path to the YCB file + * @param isAppConfig {boolean} indicates whether the file being read is the application.json + * @return {object} the contextualized configuration + */ + _readConfigYCB: function(ctx, fullpath, isAppConfig) { + var cacheKey, + appConfigStatic, + jsonCache = this._jsonCache, + json, + ycbCache = this._ycbCache, ycb; + + ctx = this._getValidYCBContext(ctx); + + //cache key only needs to account for dynamic context + cacheKey = JSON.stringify(ctx); + //logger.log('_readConfigYCB('+fullpath+')', 'mojito', NAME); - if (! fullpath) { + if (!fullpath) { //logger.log('unknown fullpath', 'mojito', NAME); return {}; } - contents = this._configCache[fullpath]; - if (! contents) { - contents = this._readConfigJSON(fullpath); - this._configCache[fullpath] = contents; + if (!ycbCache[fullpath]) { + ycbCache[fullpath] = {}; } - // TODO: bug #4942368, cache smarter so that context can be applied - ycb = this._ycbCache[fullpath]; - if (! ycb) { + ycb = ycbCache[fullpath][cacheKey]; + if (!ycb) { + json = jsonCache[fullpath]; + if (!json) { + json = this._readConfigJSON(fullpath); + jsonCache[fullpath] = json; + } + json = this._ycbDims.concat(json); + + ctx = this._mergeRecursive(this._cloneObj(this._defaultYCBContext), + ctx); + // libycb.read() will distructively modify its first argument - ycb = libycb.read(this._cloneObj(contents), {} /*ctx*/); - this._ycbCache[fullpath] = ycb; + ycb = libycb.read(this._cloneObj(json), ctx); + if (isAppConfig) { + appConfigStatic = this._cloneObj(this._appConfigStatic); + ycb = this._mergeRecursive(appConfigStatic, ycb); + } + ycbCache[fullpath][cacheKey] = ycb; } - return ycb; }, + /* + * reads a configuration file for a mojit + * @param path {string} path to the file + * @param ycb {boolean} indicates whether the file should be read using the YCB library + * @return {object} the configuration + */ _readMojitConfigFile: function(path, ycb) { //logger.log('_readMojitConfigFile(' + path + ',' + ycb + ')'); - var json, contents; - if (! this._libs.path.existsSync(path)) { + var json, + contents; + + if (!this._libs.path.existsSync(path)) { return {}; } if (ycb) { @@ -1881,20 +2609,35 @@

    MojitoServer  0.1.0

    try { contents = this._libs.fs.readFileSync(path, 'utf-8'); json = JSON.parse(contents); - } - catch (e) { - logger.log(this._reportJavaScriptSyntaxErrors(contents, path), 'warn', NAME); - throw new Error("Error reading or parsing JSON file: " + path); + } catch (e) { + logger.log(this._reportJavaScriptSyntaxErrors(contents, path), + 'warn', NAME); + throw new Error('Error reading or parsing JSON file: ' + path); } return json; }, + /* + * Sets up the static handling so that the package.json file for the + * mojit can be served. This is only done if the package.json file + * has defined yahoo.mojito.package or config.mojito.package to + * "public". + * + * @param pack {object} contents of the mojit's package.json file + * @param path {string} the mojit's directory + * @return {nothing} results are added to this object + */ _mojitPackageAsAsset: function(pack, path) { - var pkg, packagePath, fakeResource; + var pkg, + packagePath, + fakeResource; + + pkg = (pack.yahoo && pack.yahoo.mojito && + pack.yahoo.mojito['package']) || + (pack.config && pack.config.mojito && + pack.config.mojito['package']); - pkg = (pack.yahoo && pack.yahoo.mojito && pack.yahoo.mojito['package']) || - (pack.config && pack.config.mojito && pack.config.mojito['package']); if (pkg === 'public') { // We have to check if the "package.json" files wants to do this packagePath = libpath.join(path, 'package.json'); @@ -1902,26 +2645,38 @@

    MojitoServer  0.1.0

    type: 'package', fsPath: packagePath }; - this._precalcStaticURL(fakeResource, (pack.name || libpath.basename(path))); + this._precalcStaticURL(fakeResource, (pack.name || + libpath.basename(path))); } }, + /* + * checks to see if the version of Mojito specified in a mojit's + * package.json matches the current verison of Mojito. + * + * @param pack {object} contents of the mojit's package.json file + * @param version {string} current version of mojito + * @return {boolean} returns true if the mojit can be used + */ _mojitoVersionMatch: function(pack, version) { var packageVersion; + // There was no package.json file so assume version is OK if (Object.keys(pack).length === 0) { return true; } // If we have a version make sure it is less than the given one - packageVersion = (pack.yahoo && pack.yahoo.mojito && pack.yahoo.mojito.version) || + packageVersion = (pack.yahoo && pack.yahoo.mojito && + pack.yahoo.mojito.version) || (pack.config && pack.config.mojito && pack.config.mojito.version); + if (packageVersion) { if (packageVersion === '*') { return true; } - // TODO: [bug 4647440] Put real version checking code here + // TODO: [Issue 95] Put real version checking code here. return packageVersion <= version; } @@ -1930,13 +2685,42 @@

    MojitoServer  0.1.0

    }, + /* + * takes the preloaded info and resolves ("cooks down") affinity, etc + * + * This function is a doozy. This is where all the magic happens as far + * as which version of each resource is used. The results are stored in + * this._fwMeta, _appMeta, _mojitMeta, etc. The primary key of these is + * the environment ("client" or "server"). The secondary key is the + * context key -- a string representation of the partial context. + * + * We do that to have fast lookup during runtime. + * + * The algorithm chooses first from the most specific source: mojit- + * specific has higher precedence than app-level, which has higher + * precedence than framework-provided. Within each of those, the + * environment-specific version ("client" or "server") has higher + * precedence than the "common" affinity. + * + * We do this for each context key (partial context). We resolve + * context inheritance (for example no-context versus device=iphone) + * at runtime (in getMojitTypeDetails()). + * + * (Half of the above algorithm is implemented here, and half in + * _cookdownMerge() which is a utility for this method.) + */ _cookdown: function() { //logger.log('_cookdown()'); - var env, envs = [ 'client', 'server' ], - type, i, merged, - resid, resids, ctxKey; + var env, + envs = ['client', 'server'], + type, // mojit type + i, + merged, // results of _cookdownMerge() + resid, + resids, // array (really object keys) of all resource IDs + ctxKey; - // _preload.mojitMeta is + // example of _preload.mojitMeta: // [type][resid][affinity] = { // "contexts": { "device=iphone": { "device":"iphone"} }, // "device=iphone": { @@ -1944,14 +2728,16 @@

    MojitoServer  0.1.0

    // "fsPath": ... // } // } - // resid was generated during _preloadFile*() - // for example controller is 'controller' - // model is 'model-docs' + // resid was generated during _preloadFile*(), for example: + // controller is 'controller' + // model is 'model-foo' // view is 'view-index' - // TODO DREW 2011-06-16: [bug 4647391] break down into smaller pieces (at least for more fine-grained unit testing) + // + // TODO 2011-06-16: [Issue 109] break down into smaller pieces + // (at least for more fine-grained unit testing). for (type in this._preload.mojitMeta) { if (this._preload.mojitMeta.hasOwnProperty(type)) { - // TODO LINT 2011-06-16: [bug 4647450] detect dupe resids + // TODO: LINT [Issue 110] detect dupe resids. resids = {}; // need resids from all sources @@ -1973,32 +2759,43 @@

    MojitoServer  0.1.0

    for (resid in resids) { if (resids.hasOwnProperty(resid)) { - for (i=0; i<envs.length; i++) { + for (i = 0; i < envs.length; i += 1) { env = envs[i]; merged = this._cookdownMerge(env, [ // ORDER IS IMPORTANT - this._preload.fwMeta[resid], // source=fw - this._preload.appMeta[resid], // source=app - this._preload.mojitMeta[type][resid] // source=mojit + // source=fw -- lowest priority + this._preload.fwMeta[resid], + // source=app -- middle priority + this._preload.appMeta[resid], + // source=mojit -- highest priority + this._preload.mojitMeta[type][resid] ]); if (merged) { - if (! this._mojitMeta[env]) { + if (!this._mojitMeta[env]) { this._mojitMeta[env] = {}; } - if (! this._mojitMeta[env][type]) { + if (!this._mojitMeta[env][type]) { this._mojitMeta[env][type] = {}; } - if (! this._mojitMeta[env][type].contexts) { + if (!this._mojitMeta[env][type].contexts) { this._mojitMeta[env][type].contexts = {}; } for (ctxKey in merged.contexts) { - if (merged.contexts.hasOwnProperty(ctxKey)) { - this._mojitMeta[env][type].contexts[ctxKey] = merged.contexts[ctxKey]; - if (! this._mojitMeta[env][type][ctxKey]) { - this._mojitMeta[env][type][ctxKey] = {}; + if (merged.contexts. + hasOwnProperty(ctxKey)) { + this._mojitMeta[env][type + ].contexts[ctxKey] = + merged.contexts[ctxKey]; + if (!this._mojitMeta[env + ][type][ctxKey]) { + this._mojitMeta[env + ][type][ctxKey] = {}; } - // TODO DREW 2011-06-16: give example of datastructure - this._mojitMeta[env][type][ctxKey][resid] = merged[ctxKey]; + // TODO: give example of + // data structure. + this._mojitMeta[env + ][type][ctxKey][resid] = + merged[ctxKey]; } } } // have merged @@ -2010,53 +2807,55 @@

    MojitoServer  0.1.0

    for (resid in this._preload.fwMeta) { if (this._preload.fwMeta.hasOwnProperty(resid)) { - for (i=0; i<envs.length; i++) { + for (i = 0; i < envs.length; i += 1) { env = envs[i]; - merged = this._cookdownMerge(env, [ - this._preload.fwMeta[resid] - ]); + merged = this._cookdownMerge(env, + [this._preload.fwMeta[resid]]); if (merged) { - if (! this._fwMeta[env]) { + if (!this._fwMeta[env]) { this._fwMeta[env] = {}; } - if (! this._fwMeta[env].contexts) { + if (!this._fwMeta[env].contexts) { this._fwMeta[env].contexts = {}; } for (ctxKey in merged.contexts) { if (merged.contexts.hasOwnProperty(ctxKey)) { - this._fwMeta[env].contexts[ctxKey] = merged.contexts[ctxKey]; - if (! this._fwMeta[env][ctxKey]) { + this._fwMeta[env].contexts[ctxKey] = + merged.contexts[ctxKey]; + if (!this._fwMeta[env][ctxKey]) { this._fwMeta[env][ctxKey] = {}; } - this._fwMeta[env][ctxKey][resid] = merged[ctxKey]; + this._fwMeta[env][ctxKey][resid] = + merged[ctxKey]; } } } } } } - + for (resid in this._preload.appMeta) { if (this._preload.appMeta.hasOwnProperty(resid)) { - for (i=0; i<envs.length; i++) { + for (i = 0; i < envs.length; i += 1) { env = envs[i]; - merged = this._cookdownMerge(env, [ - this._preload.appMeta[resid] - ]); + merged = this._cookdownMerge(env, + [this._preload.appMeta[resid]]); if (merged) { - if (! this._appMeta[env]) { + if (!this._appMeta[env]) { this._appMeta[env] = {}; } - if (! this._appMeta[env].contexts) { + if (!this._appMeta[env].contexts) { this._appMeta[env].contexts = {}; } for (ctxKey in merged.contexts) { if (merged.contexts.hasOwnProperty(ctxKey)) { - this._appMeta[env].contexts[ctxKey] = merged.contexts[ctxKey]; - if (! this._appMeta[env][ctxKey]) { + this._appMeta[env].contexts[ctxKey] = + merged.contexts[ctxKey]; + if (!this._appMeta[env][ctxKey]) { this._appMeta[env][ctxKey] = {}; } - this._appMeta[env][ctxKey][resid] = merged[ctxKey]; + this._appMeta[env][ctxKey][resid] = + merged[ctxKey]; } } } @@ -2067,18 +2866,87 @@

    MojitoServer  0.1.0

    }, - _precalcYuiDependencies: function() { - var e, i, env, envs = [ 'client', 'server' ], - mojitType, ctxKey, module, - parts, required, resid, res, - sorted, ctxs, onlyLoadNecessary = true; + /* + * This is a utility for _cookdown(). See docs on that for details. + * + * The general idea is that we start with the lowest priority items + * and let higher priority items clobber. + * + * @param env {string} "client" or "server" + * @param srcs {array} ORDER MATTERS! list of resources to merge + * @return {DOING} DOING + */ + _cookdownMerge: function(env, srcs) { + var merged = { contexts: {} }, + affinities = ['common', env], // priority order + s, + src, + lastS = srcs.length - 1, + found = false, // TODO: when is found==false? + a, + affinity, + ctx, + res, + ctxKey; + + for (s = 0; s < srcs.length; s += 1) { + src = srcs[s]; + if (!src) { + continue; + } + for (a = 0; a < affinities.length; a += 1) { + affinity = affinities[a]; + if (!src[affinity]) { + continue; + } + for (ctxKey in src[affinity].contexts) { + if (src[affinity].contexts.hasOwnProperty(ctxKey)) { + merged.contexts[ctxKey] = + src[affinity].contexts[ctxKey]; + res = this._cloneObj(src[affinity][ctxKey]); + if (('config' === res.type) && (s !== lastS)) { + // only pull in configs from the last source + continue; + } + merged.type = res.type; + merged[ctxKey] = res; + found = true; + } + } + } + } + if (!found) { + return null; + } + return merged; + }, + - for (e=0; e<envs.length; e++) { + /* + * calculates, at server start time, the YUI module dependencies + * for mojit controllers and binders + */ + _precalcYuiDependencies: function() { + var e, + i, + env, + envs = ['client', 'server'], + mojitType, + ctxKey, + module, + parts, + required, + resid, + res, + sorted, + ctxs; + + for (e = 0; e < envs.length; e += 1) { env = envs[e]; // mojit-specific // -------------- - if (! this._mojitYuiSorted[env]) { + if (!this._mojitYuiSorted[env]) { this._mojitYuiRequired[env] = {}; this._mojitYuiSorted[env] = {}; this._mojitYuiSortedPaths[env] = {}; @@ -2086,124 +2954,194 @@

    MojitoServer  0.1.0

    for (mojitType in this._mojitMeta[env]) { if (this._mojitMeta[env].hasOwnProperty(mojitType)) { - if (! this._mojitYuiSorted[env][mojitType]) { + if (!this._mojitYuiSorted[env][mojitType]) { this._mojitYuiRequired[env][mojitType] = {}; this._mojitYuiSorted[env][mojitType] = {}; this._mojitYuiSortedPaths[env][mojitType] = {}; } for (ctxKey in this._mojitMeta[env][mojitType].contexts) { - if (this._mojitMeta[env][mojitType].contexts.hasOwnProperty(ctxKey)) { + if (this._mojitMeta[env + ][mojitType].contexts.hasOwnProperty(ctxKey)) { + + // we handle non-context version below if ('*' === ctxKey) { continue; } - if (! this._mojitYuiSorted[env][mojitType].contexts) { - this._mojitYuiRequired[env][mojitType].contexts = {}; - this._mojitYuiSorted[env][mojitType].contexts = {}; - this._mojitYuiSortedPaths[env][mojitType].contexts = {}; + if (!this._mojitYuiSorted[env + ][mojitType].contexts) { + this._mojitYuiRequired[env + ][mojitType].contexts = {}; + this._mojitYuiSorted[env + ][mojitType].contexts = {}; + this._mojitYuiSortedPaths[env + ][mojitType].contexts = {}; } parts = {}; - this._precalcYuiDependencies_getDepParts(env, this._mojitMeta[env][mojitType]['*'], parts); - this._precalcYuiDependencies_getDepParts(env, this._mojitMeta[env][mojitType][ctxKey], parts); - if (parts.controller && parts.modules['inlinecss/'+mojitType]) { - parts.modules[parts.controller.yuiModuleName].requires.push('inlinecss/'+mojitType); + this._precalcYuiDependencies_getDepParts(env, + this._mojitMeta[env][mojitType]['*'], parts); + this._precalcYuiDependencies_getDepParts(env, + this._mojitMeta[env][mojitType][ctxKey], parts); + if (parts.controller && + parts.modules['inlinecss/' + mojitType]) { + parts.modules[parts.controller.yuiModuleName]. + requires.push('inlinecss/' + mojitType); } - this._mojitYuiSorted[env][mojitType].contexts[ctxKey] = - this._mojitMeta[env][mojitType].contexts[ctxKey]; - this._mojitYuiRequired[env][mojitType].contexts[ctxKey] = - this._mojitMeta[env][mojitType].contexts[ctxKey]; + this._mojitYuiSorted[env + ][mojitType].contexts[ctxKey] = + this._mojitMeta[env + ][mojitType].contexts[ctxKey]; + this._mojitYuiRequired[env + ][mojitType].contexts[ctxKey] = + this._mojitMeta[env + ][mojitType].contexts[ctxKey]; if (parts.controller) { - parts.required[parts.controller.yuiModuleName] = true; + parts.required[parts.controller.yuiModuleName] = + true; // dependencies necessary to dispatch the mojit parts.required['mojito-dispatcher'] = true; sorted = this._sortYUIModules( - this._mojitMeta[env][mojitType].contexts[ctxKey], - env, this._appConfigNC.yui, mojitType, parts.modules, parts.required); - this._mojitYuiRequired[env][mojitType][ctxKey] = Object.keys(parts.required); - this._mojitYuiSorted[env][mojitType][ctxKey] = sorted.sorted; - this._mojitYuiSortedPaths[env][mojitType][ctxKey] = sorted.paths; + this._mojitMeta[env][mojitType + ].contexts[ctxKey], + env, + this._appConfigStatic.yui, + mojitType, + parts.modules, + parts.required + ); + this._mojitYuiRequired[env + ][mojitType][ctxKey] = + Object.keys(parts.required); + this._mojitYuiSorted[env + ][mojitType][ctxKey] = sorted.sorted; + this._mojitYuiSortedPaths[env + ][mojitType][ctxKey] = sorted.paths; } // also calculate sortedPaths for each individual binder if ('client' === env) { - for (resid in this._mojitMeta[env][mojitType][ctxKey]) { - if (this._mojitMeta[env][mojitType][ctxKey].hasOwnProperty(resid)) { - res = this._mojitMeta[env][mojitType][ctxKey][resid]; + for (resid in this._mojitMeta[env + ][mojitType][ctxKey]) { + if (this._mojitMeta[env + ][mojitType][ctxKey + ].hasOwnProperty(resid)) { + res = this._mojitMeta[env + ][mojitType][ctxKey][resid]; if (res.type !== 'binder') { continue; } required = {}; required[res.yuiModuleName] = true; - // all binders have this dependency, even if not explicitly given + // all binders have this dependency, + // even if not explicitly given required['mojito-client'] = true; - // view engines are needed to support mojitProxy.render() + // view engines are needed to support + // mojitProxy.render() for (i in parts.viewEngines) { - if (parts.viewEngines.hasOwnProperty(i)) { - required[parts.viewEngines[i]] = true; + if (parts.viewEngines. + hasOwnProperty(i)) { + required[parts.viewEngines[i]] = + true; } } sorted = this._sortYUIModules( - this._mojitMeta[env][mojitType].contexts[ctxKey], - env, this._appConfigNC.yui, mojitType, parts.modules, required); + this._mojitMeta[env][mojitType + ].contexts[ctxKey], + env, + this._appConfigStatic.yui, + mojitType, + parts.modules, + required + ); res.yuiSortedPaths = sorted.paths; } } - } - } // foreach context (except '*') - } + } // env==client + } + } // foreach context (except '*') + // here's where we handle the non-context version if (this._mojitMeta[env][mojitType]['*']) { - if (! this._mojitYuiSorted[env][mojitType].contexts) { - this._mojitYuiRequired[env][mojitType].contexts = {}; + if (!this._mojitYuiSorted[env][mojitType].contexts) { + this._mojitYuiRequired[env + ][mojitType].contexts = {}; this._mojitYuiSorted[env][mojitType].contexts = {}; - this._mojitYuiSortedPaths[env][mojitType].contexts = {}; + this._mojitYuiSortedPaths[env + ][mojitType].contexts = {}; } parts = {}; - this._precalcYuiDependencies_getDepParts(env, this._mojitMeta[env][mojitType]['*'], parts); - if (parts.controller && parts.modules['inlinecss/'+mojitType]) { - parts.modules[parts.controller.yuiModuleName].requires.push('inlinecss/'+mojitType); + this._precalcYuiDependencies_getDepParts(env, + this._mojitMeta[env][mojitType]['*'], + parts); + if (parts.controller && parts.modules['inlinecss/' + + mojitType]) { + parts.modules[parts.controller.yuiModuleName]. + requires.push('inlinecss/' + mojitType); } this._mojitYuiSorted[env][mojitType].contexts['*'] = - this._mojitMeta[env][mojitType].contexts['*']; + this._mojitMeta[env][mojitType].contexts['*']; this._mojitYuiRequired[env][mojitType].contexts['*'] = - this._mojitMeta[env][mojitType].contexts['*']; + this._mojitMeta[env][mojitType].contexts['*']; if (parts.controller) { - parts.required[parts.controller.yuiModuleName] = true; + parts.required[parts.controller.yuiModuleName] = + true; // dependencies necessary to dispatch the mojit parts.required['mojito-dispatcher'] = true; sorted = this._sortYUIModules( this._mojitMeta[env][mojitType].contexts['*'], - env, this._appConfigNC.yui, mojitType, parts.modules, parts.required); - this._mojitYuiRequired[env][mojitType]['*'] = Object.keys(parts.required); - this._mojitYuiSorted[env][mojitType]['*'] = sorted.sorted; - this._mojitYuiSortedPaths[env][mojitType]['*'] = sorted.paths; + env, + this._appConfigStatic.yui, + mojitType, + parts.modules, + parts.required + ); + this._mojitYuiRequired[env][mojitType]['*'] = + Object.keys(parts.required); + this._mojitYuiSorted[env][mojitType]['*'] = + sorted.sorted; + this._mojitYuiSortedPaths[env][mojitType]['*'] = + sorted.paths; } // also calculate sortedPaths for each individual binder if ('client' === env) { - for (resid in this._mojitMeta[env][mojitType]['*']) { - if (this._mojitMeta[env][mojitType]['*'].hasOwnProperty(resid)) { - res = this._mojitMeta[env][mojitType]['*'][resid]; + for (resid in this._mojitMeta[env + ][mojitType]['*']) { + if (this._mojitMeta[env][mojitType + ]['*'].hasOwnProperty(resid)) { + res = this._mojitMeta[env][mojitType + ]['*'][resid]; if (res.type !== 'binder') { continue; } required = {}; required[res.yuiModuleName] = true; - // all binders have this dependency, even if not explicitly given + // all binders have this dependency, even if + // not explicitly given required['mojito-client'] = true; - // view engines are needed to support mojitProxy.render() + // view engines are needed to support + // mojitProxy.render() for (i in parts.viewEngines) { - if (parts.viewEngines.hasOwnProperty(i)) { - required[parts.viewEngines[i]] = true; + if (parts.viewEngines. + hasOwnProperty(i) + ) { + required[parts.viewEngines[i]] = + true; } } sorted = this._sortYUIModules( - this._mojitMeta[env][mojitType].contexts['*'], - env, this._appConfigNC.yui, mojitType, parts.modules, required); + this._mojitMeta[env][mojitType + ].contexts['*'], + env, + this._appConfigStatic.yui, + mojitType, + parts.modules, + required + ); res.yuiSortedPaths = sorted.paths; } } - } + } // env==client } // context=='*' } } // foreach mojitType @@ -2218,11 +3156,20 @@

    MojitoServer  0.1.0

    // requires: list of required modules // } // .moduleSources hash yuiModuleName:source - // .required hash yuiModuleName:true of modules required by the source controller + // .required hash yuiModuleName:true of modules required by the + // source controller // .viewEngines hash name:yuiModuleName of view engines + // + // @param env {string} "client" or "server" + // @param source {object} list of resources + // @param dest {object} where to add results + // @return {nothing} results put in "dest" argument _precalcYuiDependencies_getDepParts: function(env, source, dest) { - var resid, res, viewEngine; - if (! source) { + var resid, + res, + viewEngine; + + if (!source) { return; } dest.required = dest.required || {}; @@ -2230,7 +3177,8 @@

    MojitoServer  0.1.0

    dest.modules = dest.modules || {}; dest.moduleSources = dest.moduleSources || {}; - // all mojits essentially have this dependency implicitly (even it not given explicitly) + // all mojits essentially have this dependency implicitly (even it not + // given explicitly) dest.required.mojito = true; for (resid in source) { @@ -2240,7 +3188,8 @@

    MojitoServer  0.1.0

    viewEngine = source['addon-view-engines-' + res.viewEngine]; if (viewEngine) { dest.required[viewEngine.yuiModuleName] = true; - dest.viewEngines[res.viewEngine] = viewEngine.yuiModuleName; + dest.viewEngines[res.viewEngine] = + viewEngine.yuiModuleName; } } if (res.yuiModuleName) { @@ -2254,92 +3203,177 @@

    MojitoServer  0.1.0

    } dest.modules[res.yuiModuleName] = { requires: res.yuiModuleMeta.requires, - fullpath: (('client' === env) ? res.staticHandlerURL : res.fsPath) + fullpath: (('client' === env) ? + res.staticHandlerURL : + res.fsPath) }; dest.moduleSources[res.yuiModuleName] = res.source; - if (('controller' === res.type) ) { + if (('controller' === res.type)) { dest.controller = res; } } } } - // TODO 2011-08-10 -- move other dynamic dependency adjustments (compiled views inlinecss) here + // TODO: move other dynamic dependency adjustments + // (compiled views inlinecss) here. + }, + + + /* + * uses YUI Loader to sort a list of YUI modules + */ + _sortYUIModules: function(ctx, env, yuiConfig, mojitType, modules, + required) { + var YUI = serverYUI, + Y, + loader, + sortedPaths = {}, + usePrecomputed = -1 !== this._appConfigStatic.yui. + dependencyCalculations.indexOf('precomputed'), + useOnDemand = -1 !== this._appConfigStatic.yui. + dependencyCalculations.indexOf('ondemand'), + j, + module, + info; + + if (!usePrecomputed) { + useOnDemand = true; + } + + if ('client' === env) { + // Use clientYUI to avoid cross-contamination with serverYUI + YUI = clientYUI; + // GlobalConfig is needed on nodejs but is invalid on the client + delete YUI.GlobalConfig; + } + + // We don't actually need the full list, just the base required modules. + // YUI.Loader() will do the rest at runtime. + if (useOnDemand) { + for (module in required) { + if (required.hasOwnProperty(module)) { + sortedPaths[module] = modules[module].fullpath; + } + } + return { sorted: Object.keys(required), paths: sortedPaths }; + } + + Y = YUI().useSync('loader-base'); + loader = new Y.Loader({ lang: ctx.lang }); + + // We need to clear YUI's cached dependencies, since there's no + // guarantee that the previously calculated dependencies have been done + // using the same context as this calculation. + delete YUI.Env._renderedMods; + + // This approach seems odd, but it's what the YUI Configurator is also + // doing. + if (yuiConfig && yuiConfig.base) { + loader.base = yuiConfig.base; + } else { + loader.base = Y.Env.meta.base + Y.Env.meta.root; + } + loader.addGroup({modules: modules}, mojitType); + loader.calculate({required: required}); + for (j = 0; j < loader.sorted.length; j += 1) { + module = loader.sorted[j]; + info = loader.moduleInfo[module]; + if (info) { + sortedPaths[module] = info.fullpath || loader._url(info.path); + } + } + return { sorted: loader.sorted, paths: sortedPaths }; }, + /* + * calculates the static handling URL for a resource + * + * @param res {object} metadata about the resource + * @param mojitType {string} mojit type, can be undefined for non-mojit-specific resources + * @return {nothing} new metadata added to the "res" argument + */ _precalcStaticURL: function(res, mojitType) { /* alternate approach which shows power of precalculating the URL and * then passing it around everywhere - res.staticHandlerURL = '/static/' + Math.floor(Math.random() * 1000000000); + res.staticHandlerURL = '/static/' + Math.floor(Math.random() * + 1000000000); return; */ - var url, parts = [], - path, i, relpath, - config = this._appConfigNC.staticHandling || {}, + var url, + parts = [], + path, + i, + relpath, + config = this._appConfigStatic.staticHandling || {}, prefix = config.prefix, appName = config.appName || this._shortRoot, frameworkName = config.frameworkName || 'mojito', - rollupParts = [], rollupFsPath; - // TODO DREW: [bug 4647457] magic constants should should come from fw.json + rollupParts = [], + rollupFsPath; + + // TODO: [Issue 111] magic constants should should come from fw.json. /* - Server only framework mojits like DaliProxy and HTMLFrameMojit should never have static - URLs associated with them, so we skip them. This never used to be an issue until we added - the "assumeRollups" functionality to preload JSON specs for specified mojits during the - compile step (mojito compile json) for Livestand. I think we need to reevaluate this entire - process so we don't have such a fragile condition below. -- Matt + Server only framework mojits like DaliProxy and HTMLFrameMojit should + never have static URLs associated with them, so we skip them. This never + used to be an issue until we added the "assumeRollups" functionality to + preload JSON specs for specified mojits during the compile step (mojito + compile json) for Livestand. I think we need to reevaluate this entire + process so we don't have such a fragile condition below. */ - // TODO: reevaluate this entire process so we don't have such a fragile condition below. + // TODO: reevaluate this entire process so we don't have such a fragile + // condition below. if (mojitType === 'DaliProxy' || mojitType === 'HTMLFrameMojit') { return; } switch (res.type) { - case 'action': - path = libpath.join('actions', libpath.basename(res.fsPath)); - break; - case 'addon': - i = res.fsPath.indexOf('/addons/'); - relpath = res.fsPath.substr(i+8); - path = libpath.join('addons', relpath); - break; - case 'asset': - i = res.fsPath.indexOf('/assets/'); - relpath = res.fsPath.substr(i+8); - path = libpath.join('assets', relpath); - break; - case 'binder': - i = res.fsPath.indexOf('/binders/'); - relpath = res.fsPath.substr(i+9); - path = libpath.join('binders', relpath); - break; - case 'controller': - path = libpath.basename(res.fsPath); - break; - case 'model': - path = libpath.join('models', libpath.basename(res.fsPath)); - break; - case 'view': - i = res.fsPath.indexOf('/views/'); - relpath = res.fsPath.substr(i+7); - path = libpath.join('views', relpath); - break; - case 'yui-lang': - path = libpath.join('lang', libpath.basename(res.fsPath)); - break; - case 'yui-module': - i = res.fsPath.indexOf('/autoload/'); - relpath = res.fsPath.substr(i+10); - path = libpath.join('autoload', relpath); - break; - case 'package': - path = libpath.basename(res.fsPath); - break; - default: - return; + case 'action': + path = libpath.join('actions', libpath.basename(res.fsPath)); + break; + case 'addon': + i = res.fsPath.indexOf('/addons/'); + relpath = res.fsPath.substr(i + 8); + path = libpath.join('addons', relpath); + break; + case 'asset': + i = res.fsPath.indexOf('/assets/'); + relpath = res.fsPath.substr(i + 8); + path = libpath.join('assets', relpath); + break; + case 'binder': + i = res.fsPath.indexOf('/binders/'); + relpath = res.fsPath.substr(i + 9); + path = libpath.join('binders', relpath); + break; + case 'controller': + path = libpath.basename(res.fsPath); + break; + case 'model': + path = libpath.join('models', libpath.basename(res.fsPath)); + break; + case 'view': + i = res.fsPath.indexOf('/views/'); + relpath = res.fsPath.substr(i + 7); + path = libpath.join('views', relpath); + break; + case 'yui-lang': + path = libpath.join('lang', libpath.basename(res.fsPath)); + break; + case 'yui-module': + i = res.fsPath.indexOf('/autoload/'); + relpath = res.fsPath.substr(i + 10); + path = libpath.join('autoload', relpath); + break; + case 'package': + path = libpath.basename(res.fsPath); + break; + default: + return; } - if (! config.hasOwnProperty('prefix')) { + if (!config.hasOwnProperty('prefix')) { prefix = 'static'; } if (prefix) { @@ -2354,35 +3388,37 @@

    MojitoServer  0.1.0

    rollupParts.push(appName); rollupFsPath = libpath.join(this._root, 'rollup.client.js'); } - } - else if ('app' === res.source) { + } else if ('app' === res.source) { parts.push(appName); if (config.useRollups && res.yuiModuleName) { rollupParts.push(appName); rollupFsPath = libpath.join(this._root, 'rollup.client.js'); } - } - else { + } else { parts.push(mojitType); if (config.useRollups && res.yuiModuleName) { rollupParts.push(mojitType); - rollupFsPath = libpath.join(this._mojitPaths[mojitType], 'rollup.client.js'); + rollupFsPath = libpath.join(this._mojitPaths[mojitType], + 'rollup.client.js'); } } if (mojitType) { - if (! this._mojitAssetRoots[mojitType]) { - this._mojitAssetRoots[mojitType] = '/' + libpath.join(parts.join('/'), 'assets'); + if (!this._mojitAssetRoots[mojitType]) { + this._mojitAssetRoots[mojitType] = '/' + + libpath.join(parts.join('/'), 'assets'); } } // only use rollup URL if rollup file exists or we are assuming rollups - if ((rollupFsPath && this._libs.path.existsSync(rollupFsPath) && config.useRollups) || this._appConfigNC.assumeRollups) { + if ((rollupFsPath && this._libs.path.existsSync(rollupFsPath) && + config.useRollups) || this._appConfigStatic.assumeRollups) { // useful for debugging: path += '?orig=' + path; - res.rollupURL = '/' + libpath.join(rollupParts.join('/'), 'rollup.client.js'); + res.rollupURL = '/' + libpath.join(rollupParts.join('/'), + 'rollup.client.js'); url = res.rollupURL; this._staticURLs[url] = rollupFsPath; } - if (! url) { + if (!url) { url = '/' + libpath.join(parts.join('/'), path); this._staticURLs[url] = res.fsPath; } @@ -2390,7 +3426,12 @@

    MojitoServer  0.1.0

    }, - // attempt to gather YUI-module details + /* + * attempt to gather YUI-module details + * + * @param res {object} metadata about the resource + * @return {nothing} new metadata added to the "res" argument + */ _precalcYuiModule: function(res) { var file = this._libs.fs.readFileSync(res.fsPath, 'utf8'), ctx = { @@ -2400,27 +3441,29 @@

    MojitoServer  0.1.0

    window: {}, document: {}, YUI: { - add: function(name,fn,version,meta) { + add: function(name, fn, version, meta) { res.yuiModuleName = name; res.yuiModuleVersion = version; res.yuiModuleMeta = meta || {}; } } }; + try { libvm.runInNewContext(file, ctx, res.fsPath); - } - catch (e) { + } catch (e) { if (e.stack.indexOf('SyntaxError:') === 0) { // the stack of a SyntaxError thrown by runInNewContext() lacks - // filename, line and column numbers for the error. Also, it does - // not write to stderr as the docs claim. + // filename, line and column numbers for the error. Also, it + // does not write to stderr as the docs claim. // see "Lack of error message in vm.* stuff" from 2011-04-29 at - // http://groups.google.com/group/nodejs/browse_thread/thread/2075b964a3f7dd79/bd0df1ae36829813 + // http://groups.google.com/group/nodejs/browse_thread/ + // thread/2075b964a3f7dd79/bd0df1ae36829813 logger.log(this._reportJavaScriptSyntaxErrors(file)); - logger.log(e.message + ' in file: ' + res.fsPath, 'error', NAME); + logger.log(e.message + ' in file: ' + res.fsPath, 'error', + NAME); } else { logger.log(e.message + '\n' + e.stack, 'error', NAME); @@ -2430,71 +3473,50 @@

    MojitoServer  0.1.0

    }, - _getMojitConfig: function(env, ctx, mojitIn, name) { - //logger.log('_getMojitConfig('+env+','+mojitIn+','+name+')'); - var resid, res, mojit, - appConfig, specs, spec; - - mojit = mojitIn; - resid = 'config-' + name; + /* + * reads one the configuration files for a mojit + * + * @param env {string} "client" or "server" + * @param ctx {object} runtime context + * @param mojitType {string} name of mojit + * @param name {string} config resource name, either "definition" or "defaults" + */ + _getMojitConfig: function(env, ctx, mojitType, name) { + //logger.log('_getMojitConfig('+env+','+mojitType+','+name+')'); + var resid, + res; - if (! this._mojitMeta[env][mojit]) { - throw new Error("Cannot find meta data for mojit type \"" + mojit + "\""); + if (!this._mojitMeta[env][mojitType]) { + throw new Error('Cannot find meta data for mojit type \"' + mojitType + + '\"'); } - res = this._getContextualizedResource(this._mojitMeta[env][mojit], ctx, resid); - if (! res) { + resid = 'config-' + name; + res = this._getContextualizedResource(this._mojitMeta[env][mojitType], ctx, + resid); + if (!res) { return {}; } return this._readConfigYCB(ctx, res.fsPath); }, - _sortYUIModules: function(ctx, env, yuiConfig, mojitType, modules, required) { - var Y, loader, sortedPaths = {}, j, module, info; - Y = YUI().useSync('loader-base'); - loader = new Y.Loader({ lang: ctx.lang }); - - // We need to clear YUI's cached dependencies, since there's no guarantee that - // the previously calculated dependencies have been done using the same context - // as this calculation. - delete YUI.Env._renderedMods; - - // This approach seems odd, but it's what the YUI Configurator is also doing. - if (yuiConfig && yuiConfig.base) { - loader.base = yuiConfig.base; - } - else { - loader.base = Y.Env.meta.base + Y.Env.meta.root; - } - loader.addGroup({modules: modules}, mojitType); - loader.calculate({required: required}); - // This is required because loader.calculate() isn't taking into consideration - // conditional modules. - // http://yuilibrary.com/projects/yui3/ticket/2530343 - if ('server' === env) { - loader.sorted.unshift('io-nodejs'); - loader.sorted.unshift('nodejs-node'); - loader.sorted.unshift('nodejs-dom'); - } - for (j=0; j<loader.sorted.length; j++) { - module = loader.sorted[j]; - info = loader.moduleInfo[module]; - if (info) { - sortedPaths[module] = info.fullpath || loader._url(info.path); - } - } - return { sorted: loader.sorted, paths: sortedPaths }; - }, - - + /* + * returns whether a runtime context matches a partial context + * + * @param ctx {object} runtime context + * @param ctxParts {object} partial context + */ _matchContext: function(ctx, ctxParts) { var k; + for (k in ctxParts) { if (ctxParts.hasOwnProperty(k)) { - // FUTURE -- handle "lang" slightly specially ("en" should match "en-US") - // For now we will skip the "lang" check as is could change on the fly in the client - // and we need all the "lang" files avaliable in our YUI instance. + // FUTURE -- handle "lang" slightly specially ("en" should match + // "en-US") + // For now we will skip the "lang" check as it could change on + // the fly in the client and we need all the "lang" files + // available in our YUI instance. if (k !== 'lang' && ctx[k] !== ctxParts[k]) { return false; } @@ -2504,13 +3526,22 @@

    MojitoServer  0.1.0

    }, + /* + * returns a list of resource metadata that match the context + * + * @param src {object} list of contextualized resources, key is contextKey + * @param ctx {object} context to match + * @return {object} list of resources, key is resource ID + */ _getResourceListForContext: function(src, ctx) { - var list = {}, // key: value - key, ctxKey; + var list = {}, // resid: resource + resid, + ctxKey; + if (src['*']) { - for (key in src['*']) { - if (src['*'].hasOwnProperty(key)) { - list[key] = src['*'][key]; + for (resid in src['*']) { + if (src['*'].hasOwnProperty(resid)) { + list[resid] = src['*'][resid]; } } } @@ -2519,12 +3550,12 @@

    MojitoServer  0.1.0

    if ('*' === ctxKey) { continue; } - if (! this._matchContext(ctx, src.contexts[ctxKey])) { + if (!this._matchContext(ctx, src.contexts[ctxKey])) { continue; } - for (key in src[ctxKey]) { - if (src[ctxKey].hasOwnProperty(key)) { - list[key] = src[ctxKey][key]; + for (resid in src[ctxKey]) { + if (src[ctxKey].hasOwnProperty(resid)) { + list[resid] = src[ctxKey][resid]; } } } @@ -2533,9 +3564,20 @@

    MojitoServer  0.1.0

    }, + /* + * returns a list of the language resources + * doesn't discriminate based on context: returns all langs for all + * contexts. + * + * @param src {object} list of contextualized resources, key is contextKey + * @return {object} list of language resources, key is resource ID + */ _getLangList: function(src) { var list = {}, // resid: res - ctxKey, resid, res; + ctxKey, + resid, + res; + for (ctxKey in src.contexts) { if (src.contexts.hasOwnProperty(ctxKey)) { for (resid in src[ctxKey]) { @@ -2552,51 +3594,20 @@

    MojitoServer  0.1.0

    }, - // TODO DREW 2011-06-16: [bug 4647391] more comments, example, etc. get knuthy - // this is an "affinity resolver" - _cookdownMerge: function(env, srcs) { - var merged = {contexts: {}}, - affinities = [ 'common', env ], - s, src, lastS = srcs.length - 1, - found = false, // TODO DREW 2011-06-16: when is found==false? - a, affinity, ctx, res, ctxKey; - for (s=0; s<srcs.length; s++) { - src = srcs[s]; - if (! src) { - continue; - } - for (a=0; a<affinities.length; a++) { - affinity = affinities[a]; - if (! src[affinity]) { - continue; - } - for (ctxKey in src[affinity].contexts) { - if (src[affinity].contexts.hasOwnProperty(ctxKey)) { - merged.contexts[ctxKey] = src[affinity].contexts[ctxKey]; - res = this._cloneObj(src[affinity][ctxKey]); - if (('config' === res.type) && (s !== lastS)) { - // only pull in configs from the last source - continue; - } - merged.type = res.type; - merged[ctxKey] = res; - found = true; - } - } - } - } - if (! found) { - return null; - } - return merged; - }, - - + /* + * returns the metadata for a resource specific for a particular runtime context + * + * @param src {object} list of contextualized resources, key is contextKey + * @param ctx {object} context to match + * @param resid {string} ID of resource to find + * @return {object} resource metadata + */ _getContextualizedResource: function(src, ctx, resid) { - var ctxKey, res; + var ctxKey, + res; - // TODO: [bug 4647333] Review, Ric added this for when there is no app.json file - if(!src || !src.contexts){ + // TODO: [Issue 100] Review, for when there is no app.json file. + if (!src || !src.contexts) { return {}; } @@ -2606,7 +3617,7 @@

    MojitoServer  0.1.0

    if ('*' === ctxKey) { continue; } - if (! this._matchContext(ctx, src.contexts[ctxKey])) { + if (!this._matchContext(ctx, src.contexts[ctxKey])) { continue; } res = src[ctxKey][resid]; @@ -2620,16 +3631,25 @@

    MojitoServer  0.1.0

    }, + /* + * utility for the _preloadFile*() methods that sets the new resource metadata + * into a location consistent with the other parts of the algorithm + * + * @param dest {object} where to store the results + * @param resid {string} resource ID + * @param res {object} metadata about the resource + * @param pathParts {object} results of _parsePath(), or the equivalent + */ _preloadSetDest: function(dest, resid, res, pathParts) { - if (! dest[resid]) { + if (!dest[resid]) { dest[resid] = {}; } dest = dest[resid]; - if (! dest[pathParts.affinity]) { + if (!dest[pathParts.affinity]) { dest[pathParts.affinity] = {}; } dest = dest[pathParts.affinity]; - if (! dest.contexts) { + if (!dest.contexts) { dest.contexts = {}; } dest.contexts[pathParts.contextKey] = pathParts.contextParts; @@ -2637,22 +3657,36 @@

    MojitoServer  0.1.0

    }, - // TODO DREW 2011-06-16: [bug 4647391] comment this stuff + /* + * utility for the _preloadFile*() methods that takes a file path + * and returns metadata about it + * + * @param fullpath {string} full path to resource + * @param defaultAffinity {string} affinity to use if the resource filename doesn't specify one + * @param dir {string} base directory of resource type + */ _parsePath: function(fullpath, defaultAffinity, dir) { - var shortpath, reldir, parts, outParts = [], - i, part, device, affinity, + var shortpath, + reldir, + parts, + outParts = [], + i, + part, + device, + affinity, out = { contextKey: '*', contextParts: {}, affinity: defaultAffinity || 'server' }; - if (! dir) { + + if (!dir) { dir = libpath.dirname(fullpath); } dir = libpath.join(dir, '/'); out.relpath = fullpath.substr(dir.length); - // TODO -- support strict {name}.{selector}?.{affinity}?.{ext} syntax + // TODO: support strict {name}.{selector}?.{affinity}?.{ext} syntax. out.ext = libpath.extname(fullpath); shortpath = libpath.basename(out.relpath, out.ext); reldir = libpath.dirname(out.relpath); @@ -2661,14 +3695,15 @@

    MojitoServer  0.1.0

    if (affinity) { out.affinity = affinity; } - device = this._detectDeviceFromShortFilename(shortpath, out.contextParts.device); + device = this._detectDeviceFromShortFilename(shortpath, + out.contextParts.device); if (device) { out.contextParts.device = device; } outParts.push(this._extractRootNameFromShortFilename(shortpath)); - if (! this._objectIsEmpty(out.contextParts)) { + if (!this._objectIsEmpty(out.contextParts)) { out.contextKey = libqs.stringify(out.contextParts); } @@ -2679,51 +3714,95 @@

    MojitoServer  0.1.0

    }, + /* + * indicates whether file should be skipped based on its path + * + * @param pathParts {object} return value of _parsePath() (or the equivalent) + * @return {boolean} true indicates that the file should be skipped + */ + _skipBadPath: function(pathParts) { + var ext = pathParts.ext.substring(1); + if (ext.match(isNotAlphaNum)) { + return true; + } + return false; + }, + + /* * Generate a report of syntax errors for JavaScript code. This is also * very useful to find syntax errors in JSON documents. * * @param {string} js the JavaScript - * @param {string} filename OPTIONAL. the name of the file containing the JavaScript + * @param {string} filename OPTIONAL. the name of the file containing the + * JavaScript * @return {string} if errors were found, a multi-line error report */ _reportJavaScriptSyntaxErrors: function(js, filename) { // use a really lenient JSLINT to find syntax errors - var JSLINT = require('./management/fulljslint').JSLINT, + var jslint = require('./management/fulljslint').jslint, opts = { // turn off all the usual checks - devel: true, browser: true, node: true, rhino: true, widget: true, windows: true, - bitwise: true, regexp: true, confusion: true, undef: true, 'continue': true, - unparam: true, debug: true, sloppy: true, eqeq: true, sub: true, es5: true, - vars: true, evil: true, white: true, forin: true, css: true, newcap: true, - cap: true, nomen: true, on: true, plusplus: true, fragment: true, + devel: true, + browser: true, + node: true, + rhino: true, + widget: true, + windows: true, + bitwise: true, + regexp: true, + confusion: true, + undef: true, + 'continue': true, + unparam: true, + debug: true, + sloppy: true, + eqeq: true, + sub: true, + es5: true, + vars: true, + evil: true, + white: true, + forin: true, + css: true, + newcap: true, + cap: true, + nomen: true, + on: true, + plusplus: true, + fragment: true, // prevent well-known globals from showing up as errors - predef:[ - "exports", // CommonJS - "YUI", "YUI_config", "YAHOO", "YAHOO_config", "Y", // YUI - "global", "process","require", "__filename", "module", // Node - "document", "navigator", "console", "self", "window" // Browser + predef: [ + // CommonJS + 'exports', + // YUI + 'YUI', 'YUI_config', 'YAHOO', 'YAHOO_config', 'Y', + // Node + 'global', 'process', 'require', '__filename', 'module', + // Browser + 'document', 'navigator', 'console', 'self', 'window' ] }, // identify errors about undefined globals - nameIsNotDefined = / is not defined.$/, + nameIsNotDefined = / is not defined\.$/, success, report = [], len, e, i; - success = JSLINT(js, opts); + success = jslint(js, opts); if (!success) { - len = JSLINT.errors.length; - for (i = 0; i < len; i++) { - e = JSLINT.errors[i]; + len = jslint.errors.length; + for (i = 0; i < len; i += 1) { + e = jslint.errors[i]; if (e && e.reason && !nameIsNotDefined.test(e.reason)) { report.push(e.line + ',' + e.character + ': ' + e.reason); - report.push(' ' + (e.evidence || '').replace(/^\s+|\s+$/, '')); + report.push(' ' + + (e.evidence || '').replace(/^\s+|\s+$/, '')); } } } @@ -2736,23 +3815,45 @@

    MojitoServer  0.1.0

    }, + /* + * finds the affinity in the filename + * + * @param name {string} filename + * @return {string|undefined} affinity found in the filename + */ _detectAffinityFromShortFilename: function(name) { var affinity; + if (name.indexOf('.') >= 0) { affinity = new Affinity(name.split('.').pop()); } return affinity; }, + + /* + * finds the device in the filename + * + * @param name {string} filename + * @return {string|undefined} device found in the filename + */ _detectDeviceFromShortFilename: function(name) { - // FUTURE: [bug 4647471]real device detection + // FUTURE: [Issue 86]real device detection var device; + if (name.indexOf('iphone') > -1) { device = 'iphone'; } return device; }, + + /* + * returns the selector for the runtime context + * + * @param ctx {object} runtime context + * @return {string|null} selector for context + */ _selectorFromContext: function(ctx) { if (ctx.device) { return ctx.device; @@ -2760,8 +3861,16 @@

    MojitoServer  0.1.0

    return null; }, + + /* + * returns the short filename without the selector + * + * @param name {string} short filename + * @return {string} short filename without the selector + */ _extractRootNameFromShortFilename: function(name) { var parts; + if (name.indexOf('.') === -1) { return name; } @@ -2770,34 +3879,45 @@

    MojitoServer  0.1.0

    return parts.join('.'); }, + + // returns true if the object is empty _objectIsEmpty: function(o) { - if (! o) { + if (!o) { return true; } return (0 === Object.keys(o).length); }, - // from http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically/383245#383245 + // from http://stackoverflow.com/questions/171251/ + // how-can-i-merge-properties-of-two-javascript-objects-dynamically/ + // 383245#383245 /* - * Recursively merge properties of two objects - */ + * Recursively merge one object onto another + * + * @param dest {object} object to merge into + * @param src {object} object to merge onto "dest" + * @param matchType {boolean} controls whether a non-object in the src is + * allowed to clobber a non-object in the dest (if a different type) + * @return {object} the modified "dest" object is also returned directly + */ _mergeRecursive: function(dest, src, typeMatch) { var p; + for (p in src) { if (src.hasOwnProperty(p)) { // Property in destination object set; update its value. - if ( src[p] && src[p].constructor === Object ) { - if(!dest[p]){ + if (src[p] && src[p].constructor === Object) { + if (!dest[p]) { dest[p] = {}; } dest[p] = this._mergeRecursive(dest[p], src[p]); } else { - if(dest[p] && typeMatch){ - if(typeof dest[p] === typeof src[p]){ + if (dest[p] && typeMatch) { + if (typeof dest[p] === typeof src[p]) { dest[p] = src[p]; } - }else{ + } else { dest[p] = src[p]; } } @@ -2807,35 +3927,52 @@

    MojitoServer  0.1.0

    }, + // deep copies an object _cloneObj: function(o) { - var newO, i; + var newO, + i; - if(typeof(o) !== 'object') { + if (typeof o !== 'object') { return o; } - if(!o) { + if (!o) { return o; } if ('[object Array]' === Object.prototype.toString.apply(o)) { newO = []; - for(i=0; i<o.length; i++) { + for (i = 0; i < o.length; i += 1) { newO[i] = this._cloneObj(o[i]); } return newO; } newO = {}; - for(i in o) { + for (i in o) { if (o.hasOwnProperty(i)) { newO[i] = this._cloneObj(o[i]); } } return newO; + }, + + + /* + * A wrapper for fs.readdirSync() that guarantees ordering. The order in + * which the file system is walked is significant within the resource + * store, e.g., when looking up a matching context. + * + * @param path {string} directory to read + * @return {array} files in the directory + */ + _sortedReaddirSync: function(path) { + var out = this._libs.fs.readdirSync(path); + return out.sort(); } }; + module.exports = ServerStore;
    @@ -2858,16 +3995,9 @@

    Modules

    @@ -2876,27 +4006,11 @@

    Classes

    Files

    --> @@ -2914,7 +4028,7 @@

    Files

    diff --git a/docs/api/transport.client-optional.js.html b/docs/api/transport.client-optional.js.html index 618f6e874..c223fcd46 100644 --- a/docs/api/transport.client-optional.js.html +++ b/docs/api/transport.client-optional.js.html @@ -2,23 +2,23 @@ - API: ActionContext transport.client-optional.js (YUI Library) + Mojito API: CommonLibs transport.client-optional.js ( - - + + - - + +
    -

    mojito

    -

    ActionContext  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > ActionContext + > CommonLibs > transport.client-optional.js (source view) @@ -47,143 +47,188 @@

    ActionContext  0.1.0

    -
    YUI.add('dali-transport-base', function(Y) {
    -	
    -	var NAME = 'transport',
    +
    /*
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
    + */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
    +YUI.add('dali-transport-base', function(Y) {
    +
    +    var NAME = 'transport',
     
             //YUI method shortcuts
    -        Lang         = Y.Lang,
    -        isArray      = Lang.isArray,
    -		
    -		// events
    -		INJECTION_COMPLETE = 'injd',
    -        
    -		// beans
    -        _requestHandler;
    -	
    -	var Transport = function() {
    -		var inst = {
    -			name: NAME,
    -			setRequestHandler: function(handler) {
    -				if (_requestHandler) { 
    -					_requestHandler.removeTarget(this);
    -					_requestHandler.detach(); 
    -				}
    -				_requestHandler = handler;
    -				// bubble up request events
    -				_requestHandler.addTarget(this);
    -			},
    -			getRequestHandler: function() {
    -				return _requestHandler;
    -			},
    -			
    -	        /**
    -	         * Disables all Ajax requests for the application. 
    -	         * 
    -	         * @method disable
    -	         * @param {Boolean} queue (Optional) When set to true, queues all requests while disabled. 
    -	         */
    -	        disable:function(/* boolean */ queue){
    -	            _requestHandler.disable(queue);
    -	        },
    -	
    -	        /**
    -	         * Enables sending of requests.    
    -	         * @method enable 
    -	         * @static
    -	         */
    -	        enable:function(){
    -	            _requestHandler.enable();
    -	        },
    -			
    -			isEnabled: function() {
    -				return _requestHandler.isEnabled();
    -			},
    -	        
    -	        makeRequest: function (data, callback, id) {
    -	             // Y.log('Making request...', 'info', NAME);
    -	             if(_requestHandler.isEnabled()){
    -	                 if(isArray(data) && data.length > 1){
    -	                     for (var i=0, len=data.length; i < len; i++) {
    -						 	// all arrays of requests are assumed to be batchable by default
    -							if (data[i].batchable === undefined) {
    -							 	data[i].batchable = true; 
    -							}
    -	                        _requestHandler.processRequest(data[i], callback, id);
    -	                     }
    -	                     return null; //no trackable id for an array
    -	                 }else{
    -	                     return _requestHandler.processRequest((isArray(data) ? data[0] : data), callback, id);
    -	                 } 
    -	             }else{
    -	                 // Y.log('Transport is disabled!', 'warn', NAME);
    -	                 return false;
    -	             }
    -	         },
    -			 
    -	         getMetrics:function(requestId){
    -	             return _requestHandler.getMetrics(requestId);
    -	         },
    -	         
    -	         clearMetrics:function(requestId){
    -	             _requestHandler.clearMetrics(requestId);
    -	         },
    -			 
    -	         abortRequest: function (requestId, moduleId){
    -	             return _requestHandler.abortRequest(requestId, moduleId);
    -	         },
    -			 
    -			 abortModuleRequests: function(moduleId) {
    -			 	return _requestHandler.abortModuleRequests(moduleId);
    -			 },
    -			 
    -			 isRequestPending: function(requestId, moduleId) {
    -			 	return _requestHandler.isRequestPending(requestId, moduleId);
    -			 },
    -			 
    -	        /**
    -	         * Sets the request formatter function for a given request type.
    -	         * @param {String} requestType The type of request that the formatter should handle.
    -	         * @param {Function} formatter The function to call to format the request.
    -	         * @method setRequestFormatter
    -	         */
    -	         setRequestFormatter:function(requestType, formatter) {
    -			 	_requestHandler.replaceRequestFormatter(requestType, formatter);
    -	         },
    -	     
    -	         /**
    -	          * Sets the response formatter function for all responses.
    -	          * @param {Function} formatter The function to call to format the response object.
    -	          * @method setResponseFormatter
    -	          */
    -	         setResponseFormatter:function(formatter){
    -				_requestHandler.replaceResponseFormatter(formatter);
    -	         },
    -			 
    -			 /**
    -			  * Called by the bean registry whenever this bean is reinitialized
    -			  */
    -			 destroy: function() {
    -			 	return true;
    -			 }
    -			  
    -		};
    -		// this will make the transport available globally if there is no Module Platform once
    -		// all beans have been injected
    -		Y.Dali.beanRegistry.on(INJECTION_COMPLETE, function() {
    +        Lang = Y.Lang,
    +        isArray = Lang.isArray,
    +
    +        // events
    +        INJECTION_COMPLETE = 'injd',
    +
    +        // beans
    +        _requestHandler,
    +        Transport;
    +
    +
    +    Transport = function() {
    +
    +        var inst = {
    +
    +            name: NAME,
    +
    +
    +            setRequestHandler: function(handler) {
    +                if (_requestHandler) {
    +                    _requestHandler.removeTarget(this);
    +                    _requestHandler.detach();
    +                }
    +                _requestHandler = handler;
    +                // bubble up request events
    +                _requestHandler.addTarget(this);
    +            },
    +
    +
    +            getRequestHandler: function() {
    +                return _requestHandler;
    +            },
    +
    +
    +            /**
    +             * Disables all Ajax requests for the application.
    +             * @param {Boolean} queue (Optional) When set to true, queues all
    +             *     requests while disabled.
    +             */
    +            disable: function(queue) {
    +                _requestHandler.disable(queue);
    +            },
    +
    +
    +            /**
    +             * Enables sending of requests.
    +             */
    +            enable: function() {
    +                _requestHandler.enable();
    +            },
    +
    +
    +            isEnabled: function() {
    +                return _requestHandler.isEnabled();
    +            },
    +
    +
    +            makeRequest: function(data, callback, id) {
    +                var i,
    +                    len;
    +
    +                // Y.log('Making request...', 'info', NAME);
    +                if (_requestHandler.isEnabled()) {
    +                    if (isArray(data) && data.length > 1) {
    +                        for (i = 0, len = data.length; i < len; i += 1) {
    +                            // all arrays of requests are assumed to be
    +                            // batchable by default
    +                            if (data[i].batchable === undefined) {
    +                                data[i].batchable = true;
    +                            }
    +                            _requestHandler.processRequest(data[i], callback,
    +                                id);
    +                        }
    +                        return null; //no trackable id for an array
    +                    } else {
    +                        return _requestHandler.processRequest(
    +                            (isArray(data) ?
    +                                    data[0] :
    +                                    data),
    +                            callback,
    +                            id
    +                        );
    +                    }
    +                } else {
    +                    // Y.log('Transport is disabled!', 'warn', NAME);
    +                    return false;
    +                }
    +            },
    +
    +
    +            getMetrics: function(requestId) {
    +                return _requestHandler.getMetrics(requestId);
    +            },
    +
    +
    +            clearMetrics: function(requestId) {
    +                _requestHandler.clearMetrics(requestId);
    +            },
    +
    +
    +            abortRequest: function(requestId, moduleId) {
    +                return _requestHandler.abortRequest(requestId, moduleId);
    +            },
    +
    +
    +            abortModuleRequests: function(moduleId) {
    +                return _requestHandler.abortModuleRequests(moduleId);
    +            },
    +
    +
    +            isRequestPending: function(requestId, moduleId) {
    +                return _requestHandler.isRequestPending(requestId, moduleId);
    +            },
    +
    +
    +            /**
    +             * Sets the request formatter function for a given request type.
    +             * @param {String} requestType The type of request that the
    +             *     formatter should handle.
    +             * @param {Function} formatter The function to call to format the
    +             *     request.
    +             */
    +            setRequestFormatter: function(requestType, formatter) {
    +                _requestHandler.replaceRequestFormatter(requestType, formatter);
    +            },
    +
    +
    +            /**
    +             * Sets the response formatter function for all responses.
    +             * @param {Function} formatter The function to call to format the
    +             *     response object.
    +             */
    +            setResponseFormatter: function(formatter) {
    +                _requestHandler.replaceResponseFormatter(formatter);
    +            },
    +
    +
    +            /**
    +             * Called by the bean registry whenever this bean is reinitialized
    +             */
    +            destroy: function() {
    +                return true;
    +            }
    +        };
    +
    +        // this will make the transport available globally if there is no Module
    +        // Platform once all beans have been injected
    +        Y.Dali.beanRegistry.on(INJECTION_COMPLETE, function() {
                 if (!Y.Dali && !Y.Dali.Platform) {
                     Y.namespace('Dali');
    -                Y.Dali.transport = new Transport();                
    +                Y.Dali.transport = new Transport();
                 }
             });
    -		return new Y.Dali.Bean(inst);
    -	};
    -	
    -	Transport.NAME = NAME;
    -	
    -	Y.Dali.beanRegistry.registerBean(NAME, Transport);
    -		
    -}, '1.6.3', {requires:['event-custom', 'breg', 'dali-bean']});
    +
    +        return new Y.Dali.Bean(inst);
    +    };
    +
    +    Transport.NAME = NAME;
    +
    +    Y.Dali.beanRegistry.registerBean(NAME, Transport);
    +
    +}, '1.6.3', {requires: [
    +    'event-custom',
    +    'breg',
    +    'dali-bean'
    +]});
     
    @@ -194,9 +239,9 @@

    ActionContext  0.1.0

    diff --git a/docs/api/transport_utils.client-optional.js.html b/docs/api/transport_utils.client-optional.js.html index 62d6b062b..8fc59d236 100644 --- a/docs/api/transport_utils.client-optional.js.html +++ b/docs/api/transport_utils.client-optional.js.html @@ -2,23 +2,23 @@ - API: ActionContext transport_utils.client-optional.js (YUI Library) + Mojito API: CommonLibs transport_utils.client-optional.js ( - - + + - - + +
    -

    mojito

    -

    ActionContext  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > ActionContext + > CommonLibs > transport_utils.client-optional.js (source view) @@ -47,22 +47,36 @@

    ActionContext  0.1.0

    -
    YUI.add('transport-utils', function(Y) {
    -	var NAME = 'transportUtils';
    -	
    -	function TransportUtils() {
    -		return {
    -			formatUrl: function(url, data){
    -				return url + ((url.indexOf('?') === -1) ? '?' : '&') + data; 
    -	        }
    -		};
    -	}
    -	
    -	TransportUtils.NAME = NAME;
    -	
    -	Y.Dali.beanRegistry.registerBean(NAME, TransportUtils);
    -	
    -}, '1.6.3', {requires:['breg']});
    +
    /*
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
    + */
    +
    +
    +/*jslint anon:true, sloppy:true*/
    +/*global YUI*/
    +
    +
    +YUI.add('transport-utils', function(Y) {
    +
    +    var NAME = 'transportUtils';
    +
    +    function TransportUtils() {
    +        return {
    +            formatUrl: function(url, data) {
    +                return url + ((url.indexOf('?') === -1) ? '?' : '&') + data;
    +            }
    +        };
    +    }
    +
    +    TransportUtils.NAME = NAME;
    +
    +    Y.Dali.beanRegistry.registerBean(NAME, TransportUtils);
    +
    +}, '1.6.3', {requires: [
    +    'breg'
    +]});
     
    @@ -73,9 +87,9 @@

    ActionContext  0.1.0

    diff --git a/docs/api/tunnel.client-optional.js.html b/docs/api/tunnel.client-optional.js.html index 4a6fa8710..c5ff2d5b8 100644 --- a/docs/api/tunnel.client-optional.js.html +++ b/docs/api/tunnel.client-optional.js.html @@ -2,21 +2,21 @@ - API: CommonLibs tunnel.client-optional.js (YUI Library) + Mojito API: CommonLibs tunnel.client-optional.js ( - - + + - - + +
    -

    mojito

    -

    CommonLibs  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito > CommonLibs @@ -48,18 +48,28 @@

    CommonLibs  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     YUI.add('mojito-tunnel-client', function(Y, NAME) {
     
         function TunnelClient(appConfig) {
             this._appConfig = appConfig;
    +
             var errorReporter = {
    -                error: function(type, msg) {
    -                    throw new Error("TRANSPORT ERROR: " + type + " : " + msg);
    -                }
    -            },
    +            error: function(type, msg) {
    +                throw new Error('TRANSPORT ERROR: ' + type + ' : ' + msg);
    +            }
    +        },
                 configProvider = {
    +
                     getProxyUrl: function() {
                         return appConfig.tunnelPrefix;
                     },
    @@ -72,12 +82,14 @@ 

    CommonLibs  0.1.0

    return 10000; } }; + Y.Dali.beanRegistry.registerBean('errorReporter', errorReporter); Y.Dali.beanRegistry.registerBean('configProvider', configProvider); Y.Dali.beanRegistry.doInjection(); this._transport = Y.Dali.beanRegistry.getBean('transport'); } + TunnelClient.prototype = { rpc: function(command, adapter) { @@ -86,22 +98,34 @@

    CommonLibs  0.1.0

    command.forcepost = true; this._transport.makeRequest(command, { + success: function(resp) { Y.log('rpc success', 'debug', NAME); adapter.done(resp.html, resp.data.meta); }, + failure: function() { Y.log('rpc failure!', 'warn', NAME); Y.log(arguments, 'warn', NAME); } }); - } }; Y.mojito.TunnelClient = TunnelClient; -}, '0.1.0', {requires: ['breg', 'querystring-stringify-simple', 'mojito', 'dali-transport-base', 'request-handler', 'simple-request-formatter', 'requestor', 'io-facade', 'response-formatter', 'response-processor']}); +}, '0.3.0', {requires: [ + 'breg', + 'querystring-stringify-simple', + 'mojito', + 'dali-transport-base', + 'request-handler', + 'simple-request-formatter', + 'requestor', + 'io-facade', + 'response-formatter', + 'response-processor' +]});
    @@ -131,12 +155,27 @@

    Classes

    --> @@ -154,7 +193,7 @@

    Files

    diff --git a/docs/api/url.common.js.html b/docs/api/url.common.js.html index 22981cede..7812db15b 100644 --- a/docs/api/url.common.js.html +++ b/docs/api/url.common.js.html @@ -2,23 +2,23 @@ - API: MojitoServer url.common.js (YUI Library) + Mojito API: ActionContextAddon url.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoServer  0.1.0

    +

    mojito

    +

    ActionContextAddon  0.3.0

    mojito - > MojitoServer + > ActionContextAddon > url.common.js (source view) @@ -48,13 +48,39 @@

    MojitoServer  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true*/
    +/*global YUI*/
    +
    +
     /**
    - * @submodule ActionContextAddon
    + * @module ActionContextAddon
      */
     YUI.add('mojito-url-addon', function(Y, NAME) {
     
    +    function objectToQueryStr(obj, removeEmpty) {
    +        // If "removeEmpty" is true we remove any params with no value.
    +        if (removeEmpty) {
    +            Y.Object.each(obj, function(val, key) {
    +                if (!val) {
    +                    delete obj[key];
    +                }
    +            });
    +        }
    +
    +        if (Y.Lang.isObject(obj) && Y.Object.size(obj) > 0) {
    +            obj = Y.QueryString.stringify(obj);
    +        }
    +
    +        return obj;
    +    }
    +
    +
         /**
          * <strong>Access point:</strong> <em>ac.url.*</em>
          * Generates URL's based on the applictions routing configuration
    @@ -62,24 +88,29 @@ 

    MojitoServer  0.1.0

    */ function UrlAcAddon(command, adapter, ac) { this.maker = new Y.mojito.RouteMaker(ac.app.routes); + this.appConfig = ac.app.config; } + UrlAcAddon.prototype = { namespace: 'url', /** * Generates a URL from the given parameters - * - * @param id {string} it to a mojit defined at the root level of the Mojito application configuration - * @param action {string} - * @param routeParams {object} used to lookup the route in the routing table - * @param verb {string} GET, POST, PUT, DELETE (case insensitive) - * @param urlParams {object} added to the looked up route as query params + * @param {string} base Base mojit defined at the root level of the + * Mojito application configuration. + * @param {string} action Action reference, concatenated to the base + * using a period (.) separator. + * @param {object} routeParams used to lookup the route in the routing + * table. + * @param {string} varb GET, POST, PUT, DELETE (case insensitive). + * @param {object} urlParams added to the looked up route as query + * params. */ - make: function(base, action, routeParams, verb, urlParams){ - - var url, query = base+'.'+action; + make: function(base, action, routeParams, verb, urlParams) { + var url, + query = base + '.' + action; routeParams = objectToQueryStr(routeParams); @@ -89,7 +120,7 @@

    MojitoServer  0.1.0

    url = this.maker.make(query, verb); - if(urlParams){ + if (urlParams) { urlParams = objectToQueryStr(urlParams, true); if (urlParams && urlParams.length) { @@ -97,30 +128,34 @@

    MojitoServer  0.1.0

    } } - // Now we do some bad shit for iOS - if(typeof window !== 'undefined'){ + // IOS PATCH + if (typeof window !== 'undefined') { url = Y.mojito.util.iOSUrl(url); } + // this is mainly used by html5app + if (this.appConfig.pathToRoot) { + url = this.appConfig.pathToRoot + url; + } + return url; }, + /** * Finds the first matching route from the given URL - * - * @method find - * @param url {string} the URL to find a route for - * @param verb {string} the HTTP method + * @param {string} url the URL to find a route for. + * @param {string} verb the HTTP method. */ - find: function(url, verb){ + find: function(url, verb) { // Remove http://some.domain.com/ stuff - if(url.indexOf('http://')===0){ + if (url.indexOf('http://') === 0) { url = url.slice(url.indexOf('/', 7)); } // Remove an query params given - if(url.indexOf('?')>0){ + if (url.indexOf('?') > 0) { url = url.slice(0, url.indexOf('?')); } @@ -128,27 +163,9 @@

    MojitoServer  0.1.0

    } }; - function objectToQueryStr(obj, removeEmpty){ - - // If "removeEmpty" is true we remove any params with no value. - if(removeEmpty){ - Y.Object.each(obj, function(val, key){ - if(!val){ - delete obj[key]; - } - }); - } - - if (Y.Lang.isObject(obj) && Y.Object.size(obj) > 0) { - obj = Y.QueryString.stringify(obj); - } - - return obj; - } - Y.mojito.addons.ac.url = UrlAcAddon; -}, '0.1.0', {requires: [ +}, '0.3.0', {requires: [ 'querystring-stringify-simple', 'mojito-route-maker', 'mojito-util' @@ -164,23 +181,29 @@

    MojitoServer  0.1.0

    Modules

    diff --git a/docs/api/util.common.js.html b/docs/api/util.common.js.html index ca60ed784..c8f0aa0ad 100644 --- a/docs/api/util.common.js.html +++ b/docs/api/util.common.js.html @@ -2,23 +2,23 @@ - API: MojitoClient util.common.js (YUI Library) + Mojito API: CommonLibs util.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoClient  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > MojitoClient + > CommonLibs > util.common.js (source view) @@ -48,38 +48,84 @@

    MojitoClient  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     YUI.add('mojito-util', function(Y) {
     
         var META_AUTOCLOBBER = ['content-type'],
             META_EXCLUDE = ['view'],
             META_ATOMIC = ['content-type'];
     
    +
    +    function arrayContainsLowerCase(a, obj) {
    +        var i = a.length,
    +            selector = obj.toLowerCase();
    +
    +        i -= 1;
    +        while (i >= 0) {
    +            if (a[i].toLowerCase() === selector) {
    +                return true;
    +            }
    +            i -= 1;
    +        }
    +        return false;
    +    }
    +
    +
    +    function shouldAutoClobber(k) {
    +        return arrayContainsLowerCase(META_AUTOCLOBBER, k);
    +    }
    +
    +
    +    function isExcluded(k) {
    +        return arrayContainsLowerCase(META_EXCLUDE, k);
    +    }
    +
    +
    +    function isAtomic(k) {
    +        return arrayContainsLowerCase(META_ATOMIC, k);
    +    }
    +
    +
         Y.mojito.util = {
     
             array: {
    +
                 remove: function(arr, from, to) {
                     var rest = arr.slice((to || from) + 1 || arr.length);
    +
                     arr.length = from < 0 ? arr.length + from : from;
                     return this.push.apply(arr, rest);
                 },
     
                 contains: function(a, obj) {
                     var i = a.length;
    -                while (i--) {
    +
    +                i -= 1;
    +                while (i >= 0) {
                         if (a[i] === obj) {
                             return true;
                         }
    +                    i -= 1;
                     }
                     return false;
                 }
             },
     
    +
             copy: function(obj) {
                 var temp = null,
                     key = '';
    -            if (!obj || typeof(obj) !== 'object') { return obj; }
    +
    +            if (!obj || typeof obj !== 'object') { return obj; }
                 temp = new obj.constructor();
                 for (key in obj) {
                     if (obj.hasOwnProperty(key)) {
    @@ -89,94 +135,104 @@ 

    MojitoClient  0.1.0

    return temp; }, + heir: function(o) { function F() {} F.prototype = o; return new F(); }, + /** - * Used to merge meta objects into each other. Special consideration for certain headers values - * like 'content-type'. - * @method metaMerge + * Used to merge meta objects into each other. Special consideration for + * certain headers values like 'content-type'. * @private - * @param to - * @param from - * @param clobber + * @param {object} to The target object. + * @param {object} from The source object. + * @param {boolean} clobber True to overwrite existing properties. */ - metaMerge: function(to, from, clobber) { - var k, tv, fv, - internal = arguments[3]; + metaMerge: function(to, from, clobber, __internal) { + var k, + tv, + fv, + internal = __internal; + for (k in from) { if (from.hasOwnProperty(k)) { - if (! internal && isExcluded(k)) { - continue; - } - fv = from[k]; - tv = to[k]; - if (! tv) { - // Y.log('replacing ' + k); - to[k] = fv; - } else if (Y.Lang.isArray(fv)) { - // Y.log('from array ' + k); - if (! Y.Lang.isArray(tv)) { - throw new Error("Meta merge error. Type mismatch between mojit metas."); - } - if (shouldAutoClobber(k)) { - if (isAtomic(k)) { - to[k] = [fv[fv.length-1]]; + if (internal || !isExcluded(k)) { + fv = from[k]; + tv = to[k]; + if (!tv) { + // Y.log('replacing ' + k); + to[k] = fv; + } else if (Y.Lang.isArray(fv)) { + // Y.log('from array ' + k); + if (!Y.Lang.isArray(tv)) { + throw new Error('Meta merge error.' + + ' Type mismatch between mojit metas.'); + } + if (shouldAutoClobber(k)) { + if (isAtomic(k)) { + to[k] = [fv[fv.length - 1]]; + } else { + to[k] = fv; + } } else { + tv.push.apply(tv, fv); + } + } else if (Y.Lang.isObject(fv)) { + // Y.log('from object ' + k); + if (Y.Lang.isObject(tv)) { + // Y.log('merging ' + k); + to[k] = Y.mojito.util.metaMerge(tv, fv, clobber, + true); + } else if (Y.Lang.isNull(tv) || + Y.Lang.isUndefined(tv)) { to[k] = fv; + } else { + throw new Error('Meta merge error.' + + ' Type mismatch between mojit metas.'); } - } else { - tv.push.apply(tv, fv); - } - } else if (Y.Lang.isObject(fv)) { - // Y.log('from object ' + k); - if (Y.Lang.isObject(tv)) { - // Y.log('merging ' + k); - to[k] = Y.mojito.util.metaMerge(tv, fv, clobber, true); - } else if (Y.Lang.isNull(tv) || Y.Lang.isUndefined(tv)) { + } else if (clobber) { + // Y.log('clobbering ' + k); to[k] = fv; - } else { - throw new Error("Meta merge error. Type mismatch between mojit metas."); } - } else if (clobber) { - // Y.log('clobbering ' + k); - to[k] = fv; } } } return to; }, - /* + + /** * Recursively merge properties of two objects - * - * @method mergeRecursive - * @param {dest} the destination object - * @param {src} the source object - * @param {typeMatch} Only replace if src and dest types are the same + * @param {object} dest The destination object. + * @param {object} src The source object. + * @param {boolean} typeMatch Only replace if src and dest types are + * the same type if true. */ mergeRecursive: function(dest, src, typeMatch) { var p; + for (p in src) { if (src.hasOwnProperty(p)) { // Property in destination object set; update its value. - if ( src[p] && src[p].constructor === Object ) { - if(!dest[p]){ + // TODO: lousy test. Constructor matches don't always work. + if (src[p] && src[p].constructor === Object) { + if (!dest[p]) { dest[p] = {}; } dest[p] = this.mergeRecursive(dest[p], src[p]); } else { - if(dest[p] && typeMatch){ - if(typeof dest[p] === typeof src[p]){ + if (dest[p] && typeMatch) { + if (typeof dest[p] === typeof src[p]) { dest[p] = src[p]; } - } - // only copy values that are not undefined, null and falsey values should be copied - else if (typeof src[p] !== 'undefined') { - // for null sources, we only want to copy over values that are undefined + } else if (typeof src[p] !== 'undefined') { + // only copy values that are not undefined, null and + // falsey values should be copied + // for null sources, we only want to copy over + // values that are undefined if (src[p] === null) { if (typeof dest[p] === 'undefined') { dest[p] = src[p]; @@ -191,56 +247,38 @@

    MojitoClient  0.1.0

    return dest; }, + /* - * TODO: [bug 4649708] I'm sure we can do this better + * TODO: [Issue 79] I'm sure we can do this better. * * This function trys to make the given URL relative to the * folder the iOS UIWebView is running in. */ - iOSUrl: function(url){ + iOSUrl: function(url) { // If we are not in a DOM, return - if(typeof window === 'undefined'){ + if (typeof window === 'undefined') { return url; } - // Now we do some bad shit for iOS - // Basicly if we are in a UIWebView and its location is a file:// on the device - // we have to make our URL relative to the file that was opened - if(window.location.href.indexOf('file://') === 0 && window.location.href.indexOf('/Applications/') > 0 && window.location.href.indexOf('.app/') > 0){ - if(url.charAt(0) === '/' ){ + // Now we do some bad stuff for iOS + // Basically if we are in a UIWebView and its location is a + // file:// on the device we have to make our URL relative to the + // file that was opened + if (window.location.href.indexOf('file://') === 0 && + window.location.href.indexOf('/Applications/') > 0 && + window.location.href.indexOf('.app/') > 0) { + if (url.charAt(0) === '/') { url = url.slice(1); } } - return url; } }; - function shouldAutoClobber(k) { - return arrayContainsLowerCase(META_AUTOCLOBBER, k); - } - - function isExcluded(k) { - return arrayContainsLowerCase(META_EXCLUDE, k); - } - - function isAtomic(k) { - return arrayContainsLowerCase(META_ATOMIC, k); - } - - function arrayContainsLowerCase(a, obj) { - var i = a.length, - selector = obj.toLowerCase(); - while (i--) { - if (a[i].toLowerCase() === selector) { - return true; - } - } - return false; - } - -}, '0.1.0', {requires: ['mojito']}); +}, '0.3.0', {requires: [ + 'mojito' +]});
    @@ -253,8 +291,8 @@

    Modules

    @@ -262,8 +300,7 @@

    Modules

    @@ -271,16 +308,25 @@

    Classes

    diff --git a/docs/api/view-renderer.common.js.html b/docs/api/view-renderer.common.js.html index 2976479a1..fdcd90c51 100644 --- a/docs/api/view-renderer.common.js.html +++ b/docs/api/view-renderer.common.js.html @@ -2,23 +2,23 @@ - API: MojitoClient view-renderer.common.js (YUI Library) + Mojito API: CommonLibs view-renderer.common.js ( - - + + - - + +
    -

    mojito

    -

    MojitoClient  0.1.0

    +

    mojito

    +

    CommonLibs  0.3.0

    mojito - > MojitoClient + > CommonLibs > view-renderer.common.js (source view) @@ -48,46 +48,55 @@

    MojitoClient  0.1.0

    #doc3 .classopts { display:none; }
    /*
    - * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
    + * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
    + * Copyrights licensed under the New BSD License.
    + * See the accompanying LICENSE file for terms.
      */
    +
    +
    +/*jslint anon:true, sloppy:true, nomen:true*/
    +/*global YUI*/
    +
    +
     YUI.add('mojito-view-renderer', function(Y) {
     
         /*
    -     * Mojito's view renderer abstraction. Will plugin in the specified view plugin to do
    -     * the rendering, depending on the 'type' specified.
    +     * Mojito's view renderer abstraction. Will plugin in the specified view
    +     * plugin to do the rendering, depending on the 'type' specified.
          * @class ViewRenderer
          * @namespace Y.mojit
          * @constructor
          * @param {String} type view engine addon type to use
          */
    -    function Renderer(type, instanceId) {
    +    function Renderer(type, viewId) {
             type = type || 'mu';
    -        this._renderer = new (Y.mojito.addons.viewEngines[type])(instanceId);
    +        this._renderer = new (Y.mojito.addons.viewEngines[type])(viewId);
         }
     
    +
         Renderer.prototype = {
     
             /*
              * Renders a view
    -         * @method render
    -         * @param {Object} data data to push into the view
    -         * @param {string} mojitType name of the mojit type
    -         * @param {Object} tmpl some type of template identifier for the view engine
    -         * @param {Object} adapter
    -         * @param {Object} meta
    -         * @param {boolean} more whether there will be more data to render later (streaming)
    +         * @param {Object} data data to push into the view.
    +         * @param {string} mojitType name of the mojit type.
    +         * @param {Object} tmpl some type of template identifier for the view
    +         *     engine.
    +         * @param {Object} adapter The output adapter.
    +         * @param {Object} meta Optional metadata to use.
    +         * @param {boolean} more Whether there will be more data to render
    +         *     later. (streaming)
              */
             render: function(data, mojitType, tmpl, adapter, meta, more) {
    -
                 this._renderer.render(data, mojitType, tmpl, adapter, meta, more);
    -
             }
    -
         };
     
         Y.mojito.ViewRenderer = Renderer;
     
    -}, '0.1.0', {requries: ['mojito']});
    +}, '0.3.0', {requires: [
    +    'mojito'
    +]});
     
    @@ -100,8 +109,8 @@

    Modules

    @@ -109,8 +118,7 @@

    Modules

    @@ -118,16 +126,25 @@

    Classes

    diff --git a/examples/developer-guide/inter-mojit/package.json b/examples/developer-guide/inter-mojit/package.json index 84e002f0c..99e0b99aa 100644 --- a/examples/developer-guide/inter-mojit/package.json +++ b/examples/developer-guide/inter-mojit/package.json @@ -2,13 +2,23 @@ "name": "inter-mojit", "description": "My hackday 2011 Mojito application", "version": "0.1.0", - "author": "Your Name ", + "author": "Kaamini kaamini@yahoo-inc.com", "contributors": [ { - "name": "Your Name", - "email": "nobody@yahoo-inc.com" + "name": "Kaamini", + "email": "kaamini@yahoo-inc.com" } ], + "yahoo": { + "bugzilla" : { + "product" : "mojito", + "component" : "General" + }, + "dist-package" : { + "tag-name-with-userid" : true, + "srcdirs" : ["http://svn.corp.yahoo.com/view/yahoo/mobile/cocktails/mojito/open_mojito/trunk/examples/developer-guide/inter-mojit/"] + } + }, "scripts": { "start": "mojito start" }, diff --git a/examples/sandbox/bindercomm/mojits/Parent/binders/dyno.js b/examples/sandbox/bindercomm/mojits/Parent/binders/dyno.js index c1384a680..26d0109d2 100644 --- a/examples/sandbox/bindercomm/mojits/Parent/binders/dyno.js +++ b/examples/sandbox/bindercomm/mojits/Parent/binders/dyno.js @@ -31,9 +31,9 @@ YUI.add('ParentBinderDyno', function(Y, NAME) { var mp = this.mp = mojitProxy; this.mp.listen('hover', function(payload) { var source = payload.source; - var child = findChild(source, mp.children); + var child = findChild(source, mp.getChildren()); var order = child.config.order; - var surrounding = findChildrenAround(order, mp.children); + var surrounding = findChildrenAround(order, mp.getChildren()); var i; for (i=0; irpc
    <boolean> Means that we are immediately * sending the request to the server to answer the invocation.
    * - * @param {string} action name of the action to invoke. + * @param {String} action name of the action to invoke. * @param {Object} options see above. - * @param {function} cb function to be called on completion. + * @param {Function} cb function to be called on completion. */ invoke: function(action, options, cb) { var callback, command, instance; @@ -222,8 +222,8 @@ YUI.add('mojito-mojit-proxy', function(Y, NAME) { * Refreshes the current DOM view for this binder without recreating the * binder instance. Will call the binder's onRefreshView() function when * complete with the new Y.Node and HTMLElement objects. - * @param {object} opts same as the options for invoke(). - * @param {function} cb Called after replacement and onRefreshView have + * @param {Object} opts same as the options for invoke(). + * @param {Function} cb Called after replacement and onRefreshView have * been called, sends data/meta. */ refreshView: function(opts, cb) { @@ -238,8 +238,8 @@ YUI.add('mojito-mojit-proxy', function(Y, NAME) { /** * Gets URL parameters - * @param {string} key The name of the parameter required. - * @return {string|object} param value, or all params if no key + * @param {String} key The name of the parameter required. + * @return {String|Object} param value, or all params if no key * specified. */ getFromUrl: function(key) { @@ -259,7 +259,7 @@ YUI.add('mojito-mojit-proxy', function(Y, NAME) { /* * Returns the DOM Node ID for the current binder - * @return {string} YUI GUID + * @return {String} YUI GUID */ getId: function() { return this._viewId; @@ -269,7 +269,7 @@ YUI.add('mojito-mojit-proxy', function(Y, NAME) { /** * Helper function to gather up details about a mojit's children from * the Mojito Client. - * @return {object} slot-->child information. + * @return {Object} slot <String>-->child information <Object>. */ getChildren: function() { return this._client._mojits[this.getId()].children; @@ -280,19 +280,21 @@ YUI.add('mojito-mojit-proxy', function(Y, NAME) { * Clears out a child's view, calling the appropriate life cycle * functions, then destroy's its binder and dereferences it. Will also * dereference the child from this mojit's children. - * @param {string} id Either the slot key of the child, or the DOM + * @param {String} id Either the slot key of the child, or the DOM * view id of the child. - * @param {boolean} retainNode if true, the binder's node will remain in + * @param {Boolean} retainNode if true, the binder's node will remain in * the dom. */ destroyChild: function(id, retainNode) { - var slot, doomed, children = this.getChildren(); - if (children[id]) { - doomed = children[id].viewId; + var slot, doomed, children = this.getChildren(), child = children[id]; + + if (child) { + doomed = child.viewId; + } else { + //child key could be a random YUI Id for (slot in children) { - if (children.hasOwnProperty(slot) && - children[slot].viewId === id) { + if (children.hasOwnProperty(slot) && children[slot].viewId === id) { doomed = id; } } @@ -301,17 +303,21 @@ YUI.add('mojito-mojit-proxy', function(Y, NAME) { throw new Error("Cannot destroy a child mojit with id '" + id + "'. Are you sure this is your child?"); } + this._client.destroyMojitProxy(doomed, retainNode); - delete children[id]; - if (this.config.children) { - delete this.config.children[id]; + + if (child) { + if (this.config.children) { + delete this.config.children[id]; + } + delete children[id]; } }, /** * Destroys all children. (Calls destroyChild() for each child.) - * @param {boolean} retainNode if true, the binder's node will remain in + * @param {Boolean} retainNode if true, the binder's node will remain in * the dom. */ destroyChildren: function(retainNode) { @@ -325,7 +331,7 @@ YUI.add('mojito-mojit-proxy', function(Y, NAME) { /** * Allows a binder to destroy itself and be removed from Mojito client * runtime entirely. - * @param {boolean} retainNode if true, the binder's node will remain in + * @param {Boolean} retainNode if true, the binder's node will remain in * the dom. */ destroySelf: function(retainNode) { diff --git a/source/lib/middleware/mojito-contextualizer.js b/source/lib/app/middleware/mojito-contextualizer.js similarity index 100% rename from source/lib/middleware/mojito-contextualizer.js rename to source/lib/app/middleware/mojito-contextualizer.js diff --git a/source/lib/middleware/mojito-handler-static.js b/source/lib/app/middleware/mojito-handler-static.js similarity index 92% rename from source/lib/middleware/mojito-handler-static.js rename to source/lib/app/middleware/mojito-handler-static.js index 2c9060638..88258b428 100644 --- a/source/lib/middleware/mojito-handler-static.js +++ b/source/lib/app/middleware/mojito-handler-static.js @@ -26,7 +26,7 @@ * Module dependencies. */ var fs = require('fs'), - mime = require('../libs/mime'), + mime = require('../../libs/mime'), pa = require('path'), parseUrl = require('url').parse, logger, @@ -234,22 +234,17 @@ function staticProvider(store, globalLogger) { charset = mime.charsets.lookup(mimetype), // Response headers headers = { - 'Content-Type': mimetype + (charset ? '; charset="' + - charset + '"' : ''), + 'Content-Type': mimetype + (charset ? '; charset=' + + charset : ''), 'Content-Length': stat.size, - //"Last-Modified": stat.ctime.toUTCString(), - // TODO: [Issue 91] See todo below - 'Last-Modified': new Date().toUTCString(), + 'Last-Modified': options.forceUpdate ? new Date().toUTCString() : stat.ctime.toUTCString(), 'Cache-Control': 'public max-age=' + (maxAge / 1000), 'ETag': etag(stat) }; - // TODO: [Issue 91] Removed for dev, need to add a switch - // here - // Conditional GET - //if (!modified(req, headers)) { - // return notModified(res, headers); - //} + if (!options.forceUpdate && !modified(req, headers)) { + return notModified(res, headers); + } // logger.log('(staticProvider) serving static file: ' + // filename); diff --git a/source/lib/middleware/mojito-handler-tunnel.js b/source/lib/app/middleware/mojito-handler-tunnel.js similarity index 100% rename from source/lib/middleware/mojito-handler-tunnel.js rename to source/lib/app/middleware/mojito-handler-tunnel.js diff --git a/source/lib/middleware/mojito-parser-body.js b/source/lib/app/middleware/mojito-parser-body.js similarity index 100% rename from source/lib/middleware/mojito-parser-body.js rename to source/lib/app/middleware/mojito-parser-body.js diff --git a/source/lib/middleware/mojito-parser-cookies.js b/source/lib/app/middleware/mojito-parser-cookies.js similarity index 100% rename from source/lib/middleware/mojito-parser-cookies.js rename to source/lib/app/middleware/mojito-parser-cookies.js diff --git a/source/lib/middleware/mojito-router.js b/source/lib/app/middleware/mojito-router.js similarity index 100% rename from source/lib/middleware/mojito-router.js rename to source/lib/app/middleware/mojito-router.js diff --git a/source/lib/mojits/DaliProxy/autoload/store-provider.server.js b/source/lib/app/mojits/DaliProxy/autoload/store-provider.server.js similarity index 100% rename from source/lib/mojits/DaliProxy/autoload/store-provider.server.js rename to source/lib/app/mojits/DaliProxy/autoload/store-provider.server.js diff --git a/source/lib/mojits/DaliProxy/controller.server.js b/source/lib/app/mojits/DaliProxy/controller.server.js similarity index 100% rename from source/lib/mojits/DaliProxy/controller.server.js rename to source/lib/app/mojits/DaliProxy/controller.server.js diff --git a/source/lib/mojits/DaliProxy/defaults.json b/source/lib/app/mojits/DaliProxy/defaults.json similarity index 100% rename from source/lib/mojits/DaliProxy/defaults.json rename to source/lib/app/mojits/DaliProxy/defaults.json diff --git a/source/lib/mojits/DaliProxy/definition.json b/source/lib/app/mojits/DaliProxy/definition.json similarity index 100% rename from source/lib/mojits/DaliProxy/definition.json rename to source/lib/app/mojits/DaliProxy/definition.json diff --git a/source/lib/mojits/HTMLFrameMojit/controller.server.js b/source/lib/app/mojits/HTMLFrameMojit/controller.server.js similarity index 100% rename from source/lib/mojits/HTMLFrameMojit/controller.server.js rename to source/lib/app/mojits/HTMLFrameMojit/controller.server.js diff --git a/source/lib/mojits/HTMLFrameMojit/definition.json b/source/lib/app/mojits/HTMLFrameMojit/definition.json similarity index 100% rename from source/lib/mojits/HTMLFrameMojit/definition.json rename to source/lib/app/mojits/HTMLFrameMojit/definition.json diff --git a/source/lib/mojits/HTMLFrameMojit/tests/controller.server-tests.js b/source/lib/app/mojits/HTMLFrameMojit/tests/controller.server-tests.js similarity index 100% rename from source/lib/mojits/HTMLFrameMojit/tests/controller.server-tests.js rename to source/lib/app/mojits/HTMLFrameMojit/tests/controller.server-tests.js diff --git a/source/lib/mojits/HTMLFrameMojit/views/index.iphone.mu.html b/source/lib/app/mojits/HTMLFrameMojit/views/index.iphone.mu.html similarity index 100% rename from source/lib/mojits/HTMLFrameMojit/views/index.iphone.mu.html rename to source/lib/app/mojits/HTMLFrameMojit/views/index.iphone.mu.html diff --git a/source/lib/mojits/HTMLFrameMojit/views/index.mu.html b/source/lib/app/mojits/HTMLFrameMojit/views/index.mu.html similarity index 100% rename from source/lib/mojits/HTMLFrameMojit/views/index.mu.html rename to source/lib/app/mojits/HTMLFrameMojit/views/index.mu.html diff --git a/source/lib/mojits/LazyLoad/binders/index.js b/source/lib/app/mojits/LazyLoad/binders/index.js similarity index 100% rename from source/lib/mojits/LazyLoad/binders/index.js rename to source/lib/app/mojits/LazyLoad/binders/index.js diff --git a/source/lib/mojits/LazyLoad/controller.common.js b/source/lib/app/mojits/LazyLoad/controller.common.js similarity index 100% rename from source/lib/mojits/LazyLoad/controller.common.js rename to source/lib/app/mojits/LazyLoad/controller.common.js diff --git a/source/lib/mojits/LazyLoad/views/index.mu.html b/source/lib/app/mojits/LazyLoad/views/index.mu.html similarity index 100% rename from source/lib/mojits/LazyLoad/views/index.mu.html rename to source/lib/app/mojits/LazyLoad/views/index.mu.html diff --git a/source/lib/archetypes/app/default/application.json b/source/lib/archetypes/app/default/application.json index 70f9bb90f..d5bfe8041 100644 --- a/source/lib/archetypes/app/default/application.json +++ b/source/lib/archetypes/app/default/application.json @@ -2,5 +2,11 @@ { "settings": [ "master" ], "specs": {} + }, + { + "settings": [ "environment:development" ], + "staticHandling": { + "forceUpdate": true + } } ] diff --git a/source/lib/archetypes/app/full/application.json b/source/lib/archetypes/app/full/application.json index 8f89636c9..506b4a064 100644 --- a/source/lib/archetypes/app/full/application.json +++ b/source/lib/archetypes/app/full/application.json @@ -42,5 +42,11 @@ } } + }, + { + "settings": [ "environment:development" ], + "staticHandling": { + "forceUpdate": true + } } ] diff --git a/source/lib/archetypes/app/simple/application.json b/source/lib/archetypes/app/simple/application.json index 70f9bb90f..d5bfe8041 100644 --- a/source/lib/archetypes/app/simple/application.json +++ b/source/lib/archetypes/app/simple/application.json @@ -2,5 +2,11 @@ { "settings": [ "master" ], "specs": {} + }, + { + "settings": [ "environment:development" ], + "staticHandling": { + "forceUpdate": true + } } ] diff --git a/source/lib/index.js b/source/lib/index.js index ad4379c47..bbf91f75e 100644 --- a/source/lib/index.js +++ b/source/lib/index.js @@ -280,7 +280,7 @@ MojitoServer.prototype = { // "builtin mojito-handler-dispatcher"); app.use(dispatcher); } else { - midPath = libpath.join(__dirname, 'middleware', midName); + midPath = libpath.join(__dirname, 'app', 'middleware', midName); //console.log("======== MIDDLEWARE mojito " + midPath); midFactory = require(midPath); // We assume the middleware is a factory function diff --git a/source/lib/management/cli.js b/source/lib/management/cli.js index aa050f7cc..291005de9 100644 --- a/source/lib/management/cli.js +++ b/source/lib/management/cli.js @@ -96,12 +96,15 @@ function main() { argInfo; try { - command = require('./commands/' + commandName); + command = require('mojito-cli-cmd-' + commandName); } catch (e) { - console.log(e); - utils.error('Invalid command: ' + command, - 'mojito [] []'); - return; + try { + command = require('./commands/' + commandName); + } catch (e) { + utils.error('Invalid command: ' + command, + 'mojito [] []'); + return; + } } if (args.length === 0) { diff --git a/source/lib/management/commands/help.js b/source/lib/management/commands/help.js index be9b001df..e9bb56ef2 100644 --- a/source/lib/management/commands/help.js +++ b/source/lib/management/commands/help.js @@ -40,13 +40,21 @@ function helpTop() { function helpCommand(command) { var module; - try { - module = require('./' + command); + function help(ref) { + module = require(ref); console.log(module.help || module.usage || ('No help available for command: ' + command)); + } + + try { + help('mojito-cli-cmd-' + command); } catch (e) { - console.log('No such command: ' + command); - helpTop(); + try { + help('./' + command); + } catch(e) { + console.log('No such command: ' + command); + helpTop(); + } } } diff --git a/source/lib/management/commands/test.js b/source/lib/management/commands/test.js index a81026a6b..0170a11fb 100644 --- a/source/lib/management/commands/test.js +++ b/source/lib/management/commands/test.js @@ -649,7 +649,7 @@ runTests = function(opts) { targetTests, testName = opts.name, testType = opts.type || 'fw', - path = opts.path, + path = pathlib.resolve(opts.path), coverage = inputOptions.coverage, verbose = inputOptions.verbose, store, diff --git a/source/lib/store.server.js b/source/lib/store.server.js index 987438e1e..61b33cf07 100644 --- a/source/lib/store.server.js +++ b/source/lib/store.server.js @@ -1561,7 +1561,7 @@ ServerStore.prototype = { // (A better name might have been "global" instead of "app-level".) this._preloadDirMojit('fw', false, libpath.join(mojitoRoot, 'app')); - this._preloadDirMojits(false, libpath.join(mojitoRoot, 'mojits')); + this._preloadDirMojits(false, libpath.join(mojitoRoot, 'app', 'mojits')); this._preloadFileConfig(this._preload.appMeta, 'app', null, libpath.join(this._root, 'application.json'), 'definition'); diff --git a/source/lib/tests/autoload/middleware/contextualizer-tests.js b/source/lib/tests/autoload/middleware/contextualizer-tests.js index 207d6b9fc..c11bba988 100644 --- a/source/lib/tests/autoload/middleware/contextualizer-tests.js +++ b/source/lib/tests/autoload/middleware/contextualizer-tests.js @@ -7,7 +7,7 @@ YUI.add('mojito-middleware-contextualizer-tests', function(Y, NAME) { var suite = new YUITest.TestSuite(NAME), path = require('path'), - contextualizer = require(path.join(__dirname, '../../../middleware/mojito-contextualizer')), + contextualizer = require(path.join(__dirname, '../../../app/middleware/mojito-contextualizer')), handler = null, res = null, nextCalled = false, diff --git a/source/lib/tests/autoload/middleware/handler-static-tests.js b/source/lib/tests/autoload/middleware/handler-static-tests.js index 95a239d8e..6ad679ce7 100644 --- a/source/lib/tests/autoload/middleware/handler-static-tests.js +++ b/source/lib/tests/autoload/middleware/handler-static-tests.js @@ -7,6 +7,6 @@ YUI.add('mojito-middleware-handler-static-tests', function(Y, NAME) { var suite = new YUITest.TestSuite(NAME), path = require('path'), - staticHandler = require(path.join(__dirname, '../../../middleware/mojito-handler-static')); + staticHandler = require(path.join(__dirname, '../../../app/middleware/mojito-handler-static')); }, '0.0.1'); diff --git a/source/lib/tests/autoload/middleware/handler-tunnel-tests.server.js b/source/lib/tests/autoload/middleware/handler-tunnel-tests.server.js index 9284c5232..1a0ea0c93 100644 --- a/source/lib/tests/autoload/middleware/handler-tunnel-tests.server.js +++ b/source/lib/tests/autoload/middleware/handler-tunnel-tests.server.js @@ -8,7 +8,7 @@ YUI.add('mojito-middleware-handler-tunnel-tests', function(Y, NAME) { var Assert = YUITest.Assert, suite = new YUITest.TestSuite(NAME), path = require('path'), - factory = require(path.join(__dirname, '../../../middleware/mojito-handler-tunnel')); + factory = require(path.join(__dirname, '../../../app/middleware/mojito-handler-tunnel')); suite.add(new YUITest.TestCase({ diff --git a/source/lib/tests/autoload/middleware/router-tests.js b/source/lib/tests/autoload/middleware/router-tests.js index b9736bac7..e173fbfdb 100644 --- a/source/lib/tests/autoload/middleware/router-tests.js +++ b/source/lib/tests/autoload/middleware/router-tests.js @@ -7,7 +7,7 @@ YUI.add('mojito-middleware-router-tests', function(Y, NAME) { var path = require('path'), suite = new YUITest.TestSuite(NAME), - factory = require(path.join(__dirname, '../../../middleware/mojito-router')), + factory = require(path.join(__dirname, '../../../app/middleware/mojito-router')), A = YUITest.Assert, AA = YUITest.ArrayAssert; diff --git a/source/package.json b/source/package.json index 661e5379e..dd143e2bf 100644 --- a/source/package.json +++ b/source/package.json @@ -1,6 +1,6 @@ { "name": "mojito", - "version": "0.3.1", + "version": "0.3.8", "description": "Mojito provides an architecture, components and tools for developers to build complex web applications faster.", "preferGlobal": true, "author": "Team Mojito (http://developer.yahoo.com/cocktails/mojito)",