You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by bu...@apache.org on 2017/09/16 02:22:41 UTC

svn commit: r1018228 [4/41] - in /websites/production/tapestry/content: ./ cache/

Modified: websites/production/tapestry/content/class-reloading.html
==============================================================================
--- websites/production/tapestry/content/class-reloading.html (original)
+++ websites/production/tapestry/content/class-reloading.html Sat Sep 16 02:22:40 2017
@@ -27,16 +27,6 @@
       </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>
-      SyntaxHighlighter.defaults['toolbar'] = false;
-      SyntaxHighlighter.all();
-    </script>
   
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -77,47 +67,13 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><h1 id="ClassReloading-LiveClassandTemplateReloading">Live Class and Template Reloading</h1><div class="aui-label" style="float:right" title="Related Articles">
-
-
-
-
-
-
-
-
-<h3>Related Articles</h3>
-
-<ul class="content-by-label"><li>
-        <div>
-                <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span>        </div>
-
-        <div class="details">
-                        <a  href="service-implementation-reloading.html">Service Implementation Reloading</a>
-                
-                        
-                    </div>
-    </li><li>
-        <div>
-                <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span>        </div>
-
-        <div class="details">
-                        <a  href="class-reloading.html">Class Reloading</a>
-                
-                        
-                    </div>
-    </li></ul>
-</div>
-
-
-<p>One of the best features of Tapestry is automatic reloading of changed classes and templates. <em>Page and component</em> classes will automatically reload when changed. Likewise, changes to component templates and other related resources will also be picked up immediately. In addition, starting in version 5.2, your service classes will also be reloaded automatically after changes (if you're using <a  href="ioc.html">Tapestry IoC</a>).</p><h2 id="ClassReloading-TemplateReloading">Template Reloading</h2><p>When a template changes, all page instances (as well as the hierarchy of components below them) are discarded and reconstructed with the new template. However, classes are not reloaded in this case.</p><h2 id="ClassReloading-ClassReloading">Class Reloading</h2><p>On a change to <em>any</em> loaded class from inside a controlled package (or any sub-package of a controlled package), Tapestry will discard all page instances, and discard the class loader.</p><p><a  href="persistent-
 page-data.html">Persistent field data</a> on the pages will usually not be affected (as it is stored separately, usually in the session). This allows you to make fairly significant changes to a component class even while the application continues to run.</p><h2 id="ClassReloading-PackagesScanned">Packages Scanned</h2><p>Only certain classes are subject to reload. Reloading is based on package name; the packages that are reloaded are derived from the <a  href="configuration.html">application configuration</a>.</p><p>If your root package is <code>org.example.myapp</code>, then only classes in the following packages (and their sub-packages) will be scanned for automatic reloads:</p><ul><li>org.example.myapp.pages</li><li>org.example.myapp.components</li><li>org.example.myapp.mixins</li><li>org.example.myapp.base</li><li>org.example.myapp.services (Tapestry 5.2 and later, with restrictions)</li></ul><p>
+                <div id="ConfluenceContent"><h1 id="ClassReloading-LiveClassandTemplateReloading">Live Class and Template Reloading</h1><parameter ac:name="style">float:right</parameter><parameter ac:name="title">Related Articles</parameter><parameter ac:name="class">aui-label</parameter><rich-text-body><parameter ac:name="showLabels">false</parameter><parameter ac:name="showSpace">false</parameter><parameter ac:name="title">Related Articles</parameter><parameter ac:name="cql">label = "class-reloading" and space = currentSpace()</parameter></rich-text-body><p>One of the best features of Tapestry is automatic reloading of changed classes and templates. <em>Page and component</em> classes will automatically reload when changed. Likewise, changes to component templates and other related resources will also be picked up immediately. In addition, starting in version 5.2, your service classes will also be reloaded automatically after changes (if you're using <a  href="ioc.html">Tapestry I
 oC</a>).</p><h2 id="ClassReloading-TemplateReloading">Template Reloading</h2><p>When a template changes, all page instances (as well as the hierarchy of components below them) are discarded and reconstructed with the new template. However, classes are not reloaded in this case.</p><h2 id="ClassReloading-ClassReloading">Class Reloading</h2><p>On a change to <em>any</em> loaded class from inside a controlled package (or any sub-package of a controlled package), Tapestry will discard all page instances, and discard the class loader.</p><p><a  href="persistent-page-data.html">Persistent field data</a> on the pages will usually not be affected (as it is stored separately, usually in the session). This allows you to make fairly significant changes to a component class even while the application continues to run.</p><h2 id="ClassReloading-PackagesScanned">Packages Scanned</h2><p>Only certain classes are subject to reload. Reloading is based on package name; the packages that are reloaded a
 re derived from the <a  href="configuration.html">application configuration</a>.</p><p>If your root package is <code>org.example.myapp</code>, then only classes in the following packages (and their sub-packages) will be scanned for automatic reloads:</p><ul><li>org.example.myapp.pages</li><li>org.example.myapp.components</li><li>org.example.myapp.mixins</li><li>org.example.myapp.base</li><li>org.example.myapp.services (Tapestry 5.2 and later, with restrictions)</li></ul><p>
 
 </p><div class="confluence-information-macro confluence-information-macro-information"><p class="title">Added in 5.2</p><span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span><div class="confluence-information-macro-body">
 </div></div>
 <div class="error"><span class="error">Unknown macro: {div}</span> 
 <p>Starting in Tapestry 5.2, live class reloading includes service implementation classes. There are some limitations to this. See <a  href="service-implementation-reloading.html" title="Service Implementation Reloading">Service Implementation Reloading</a> for more details.</p>
-</div><h2 id="ClassReloading-FileSystemOnly">File System Only</h2><p>Reloading of classes and other files applies only to files that are actually on the file system, and not files obtained from JAR files. This is perfect during development, where the files in question are in your local workspace. In a deployed application, you are somewhat subject to the implementation of your servlet container or application server.</p><h2 id="ClassReloading-ClassLoaderIssues">Class Loader Issues</h2><p>Tapestry uses an extra class loader to load page and component classes.</p><p>When a change to an underlying Java class file is detected, Tapestry discards the class loader and any pooled page instances.</p><p>You should be careful to not hold any references to Tapestry pages or components in other code, such as Tapestry IoC services. Holding such references can cause significant memory leaks, as they can prevent the class loader from being reclaimed by the garbage collector.</p><h2 id="ClassReloadi
 ng-ClassCastExceptions">ClassCastExceptions</h2><p>Tapestry's class loader architecture can cause minor headaches when you make use of a services layer, or any time that you pass component instances to objects that are not themselves components.</p><p>In such cases you may see ClassCastException errors. This is because the same class name, say org.example.myapp.pages.Start, exists as two different class instances. One class instance is loaded by the web application's default class loader. A second class instance has been loaded <em>and transformed</em> by Tapestry's reloading class loader.</p><p>Ordinary classes, such as Tapestry IoC Services, will be loaded by the default class loader and expect instances to be loaded by the same class loader (or a parent).</p><p>The solution to this problem is to introduce an interface; the component class should implement the interface, and the service should expect an instance of the interface, rather than a specific type.</p><p>It is important 
 that the interface be loaded by the default class loader. It should not be in the pages or components package, but instead be in another package, such as services.</p><h2 id="ClassReloading-HandlingReloadsinyourCode">Handling Reloads in your Code</h2><p>On occasion, you may need to know when invalidations occur, to clear your own cache. For example, if you have a binding that creates new classes, the way <a  class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/PropertyConduitSource.html">PropertyConduitSource</a> does, you need to discard any cached classes or instances when a change is detected in component classes.</p><p>You do this by registering a listener with the correct <a  class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tpaestry5/services/InvalidationEventHub.html">InvalidationEventHub</a> service.</p><p>For example, your service may be in the business of creating new classes based on component
  classes, and keep a cache of those classes:</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;">public class MyServiceImpl implements MyService, InvalidationEventListener
+</div><h2 id="ClassReloading-FileSystemOnly">File System Only</h2><p>Reloading of classes and other files applies only to files that are actually on the file system, and not files obtained from JAR files. This is perfect during development, where the files in question are in your local workspace. In a deployed application, you are somewhat subject to the implementation of your servlet container or application server.</p><h2 id="ClassReloading-ClassLoaderIssues">Class Loader Issues</h2><p>Tapestry uses an extra class loader to load page and component classes.</p><p>When a change to an underlying Java class file is detected, Tapestry discards the class loader and any pooled page instances.</p><p>You should be careful to not hold any references to Tapestry pages or components in other code, such as Tapestry IoC services. Holding such references can cause significant memory leaks, as they can prevent the class loader from being reclaimed by the garbage collector.</p><h2 id="ClassReloadi
 ng-ClassCastExceptions">ClassCastExceptions</h2><p>Tapestry's class loader architecture can cause minor headaches when you make use of a services layer, or any time that you pass component instances to objects that are not themselves components.</p><p>In such cases you may see ClassCastException errors. This is because the same class name, say org.example.myapp.pages.Start, exists as two different class instances. One class instance is loaded by the web application's default class loader. A second class instance has been loaded <em>and transformed</em> by Tapestry's reloading class loader.</p><p>Ordinary classes, such as Tapestry IoC Services, will be loaded by the default class loader and expect instances to be loaded by the same class loader (or a parent).</p><p>The solution to this problem is to introduce an interface; the component class should implement the interface, and the service should expect an instance of the interface, rather than a specific type.</p><p>It is important 
 that the interface be loaded by the default class loader. It should not be in the pages or components package, but instead be in another package, such as services.</p><h2 id="ClassReloading-HandlingReloadsinyourCode">Handling Reloads in your Code</h2><p>On occasion, you may need to know when invalidations occur, to clear your own cache. For example, if you have a binding that creates new classes, the way <a  class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/PropertyConduitSource.html">PropertyConduitSource</a> does, you need to discard any cached classes or instances when a change is detected in component classes.</p><p>You do this by registering a listener with the correct <a  class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tpaestry5/services/InvalidationEventHub.html">InvalidationEventHub</a> service.</p><p>For example, your service may be in the business of creating new classes based on component
  classes, and keep a cache of those classes:</p><parameter ac:name="">java</parameter><plain-text-body>public class MyServiceImpl implements MyService, InvalidationEventListener
 {
   public final Map&lt;String,Class&gt; cache = new ConcurrentHashMap&lt;String,Class&gt;();
 
@@ -125,19 +81,14 @@
 
   public void objectWasInvalidated() { cache.clear(); }
 }
-</pre>
-</div></div><p>Here, the service implementation implements the InvalidationEventListener interface, as well as its service interface. The question is: how does it register for notifications?</p><p>In your module, you will want to use a service builder method, such as:</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;">public static MyService buildMyService(@Autobuild MyServiceImpl service, @ComponentClasses InvalidationEventHub hub)
+</plain-text-body><p>Here, the service implementation implements the InvalidationEventListener interface, as well as its service interface. The question is: how does it register for notifications?</p><p>In your module, you will want to use a service builder method, such as:</p><parameter ac:name="">java</parameter><plain-text-body>public static MyService buildMyService(@Autobuild MyServiceImpl service, @ComponentClasses InvalidationEventHub hub)
 {
   hub.addInvalidationListener(service);
 
   return service;
 }
-</pre>
-</div></div><p>This is the intent of service builder methods; to do more than just injecting dependencies.</p><h2 id="ClassReloading-CheckingForUpdates">Checking For Updates</h2><p>The built in InvalidationEventHub services provide notifications of changes to component classes, to component templates, and to component message catalogs. If you wish to check some other resources (for example, files in a directory of the file system or rows in a database table), you should register as an <a  class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/UpdateListener.html">UpdateListener</a> with the <a  class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/UpdateListenerHub.html">UpdateListenerHub</a> service.</p><p>Periodically (the frequency is configurable), UpdateListeners are notified that they should check for updates. Typically, UpdateListeners are also InvalidationEventHubs (or provide Invali
 dationEventHubs), so that other interested parties can be alerted when underlying data changes.</p><h2 id="ClassReloading-TroubleshootingLiveClassReloading">Troubleshooting Live Class Reloading</h2><h3 id="ClassReloading-QuickChecklist">Quick Checklist</h3><ul><li>"Production Mode" must be false (in Tapestry 5.3 and later)</li><li>The class must be one that Tapestry instantiates (a page, component, or mixin class, or a Tapestry IOC service implementation that implements an interface)</li><li>Turn on "Build Automatically" in your IDE, or remember to build manually.</li><li>Turn <em>off</em> JVM hot code swapping, if your servlet container supports it.</li><li>Eclipse: Uncheck the "derived" checkbox for the Target dir (in the Project Explorer view, right click on "target", select properties, uncheck "derived" on the Resource tab)</li></ul><p>Some of these issues are described in more detail below.</p><h3 id="ClassReloading-IfLiveClassReloadingdoesn'twork">If Live Class Reloading doesn
 't work</h3><h4 id="ClassReloading-ProductionMode">Production Mode</h4><p>Starting with Tapestry 5.3, Live Class Reloading only works when not in "Production Mode". Check your application module (usually AppModule.java) to be sure you have:</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;">configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
-</pre>
-</div></div><p>and that this isn't being overridden to "true" on your application's startup command line.</p><h4 id="ClassReloading-BuildPathIssues">Build Path Issues</h4><p>Live Class Reloading can fail if your build path isn't set correctly, and the exact configuration may differ between Maven plugin versions and Eclipse versions. The build process must be set to create classes in a folder which is in the servlet container's classpath.</p><p>Live Class Reloading won't work correctly with vanilla Tomcat without some tweaks (see below).</p><p>Non-Tapestry filters can interfere with LCR. Try disabling other filters in your web.xml file to see if that helps.</p><h4 id="ClassReloading-BuildingAutomatically">Building Automatically</h4><p>Although LCR allows you to see changes without restarting your app, you still need to "build" your project (to compile the Java source into byte code). Your IDE can be set to do this automatically every time you save a file. (In Eclipse, this is done us
 ing <code>Project &gt; Build Automatically</code>.) Alternatively, you can manually trigger a build after you save a file. (In Eclipse, this is done using <code>Project &gt; Build</code>, or by pressing <code>Control-B</code>.)</p><h4 id="ClassReloading-TurnoffJVMhotcodeswapping&amp;automaticrestarts">Turn off JVM hot code swapping &amp; automatic restarts</h4><p>Many servlet containers, including Tomcat and Jetty, support various forms of hot code swapping and/or automatic restarts when file changes are detected. These are generally <strong>much slower</strong> than LCR and usually should be turned off with Tapestry applications. If you're using RunJettyRun plugin for Eclipse, for example, edit your Run Configuration, and on the Jetty tab, click Show Advanced Options and uncheck the Enable Scanner checkbox.</p><h3 id="ClassReloading-TomcatSpecifics">Tomcat Specifics</h3><p>See <a  class="external-link" href="http://docs.codehaus.org/display/TYNAMO/Developing+with+Tomcat+and+Eclipse
 " rel="nofollow">these Tomcat-specific hints</a></p><h3 id="ClassReloading-IfLiveClassReloadingworksbutisslow">If Live Class Reloading works but is slow</h3><p>If LCR works for you but is slow (more than a second or two), consider the following.</p><ul><li>Be sure your project source files (your workspace in Eclipse, for example), are on a local drive, NOT a network location. Network drives are always slower, and the file system scanning needed for LCR can add a noticable lag if I/O is slow. If you use Maven, be sure to put your local repository (e.g. ~/.m2/repository) on a local drive for similar reasons.</li><li>Since LCR adds classes to your PermGen space, you may be running low on PermGen memory (and may eventually get a "java.lang.OutOfMemoryError: PermGen space" error). Try increasing PermGen size with a JVM argument of something like <code>-XX:MaxPermSize=400m</code></li></ul><p></p></div>
