Modified: websites/production/tapestry/content/javascript-rewrite-in-54.html
==============================================================================
--- websites/production/tapestry/content/javascript-rewrite-in-54.html 
(original)
+++ websites/production/tapestry/content/javascript-rewrite-in-54.html Mon Feb 
19 20:20:17 2018
@@ -67,22 +67,22 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p><style 
type="text/css">/*<![CDATA[*/
-div.rbtoc1518405665745 {padding: 0px;}
-div.rbtoc1518405665745 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1518405665745 li {margin-left: 0px;padding-left: 0px;}
+                <div id="ConfluenceContent"><div 
class="confluence-information-macro 
confluence-information-macro-information"><span class="aui-icon aui-icon-small 
aui-iconfont-info confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>This is a historical document in 
which Tapestry's Howard Lewis Ship describes the motivations and plan for 
significantly changing Tapestry's client-side functionality starting in 
Tapestry 5.4. This plan closely matches the actual results delivered in 
Tapestry 5.4, but this document is mostly kept for historical 
reference.</p></div></div><h2 
id="JavaScriptRewritein5.4-Contents">Contents</h2><p><style 
type="text/css">/*<![CDATA[*/
+div.rbtoc1519071582821 {padding: 0px;}
+div.rbtoc1519071582821 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1519071582821 li {margin-left: 0px;padding-left: 0px;}
 
-/*]]>*/</style></p><div class="toc-macro rbtoc1518405665745">
+/*]]>*/</style></p><div class="toc-macro rbtoc1519071582821">
 <ul class="toc-indentation"><li><a  
href="#JavaScriptRewritein5.4-TapestryandJavaScript">Tapestry and 
JavaScript</a></li><li><a  
href="#JavaScriptRewritein5.4-TapestryJavaScriptLimitations(through5.3)">Tapestry
 JavaScript Limitations (through 5.3)</a>
 <ul class="toc-indentation"><li><a  
href="#JavaScriptRewritein5.4-DependenceonPrototype/Scriptaculous">Dependence 
on Prototype/Scriptaculous</a></li><li><a  
href="#JavaScriptRewritein5.4-LackofDocumentation">Lack of 
Documentation</a></li><li><a  
href="#JavaScriptRewritein5.4-LackofModuleStructure">Lack of Module 
Structure</a></li><li><a  
href="#JavaScriptRewritein5.4-ComplexInitialization">Complex 
Initialization</a></li></ul>
 </li><li><a  
href="#JavaScriptRewritein5.4-JavaScriptImprovementsfor5.4">JavaScript 
Improvements for 5.4</a>
 <ul class="toc-indentation"><li><a  
href="#JavaScriptRewritein5.4-RequireJS">RequireJS</a></li><li><a  
href="#JavaScriptRewritein5.4-SlowPageLoadandInitialization">Slow Page Load and 
Initialization</a></li><li><a  
href="#JavaScriptRewritein5.4-MappingModulestoAssets">Mapping Modules to 
Assets</a></li><li><a  
href="#JavaScriptRewritein5.4-ExtensionstoJavaScriptSupport">Extensions to 
JavaScriptSupport</a></li><li><a  
href="#JavaScriptRewritein5.4-AvoidingJavaScriptClasses">Avoiding JavaScript 
Classes</a></li><li><a  
href="#JavaScriptRewritein5.4-ExposeGlobalMessageCatalogtoClient">Expose Global 
Message Catalog to Client</a></li><li><a  
href="#JavaScriptRewritein5.4-PartialPageUpdateResponse">Partial Page Update 
Response</a></li></ul>
 </li><li><a  
href="#JavaScriptRewritein5.4-MaintainingBackwardsCompatibility">Maintaining 
Backwards Compatibility</a></li><li><a  
href="#JavaScriptRewritein5.4-TwitterBootstrap">Twitter 
Bootstrap</a></li><li><a  
href="#JavaScriptRewritein5.4-ContentDeliveryNetworkIntegration">Content 
Delivery Network Integration</a></li><li><a  
href="#JavaScriptRewritein5.4-ExtJSCompatibility">ExtJS 
Compatibility</a></li><li><a  href="#JavaScriptRewritein5.4-MoreThoughts">More 
Thoughts</a></li></ul>
-</div><h1 id="JavaScriptRewritein5.4-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 in
 side 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  class="external-link" 
