Modified: websites/production/tapestry/content/javascript-rewrite.html
==============================================================================
--- websites/production/tapestry/content/javascript-rewrite.html (original)
+++ websites/production/tapestry/content/javascript-rewrite.html Mon Feb 16 
23:20:21 2015
@@ -21,21 +21,12 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     JavaScript Rewrite -- Apache Tapestry
   </title>
   <link type="text/css" rel="stylesheet" href="/resources/space.css">
 
-    <link href='/resources/highlighter/styles/shCoreCXF.css' rel='stylesheet' 
type='text/css' />
-  <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet' 
type='text/css' />
-  <script src='/resources/highlighter/scripts/shCore.js' 
type='text/javascript'></script>
-  <script src='/resources/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script>
-  <script src='/resources/highlighter/scripts/shBrushXml.js' 
type='text/javascript'></script>
-  <script src='/resources/highlighter/scripts/shBrushPlain.js' 
type='text/javascript'></script>
-  <script type="text/javascript">
-  SyntaxHighlighter.defaults['toolbar'] = false;
-  SyntaxHighlighter.all();
-  </script>
 
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -66,432 +57,18 @@
   </div>
 
 <div id="content">
-<div id="ConfluenceContent"><style type="text/css">/*<![CDATA[*/
-div.rbtoc1418617228624 {padding: 0px;}
-div.rbtoc1418617228624 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1418617228624 li {margin-left: 0px;padding-left: 0px;}
+<div id="ConfluenceContent"><p><style type="text/css">/*<![CDATA[*/
+div.rbtoc1424128773715 {padding: 0px;}
+div.rbtoc1424128773715 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1424128773715 li {margin-left: 0px;padding-left: 0px;}
 
-/*]]>*/</style><div class="toc-macro rbtoc1418617228624">
+/*]]>*/</style></p><div class="toc-macro rbtoc1424128773715">
 <ul class="toc-indentation"><li><a shape="rect" 
href="#JavaScriptRewrite-TapestryandJavaScript">Tapestry and 
JavaScript</a></li><li><a shape="rect" 
href="#JavaScriptRewrite-TapestryJavaScriptLimitations(through5.3)">Tapestry 
JavaScript Limitations (through 5.3)</a>
 <ul class="toc-indentation"><li><a shape="rect" 
href="#JavaScriptRewrite-DependenceonPrototype/Scriptaculous">Dependence on 
Prototype/Scriptaculous</a></li><li><a shape="rect" 
href="#JavaScriptRewrite-LackofDocumentation">Lack of 
Documentation</a></li><li><a shape="rect" 
href="#JavaScriptRewrite-LackofModuleStructure">Lack of Module 
Structure</a></li><li><a shape="rect" 
href="#JavaScriptRewrite-ComplexInitialization">Complex 
Initialization</a></li></ul>
 </li><li><a shape="rect" 
href="#JavaScriptRewrite-JavaScriptImprovementsfor5.4">JavaScript Improvements 
for 5.4</a>
 <ul class="toc-indentation"><li><a shape="rect" 
href="#JavaScriptRewrite-RequireJS">RequireJS</a></li><li><a shape="rect" 
href="#JavaScriptRewrite-SlowPageLoadandInitialization">Slow Page Load and 
Initialization</a></li><li><a shape="rect" 
href="#JavaScriptRewrite-MappingModulestoAssets">Mapping Modules to 
Assets</a></li><li><a shape="rect" 
href="#JavaScriptRewrite-ExtensionstoJavaScriptSupport">Extensions to 
JavaScriptSupport</a></li><li><a shape="rect" 
href="#JavaScriptRewrite-@Requireannotation">@Require annotation</a></li><li><a 
shape="rect" 
href="#JavaScriptRewrite-IncreasedUseOfPublish/Subscribe">Increased Use Of 
Publish/Subscribe</a></li><li><a shape="rect" 
href="#JavaScriptRewrite-AvoidingJavaScriptClasses">Avoiding JavaScript 
Classes</a></li><li><a shape="rect" 
href="#JavaScriptRewrite-ExposeGlobalMessageCatalogtoClient">Expose Global 
Message Catalog to Client</a></li><li><a shape="rect" 
href="#JavaScriptRewrite-PartialPageUpdateResponse">Partial Page Update 
Response</a></l
 i></ul>
 </li><li><a shape="rect" 
href="#JavaScriptRewrite-MaintainingBackwardsCompatibility">Maintaining 
Backwards Compatibility</a></li><li><a shape="rect" 
href="#JavaScriptRewrite-TwitterBootstrap">Twitter Bootstrap</a></li><li><a 
shape="rect" 
href="#JavaScriptRewrite-ContentDeliveryNetworkIntegration">Content Delivery 
Network Integration</a></li><li><a shape="rect" 
href="#JavaScriptRewrite-ExtJSCompatibility">ExtJS Compatibility</a></li><li><a 
shape="rect" href="#JavaScriptRewrite-MoreThoughts">More Thoughts</a></li></ul>
-</div>
-
-<h1 id="JavaScriptRewrite-TapestryandJavaScript">Tapestry and JavaScript</h1>
-
-<p>Tapestry 5 has had a interesting mix of characteristics.</p>
-
-<p>On the one hand, it has had a large number of features that work, and work 
well, right out of the box, with no special configuration or setup. This 
includes client-side validation, dynamic content updates, simple animations, 
progressive enhancement, and other standard Ajax and DHTML use cases.</p>
-
-<p>In addition, Tapestry has evolved, from Tapestry 5.0 through 5.3, into a 
quite capable <em>provisioning</em> framework:</p>
-
-<ul><li>JavaScript libraries may be combined into <em>stacks</em> that are 
combined (in production) into a single virtual file</li><li>JavaScript 
libraries and CSS files may be minified</li><li>Libraries, stacks, and other 
resources are exposed to the browser with a versioned URL and far-future 
expires header, to support aggressive client-caching</li><li>Resources, 
including JavaScript and CSS, can be distributed inside JARs (as part of 
reusable component libraries)</li><li>Compressible resources will be 
automatically GZip compressed if the client supports it</li></ul>
-
-
-<p>However, JavaScript support in Tapestry is still unsatisfactory. Too often, 
Tapestry falls into an <a shape="rect" class="external-link" 
href="http://en.wikipedia.org/wiki/Uncanny_valley"; >uncanny valley</a> where 
the framework (server-side and client-side) does so much automatically that it 
becomes accepted that it does everything ... developers later discover, to 
their dismay, that the last 10% of custom behavior they desire is very hard to 
implement, because of all the common problems that plague any complex system: 
insufficient APIs, unexpected leaky abstractions, or just plain bugs.  </p>
-
-<p>Common examples of the challenges imposed by Tapestry include implementing 
a Confirm mixin, customizing behavior when a Zone component is dynamically 
updated, or any number of issues related to Forms, form elements, and Ajax 
updates.</p>
-
-<p>This document is a roadmap for how Tapestry 5.4 will revisit the 
relationship between server-side Java and client-side JavaScript. Ultimately, 
we hope to convert this relationship from an obstacle to using Tapestry into an 
essential reason to select Tapestry in the first place.</p>
-
-<h1 id="JavaScriptRewrite-TapestryJavaScriptLimitations(through5.3)">Tapestry 
JavaScript Limitations (through 5.3)</h1>
-
-<h2 id="JavaScriptRewrite-DependenceonPrototype/Scriptaculous">Dependence on 
Prototype/Scriptaculous</h2>
-
-<p>Tapestry made an early choice to embrace Prototype and Scriptaculous at a 
time when this made sense, circa 2006-2007.</p>
-
-<p>The goal was to have Tapestry provide a client-side API, the 
<code>Tapestry</code> namespace, that in turn would delegate complex behaviors 
(including DOM element selection, event management, and XmlHttpRequest 
processing) to a <em>foundational framework</em>. The goal was to isolate all 
the direct dependencies on Prototype in such a way that it would be possible, 
in the future, to swap out for a different foundational framework, such as 
jQuery or ExtJS. Unfortunately, expediency has proven to make this goal even 
less reachable!</p>
-
-<h2 id="JavaScriptRewrite-LackofDocumentation">Lack of Documentation</h2>
-
-<p>There has not, to date, been an adequate documentation of the 
<code>T5</code> and <code>Tapestry</code> namespaces, beyond the code 
itself.</p>
-
-<h2 id="JavaScriptRewrite-LackofModuleStructure">Lack of Module Structure</h2>
-
-<p>Beyond the basic use of namespaces, Tapestry has not embraced modern 
JavaScript usage; specifically, it makes limited use of <em>hygenic 
functions</em> to form modules.  Hygenic functions are JavaScript functions 
that exist as a way to encapsulate private properties and functions.  Tapestry 
5.3 makes more use of this pattern than previous releases.</p>
-
-<p>What modularity is present in the JavaScript is organized around the 
<code>T5.initializers</code> (<code>Tapestry.Initializers</code>) namespace, 
and the mechanics of full-page and partial-page renders (described more fully 
below).</p>
-
-<h2 id="JavaScriptRewrite-ComplexInitialization">Complex Initialization</h2>
-
-<p>Many users are perplexed by how Tapestry performs initialization: in a 
typical <em>bespoke</em></p><p></p><p></p><p></p><p></p><p></p><p>&lt;style 
type='text/css'&gt;
-.FootnoteMarker, .FootnoteNum a {
-  background: transparent 
url(/confluence/download/resources/com.adaptavist.confluence.footnoteMacros:footnote/gfx/footnote.png)
 no-repeat top right;
-  padding: 1px 2px 0px 1px;
-  border-left: 1px solid #8898B8;
-  border-bottom: 1px solid #6B7C9B;
-  margin: 1px;
-  text-decoration: none;
-}
-.FootnoteNum a {
-  margin-top: 2px;
-  margin-right: 0px;
-}
-.FootnoteNum {
-  font-size: x-small;
-  text-align: right;
-  padding-bottom: 4px;
-}
-.footnote-th1 {
-  text-align: right;
-}
-.Footnote {
-  padding-left: 7px;
-  margin-bottom: 4px;
-  border: 1px none #DDDDDD;
-  writingMode: tb-rl;
-}
-.accessibility {
-     display: none;
-     visibility: hidden;
-}
-@media aural,braille,embossed {
-        .FootnoteMarker, .FootnoteNum a {
-         border: 1px solid #000000;
-         background: #ffffff none;
-    }
-    .accessibility {
-         display: run-in;
-         visibility: visible;
-    }
-}
-&lt;/style&gt;
-&lt;script type='text/javascript' language='JavaScript'&gt;
-//&lt;!--\n
-var effectInProgress = {};
-var despamEffect = function (id,effectType,duration) {
-  if ((effectInProgress[id]) || (typeof(Effect)=="undefined") || 
(typeof(Effect[effectType])=="undefined")) return;
-  new Effect[effectType](id);
-  effectInProgress[id]=true;
-  setTimeout('effectInProgress[\"'+id+'\"]=false;',duration*1000);
-};
-var oldFootnoteId = '';
-var footnoteHighlight = function(id,pulsateNum) {
-  if (oldFootnoteId!='') 
document.getElementById('Footnote'+oldFootnoteId).style['borderStyle'] = 'none';
-  oldFootnoteId = id;
-  document.getElementById('Footnote'+id).style['borderStyle'] = 'solid';
-  despamEffect('Footnote'+id,'Highlight',1)
-  if (pulsateNum) despamEffect('FootnoteNum'+id,'Pulsate',3)
-}
-var footnoteMarkerHighlight = function(id) {
-  if (oldFootnoteId!='') 
document.getElementById('Footnote'+oldFootnoteId).style['borderStyle'] = 'none';
-  oldFootnoteId = '';
-  despamEffect('FootnoteMarker'+id,'Pulsate',3)
-}
-//--&gt;
-&lt;/script&gt;
-
-<sup id="FootnoteMarker1">
-    <a shape="rect" class="FootnoteMarker" name="FootnoteMarker1" 
href="#Footnote1" onclick="footnoteHighlight(&quot;1&quot;,true);" 
alt="Footnote: Click here to display the footnote" title="Footnote: Click here 
to display the footnote">
-            1
-    </a>
-</sup>
-</p><p></p><p></p><p></p><p></p><p></p> application, the developer will create 
a <code>&lt;script&gt;</code> block at the bottom of the page, and do 
initializations there. In Tapestry, it can be much more complex:<p></p>
-
-<ul><li>A JavaScript library, containing one or more <em>initialization 
functions</em>, is created</li><li>The initialization functions must be <a 
shape="rect" class="external-link" 
href="http://en.wikipedia.org/wiki/Monkey_patching"; ><em>monkey 
patched</em></a> into the <code>T5.initializers</code> namespace 
<p></p><p></p><p></p><p></p><p></p><p>
-<sup id="FootnoteMarker2">
-    <a shape="rect" class="FootnoteMarker" name="FootnoteMarker2" 
href="#Footnote2" onclick="footnoteHighlight(&quot;2&quot;,true);" 
alt="Footnote: Click here to display the footnote" title="Footnote: Click here 
to display the footnote">
-            2
-    </a>
-</sup>
-</p><p></p><p></p><p></p><p></p><p></p></li><li>The <a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html";>JavaScriptSupport</a>
 environmental must be used to invoke the function, by name, passing it a 