+</plain-text-body><p>This is the intent of service builder methods; to do more than just injecting dependencies.</p><h2 id="ClassReloading-CheckingForUpdates">Checking For Updates</h2><p>The built in InvalidationEventHub services provide notifications of changes to component classes, to component templates, and to component message catalogs. If you wish to check some other resources (for example, files in a directory of the file system or rows in a database table), you should register as an <a  class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/UpdateListener.html">UpdateListener</a> with the <a  class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/UpdateListenerHub.html">UpdateListenerHub</a> service.</p><p>Periodically (the frequency is configurable), UpdateListeners are notified that they should check for updates. Typically, UpdateListeners are also InvalidationEventHubs (or provide 
 InvalidationEventHubs), so that other interested parties can be alerted when underlying data changes.</p><h2 id="ClassReloading-TroubleshootingLiveClassReloading">Troubleshooting Live Class Reloading</h2><h3 id="ClassReloading-QuickChecklist">Quick Checklist</h3><ul><li>"Production Mode" must be false (in Tapestry 5.3 and later)</li><li>The class must be one that Tapestry instantiates (a page, component, or mixin class, or a Tapestry IOC service implementation that implements an interface)</li><li>Turn on "Build Automatically" in your IDE, or remember to build manually.</li><li>Turn <em>off</em> JVM hot code swapping, if your servlet container supports it.</li><li>Eclipse: Uncheck the "derived" checkbox for the Target dir (in the Project Explorer view, right click on "target", select properties, uncheck "derived" on the Resource tab)</li></ul><p>Some of these issues are described in more detail below.</p><h3 id="ClassReloading-IfLiveClassReloadingdoesn'twork">If Live Class Reloading
  doesn't work</h3><h4 id="ClassReloading-ProductionMode">Production Mode</h4><p>Starting with Tapestry 5.3, Live Class Reloading only works when not in "Production Mode". Check your application module (usually AppModule.java) to be sure you have:</p><parameter ac:name="lang">java</parameter><plain-text-body>configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