href="http://en.wikipedia.org/wiki/Uncanny_valley"; rel="nofollow">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="JavaScriptRewritein5.4-TapestryJavaScriptLimitations(through5.3)">Tapestry 
JavaScript Limitations (through 5.3)</h1><h2 
id="JavaScriptRewritein5.4-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 w
 ould 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="JavaScriptRewritein5.4-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="JavaScriptRewritein5.4-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>) namespac
 e, and the mechanics of full-page and partial-page renders (described more 
fully below).</p><h2 id="JavaScriptRewritein5.4-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  
class="external-link" href="http://en.wikipedia.org/wiki/Monkey_patching"; 
rel="nofollow">monkey patched</a> into the T5.initializers (or older 
Tapestry.Initializers) namespace.</li><li>The <a  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 nam
 e, 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. (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 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="JavaScriptRewritein5.4-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-sid
 e "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="JavaScriptRewritein5.4-RequireJS">RequireJS</h2><p>Rather than reinvent the 
wheel, Tapestry should incorporate a proper JavaScript module loader; <a  
class="external-link" href="http://requirejs.org/"; rel="nofollow">RequireJS</a> 
is an excellent candidate, especially considering the new features provided in 
its 2.0.1 release.</p><p>RequireJS supports the <a  class="external-link" 
href="https://github.com/amdjs/amdjs-api/wiki/AMD"; rel="nofollow">AMD (Asynchro
 nous Module Format)</a>, with some additional support for the <a  
class="external-link" href="http://www.commonjs.org/"; 
rel="nofollow">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 detai
 ls of where each module is stored is quite variable.</p><h2 
id="JavaScriptRewritein5.4-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  
class="external-link" href="http:
 //api.prototypejs.org/dom/document/observe/" rel="nofollow">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><p>Tapestry 5.4 uses JavaScript to add a "page 
loading mask", which is removed once all JavaScript has initialized. Using CSS 
animation tricks, the mask becomes visible after a fraction of a second, and 
includes a spinning icon. The page loading mask prevents any interaction by the 
user on the incompletely initialized page.</p><h2 
id="JavaScriptRewritein5.4-MappingModulestoAssets">Mapping Modules to 
Assets</h2><p>Under RequireJS, modules are ide
 ntified 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 overridden (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>Modu
 le 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 
 class="external-link" href="http://requirejs.org/docs/commonjs.html"; 
rel="nofollow">wrap CommonJS modules as AMD modules</a>. (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.)</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 req
 uire 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  class="external-link" href="http://documentcloud.github.com/underscore/"; 
rel="nofollow">Underscore</a> may be mapped at the root level, as they are used 
so often.</p><h2 
id="JavaScriptRewritein5.4-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 m
 odule functions may be limited to String and <a  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="JavaScriptRewritein5.4-AvoidingJavaScriptClasses"><span>Avoiding JavaScript 
Classes</span></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  class="external-link" href="ht
 tp://api.prototypejs.org/language/Class/" rel="nofollow">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="JavaScriptRewritein5.4-ExposeGlobalMessageCatalogtoClient">Expose Global 
Message Catalog to Client</h2><p>Tape
 stry currently maintains two global message catalogs; a global server-side 
catalog (usually named <code>WEB-INF/app.properties)
+</div><h1 id="JavaScriptRewritein5.4-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 in
 side 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  class="external-link" 
href="http://en.wikipedia.org/wiki/Uncanny_valley"; rel="nofollow">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="JavaScriptRewritein5.4-TapestryJavaScriptLimitations(through5.3)">Tapestry 
JavaScript Limitations (through 5.3)</h1><h2 
id="JavaScriptRewritein5.4-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 w
 ould 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="JavaScriptRewritein5.4-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="JavaScriptRewritein5.4-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>) namespac
 e, and the mechanics of full-page and partial-page renders (described more 
fully below).</p><h2 id="JavaScriptRewritein5.4-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  
class="external-link" href="http://en.wikipedia.org/wiki/Monkey_patching"; 
rel="nofollow">monkey patched</a> into the T5.initializers (or older 
Tapestry.Initializers) namespace.</li><li>The <a  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 nam
 e, 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. (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 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="JavaScriptRewritein5.4-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-sid
 e "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="JavaScriptRewritein5.4-RequireJS">RequireJS</h2><p>Rather than reinvent the 
wheel, Tapestry should incorporate a proper JavaScript module loader; <a  
class="external-link" href="http://requirejs.org/"; rel="nofollow">RequireJS</a> 
is an excellent candidate, especially considering the new features provided in 
its 2.0.1 release.</p><p>RequireJS supports the <a  class="external-link" 
href="https://github.com/amdjs/amdjs-api/wiki/AMD"; rel="nofollow">AMD (Asynchro
 nous Module Format)</a>, with some additional support for the <a  
class="external-link" href="http://www.commonjs.org/"; 
rel="nofollow">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 detai
 ls of where each module is stored is quite variable.</p><h2 
id="JavaScriptRewritein5.4-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  
class="external-link" href="http:
 //api.prototypejs.org/dom/document/observe/" rel="nofollow">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><p>Tapestry 5.4 uses JavaScript to add a "page 
loading mask", which is removed once all JavaScript has initialized. Using CSS 
animation tricks, the mask becomes visible after a fraction of a second, and 
includes a spinning icon. The page loading mask prevents any interaction by the 
user on the incompletely initialized page.</p><h2 
id="JavaScriptRewritein5.4-MappingModulestoAssets">Mapping Modules to 
Assets</h2><p>Under RequireJS, modules are ide
 ntified 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 overridden (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>Modu
 le 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 
 class="external-link" href="http://requirejs.org/docs/commonjs.html"; 
rel="nofollow">wrap CommonJS modules as AMD modules</a>. (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.)</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 req
 uire 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  class="external-link" href="http://underscorejs.org/"; 
rel="nofollow">Underscore</a> may be mapped at the root level, as they are used 
so often.</p><h2 
id="JavaScriptRewritein5.4-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  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="JavaScriptRewritein5.4-AvoidingJavaScriptClasses"><span>Avoiding JavaScript 
Classes</span></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  class="external-link" href="http://api.prototypej
 s.org/language/Class/" rel="nofollow">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="JavaScriptRewritein5.4-ExposeGlobalMessageCatalogtoClient">Expose Global 
Message Catalog to Client</h2><p>Tapestry currently main
 tains 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="JavaScriptRewritein5.4-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 re
 quest 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 hav
 e 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 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  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/Initi
 alizationPriority.html#IMMEDIATE">IMMEDIATE</a> may occur before DOM 
changes</li><li>Module requirement/invocation will occur in <a  
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 s
 tep. 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="JavaScriptRewritein5.4-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  
href="javascript-rewrite-in-54.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 term
 s of the new module system. The loading of the compatibility layer will occur 
during full page render.</p><h1 
id="JavaScriptRewritein5.4-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  class="external-link" 
href="http://twitter.github.com/bootstrap/"; rel="nofollow">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 tha
 n 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="JavaScriptRewritein5.4-ContentDeliveryNetworkIntegration">Content Delivery 
Network Integration</h1><p>Tapestry 5.3 has limited ability to integrate into a 
<a  class="external-link" 
href="http://en.wikipedia.org/wiki/Content_delivery_network"; 
rel="nofollow">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 
woul
 d 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="JavaScriptRewritein5.4-ExtJSCompatibility">Ex
 tJS 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="JavaScriptRewritein5.4-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>
+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="JavaScriptRewritein5.4-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 re
 quest 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 hav
 e 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 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  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/Initi
 alizationPriority.html#IMMEDIATE">IMMEDIATE</a> may occur before DOM 
changes</li><li>Module requirement/invocation will occur in <a  
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 s
 tep. 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="JavaScriptRewritein5.4-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  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 modu
 le system. The loading of the compatibility layer will occur during full page 
render.</p><h1 id="JavaScriptRewritein5.4-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  
class="external-link" href="http://getbootstrap.com/"; rel="nofollow">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 applicat
 ion, 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="JavaScriptRewritein5.4-ContentDeliveryNetworkIntegration">Content Delivery 
Network Integration</h1><p>Tapestry 5.3 has limited ability to integrate into a 
<a  class="external-link" 
href="http://en.wikipedia.org/wiki/Content_delivery_network"; 
rel="nofollow">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 migh
 t 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="JavaScriptRewritein5.4-ExtJSCompatibility">ExtJS 
Compatibility</h1><p>To b
 e 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="JavaScriptRewritein5.4-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/release-notes-537.html
==============================================================================
--- websites/production/tapestry/content/release-notes-537.html (original)
+++ websites/production/tapestry/content/release-notes-537.html Mon Feb 19 
20:20:17 2018
@@ -77,7 +77,7 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p>This is the consolidated list 
of changes between Tapestry versions 5.3.6 and 5.3.7. Tapestry 5.3.7 is a 
drop-in replacement for prior Tapestry 5.3 releases. To upgrade, just update 
the Maven dependency in your POM file (or <a  
href="release-notes-537.html">download</a> the new JAR file) and the new 
version will just work. However, please review the <a  
href="release-notes-537.html">Release Notes 5.3.7</a> instructions before 
upgrading.</p><p>This is a bug fix release, mainly focused on three 
aspects:</p><ul><li>make Tapestry work better under Tomcat</li><li>minimize the 
possibility of clash for generated ids</li><li>let the BeanEditor be more 
JSR-303 friendly</li></ul><p>Some work has been made on the form component 
too.</p><p>As with any Tapestry upgrade, be sure to change your <a  
href="release-notes-537.html">application's version number</a>.</p><p>&#160;    
            
+                <div id="ConfluenceContent"><p>This is the consolidated list 
of changes between Tapestry versions 5.3.6 and 5.3.7. Tapestry 5.3.7 is a 
drop-in replacement for prior Tapestry 5.3 releases. To upgrade, just update 
the Maven dependency in your POM file (or <a  
href="release-notes-537.html">download</a> the new JAR file) and the new 
version will just work. However, please review the&#160;<a  
href="how-to-upgrade.html">How to Upgrade</a> instructions before 
upgrading.</p><p>This is a bug fix release, mainly focused on three 
aspects:</p><ul><li>make Tapestry work better under Tomcat</li><li>minimize the 
possibility of clash for generated ids</li><li>let the BeanEditor be more 
JSR-303 friendly</li></ul><p>Some work has been made on the form component 
too.</p><p>As with any Tapestry upgrade, be sure to change your <a  
href="configuration.html">application's version number</a>.</p><p>&#160;        
        
 </p><h2>        Bug Fixed
 </h2>
 <ul><li>[<a  
href="https://issues.apache.org/jira/browse/TAP5-1010";>TAP5-1010</a>] -         
Fix Finnish validation message translation - corrected file attached

Modified: websites/production/tapestry/content/release-notes-538.html
==============================================================================
--- websites/production/tapestry/content/release-notes-538.html (original)
+++ websites/production/tapestry/content/release-notes-538.html Mon Feb 19 
20:20:17 2018
@@ -30,7 +30,7 @@
           <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>
       SyntaxHighlighter.defaults['toolbar'] = false;
       SyntaxHighlighter.all();
@@ -75,20 +75,20 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p>Tapestry 5.3.8 is a drop-in 
replacement for prior Tapestry 5.3 releases. To upgrade, just update the 
dependency in your build configuration (Maven POM, Gradle build script, etc.) 
&#8211; or&#160;<a  href="release-notes-538.html">Release Notes 5.3.8</a> the 
new JAR file -- and the new version will just work. However, please review 
the&#160;<a  href="release-notes-538.html">Release Notes 5.3.8</a> instructions 
before upgrading.</p><p>This is a bug fix release, mainly meant to address 
compatibility with Java 8. The ASM library is updated to a Java 8 compatible 
version (5.0), however, if you wish to run this release on JRE 8, you still 
need to manually specify a Java 8 compatible version of javassist (such as 
3.18.2-GA). With Maven you'd include:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">&lt;dependency&gt;
+                <div id="ConfluenceContent"><p 
class="confluence-link">Tapestry 5.3.8 is a drop-in replacement for prior 
Tapestry 5.3 releases. To upgrade, just update the dependency in your build 
configuration (Maven POM, Gradle build script, etc.) &#8211; or <a  
href="download.html">Download</a> the new JAR file -- and the new version will 
just work. However, please review the&#160;<a  href="how-to-upgrade.html">How 
to Upgrade</a> instructions before upgrading.</p><p>This is a bug fix release, 
mainly meant to address compatibility with Java 8. The ASM library is updated 
to a Java 8 compatible version (5.0), however, if you wish to run this release 
on JRE 8, you still need to manually specify a Java 8 compatible version of 
javassist (such as 3.18.2-GA). With Maven you'd include:</p><div class="code 
panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>pom.xml (partial)</b></div><div 
class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;dependency&gt;
   &lt;groupId&gt;org.javassist&lt;/groupId&gt;
   &lt;artifactId&gt;javassist&lt;/artifactId&gt;
   &lt;version&gt;3.18.2-GA&lt;/version&gt;
 &lt;/dependency&gt;</pre>
-</div></div><p>Javassist has changed their group coordinates (from javassist 
to org.javassist), which further complicates the situation. You'll also have to 
manually exclude javassist:javassist dependency (if your dependencies are 
resolved automatically). With Maven, you'd add:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">&lt;exclusions&gt;
+</div></div><p>Javassist has changed their group coordinates (from javassist 
to org.javassist), which further complicates the situation. You'll also have to 
manually exclude javassist:javassist dependency (if your dependencies are 
resolved automatically). With Maven, you'd add:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>pom.xml (partial)</b></div><div 
class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;exclusions&gt;
   &lt;exclusion&gt;
     &lt;artifactId&gt;javassist&lt;/artifactId&gt;
     &lt;groupId&gt;javassist&lt;/groupId&gt;
   &lt;/exclusion&gt;
 &lt;/exclusions&gt;</pre>
-</div></div><p>where needed.</p><p>As with any Tapestry upgrade, be sure to 
change your&#160;<a  href="release-notes-538.html">application's version 
number</a>.</p><p>&#160;</p>             
+</div></div><p>where needed.</p><p>As with any Tapestry upgrade, be sure to 
change your&#160;<a  href="configuration.html">application's version 
number</a>.</p><p>&#160;</p>             
 <h2>        Bugs fixed
 </h2>
 <ul><li>[<a  
href="https://issues.apache.org/jira/browse/TAP5-311";>TAP5-311</a>] -         
NPE in BeanDisplay if used in a form with a default model

Modified: websites/production/tapestry/content/release-notes-54.html
==============================================================================
--- websites/production/tapestry/content/release-notes-54.html (original)
+++ websites/production/tapestry/content/release-notes-54.html Mon Feb 19 
20:20:17 2018
@@ -77,7 +77,7 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p>This is the consolidated list 
of changes between Tapestry versions 5.3 and 5.4. To upgrade to 5.4, most users 
who are not using deprecated features will be able to just update the 
dependency version in their Maven POM file or Gradle build script (or <a  
href="release-notes-54.html">download</a> the new JAR files) and the new 
version will just work, although the introduction of Bootstrap CSS will require 
some styling adjustments for most applications not already using Bootstrap. 
Please read carefully below before upgrading, and also review the <a  
href="release-notes-54.html">Release Notes 5.4</a> instructions.</p><h2 
id="ReleaseNotes5.4-IncompatibleAPIs">Incompatible APIs</h2><h3 
id="ReleaseNotes5.4-JavaScriptSupport">JavaScriptSupport</h3><p>Some existing 
methods of JavaScriptSupport were changed from returning void, to returning the 
JavaScriptSupport instance, to allow for chaining of calls. This interface is 
consumed by end-user code
 , but not generally implemented by end-user code.</p><h2 
id="ReleaseNotes5.4-BreakingFeatures">Breaking Features</h2><h3 
id="ReleaseNotes5.4-ClassFactoryRemoved">ClassFactory Removed</h3><p>Tapestry's 
use of the <a  class="external-link" 
href="http://www.csg.is.titech.ac.jp/~chiba/javassist/"; 
rel="nofollow">Javassist</a> bytecode library has been completely removed, 
along with many related services, such as <a  class="external-link" 
href="http://tapestry.apache.org/5.3/apidocs/org/apache/tapestry5/ioc/services/ClassFactory.html";>ClassFactory</a>,
 that were deprecated in 5.3. Use <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/PlasticProxyFactory.html";>PlasticProxyFactory</a>
 instead. Most users will not be affected by this unless they relied on 
Tapestry's dependency on Javassist.</p><h3 
id="ReleaseNotes5.4-ClientBehaviorSupportFunctionalityRemoved">ClientBehaviorSupport
 Functionality Removed</h3><p>This service collected d
 etails about zone usage, including the client-side behavior associated with 
<code>FormFragment</code>s. This interface is only kept for binary 
compatibility in Tapestry 5.4; the implementation no longer does anything but 
throw exceptions and will be removed in 5.5 or later.</p><h3 
id="ReleaseNotes5.4-FormInjectorRemoved">FormInjector Removed</h3><p>The 
FormInjector component was removed; it was intended for use only inside the 
AjaxFormLoop component (which was rewritten in 5.4 and no longer uses 
FormInjector). FormInjector was not widely used elsewhere, if it was used at 
all.</p><h3 
id="ReleaseNotes5.4-MarkupWriterFactoryAPIChanged">MarkupWriterFactory API 
Changed</h3><p>The <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/MarkupWriterFactory.html";>MarkupWriterFactory</a>
 interface has 3 new methods, added to support the HTML5 rules for element 
endings. If you have any classes that <em>implement</em> MarkupWriterFactory 
(which 
 is rare), they'll need to be modified to implement the new methods. As noted 
in the <a  class="external-link" 
href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/services/ClientBehaviorSupport.html";>Javadocs</a>,
 use JavaScriptSupport directly instead.</p><h3 
id="ReleaseNotes5.4-InjectedScriptsatBottom">Injected Scripts at 
Bottom</h3><p>In prior versions of Tapestry, JavaScript libraries injected into 
the page (via the @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Import.html";>Import</a>
 annotation, or via <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html";>JavaScriptSupport</a>),
 were injected into the &lt;head&gt; element of the HTML page, either at the 
end of the element, or before any existing &lt;script&gt; element.</p><p>With 
this release, the Tapestry integrates with <a  class="external-link" 
href="http://requirej
 s.org/" rel="nofollow">RequireJS</a> to dynamically load libraries. This may 
affect a small number of JavaScript libraries, such as <a  
class="external-link" href="http://www.google.com/analytics/"; 
rel="nofollow">Google Analytics</a> that need to be placed at the top of the 
page; in those cases, the library should be added to the template of your 
application's main layout component, instead of relying on @Import and 
JavaScriptSupport.</p><h3 
id="ReleaseNotes5.4-NoRedirectOnFormValidationErrors">No Redirect On Form 
Validation Errors</h3><p>In prior releases of Tapestry, when a client-side form 
was submitted and there were server-side validation errors, Tapestry would 
perform a redirect-after-post to re-render the page; this meant that the <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ValidationTracker.html";>ValidationTracker</a>
 object that stores validation errors would, itself, need to persist to the new 
render request, causing a se
 rver-side session to be created. Starting in 5.4, the default behavior for 
server-side validation exceptions is to re-render the page content immediately, 
within the same request; this obviates the need to use a persistent field to 
store the tracker.</p><h2 id="ReleaseNotes5.4-NewFeatures">New Features</h2><h3 
id="ReleaseNotes5.4-Componentfieldvisibility">Component field 
visibility</h3><p>In prior versions of Tapestry, all instance fields of 
components had to be visibility private; starting with versions 5.3.2 and 5.4, 
this has been relaxed. Component fields may be protected, or package private 
(that is, no visibility modifier). Fields that are final, or annotated with @<a 
 class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Retain.html";>Retain</a>
 may even be public. In any case, this makes it easier for pages to work with 
other pages in the same package, and for subclasses to more easily access the 
fields (including parameter fie
 lds, or injections) provided by base classes. This feature should be used with 
care, as it can lead to designs that are more difficult to maintain.</p><h3 
id="ReleaseNotes5.4-JavaScriptModules">JavaScript Modules</h3><p>Prior releases 
of Tapestry primarily organized client-side logic in terms of JavaScript 
libraries. These libraries can be declaratively imported into the page (either 
during a full-page render, or during an Ajax partial page update). In addition, 
libraries can be combined together into <em>stacks</em>, which (in a production 
application) are combined into a single virtual asset.</p><p>The library 
approach is <a  href="release-notes-54.html">fundamentally limited in a number 
of ways</a>, including namespace pollution and dealing with dependencies 
between libraries. Tapestry 5.4 introduces a parallel mechanism, based on <a  
class="external-link" href="http://requirejs.org"; rel="nofollow">RequireJS</a> 
and the <a  class="external-link" href="https://github.com/amdjs/amd
 js-api/wiki/AMD" rel="nofollow">Asynchronous Module Definition</a> as a way to 
speed up initial page load and organize client-side JavaScript in a more 
expressive and maintainable way.</p><h3 
id="ReleaseNotes5.4-Client-sideAPIforinvokingserver-sideevents">Client-side API 
for invoking server-side events</h3><p>Tapestry 5.4.2 adds an API which makes 
it easy for server-side events to be invoked from JavaScript. In the 
server-side, you first need to annotate the event handler methods you want 
exposed with the new&#160;<code>@PublishEvent</code> annotation. Then, in JS, 
all you need to do is to call the&#160;<code>t5/core/ajax</code>&#160;function 
with the server-side event name/type in the <code>url</code> parameter 
and&#160;with an&#160;<code>options</code> parameter containing 
an&#160;<code>element</code> property, be it null or specifying an DOM element 
to be used as the starting point for finding the event information. More 
details in the&#160;<a  class="external-link" href="http://
 tapestry.apache.org/ajax-and-zones.html">Ajax and Zones page</a>.</p><h2>      
  Sub-task
+                <div id="ConfluenceContent"><p>This is the consolidated list 
of changes between Tapestry versions 5.3 and 5.4. To upgrade to 5.4, most users 
who are not using deprecated features will be able to just update the 
dependency version in their Maven POM file or Gradle build script (or <a  
href="download.html">download</a> the new JAR files) and the new version will 
just work, although the introduction of Bootstrap CSS will require some styling 
adjustments for most applications not already using Bootstrap. Please read 
carefully below before upgrading, and also review the&#160;<a  
href="how-to-upgrade.html">How to Upgrade</a> instructions.</p><h2 
id="ReleaseNotes5.4-IncompatibleAPIs">Incompatible APIs</h2><h3 
id="ReleaseNotes5.4-JavaScriptSupport">JavaScriptSupport</h3><p>Some existing 
methods of JavaScriptSupport were changed from returning void, to returning the 
JavaScriptSupport instance, to allow for chaining of calls. This interface is 
consumed by end-user code, but no
 t generally implemented by end-user code.</p><h2 
id="ReleaseNotes5.4-BreakingFeatures">Breaking Features</h2><h3 
id="ReleaseNotes5.4-ClassFactoryRemoved">ClassFactory Removed</h3><p>Tapestry's 
use of the <a  class="external-link" 
href="http://www.csg.is.titech.ac.jp/~chiba/javassist/"; 
rel="nofollow">Javassist</a> bytecode library has been completely removed, 
along with many related services, such as <a  class="external-link" 
href="http://tapestry.apache.org/5.3/apidocs/org/apache/tapestry5/ioc/services/ClassFactory.html";>ClassFactory</a>,
 that were deprecated in 5.3. Use <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/PlasticProxyFactory.html";>PlasticProxyFactory</a>
 instead. Most users will not be affected by this unless they relied on 
Tapestry's dependency on Javassist.</p><h3 
id="ReleaseNotes5.4-ClientBehaviorSupportFunctionalityRemoved">ClientBehaviorSupport
 Functionality Removed</h3><p>This service collected details a
 bout zone usage, including the client-side behavior associated with 
<code>FormFragment</code>s. This interface is only kept for binary 
compatibility in Tapestry 5.4; the implementation no longer does anything but 
throw exceptions and will be removed in 5.5 or later.</p><h3 
id="ReleaseNotes5.4-FormInjectorRemoved">FormInjector Removed</h3><p>The 
FormInjector component was removed; it was intended for use only inside the 
AjaxFormLoop component (which was rewritten in 5.4 and no longer uses 
FormInjector). FormInjector was not widely used elsewhere, if it was used at 
all.</p><h3 
id="ReleaseNotes5.4-MarkupWriterFactoryAPIChanged">MarkupWriterFactory API 
Changed</h3><p>The <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/MarkupWriterFactory.html";>MarkupWriterFactory</a>
 interface has 3 new methods, added to support the HTML5 rules for element 
endings. If you have any classes that <em>implement</em> MarkupWriterFactory 
(which is rare)
 , they'll need to be modified to implement the new methods. As noted in the <a 
 class="external-link" 
href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/services/ClientBehaviorSupport.html";>Javadocs</a>,
 use JavaScriptSupport directly instead.</p><h3 
id="ReleaseNotes5.4-InjectedScriptsatBottom">Injected Scripts at 
Bottom</h3><p>In prior versions of Tapestry, JavaScript libraries injected into 
the page (via the @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Import.html";>Import</a>
 annotation, or via <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html";>JavaScriptSupport</a>),
 were injected into the &lt;head&gt; element of the HTML page, either at the 
end of the element, or before any existing &lt;script&gt; element.</p><p>With 
this release, the Tapestry integrates with <a  class="external-link" 
href="http://requirejs.org/"; 
 rel="nofollow">RequireJS</a> to dynamically load libraries. This may affect a 
small number of JavaScript libraries, such as <a  class="external-link" 
href="http://www.google.com/analytics/"; rel="nofollow">Google Analytics</a> 
that need to be placed at the top of the page; in those cases, the library 
should be added to the template of your application's main layout component, 
instead of relying on @Import and JavaScriptSupport.</p><h3 
id="ReleaseNotes5.4-NoRedirectOnFormValidationErrors">No Redirect On Form 
Validation Errors</h3><p>In prior releases of Tapestry, when a client-side form 
was submitted and there were server-side validation errors, Tapestry would 
perform a redirect-after-post to re-render the page; this meant that the <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ValidationTracker.html";>ValidationTracker</a>
 object that stores validation errors would, itself, need to persist to the new 
render request, causing a server-sid
 e session to be created. Starting in 5.4, the default behavior for server-side 
validation exceptions is to re-render the page content immediately, within the 
same request; this obviates the need to use a persistent field to store the 
tracker.</p><h2 id="ReleaseNotes5.4-NewFeatures">New Features</h2><h3 
id="ReleaseNotes5.4-Componentfieldvisibility">Component field 
visibility</h3><p>In prior versions of Tapestry, all instance fields of 
components had to be visibility private; starting with versions 5.3.2 and 5.4, 
this has been relaxed. Component fields may be protected, or package private 
(that is, no visibility modifier). Fields that are final, or annotated with @<a 
 class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Retain.html";>Retain</a>
 may even be public. In any case, this makes it easier for pages to work with 
other pages in the same package, and for subclasses to more easily access the 
fields (including parameter fields, or 
 injections) provided by base classes. This feature should be used with care, 
as it can lead to designs that are more difficult to maintain.</p><h3 
id="ReleaseNotes5.4-JavaScriptModules">JavaScript Modules</h3><p>Prior releases 
of Tapestry primarily organized client-side logic in terms of JavaScript 
libraries. These libraries can be declaratively imported into the page (either 
during a full-page render, or during an Ajax partial page update). In addition, 
libraries can be combined together into <em>stacks</em>, which (in a production 
application) are combined into a single virtual asset.</p><p>The library 
approach is <a  href="javascript-rewrite-in-54.html">fundamentally limited in a 
number of ways</a>, including namespace pollution and dealing with dependencies 
between libraries. Tapestry 5.4 introduces a parallel mechanism, based on <a  
class="external-link" href="http://requirejs.org"; rel="nofollow">RequireJS</a> 
and the <a  class="external-link" href="https://github.com/amdjs/amd
 js-api/wiki/AMD" rel="nofollow">Asynchronous Module Definition</a> as a way to 
speed up initial page load and organize client-side JavaScript in a more 
expressive and maintainable way.</p><h3 
id="ReleaseNotes5.4-Client-sideAPIforinvokingserver-sideevents">Client-side API 
for invoking server-side events</h3><p>Tapestry 5.4.2 adds an API which makes 
it easy for server-side events to be invoked from JavaScript. In the 
server-side, you first need to annotate the event handler methods you want 
exposed with the new&#160;<code>@PublishEvent</code> annotation. Then, in JS, 
all you need to do is to call the&#160;<code>t5/core/ajax</code>&#160;function 
with the server-side event name/type in the <code>url</code> parameter 
and&#160;with an&#160;<code>options</code> parameter containing 
an&#160;<code>element</code> property, be it null or specifying an DOM element 
to be used as the starting point for finding the event information. More 
details in the&#160;<a  href="ajax-and-zones.html">Ajax and
  Zones page</a>.</p><h2>        Sub-task
 </h2>
 <ul><li>[<a  
href="https://issues.apache.org/jira/browse/TAP5-2445";>TAP5-2445</a>] -         
Reduce usage of PerthreadMap in AbstractConditional
 </li><li>[<a  
href="https://issues.apache.org/jira/browse/TAP5-2446";>TAP5-2446</a>] -         
Use ObjectCreator instead of PerThreadValue when appropriate

Modified: websites/production/tapestry/content/release-notes-542.html
==============================================================================
--- websites/production/tapestry/content/release-notes-542.html (original)
+++ websites/production/tapestry/content/release-notes-542.html Mon Feb 19 
20:20:17 2018
@@ -67,7 +67,7 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p>Tapestry 5.4.2 is a drop-in 
replacement for Tapestry 5.4 releases. To upgrade, just update the dependency 
in your build configuration (Maven POM, Gradle build script, etc.) &#8211; 
or&#160;<a  href="release-notes-542.html">Release Notes 5.4.2</a> the new JAR 
file -- and the new version will just work. However, please review the&#160;<a  
href="release-notes-542.html">Release Notes 5.4.2</a> instructions before 
upgrading.</p><p>&#160;</p>        Release Notes - Tapestry 5 - Version 5.4.2
+                <div id="ConfluenceContent"><p>Tapestry 5.4.2 is a drop-in 
replacement for Tapestry 5.4 releases. To upgrade, just update the dependency 
in your build configuration (Maven POM, Gradle build script, etc.) &#8211; 
or&#160;<a  href="download.html">Download</a> the new JAR file -- and the new 
version will just work. However, please review the&#160;<a  
href="how-to-upgrade.html">How to Upgrade</a> instructions before 
upgrading.</p><p>&#160;</p>        Release Notes - Tapestry 5 - Version 5.4.2
                                 
 <h2>        Bugs fixed
 </h2>

Modified: websites/production/tapestry/content/release-notes-543.html
==============================================================================
--- websites/production/tapestry/content/release-notes-543.html (original)
+++ websites/production/tapestry/content/release-notes-543.html Mon Feb 19 
20:20:17 2018
@@ -67,7 +67,7 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p>Tapestry 5.4.3 is a drop-in 
replacement for Tapestry 5.4 releases. To upgrade, just update the dependency 
in your build configuration (Maven POM, Gradle build script, etc.) &#8211; 
or&#160;<a  href="release-notes-543.html">Release Notes 5.4.3</a> the new JAR 
file -- and the new version will just work. However, please review the&#160;<a  
href="release-notes-543.html">Release Notes 5.4.3</a> instructions before 
upgrading.</p><p>&#160;</p>        Release Notes - Tapestry 5 - Version 5.4.3
+                <div id="ConfluenceContent"><p 
class="confluence-link">Tapestry 5.4.3 is a drop-in replacement for Tapestry 
5.4 releases. To upgrade, just update the dependency in your build 
configuration (Maven POM, Gradle build script, etc.) &#8211; or&#160;<a  
href="download.html">Download</a> the new JAR file -- and the new version will 
just work. However, please review the&#160;<a  href="how-to-upgrade.html">How 
to Upgrade</a> instructions before upgrading.</p><p>&#160;</p>        Release 
Notes - Tapestry 5 - Version 5.4.3
                                 
 <h2>        Bugs fixed
 </h2>


Reply via email to