JSONObject to configure itself (the "specification")</li><li>The affected 
element must have a unique id attribute, used to coordinate the initialization 
in the client web browser<p></p><p></p><p></p><p></p><p></p><p>
-<sup id="FootnoteMarker3">
-    <a shape="rect" class="FootnoteMarker" name="FootnoteMarker3" 
href="#Footnote3" onclick="footnoteHighlight(&quot;3&quot;,true);" 
alt="Footnote: Click here to display the footnote" title="Footnote: Click here 
to display the footnote">
-            3
-    </a>
-</sup>
-</p><p></p><p></p><p></p><p></p><p></p></li></ul>
-
-
-<p>This often feels like overkill, but it is necessary for a number of 
desirable characteristics:</p>
-
-<ul><li>Initialization code occurs in a single Tapestry-generated 
<code>&lt;script&gt;</code> block at the end of the page (just before the 
<code>&lt;/body&gt;</code> tag)</li><li>There is limited support for 
structuring the order of initialization</li><li>The mechanism works 
transparently in both full-page render requests (traditional) and partial-page 
render requests (Ajax)</li></ul>
-
-
-<p>Despite this, the Tapestry approach can feel very "heavy".  In a bespoke 
page, initialization that may affect many elements of the page often takes the 
form of a single event handler, attached to the <code>&lt;body&gt;</code> 
element, that catches events that bubble up from much lower in the DOM.  The 
single handler function identifies the applicable elements using CSS selectors, 
including those that are based on HTML5 data- attributes.  Additional data- 
attributes will define additional behavior ... for example, a URL for a 
triggered request.  This is "light" because:</p>
-
-<ul><li>There's a single event handler function (rather than a unique handler 
function instance per element)</li><li>The event handler may be anonymous 
(there's no name, or possibility of collision)</li><li>Elements are identified 
by DOM structure and CSS rather than their unique id (the element will often 
not have an id attribute)</li><li>Additional necessary configuration is 
directly attached to the element, rather than split</li><li>As the page is 
dynamically updated, there is no extra "bookkeeping" for added or removed 
elements; new elements inserted into the DOM dynamically are recognized as 
easily as those that were present on the initial render</li></ul>
-
-
-<p>By contrast, Tapestry is "heavy":</p>
-
-<ul><li>The initialization function must have a unique name</li><li>The 
element must have a unique id, to it can be located by the initialization 
function</li><li>The event handlers are attached directly to the 
element</li><li>Duplicated elements will have duplicated event 
handlers</li><li>Additional behavior is specified as a JSON object passed to 
the initialization function</li><li>Injecting new elements into the DOM 
requires invoking initialization functions to wire up the necessary event 
handlers</li><li>In (older versions of) Internet Explorer, removing elements 
may leave memory leaks as JavaScript objects retain references to DOM objects 
and vice-versa</li></ul>
-
-
-<h1 id="JavaScriptRewrite-JavaScriptImprovementsfor5.4">JavaScript 
Improvements for 5.4</h1>
-
-<p>The goals for Tapestry 5.4 are:</p>
-
-<ul><li>Break the dependency on Prototype and allow Tapestry to be used with 
any client-side "foundation" framework, seamlessly: minimally, this should 
include jQuery</li><li>Bring Tapestry's JavaScript approach more inline with 
modern practices (the "light" approach described above)</li><li>Let the 
JavaScript be modular, and loaded dynamically and asynchonously, only as 
needed</li><li>Optimize for fast page loads</li><li>Backwards compatibility to 
the Tapestry 5.3 approach until at least 5.5 or 5.6</li><li>Simplify Tapestry's 
client-side behavior, but make it easier to hook into, extend, and 
override</li></ul>
-
-
-<h2 id="JavaScriptRewrite-RequireJS">RequireJS </h2>
-
-<p>Rather than reinvent the wheel, Tapestry should incorporate a proper 
JavaScript module loader; <a shape="rect" class="external-link" 
href="http://requirejs.org/"; >RequireJS</a> is an excellent candidate, 
especially considering the new features provided in its 2.0.1 release.</p>
-
-<p>RequireJS supports the <a shape="rect" class="external-link" 
href="https://github.com/amdjs/amdjs-api/wiki/AMD"; >AMD (Asynchronous Module 
Format)</a>, with some additional support for the <a shape="rect" 
class="external-link" href="http://www.commonjs.org/"; >CommonJS</a> module 
format (the format used by Node.js). The latter is simpler, but is designed for 
a server-side environment; AMD is specifically designed to handle asynchronous 
loading of JavaScript into a web browser.</p>
-
-<p>RequireJS is geared towards bespoke applications; for Tapestry it is 
expected that some of the pathing and other configuration normally done in the 
client using the RequireJS API will instead by handled more dynamically on the 
server, using typically Tapestry configuration and extension mechanisms. For 
example, RequireJS allows mappings of module names to URLs, which is useful 
when working with multiple third-party JavaScript libraries that may be 
organized differently form each other. Tapestry can incorporate such logic on 
the server side instead, making the interface from the browser to the server 
uniform, even when the details of where each module is stored is quite 
variable.</p>
-
-<h2 id="JavaScriptRewrite-SlowPageLoadandInitialization">Slow Page Load and 
Initialization</h2>
-
-<p>Tapestry 5.1 and up has support for dealing with slow page loads 
(especially, slow loads of extenal JavaScript). This is necessary, because in 
slow page load situations, the user may submit a form or click a link 
<em>before</em> page initialization has added an event handler for that submit 
or click; it was common in those cases for the a traditional request to be sent 
to the server for a link or form that was expected by the developer to only be 
accessed via an Ajax request. Without a server-side check (via the 
<code>Request.isXHR()</code> method), the server-side event handler would 
return a response that can not be handled in a traditional request, and the 
user would see the Tapestry exception report page.</p>
-
-<p>Tapestry 5.3 and earlier would wait for the page loaded event (by observing 
<a shape="rect" class="external-link" 
href="http://api.prototypejs.org/dom/document/observe/"; >Prototype's 
"dom:loaded" event</a>) before executing any JavaScript initialization 
functions. Likewise, in a partial page render (Ajax) update, it would ensure 
that all JavaScript libraries had been loaded before executing any 
initialization functions.</p>
-
-<p>It is not clear how this same functionality will be supported in Tapestry 
5.4 as the asynchronous module loading makes it difficult to know when all 
modules have been loaded and all initialization functions have been invoked.</p>
-
-<h2 id="JavaScriptRewrite-MappingModulestoAssets">Mapping Modules to 
Assets</h2>
-
-<p>Under RequireJS, modules are identified by string that represents a kind of 
virtual path on the server. The path does not start with a scheme, or a slash, 
or end with a ".js" suffix: in all those cases, RequireJS will load a 
JavaScript file but not treat it as a dependency.</p>
-
-<p>On the server side, Tapestry will map the path to a classpath asset.</p>
-
-<p>There must be provisions for the following options:</p>
-
-<ul><li>A module may be overriden (for instance, to work around a bug), in 
which case a specific asset may be used for the module, rather than the 
default</li><li>A module may need to be converted from one language to another: 
specifically, a module may be written in CoffeeScript, and need to be compiled 
down to JavaScript</li><li>A module's content may be aggregated with other 
related modules (much like a Tapestry 5.3 stack), especially in 
production<p></p><p></p><p></p><p></p><p></p><p>
-<sup id="FootnoteMarker4">
-    <a shape="rect" class="FootnoteMarker" name="FootnoteMarker4" 
href="#Footnote4" onclick="footnoteHighlight(&quot;4&quot;,true);" 
alt="Footnote: Click here to display the footnote" title="Footnote: Click here 
to display the footnote">
-            4
-    </a>
-</sup>
-</p><p></p><p></p><p></p><p></p><p></p></li><li>Module content (aggregated or 
not) should be minimized</li></ul>
-
-
-<p>In addition, it may be reasonable to have Tapestry automatically (or via 
some configuration) <a shape="rect" class="external-link" 
href="http://requirejs.org/docs/commonjs.html"; >wrap CommonJS modules as AMD 
modules</a></p><p></p><p></p><p></p><p></p><p></p><p>
-<sup id="FootnoteMarker5">
-    <a shape="rect" class="FootnoteMarker" name="FootnoteMarker5" 
href="#Footnote5" onclick="footnoteHighlight(&quot;5&quot;,true);" 
alt="Footnote: Click here to display the footnote" title="Footnote: Click here 
to display the footnote">
-            5
-    </a>
-</sup>
-</p><p></p><p></p><p></p><p></p><p></p><p></p>
-
-<p>Modules will be stored on the classpath, in a <code>modulejs</code> package 
below each library's root package. Modules within that package are referenced 
by their name relative to the package</p><p></p><p></p><p></p><p></p><p></p><p>
-<sup id="FootnoteMarker6">
-    <a shape="rect" class="FootnoteMarker" name="FootnoteMarker6" 
href="#Footnote6" onclick="footnoteHighlight(&quot;6&quot;,true);" 
alt="Footnote: Click here to display the footnote" title="Footnote: Click here 
to display the footnote">
-            6
-    </a>
-</sup>
-</p><p></p><p></p><p></p><p></p><p></p>.  <p></p>
-
-<p>Under this system, module <code>core/pubsub</code> would be the  file 
<code>pubsub.js</code> in the package 
<code>org.apache.tapestry5.corelib.modulejs</code>, since Tapestry's component 
library 'core' is mapped to package 
<code>org.apache.tapestry5.corelib</code>.</p>
-
-<p>Certain key modules, such as <a shape="rect" class="external-link" 
href="http://documentcloud.github.com/underscore/"; >Underscore</a> may be 
mapped at the root level, as they are used so often.</p>
-
-<h2 id="JavaScriptRewrite-ExtensionstoJavaScriptSupport">Extensions to 
JavaScriptSupport</h2>
-
-<p>A number of new methods will be added to JavaScriptSupport, to support the 
following behaviors:</p>
-
-<ul><li>require one or more modules</li><li>require a module (that exports a 
single function) and invoke the function, passing zero or more 
values<p></p><p></p><p></p><p></p><p></p><p>
-<sup id="FootnoteMarker7">
-    <a shape="rect" class="FootnoteMarker" name="FootnoteMarker7" 
href="#Footnote7" onclick="footnoteHighlight(&quot;7&quot;,true);" 
alt="Footnote: Click here to display the footnote" title="Footnote: Click here 
to display the footnote">
-            7
-    </a>
-</sup>
-</p><p></p><p></p><p></p><p></p><p></p></li><li>require a module and a 
function name and invoke named function exported by the module, passing zero or 
more values</li></ul>
-
-
-<p>The intent here is to support shifting of client-side behavior from the 5.3 
style, an approach that involved monkey-patching functions onto 
<code>T5.initializers</code>, and move the same logic into modules, preferably 
with simpler parameters.  It is also expected that there will be greater use of 
<code>data-</code> prefixed HTML5 attributes in place of separate 
configuration, as outlined above.</p>
-
-<h2 id="JavaScriptRewrite-@Requireannotation">@Require annotation</h2>
-
-<p>In the (hopefully) common case that a module can operate without additional 
configuration, the @Require annotation will be analagous to the Tapestry 5.2 <a 
shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Import.html";>@Import</a>
 annotation.  It will allow one or more modules to be required. This is only 
useful when the modules are stand-alone (not needing any explicit 
configuration).</p>
-
-<h2 id="JavaScriptRewrite-IncreasedUseOfPublish/Subscribe">Increased Use Of 
Publish/Subscribe</h2>
-
-<p>An inherent limitation of Tapestry 5.3 and earlier is the too-direct 
connection between DOM events and client behaviors. Coding in terms of "the 
user clicks and the event handler submits a request" makes it very hard to fine 
tune behavior.  For example, much work and experimentation was needed in order 
to introduce a Confirm mixin that could be used to introduce a confirmation 
dialog before allowing an event (clicking a link or submitting a form) to 
continue.</p>
-
-<p>A better pattern is to convert DOM events into messages in a 
Publish/Subscribe (PubSub) system. Tapestry 5.3 introduced an initial pass at a 
PubSub library for this purpose, but more work is needed in this area, 
especially in terms of preventing unwanted references to DOM elements from 
impacting garbage collection under Internet Explorer.</p>
-
-<p>Regardless of the exact details, in Tapestry all handling of user input 
should occur in two stages:  a very simple event handler whose job is simply to 
send a PubSub message, and handlers for those PubSub message.</p>
-
-<h2 id="JavaScriptRewrite-AvoidingJavaScriptClasses">Avoiding JavaScript 
Classes</h2>
-
-<p>Much of the logic for important operations, such as client-side validation 
(and input field decoration), are based on the use of client-side <a 
shape="rect" class="external-link" 
href="http://api.prototypejs.org/language/Class/"; >JavaScript classes</a>. This 
has been somewhat valuable in terms of making the behavior controllable via 
monkey patching. On the other hand, it cam be clumsy to accomplish in practice, 
as the desired behavior is only described in terms of the implementation.</p>
-
-<p>In addition, these JavaScript class instances are yet more memory for the 
browser to manage. </p>
-
-<p>By using a fine-grained set of PubSub messages, the logic usually bundled 
into a single JavaScript class can be assembled (and, in theory, replaced) more 
easily. In addition, Tapestry can do less.  For instance, rather than 
monkey-patching the <code>Tapestry.ZoneManager</code> class to enable new 
behavior when a Zone element is updated, relying on a PubSub message to learn 
when the Zone was updated, and perform the desired updates or animations 
there.</p>
-
-<h2 id="JavaScriptRewrite-ExposeGlobalMessageCatalogtoClient">Expose Global 
Message Catalog to Client</h2>
-
-<p>Tapestry currently maintains two global message catalogs; a global 
server-side catalog (usually named 
<code>WEB-INF/app.properties</code></p><p></p><p></p><p></p><p></p><p></p><p>
-<sup id="FootnoteMarker8">
-    <a shape="rect" class="FootnoteMarker" name="FootnoteMarker8" 
href="#Footnote8" onclick="footnoteHighlight(&quot;8&quot;,true);" 
alt="Footnote: Click here to display the footnote" title="Footnote: Click here 
to display the footnote">
-            8
-    </a>
-</sup>
-</p><p></p><p></p><p></p><p></p><p></p>) and a client-side catalog. The 
client-side catalog is smaller, more limited, and less extensible.<p></p>
-
-<p>Allowing the client application to have full access to the entire message 
catalog would make maintaining the catalog simpler, and make it easier to keep 
client-side and server-side messages consistent.</p>
-
-<p>For security purposes, it should be possible to exclude some keys from the 
message catalog exposed to the client. In addition, keys whose values include 
<code>String.format()</code> productions (for example, <code>%s</code>) should 
be excluded, as those productions are meaningless in the client.</p>
-
-<h2 id="JavaScriptRewrite-PartialPageUpdateResponse">Partial Page Update 
Response</h2>
-
-<p>A key part of Tapestry's dynamic behavior has been the partial page update; 
a specific JSON reply to Ajax requests (usually initiated via a Zone 
component).</p>
-
-<p>The format and behavior of the response has evolved from release to 
release.  </p>
-
-<p>When an Ajax request is processed by the server, the response should handle 
any of a number of outcomes:</p>
-
-<ul><li>Redirect the entire page to a new URL (on the server, or 
elsewhere)</li><li>A server-side error to be presented to the 
user<p></p><p></p><p></p><p></p><p></p><p>
-<sup id="FootnoteMarker9">
-    <a shape="rect" class="FootnoteMarker" name="FootnoteMarker9" 
href="#Footnote9" onclick="footnoteHighlight(&quot;9&quot;,true);" 
alt="Footnote: Click here to display the footnote" title="Footnote: Click here 
to display the footnote">
-            9
-    </a>
-</sup>
-</p><p></p><p></p><p></p><p></p><p></p></li><li>Update the content of an 
implicit (originating) element; typically the element for the Zone that 
triggered the request</li><li>Update the content of any number of other 
elements (identified by their client-side id)</li><li>Inject new JavaScript 
libraries into the page</li><li>Inject new CSS links into the 
page</li><li>Peform initializations (using <code>T5.initializers</code>) ... 
but only after all content updates have occurred</li></ul>
-
-
-<p>The injected JavaScript libraries and CSS links will often duplicate 
libraries and CSS links already present on the page; when the page is partially 
rendered, the server has no way to know what full or partial page renders have 
already occured</p><p></p><p></p><p></p><p></p><p></p><p>
-<sup id="FootnoteMarker10">
-    <a shape="rect" class="FootnoteMarker" name="FootnoteMarker10" 
href="#Footnote10" onclick="footnoteHighlight(&quot;10&quot;,true);" 
alt="Footnote: Click here to display the footnote" title="Footnote: Click here 
to display the footnote">
-            10
-    </a>
-</sup>
-</p><p></p><p></p><p></p><p></p><p></p>.<p></p>
-
-<p>Tapestry 5.3 first loads any additional JavaScript (usually by adding new 
<code>&lt;script&gt;</code> tags to the page). Once JavaScript libraries and 
CSS links have been added, and JavaScript libraries have been loaded, the DOM 
is updated with the new content. Lastly, any initializations are processed.</p>
-
-<p>For Tapestry 5.4, a number of changes are planned:</p>
-
-<ul><li>Tapestry 5.3 style initializations will be a specific application of 
5.4 style module requirement and invocation</li><li><a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/InitializationPriority.html#IMMEDIATE";>IMMEDIATE</a>
 may occur before DOM changes</li><li>Module requirement/invocation will occur 
in <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/InitializationPriority.html";>initialization
 priority order</a>; for any single priority, initialization will occur in 
render order<p></p><p></p><p></p><p></p><p></p><p>
-<sup id="FootnoteMarker11">
-    <a shape="rect" class="FootnoteMarker" name="FootnoteMarker11" 
href="#Footnote11" onclick="footnoteHighlight(&quot;11&quot;,true);" 
alt="Footnote: Click here to display the footnote" title="Footnote: Click here 
to display the footnote">
-            11
-    </a>
-</sup>
-</p><p></p><p></p><p></p><p></p><p></p>.</li><li>The response will be 
embeddable inside other JSONObject responses.</li></ul>
-
-
-<p>To expand on the last note first; the keys that define imported JavaScript 
and CSS, module requirement and invocation, and content update will not be 
top-level keys of the JSONObject response: they will be buried inside a 
<code>tapestry</code> top-level key. An available function will be provided 
that takes an arbitrary JSONObject, extracts the <code>tapestry</code> key and 
handles it, then invokes a provided callback before the module requirement and 
invocation step.  The intent is for requests that perform purely data oriented 
operations, the server-side can not only provide a response, but can <em>piggy 
back</em> client-side updates in the response.</p>
-
-<h1 id="JavaScriptRewrite-MaintainingBackwardsCompatibility">Maintaining 
Backwards Compatibility</h1>
-
-<p>Backwards compatibility is the greatest challenge here; ideally, 
applications (and third party libraries) that were written for Tapestry 5.3 
will continue to operate unchanged in Tapestry 5.4.</p>
-
-<p>At the same time, much of what Tapestry 5.3 does on the client and server 
should be deprecated (and hopefully, simplified).</p>
-
-<p>Compatibility mode will be initially enabled, via a <a shape="rect" 
href="symbols.html">symbol</a> value.</p>
-
-<p>In compatibility mode, additional client-side JavaScript will be loaded to 
provide the same <code>T5</code> and <code>Tapestry</code> namespaces available 
in Tapestry 5.3.</p>
-
-<p>The implementations of these namespaces will be reconstructed in terms of 
the new module system.  The loading of the compatibility layer will occur 
during full page render.</p>
-
-<h1 id="JavaScriptRewrite-TwitterBootstrap">Twitter Bootstrap</h1>
-
-<p>In Tapestry 5.3 and earlier, Tapestry automatically includes a default CSS 
link on all pages. This CSS file acts as a partial CSS reset (normalizing the 
look of the application across common browsers), and provides a large number of 
CSS rules that many Tapestry components expect to be present. The CSS rules are 
all given a "t-" (for Tapestry) prefix.</p>
-
-<p>For Tapestry 5.4, this  default CSS link will be changed to be the default 
<a shape="rect" class="external-link" 
href="http://twitter.github.com/bootstrap/"; >Twitter Bootstrap</a>. This will 
not only refresh the Tapestry look and feel, but will provide a better 
structure for customizing the application's look and feel.</p>
-
-<p>As with today, it will be possible to override the location of this CSS 
file (for example, to use a newer version of Bootstrap than is packaged in the 
application, or an application-specific customized version).</p>
-
-<p>This will entail some changes to some components, to make use of reasonable 
or equivalent Bootstrap CSS classes, rather than the Tapestry 5.3 classes.</p>
-
-<p>Twitter Bootstrap also includes a number of jQuery-based plugins; these 
will be exposed in the module system.</p>
-
-<h1 id="JavaScriptRewrite-ContentDeliveryNetworkIntegration">Content Delivery 
Network Integration</h1>
-
-<p>Tapestry 5.3 has limited ability to integrate into a <a shape="rect" 
class="external-link" 
href="http://en.wikipedia.org/wiki/Content_delivery_network"; >content delivery 
network</a>; it can dynamically rewrite URLs for assets (including JavaScript 
libraries, CSS files, image files, etc.). However, it assumes that the CDN can 
"pull" the content, as needed, from the live site.</p>
-
-<p>A desirable feature would be request URL that would produce a 
JSON-formatted report of all assets that should be mirrored by the CDN: this 
would include all files that might be exposed to the browser, including virtual 
assets (such as JavaScript stacks, aggregated modules, and so forth).  This 
could be leveraged by a tool that would use this information to extract the 
assets from the live application and exported to the CDN.</p>
-
-<p>Determining what assets are available is somewhat problematic as Tapestry 
mixes server-side only resources (.class files, .tml files, etc.) freely with 
assets that might be exposed to the 
browser</p><p></p><p></p><p></p><p></p><p></p><p>
-<sup id="FootnoteMarker12">
-    <a shape="rect" class="FootnoteMarker" name="FootnoteMarker12" 
href="#Footnote12" onclick="footnoteHighlight(&quot;12&quot;,true);" 
alt="Footnote: Click here to display the footnote" title="Footnote: Click here 
to display the footnote">
-            12
-    </a>
-</sup>
-</p><p></p><p></p><p></p><p></p><p></p>. Some of those server-side resource 
may expose details, such as other server hosts and potentially user names and 
passwords, that should never be exposed to the client.<p></p>
-
-<p>In addition, a "walk" of the classpath to locate potential exportable 
assets can be quite expensive (though not considerably more so than what 
Tapestry already does at startup to identify page and component classes).</p>
-
-<h1 id="JavaScriptRewrite-ExtJSCompatibility">ExtJS Compatibility</h1>
-
-<p>To be determined. ExtJS inlcudes it own system for dynamically loading 
ExtJS modules, as well as expressing dependencies between them. Its 
capabilities overlap what RequireJS offers. It would be nice if, in an ExtJS 
application, the ExtJS loader could be used instead of RequireJS, or at least, 
ensure that they do not interfere with each other.</p>
-
-<h1 id="JavaScriptRewrite-MoreThoughts">More Thoughts</h1>
-
-<p>This is a big undertaking; this document is not a contract, and is 
certainly not complete, but is only starting point for discussions about what 
will be forthcoming in Tapestry 5.4.</p>
-
-<hr>
-
-<p></p><p></p><p></p><p></p><p></p><p></p><p><table class="Footnotes" 
style="width: 100%; border:none;" cellspacing="0" cellpadding="0" summary="This 
table contains one or more notes for references made elsewhere on the 
page."><caption class="accessibility">Footnotes</caption><thead 
class="accessibility"><tr class="accessibility"><th colspan="1" rowspan="1" 
class="accessibility" id="footnote-th1">Reference</th><th colspan="1" 
rowspan="1" class="accessibility" 
id="footnote-th2">Notes</th></tr></thead><tbody><tr name="Footnote1"><td 
colspan="1" rowspan="1" valign="top" class="FootnoteNum" 
headings="footnote-th1">
-        <a shape="rect" id="FootnoteNum1" href="#FootnoteMarker1" 
onclick="footnoteMarkerHighlight(&quot;1&quot;);" 
onmouseover="footnoteHighlight(&quot;1&quot;,false);" alt="Footnote: Click to 
return to reference in text" title="Footnote: Click to return to reference in 
text">
-            1
-        </a>
-      </td><td colspan="1" rowspan="1" valign="top" class="Footnote" 
id="Footnote1" width="100%" headings="footnote-th2">
-          By "bespoke", we mean a non-component-based, manually created page; 
a standalone static HTML page.
-      </td></tr><tr name="Footnote2"><td colspan="1" rowspan="1" valign="top" 
class="FootnoteNum" headings="footnote-th1">
-        <a shape="rect" id="FootnoteNum2" href="#FootnoteMarker2" 
onclick="footnoteMarkerHighlight(&quot;2&quot;);" 
onmouseover="footnoteHighlight(&quot;2&quot;,false);" alt="Footnote: Click to 
return to reference in text" title="Footnote: Click to return to reference in 
text">
-            2
-        </a>
-      </td><td colspan="1" rowspan="1" valign="top" class="Footnote" 
id="Footnote2" width="100%" headings="footnote-th2">
-          Prior to 5.3, it was the <code>Tapestry.Initializers</code> 
namespace;  both names reference the same object, for backwards compatibility.
-      </td></tr><tr name="Footnote3"><td colspan="1" rowspan="1" valign="top" 
class="FootnoteNum" headings="footnote-th1">
-        <a shape="rect" id="FootnoteNum3" href="#FootnoteMarker3" 
onclick="footnoteMarkerHighlight(&quot;3&quot;);" 
onmouseover="footnoteHighlight(&quot;3&quot;,false);" alt="Footnote: Click to 
return to reference in text" title="Footnote: Click to return to reference in 
text">
-            3
-        </a>
-      </td><td colspan="1" rowspan="1" valign="top" class="Footnote" 
id="Footnote3" width="100%" headings="footnote-th2">
-          Tapestry assists with unique id allocation, but it would be much 
better if unique ids were not necessary.
-      </td></tr><tr name="Footnote4"><td colspan="1" rowspan="1" valign="top" 
class="FootnoteNum" headings="footnote-th1">
-        <a shape="rect" id="FootnoteNum4" href="#FootnoteMarker4" 
onclick="footnoteMarkerHighlight(&quot;4&quot;);" 
onmouseover="footnoteHighlight(&quot;4&quot;,false);" alt="Footnote: Click to 
return to reference in text" title="Footnote: Click to return to reference in 
text">
-            4
-        </a>
-      </td><td colspan="1" rowspan="1" valign="top" class="Footnote" 
id="Footnote4" width="100%" headings="footnote-th2">
-          A request for any module should provide the aggregated set of 
modules; RequireJS will not need to send additional requests for the other 
modules
-      </td></tr><tr name="Footnote5"><td colspan="1" rowspan="1" valign="top" 
class="FootnoteNum" headings="footnote-th1">
-        <a shape="rect" id="FootnoteNum5" href="#FootnoteMarker5" 
onclick="footnoteMarkerHighlight(&quot;5&quot;);" 
onmouseover="footnoteHighlight(&quot;5&quot;,false);" alt="Footnote: Click to 
return to reference in text" title="Footnote: Click to return to reference in 
text">
-            5
-        </a>
-      </td><td colspan="1" rowspan="1" valign="top" class="Footnote" 
id="Footnote5" width="100%" headings="footnote-th2">
-          Traditionally, Tapestry has configured this kind of behavior via 
service contributions, but there is ample evidence that this could be done 
using external configuration, perhaps using a JSON file in the module package, 
to control aggregation, wrapping, and other aspects the process. This would be 
more agile, as it would not require restarts when the configuration changes.
-      </td></tr><tr name="Footnote6"><td colspan="1" rowspan="1" valign="top" 
class="FootnoteNum" headings="footnote-th1">
-        <a shape="rect" id="FootnoteNum6" href="#FootnoteMarker6" 
onclick="footnoteMarkerHighlight(&quot;6&quot;);" 
onmouseover="footnoteHighlight(&quot;6&quot;,false);" alt="Footnote: Click to 
return to reference in text" title="Footnote: Click to return to reference in 
text">
-            6
-        </a>
-      </td><td colspan="1" rowspan="1" valign="top" class="Footnote" 
id="Footnote6" width="100%" headings="footnote-th2">
-          A rarely used feature of Tapestry is that a component library name 
may be mapped to multiple packages; resolving a module name may require a 
search among the packages. There is the expectation that the developer will 
ensure that there are no duplications that would lead to ambiguities.
-      </td></tr><tr name="Footnote7"><td colspan="1" rowspan="1" valign="top" 
class="FootnoteNum" headings="footnote-th1">
-        <a shape="rect" id="FootnoteNum7" href="#FootnoteMarker7" 
onclick="footnoteMarkerHighlight(&quot;7&quot;);" 
onmouseover="footnoteHighlight(&quot;7&quot;,false);" alt="Footnote: Click to 
return to reference in text" title="Footnote: Click to return to reference in 
text">
-            7
-        </a>
-      </td><td colspan="1" rowspan="1" valign="top" class="Footnote" 
id="Footnote7" width="100%" headings="footnote-th2">
-          Values passed to module functions may be limited to String and <a 
shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/json/JSONObject.html";>JSONObject</a>.
-      </td></tr><tr name="Footnote8"><td colspan="1" rowspan="1" valign="top" 
class="FootnoteNum" headings="footnote-th1">
-        <a shape="rect" id="FootnoteNum8" href="#FootnoteMarker8" 
onclick="footnoteMarkerHighlight(&quot;8&quot;);" 
onmouseover="footnoteHighlight(&quot;8&quot;,false);" alt="Footnote: Click to 
return to reference in text" title="Footnote: Click to return to reference in 
text">
-            8
-        </a>
-      </td><td colspan="1" rowspan="1" valign="top" class="Footnote" 
id="Footnote8" width="100%" headings="footnote-th2">
-          <code>app.properties</code> provides application-specific messages, 
and overrides of other messages provided by Tapestry and other third-party 
libraries. The global message catalog is actually a composite of all of these 
sources.
-      </td></tr><tr name="Footnote9"><td colspan="1" rowspan="1" valign="top" 
class="FootnoteNum" headings="footnote-th1">
-        <a shape="rect" id="FootnoteNum9" href="#FootnoteMarker9" 
onclick="footnoteMarkerHighlight(&quot;9&quot;);" 
onmouseover="footnoteHighlight(&quot;9&quot;,false);" alt="Footnote: Click to 
return to reference in text" title="Footnote: Click to return to reference in 
text">
-            9
-        </a>
-      </td><td colspan="1" rowspan="1" valign="top" class="Footnote" 
id="Footnote9" width="100%" headings="footnote-th2">
-          This was greatly enhanced in 5.3 to present the full exception 
report in a pop-up iframe.
-      </td></tr><tr name="Footnote10"><td colspan="1" rowspan="1" valign="top" 
class="FootnoteNum" headings="footnote-th1">
-        <a shape="rect" id="FootnoteNum10" href="#FootnoteMarker10" 
onclick="footnoteMarkerHighlight(&quot;10&quot;);" 
onmouseover="footnoteHighlight(&quot;10&quot;,false);" alt="Footnote: Click to 
return to reference in text" title="Footnote: Click to return to reference in 
text">
-            10
-        </a>
-      </td><td colspan="1" rowspan="1" valign="top" class="Footnote" 
id="Footnote10" width="100%" headings="footnote-th2">
-          It might be possible for the request to include a list of what's 
already loaded in the browser, so that the server can filter what it sends 
back; however, given factors such as content compression and typical upload vs. 
download bandwidth, it is almost certainly more effective for the browser to 
send too much, and let the client filter out duplicates.
-      </td></tr><tr name="Footnote11"><td colspan="1" rowspan="1" valign="top" 
class="FootnoteNum" headings="footnote-th1">
-        <a shape="rect" id="FootnoteNum11" href="#FootnoteMarker11" 
onclick="footnoteMarkerHighlight(&quot;11&quot;);" 
onmouseover="footnoteHighlight(&quot;11&quot;,false);" alt="Footnote: Click to 
return to reference in text" title="Footnote: Click to return to reference in 
text">
-            11
-        </a>
-      </td><td colspan="1" rowspan="1" valign="top" class="Footnote" 
id="Footnote11" width="100%" headings="footnote-th2">
-          Technically, in the order of invocations on JavaScriptSupport.
-      </td></tr><tr name="Footnote12"><td colspan="1" rowspan="1" valign="top" 
class="FootnoteNum" headings="footnote-th1">
-        <a shape="rect" id="FootnoteNum12" href="#FootnoteMarker12" 
onclick="footnoteMarkerHighlight(&quot;12&quot;);" 
onmouseover="footnoteHighlight(&quot;12&quot;,false);" alt="Footnote: Click to 
return to reference in text" title="Footnote: Click to return to reference in 
text">
-            12
-        </a>
-      </td><td colspan="1" rowspan="1" valign="top" class="Footnote" 
id="Footnote12" width="100%" headings="footnote-th2">
-          This should never have been the case, but that's hindsight.
-      
</td></tr></tbody></table></p><p></p><p></p><p></p><p></p><p></p><p></p></div>
+</div><h1 id="JavaScriptRewrite-TapestryandJavaScript">Tapestry and 
JavaScript</h1><p>Tapestry 5 has had a interesting mix of 
characteristics.</p><p>On the one hand, it has had a large number of features 
that work, and work well, right out of the box, with no special configuration 
or setup. This includes client-side validation, dynamic content updates, simple 
animations, progressive enhancement, and other standard Ajax and DHTML use 
cases.</p><p>In addition, Tapestry has evolved, from Tapestry 5.0 through 5.3, 
into a quite capable <em>provisioning</em> framework:</p><ul><li>JavaScript 
libraries may be combined into <em>stacks</em> that are combined (in 
production) into a single virtual file</li><li>JavaScript libraries and CSS 
files may be minified</li><li>Libraries, stacks, and other resources are 
exposed to the browser with a versioned URL and far-future expires header, to 
support aggressive client-caching</li><li>Resources, including JavaScript and 
CSS, can be distributed inside 
 JARs (as part of reusable component libraries)</li><li>Compressible resources 
will be automatically GZip compressed if the client supports 
it</li></ul><p>However, JavaScript support in Tapestry is still unsatisfactory. 
Too often, Tapestry falls into an <a shape="rect" class="external-link" 
href="http://en.wikipedia.org/wiki/Uncanny_valley"; >uncanny valley</a> where 
the framework (server-side and client-side) does so much automatically that it 
becomes accepted that it does everything ... developers later discover, to 
their dismay, that the last 10% of custom behavior they desire is very hard to 
implement, because of all the common problems that plague any complex system: 
insufficient APIs, unexpected leaky abstractions, or just plain 
bugs.</p><p>Common examples of the challenges imposed by Tapestry include 
implementing a Confirm mixin, customizing behavior when a Zone component is 
dynamically updated, or any number of issues related to Forms, form elements, 
and Ajax updates.</p><p>Th
 is document is a roadmap for how Tapestry 5.4 will revisit the relationship 
between server-side Java and client-side JavaScript. Ultimately, we hope to 
convert this relationship from an obstacle to using Tapestry into an essential 
reason to select Tapestry in the first place.</p><h1 
id="JavaScriptRewrite-TapestryJavaScriptLimitations(through5.3)">Tapestry 
JavaScript Limitations (through 5.3)</h1><h2 
id="JavaScriptRewrite-DependenceonPrototype/Scriptaculous">Dependence on 
Prototype/Scriptaculous</h2><p>Tapestry made an early choice to embrace 
Prototype and Scriptaculous at a time when this made sense, circa 
2006-2007.</p><p>The goal was to have Tapestry provide a client-side API, the 
<code>Tapestry</code> namespace, that in turn would delegate complex behaviors 
(including DOM element selection, event management, and XmlHttpRequest 
processing) to a <em>foundational framework</em>. The goal was to isolate all 
the direct dependencies on Prototype in such a way that it would be possible,
  in the future, to swap out for a different foundational framework, such as 
jQuery or ExtJS. Unfortunately, expediency has proven to make this goal even 
less reachable!</p><h2 id="JavaScriptRewrite-LackofDocumentation">Lack of 
Documentation</h2><p>There has not, to date, been an adequate documentation of 
the <code>T5</code> and <code>Tapestry</code> namespaces, beyond the code 
itself.</p><h2 id="JavaScriptRewrite-LackofModuleStructure">Lack of Module 
Structure</h2><p>Beyond the basic use of namespaces, Tapestry has not embraced 
modern JavaScript usage; specifically, it makes limited use of <em>hygenic 
functions</em> to form modules. Hygenic functions are JavaScript functions that 
exist as a way to encapsulate private properties and functions. Tapestry 5.3 
makes more use of this pattern than previous releases.</p><p>What modularity is 
present in the JavaScript is organized around the <code>T5.initializers</code> 
(<code>Tapestry.Initializers</code>) namespace, and the mechanics of ful
 l-page and partial-page renders (described more fully below).</p><h2 
id="JavaScriptRewrite-ComplexInitialization">Complex Initialization</h2><p>Many 
users are perplexed by how Tapestry performs initialization. In typical web 
page construction, the developer would create a <code>&lt;script&gt;</code> 
block at the bottom of the page, and do initializations there. In Tapestry, it 
can be much more complex:</p><ul><li>A JavaScript library, containing one or 
more <em>initialization functions</em>, is created</li><li>The initialization 
functions must be <a shape="rect" class="external-link" 
href="http://en.wikipedia.org/wiki/Monkey_patching"; >monkey patched</a> into 
the T5.initializers (or older Tapestry.Initializers) namespace.</li><li>The <a 
shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html";>JavaScriptSupport</a>
 environmental must be used to invoke the function, by name, passing it a JSONOb
 ject to configure itself (the "specification")</li><li>The affected element 
must have a unique id attribute, used to coordinate the initialization in the 
client web browser. (Tapestry assists with unique id allocation, but it would 
be much better if unique ids were not necessary.)</li></ul><p>This often feels 
like overkill, but it is necessary for a number of desirable 
characteristics:</p><ul><li>Initialization code occurs in a single 
Tapestry-generated <code>&lt;script&gt;</code> block at the end of the page 
(just before the <code>&lt;/body&gt;</code> tag)</li><li>There is limited 
support for structuring the order of initialization</li><li>The mechanism works 
transparently in both full-page render requests (traditional) and partial-page 
render requests (Ajax)</li></ul><p>Despite this, the Tapestry approach can feel 
very "heavy". In a bespoke page, initialization that may affect many elements 
of the page often takes the form of a single event handler, attached to the 
<code>&lt;body&
 gt;</code> element, that catches events that bubble up from much lower in the 
DOM. The single handler function identifies the applicable elements using CSS 
selectors, including those that are based on HTML5 data- attributes. Additional 
data- attributes will define additional behavior ... for example, a URL for a 
triggered request. This is "light" because:</p><ul><li>There's a single event 
handler function (rather than a unique handler function instance per 
element)</li><li>The event handler may be anonymous (there's no name, or 
possibility of collision)</li><li>Elements are identified by DOM structure and 
CSS rather than their unique id (the element will often not have an id 
attribute)</li><li>Additional necessary configuration is directly attached to 
the element, rather than split</li><li>As the page is dynamically updated, 
there is no extra "bookkeeping" for added or removed elements; new elements 
inserted into the DOM dynamically are recognized as easily as those that were 
presen
 t on the initial render</li></ul><p>By contrast, Tapestry is 
"heavy":</p><ul><li>The initialization function must have a unique 
name</li><li>The element must have a unique id, to it can be located by the 
initialization function</li><li>The event handlers are attached directly to the 
element</li><li>Duplicated elements will have duplicated event 
handlers</li><li>Additional behavior is specified as a JSON object passed to 
the initialization function</li><li>Injecting new elements into the DOM 
requires invoking initialization functions to wire up the necessary event 
handlers</li><li>In (older versions of) Internet Explorer, removing elements 
may leave memory leaks as JavaScript objects retain references to DOM objects 
and vice-versa</li></ul><h1 
id="JavaScriptRewrite-JavaScriptImprovementsfor5.4">JavaScript Improvements for 
5.4</h1><p>The goals for Tapestry 5.4 are:</p><ul><li>Break the dependency on 
Prototype and allow Tapestry to be used with any client-side "foundation" 
framework, s
 eamlessly: minimally, this should include jQuery</li><li>Bring Tapestry's 
JavaScript approach more inline with modern practices (the "light" approach 
described above)</li><li>Let the JavaScript be modular, and loaded dynamically 
and asynchonously, only as needed</li><li>Optimize for fast page 
loads</li><li>Backwards compatibility to the Tapestry 5.3 approach until at 
least 5.5 or 5.6</li><li>Simplify Tapestry's client-side behavior, but make it 
easier to hook into, extend, and override</li></ul><h2 
id="JavaScriptRewrite-RequireJS">RequireJS</h2><p>Rather than reinvent the 
wheel, Tapestry should incorporate a proper JavaScript module loader; <a 
shape="rect" class="external-link" href="http://requirejs.org/"; >RequireJS</a> 
is an excellent candidate, especially considering the new features provided in 
its 2.0.1 release.</p><p>RequireJS supports the <a shape="rect" 
class="external-link" href="https://github.com/amdjs/amdjs-api/wiki/AMD"; >AMD 
(Asynchronous Module Format)</a>, with some a
 dditional support for the <a shape="rect" class="external-link" 
href="http://www.commonjs.org/"; >CommonJS</a> module format (the format used by 
Node.js). The latter is simpler, but is designed for a server-side environment; 
AMD is specifically designed to handle asynchronous loading of JavaScript into 
a web browser.</p><p>RequireJS is geared towards bespoke applications; for 
Tapestry it is expected that some of the pathing and other configuration 
normally done in the client using the RequireJS API will instead by handled 
more dynamically on the server, using typically Tapestry configuration and 
extension mechanisms. For example, RequireJS allows mappings of module names to 
URLs, which is useful when working with multiple third-party JavaScript 
libraries that may be organized differently form each other. Tapestry can 
incorporate such logic on the server side instead, making the interface from 
the browser to the server uniform, even when the details of where each module 
is stored is q
 uite variable.</p><h2 
id="JavaScriptRewrite-SlowPageLoadandInitialization">Slow Page Load and 
Initialization</h2><p>Tapestry 5.1 and up has support for dealing with slow 
page loads (especially, slow loads of extenal JavaScript). This is necessary, 
because in slow page load situations, the user may submit a form or click a 
link <em>before</em> page initialization has added an event handler for that 
submit or click; it was common in those cases for the a traditional request to 
be sent to the server for a link or form that was expected by the developer to 
only be accessed via an Ajax request. Without a server-side check (via the 
<code>Request.isXHR()</code> method), the server-side event handler would 
return a response that can not be handled in a traditional request, and the 
user would see the Tapestry exception report page.</p><p>Tapestry 5.3 and 
earlier would wait for the page loaded event (by observing <a shape="rect" 
class="external-link" href="http://api.prototypejs.org/dom/docum
 ent/observe/" >Prototype's "dom:loaded" event</a>) before executing any 
JavaScript initialization functions. Likewise, in a partial page render (Ajax) 
update, it would ensure that all JavaScript libraries had been loaded before 
executing any initialization functions.</p><p>It is not clear how this same 
functionality will be supported in Tapestry 5.4 as the asynchronous module 
loading makes it difficult to know when all modules have been loaded and all 
initialization functions have been invoked.</p><h2 
id="JavaScriptRewrite-MappingModulestoAssets">Mapping Modules to 
Assets</h2><p>Under RequireJS, modules are identified by string that represents 
a kind of virtual path on the server. The path does not start with a scheme, or 
a slash, or end with a ".js" suffix: in all those cases, RequireJS will load a 
JavaScript file but not treat it as a dependency.</p><p>On the server side, 
Tapestry will map the path to a classpath asset.</p><p>There must be provisions 
for the following options:</p>
 <ul><li>A module may be overriden (for instance, to work around a bug), in 
which case a specific asset may be used for the module, rather than the 
default</li><li>A module may need to be converted from one language to another: 
specifically, a module may be written in CoffeeScript, and need to be compiled 
down to JavaScript</li><li>A module's content may be aggregated with other 
related modules (much like a Tapestry 5.3 stack), especially in production. (A 
request for any module should provide the aggregated set of modules; RequireJS 
will not need to send additional requests for the other 
modules.)</li><li>Module content (aggregated or not) should be 
minimized</li></ul><p>In addition, it may be reasonable to have Tapestry 
automatically (or via some configuration) <a shape="rect" class="external-link" 
href="http://requirejs.org/docs/commonjs.html"; >wrap CommonJS modules as AMD 
modules</a>. (Traditionally, Tapestry has configured this kind of behavior via 
service contributions, but the
 re is ample evidence that this could be done using external configuration, 
perhaps using a JSON file in the module package, to control aggregation, 
wrapping, and other aspects the process. This would be more agile, as it would 
not require restarts when the configuration changes.)</p><p>Modules will be 
stored on the classpath, in a <code>modulejs</code> package below each 
library's root package. Modules within that package are referenced by their 
name relative to the package. (A rarely used feature of Tapestry is that a 
component library name may be mapped to multiple packages; resolving a module 
name may require a search among the packages. There is the expectation that the 
developer will ensure that there are no duplications that would lead to 
ambiguities.)</p><p>Under this system, module <code>core/pubsub</code> would be 
the file <code>pubsub.js</code> in the package 
<code>org.apache.tapestry5.corelib.modulejs</code>, since Tapestry's component 
library 'core' is mapped to package 
 <code>org.apache.tapestry5.corelib</code>.</p><p>Certain key modules, such as 
<a shape="rect" class="external-link" 
href="http://documentcloud.github.com/underscore/"; >Underscore</a> may be 
mapped at the root level, as they are used so often.</p><h2 
id="JavaScriptRewrite-ExtensionstoJavaScriptSupport">Extensions to 
JavaScriptSupport</h2><p>A number of new methods will be added to 
JavaScriptSupport, to support the following behaviors:</p><ul><li>require one 
or more modules</li><li>require a module (that exports a single function) and 
invoke the function, passing zero or more values. (Values passed to module 
functions may be limited to String and <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/json/JSONObject.html";>JSONObject</a>.)</li><li>require
 a module and a function name and invoke named function exported by the module, 
passing zero or more values</li></ul><p>The intent here is to support shifting 
of client-side behavior
  from the 5.3 style, an approach that involved monkey-patching functions onto 
<code>T5.initializers</code>, and move the same logic into modules, preferably 
with simpler parameters. It is also expected that there will be greater use of 
<code>data-</code> prefixed HTML5 attributes in place of separate 
configuration, as outlined above.</p><h2 
id="JavaScriptRewrite-@Requireannotation">@Require annotation</h2><p>In the 
(hopefully) common case that a module can operate without additional 
configuration, the @Require annotation will be analagous to the Tapestry 5.2 <a 
shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Import.html";>@Import</a>
 annotation. It will allow one or more modules to be required. This is only 
useful when the modules are stand-alone (not needing any explicit 
configuration).</p><h2 
id="JavaScriptRewrite-IncreasedUseOfPublish/Subscribe">Increased Use Of 
Publish/Subscribe</h2><p>An inherent limitation of 
 Tapestry 5.3 and earlier is the too-direct connection between DOM events and 
client behaviors. Coding in terms of "the user clicks and the event handler 
submits a request" makes it very hard to fine tune behavior. For example, much 
work and experimentation was needed in order to introduce a Confirm mixin that 
could be used to introduce a confirmation dialog before allowing an event 
(clicking a link or submitting a form) to continue.</p><p>A better pattern is 
to convert DOM events into messages in a Publish/Subscribe (PubSub) system. 
Tapestry 5.3 introduced an initial pass at a PubSub library for this purpose, 
but more work is needed in this area, especially in terms of preventing 
unwanted references to DOM elements from impacting garbage collection under 
Internet Explorer.</p><p>Regardless of the exact details, in Tapestry all 
handling of user input should occur in two stages: a very simple event handler 
whose job is simply to send a PubSub message, and handlers for those PubSub mes
 sage.</p><h2 id="JavaScriptRewrite-AvoidingJavaScriptClasses">Avoiding 
JavaScript Classes</h2><p>Much of the logic for important operations, such as 
client-side validation (and input field decoration), are based on the use of 
client-side <a shape="rect" class="external-link" 
href="http://api.prototypejs.org/language/Class/"; >JavaScript classes</a>. This 
has been somewhat valuable in terms of making the behavior controllable via 
monkey patching. On the other hand, it cam be clumsy to accomplish in practice, 
as the desired behavior is only described in terms of the 
implementation.</p><p>In addition, these JavaScript class instances are yet 
more memory for the browser to manage.</p><p>By using a fine-grained set of 
PubSub messages, the logic usually bundled into a single JavaScript class can 
be assembled (and, in theory, replaced) more easily. In addition, Tapestry can 
do less. For instance, rather than monkey-patching the 
<code>Tapestry.ZoneManager</code> class to enable new behavior 
 when a Zone element is updated, relying on a PubSub message to learn when the 
Zone was updated, and perform the desired updates or animations there.</p><h2 
id="JavaScriptRewrite-ExposeGlobalMessageCatalogtoClient">Expose Global Message 
Catalog to Client</h2><p>Tapestry currently maintains two global message 
catalogs; a global server-side catalog (usually named 
<code>WEB-INF/app.properties) and a client-side catalog. (app.properties 
provides application-specific messages, and overrides of other messages 
provided by Tapestry and other third-party libraries. The global message 
catalog is actually a composite of all of these sources.) </code>The 
client-side catalog is smaller, more limited, and less 
extensible.</p><p>Allowing the client application to have full access to the 
entire message catalog would make maintaining the catalog simpler, and make it 
easier to keep client-side and server-side messages consistent.</p><p>For 
security purposes, it should be possible to exclude some keys 
 from the message catalog exposed to the client. In addition, keys whose values 
include <code>String.format()</code> productions (for example, <code>%s</code>) 
should be excluded, as those productions are meaningless in the client.</p><h2 
id="JavaScriptRewrite-PartialPageUpdateResponse">Partial Page Update 
Response</h2><p>A key part of Tapestry's dynamic behavior has been the partial 
page update; a specific JSON reply to Ajax requests (usually initiated via a 
Zone component).</p><p>The format and behavior of the response has evolved from 
release to release.</p><p>When an Ajax request is processed by the server, the 
response should handle any of a number of outcomes:</p><ul><li>Redirect the 
entire page to a new URL (on the server, or elsewhere)</li><li>A server-side 
error to be presented to the user. (This was greatly enhanced in 5.3 to present 
the full exception report in a pop-up iframe.)</li><li>Update the content of an 
implicit (originating) element; typically the element for the 
 Zone that triggered the request</li><li>Update the content of any number of 
other elements (identified by their client-side id)</li><li>Inject new 
JavaScript libraries into the page</li><li>Inject new CSS links into the 
page</li><li>Peform initializations (using <code>T5.initializers</code>) ... 
but only after all content updates have occurred</li></ul><p>The injected 
JavaScript libraries and CSS links will often duplicate libraries and CSS links 
already present on the page; when the page is partially rendered, the server 
has no way to know what full or partial page renders have already occurred. (It 
might be possible for the request to include a list of what's already loaded in 
the browser, so that the server can filter what it sends back; however, given 
factors such as content compression and typical upload vs. download bandwidth, 
it is almost certainly more effective for the browser to send too much, and let 
the client filter out duplicates.)</p><p>Tapestry 5.3 first loads any ad
 ditional JavaScript (usually by adding new <code>&lt;script&gt;</code> tags to 
the page). Once JavaScript libraries and CSS links have been added, and 
JavaScript libraries have been loaded, the DOM is updated with the new content. 
Lastly, any initializations are processed.</p><p>For Tapestry 5.4, a number of 
changes are planned:</p><ul><li>Tapestry 5.3 style initializations will be a 
specific application of 5.4 style module requirement and invocation</li><li><a 
shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/InitializationPriority.html#IMMEDIATE";>IMMEDIATE</a>
 may occur before DOM changes</li><li>Module requirement/invocation will occur 
in <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/InitializationPriority.html";>initialization
 priority order</a>; for any single priority, initialization will occur in 
render order. (Technically
 , in the order of invocations on JavaScriptSupport.)</li><li>The response will 
be embeddable inside other JSONObject responses.</li></ul><p>To expand on the 
last note first; the keys that define imported JavaScript and CSS, module 
requirement and invocation, and content update will not be top-level keys of 
the JSONObject response: they will be buried inside a <code>tapestry</code> 
top-level key. An available function will be provided that takes an arbitrary 
JSONObject, extracts the <code>tapestry</code> key and handles it, then invokes 
a provided callback before the module requirement and invocation step. The 
intent is for requests that perform purely data oriented operations, the 
server-side can not only provide a response, but can <em>piggy back</em> 
client-side updates in the response.</p><h1 
id="JavaScriptRewrite-MaintainingBackwardsCompatibility">Maintaining Backwards 
Compatibility</h1><p>Backwards compatibility is the greatest challenge here; 
ideally, applications (and third p
 arty libraries) that were written for Tapestry 5.3 will continue to operate 
unchanged in Tapestry 5.4.</p><p>At the same time, much of what Tapestry 5.3 
does on the client and server should be deprecated (and hopefully, 
simplified).</p><p>Compatibility mode will be initially enabled, via a <a 
shape="rect" href="symbols.html">symbol</a> value.</p><p>In compatibility mode, 
additional client-side JavaScript will be loaded to provide the same 
<code>T5</code> and <code>Tapestry</code> namespaces available in Tapestry 
5.3.</p><p>The implementations of these namespaces will be reconstructed in 
terms of the new module system. The loading of the compatibility layer will 
occur during full page render.</p><h1 
id="JavaScriptRewrite-TwitterBootstrap">Twitter Bootstrap</h1><p>In Tapestry 
5.3 and earlier, Tapestry automatically includes a default CSS link on all 
pages. This CSS file acts as a partial CSS reset (normalizing the look of the 
application across common browsers), and provides a large n
 umber of CSS rules that many Tapestry components expect to be present. The CSS 
rules are all given a "t-" (for Tapestry) prefix.</p><p>For Tapestry 5.4, this 
default CSS link will be changed to be the default <a shape="rect" 
class="external-link" href="http://twitter.github.com/bootstrap/"; >Twitter 
Bootstrap</a>. This will not only refresh the Tapestry look and feel, but will 
provide a better structure for customizing the application's look and 
feel.</p><p>As with today, it will be possible to override the location of this 
CSS file (for example, to use a newer version of Bootstrap than is packaged in 
the application, or an application-specific customized version).</p><p>This 
will entail some changes to some components, to make use of reasonable or 
equivalent Bootstrap CSS classes, rather than the Tapestry 5.3 
classes.</p><p>Twitter Bootstrap also includes a number of jQuery-based 
plugins; these will be exposed in the module system.</p><h1 
id="JavaScriptRewrite-ContentDeliveryNetwork
 Integration">Content Delivery Network Integration</h1><p>Tapestry 5.3 has 
limited ability to integrate into a <a shape="rect" class="external-link" 
href="http://en.wikipedia.org/wiki/Content_delivery_network"; >content delivery 
network</a>; it can dynamically rewrite URLs for assets (including JavaScript 
libraries, CSS files, image files, etc.). However, it assumes that the CDN can 
"pull" the content, as needed, from the live site.</p><p>A desirable feature 
would be request URL that would produce a JSON-formatted report of all assets 
that should be mirrored by the CDN: this would include all files that might be 
exposed to the browser, including virtual assets (such as JavaScript stacks, 
aggregated modules, and so forth). This could be leveraged by a tool that would 
use this information to extract the assets from the live application and 
exported to the CDN.</p><p>Determining what assets are available is somewhat 
problematic as Tapestry mixes server-side only resources (.class files, 
 .tml files, etc.) freely with assets that might be exposed to the browser. 
(This should never have been the case, but that's hindsight.) Some of those 
server-side resource may expose details, such as other server hosts and 
potentially user names and passwords, that should never be exposed to the 
client.</p><p>In addition, a "walk" of the classpath to locate potential 
exportable assets can be quite expensive (though not considerably more so than 
what Tapestry already does at startup to identify page and component 
classes).</p><h1 id="JavaScriptRewrite-ExtJSCompatibility">ExtJS 
Compatibility</h1><p>To be determined. ExtJS inlcudes it own system for 
dynamically loading ExtJS modules, as well as expressing dependencies between 
them. Its capabilities overlap what RequireJS offers. It would be nice if, in 
an ExtJS application, the ExtJS loader could be used instead of RequireJS, or 
at least, ensure that they do not interfere with each other.</p><h1 
id="JavaScriptRewrite-MoreThoughts">More
  Thoughts</h1><p>This is a big undertaking; this document is not a contract, 
and is certainly not complete, but is only starting point for discussions about 
what will be forthcoming in Tapestry 5.4.</p></div>
 </div>
 
 <div class="clearer"></div>

Modified: websites/production/tapestry/content/javascript.html
==============================================================================
--- websites/production/tapestry/content/javascript.html (original)
+++ websites/production/tapestry/content/javascript.html Mon Feb 16 23:20:21 
2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     JavaScript -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/jmx-module.html
==============================================================================
--- websites/production/tapestry/content/jmx-module.html (original)
+++ websites/production/tapestry/content/jmx-module.html Mon Feb 16 23:20:21 
2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     JMX Module -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/json.html
==============================================================================
--- websites/production/tapestry/content/json.html (original)
+++ websites/production/tapestry/content/json.html Mon Feb 16 23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     JSON -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/key-features.html
==============================================================================
--- websites/production/tapestry/content/key-features.html (original)
+++ websites/production/tapestry/content/key-features.html Mon Feb 16 23:20:21 
2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Key Features -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/layout-component.html
==============================================================================
--- websites/production/tapestry/content/layout-component.html (original)
+++ websites/production/tapestry/content/layout-component.html Mon Feb 16 
23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Layout Component -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/legacy-javascript.html
==============================================================================
--- websites/production/tapestry/content/legacy-javascript.html (original)
+++ websites/production/tapestry/content/legacy-javascript.html Mon Feb 16 
23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Legacy JavaScript -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/limitations.html
==============================================================================
--- websites/production/tapestry/content/limitations.html (original)
+++ websites/production/tapestry/content/limitations.html Mon Feb 16 23:20:21 
2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Limitations -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/link-components-faq.html
==============================================================================
--- websites/production/tapestry/content/link-components-faq.html (original)
+++ websites/production/tapestry/content/link-components-faq.html Mon Feb 16 
23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Link Components FAQ -- Apache Tapestry
   </title>

Modified: 
websites/production/tapestry/content/loading-the-project-into-eclipse.html
==============================================================================
--- websites/production/tapestry/content/loading-the-project-into-eclipse.html 
(original)
+++ websites/production/tapestry/content/loading-the-project-into-eclipse.html 
Mon Feb 16 23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Loading the Project Into Eclipse -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/localization.html
==============================================================================
--- websites/production/tapestry/content/localization.html (original)
+++ websites/production/tapestry/content/localization.html Mon Feb 16 23:20:21 
2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Localization -- Apache Tapestry
   </title>
@@ -91,7 +92,7 @@
                     <span class="icon icon-page" title="Page">Page:</span>     
       </div>
 
             <div class="details">
-                            <a shape="rect" 
href="component-parameters.html">Component Parameters</a>
+                            <a shape="rect" 
href="localization.html">Localization</a>
                     
                 
                             </div>
@@ -100,7 +101,7 @@
                     <span class="icon icon-page" title="Page">Page:</span>     
       </div>
 
             <div class="details">
-                            <a shape="rect" 
href="localization.html">Localization</a>
+                            <a shape="rect" 
href="component-parameters.html">Component Parameters</a>
                     
                 
                             </div>

Modified: websites/production/tapestry/content/logging-in-tapestry.html
==============================================================================
--- websites/production/tapestry/content/logging-in-tapestry.html (original)
+++ websites/production/tapestry/content/logging-in-tapestry.html Mon Feb 16 
23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Logging in Tapestry -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/logging.html
==============================================================================
--- websites/production/tapestry/content/logging.html (original)
+++ websites/production/tapestry/content/logging.html Mon Feb 16 23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Logging -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/mailing-lists.html
==============================================================================
--- websites/production/tapestry/content/mailing-lists.html (original)
+++ websites/production/tapestry/content/mailing-lists.html Mon Feb 16 23:20:21 
2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Mailing Lists -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/maven-support-faq.html
==============================================================================
--- websites/production/tapestry/content/maven-support-faq.html (original)
+++ websites/production/tapestry/content/maven-support-faq.html Mon Feb 16 
23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Maven Support FAQ -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/menuleft.html
==============================================================================
--- websites/production/tapestry/content/menuleft.html (original)
+++ websites/production/tapestry/content/menuleft.html Mon Feb 16 23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     menuleft -- Apache Tapestry
   </title>

Modified: 
websites/production/tapestry/content/meta-programming-page-content.html
==============================================================================
--- websites/production/tapestry/content/meta-programming-page-content.html 
(original)
+++ websites/production/tapestry/content/meta-programming-page-content.html Mon 
Feb 16 23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Meta-Programming Page Content -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/modules.html
==============================================================================
--- websites/production/tapestry/content/modules.html (original)
+++ websites/production/tapestry/content/modules.html Mon Feb 16 23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Modules -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/navigation.html
==============================================================================
--- websites/production/tapestry/content/navigation.html (original)
+++ websites/production/tapestry/content/navigation.html Mon Feb 16 23:20:21 
2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Navigation -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/news.html
==============================================================================
--- websites/production/tapestry/content/news.html (original)
+++ websites/production/tapestry/content/news.html Mon Feb 16 23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     News -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/object-providers.html
==============================================================================
--- websites/production/tapestry/content/object-providers.html (original)
+++ websites/production/tapestry/content/object-providers.html Mon Feb 16 
23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Object Providers -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/operation-tracker.html
==============================================================================
--- websites/production/tapestry/content/operation-tracker.html (original)
+++ websites/production/tapestry/content/operation-tracker.html Mon Feb 16 
23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Operation Tracker -- Apache Tapestry
   </title>

Modified: websites/production/tapestry/content/ordering-by-constraints.html
==============================================================================
--- websites/production/tapestry/content/ordering-by-constraints.html (original)
+++ websites/production/tapestry/content/ordering-by-constraints.html Mon Feb 
16 23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Ordering by Constraints -- Apache Tapestry
   </title>

Modified: 
websites/production/tapestry/content/overriding-exception-reporting.html
==============================================================================
--- websites/production/tapestry/content/overriding-exception-reporting.html 
(original)
+++ websites/production/tapestry/content/overriding-exception-reporting.html 
Mon Feb 16 23:20:21 2015
@@ -21,6 +21,7 @@
 <head>
   <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
   <meta http-equiv="x-ua-compatible" content="IE=9">
+  <meta name="viewport" content="width=device-width, initial-scale=1"> 
   <title>
     Overriding Exception Reporting -- Apache Tapestry
   </title>
@@ -90,7 +91,7 @@ table.ScrollbarTable td.ScrollbarNextIco
                     <span class="icon icon-page" title="Page">Page:</span>     
       </div>
 
             <div class="details">
-                            <a shape="rect" 
href="error-page-recipe.html">Error Page Recipe</a>
+                            <a shape="rect" 
href="overriding-exception-reporting.html">Overriding Exception Reporting</a>
                     
                 
                             </div>
@@ -99,7 +100,7 @@ table.ScrollbarTable td.ScrollbarNextIco
                     <span class="icon icon-page" title="Page">Page:</span>     
       </div>
 
             <div class="details">
-                            <a shape="rect" 
href="overriding-exception-reporting.html">Overriding Exception Reporting</a>
+                            <a shape="rect" 
href="error-page-recipe.html">Error Page Recipe</a>
                     
                 
                             </div>


Reply via email to