<?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>Nerdpress.org &#187; JS</title>
	<atom:link href="http://nerdpress.org/category/js/feed/" rel="self" type="application/rss+xml" />
	<link>http://nerdpress.org</link>
	<description>Just another WordPress site</description>
	<lastBuildDate>Mon, 30 Jan 2012 14:28:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Sending invalid Unicode via socket.io</title>
		<link>http://nerdpress.org/2011/11/16/sending-invalid-unicode-via-socket-io/</link>
		<comments>http://nerdpress.org/2011/11/16/sending-invalid-unicode-via-socket-io/#comments</comments>
		<pubDate>Wed, 16 Nov 2011 14:48:54 +0000</pubDate>
		<dc:creator>Ivo Bathke</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[socket.io]]></category>

		<guid isPermaLink="false">http://nerdpress.org/?p=1971</guid>
		<description><![CDATA[Well you can try to, but it will end up almost probably in an disconnect which is caused by the browser. As i have learned here. Given you have a string which contains invalid unicode like: This will trouble the browser and the socket connection. If you prepare your json with PHP and  json_encode the [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>Well you can try to, but it will end up almost probably in an disconnect which is caused by the browser.<br />
As i have learned <a href="https://github.com/LearnBoost/socket.io/issues/572">here</a>.</p>
<p>Given you have a string which contains invalid unicode like:</p>
<p><a href="http://nerdpress.org/wp-content/uploads/2011/11/invalid_unicode.png" rel="lightbox[post-1971]" title=""><img class="alignnone size-medium wp-image-1976" src="http://nerdpress.org/wp-content/uploads/2011/11/invalid_unicode-300x29.png" alt="Invalid Unicode-300x29 in " width="300" height="29" /></a><br />
This will trouble the browser and the socket connection.</p>
<p>If you prepare your json with PHP and  <em>json_encode</em> the Unicode will be escaped to some strings like these:</p>
<p><code>\ud83d\ude31\ud83d\ude31\ud83d\ude04\ud83d\ude04\ud83d\udc9c\ud83d\udc9c\ud83d\udc4a</code></p>
<p>But on clientside it will still result in invalid Unicode.<br />
<span id="more-1971"></span></p>
<p>So after a lot of recherche i found <a href="http://stackoverflow.com/questions/410704/cyrillic-characters-in-phps-json-encode">this</a> and used the <em>decodeUnicodeString</em> function from Zend to convert the escaped Unicode characters again to their unescaped representation. (dont forget the replacement as described in the post at stackoverflow if you extract it from Zend)<br />
If the character is invalid it will be replaced by a question mark &#8216;?&#8217;.<br />
This is at least what i asume.<br />
The ? went through fine and the socket connection stays alive.</p>
<p>Ok the downside is you loose weird signs for an &#8216;?&#8217;, but i can live with that.<br />
But im not really convinced with that solution, so if anybody knows another way to detect invalid Unicode sequences, let me know!</p>
<div class="plus-one-wrap"><g:plusone href="http://nerdpress.org/2011/11/16/sending-invalid-unicode-via-socket-io/"></g:plusone></div>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://nerdpress.org/2011/11/16/sending-invalid-unicode-via-socket-io/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Symfony 2] AsseticBundle, Less CSS &amp; YUI Compressor unter OSX installieren</title>
		<link>http://nerdpress.org/2011/08/25/symfony-2-asseticbundle-less-css-yui-compressor-unter-osx-installieren/</link>
		<comments>http://nerdpress.org/2011/08/25/symfony-2-asseticbundle-less-css-yui-compressor-unter-osx-installieren/#comments</comments>
		<pubDate>Thu, 25 Aug 2011 16:55:02 +0000</pubDate>
		<dc:creator>Johannes Heinen</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Assetic]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[less]]></category>
		<category><![CDATA[symfony 2]]></category>
		<category><![CDATA[Twig]]></category>
		<category><![CDATA[yui-compressor]]></category>

		<guid isPermaLink="false">http://nerdpress.org/?p=1600</guid>
		<description><![CDATA[Less CSS und YUI-Compressor mit Assetic unter OSX installieren und innerhalb Symfony 2 konfigurieren.]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>Das AsseticBundle ist ein Wrapper um <a href="https://github.com/kriswallsmith/assetic">Assetic</a>, ein geniales Tool, um statische Assets für Webprojekte zu verwalten. AsseticBundle ist extrem einfach zu verwenden, einfach die entsprechende Filter-Chain via yaml konfigurieren, um mehr muss man sich nicht kümmern. Natürlich allerdings müssen die zugrundeliegenden Abhängigkeiten im Vorfeld installiert sein. In unserem Falle benötigen wir den <a href="http://developer.yahoo.com/yui/compressor/">Yui-Compressor</a> als jar-File und <a href="http://lesscss.org/">Less CSS</a>. Less ist ein <a href="http://nodejs.org/">node.js</a> Modul, was bedingt, dass wir zuvor node.js installieren müssen.<br />
<span id="more-1600"></span></p>
<p>Also node.js via macports holen:</p>
<pre class="brush: bash; title: ; notranslate">
$ sudo port install nodejs
</pre>
<p>Und den node.js-eigenen Package-Manager:</p>
<pre class="brush: bash; title: ; notranslate">
$ sudo port install npm
</pre>
<p>Mit diesem installieren wir als nächsts less, und zwar &#8220;global&#8221; (via -g)-Flag (&#8220;global&#8221; bedeutet, dass das Modul unter $nodejs_lib_path/../node_modules abgelegt wird, ansonsten wird es im aktuellen Arbeitsverzeichnis unter ./node_modules installiert):</p>
<pre class="brush: bash; title: ; notranslate">
$ sudo npm install -g less
</pre>
<p>Damit haben wir alles, um unsere less CSS Stylesheets kompilieren zu können.</p>
<p>Als nächstes holen wir uns den Yui-Kompressor, diesen habe ich mir einfach aus dem Netz gezogen und unter app/java/yuicompressor-2.4.6.jar abgelegt (Die Binary findet ihr unter <a href="http://developer.yahoo.com/yui/compressor/">http://developer.yahoo.com/yui/compressor/</a>).</p>
<p>Nun die Konfiguration:</p>
<p>app/config.yml:</p>
<pre class="brush: python; title: ; notranslate">
# Assetic Configuration
assetic:
    debug:          %kernel.debug%
    use_controller: false
    filters:
        cssrewrite: ~
        less:
          node: /opt/local/bin/node
          node_paths: [/opt/local/lib/node, /opt/local/lib/node_modules]
        yui_css:
          jar: %kernel.root_dir%/java/yuicompressor-2.4.6.jar
</pre>
<p>Zu beachten sind die &#8220;node_paths&#8221;. Der node.js-Modulpfad muss explizit angegeben werden, sonst kann node.js die require()-Statements nicht auflösen (das sind sozusagen die node.js-&#8221;Classpaths&#8221;). /opt/local/lib/node zeigt auf Core-Module, in /opt/local/lib/node_modules liegt unser less.</p>
<p>Um den Yui-Kompressor zu aktivieren, reicht der simple Pfad zur .jar-Datei.</p>
<p>Nun müssen wir nur noch unser Twig-Layout anpassen:</p>
<p>src/Nerdpress/DemoBundle/Resources/views/layout.html.twig:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
        {% stylesheets
                '@NerdpressDemoBundle/Resources/public/css/main.css'
                '@NerdpressDemoBundle/Resources/public/css/layout.css'
        	filter='less,?yui_css'
                combine=true
        %}
          &lt;link rel=&quot;stylesheet&quot; href=&quot;{{ asset_url }}&quot; type=&quot;text/css&quot; media=&quot;all&quot; /&gt;
        {% endstylesheets %}
</pre>
<p>Das &#8220;?&#8221; vor dem Filter &#8220;yui_css&#8221; bedingt, dass die CSS-Compression nur angeschaltet wird, wenn der Debug-Parameter auf false steht. &#8220;Combine&#8221; bedeutet, dass alle CSS-Dateien in einer einzigen, großen Datei zusammengefügt werden, und &#8220;less&#8221; bedeutet letztlich, dass alle CSS-Dateien mittels less CSS precompiled werden.</p>
<p>That´s it. Die Seite im Browser öffnen und das Ergebnis bewundern. Viel Spaß! Symfony ist schon was feines&#8230;</p>
<div class="plus-one-wrap"><g:plusone href="http://nerdpress.org/2011/08/25/symfony-2-asseticbundle-less-css-yui-compressor-unter-osx-installieren/"></g:plusone></div>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://nerdpress.org/2011/08/25/symfony-2-asseticbundle-less-css-yui-compressor-unter-osx-installieren/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>jquery pump effect</title>
		<link>http://nerdpress.org/2011/07/25/jquery-pump-effect/</link>
		<comments>http://nerdpress.org/2011/07/25/jquery-pump-effect/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 16:02:25 +0000</pubDate>
		<dc:creator>Ivo Bathke</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[Jquery]]></category>

		<guid isPermaLink="false">http://nerdpress.org/?p=1546</guid>
		<description><![CDATA[some new loader effect? this is a small jquery plugin that renders something like a pump or glow effect by switching two css classes with jquery UI transitions in an endless loop. the loop can be stopped by applying a stop class to the element. watch the demo on this almost autogenerated github page: Demo [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>some new loader effect?<br />
this is a small jquery plugin that renders something like a pump or glow effect by switching two css classes with jquery UI transitions in an endless loop.<br />
the loop can be stopped by applying a stop class to the element.</p>
<p>watch the demo on this <em>almost autogenerated</em> github page:<br />
<a href="http://ivoba.github.com/jquery-pump/">Demo</a></p>
<p><span id="more-1546"></span></p>
<p>Usage is like this:</p>
<pre class="brush: jscript; title: ; notranslate">
 $('.status').pump({normal: 'normal',
                    pump: 'pumpup',
                    interval: 400,
                    stop: 'statusDone'});
</pre>
<div class="plus-one-wrap"><g:plusone href="http://nerdpress.org/2011/07/25/jquery-pump-effect/"></g:plusone></div>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://nerdpress.org/2011/07/25/jquery-pump-effect/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ajax Deeplinks mit jQuery Address</title>
		<link>http://nerdpress.org/2011/04/04/ajax-deeplinks-mit-jquery-address/</link>
		<comments>http://nerdpress.org/2011/04/04/ajax-deeplinks-mit-jquery-address/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 12:49:38 +0000</pubDate>
		<dc:creator>Ivo Bathke</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Jquery]]></category>

		<guid isPermaLink="false">http://nerdpress.org/?p=1443</guid>
		<description><![CDATA[Aus der Reihe: feine jQuery Plugins, um nicht zu sagen essentielle jQuery Plugins, heute: jQuery Address Damit kann man sehr einfach Deeplinks in Ajax getriebenen Seiten realisieren. So lassen sich zum Beispiel verschiedene Zustände in einer Ajax Seite navigierbar machen, wie zum Beispiel einzelne Tabs via Link öffnen oder auch Akkordion Zustände. Oder man kann [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>Aus der Reihe: feine jQuery Plugins, um nicht zu sagen essentielle jQuery Plugins, heute:<br />
<a href="https://github.com/asual/jquery-address">jQuery Address</a></p>
<p>Damit kann man sehr einfach Deeplinks in Ajax getriebenen Seiten realisieren.</p>
<p>So lassen sich zum Beispiel verschiedene Zustände in einer Ajax Seite navigierbar machen, wie zum Beispiel einzelne Tabs via Link öffnen oder auch Akkordion Zustände.<br />
Oder man kann Ajax Bereiche SEO technisch erfassbar machen.</p>
<p><span id="more-1443"></span></p>
<p>Das Plugin nutzt auch die HTML5 History API, damit werden Ajax Zustände in die Browser History geschrieben, womit sich der Zurück Button dann auch damit nutzen läßt ohne die Seite neu laden zu müssen.<br />
Auch kann man einfach die Url im Address Bar ändern.</p>
<p>Am besten schaut man sich mal die Beispiele auf der <a href="http://www.asual.com/jquery/address/samples/">Demo Seite</a> an.</p>
<p>Tolle Sache.  </p>
<div class="plus-one-wrap"><g:plusone href="http://nerdpress.org/2011/04/04/ajax-deeplinks-mit-jquery-address/"></g:plusone></div>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://nerdpress.org/2011/04/04/ajax-deeplinks-mit-jquery-address/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>reload CSS in Firefox 4.0</title>
		<link>http://nerdpress.org/2011/03/23/reload-css-in-firefox-4-0/</link>
		<comments>http://nerdpress.org/2011/03/23/reload-css-in-firefox-4-0/#comments</comments>
		<pubDate>Wed, 23 Mar 2011 10:09:14 +0000</pubDate>
		<dc:creator>Max Girkens</dc:creator>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[bookmarklet]]></category>
		<category><![CDATA[firefox4]]></category>
		<category><![CDATA[reload css]]></category>

		<guid isPermaLink="false">http://nerdpress.org/?p=1432</guid>
		<description><![CDATA[Firefox 4 ist ja nun draussen: http://www.mozilla-europe.org/de/ Die Addons Firebug und der JSON Viewer sind ja zum Glück auch schon kompatibel. Mein anderes Lieblingsaddon, der CSS reloader leider noch nicht. Coolerweise gibt es aber dieses Bookmarklet: http://david.dojotoolkit.org/recss.html dass genau das tut. Supersache!]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>Firefox 4 ist ja nun draussen:<br />
<a href="http://www.mozilla-europe.org/de/">http://www.mozilla-europe.org/de/</a></p>
<p>Die Addons Firebug und der JSON Viewer sind ja zum Glück auch schon kompatibel.<br />
Mein anderes Lieblingsaddon, der <a href="http://nerdpress.org/2009/11/21/kleines-addon-grose-wirkung/">CSS reloader</a> leider noch nicht.</p>
<p>Coolerweise gibt es aber dieses <a href="http://de.wikipedia.org/wiki/Bookmarklet">Bookmarklet</a>:<br />
<a href="http://david.dojotoolkit.org/recss.html">http://david.dojotoolkit.org/recss.html</a><br />
dass genau das tut.<br />
Supersache!</p>
<div class="plus-one-wrap"><g:plusone href="http://nerdpress.org/2011/03/23/reload-css-in-firefox-4-0/"></g:plusone></div>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://nerdpress.org/2011/03/23/reload-css-in-firefox-4-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debuggin JSON mit JSON Views</title>
		<link>http://nerdpress.org/2010/11/17/debuggin-json-mit-json-views/</link>
		<comments>http://nerdpress.org/2010/11/17/debuggin-json-mit-json-views/#comments</comments>
		<pubDate>Wed, 17 Nov 2010 15:37:32 +0000</pubDate>
		<dc:creator>Ivo Bathke</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Firebug]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Json]]></category>

		<guid isPermaLink="false">http://nerdpress.org/?p=1214</guid>
		<description><![CDATA[Wer kennt das nicht: man entwickelt mit JSON, will die AJAX Rückgabe kontrollieren und macht, wie gewohnt, im Firefox den Firebug auf und checkt unter Console den AJAX Request und sieht folgendes: Nicht sehr erhellend! Total unübersichtlich! Nicht gut! Wird JSON mit dem richtigen Header ausgeliefert, unter PHP geht der so: Dann kann man ein [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>Wer kennt das nicht: man entwickelt mit JSON, will die AJAX Rückgabe kontrollieren und macht, wie gewohnt, im Firefox den Firebug auf und checkt unter Console den AJAX Request und sieht folgendes:<br />
<a href="http://nerdpress.org/wp-content/uploads/2010/11/json_firebug_raw.png" rel="lightbox[post-1214]" title=""><img src="http://nerdpress.org/wp-content/uploads/2010/11/json_firebug_raw-300x70.png" alt="Json Firebug Raw-300x70 in " width="300" height="70" class="alignnone size-medium wp-image-1215" /></a><br />
Nicht sehr erhellend! Total unübersichtlich! Nicht gut!</p>
<p>Wird JSON mit dem richtigen Header ausgeliefert, unter PHP geht der so:</p>
<pre class="brush: php; title: ; notranslate">
header('Content-type: application/json');
</pre>
<p><span id="more-1214"></span></p>
<p>Dann kann man ein feines Feature von Firebug nutzen:<br />
den JSON View, dieser versteckt sich unter der Response als JSON Tab.<br />
<a href="http://nerdpress.org/wp-content/uploads/2010/11/Json_view_firebug.png" rel="lightbox[post-1214]" title=""><img src="http://nerdpress.org/wp-content/uploads/2010/11/Json_view_firebug-300x141.png" alt="Json View Firebug-300x141 in " width="300" height="141" class="alignnone size-medium wp-image-1216" /></a></p>
<p>Ja schon besser! Aber, ich wiederhole, nur mit dem richtigen Header, mit <em>text/html</em> o.ä. ist dieser Tab nicht zu sehen.</p>
<p>Nun gut, trotzdem ein bißchen eng da alles in der FireBug Hülle.<br />
Ich mach ja ganz gerne den Ajax Call in einem neuen Tab auf, um zu sehen ob alles drin ist.<br />
Dann empfiehlt sich ein Firefox AddOn: <a href="https://addons.mozilla.org/de/firefox/addon/10869/">JSONView</a></p>
<p>Dies rendered das JSON schön im Firefox, wenn , Ihr habts erraten, der Header stimmt: <strong>application/json</strong> !<br />
<a href="http://nerdpress.org/wp-content/uploads/2010/11/JSONViewer.png" rel="lightbox[post-1214]" title=""><img src="http://nerdpress.org/wp-content/uploads/2010/11/JSONViewer-300x183.png" alt="JSONViewer-300x183 in " width="300" height="183" class="alignnone size-medium wp-image-1217" /></a><br />
So ist gut!</p>
<div class="plus-one-wrap"><g:plusone href="http://nerdpress.org/2010/11/17/debuggin-json-mit-json-views/"></g:plusone></div>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://nerdpress.org/2010/11/17/debuggin-json-mit-json-views/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Selenium functional tests mit PHPUnit</title>
		<link>http://nerdpress.org/2010/11/14/selenium-functional-tests-mit-phpunit/</link>
		<comments>http://nerdpress.org/2010/11/14/selenium-functional-tests-mit-phpunit/#comments</comments>
		<pubDate>Sun, 14 Nov 2010 15:03:14 +0000</pubDate>
		<dc:creator>Max Girkens</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[PHP 5.3]]></category>
		<category><![CDATA[PHPUnit]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[sfPhpunitPlugin]]></category>
		<category><![CDATA[test driven developement]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://nerdpress.org/?p=1193</guid>
		<description><![CDATA[PHPUnit hat coolerweise eine Extension für Selenium Tests. Dafür braucht man noch den PHP Client für die Selenium Remote Control. Bei mir auf Debian Lenny, bzw. Mac OSX musste ich noch den include_path dafür anpassen, damit phpunit Testing/Selenium.php gefunden hat. Damit kann man mit PHP komfortabel einen Selenium Test Server über die Selenium RC ansprechen, [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p><a href="http://www.phpunit.de/">PHPUnit</a> hat coolerweise eine <a href="https://github.com/sebastianbergmann/phpunit-selenium">Extension</a> für <a href="http://seleniumhq.org/">Selenium</a> Tests.</p>
<p>Dafür braucht man noch den PHP Client für die Selenium Remote Control.</p>
<pre class="brush: bash; title: ; notranslate">
pear install Testing_Selenium-0.4.3
</pre>
<p>Bei mir auf Debian Lenny, bzw. Mac OSX musste ich noch den include_path dafür anpassen,<br />
damit phpunit Testing/Selenium.php gefunden hat.</p>
<p>Damit kann man mit PHP komfortabel einen Selenium Test Server über die <a href="http://seleniumhq.org/docs/05_selenium_rc.html">Selenium RC</a> ansprechen,<br />
der dann beliebige Browser für functional Tests benutzt.</p>
<p>Der Selenium Server ist auch im Prinzip <a href="http://seleniumhq.org/docs/05_selenium_rc.html#installation">schnell</a> installiert<br />
und lokal ist das ganze einigermaßen unproblematisch, weil man ja schon mal die Browser seines OS zur Verfügung hat.</p>
<p>In einem Continuous Integration Setup möchte man aber vielleicht Selenium lieber auf einem Web Server laufen lassen.</p>
<p>Da sieht es dann erstmal weniger gut aus mit Browser executables.<br />
Was also tun?</p>
<p><span id="more-1193"></span></p>
<p>Eine Möglichkeit ist <a href="http://saucelabs.com/">saucelabs.com</a>.<br />
Die bieten &#8220;Cross browser testing with Selenium in the cloud&#8221; an.<br />
Sogar gratis für Firefox unter Linux.<br />
Für die anderen Browser und OS muss man dann schon auf einen bezahlten Account umsteigen.</p>
<p>Dann einfach den saucelabs Selenium Server mit oben erwähnter Extension aus PHPUnit ansprechen:</p>
<p><em>Das Example.php Script von saucelabs</em></p>
<pre class="brush: php; title: ; notranslate">
require_once 'Testing/Selenium.php';
require_once 'PHPUnit/Framework/TestCase.php';

class Example extends PHPUnit_Framework_TestCase
{
    private $selenium;

    public function setUp()
    {
        $this-&gt;selenium = new Testing_Selenium(
            json_encode(array(
                &quot;username&quot; =&gt; &quot;YOUR_USERNAME&quot;,
                &quot;access-key&quot; =&gt; &quot;YOUR_ACCESS_KEY&quot;,
                &quot;os&quot; =&gt; &quot;Windows 2003&quot;,
                &quot;browser&quot; =&gt; &quot;firefox&quot;,
                &quot;browser-version&quot; =&gt; &quot;3.6.&quot;,
                &quot;name&quot; =&gt; $this-&gt;getName()
            )),
            &quot;http://saucelabs.com&quot;,
            &quot;ondemand.saucelabs.com&quot;,
            80,
            90000);
        $this-&gt;selenium-&gt;start();
    }

    public function tearDown()
    {
        $this-&gt;selenium-&gt;stop();
    }

    public function testSauce()
    {
        $this-&gt;selenium-&gt;open(&quot;/&quot;);
        $this-&gt;assertEquals(&quot;Cross browser testing with Selenium - Sauce Labs&quot;,
                            $this-&gt;selenium-&gt;getTitle());
    }

}
</pre>
<p>und PHPUnit macht Selenium Tests:</p>
<pre class="brush: bash; title: ; notranslate">
phpunit Example.php
</pre>
<p>:)</p>
<div class="plus-one-wrap"><g:plusone href="http://nerdpress.org/2010/11/14/selenium-functional-tests-mit-phpunit/"></g:plusone></div>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://nerdpress.org/2010/11/14/selenium-functional-tests-mit-phpunit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cheat-Sheets für alle(s)</title>
		<link>http://nerdpress.org/2010/06/13/cheat-sheets-fur-alles/</link>
		<comments>http://nerdpress.org/2010/06/13/cheat-sheets-fur-alles/#comments</comments>
		<pubDate>Sun, 13 Jun 2010 13:26:01 +0000</pubDate>
		<dc:creator>Johannes Heinen</dc:creator>
				<category><![CDATA[API]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Bookmarks]]></category>
		<category><![CDATA[Cheat-Sheet]]></category>
		<category><![CDATA[Dokumentation]]></category>
		<category><![CDATA[Referenz]]></category>

		<guid isPermaLink="false">http://nerdpress.org/?p=1052</guid>
		<description><![CDATA[Diesem Mann ist sicher nie langweilig: http://www.addedbytes.com/cheat-sheets/. Hinter diesem Link verbergen sich Cheat Sheets zum Selber-Ausdrucken für alles Denkbare.]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>Diesem Mann ist sicher nie langweilig: <a href="http://www.addedbytes.com/cheat-sheets/">http://www.addedbytes.com/cheat-sheets/</a>. Hinter diesem Link verbergen sich Cheat Sheets zum Selber-Ausdrucken für alles Denkbare. </p>
<div class="plus-one-wrap"><g:plusone href="http://nerdpress.org/2010/06/13/cheat-sheets-fur-alles/"></g:plusone></div>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://nerdpress.org/2010/06/13/cheat-sheets-fur-alles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ajax (Fake) Push: Long Polling mit HTML 5 WebWorker</title>
		<link>http://nerdpress.org/2010/06/11/ajax-fake-push-long-polling-mit-html-5-dedicated-worker/</link>
		<comments>http://nerdpress.org/2010/06/11/ajax-fake-push-long-polling-mit-html-5-dedicated-worker/#comments</comments>
		<pubDate>Fri, 11 Jun 2010 11:28:23 +0000</pubDate>
		<dc:creator>Johannes Heinen</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Comet]]></category>
		<category><![CDATA[Html5]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Long Poll]]></category>
		<category><![CDATA[Push]]></category>
		<category><![CDATA[Threads]]></category>
		<category><![CDATA[WebWorker]]></category>
		<category><![CDATA[Worker]]></category>

		<guid isPermaLink="false">http://nerdpress.org/?p=1037</guid>
		<description><![CDATA[Push-Mechanismen im Web sind mittlerweile weit verbreitet &#8211; die Anforderungen an die Infrastruktur aber recht hoch. Nichts geht ohne Plugins (Flash, Applet, WebSocket) &#8211; dann braucht man mindestens einen zweiten Server, der via persistenter Verbindung Nachrichten verteilt. Bedient man sich herkömmlicher JavaScript-Technik, muss man mit aynchronen Ajax-Requests herumkaspern, sich mit Timeouts, Memory-Leaks und Cross-Domain-Sicherheitspolicen herumschlagen. [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>Push-Mechanismen im Web sind mittlerweile weit verbreitet &#8211; die Anforderungen an die Infrastruktur aber recht hoch. Nichts geht ohne Plugins (Flash, Applet, WebSocket) &#8211; dann braucht man mindestens einen zweiten Server, der via persistenter Verbindung Nachrichten verteilt. </p>
<p><span id="more-1037"></span></p>
<p>Bedient man sich herkömmlicher JavaScript-Technik, muss man mit aynchronen Ajax-Requests herumkaspern, sich mit Timeouts, Memory-Leaks und Cross-Domain-Sicherheitspolicen herumschlagen. Und auch hier kommt man nicht herum, den Server zu tweaken oder gleich einen zweiten aufzusetzen, der ausschließlich auf Polls oder Long-Polls trainiert ist.</p>
<p>Gerade in der PHP-Welt ist es nicht einfach, einen üblichen LAMP-Stack soweit zu bringen, dass so etwas auch unter Last funktioniert &#8211; Java ist da wie immer weiter und bietet mit <a href="http://java.sun.com/products/jms/">JMS</a> ein einheitliches Interface &#8211; da gibt es Software für den gewöhnlichen Servletcontainer, im Anwendungsserver muss das laut Spezifikation sogar im Lieferumfang enthalten sein.</p>
<p>Möchte man trotzdem mit &#8220;Bordmitteln&#8221; mal schnell eine Chatbox aufsetzen, führt Longpolling + Ajax eigentlich schnell zu einem akzeptablen Ergebnis &#8211; nichts für Millionen konkurrierende Zugriffe, aber immerhin eine nette Spielerei für zwischendurch. Wäre da nicht ständiges Warten auf die Response, das sich nach einiger Zeit einerseits mit einer merklichen Ruckelorgie bemerkbar macht oder gar den Mauszeiger in eine ewiglich drehende Sanduhr verwandelt.</p>
<h4>HTML 5 to the rescue&#8230;</h4>
<p>HTML 5 kann sogenannte Dedicated Worker &#8211; &#8220;echte&#8221; Workerthreads auf Betriebssystemebene, die man mit einer Zeile spawnen kann.</p>
<pre class="brush: jscript; title: ; notranslate">
new Worker('meinScript.js')
</pre>
<p>Innerhalb eines Threads kann man lang laufende Rechenoperationen im Hintergrund verstecken &#8211; warum also nicht auch einen Ajax-Request? Allerdings haben diese Threads einen Nachteil: Aus Sicherheitsgründen laufen sie in einem klar abgegrenzten Scope, in dem sozusagen nichts vorhanden ist. Auch keine Referenz auf das document-Object der Elternseite. Das stoppt die meisten Javascript-Bibliotheken, wie bspw. JQuery. Man muss sich also mit Bordmitteln begnügen.</p>
<p>Eine Methode, die einen Worker initialisiert, könnte so aussehen:</p>
<pre class="brush: jscript; title: ; notranslate">
    _initializeLongPoll: function()
    {
      var messenger = this;

      var worker = new Worker('my-ajax-worker.js');
        worker.onmessage = function(event)
        {
          var json = jQuery.parseJSON(event.data);

          // NEUE CHAT-NACHRICHT ERZEUGEN
          messenger.$_list.append($('&lt;li class=&quot;messenger-list-item&quot;&gt;'
            + '&lt;strong class=&quot;messenger-list-item-author&quot;&gt;' + json.author + '&lt;/strong&gt;'
            + '&lt;span class=&quot;messenger-list-item-message&quot;&gt;' + json.text + '&lt;/span&gt;&lt;/li&gt;'));
        };
    }
</pre>
<p>&#8220;my-ajax-worker.js&#8221; ist ausschließlich für den Ajax-Request zuständig. Hier wird ein dynamisches Javascript in einem Symfony-Projekt generiert:</p>
<pre class="brush: jscript; title: ; notranslate">

    var onLoad = function()
    {
      var output = httpRequest.responseText;
      if (output) {

        // DELEGIERT DIE RESPONSE ZURÜCK.
        postMessage(output.trim());

        // ERZEUGE NEUEN XmlHttpRequest
        httpRequest = initRequest();
      }
    };

    // WIR SPAREN UND DEN X-BROWSER XmlHttpRequest-KRAM
    var httpRequest = initRequest();
</pre>
<p>Details zum serverseitigen Script möchte ich an dieser Stelle vernachlässigen, im Grunde funktioniert es folgendermaßen: Es arbeitet so lange, bis eine Änderung festzustellen ist. Erst bei Änderung wird die Response an den Client ausgeliefert (darum heißt es &#8220;Long-Polling&#8221;, weil ein Request ganz schön lange dauern kann):</p>
<pre class="brush: java; title: ; notranslate">
while(true)
{
  if(newData())
  {
    return getNewData()
  }
  sleep(5);
}
</pre>
<p>Der Kram funktioniert natürlich nur in HTML5-Browsern, die das Worker-Objekt unterstützen. Dazu zählen Firefox 3.6, Google Chrome und natürlich Safari. Ob Opera es beherrscht, weiß ich nicht, ob der IE 8 es beherrscht, bezweifle ich. Aber wie gesagt: Es ist nur eine Spielerei und keine produktiv geeignete Anwendung. Demnächst schau ich mir auch mal die WebSocket API an&#8230;</p>
<h4>Known Issues</h4>
<p>Vorsicht mit <a href="http://php.net/manual/de/function.session-start.php">session_start()</a> und konkurrierenden (asynchronen) HTTP-Zugriffen. Im User-Sessionscope wird der Apache immer auf das Schließen einer Session warten, bis er dem nächsten Request erlaubt, die Session wieder &#8220;aufzunehmen&#8221;. Und im Normalfall dauert eine User-Session genau so lange wie die Request-Lifetime. Das führt dazu, dass bei 4 gleichzeitig abgefeuerten XmlHttpRequests diese trotzdem als Stack nach dem FIFO-Prinzip abgehandelt werden. Man verliert somit den Vorteil der Asynchronität. Es ist also zwingend erforderlich, die Session bereits vor dem Long-Poll-Loop abzuschließen (durch den Aufruf von <a href="http://php.net/manual/en/function.session-write-close.php">session_write_close()</a>;</p>
<div class="plus-one-wrap"><g:plusone href="http://nerdpress.org/2010/06/11/ajax-fake-push-long-polling-mit-html-5-dedicated-worker/"></g:plusone></div>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://nerdpress.org/2010/06/11/ajax-fake-push-long-polling-mit-html-5-dedicated-worker/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[Jquery]Namespaces via CSS-Selector adressieren</title>
		<link>http://nerdpress.org/2010/04/29/jquerynamespaces-via-selector-adressieren/</link>
		<comments>http://nerdpress.org/2010/04/29/jquerynamespaces-via-selector-adressieren/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 21:38:59 +0000</pubDate>
		<dc:creator>Johannes Heinen</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[Jquery]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[Selektor]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://nerdpress.org/?p=952</guid>
		<description><![CDATA[Vielleicht braucht es mal jemand, jedenfalls lassen sich &#8220;genamespacete&#8221; Tags in einer DOM (XML)document Instanz recht einfach mittels \: als Separator adressieren. Ein Beispiel: Ich möchte ein Dublin-Core Metadatum aus einem beliebigen Feed lesen: Dies entspricht wohl rein syntaktisch nicht ganz dem entsprechendem CSS3-Proposal (einzusehen unter http://www.w3.org/TR/css3-selectors/#typenmsp). Ich habe beide Möglichkeiten interessehalber auch einmal in [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>Vielleicht braucht es mal jemand, jedenfalls lassen sich &#8220;genamespacete&#8221; Tags in einer DOM (XML)document Instanz recht einfach mittels \: als Separator adressieren. Ein Beispiel: Ich möchte ein <a href="http://dublincore.org/">Dublin-Core</a> Metadatum aus einem beliebigen Feed lesen:</p>
<pre class="brush: jscript; title: ; notranslate">
(function($) {

  $('item').each(function() { $(arguments[1]).find('dc\:creator').[...]() } );

})(jQuery);
</pre>
<p>Dies entspricht wohl rein syntaktisch nicht ganz dem entsprechendem CSS3-Proposal (einzusehen unter <a href="http://www.w3.org/TR/css3-selectors/#typenmsp">http://www.w3.org/TR/css3-selectors/#typenmsp</a>). Ich habe beide Möglichkeiten interessehalber auch einmal in einem aktuellen FF3.6 und Chromium  getestet:</p>
<pre class="brush: css; title: ; notranslate">
&lt;style type=&quot;text/css&quot;&gt;
/*&lt;![CDATA[*/
  @namespace hanswurst url(http://www.meins.int)

  hanswurst|kaese
  {
    color: red;
  }
/*]]&gt;*/
&lt;/style&gt;
&lt;hanswurst:kaese&gt;
  Hanswurst liebt käse
&lt;/hanswurst:kaese&gt;
</pre>
<p>Ergebnis: Naja, klappt nicht. Eventuell hat jemand eine Idee oder kann mich korrigieren?</p>
<div class="plus-one-wrap"><g:plusone href="http://nerdpress.org/2010/04/29/jquerynamespaces-via-selector-adressieren/"></g:plusone></div>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://nerdpress.org/2010/04/29/jquerynamespaces-via-selector-adressieren/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

