Skip to content

Commit

Permalink
adding documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Scott Miles committed May 19, 2012
1 parent f2cf703 commit 79b3ed2
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 49 deletions.
35 changes: 32 additions & 3 deletions source/ajax/Ajax.js
@@ -1,11 +1,40 @@
/**
IMPORTANT: Ajax implements the properties of the shared
<a href="#enyo.AjaxProperties">enyo.AjaxProperties</a> object.
The properties documented under AjaxProperties are published by _enyo.Async_.
_enyo.Ajax_ is a wrapper for _XmlHttpRequest_ that uses
the <a href="#enyo.Async">enyo.Async</a> API.
IMPORTANT: _enyo.Ajax_ publishes all the properties of the
<a href="#enyo.AjaxProperties">enyo.AjaxProperties</a>
object.
Like _enyo.Async_, _enyo.Ajax_ is an **Object** not a **Component**.
Do not try to make _enyo.Ajax_ objects in a components block.
If you want to use _enyo.Ajax_ as a Component, you are probably
looking for <a href="#enyo.WebService">enyo.WebService</a>.
Example
getWoeid: function(inPlace) {
// setup <a href="#enyo.AjaxProperties">enyo.AjaxProperties</a> by sending them to the _enyo.Ajax_ constructor
var x = enyo.Ajax({url: "http://query.yahooapis.com/v1/public/yql?format=json"});
// send parameters the remote service using the 'go()' method
x.go({
q: 'select woeid from geo.placefinder where text="' + inPlace + '"'
});
// attach responders to the transaction object
x.response(this, function(inSender, inResponse) {
// extra information from response object
var woeid = inResponse.data.query.results.Result.woeid;
// do something with it
this.setWoeid(inPlace, woeid);
};
}
*/
enyo.kind({
name: "enyo.Ajax",
kind: enyo.Async,
//* See <a href="#enyo.AjaxProperties">enyo.AjaxProperties</a> for the list of properties
//* published by _enyo.Ajax_.
published: enyo.AjaxProperties,
//* @protected
constructor: function(inParams) {
Expand Down
96 changes: 81 additions & 15 deletions source/ajax/Async.js
@@ -1,16 +1,72 @@
/**
Base kind for handling asynchronous operations. To use it, create a new
instance of _enyo.Async_ or a kind derived from it, then register response
and error handlers. Finally, start the async operation by calling the _go_
method.
Base kind for handling asynchronous operations.
_enyo.Aync_ is an **Object**, not a **Component**, you may not declare
them in component blocks. If you want to use Async as a Component, you
are probably looking for <a href="#enyo.WebService">enyo.WebService</a>.
An Async object represents a task that has not yet completed. Callback
functions can be attached to an Async that will be called with the task
completes or encounters an error.
To use it, create a new instance of _enyo.Async_ or a kind derived from it,
then register handlers with the _response()_ and _error()_ methods.
Start the async operation by calling the _go()_ method.
Handlers may either be methods with the signature _(asyncObject, value)_ or
new instances of _enyo.Async_ or its subkinds. This allows for chaining of
async objects (e.g., when calling a Web API).
The base implementation isn't actually sync. Calling _go_ causes all the
response handlers to be called. However, it's useful for chaining multiple
_enyo.Async_ subkinds together.
If a response method returns a value (other than undefined) that value is
sent to subsequent handlers in the chain, replacing the original value.
A failure method can call _recover()_ to undo the error condition and switch
to calling response methods.
The default implementation of _go_ causes all the response handlers
to be called (asynchronously).
Here is a complicated example which demonstrates many of these features:
var transaction = function() {
// create a transaction object
var async = new enyo.Async();
// cause handlers to fire asynchronously (sometime after we yield this thread)
// "initial response" will be sent to handlers as inResponse
async.go("intial response");
// until we yield the thread, we can continue to add handlers
async.response(function(inSender, inResponse) {
console.log("first response: returning a string, subsequent handlers receive this value for 'inResponse'");
return "some response"
});
return async;
};
Users of the _transaction()_ function can add handlers to the Async object until all functions return (synchronously).
// get a new transaction, it's been started, but we can add more handlers synchronously
var x = transaction();
// add an handler that will be called if an error is detected ... this handler recovers and sends a custom message
x.error(function(inSender, inResponse) {
console.log("error: calling recover", inResponse);
this.recover();
return "recovered message";
});
// add a response handler that halts response handler and triggers the error chain
// the error will be sent to the error handler registered above, which will
// restart the handler chain
x.response(function(inSender, inResponse) {
console.log("response: calling fail");
this.fail(inResponse);
});
// recovered message will end up here
x.response(function(inSender, inResponse) {
console.log("response: ", inResponse);
});
*/
enyo.kind({
name: "enyo.Async",
Expand All @@ -27,16 +83,20 @@ enyo.kind({
inArray.push(fn);
},
//* @public
/** Registers a response function.
/**
Registers a response function.
First parameter is an optional this context for the response method.
Second (or only) parameter is the function object. */
Second (or only) parameter is the function object.
*/
response: function(/* [inContext], inResponder */) {
this.accumulate(this.responders, arguments);
return this;
},
/** Registers an error handler.
/**
Registers an error handler.
First parameter is an optional this context for the response method.
Second (or only) parameter is the function object. */
Second (or only) parameter is the function object.
*/
error: function(/* [inContext], inResponder */) {
this.accumulate(this.errorHandlers, arguments);
return this;
Expand All @@ -59,7 +119,11 @@ enyo.kind({
if (r instanceof enyo.Async) {
this.route(r, inValue);
} else {
// handler can return a new 'value'
var v = enyo.call(this.context || this, r, [this, inValue]);
// ... but only if it returns something other than undefined
v = (v !== undefined) ? v : inValue;
// next handler
(this.failed ? this.fail : this.respond).call(this, v);
}
}
Expand All @@ -82,20 +146,22 @@ enyo.kind({
this.timedout = true;
this.fail("timeout");
},
//* @public
//* Called from async handler, indicates successful completion.
//* @protected
//* Called as part of the async implementation, triggers the handler chain.
respond: function(inValue) {
this.failed = false;
this.endTimer();
this.handle(inValue, this.responders);
},
//* Called from async handler, indicates error.
//* @public
//* Can be called from any handler to trigger the error chain.
fail: function(inError) {
this.failed = true;
this.endTimer();
this.handle(inError, this.errorHandlers);
},
//* Clears error condition to allow retrying.
//* Called from an error handler, this method clears the error
// condition and resumes calling handler methods.
recover: function() {
this.failed = false;
},
Expand Down
52 changes: 47 additions & 5 deletions source/ajax/WebService.js
@@ -1,7 +1,36 @@
enyo.kind({
name: "enyo.WebService",
//* @protected
enyo.kind({
name: "enyo._AjaxComponent",
kind: enyo.Component,
published: enyo.AjaxProperties,
published: enyo.AjaxProperties
});

//* @public
/**
_enyo.WebService_ is a Component that performs web requests (_XmlHttpRequest_).
Interally, _enyo.WebService_ uses _enyo.Async_ subkinds (namely, _enyo.Ajax_
and _enyo.JsonPRequest_) to manage transactions. The async instance for
a request is returned from the _send()_ method.
IMPORTANT: _enyo.Ajax_ publishes all the properties of the
<a href="#enyo.AjaxProperties">enyo.AjaxProperties</a>
object.
*/
enyo.kind({
name: "enyo.WebService",
kind: enyo._AjaxComponent,
published: {
//* Set true to use JSONP protocol.
jsonp: false,
/**
When using JSONP, the name of the callback parameter.
Note: this not the name of a callback function, but only
the name of the callback parameter. Enyo will create an
internal callback function as necessary.
*/
callback: "callback"
},
events: {
onResponse: "",
onError: ""
Expand All @@ -12,12 +41,25 @@
},
//* @public
send: function(inParams) {
return this.jsonp ? this.sendJsonp(inParams) : this.sendAjax(inParams);
},
//* @protected
sendJsonp: function(inParams) {
var jsonp = new enyo.JsonpRequest();
for (var n in ['url', 'callback']) {
jsonp[n] = this[n];
}
return this.sendAsync(ajax, inParams);
},
sendAjax: function(inParams) {
var ajax = new enyo.Ajax();
// hardcore
for (var n in enyo.AjaxProperties) {
ajax[n] = this[n];
}
return ajax.go(inParams).response(this, "response").error(this, "error");
return this.sendAsync(ajax, inParams);
},
sendAsync: function(inAjax, inParams) {
return inAjax.go(inParams).response(this, "response").error(this, "error");
},
response: function(inSender, inData) {
this.doResponse({ajax: inSender, data: inData});
Expand Down
2 changes: 0 additions & 2 deletions source/dom/Control.js
Expand Up @@ -519,8 +519,6 @@ enyo.kind({
this.tagsValid = false;
},
prepareTags: function() {
//this.log("(" + this.owner.name + ") " + this.name + ": " + this.id + " (" + this.attributes.id + ")");
//var htmlStyle = enyo.Control.domStylesToCssText(this.domStyles);
var htmlStyle = this.domCssText + this.style;
this._openTag = '<'
+ this.tag
Expand Down
46 changes: 23 additions & 23 deletions source/kernel/Component.js
Expand Up @@ -7,7 +7,7 @@
Component constructors take a single argument (sometimes called a
_Component configuration_), a JavaScript object that defines various
properties to be initialized on the Component. For example:
properties to be initialized on the Component. For example:
// create a new component, initialize its name property to 'me'.
var c = new enyo.Component({
Expand All @@ -26,13 +26,13 @@
});
In this case, when _me_ is created, _other_ is also created, and we say that
_me owns other_. In other words, the _owner_ property of _other_ equals
_me_. Notice that you can specify the _kind_ of _other_ explicitly in its
_me owns other_. In other words, the _owner_ property of _other_ equals
_me_. Notice that you can specify the _kind_ of _other_ explicitly in its
configuration block, to tell _me_ what constructor to use to create _other_.
Note that _kind_ values may be references to actual kinds or string-names of
kinds. Kind names that do not resolve directly to kinds are looked up in
default namespaces. In this case, _kind: "Component"_ resolves to
kinds. Kind names that do not resolve directly to kinds are looked up in
default namespaces. In this case, _kind: "Component"_ resolves to
_enyo.Component_.
## Ownership
Expand All @@ -46,17 +46,17 @@
* Component D (owner A)
Note that, when designing code, a component should only be concerned with
the components it owns (one level down). The coder never needs to worry
about the complex tree structure that exists at runtime. For example,
the components it owns (one level down). The coder never needs to worry
about the complex tree structure that exists at runtime. For example,
Component A will never reference Component E directly; it will only access
the interface supplied by Component C.
The ownership status of a component is controlled by the _owner_ property,
so, to change ownership of a component, use the _setOwner_ method.
The ownership of a component is controlled by the _owner_ property. To
change ownership of a component, use the _setOwner_ method.
Every component has a name, and its name must be unique among all the
components of its owner. In other words, a component can't own two
components with the same name. A component may access its owned components
components of its owner. In other words, a component can't own two
components with the same name. A component may access its owned components
by name using the _$_ hash.
For example, if a component owns components named 'componentB' and
Expand Down Expand Up @@ -85,22 +85,22 @@
});
Although the components _third_ and _fourth_ are nested inside the
configuration for _other_, they are still owned by _me_. This concept is
configuration for _other_, they are still owned by _me_. This concept is
important; it means that whatever components you can see listed are in the
top-level component's scope.
The _me_ component might have a complex configuration, but we can see at a
glance that it has access to _other_, _third_, and _fourth_ to get its work
done. Those objects will be available in the _$_ hash.
done. Those objects will be available in the _$_ hash.
## Events
A component can send a message to its owner using the _event_ mechanism. A
A component can send a message to its owner using the _event_ mechanism. A
component exposes events as string properties whose names begin with "on".
To listen to messages, a component may assign the name of one of its methods
to the event property of an owned component.
For example, the _WebService_ component has an _onSuccess_ property. The
For example, the _WebService_ component has an _onSuccess_ property. The
owner of a WebService can set _onSuccess_ to the name of a method to be
called when the WebService operation completes successfully.
Expand All @@ -117,22 +117,22 @@
});
We call _webSuccess_ the _delegate_ for the _success_ event of the
WebService. Because the event properties take method names as values, we
WebService. Because the event properties take method names as values, we
call the event property values _named delegates_.
Note that the _webSuccess_ method takes an argument called _inSender_, which
refers to the object that generated the event. Different events may supply
refers to the object that generated the event. Different events may supply
additional arguments, but they all supply _inSender_ as the first argument.
Component events are much like DOM events. In fact, Enyo makes many DOM
events available as component events. Remember that Ccmponents do not, in
Component events are much like DOM events. In fact, Enyo makes many DOM
events available as component events. Remember that Ccmponents do not, in
general, represent DOM nodes, but _Controls_ do; see the
<a href="#enyo.Control">Control</a> documentation for more information.
## Create and Destroy
When a component is instantiated, and after all constructors are executed,
the _create_ method is invoked. During _Component.create_, all owned
the _create_ method is invoked. During _Component.create_, all owned
components are created.
Subclasses of Component often override _create_ to do initialization tasks.
Expand All @@ -150,9 +150,9 @@
}
});
To delete a component, use the _destroy_ method. Calling _destroy_ on a
To delete a component, use the _destroy_ method. Calling _destroy_ on a
component will remove it from all framework bookkeeping, and in particular
will set its owner to _null_. Generally, this will be enough to allow the
will set its owner to _null_. Generally, this will be enough to allow the
object to be garbage-collected, unless you have maintained a reference to it
yourself.
Expand Down Expand Up @@ -238,7 +238,7 @@ enyo.kind({
//* @public
/**
Removes this Component from its owner (sets owner to null) and does any
cleanup. The Component is flagged with a _destroyed: true_ property.
cleanup. The Component is flagged with a _destroyed: true_ property.
Usually the Component will be suitable for garbage collection after
being destroyed, unless user code keeps a reference to it.
*/
Expand Down

0 comments on commit 79b3ed2

Please sign in to comment.