+</plain-text-body><p>and that this isn't being overridden to "true" on your application's startup command line.</p><h4 id="ClassReloading-BuildPathIssues">Build Path Issues</h4><p>Live Class Reloading can fail if your build path isn't set correctly, and the exact configuration may differ between Maven plugin versions and Eclipse versions. The build process must be set to create classes in a folder which is in the servlet container's classpath.</p><p>Live Class Reloading won't work correctly with vanilla Tomcat without some tweaks (see below).</p><p>Non-Tapestry filters can interfere with LCR. Try disabling other filters in your web.xml file to see if that helps.</p><h4 id="ClassReloading-BuildingAutomatically">Building Automatically</h4><p>Although LCR allows you to see changes without restarting your app, you still need to "build" your project (to compile the Java source into byte code). Your IDE can be set to do this automatically every time you save a file. (In Eclipse, this is d
 one using <code>Project &gt; Build Automatically</code>.) Alternatively, you can manually trigger a build after you save a file. (In Eclipse, this is done using <code>Project &gt; Build</code>, or by pressing <code>Control-B</code>.)</p><h4 id="ClassReloading-TurnoffJVMhotcodeswapping&amp;automaticrestarts">Turn off JVM hot code swapping &amp; automatic restarts</h4><p>Many servlet containers, including Tomcat and Jetty, support various forms of hot code swapping and/or automatic restarts when file changes are detected. These are generally <strong>much slower</strong> than LCR and usually should be turned off with Tapestry applications. If you're using RunJettyRun plugin for Eclipse, for example, edit your Run Configuration, and on the Jetty tab, click Show Advanced Options and uncheck the Enable Scanner checkbox.</p><h3 id="ClassReloading-TomcatSpecifics">Tomcat Specifics</h3><p>See <a  class="external-link" href="http://docs.codehaus.org/display/TYNAMO/Developing+with+Tomcat+and+E
 clipse" rel="nofollow">these Tomcat-specific hints</a></p><h3 id="ClassReloading-IfLiveClassReloadingworksbutisslow">If Live Class Reloading works but is slow</h3><p>If LCR works for you but is slow (more than a second or two), consider the following.</p><ul><li>Be sure your project source files (your workspace in Eclipse, for example), are on a local drive, NOT a network location. Network drives are always slower, and the file system scanning needed for LCR can add a noticable lag if I/O is slow. If you use Maven, be sure to put your local repository (e.g. ~/.m2/repository) on a local drive for similar reasons.</li><li>Since LCR adds classes to your PermGen space, you may be running low on PermGen memory (and may eventually get a "java.lang.OutOfMemoryError: PermGen space" error). Try increasing PermGen size with a JVM argument of something like <code>-XX:MaxPermSize=400m</code></li></ul><p><plain-text-body>{scrollbar}</plain-text-body></p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/client-side-javascript.html
