1 |
dpavlin |
46 |
<response> |
2 |
|
|
<action type='html'> |
3 |
|
|
<a name='overview' /> |
4 |
|
|
<h2>Overview</h2> |
5 |
|
|
<p> |
6 |
|
|
<a href='http://iwf.sourceforge.net'>Interactive Website Framework</a>, or IWF, is essentially a set of javascripts which encapsulate a large |
7 |
|
|
portion of the "grunt work" required when making highly interactive websites. A highly interactive |
8 |
|
|
website can be defined as a site which performs background http requests (Ajax), permits smooth |
9 |
|
|
transitioning of elements' visibility and location (Animation), and immediate form validation. |
10 |
|
|
</p> |
11 |
|
|
<h3>Intuitive API</h3> |
12 |
|
|
<p> |
13 |
|
|
IWF has been designed from the ground up to allow for a "typical" web developer to be able to |
14 |
|
|
harness its power without changing his or her methodologies drastically. |
15 |
|
|
</p> |
16 |
|
|
<p> |
17 |
|
|
All IWF-related javascript and HTML has '<code>iwf</code>' as the prefix -- <code>iwfRequest()</code>, <code>iwfGetById()</code>, <code>iwfOnRequestError()</code>, etc. |
18 |
|
|
The only exception to this are 'private' functions which should be used internally by IWF itself -- these have a '<code>_iwf</code>' prefix. |
19 |
|
|
This '<code>iwf</code>' prefixing minimizes name clashing and makes it very obvious when calling into IWF. |
20 |
|
|
</p> |
21 |
|
|
<p> |
22 |
|
|
The primary limitation IWF imposes is that all HTML it handles <b>must</b> be XHTML compliant. |
23 |
|
|
However, I do not believe this is a very stringent requirement with disciplined developers. |
24 |
|
|
</p> |
25 |
|
|
<p> |
26 |
|
|
IWF also includes and uses its own xml parser, <code>iwfXmlDoc</code> and <code>iwfXmlNode</code>. |
27 |
|
|
I wrote this xml parser to have more intuitive javascript when manipulating xml on the client. |
28 |
|
|
For example, let's say we have the following xml: |
29 |
|
|
<pre> |
30 |
|
|
<internet> |
31 |
|
|
<site url='www.sourceforge.net'> |
32 |
|
|
<description>Great place for open source projects!</description> |
33 |
|
|
</site> |
34 |
|
|
<site url='iwf.sourceforge.net'> |
35 |
|
|
<description>IWF Project Home</description> |
36 |
|
|
</site> |
37 |
|
|
</internet> |
38 |
|
|
</pre> |
39 |
|
|
To pull the description for the IWF site using the typical DOM:<br /> |
40 |
|
|
<pre>var desc = doc.documentElement.lastChild().firstChild().innerText;</pre> |
41 |
|
|
To pull the same node using the custom IWF implementation:<br /> |
42 |
|
|
<pre>var desc = doc.internet.site[1].description[0].getText();</pre> |
43 |
|
|
</p> |
44 |
|
|
<p> |
45 |
|
|
As you can see, the IWF implementation produces very readable and maintainable javascript, |
46 |
|
|
albeit a non-standard way of accessing xml data. |
47 |
|
|
</p> |
48 |
|
|
|
49 |
|
|
<h3>Xml At Heart</h3> |
50 |
|
|
<p> |
51 |
|
|
IWF only understands xml. In fact, IWF has a very specific xml format it requires to enable |
52 |
|
|
one to fully utilize its capabilities. |
53 |
|
|
</p> |
54 |
|
|
<p> |
55 |
|
|
A typical xml stream that IWF understands and can automatically process looks like the following: |
56 |
|
|
</p> |
57 |
|
|
<p> |
58 |
|
|
<pre> |
59 |
|
|
<response> |
60 |
|
|
<action type='html' target='divResponse' errorCode='' errorMessage='' > |
61 |
|
|
<h1>This is text within an H1 element. |
62 |
|
|
All data within this action node will be populated into the innerHTML |
63 |
|
|
attribute of the element with the id matching the one specified by the |
64 |
|
|
target attribute above, which is 'divResponse'.</h1> |
65 |
|
|
</action> |
66 |
|
|
</response> |
67 |
|
|
</pre> |
68 |
|
|
</p> |
69 |
|
|
<p> |
70 |
|
|
Things to note: |
71 |
|
|
<ul> |
72 |
|
|
<li>A <code>response</code> node wraps the entire thing, but does nothing else.</li> |
73 |
|
|
<li>There may be multiple <code>action</code> nodes.</li> |
74 |
|
|
<li>The <code>action</code> node causes the browser to do different things based on the <code>type</code> attribute.</li> |
75 |
|
|
<li>If the <code>errorCode</code> is specified and != 0, the javascript function iwfOnRequestError will be called if it exists, and processing of this <code>action</code> node is aborted.</li> |
76 |
|
|
<li>The values for the <code>type</code> attribute are: |
77 |
|
|
<ul> |
78 |
|
|
<li>html == contents of node are XHTML</li> |
79 |
|
|
<li>javascript == contents of node are javascript</li> |
80 |
|
|
<li>xml == contents of node are xml</li> |
81 |
|
|
</ul> |
82 |
|
|
</li> |
83 |
|
|
<li>The <code>target</code> only applies when <code>type</code> is 'html'. This specifies the id of the element which will be populated with the contents of the node.</li> |
84 |
|
|
<li>When <code>type</code> is javascript, the contents of the node are parsed and executed as javascript. It will be made available to the browser so other javascript already in the document can call this javascript.</li> |
85 |
|
|
<li>When <code>type</code> is xml, an <code>iwfXmlNode</code> object is passed to the <code>callback</code> function defined when <code>iwfRequest</code> was called. If none exists, this action is ignored.</li> |
86 |
|
|
</ul> |
87 |
|
|
</p> |
88 |
|
|
<h3>Thread Safe Requests</h3> |
89 |
|
|
<p> |
90 |
|
|
IWF uses a javascript feature called an inner function to handle multiple requests simultaneously. |
91 |
|
|
An inner function is simply a function defined within another function. What makes it special is the |
92 |
|
|
inner function has visibility to the outer function's local variables. Those local variables do not |
93 |
|
|
fall out of scope until after all items in the outer function's activation context has completed. By |
94 |
|
|
setting the XmlHttpRequest object's <code>onreadystatechange</code> callback to our inner function, |
95 |
|
|
it causes the inner function to stay activated -- which means the outer function's local variables are |
96 |
|
|
still available until that inner function has executed. When the XmlHttpRequest has completed, the |
97 |
|
|
inner function uses the outer function's variables to determine what method to callback (if any), |
98 |
|
|
which target was specified (if any), etc. |
99 |
|
|
</p> |
100 |
|
|
<p> |
101 |
|
|
If that was a little too much at once, don't sweat it. Essentially, your users can click multiple links |
102 |
|
|
rapidly and all requests will be performed and processed, without the worry of "missing" or "dropping" any. |
103 |
|
|
</p> |
104 |
|
|
<h3>As Flexibile As Needed</h3> |
105 |
|
|
<p> |
106 |
|
|
As mentioned above, IWF uses xml for all of its responses. That xml is inspected, and IWF acts |
107 |
|
|
according to how the xml specifies. So if you want to have your server kicking back XHTML and injecting |
108 |
|
|
it into an element in the browser, you can. If you want the server kicking back javascript and executing |
109 |
|
|
it, you can. If you want the server kicking back straight xml, which the client will be responsible for |
110 |
|
|
parsing and acting upon, you can. |
111 |
|
|
</p> |
112 |
|
|
<p> |
113 |
|
|
</p> |
114 |
|
|
<h3>Browser Independent</h3> |
115 |
|
|
<p> |
116 |
|
|
IWF is heavily reliant upon client-side javascript. In fact, if the user does not have a |
117 |
|
|
javascript-capable browser, or javascript is disabled, IWF simply will not work. |
118 |
|
|
</p> |
119 |
|
|
<p> |
120 |
|
|
However, all javascript has been written / tested / verified on Firefox 1.0.3 and IE 6.0 running under Win XP. |
121 |
|
|
Most of what IWF does is fairly basic, so most other major browsers should work fine. If not, <a href='mailto:brockweaver@sourceforge.net'>drop me a line</a> and I'll see if I can get it working. |
122 |
|
|
<pre> |
123 |
|
|
<plug type='shameless'> |
124 |
|
|
If you want me to start supporting Safari, <a href='donate.php'>donate to my iMac fund</a>! |
125 |
|
|
</plug> |
126 |
|
|
</pre> |
127 |
|
|
</p> |
128 |
|
|
<h3>Server Platform Independent</h3> |
129 |
|
|
<p> |
130 |
|
|
Since IWF is primarily a client-side technology, any web server which can kick out ASCII will work perfectly -- and by definition, any web server |
131 |
|
|
can do this. All IWF requires from the server is a valid xml stream in IWF format. |
132 |
|
|
</p> |
133 |
|
|
<p> |
134 |
|
|
PHP is my favorite web scripting language, so I have implemented a very simple class for emitting |
135 |
|
|
IWF-copmliant xml from a PHP server. This could very easily be ported to ASP, but since the release |
136 |
|
|
of ASP.NET, my focus has shifted away from it. |
137 |
|
|
</p> |
138 |
|
|
<p> |
139 |
|
|
|
140 |
|
|
</p> |
141 |
|
|
<p> |
142 |
|
|
</p> |
143 |
|
|
<p> |
144 |
|
|
</p> |
145 |
|
|
<p> |
146 |
|
|
</p> |
147 |
|
|
<p> |
148 |
|
|
</p> |
149 |
|
|
<p> |
150 |
|
|
</p> |
151 |
|
|
<p> |
152 |
|
|
</p> |
153 |
|
|
<p> |
154 |
|
|
</p> |
155 |
|
|
<p> |
156 |
|
|
</p> |
157 |
|
|
<p> |
158 |
|
|
</p> |
159 |
|
|
<p> |
160 |
|
|
</p> |
161 |
|
|
<p> |
162 |
|
|
</p> |
163 |
|
|
<p> |
164 |
|
|
</p> |
165 |
|
|
<p> |
166 |
|
|
</p> |
167 |
|
|
<p> |
168 |
|
|
</p> |
169 |
|
|
<p> |
170 |
|
|
</p> |
171 |
|
|
<p> |
172 |
|
|
</p> |
173 |
|
|
<p> |
174 |
|
|
</p> |
175 |
|
|
<p> |
176 |
|
|
</p> |
177 |
|
|
<p> |
178 |
|
|
</p> |
179 |
|
|
<p> |
180 |
|
|
</p> |
181 |
|
|
<p> |
182 |
|
|
</p> |
183 |
|
|
<p> |
184 |
|
|
</p> |
185 |
|
|
<p> |
186 |
|
|
</p> |
187 |
|
|
<p> |
188 |
|
|
</p> |
189 |
|
|
<p> |
190 |
|
|
</p> |
191 |
|
|
<p> |
192 |
|
|
</p> |
193 |
|
|
<p> |
194 |
|
|
</p> |
195 |
|
|
<p> |
196 |
|
|
</p> |
197 |
|
|
<p> |
198 |
|
|
</p> |
199 |
|
|
<p> |
200 |
|
|
</p> |
201 |
|
|
<p> |
202 |
|
|
</p> |
203 |
|
|
<p> |
204 |
|
|
</p> |
205 |
|
|
<p> |
206 |
|
|
</p> |
207 |
|
|
</action> |
208 |
|
|
</response> |