<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>agimatec &#187; YUI</title>
	<atom:link href="http://www.agimatec.de/blog/tag/yui/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.agimatec.de/blog</link>
	<description>Clash of realities</description>
	<lastBuildDate>Tue, 22 Dec 2009 16:50:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Javascript Unit Tests with the YUI TestManager</title>
		<link>http://www.agimatec.de/blog/2009/01/javascript-unit-tests-with-the-yui-testmanager/</link>
		<comments>http://www.agimatec.de/blog/2009/01/javascript-unit-tests-with-the-yui-testmanager/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 14:02:30 +0000</pubDate>
		<dc:creator>Simon Tiffert</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[Test]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=473</guid>
		<description><![CDATA[Testing your Javascript is very important. Especially when the amount of code is growing and growing. The easiest method are unit tests. We have tried several JS unit test frameworks. Including JSUnit, Scriptaculous Unit Test Runner and YUI test. With a lot of YUI components like the YUI Loader and many YUI widgets we refactored [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-474" href="http://www.agimatec.de/blog/2009/01/javascript-unit-tests-with-the-yui-testmanager/steps-2/"><img class="alignleft size-full wp-image-474" title="steps" src="http://www.agimatec.de/blog/wp-content/uploads/2009/01/steps.jpg" alt="steps" width="425" height="282" /></a>Testing your Javascript is very important. Especially when the amount of code is growing and growing.</p>
<p>The easiest method are unit tests. We have tried several JS unit test frameworks. Including JSUnit, Scriptaculous Unit Test Runner and YUI test. With a lot of YUI components like the <a href="http://www.agimatec.de/blog/2009/01/using-yui-to-load-your-javascript-modules/">YUI Loader</a> and many <a href="http://developer.yahoo.com/yui/">YUI widgets</a> we refactored our unit tests to use YUI Test. We like the Yahoo User Interface because of its documentation and also of its code quality.</p>
<p>YUI Test is not bundled with YUI. You can use it with YUI but we also use other frameworks like Prototype and DWR. To learn more about YUI Test you can <a href="http://developer.yahoo.com/yui/yuitest/">watch the presentation of Nicholas C. Zakas</a>.</p>
<p>Ok, this is great, now I can test my Javascript. But wait, what is if I have a lot of Javascript. I can group my tests in test cases and test cases in test suites. This is supported. But while the amount of Javascript is growing one file for all tests isn&#8217;t enough. We have a lot of different modules. Each consists of a lot of test cases. Sure, you can copy them all together in a file which is several thousand lines long. But every test run takes then a lot of time, debugging is more complex and it is more complicated to manage this file.</p>
<p><span id="more-473"></span></p>
<h2>YUI TestManager</h2>
<p>Wouldn&#8217;t it be great to have a test runner. A script which takes a lot of unit test files and run them one after another.  Our first approach was based on the Scriptaculous Unit Test Runner embedded in a frameset. We had a navigation frame and some Javascript included to run one unit test file in the main frame. One problem was to collect the results of all unit test files. We patched the Unit Test Runner and collected the data. It was ok and I wanted to refactor the solution to publish it. After starting I suddenly found an undocumented feature of YUI Test &#8211; The <a href="http://developer.yahoo.com/yui/docs/YAHOO.tool.TestManager.html">YUI TestManager</a>. It is exactly what I wanted to do, define the unit test files, run through all of them and collect the results. I think Yahoo is using this feature internally and didn&#8217;t talk a lot about it. But it is included in the <a href="http://developer.yahoo.com/yui/docs/YAHOO.tool.TestManager.html">API</a>, so please YUI team, include it to the documentation. It is a great piece of code.</p>
<h2>Continuous Integration of Javascript with Selenium</h2>
<p>Before I will show you how to use it, some more thoughts about this. We are coming from the agile Java world. So continuous integration is very important for us. Please search for &#8220;Continuous Integration Javascript&#8221; in your search machine. There are just a few hits and no ready to use solution. Yes, you can try to go back to the Java world and run tests with Rhino. There are some Java based unit test frameworks for Javascript. But there are two downsides. You are leaving the Javascript world and you are leaving the browser. It can be ok for you but I don&#8217;t trust the different browsers. I want to be able to run the tests fast in the browser when I&#8217;m developing and I want to test as many browsers as I can. We searched for a solution and what we have running is a suite of Selenium tests. They are at another level. Functional tests which run through use cases in the web frontend. But if we could give them a result of our unit tests we are able to include this in our setup. Then we can run the unit tests in IE, Firefox and Opera automatically.</p>
<p>YUI Test gives you the logger to view the results of your tests. It is not the best view for test results but it is ok. Also there are a lot of events which include the results of the tests after running them. We have implemented a little script which displays a nice summary which we test with Selenium.</p>
<h2>Source code</h2>
<p>Now let&#8217;s head to the source code.</p>
<p>At the beginning we need a unit test. Because I&#8217;m want to concentrate on the TestManager you will find a very very simple test.</p>
<pre name="code" class="javascript">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
&lt;head&gt;
    &lt;title&gt;String test&lt;/title&gt;

    &lt;!--CSS--&gt;
	&lt;link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.6.0/build/logger/assets/logger.css"&gt;
	&lt;link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.6.0/build/yuitest/assets/testlogger.css"&gt;

	&lt;!-- Dependencies --&gt;
	&lt;script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/yahoo-dom-event/yahoo-dom-event.js"&gt;&lt;/script&gt;
	&lt;script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/logger/logger-min.js"&gt;&lt;/script&gt;

	&lt;!-- Source File --&gt;
	&lt;script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/yuitest/yuitest-min.js"&gt;&lt;/script&gt;

    &lt;script type="text/javascript"&gt;
    YAHOO.tool.TestRunner.add(new YAHOO.tool.TestCase({

        name: "String test",

        testEqualityAsserts : function () {
            var Assert = YAHOO.util.Assert;

            Assert.areEqual("hel"+"lo", "hello");     //passes
            Assert.areEqual("YUI test".substr(0,3), "YUI");     //passes
        }
    }));

    YAHOO.util.Event.onDOMReady(function (){

	    if (parent &#038;&#038; parent.TestManager) {
            parent.TestManager.load();
        }
        else {
            var logger = new YAHOO.tool.TestLogger();

            //run the tests
            YAHOO.tool.TestRunner.run();
        }
  	});
  	&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>In the first part we define our tests. In the second part you will see that the test will be called after the DOM is ready. It is a little bit different from the normal examples, because we call <em>parent.TestManager.load()</em> if it is available. Now you can copy this code, write your own tests, define test suites, &#8230; It starts to get interesting, if you have so many tests, that you want to group them into different files. With the code above you can go ahead and  create multiple tests. In the example code I have created to test files calcTest.html and stringTest.html.</p>
<p>To run all tests in all your test files you need to call the TestManager:</p>
<pre name="code" class="html">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
&lt;head&gt;
    &lt;title&gt;JS Unit Tests&lt;/title&gt;
    &lt;meta http-equiv="content-type" content="text/html; charset=utf-8"/&gt;

    &lt;!--CSS--&gt;
    &lt;link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.6.0/build/logger/assets/logger.css"&gt;
    &lt;link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.6.0/build/yuitest/assets/testlogger.css"&gt;

    &lt;!-- Dependencies --&gt;
    &lt;script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/yahoo-dom-event/yahoo-dom-event.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/logger/logger-min.js"&gt;&lt;/script&gt;

    &lt;!-- Source File --&gt;
    &lt;script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/yuitest/yuitest-min.js"&gt;&lt;/script&gt;

    &lt;!-- Source file --&gt;
    &lt;script type="text/javascript"&gt;
    	var TestManager = YAHOO.tool.TestManager;

        TestManager.setPages([
            "./stringTest.html",
            "./calcTest.html"
            ]);

        YAHOO.util.Event.onDOMReady(function() {
        	TestManager.start();
        });
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;h1&gt;JS Unit Tests&lt;/h1&gt;

&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>That&#8217;s simple, isn&#8217;t it?</p>
<p>That will give you the following output:<br />
<img src="http://www.agimatec.de/blog/wp-content/uploads/2009/01/logger.png" alt="logger" title="logger" width="656" height="303" class="alignnone size-full wp-image-491" /></p>
<p>We wanted to give it more the feeling of a unit test suite. As I told you there is an event after test completion, which includes the test results. With our script we are building a summary table which gives you a nice overview for your test results.<br />
<img src="http://www.agimatec.de/blog/wp-content/uploads/2009/01/testrunner.png" alt="testrunner" title="testrunner" width="713" height="502" class="alignnone size-full wp-image-492" /></p>
<p>With the overview table we also can track the results with a simple Selenium test:</p>
<pre name="code" class="java">
package com.agimatec.ostium.portlets.jsunit;

import com.agimatec.ostium.portlets.util.ScreenshottingSelenium;
import com.thoughtworks.selenium.Selenium;
import org.testng.Assert;
import org.testng.Reporter;
import org.testng.annotations.*;

public class JsUnitTest {
    Selenium selenium;

    @BeforeMethod
    @Parameters({"selenium.host", "selenium.port", "browser", "baseUrl", "ostium.login",
            "ostium.password"})
    public void startSelenium(
            @Optional("localhost")String host,
            @Optional("4444")int port,
            @Optional("*firefox")String browser,
            @Optional("http://localhost:8080")String baseUrl
    ) throws Exception {
        Reporter.log("Running selenium");
        selenium = new ScreenshottingSelenium(host, port, browser, baseUrl);
        selenium.start();
    }

    @Test
    public void checkPassedJsUnitTests() throws InterruptedException {
        selenium.open("/portlets/ostium/utilities/ajf/src/test/javascript/testrunner.html");
        for (int second = 0; ; second++) {
            if (second >= 60) Assert.fail("timeout");
            try {
                if (selenium.isElementPresent("//div[@id='testcontainer']/div/h2")) break;
            } catch (Exception e) {
            }
            Thread.sleep(1000);
        }

        Assert.assertTrue(
                selenium.isTextPresent("exact:Result: Passed"),
                "The result of the JS tests should be 'PASSED'.");
    }

    @AfterMethod
    public void stopSelenium() {
        Reporter.log("Stopping selenium");
        selenium.stop();
    }
}
</pre>
<p>The only thing to do is to run the files on a local server. We use a Jetty with Maven to host the files because Selenium needs to include a proxy which didn&#8217;t work if you access the file directly. </p>
<p>Find more to Selenium on our other posts:</p>
<ul>
<li><a href="http://www.agimatec.de/blog/2008/08/selenium-testing-of-massive-ajax-apps/">Selenium testing of massive Ajax Apps</a></li>
<li><a href="http://www.agimatec.de/blog/2008/07/selenium-ci-tests-with-teamcity/">Selenium CI tests with TeamCity</a></li>
<li><a href="http://www.agimatec.de/blog/2008/07/robust-portlet-testing/">Robust portlet testing</a></li>
</ul>
<p><a href='http://www.agimatec.de/blog/wp-content/uploads/2009/01/yuitestmanager.zip'>Download the script and some examples here.</a> We are planning to release it with some other JS stuff as a Google code project, but we are still searching for a name. </p>
<p>If this post was helpful or you have additional ideas, please don&#8217;t hesitate to comment. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2009/01/javascript-unit-tests-with-the-yui-testmanager/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Using YUI to load your Javascript modules</title>
		<link>http://www.agimatec.de/blog/2009/01/using-yui-to-load-your-javascript-modules/</link>
		<comments>http://www.agimatec.de/blog/2009/01/using-yui-to-load-your-javascript-modules/#comments</comments>
		<pubDate>Mon, 19 Jan 2009 14:25:53 +0000</pubDate>
		<dc:creator>Sebastian Schuth</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Portlet]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=398</guid>
		<description><![CDATA[As promised earlier, i&#8217;ll discuss in this post how we load the Javascript modules we have written over the last months. Please note that despite i am mainly talking about portlets in this post, the technique described is also usable in web applications that need to load additional Javascript after page load. The setting Let [...]]]></description>
			<content:encoded><![CDATA[<p>As <a href="http://www.agimatec.de/blog/2008/10/advanced_javascript_namespaces_for_portlets/">promised earlier</a>, i&#8217;ll discuss in this post how we load the Javascript modules we have written over the last months. Please note that despite i am mainly talking about portlets in this post, the technique described is also usable in web applications that need to load additional Javascript after page load.</p>
<h1>The setting</h1>
<p>Let me explain the structure of our project a bit. The main constraint we are facing when developing rich user interfaces for the web platform is that we were up to do so using Java Portlets. Using the portlets standard (JSR-168), we are able to meet our customer&#8217;s needs in a way we never could have done when developing traditional, monolithic web applications. But this flexibility comes at a price: we do not know which apps are on a page when it gets loaded; further, we want to be able to add new portlets to each page at any time. From a Javascript perspective, this means that traditional &#8220;just put script tags into the header&#8221;-style Javascript coding will lead to a very bad user experience, since every page would be bloated with stuff the user will never use and &#8211; even more important- the user experience will degrade as we are adding new features to our product, even if our customer does not need or want the new features. As explained before, adding Javascript code to HTML/JSP Parts of the Portlets were no option and would have caused massive double-loading of script code. As our platform grew, we saw the need to put together a Javascript library to support code reuse up front. We clearly needed a mechanism to load our Javascript modules as they are needed. After some experiments (including the use of unholy synchronous XHR calls&#8230; shame on me!), we tried the YUI Loader.</p>
<h1>Meet the YUI Loader Utility</h1>
<p>Its no secret that we are using YUI in our product. As YUI comes with a special module for loading dependencies, the YUI Loader Utility, we explored if we could use YUI for our needs. The Loader&#8217;s <a href="http://developer.yahoo.com/yui/yuiloader/">feature list</a> reads like our wish-list:</p>
<ul>
<li>Reliable, sorted loading of dependencies</li>
<li>Safe, efficient mechanism for adding new components to a page on which YUI may already be present.</li>
<li>Automatic use of rolled-up files.</li>
</ul>
<p>So we&#8217;ve developed our own solution on top of the YUI loader for our Framework. It consists of two components: A Compile-time dependency analyzer and a configuration file generated by the dependency analyzer that tells YUI how to load our modules.</p>
<h1>Analyzing JS dependencies</h1>
<p>First of all, every JS module file starts with a set of comments telling the dependency analyzer how the current module is called and what modules are required by the declared module:</p>
<pre class="js">// @@module agimatec.topic
// @@requires event, agimatec.datatypes

// Module code goes here
// ...
// ...
// ...
// ...
// ...

// Tell the loader that this module has been loaded
YAHOO.register("agimatec.topic", agimatec.topic, {version:'1.0',build:'000'});</pre>
<p>The analyzer (which is current implemented as stand-alone groovy script that is run by maven &#8211; we have plans to implement it as maven Mojo) parses the dependency information in the module files and generates a Javascript configuration file for the YUI loader from it:</p>
<pre class="js">// ******************************
// Generated Code - DO NOT EDIT
// ******************************
/*
  This script adds all AJF module definitions to the YUI Loader utility as noted by
  '// @@' - style comments inside the *.js files.
  If the global variable 'agimatec_config' is not defined, it is defined by this script.
*/
(function(){
    var arrModules =[

            //...

            {
             name:'agimatec.scaffolding',
             type:'js',
             skinnable:false,
             path: '../../agimatec/scaffolding-2.1.11-SNAPSHOT-min.js',
             requires:["yahoo","event","calendar","tabview","agimatec.topic","agimatec.util","agimatec.util.table","agimatec.util.element","agimatec.util.minibrowser","agimatec.util.datePicker","agimatec.util.hintedText","agimatec.validator","agimatec.metadata"]},

            {
             name:'agimatec.topic',
             type:'js',
             skinnable:false,
             path: '../../agimatec/topic-2.1.11-SNAPSHOT-min.js',
             requires:["event","agimatec.datatypes"]},

            {
             name:'agimatec.util.browser',
             type:'js',
             skinnable:false,
             path: '../../agimatec/util/browser-2.1.11-SNAPSHOT-min.js',
             requires:["yahoo","dom","event","animation","datatable","agimatec.topic","agimatec.util","agimatec.util.yui","agimatec.util.lucene","agimatec.util.element","agimatec.preferences"]},

            {
             name:'agimatec.util.connector',
             type:'js',
             skinnable:false,
             path: '../../agimatec/util/connector-2.1.11-SNAPSHOT-min.js',
             requires:["yahoo","dom","event","container","datatable","agimatec.util","agimatec.metadata","agimatec.util.table","agimatec.portletservice","agimatec.util.minibrowser"]},

            {
             name:'agimatec.util.context',
             type:'js',
             skinnable:false,
             path: '../../agimatec/util/context-2.1.11-SNAPSHOT-min.js',
             requires:["agimatec.metadata","agimatec.util"]},

            {
             name:'agimatec.util.datePicker',
             type:'js',
             skinnable:false,
             path: '../../agimatec/util/datePicker-2.1.11-SNAPSHOT-min.js',
             requires:["yahoo","dom","event","agimatec.util","agimatec.util.hintedText"]},

		 // ...
    ];

    agimatec_config = agimatec_config || {};
    agimatec_config._modules = arrModules;
    agimatec_config.getLoader = function(){
        var modulesLength=agimatec_config._modules.length, i;
        var configObject = {};
        configObject.base = agimatec_config.yuiBasePath;
        if(agimatec_config.moduleFilter){
            configObject.filter=agimatec_config.moduleFilter;
        }
        if(undefined !== agimatec_config.allowRollup){
            configObject.allowRollup = agimatec_config.allowRollup;
        }
        // configure the default skin
        configObject.skin = {
            'defaultSkin':agimatec_config.defaultSkinName,
            'base': 'assets/skins/',
            'path': 'skin.css',
            'rollup': 3
        };
        var loader = new YAHOO.util.YUILoader(configObject);
        for(i=0; i</pre>
<p>This file is included inside the header of every portlet page. You see that thanks to the YUI Loader, we can mix YUI modules with our own ones without hassle, making development of a comprehensive Javascript Library much easier. (If your wondering why we add version numbers to the referenced module names, <a href="http://www.agimatec.de/blog/2008/07/cache-refresh/">see this article</a>)</p>
<p>Loading a module is as easy as:</p>
<pre class="js">// ...

var loader = agimatec_config.getLoader()
loader.require("agimatec.topic");
loader.insert(function(){
	// use agimatec.topic and ALL of its dependencies here !!!!
});</pre>
<p>You see that using modules is very easy. All you have to do is to tell the loader what you need and provide a function that should get executed as soon as the dependencies are resolved by adding the noted Javascript files.<br />
This solution served us very well in the last months, in fact our complete webapp development depends on this loading mechanism. It made growing a stable and feature-rich javascript library possible for us without destroying the user experience.</p>
<p>This post just scratches the features of our Javascript module tooling. We have also added support for a module description file format that allows us to describe Javascript modules using XML and generate the loading and dependency management code, along with support for &#8220;rollup&#8221; JS modules that allow us to reduce the number of requests needed to load portal pages.</p>
<p>If you are interested in this component, just tell us so in the comments and we will see how fast we can get this utility out of the door as Open Source.</p>
<p>This is part two of an article series about Ajax Portlet development. In my next post, i will tell you about how we handle inter-portlet communication in our framework and how our approach makes our application extremely flexible without hardcoding dependencies between portlets.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2009/01/using-yui-to-load-your-javascript-modules/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Advanced Javascript Namespaces for Portlets</title>
		<link>http://www.agimatec.de/blog/2008/10/advanced_javascript_namespaces_for_portlets/</link>
		<comments>http://www.agimatec.de/blog/2008/10/advanced_javascript_namespaces_for_portlets/#comments</comments>
		<pubDate>Tue, 28 Oct 2008 15:06:00 +0000</pubDate>
		<dc:creator>Sebastian Schuth</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Portlet]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=311</guid>
		<description><![CDATA[As mentioned earlier, we are doing some heavily ajaxified portlets over here at agimatec. When we switched to this Javascript-Centric Portlets, we had to solve a problem more people tend to have: The fundamental flaw of Javascript to depend on global variables for linking and the resulting clash of function names we wrote for our [...]]]></description>
			<content:encoded><![CDATA[<p id="mdq_"><a href="http://www.agimatec.de/blog/2008/08/selenium-testing-of-massive-ajax-apps/">As mentioned earlier</a>, we are doing some heavily <span id="tcls" class="misspell">ajaxified</span> portlets over here at agimatec. When we switched to this Javascript-Centric Portlets, we had to solve a problem more people tend to have: The fundamental flaw of Javascript to depend on global variables for linking and the resulting clash of function names we wrote for our portlets. There is a wildly-published way to handle this, which is not suitable when writing more than a few Javascript functions, and the way we handle this problem. But let&#8217;s start with a description of the commonly advised way of handling this problem and how that way falls short when doing serious Javascript in portlets.</p>
<h1 id="mdq_1">The easy way</h1>
<p id="mdq_2">When consulting the portlet books on the market or <a href="http://developers.sun.com/portalserver/reference/techart/ajax-portlets.html">Sun&#8217;s own tips</a>, you&#8217; gonna find one easy solution to the problem: using the portlet namespace for your Javascript. The portlet namespace is a portlet-instance specific string that is suitable to identify assets of a portlet instance. So the easy way out is to use it as prefix or post fix for the functions you write:</p>
<pre class="js" name="code">
&lt;!-- Example: JSP page --&gt;
&lt;%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %&gt;
<!-- ... -->
<script type="text/javascript">
    function doTerriblyUsefulStuff_
<portlet:namespace/>(){
        // your logic here
    }
</script>
<!-- ... -->
</pre>
<p id="mdq_4">Wow, that was easy. But there are some drawback when doing this:</p>
<ul id="mdq_5">
<li id="mdq_6">you have to stick to define your Javascript inside the portlets &#8211; no external Javascript files!</li>
<li id="mdq_7">being unable to define external Javascript files, there is no easy way of sharing Javascript code between portlets, which is not <a id="mdq_8" title="DRY" href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself" target="_blank">DRY</a></li>
<li id="mdq_9">Debugging gets even more painful with function names like &#8220;show_&lt;insert some lengthy string here&gt;()&#8221;</li>
</ul>
<p id="mdq_10">So, if your are up to make heavy use of Javascript and Ajax-based rich user interfaces, this is a <b>no-go</b>.</p>
<h1 id="mdq_11">Using external Javascript files</h1>
<p id="mdq_12">So, loading Javascript form external file is the way to go. So here is our approach to the problem:</p>
<h2 id="mdq_13">Use Javascript <span id="tcls4" class="misspell">namespaces</span></h2>
<p id="mdq_14">We are putting all our stuff into one global variable, called &#8220;agimatec&#8221; (at the time we chose the name, we were not aware of <a href="http://www.crockford.com/">Douglas Crockford</a>&#8216;s advice on making globals uppercase &#8211; otherwise we would haven named it &#8220;AGIMATEC&#8221;). This ensures that we&#8217;re leaving all third party scripts on the page untouched. Each portlet has its own (sub-)namespace inside this global.</p>
<h2 id="mdq_15">Use a convention to locate the script files</h2>
<p id="mdq_16">We&#8217;re putting our javascript files into a java-like folder structure that reflects our namespace structure, so the portlet &#8220;<span id="tcls5" class="misspell">Clientis</span> Edit User&#8221; is put into the namespace &#8220;agimatec.portlet&#8221; and the corresponding file can be found under &#8220;agimatec/portlet/clientisEditUser.js&#8221;</p>
<h2 id="mdq_17">Use a common initialization method for all portlets</h2>
<p id="mdq_18">All our portlet scripts must define the function &#8220;<span id="tcls9" class="misspell">getPortlet</span>()&#8221;, which returns a &#8220;raw&#8221; version of the portlet script.</p>
<h2 id="mdq_19">Let a library create portlet script objects</h2>
<p id="mdq_20">Last but definitely not least we have written our own library to create portlet instances. The library contains a function that takes the portlet namespace string, along with the name of the portlet Javascript object, creates a new instance by calling &#8220;<span id="tcls10" class="misspell">getPortlet</span>()&#8221; on the Portlet object and puts the instance into its own namespace which is created using the portlet namespace:</p>
<pre class="js" name="code">
/**
* Create a portlet namespace instance.
* @param {object} portletObject           A raw portlet namespace
* @param {string} portletNamespace    The Portlet ID as given by the portlet container
*/
agimatec.createPortletInstance(portletObject, portletNamespaceId){
    var rawNamespace = portletObject.getPortlet();
    portletObject[portletNamespaceId] = rawNamespace;
}</pre>
<p id="mdq_23">Using this technique, we are able to write clean, fully namespace-wrapped portlet scripts that have no problems with colliding function names and can co-exist even in multiple instances on one page without problems. As bonus, two instances of the same portlet on one page only load the external Javascript file once.</p>
<p>One major thing is not mentioned of this post: how to load the portlet scripts. We are using the <a href="http://developer.yahoo.com/yui/yuiloader/">YUI Loader</a> for loading the portlet scripts, amoung other things. I&#8217;ll cover this in another post in the next weeks, so stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/10/advanced_javascript_namespaces_for_portlets/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>YUI 2.5.2 released</title>
		<link>http://www.agimatec.de/blog/2008/05/yui-252-released/</link>
		<comments>http://www.agimatec.de/blog/2008/05/yui-252-released/#comments</comments>
		<pubDate>Thu, 29 May 2008 06:39:35 +0000</pubDate>
		<dc:creator>Simon Tiffert</dc:creator>
				<category><![CDATA[Deutsch]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=160</guid>
		<description><![CDATA[Als große YUI-Fans verfolgen wir die Entwicklung immer sehr gespannt und versuchen auf dem aktuellen Versionsstand zu bleiben. Aktuell stehen wir auf der Version 2.5.1 und werden dann wohl in Kürze auch auf YUI 2.5.2 umsteigen. Gerade der A-Grade Support der neuen Browser Firefox 3 und Opera 9.5 ist interessant, da diese einen großen Schritt [...]]]></description>
			<content:encoded><![CDATA[<p>Als große YUI-Fans verfolgen wir die Entwicklung immer sehr gespannt und versuchen auf dem aktuellen Versionsstand zu bleiben. Aktuell stehen wir auf der Version 2.5.1 und werden dann wohl in Kürze auch auf <a href="http://yuiblog.com/blog/2008/05/28/yui-252/">YUI 2.5.2</a> umsteigen. </p>
<p>Gerade der A-Grade Support der neuen Browser Firefox 3 und Opera  9.5 ist interessant, da diese einen großen Schritt nach vorne in der Browser-Performance liefern. Wer also überlegt sein DSL von ADSL 1000 auf ADSL 6000 aufzustocken, sollte erst einmal die neueste Generation der Browser antesten, die bald auch in finalen Versionen erscheinen werden.</p>
<p>Links:</p>
<ul>
<li><a href="http://developer.yahoo.com/yui/">YUI</a></li>
<li><a href="http://yuiblog.com/blog/2008/05/28/yui-252/">Announcement 2.5.2</a></li>
<li><a href="http://tech.groups.yahoo.com/group/ydn-javascript/message/31724">Changelog 2.5.2</a></li>
<li><a href="http://sourceforge.net/project/downloading.php?group_id=165715&#038;filename=yui_2.5.2.zip">Download</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/05/yui-252-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Schritt für Schritt zur schnelleren Web-Anwendung</title>
		<link>http://www.agimatec.de/blog/2008/05/schritt-fur-schritt-zur-schnelleren-web-anwendung/</link>
		<comments>http://www.agimatec.de/blog/2008/05/schritt-fur-schritt-zur-schnelleren-web-anwendung/#comments</comments>
		<pubDate>Tue, 20 May 2008 05:08:03 +0000</pubDate>
		<dc:creator>Simon Tiffert</dc:creator>
				<category><![CDATA[Deutsch]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=119</guid>
		<description><![CDATA[Große Web-Anwendungen haben ein Problem. Sie werden immer größer und damit langsamer, wenn man nicht regelmäßig optimiert. Dabei ist die Optimierung nicht ein Schalter den man auf optimization=true stellt. Optimierung ist ein nahezu dauerhafter Prozess den man Stufe für Stufe erklimmt und regelmäßig überprüfen muss. Diese Woche war es mal wieder soweit und der Code [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft alignnone size-medium wp-image-120" style="float: left;" title="steps" src="http://www.agimatec.de/blog/wp-content/uploads/2008/05/steps.jpg" alt="" width="300" height="199" />Große Web-Anwendungen haben ein Problem. Sie werden immer größer und damit langsamer, wenn man nicht regelmäßig optimiert. Dabei ist die Optimierung nicht ein Schalter den man auf <strong>optimization=true</strong> stellt. Optimierung ist ein nahezu dauerhafter Prozess den man Stufe für Stufe erklimmt und regelmäßig überprüfen muss.</p>
<p>Diese Woche war es mal wieder soweit und der Code kam unter die Lupe. Die Lupe stellen in diesem Fall folgende Tools dar:</p>
<ul>
<li><a href="http://www.getfirebug.com">Firebug</a> im Reiter Net zur Ansicht aller Dateien, die zu einer Webseite gehören</li>
<li><a href="http://developer.yahoo.com/yslow/">YSlow</a> zur einfachen Analyse der Schwachstellen</li>
<li><a href="http://livehttpheaders.mozdev.org/">Live HTTP Headers</a> zur Analyse der einzelnen Requests</li>
<li><a href="http://www.httpdebugger.com/">HttpDebugger</a> bzw. <a href="http://www.fiddlertool.com/fiddler/">Fiddler</a> als Proxy zur übersichtlichen Analyse der Requests</li>
</ul>
<p>Was man sich klar machen sollte ist, dass das HTML nur einen Bruchteil der Zeit benötigt. Bilder, CSS, Javascript und eventuell weitere Medientypen benötigen den Großteil der Zeit. Sicherlich sollte man sauberes XHTML ausliefern, dass auf ein Minimum an DOM-Knoten reduziert ist, aber in einer riesigen Ajax-Anwendung mit Javascript-Widgets und vielen Effekten ist dies schon fast zu vernachlässigen. Da wir ein Portal mit Portlets einsetzen, haben wir eine weitere Herausforderung, da wir modulare Komponenten einsetzen. Diese sollen im Idealfall nur das enthalten, was sie benötigen, aber soviel zusammenfassen, dass keine Teile redundant vorhanden sind. Hier hat schon regelmäßig ein Refactoring stattgefunden, um gemeinsame Teile aus einer zentralen Stelle zur Verfügung zu stellen. Andererseits ist der Fundus an Portlets so groß, dass nicht alle Teile immer geladen werden sollten.</p>
<p><span id="more-119"></span></p>
<p>Schon bei einer vorherigen Analyse war aufgefallen, dass der Anteil an Javascript-Dateien einen Großteil der Requests ausmacht. Der Einsatz von YUI trägt hier auch seine Last bei, da die Hauptkomponenten ebenfalls modular zusammengesetzt werden und Datasource, Datatable, Tabs, &#8230; in eigenen Dateien liegen. Die Rollups über den YUI Loader verbessern die Anzahl der Requests, aber eine Grundlast bleibt erhalten. Der andere Teil ist unser Javascript-Framework, welches von Tag zu Tag anwächst und dessen Zusammenfassung zu einem Rollup eine beträchtliche Reduktion an Requests mit sich gebracht hat. Über den Build mit Maven haben wir an dieser Stelle einige Tools im Einsatz die schon im Vorfeld die Dateien kombinieren und die YUI Loader Konfiguration automatisch erstellen. Das Minifying der Javascript-Dateien hat den schönen Effekt, dass dies optional über den YUI Loader konfiguriert werden kann und somit immer noch ein vernünftiges Debugging möglich ist. Zudem ist die Lesbarkeit erhöht und ein ausführliches JSDoc kann gepflegt werden, ohne die Dateigröße in der Produktion zu beeinflussen.</p>
<p>Nachdem im Code somit viel Optimiert wurde, kann man sich noch anschauen, was der Server für einen Leisten kann. Hier spielt vorallem das Caching im Browser und die Auslieferung der Dateien eine große Rolle. Sowohl Tomcat-Standalone als auch ein Apache im Single-Mode oder über einen mit AJP-verbundenen Tomcat können sehr einfach dazu gebracht werden, komprimierte Dateien zum Browser zu senden. Kaum zu glauben, wie einfach diese Stufe erklommen werden kann, sind doch erhebliche Größeneinsparungen von teilweise 70% einfach möglich. Ob der Browser GZip unterstützt teilt er bei seiner Anfrage im HTTP-Request mit. Auch ein Grund, warum oben genannte Tools so wichtig sind. Viele serverseitige Optimierungen arbeiten im Header-Teil des Protokolls und ein auslesen der Information ist im Browser oft nicht oder nur umständlich möglich.</p>
<p>Die Komprimierung wird im Tomcat wie folgt aktiviert. In der Datei server.xml werden dem Connector auf Port 8080 folgende Attribute mitgegeben:</p>
<p><em>compression=&#8221;on&#8221;<br />
compressionMinSize=&#8221;512&#8243;<br />
noCompressionUserAgents=&#8221;gozilla, traviata&#8221;<br />
compressableMimeType=&#8221;text/html,text/xml,text/css,text/javascript,application/x-javascript,application/javascript&#8221;<br />
</em></p>
<p>Wichtig ist, dass z.B. Bilder nicht mehr komprimiert werden, da sie bereits komprimiert (JPG, PNG, GIF) vorliegen sollten und die Resourcen zum Packen und Entpacken unnötig verschwendet werden würden.</p>
<p>Will man im Apache2 die Komprimierung aktivieren, so ist dafür das Modul <strong>mod_deflate</strong> zuständig. Dieses muss aktiviert werden und kann mit ähnlichen Konfigurationen wie im Tomcat an die Bedürfnisse angepasst werden. Diese kleine Änderung mit großer Auswirkung sollte auf keinen Fall ungenutzt bleiben, führte sie bei uns zu Verkleinerung von 2/3 des gesamten Downloads.</p>
<p>Ein weiterer wichtiger Punkt ist der richtige Support des Browserscaches. Nur ein Teil der Informationen sollte bei einem erneuten Aufruf der Webseite notwendig sein. Dass CSS, Javascript und Bilder ändern sich normalerweise nicht und sind z.T. auch auf mehreren Seiten vorhanden. Hier sollte mit einem Expire-Header weit in der Zukunft dafür gesorgt werden, dass kein Request mehr zum Server stattfindet. Wird dieser Header nicht gesetzt, so findet zumindest ein Request statt, der überprüft, ob sich die Datei serverseitig geändert hat. Sind auf der Seite viele kleine Dateien so kann dies sehr zeitintensiv sein, da normalerweise nur zwei parallele Requests durchgeführt werden. Um den Expire-Header richtig zu setzen kann man z.B. das Modul mod_expire für den Apache2 einsetzen und für alle geeigneten Datentypen konfigurieren. Bei Bildern ist dies sehr gebräuchlich, aber auch CSS, Javascript und andere Medientypen sollten den Expire-Header explizit gesetzt bekommen.</p>
<p>Das Thema könnte man noch weiter ausführen und das Ende der Treppe ist für uns noch lange nicht erreicht. Mit etwas Beschäftigung mit der Materie kann man aber bereits große Fortschritte erzielen, die für sich und den Kunden enorme Vorteile bieten.</p>
<p>Als Literatur sei hier vorallem das Buch <a href="http://www.oreilly.de/catalog/hpwebsitesger/index.html">High Performance Web Sites</a> von <a href="http://stevesouders.com/">Steve Souders</a> zu empfehlen. Er arbeitete bei Yahoo in einem Team, welches sich nur um die Optimierung der Webseiten kümmert. Ein Dank an Yahoos Feedback über ihre Erfahrungen, die auch <a href="http://developer.yahoo.com/performance/">hier</a> zu finden sind.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/05/schritt-fur-schritt-zur-schnelleren-web-anwendung/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>YUI Compressor</title>
		<link>http://www.agimatec.de/blog/2008/04/yui-compressor/</link>
		<comments>http://www.agimatec.de/blog/2008/04/yui-compressor/#comments</comments>
		<pubDate>Mon, 21 Apr 2008 20:43:02 +0000</pubDate>
		<dc:creator>Simon Tiffert</dc:creator>
				<category><![CDATA[Deutsch]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=75</guid>
		<description><![CDATA[Die Dateigröße und die Anzahl der Requests sind gerade im Webbereich ein großes Problem. Allerdings will und sollte man nicht auf eine vernünftige Formatierung und Kommentare im Quellcode verzichten. Abhilfe schafft hier der YUI Kompressor. Dieser ist in Java geschrieben und basiert auf der Javascript-Engine Rhino. Dadurch ist es ihm möglich den Quellcode tiefer zu [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.agimatec.de/blog/wp-content/uploads/2008/04/50.jpg"><img class="alignleft size-medium wp-image-79" style="float: left;" title="Sale tag #3" src="http://www.agimatec.de/blog/wp-content/uploads/2008/04/50.jpg" alt="" width="300" height="187" /></a>Die Dateigröße und die Anzahl der Requests sind gerade im Webbereich ein großes Problem. Allerdings will und sollte man nicht auf eine vernünftige Formatierung und Kommentare im Quellcode verzichten. Abhilfe schafft hier der <a href="http://developer.yahoo.com/yui/compressor/">YUI Kompressor</a>.  Dieser ist in Java geschrieben und  basiert auf der Javascript-Engine Rhino.  Dadurch ist es ihm möglich den Quellcode tiefer zu analysieren und unter anderem die Variablennamen zu ersetzen. Natürlich werden Kommentare und unnötige Leerzeichen auch entfernt, was insgesamt zu einer drastisch reduzierten Größte der Datei führt.</p>
<p>Neben der Komprimierung von Javascript-Dateien beherrscht der YUI Compressor auch die Kompression von CSS-Dateien. Hier werden auch Kommentare, Leerzeichen und Zeilenumbrüche entfernt, sodass die Größe der zu übertragenden Datei deutlich schrumpft.</p>
<p><span id="more-75"></span></p>
<p><strong>Wie verwendet man diese Tools?</strong></p>
<p>Die Komprimierung sollte die orginale Datei keinesfalls ersetzen. Das Orginal ist notwendig für Dokumentation (JsDoc), Debugging und Lesbarkeit. Somit benötigt man eine automatische Generierung dieser Dateien, wenn es zum Deployment geht.</p>
<p>Da wir Maven2 als allumfassendes Buildtool einsetzen, haben wir hierfür eine Lösung gesucht und gefunden. Das <a id="bannerLeft" href="http://alchim.sourceforge.net/yuicompressor-maven-plugin/overview.html">YUI Compressor Maven Plugin</a> von <a href="http://sourceforge.net/projects/alchim">sourceforge.net/projects/alchim</a> bietet die Möglichkeit das Minifying automatisch auf den Sourcen auszuführen und diese gepackt als min-Version in dem Target-Ordner abzulegen.</p>
<p>Das Plugin wird wie folgt eingebunden:</p>
<pre name="code" class="xml">
&lt;project&gt;
...
  &lt;build&gt;
    &lt;plugins&gt;
...
      &lt;plugin&gt;
        &lt;groupId&gt;net.sf.alchim&lt;/groupId&gt;
        &lt;artifactId&gt;yuicompressor-maven-plugin&lt;/artifactId&gt;
        &lt;executions&gt;
          &lt;execution&gt;
            &lt;goals&gt;
              &lt;goal&gt;compress&lt;/goal&gt;
            &lt;/goals&gt;
          &lt;/execution&gt;
        &lt;/executions&gt;
      &lt;/plugin&gt;
...
    &lt;/plugins&gt;
  &lt;/build&gt;
...
&lt;/project&gt;</pre>
<p>Neben der Komprimierung bietet das Maven-Plugin auch die Möglichkeit der Aggregation von Dateien und zur Überprüfung der Javascript-Dateien mit JS-Lint. Mehr dazu im nächsten Post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/04/yui-compressor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