==============================================================================
--- websites/production/tapestry/content/client-side-javascript.html (original)
+++ websites/production/tapestry/content/client-side-javascript.html Sat Sep 16 02:22:40 2017
@@ -27,14 +27,6 @@
       </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>
-      SyntaxHighlighter.defaults['toolbar'] = false;
-      SyntaxHighlighter.all();
-    </script>
   
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -44,13 +36,26 @@
 
   <div class="wrapper bs">
 
-        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  href="index.html">Home</a></li><li><a  href="getting-started.html">Getting Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  href="download.html">Download</a></li><li><a  href="about.html">About</a></li><li><a  class="external-link" href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a  href="community.html">Community</a></li><li><a  class="external-link" href="http://www.apache.org/security/">Security</a></li><li><a  class="external-link" href="http://www.apache.org/">Apache</a></li><li><a  class="external-link" href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a  class="external-link" href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div></div>
+        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  href="index.html">Home</a></li><li><a  href="getting-started.html">Getting Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  href="download.html">Download</a></li><li><a  href="about.html">About</a></li><li><a  class="external-link" href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a  href="community.html">Community</a></li><li><a  class="external-link" href="http://www.apache.org/security/">Security</a></li><li><a  class="external-link" href="http://www.apache.org/">Apache</a></li><li><a  class="external-link" href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a  class="external-link" href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div>
+
+</div>
 
           <div id="top">
-            <div id="smallbanner"><div class="searchbox" style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span><form enctype="application/x-www-form-urlencoded" method="get" action="http://tapestry.apache.org/search.html"> 
- <input type="text" name="q"> 
- <input type="submit" value="Search"> 
-</form></div><div class="emblem" style="float:left"><p><a  href="index.html"><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image confluence-external-resource" src="http://tapestry.apache.org/images/tapestry_small.png" data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div><div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">Client-Side JavaScript</h1></div></div>
+            <div id="smallbanner"><div class="searchbox" style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span>
+<form enctype="application/x-www-form-urlencoded" method="get" action="http://tapestry.apache.org/search.html">
+  <input type="text" name="q">
+  <input type="submit" value="Search">
+</form>
+
+</div>
+
+
+<div class="emblem" style="float:left"><p><a  href="index.html"><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image confluence-external-resource" src="http://tapestry.apache.org/images/tapestry_small.png" data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div>
+
+
+<div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">Client-Side JavaScript</h1></div>
+
+</div>
       <div class="clearer"></div>
       </div>
 
@@ -62,62 +67,7 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p>Perhaps nothing in Tapestry has changed over the years so much as the way client-side JavaScript is supported. From the get go, the goal was to make JavaScript a first-class citizen in the Tapestry world, and make it easy to encapsulate JavaScript within components.</p><div class="aui-label" style="float:right" title="Related Articles"><h3>Related Articles</h3><ul class="content-by-label"><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="ajax-and-zones.html">Ajax and Zones</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="legacy-javascript.html">Legacy JavaScript</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="coffeescript.html">CoffeeScript</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="client-side-javascript.html">Client-Side JavaScript</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="javascript-modules.html">JavaScript Modules</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="javascript-faq.html">JavaScript FAQ</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="ajax-components-faq.html">Ajax Components FAQ</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="component-cheat-sheet.html">Component Cheat Sheet</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="assets.html">Assets</a> 
-  </div> </li></ul></div><p>The <a  href="legacy-javascript.html">legacy JavaScript</a> page discusses the earlier approaches; the main feature of Tapestry 5.4 is a total rewrite of all things client-side, with the following goals:</p><ul><li>Break the hard linkage of Tapestry to <a  class="external-link" href="http://prototypejs.org/" rel="nofollow">Prototype</a> and <a  class="external-link" href="http://script.aculo.us/" rel="nofollow">Scriptaculous</a>, by introducing an abstraction layer</li><li>Remove the clumsy <code>Tapestry</code> and <code>T5</code> "namespaces"</li><li>Reduce the amount of page-specific JavaScript initialization</li><li>Make it easier to override behavior associated with client elements</li><li>Support CoffeeScript and (potentially) other languages that target JavaScript</li><li>Organize client-side JavaScript using <a  href="javascript-modules.html">modules</a></li><li>Make pages load faster</li><li>Integrate <a  class="external-link" href="http://getboo
 tstrap.com/" rel="nofollow">Bootstrap</a></li><li>Make it easier for rich client libraries such as&#160;<a  class="external-link" href="http://backbonejs.org/" rel="nofollow">Backbone</a> or&#160;<a  class="external-link" href="https://angularjs.org/" rel="nofollow">AngularJS</a> to operate within a page</li><li>Properly document Tapestry's client support</li></ul><h3 id="Client-SideJavaScript-TheOverallVision">The Overall Vision</h3><p>The overall vision for the client-side in Tapestry is encapsulation, at several different levels.</p><p>On the server-side, a Tapestry component (or mixin) exposes configurable parameters. The component writes DOM elements or attributes, as well as some amount of JavaScript initialization. The encapsulation here allows developers with little or no knowledge of client-side JavaScript to enjoy the benefits (as consumers of components created by developers who are versed in client-side coding and Tapestry components).</p><p>On the client-side, the JavaS
 cript combines with the special markup to produce the behaviors that are desired ... anything from controlling the initial focus field, to performing client-side input field validation, to running complex Ajax workflows.</p><p>Where possible, all of this behavior is driven by <code>data-</code> attributes on the elements, combined with top-level event handlers. On the client side, events are used not only to respond directly to user actions (with "click", "mouseOver", "submit", or other event listeners) but also to allow elements to collaborate in various ways. &#160;For example, input validation is based on triggering a specific custom event on each form control element, and top-level event handlers can then manage the validation for any number of fields.</p><h3 id="Client-SideJavaScript-Prototypevs.jQuery">Prototype vs. jQuery</h3><p>For several years, it has been obvious that Tapestry "backed the wrong horse" with respect to Prototype and jQuery. When the first code was being lai
 d down in 2007 or 2008, it wasn't so clear that jQuery with its odd abstractions and unfamiliar approach, would go on to conquer the world. Meanwhile, Prototype was very strongly integrated into Ruby on Rails and had first class documentation and books.</p><p>That being said, jQuery is not the be-all and end-all either. Tapestry 5.4 introduces an abstraction layer, that allows many components to write code that doesn't care whether the foundation framework is Prototype or jQuery or something else. If<span style="font-size: 14.0px;">&#160;you like jQuery then there's no problem: write your application using just jQuery and you can ignore a lot of the features in the abstraction layer. Your code will likely be just a bit more efficient.</span></p><p>If you are building a reusable component or library, writing to the abstraction layer may be worth the effort; it is entirely possible that someone may write a replacement for the abstraction layer that targets your favorite foundation fra
 mework, such as ExtJS, MooTools, or something not even known of today.</p><h3 id="Client-SideJavaScript-Heavyvs.Light">Heavy vs. Light</h3><p>Earlier Tapestry JavaScript was&#160;<em>heavy</em>. Essentially, each component would write some very specific JavaScript initialization that would include the component's DOM id and many other details. This initialization would reference a function on the <code>T5.inits</code> namespace.</p><p>The function there would typically locate the specific element by its client DOM id, then attach event handlers to the one element. It might also create some form of client-side controller object. There were issues due to this: for complex pages (or perhaps even typical pages), the "blob" of JavaScript initialization at the bottom of the page could be quite large.</p><p>The use of individual event handlers meant that Tapestry applications would use more client-side objects that a bespoke jQuery solution ... because the normal approach in jQuery is to a
 ttach a single event handler to the document or body that handles any events that bubble up to the top&#160;<em>and</em> match a CSS selector.</p><p>In Tapestry 5.4, the goal is to make things&#160;<em>light</em>. In most cases, there isn't a specific initialization function; instead a <a  href="javascript-modules.html">JavaScript module</a>&#160;is loaded, and it installs one or more top-level event handlers; the elements has data-<a  class="external-link" href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes" rel="nofollow">&#160;attributes</a> that are used by those top level handlers to recognize which elements they are responsible for.</p><p>This is more of a full lifecycle approach; adding or removing page content (such as with a&#160;<a  href="ajax-and-zones.html">Zone</a> component) is both cheaper and less error prone using top-level event handlers than per-element event handlers; there's also less of a chance of memory leaks under Internet Exp
 lorer.</p><div class="confluence-information-macro confluence-information-macro-note"><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>Internet Explorer is pretty well known for memory leaks; its DOM and JavaScript run in different kinds of memory, which are garbage collected individually. This means that a reference from JavaScript to a DOM element will keep the DOM element live, even if that's the only reference to the DOM element anywhere. Meanwhile, event handler JavaScript functions are kept live from the DOM element, making a cycle that can't be broken. Libraries like Prototype and jQuery have to expend some effort to break this link by unregistering event handlers from DOM elements when removing them from the DOM.</p></div></div><p>A specific example of this approach is how client-side validation now works; in the past, there was a complex system of classes and event listeners
  that were specific to each individual field. Field controllers had to register with Form controllers. Validators had to register with Field controllers.</p><p>Under 5.4, there are a number of&#160;<code>data-</code> attributes that can be attached to any DOM element. A form searches for elements with a non-blank value for&#160;<code>data-validation</code>; each such element has a series of custom events triggered on it. The top-level handlers for those events receive notifications for elements throughout the document.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>t5/core/validation.coffee (partial)</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">define ["underscore", "./dom", "./events", "./utils", "./messages", "./fields"],
+                <div id="ConfluenceContent"><p>Perhaps nothing in Tapestry has changed over the years so much as the way client-side JavaScript is supported. From the get go, the goal was to make JavaScript a first-class citizen in the Tapestry world, and make it easy to encapsulate JavaScript within components.</p><parameter ac:name="style">float:right</parameter><parameter ac:name="title">Related Articles</parameter><parameter ac:name="class">aui-label</parameter><rich-text-body><parameter ac:name="showLabels">false</parameter><parameter ac:name="showSpace">false</parameter><parameter ac:name="title">Related Articles</parameter><parameter ac:name="cql">label in ("javascript","ajax") and space = currentSpace()</parameter></rich-text-body><p>The <a  href="legacy-javascript.html">legacy JavaScript</a> page discusses the earlier approaches; the main feature of Tapestry 5.4 is a total rewrite of all things client-side, with the following goals:</p><ul><li>Break the hard linkage of Tape
 stry to <a  class="external-link" href="http://prototypejs.org/" rel="nofollow">Prototype</a> and <a  class="external-link" href="http://script.aculo.us/" rel="nofollow">Scriptaculous</a>, by introducing an abstraction layer</li><li>Remove the clumsy <code>Tapestry</code> and <code>T5</code> "namespaces"</li><li>Reduce the amount of page-specific JavaScript initialization</li><li>Make it easier to override behavior associated with client elements</li><li>Support CoffeeScript and (potentially) other languages that target JavaScript</li><li>Organize client-side JavaScript using <a  href="javascript-modules.html">modules</a></li><li>Make pages load faster</li><li>Integrate <a  class="external-link" href="http://getbootstrap.com/" rel="nofollow">Bootstrap</a></li><li>Make it easier for rich client libraries such as&#160;<a  class="external-link" href="http://backbonejs.org/" rel="nofollow">Backbone</a> or&#160;<a  class="external-link" href="https://angularjs.org/" rel="nofollow">Angula
 rJS</a> to operate within a page</li><li>Properly document Tapestry's client support</li></ul><h3 id="Client-SideJavaScript-TheOverallVision">The Overall Vision</h3><p>The overall vision for the client-side in Tapestry is encapsulation, at several different levels.</p><p>On the server-side, a Tapestry component (or mixin) exposes configurable parameters. The component writes DOM elements or attributes, as well as some amount of JavaScript initialization. The encapsulation here allows developers with little or no knowledge of client-side JavaScript to enjoy the benefits (as consumers of components created by developers who are versed in client-side coding and Tapestry components).</p><p>On the client-side, the JavaScript combines with the special markup to produce the behaviors that are desired ... anything from controlling the initial focus field, to performing client-side input field validation, to running complex Ajax workflows.</p><p>Where possible, all of this behavior is driven
  by <code>data-</code> attributes on the elements, combined with top-level event handlers. On the client side, events are used not only to respond directly to user actions (with "click", "mouseOver", "submit", or other event listeners) but also to allow elements to collaborate in various ways. &#160;For example, input validation is based on triggering a specific custom event on each form control element, and top-level event handlers can then manage the validation for any number of fields.</p><h3 id="Client-SideJavaScript-Prototypevs.jQuery">Prototype vs. jQuery</h3><p>For several years, it has been obvious that Tapestry "backed the wrong horse" with respect to Prototype and jQuery. When the first code was being laid down in 2007 or 2008, it wasn't so clear that jQuery with its odd abstractions and unfamiliar approach, would go on to conquer the world. Meanwhile, Prototype was very strongly integrated into Ruby on Rails and had first class documentation and books.</p><p>That being sa
 id, jQuery is not the be-all and end-all either. Tapestry 5.4 introduces an abstraction layer, that allows many components to write code that doesn't care whether the foundation framework is Prototype or jQuery or something else. If<span style="font-size: 14.0px;">&#160;you like jQuery then there's no problem: write your application using just jQuery and you can ignore a lot of the features in the abstraction layer. Your code will likely be just a bit more efficient.</span></p><p>If you are building a reusable component or library, writing to the abstraction layer may be worth the effort; it is entirely possible that someone may write a replacement for the abstraction layer that targets your favorite foundation framework, such as ExtJS, MooTools, or something not even known of today.</p><h3 id="Client-SideJavaScript-Heavyvs.Light">Heavy vs. Light</h3><p>Earlier Tapestry JavaScript was&#160;<em>heavy</em>. Essentially, each component would write some very specific JavaScript initiali
 zation that would include the component's DOM id and many other details. This initialization would reference a function on the <code>T5.inits</code> namespace.</p><p>The function there would typically locate the specific element by its client DOM id, then attach event handlers to the one element. It might also create some form of client-side controller object. There were issues due to this: for complex pages (or perhaps even typical pages), the "blob" of JavaScript initialization at the bottom of the page could be quite large.</p><p>The use of individual event handlers meant that Tapestry applications would use more client-side objects that a bespoke jQuery solution ... because the normal approach in jQuery is to attach a single event handler to the document or body that handles any events that bubble up to the top&#160;<em>and</em> match a CSS selector.</p><p>In Tapestry 5.4, the goal is to make things&#160;<em>light</em>. In most cases, there isn't a specific initialization functi
 on; instead a <a  href="javascript-modules.html">JavaScript module</a>&#160;is loaded, and it installs one or more top-level event handlers; the elements has data-<a  class="external-link" href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes" rel="nofollow">&#160;attributes</a> that are used by those top level handlers to recognize which elements they are responsible for.</p><p>This is more of a full lifecycle approach; adding or removing page content (such as with a&#160;<a  href="ajax-and-zones.html">Zone</a> component) is both cheaper and less error prone using top-level event handlers than per-element event handlers; there's also less of a chance of memory leaks under Internet Explorer.</p><rich-text-body><p>Internet Explorer is pretty well known for memory leaks; its DOM and JavaScript run in different kinds of memory, which are garbage collected individually. This means that a reference from JavaScript to a DOM element will keep the DOM element l
 ive, even if that's the only reference to the DOM element anywhere. Meanwhile, event handler JavaScript functions are kept live from the DOM element, making a cycle that can't be broken. Libraries like Prototype and jQuery have to expend some effort to break this link by unregistering event handlers from DOM elements when removing them from the DOM.</p></rich-text-body><p>A specific example of this approach is how client-side validation now works; in the past, there was a complex system of classes and event listeners that were specific to each individual field. Field controllers had to register with Form controllers. Validators had to register with Field controllers.</p><p>Under 5.4, there are a number of&#160;<code>data-</code> attributes that can be attached to any DOM element. A form searches for elements with a non-blank value for&#160;<code>data-validation</code>; each such element has a series of custom events triggered on it. The top-level handlers for those events receive no
 tifications for elements throughout the document.</p><parameter ac:name="title">t5/core/validation.coffee (partial)</parameter><plain-text-body>define ["underscore", "./dom", "./events", "./utils", "./messages", "./fields"],
   (_, dom, events, utils, messages) -&gt;
 
 
@@ -134,8 +84,7 @@
       min = parseInt @attr "data-validate-min-length"
       if memo.translated.length &lt; min
         memo.error = (@attr "data-min-length-message") or "TOO SHORT"
-        return false</pre>
-</div></div><p>The&#160;<code>t5/core/events</code> module defines constants for different custom event name, it's also a handy place to <a  class="external-link" href="http://tapestry.apache.org/5.4/coffeescript/events.html">hang documentation</a> about those events.</p><p>The&#160;<code>t5/core/dom</code> namespace is the abstraction layer. &#160;<code>onDocument</code> is a handy way to attach a top-level event handler.</p><p>Fields that are required have the attribute&#160;<code>data-optionality=required</code>; the event handler is passed a&#160;<em>memo</em> object that includes a&#160;<code>value</code> property, the value from the field. This makes it easier to generate an error if the value is blank. &#160;Because the exact error message may be customized or localized, it is provided in the element as well, as the&#160;<code>data-required-message</code> attribute. Setting&#160;<code>memo.error</code> to a validation error string causes the field to be decorated with the err
 or message and indicates that the form itself is in error and not ready for submission.</p><p>A different event is triggered after the optionality check; The&#160;<code>memo.translated</code> property is the value translated before validation (for a numeric field, it would be translated from a string to a number, for example). Again, the&#160;<code>error</code> property is set, and the&#160;<code>return false</code> ensures that the event will stop bubbling to containing elements or event handlers.</p><p>What's very useful in this overall approach is that it no longer matters whether the fields were rendered by Tapestry on the server, or rendered locally (perhaps using Backbone or AngularJS) on the client. As long as they have the correct&#160;<code>data-</code> attributes, then they can participate in Tapestry's overall form validation and submission cycle, and even leverage the default validation decoration behavior.</p><h3 id="Client-SideJavaScript-TheAbstractionLayer">The Abstra
 ction Layer</h3><p>The abstraction layer is defined by the&#160;<code>t5/core/dom</code> module. This module currently has two different implementations - one is a wrapper around Prototype, and the other is a wrapper around jQuery.</p><p>The resulting abstraction layer is a bit of a hybrid; it mostly looks like jQuery, but events look a bit more like Prototype. It also doesn't have jQuery's concept of operating on a matched set of elements.</p><p>The abstraction is both transitional and permanent. It is transitional in that it is about allowing existing sites with a heavy investment in Prototype to continue to operate with Prototype in the mix. It is permanent &#160;in that it is desirable for third party library developers to keep an abstraction layer between Tapestry's client-side code and any underlying framework, so that particular applications can provide their own abstraction layer and operate without breaking built-in components.</p><p>Most applications should transition to j
 Query and feel free to use jQuery directly. &#160;It is still best to inject module <span style="font-family: monospace;">jquery</span>&#160;into your own modules (usually as parameter&#160;<code>$</code>).&#160;</p><p>If you are writing a third-party application and want to maximize re-use, then use the abstraction layer.</p><p>It is often easier to use the abstraction layer to respond correctly to custom Tapestry events.</p></div>
+        return false</plain-text-body><p>The&#160;<code>t5/core/events</code> module defines constants for different custom event name, it's also a handy place to <a  class="external-link" href="http://tapestry.apache.org/5.4/coffeescript/events.html">hang documentation</a> about those events.</p><p>The&#160;<code>t5/core/dom</code> namespace is the abstraction layer. &#160;<code>onDocument</code> is a handy way to attach a top-level event handler.</p><p>Fields that are required have the attribute&#160;<code>data-optionality=required</code>; the event handler is passed a&#160;<em>memo</em> object that includes a&#160;<code>value</code> property, the value from the field. This makes it easier to generate an error if the value is blank. &#160;Because the exact error message may be customized or localized, it is provided in the element as well, as the&#160;<code>data-required-message</code> attribute. Setting&#160;<code>memo.error</code> to a validation error string causes the field to
  be decorated with the error message and indicates that the form itself is in error and not ready for submission.</p><p>A different event is triggered after the optionality check; The&#160;<code>memo.translated</code> property is the value translated before validation (for a numeric field, it would be translated from a string to a number, for example). Again, the&#160;<code>error</code> property is set, and the&#160;<code>return false</code> ensures that the event will stop bubbling to containing elements or event handlers.</p><p>What's very useful in this overall approach is that it no longer matters whether the fields were rendered by Tapestry on the server, or rendered locally (perhaps using Backbone or AngularJS) on the client. As long as they have the correct&#160;<code>data-</code> attributes, then they can participate in Tapestry's overall form validation and submission cycle, and even leverage the default validation decoration behavior.</p><h3 id="Client-SideJavaScript-TheAb
 stractionLayer">The Abstraction Layer</h3><p>The abstraction layer is defined by the&#160;<code>t5/core/dom</code> module. This module currently has two different implementations - one is a wrapper around Prototype, and the other is a wrapper around jQuery.</p><p>The resulting abstraction layer is a bit of a hybrid; it mostly looks like jQuery, but events look a bit more like Prototype. It also doesn't have jQuery's concept of operating on a matched set of elements.</p><p>The abstraction is both transitional and permanent. It is transitional in that it is about allowing existing sites with a heavy investment in Prototype to continue to operate with Prototype in the mix. It is permanent &#160;in that it is desirable for third party library developers to keep an abstraction layer between Tapestry's client-side code and any underlying framework, so that particular applications can provide their own abstraction layer and operate without breaking built-in components.</p><p>Most applicati
 ons should transition to jQuery and feel free to use jQuery directly. &#160;It is still best to inject module <span style="font-family: monospace;">jquery</span>&#160;into your own modules (usually as parameter&#160;<code>$</code>).&#160;</p><p>If you are writing a third-party application and want to maximize re-use, then use the abstraction layer.</p><p>It is often easier to use the abstraction layer to respond correctly to custom Tapestry events.</p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/coffeescript.html
==============================================================================
--- websites/production/tapestry/content/coffeescript.html (original)
+++ websites/production/tapestry/content/coffeescript.html Sat Sep 16 02:22:40 2017
@@ -27,14 +27,6 @@
       </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/shBrushXml.js' type='text/javascript'></script>
-        <script>
-      SyntaxHighlighter.defaults['toolbar'] = false;
-      SyntaxHighlighter.all();
-    </script>
   
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -44,13 +36,26 @@
 
   <div class="wrapper bs">
 
-        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  href="index.html">Home</a></li><li><a  href="getting-started.html">Getting Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  href="download.html">Download</a></li><li><a  href="about.html">About</a></li><li><a  class="external-link" href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a  href="community.html">Community</a></li><li><a  class="external-link" href="http://www.apache.org/security/">Security</a></li><li><a  class="external-link" href="http://www.apache.org/">Apache</a></li><li><a  class="external-link" href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a  class="external-link" href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div></div>
+        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  href="index.html">Home</a></li><li><a  href="getting-started.html">Getting Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  href="download.html">Download</a></li><li><a  href="about.html">About</a></li><li><a  class="external-link" href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a  href="community.html">Community</a></li><li><a  class="external-link" href="http://www.apache.org/security/">Security</a></li><li><a  class="external-link" href="http://www.apache.org/">Apache</a></li><li><a  class="external-link" href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a  class="external-link" href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div>
+
+</div>
 
           <div id="top">
-            <div id="smallbanner"><div class="searchbox" style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span><form enctype="application/x-www-form-urlencoded" method="get" action="http://tapestry.apache.org/search.html"> 
- <input type="text" name="q"> 
- <input type="submit" value="Search"> 
-</form></div><div class="emblem" style="float:left"><p><a  href="index.html"><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image confluence-external-resource" src="http://tapestry.apache.org/images/tapestry_small.png" data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div><div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">CoffeeScript</h1></div></div>
+            <div id="smallbanner"><div class="searchbox" style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span>
+<form enctype="application/x-www-form-urlencoded" method="get" action="http://tapestry.apache.org/search.html">
+  <input type="text" name="q">
+  <input type="submit" value="Search">
+</form>
+
+</div>
+
+
+<div class="emblem" style="float:left"><p><a  href="index.html"><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image confluence-external-resource" src="http://tapestry.apache.org/images/tapestry_small.png" data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div>
+
+
+<div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">CoffeeScript</h1></div>
+
+</div>
       <div class="clearer"></div>
       </div>
 
@@ -62,61 +67,11 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p><strong>CoffeeScript</strong> (<a  class="external-link" href="http://coffeescript.org" rel="nofollow">http://coffeescript.org</a>) is a language that compiles down to JavaScript.</p><div class="aui-label" style="float:right" title="Related Articles"><h3>Related Articles</h3><ul class="content-by-label"><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="coffeescript.html">CoffeeScript</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="client-side-javascript.html">Client-Side JavaScript</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="javascript-modules.html">JavaScript Modules</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="javascript-faq.html">JavaScript FAQ</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="ajax-and-zones.html">Ajax and Zones</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="component-cheat-sheet.html">Component Cheat Sheet</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="legacy-javascript.html">Legacy JavaScript</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="assets.html">Assets</a> 
-  </div> </li></ul></div><p><em>Starting with version 5.4,</em> Tapestry can automatically compile your CoffeeScript code into JavaScript on the fly. This is done with the optional tapestry-webresources module. It is highly recommended for anyone who wants to use CoffeeScript in their application ... just let Tapestry do the compilation at runtime (with access to Tapestry's full exception reporting capabilities).</p><p>To use the tapestry-webresources module, just add the JAR to your project. For example, if you're using Maven:</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;
+                <div id="ConfluenceContent"><p><strong>CoffeeScript</strong> (<a  class="external-link" href="http://coffeescript.org" rel="nofollow">http://coffeescript.org</a>) is a language that compiles down to JavaScript.</p><parameter ac:name="style">float:right</parameter><parameter ac:name="title">Related Articles</parameter><parameter ac:name="class">aui-label</parameter><rich-text-body><parameter ac:name="showLabels">false</parameter><parameter ac:name="showSpace">false</parameter><parameter ac:name="title">Related Articles</parameter><parameter ac:name="cql">label = "javascript" and space = currentSpace()</parameter></rich-text-body><p><em>Starting with version 5.4,</em> Tapestry can automatically compile your CoffeeScript code into JavaScript on the fly. This is done with the optional tapestry-webresources module. It is highly recommended for anyone who wants to use CoffeeScript in their application ... just let Tapestry do the compilation at runtime (with access to Tape
 stry's full exception reporting capabilities).</p><p>To use the tapestry-webresources module, just add the JAR to your project. For example, if you're using Maven:</p><parameter ac:name="language">xml</parameter><parameter ac:name="title">pom.xml (partial)</parameter><plain-text-body>&lt;dependency&gt;
     &lt;groupId&gt;org.apache.tapestry&lt;/groupId&gt;
     &lt;artifactId&gt;tapestry-webresources&lt;/artifactId&gt;
     &lt;version&gt;${tapestry-release-version}&lt;/version&gt;
-&lt;/dependency&gt;</pre>
-</div></div><p>All of Tapestry's own client-side code is written in CoffeeScript and compiled, at <em>build</em> time, to JavaScript.</p><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>You are completely free to use either JavaScript or CoffeeScript in your Tapestry application.</p></div></div><h2 id="CoffeeScript-CoffeeScriptversusJavaScript">CoffeeScript versus JavaScript</h2><p>CoffeeScript can be quite controversial, but also quite effective.</p><p>On the controversial side, it uses significant whitespace to denote blocks of code (like Python or Haskell) rather than curl braces (like Java, JavaScript, or Ruby). In fact, it draws influences from a wide rage of other languages, incorporating many functional programming features, a rudimentary class system, string interpolation, destructuring assignment
 , and more.</p><p>However, for all that, it is very close to JavaScript; it simply rounds out many of the rough edges of JavaScript (and adds a few of its own). As wide ranging as CoffeeScript syntax can be, there's generally a very close mapping from CoffeeScript to JavaScript.</p><p>CoffeeScript code often approaches Python's goal of being a "executable psuedo-code"; code that looks like a placeholder that will actually run. Some people find it more pleasant to read than JavaScript ... more&#160;<em>essence</em> and less&#160;<em>ceremony</em>.</p><p>You can still write bad code in CoffeeScript. You can write bad code in any language.</p></div>
+&lt;/dependency&gt;</plain-text-body><p>All of Tapestry's own client-side code is written in CoffeeScript and compiled, at <em>build</em> time, to JavaScript.</p><rich-text-body><p>You are completely free to use either JavaScript or CoffeeScript in your Tapestry application.</p></rich-text-body><h2 id="CoffeeScript-CoffeeScriptversusJavaScript">CoffeeScript versus JavaScript</h2><p>CoffeeScript can be quite controversial, but also quite effective.</p><p>On the controversial side, it uses significant whitespace to denote blocks of code (like Python or Haskell) rather than curl braces (like Java, JavaScript, or Ruby). In fact, it draws influences from a wide rage of other languages, incorporating many functional programming features, a rudimentary class system, string interpolation, destructuring assignment, and more.</p><p>However, for all that, it is very close to JavaScript; it simply rounds out many of the rough edges of JavaScript (and adds a few of its own). As wide ranging as C
 offeeScript syntax can be, there's generally a very close mapping from CoffeeScript to JavaScript.</p><p>CoffeeScript code often approaches Python's goal of being a "executable psuedo-code"; code that looks like a placeholder that will actually run. Some people find it more pleasant to read than JavaScript ... more&#160;<em>essence</em> and less&#160;<em>ceremony</em>.</p><p>You can still write bad code in CoffeeScript. You can write bad code in any language.</p></div>
       </div>
 
       <div class="clearer"></div>