<?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>_nec &#187; JS</title>
	<atom:link href="http://nec.shell8.net/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://nec.shell8.net</link>
	<description>webfejlesztés, front-end programozás, javascript, css, xhtml, ajax, air</description>
	<lastBuildDate>Wed, 31 Aug 2011 06:54:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Üzenetszórás CORS XHR segítségével Nginx alapú Comet szerveren</title>
		<link>http://nec.shell8.net/2011/08/31/cors-xhr-nginx-comet/</link>
		<comments>http://nec.shell8.net/2011/08/31/cors-xhr-nginx-comet/#comments</comments>
		<pubDate>Wed, 31 Aug 2011 06:51:24 +0000</pubDate>
		<dc:creator>_nec</dc:creator>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[comet]]></category>
		<category><![CDATA[cors]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[xhr]]></category>

		<guid isPermaLink="false">http://nec.shell8.net/?p=402</guid>
		<description><![CDATA[Üzenetszórás alatt nem feltétlenül egy chat alkalmazást érthetünk, lehet bármilyen webes értesítő rendszer, vagy egy gyakran frissülő adatfolyam. Ennek a megvalósításához egy szabványos lehetőséget ad a CORS protokoll, amit egy nginx comet szerverrel oldottam meg.]]></description>
			<content:encoded><![CDATA[<p>Üzenetszórás alatt nem feltétlenül egy chat alkalmazást érthetünk, lehet bármilyen webes értesítő rendszer, vagy egy gyakran frissülő adatfolyam. Ennek a megvalósításához egy szabványos lehetőséget ad a CORS protokoll, amit egy nginx comet szerverrel oldottam meg.<br />
<span id="more-402"></span><br />
Az ilyen alkalmazásoknak felhasználói élményét alapvetően az élő, folytonos működés adja, ennek a megvalósításához van több lehetőség is, nagyjából ezek:</p>
<p><strong>Iframe ál-ajax</strong></p>
<p>a legősibb ajax-szerű aszinkron adatcsere, mivel az iframekre is vonatkozik a same-origin szabály, a terheléselosztás ugyanúgy problémás lehet, nem is beszélve pár böngészpő iframe specifikus bugjairól</p>
<p><strong>Ajax pollozás</strong></p>
<p>periódikusan kiszólunk egy szervernek, hogy van-e új üzenet. Előnye hogy kb mindenben működhet, hátránya, hogy a böngészők same-origin szabálya miatt csak azt a szervert hivogathatjuk, ami az oldalt is kiszolgálja, így nehezebb elosztani a terhelést, valamint, amíg nincs új üzenet, feleslegesen ütögeti a szervert</p>
<p><strong>Ajax jsonp poll</strong></p>
<p>már hívhat akármilyen szervert, de ugyanúgy a kliens futtat időzítőket, ráadásul a kéréssel érdemes elküldeni valami időpontot hogy mikortól akarjuk a friss üzeneteket, azt szerveroldalon le kell kezelni külön logikával, plusz terhelést okozhat</p>
<p><strong>Egy ideális világban</strong></p>
<ul>
<li>más domaineket is hívhassunk aszinkron GET kérésekkel, biztonságosan</li>
<li>ne fusson feleslegesen időzített kérések hada a kliensen</li>
<li>a friss üzenetek idejével se kelljen foglalkozni, külön</li>
</ul>
<p>Ebben a a posztban efelé az álomvilág felé próbálok haladni.</p>
<h3>Mi az a CORS?</h3>
<p>A böngészőinkből eddig nem rángathattunk AJAX segítségével csak úgy, tetszőleges URL-eket az interneten, köszönhetően az úgynevezett &#8220;Same-Origin policy&#8221; -nak, azaz annak a szabálynak, hogy a hívott URL csak azonos protokollon, azonos domainen és porton lehet. Ezen probléma feloldására találták ki a JSONP-t, annak számos hátrányával, pl:</p>
<ul>
<li>a választ egy javacript függvénybe kell csomagolni a küldőnek</li>
<li>nem XHR alapú, egy script taget tesz az oldalba minden hívásnál, nem érhetjük el a küldő/fogadó http fejléceket</li>
</ul>
<p>Erre találták ki 2010 körül a Cross-Origin Resource Sharing (CORS) protokollt, amit ma már az újabb böngészők támogatnak (IE8+, Firefox 3.5+, Safari 4+ és a Chrome). A teljes leírását a <a href="http://www.w3.org/TR/access-control/">W3C oldalán</a> olvashatjátok, tömören arról van szó, hogy a kliens és a szerver extra http fejlécek segítségével &#8220;ismerkedik össze&#8221; és döntik el, hogy a kérést lehet e teljesíteni vagy sem.</p>
<p>A kliens többek között küld egy <em>Origin</em> fejlécet, azzal a hosztnévvel ahonnan a kérés indul, a szervernek a válaszban ezt egy <em>Access-Control-Allow-Origin</em> fejléccel nyugtáznia kell, azaz visszaküldi a hosztnevet ahonnan elérhető a kért adat. Ha más fejléceket is küldünk, azokat egy vesszővel elválasztott listában a szervernek szintén nyugtáznia kell egy <em>Access-Control-Allow-Headers</em> válasz fejlécben. Mindezeket a webszerver intézi nekünk, esetünkben az Nginx.</p>
<p>Firefox esetében az első POST kérést megelőzi egy OPTIONS kérés, aminek válasza eldönti, hogy a böngésző folytathatja e, ez az ún. <em>preflighted</em> kérés. Az OPTIONS-re válaszban érkezik egy <em>Access-Control-Max-Age</em> fejléc, ami azt mondja meg a böngészőnek, hogy meddig nem kell újra küldenie az OPTIONS ellenőrzést.</p>
<p>A témában ajánlott <a href="http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/">Zakas cikke a CORS-ról</a>.</p>
<h3>Mi az az Nginx?</h3>
<p>Az <a href="http://nginx.org/en/">Nginx</a> egy relatíve új webszerver, fő ereje, hogy spórol az erőforrásokkal, 2010 áprilisában a net legforgalmasabb oldalainak 4%-át szolgálta ki. Egyszerű összerakni, beállítani, de pl PHP-t nem kezel úgy modulként mint az Apache, fastCGI kell hozzá, vagy a PHP 5.3.3-ba csomagolt PHP-FPM szerver.</p>
<p>A jelenlegi megoldásban a fejlécek módosítása miatt szükség lesz a <a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule">ngx_headers_more</a> modulra, valamint az <a href="http://pushmodule.slact.net/">nginx_http_push</a> modulra, ami Comet szerverré emeli az egészet.</p>
<h3>Comet, és hogy miért jó mindez</h3>
<p>Eddig, ha egy szerver akart a kliensnek üzenetet küldeni egy böngészőben, akkor a kliensnek kellett kéregetnie a szervert (polling), hogy van e új adat. A comet (vagy ajax-push, http server push) megoldás lényege az az, hogy a kliens hívja a szervert, egy egyszerű GET hívással. A szerver nem ad azonnal választ rá, nyitvatartja kapcsolatot, viszont ha új üzenet kerül a csatornába, azt azonnal visszaküldi a kliensnek, ami a választ feldolgozza és azonnal újranyitja a GET hívást. Így lényegében a kliens akkor kapja meg az üzenetet amikor a szerver akarja.</p>
<p>Ez persze működik JSONP-vel is, ha a GET paraméterekben küldünk pontos időket, hogy mikortól kérjük az üzeneteket, hogy a régieket ne kapjuk meg, talán ez a legböngészőfüggetlenebb megoldás, már ha sikerül olyan comet szervert találni amivel ez lehetséges.</p>
<p>Amúgy itt egy beállítás Nginx-hez, hogy szépen válaszoljon JSONP kérésekre, egy <a href="http://wiki.nginx.org/HttpEchoModule">Http_Echo_Module</a> nevű nginx modul kell hozzá:</p>
<pre class="brush: plain; title: ; notranslate">

location /subscribe {
set $jsonp_callback $arg_callback; # ?callback= GET parametert varja
echo_before_body &quot;$jsonp_callback(&quot;;
echo_after_body &quot;);&quot;;
}
</pre>
<p>Jelen esetben nem jsonp-t használtam, ezért erre most nem lesz szükség. </p>
<h3>Az nginx_http_push modul</h3>
<p>A <a href="http://pushmodule.slact.net/">modul</a> használat szempontjából rém egyszerű, alapvetően nem igényel semmilyen speciális programnyelvet. Két elérési pontot definiál a webszerveren, az egyik, amin a csatornákba küldhetünk, és a másik, amire a kliensek felcsatlakoznak az csatornákon szórt üzenetekre. Az előbbit érdemes priváttá tenni, korlátozni a hozzáférést, az utóbbit fogja a javascriptünk rángatni. Az üzenetek csatornába küldése sima POST kérésekkel történik, magyarul küldhet bele bármi, ami képes HTTP POST küldésre, szerveroldalon a programunk lehet php, ruby, javascript, stb. <a href="http://www.igvita.com/2009/10/21/nginx-comet-low-latency-server-push/">Itt egy eléggé jó cikk a működéséről, és egy példa ruby-val.</a></p>
<p><strong>Az Nginx Comet konfiguráció</strong></p>
<pre class="brush: plain; title: ; notranslate">

# belso, privat eleresi pont az uzenetek bekuldesehez
location /publisher_endpoint {
    set $push_channel_id $arg_id;       #/?id=_CHANNELID_ pl.
    push_publisher;

    push_store_messages on;            # üzenet tárolás, korábbi üzenetekre
    push_message_timeout 2h;           # két óráig tárol egy üzenetet
    push_max_message_buffer_length 30; # max ennyi üzentet tárol egyszerre a csatorna
}

# nyilvanos ajax GET eleresi pont
location /activity {

    push_subscriber;
    push_subscriber_concurrency broadcast;

    set $push_channel_id $arg_id;
    set $orig $http_origin;

    if ($request_method = OPTIONS) {
        more_set_headers &quot;Access-Control-Max-Age: 1728000&quot;;
        echo &quot;&quot;;
    }

    # a CORS működéséhez szükséges konfiguráció
    more_set_headers &quot;Access-Control-Allow-Credentials: true&quot;;
    more_set_headers &quot;Access-Control-Allow-Headers: Overwrite, Destination, Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, If-None-Match, X-File-Name, Cache-Control&quot;;
    more_set_headers &quot;Access-Control-Allow-Methods: PROPFIND, PROPPATCH, COPY, MOVE, DELETE, MKCOL, LOCK, UNLOCK, PUT, GETLIB, VERSION-CONTROL, CHECKIN, CHECKOUT, UNCHECKOUT, REPORT, UPDATE, CANCELUPLOAD, HEAD, OPTIONS, GET, POST&quot;;
    more_set_headers &quot;Access-Control-Expose-Headers: Etag&quot;;
    more_set_headers &quot;Access-Control-Allow-Origin: $orig&quot;;

    more_set_headers &quot;Vary: Accept-Encoding&quot;;

    types         { }
    default_type application/json;

    more_set_headers &quot;Content-Type: application/json&quot;;
}
</pre>
<p>Kicsit bővebb leírás a válaszban küldött fejlécekről:</p>
<p><strong>Access-Control-Allow-Credentials</strong></p>
<p>Amennyiben a kliens ajax kérésében megadjuk parameternek a <strong>withCredentials</strong> true értéket, a válasznak tartalmaznia kell ezt a fejlécet, különben a böngésző nem adja tovább a választ a javascriptnek.</p>
<p><strong>Access-Control-Allow-Headers</strong></p>
<p>Amennyiben bármilyen, nem általános fejlécet küldünk a kéréssel, annak szerepelnie kell ebben a listában, különben nem engedélyezett az adatcsere. Esetünkben ez a comet szervernek szükséges <em>If-Modified-Since</em> és <em>If-None-Match</em> fejlécek, de érdemes felkészülni többel is.</p>
<p><strong>Access-Control-Allow-Methods</strong></p>
<p>Kérés típusok, szigoríthatjuk csak GET elfogadására is.</p>
<p><strong>Access-Control-Expose-Headers</strong></p>
<p>Ha a szerver a válaszban küld valami nem általános fejlécet, ezzel a listával tudja azokat olvashatóvá tenni a kliens számára a válaszban.</p>
<p><strong>Access-Control-Allow-Origin</strong></p>
<p>Ezzel a fejléccel biztosítjuk, hogy a válasz csak olyan kérésnek szól, aminek az <em>Origin</em> fejlécében található hoszt név ezzel megegyezik. Az egész CORS alapja talán.</p>
<p><strong>Access-Control-Max-Age</strong></p>
<p>Előellenőrzés, vagyis <em>preflighted</em> kérés esetén a következő ellenőrzésig tartó idő.</p>
<h3>Probléma &#8211; az időzítés, üzenet ütközés</h3>
<p>Problémás eset lehet, ha egyenként, a küldött sorrendben pakolásszuk az üzeneteket a Comet csatornába. Mivel az <em>If-Modified-Since</em> header maximum másodpercekben gondolkozik, nincs microtime, ha két üzenet között nincs egy másodpercnyi eltelt idő, gondot okozhat a sorrendiség, vagy ha &#8211; pl esetünkben &#8211; nem férünk hozzá az ETag fejléchez, el is szállhat az egész egy, ugyanazt az üzenetet kapó végtelen ciklussal. (Belefutottam párszor&#8230;)</p>
<h3>Megoldás, message queue, demon</h3>
<p>Vegyük el a kliensektől a &#8211; php POST-on keresztüli, de &#8211; közvetlen hozzáférést a Comet csatornától, helyette az ajax POST üzenetküldések pakolásszanak egy adatbázisba, esetünkben egy MySQL táblába. (Ezzel később az üzenetek archiválása is megoldott lesz) A mentés során az üzenetek a php-tól microtime pontosságú időt kapnak, majd ebből a táblából egy rendszerszinten futó démon másodpercenként kiszedegeti az időközben bekerült üzeneteket. A démon az éppen összegyűjtött üzeneteket egy json enkódolt tömbként küldi tovább a comet csatornára, ami kiszórja majd a klienseknek.</p>
<p><a href="http://nec.shell8.net/2011/08/31/cors-xhr-nginx-comet/comet-nginx/" rel="attachment wp-att-425"><img class="alignnone size-medium wp-image-425" title="COMET-nginx" src="http://nec.shell8.net/wp-content/uploads/2011/08/COMET-nginx-500x351.png" alt="" width="500" height="351" /></a></p>
<p>Amiért ez jó:</p>
<ul>
<li>szabályozhatjuk az üzenetek beérkezését, szűrés, feldolgozás, stb</li>
<li>nem kérdés, hogy melyik üzenet volt elől</li>
<li>másodpercenként több üzenet is jöhet így</li>
<li>skálázhatóság, a démonnak csak meg kell adni a többi, csatasorba tett nginx szervert, hogy küldje nekik is az üzeneteket</li>
<li>a démon figyelheti az üzenet csatornában található üzenetek mennyiségét, és hogy mennyi feliratkozó van épp a csatornán</li>
<li>ha a <em>push_message_timeout</em> miatt kiürül a csatorna, a démon visszatöltheti az adatbázisból az utolsó néhány üzenetet</li>
</ul>
<p><a href="http://nec.shell8.net/projects/comet/">Működő példa</a>, Firefox 3.6+, Chrome és Safari böngészőkben. iOS-en nem működik, IE8/9 -ben elméletileg van rá megoldás, utánajárok. Majd.</p>
<p>PHP démon írásához most már PEAR modul ad segítséget, én <a href="http://kevin.vanzonneveld.net/techblog/article/create_daemons_in_php/">ezt vettem</a> alapul. A példában használt fileokat <a href="http://nec.shell8.net/projects/comet/cors-xhr-nginx-comet.zip">itt letölthetitek</a>.</p>
<h3>Konklúzió</h3>
<p>Ahogy minden lassan terjedő szabvány, ez is fájdalmas, már ami az IE-t illeti. A megoldás elvileg  az <em>Etag</em> fejléccel pontosítaná az üzenetlistát, de azt nem adták vissza CORS használatakor a böngészők, emiatt kellett a démonos megoldás. A nem általános fejlécek miatt sok vállalati tűzfalon elbukhat a dolog, ez is hátráltató tényező.</p>
<p>A démont lehet le fogom lőni a jövőben, ha érdekel a demó, de nem akarod te feltenni magadhoz, írj emailt.</p>
<p>A következő próbálkozással egy másik comet modult, a <a href="https://github.com/wandenberg/nginx-push-stream-module">nginx-push-stream-module</a> -t próbálom ki, ebben az friss üzenetek eléréséről egy GET paraméterben adott microtime unix timestamp segítségével gondoskodik a szerver, ha jsonp-vel megoldható, akkor az válasz lehet a böngészőfüggetlenségre.</p>
]]></content:encoded>
			<wfw:commentRss>http://nec.shell8.net/2011/08/31/cors-xhr-nginx-comet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cufón &#8211; saját font, flash nélkül</title>
		<link>http://nec.shell8.net/2009/05/18/cufon-sajat-font-flash-nelkul/</link>
		<comments>http://nec.shell8.net/2009/05/18/cufon-sajat-font-flash-nelkul/#comments</comments>
		<pubDate>Mon, 18 May 2009 08:18:25 +0000</pubDate>
		<dc:creator>_nec</dc:creator>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[cufon]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[js]]></category>

		<guid isPermaLink="false">http://nec.shell8.net/?p=311</guid>
		<description><![CDATA[Itt a blogon, és máshol is előszeretettel alkalmaztam egy flash alapú font megjelenítő megoldást, ami véletlenül sem a sIFR volt. Azzal kapcsolatban régóta több fenntartásom is volt, kényelmesebb volt a saját megoldásom használni, ismerve annak limitációit. Nemrég viszont elémkerült a cufón, egy tisztán JS alapú megoldás, ami egészen zseniális. Működése eléggé komplex, mivel a betűtípusok [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-318 alignleft" title="blabla" src="http://nec.shell8.net/wp-content/uploads/2009/05/blabla.jpg" alt="blabla" width="536" height="151" /></p>
<p>Itt a blogon, és máshol is előszeretettel alkalmaztam egy flash alapú font megjelenítő megoldást, ami véletlenül sem a sIFR volt. Azzal kapcsolatban régóta több fenntartásom is volt, kényelmesebb volt a saját megoldásom használni, ismerve annak limitációit.</p>
<p>Nemrég viszont elémkerült a <a href="http://wiki.github.com/sorccu/cufon/about">cufón</a>, egy tisztán JS alapú megoldás, ami egészen zseniális.<br />
<span id="more-311"></span><br />
Működése eléggé komplex, mivel a betűtípusok grafikáit kénytelen a böngésző saját eszközeivel megrajzolni. Ehhez a <a href="http://en.wikipedia.org/wiki/Canvas_(HTML_element)">canvas</a> elemet, Explorer alatt pedig annak natív <a href="http://www.w3.org/TR/NOTE-VML.html">VML</a> támogatását használja ki.</p>
<p><img class="alignright" title="A Cufon működése" src="http://cufon.shoqolate.com/doc/Generation.png" alt="" width="285" height="416" /></p>
<p>A használni kívánt betűtípusból egy <a href="http://cufon.shoqolate.com/generate/">online generátor segítségével</a> <em>SVG </em>alapú fontfile készül, amit a cufón számára <em>VML </em>görbékké számol át. Ezekkel már képes canvas elemre rajzolni, vagy vml elemeket készíteni.</p>
<p>A generátornál &#8211; a flashez hasonlóan &#8211; megadhatjuk mely karakterkészleteket akarjuk beemelni, ezzel optimalizálva a kapott font állomány méretét. A fontfile-t rögzíthetjük egy domainhez, ilyenkor az elkészült javascript &#8220;font&#8221; kódolásába bevonja az adott domaint, ezzel is védve a megvásárolt fontokat.</p>
<p>Ha nem bízunk a generátorban, saját dárga betűkészleteinket, vagy az ügyfél által készítetett teljesen egyedi <em>TrueType </em>fontot féltve, letölthetjük a generátor forrását, és azt saját fejlesztői szerveren futtatva, elkészíthetjük a font javascript megfelelőjét.</p>
<p>Ha kész a font, csak be kell emelni a html kódunkba, magával a cufón scripttel együtt, és amikor szükség van rá, javascriptben ráereszteni a kívánt css selector-ra.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;/js/cufon.js&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #808080; font-style: italic;">&lt;!--mce:0--&gt;</span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;/js/myfont.js&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #808080; font-style: italic;">&lt;!--mce:1--&gt;</span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #808080; font-style: italic;">&lt;!--mce:2--&gt;</span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Az összes elterjedt böngészőben használható de előtte <a href="http://wiki.github.com/sorccu/cufon/known-bugs-and-issues">legyünk tisztában a korlátaival</a>, nem igényel külön plugint, és érdemes egy pillantást vetni pár <a href="http://cameronmoll.com/articles/cufon/bickham.html">tesztoldalra</a> vele.</p>
]]></content:encoded>
			<wfw:commentRss>http://nec.shell8.net/2009/05/18/cufon-sajat-font-flash-nelkul/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Három hasznos jQuery plugin</title>
		<link>http://nec.shell8.net/2009/01/22/harom-hasznos-jquery-plugin-animalt-effektekhez/</link>
		<comments>http://nec.shell8.net/2009/01/22/harom-hasznos-jquery-plugin-animalt-effektekhez/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 16:48:36 +0000</pubDate>
		<dc:creator>_nec</dc:creator>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[background]]></category>
		<category><![CDATA[color]]></category>
		<category><![CDATA[easing]]></category>
		<category><![CDATA[effects]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[js]]></category>

		<guid isPermaLink="false">http://nec.shell8.net/?p=219</guid>
		<description><![CDATA[Három olyan plugin-t mutatnék be röviden, melyek funkcionalitásuk alapján alapvetőnek érezhetőek, de a sima jQuery csomagból kimaradtak, valószínüleg helyspórolás, erőforrás kímélés céljából, no meg ezek valóban csak animációkhoz szükségesek. Mind a három kiterjesztés az .animate() metódus használatakor lehet hasznos. backGround animation A segítségével háttérképet mozgathatunk, majdnem a megszokott sílus attribútummal az .animate() metódus paraméterei között.  [...]]]></description>
			<content:encoded><![CDATA[<p>Három olyan plugin-t mutatnék be röviden, melyek funkcionalitásuk alapján alapvetőnek érezhetőek, de a sima jQuery csomagból kimaradtak, valószínüleg helyspórolás, erőforrás kímélés céljából, no meg ezek valóban csak animációkhoz szükségesek. Mind a három kiterjesztés az <em>.animate()</em> metódus használatakor lehet hasznos.</p>
<p><span id="more-219"></span></p>
<p><strong>backGround animation</strong></p>
<p>A segítségével háttérképet mozgathatunk, majdnem a megszokott sílus attribútummal az <em>.animate()</em> metódus paraméterei között. </p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#myId'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">animate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>backgroundPosition<span style="color: #339933;">:</span> <span style="color: #3366CC;">'(150px 250px)'</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// ide</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#myId'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">animate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>backgroundPosition<span style="color: #339933;">:</span> <span style="color: #3366CC;">'(-75px -50px)'</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// vagy oda</span></pre></div></div>

<p>Érdemes odafigyelni a paraméterek körüli zárójelekre.</p>
<p>A plugin <a href="http://plugins.jquery.com/project/backgroundPosition-Effect">itt érhető el</a> , használatára példa pl <a href="http://djuice.hu/baratsagproba">itt a menüben</a>.</p>
<p><strong>color animation</strong></p>
<p>Ez a plugin lehetne talán igazán része a teljes csomagnak, pláne hogy John Resig írta &#8211; aki a jQuery-t magát is. Segítségével betűszínt, keretszínt és háttérszínt animálhatunk egy értékre.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.box'</span><span style="color: #009900;">&#41;</span>
	.<span style="color: #660066;">animate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> backgroundColor<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;blue&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'slow'</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">// elobb legyen kek</span>
	.<span style="color: #660066;">animate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> backgroundColor<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;#ff9900&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'slow'</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">// aztan narancs</span></pre></div></div>

<p>Itt a <a href="http://plugins.jquery.com/project/color">plugin oldala</a>, példát pedig <a href="http://dev.jquery.com/~john/ticket/fx-rewrite2/">itt találhattok</a>.</p>
<p><strong>jQuery easing</strong></p>
<p>Kicsit zavarbaejtő a jQuery dokumentációja az <em>animate</em> esetén:</p>
<p><strong><em>animate</em></strong><em>( params, </em><span class="optional"><em>[</em></span><em>duration</em><span class="optional"><em>]</em></span><em>, </em><span class="optional"><em>[</em></span><em>easing</em><span class="optional"><em>]</em></span><em>, </em><span class="optional"><em>[</em></span><em>callback</em><span class="optional"><em>]</em></span><em> )</em></p>
<p>Az <em>easing</em> nincs túlságosan kifejtve, sokszor nem is használjuk emiatt. Ez a plugin rengeteg animációs effektet ad, amivel feldobhatjuk alkalmazásunkat.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.box'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">animate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	width<span style="color: #339933;">:</span> <span style="color: #3366CC;">'+=250'</span><span style="color: #339933;">,</span>
	height<span style="color: #339933;">:</span> <span style="color: #3366CC;">'+=200'</span><span style="color: #339933;">,</span>
	left<span style="color: #339933;">:</span> <span style="color: #CC0000;">100</span><span style="color: #339933;">,</span>
	top<span style="color: #339933;">:</span> <span style="color: #CC0000;">200</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'slow'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'easeOutBack'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>A <a href="http://gsgd.co.uk/sandbox/jquery/easing/">plugin oldala</a>, a mozgásokra az összes példa demó ugyamott, némi funkcionális játszadozás pedig <a href="http://nec.shell8.net/projects/fluidbox/">itt látható</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nec.shell8.net/2009/01/22/harom-hasznos-jquery-plugin-animalt-effektekhez/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Adobe AIR 1.5</title>
		<link>http://nec.shell8.net/2008/11/18/adobe-air-15/</link>
		<comments>http://nec.shell8.net/2008/11/18/adobe-air-15/#comments</comments>
		<pubDate>Tue, 18 Nov 2008 09:17:23 +0000</pubDate>
		<dc:creator>_nec</dc:creator>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[air]]></category>
		<category><![CDATA[update]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://nec.shell8.net/?p=211</guid>
		<description><![CDATA[Megjelent  az újabb AIR verzió, melyet hasonló mérföldkőnek szántak az Adobenál mint az 1.0-át anno. Lássuk mit kapunk ezzel a frissítéssel. Titkosított helyi adatbázis Ha eddig &#8211; valahol joggal &#8211; óczkodtál nagyobb üzleti alkalmazás AIR re portolásától, mert nem tartottad elég biztonságosnak, akkor most már közelebb állhat hozzád az AIR, mivel lehetőség van titkosított adatbázisok [...]]]></description>
			<content:encoded><![CDATA[<p>Megjelent  az újabb AIR verzió, melyet hasonló mérföldkőnek szántak az Adobenál mint az 1.0-át anno. Lássuk mit kapunk ezzel a frissítéssel.</p>
<p><span id="more-211"></span></p>
<p><strong>Titkosított helyi adatbázis</strong></p>
<p>Ha eddig &#8211; valahol joggal &#8211; óczkodtál nagyobb üzleti alkalmazás AIR re portolásától, mert nem tartottad elég biztonságosnak, akkor most már közelebb állhat hozzád az AIR, mivel lehetőség van titkosított adatbázisok - <a href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS8AFC5E35-DC79-4082-9AD4-DE1A2B41DAAF.html">Encrypted Local Store (ELS)</a> -  használatára, melyekbe nagyobb mennyiségű adat is belepakolható.</p>
<h3>Flash Player 10</h3>
<p>Az Adobe Flash legújabb üdvöskéje mostmár futhat AIRben is, a 10es verzióval azt remélik, hogy 3D-s flash alkalmazások serege jelenhet meg ebben a környezetben is.</p>
<h3>WebKit update</h3>
<p>Frissítették a beépített webkit motort, legfontosabb itt a Squirrelfish JS motor beemelése, amit a Safarival már megtettek. A tesztek során az Adobenál átlagosan 35%-os sebességnövekedést mértek a fejlesztők, kíváncsian várjuk.</p>
]]></content:encoded>
			<wfw:commentRss>http://nec.shell8.net/2008/11/18/adobe-air-15/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Adobe AIR #6 SQLite JavaScriptből</title>
		<link>http://nec.shell8.net/2008/10/22/adobe-air-sqlite-javascript/</link>
		<comments>http://nec.shell8.net/2008/10/22/adobe-air-sqlite-javascript/#comments</comments>
		<pubDate>Wed, 22 Oct 2008 15:17:17 +0000</pubDate>
		<dc:creator>_nec</dc:creator>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[air]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[sqlite]]></category>

		<guid isPermaLink="false">http://nec.shell8.net/?p=20</guid>
		<description><![CDATA[Szünet után folytatva az Adobe AIR-ről szóló sorozatom, most az AIR beépített SQL adazbázis kezelését igyekszem bemutatni. Pár példával letudjuk az alapvető, az SQL lekérdező nyelvben ismert műveletet, majd kitérek pár optimalizációs megoldásra. Az AIR futtatókörnyezet tartalmaz egy SQLite adatbázis kezelő osztálycsomagot, melyet nyugodtan használhatunk adatok tárolására, kezelésére és szinkonizálására.  Annak, aki nem ismeri, erről az [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nec.shell8.net/wp-content/uploads/2008/10/sqlite.gif"><img src="http://nec.shell8.net/wp-content/uploads/2008/10/sqlite.gif" alt="" title="SQLite logo" width="105" height="105" class="alignleft size-full wp-image-193" /></a>Szünet után folytatva az Adobe AIR-ről szóló sorozatom, most az AIR beépített SQL adazbázis kezelését igyekszem bemutatni. Pár példával letudjuk az alapvető, az SQL lekérdező nyelvben ismert műveletet, majd kitérek pár optimalizációs megoldásra.</p>
<p><span id="more-20"></span></p>
<p>Az AIR futtatókörnyezet tartalmaz egy <a href="http://www.sqlite.org/">SQLite</a> adatbázis kezelő osztálycsomagot, melyet nyugodtan használhatunk adatok tárolására, kezelésére és szinkonizálására.  Annak, aki nem ismeri, erről az adatbázis rendszerről talán a legfontosabb amit érdemes nagy vonalakban elmondani, az az, hogy komplex file és memória struktúrák helyett egyetlen bináris file-ban tárolja az adatbázist. Mivel egy file és bináris, ezt a filet hordozhatjuk bármilyen rendszerre, ahol szintén használható, már ha létezik az adott rendszerre SQLite verzió.</p>
<p>Ennek köszönhető, hogy már rengeteg alkalmazás és operációs rendszer él ezzel a minimalista, de rendes relációs adatbázisrendszerrel, mint pl a Skype vagy a Firefox illetve a Mac OSX, jópár Symbian alapú mobiltelefon és minden iPhone vagy iPod Touch.</p>
<p>AIRben az adatbázishoz JavaScript segítségével férünk hozzá, mely elsőre szürreális élmény lehet azoknak, akik eddig csak <em>rendes </em>szerveroldali nyelvekben tettek hasonlókat.</p>
<h3>Szinkron &#8211; aszinkron műveletek</h3>
<p>Mint JS-ben rengeteg minden, az adatbázis műveleteink is lehetnek <strong>szinkron </strong>folyamatok, illetve eseményfüggők, így <strong>aszinkron </strong>lefutású kódok. Mindkettőnek van előnye ill. hátránya, a szinkron műveletek kódolás szempontjából egyszerűbbek, nem kell eseménykezelőkkel babrálni, de amíg lefut, a programunk malmozik/homokórázik használhatatlan csendben. Nem is ajánlott, csak nagyon kicsi adatbázisokkal, kevés adattal használni.</p>
<p>Az aszinkron műveletekre már készülni kell a kódunkban, eseményeket kell elkapni, adatokat mozgatni, de cserébe folyamatos marad a felhasználói élmény, meg valahogy ez közelebb is áll ahhoz a fejlesztési stílushoz, amit manapság az AJAX-al teletűzdelt weboldalak, alkalmazások megkívánnak tőlünk.</p>
<h3>Csatlakozás az adatbázishoz</h3>
<p>Lássuk az elejét, vegye elő alkalmazásunk az adatbázist.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> dbFile <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> air.<span style="color: #660066;">File</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;app:/db/database.db&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> db <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> air.<span style="color: #660066;">SQLConnection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
db.<span style="color: #000066;">open</span><span style="color: #009900;">&#40;</span>dbFile<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Meghatározunk egy File pointert ami az SQLite adatbázis filera mutat, az <em>app:/</em> relatív elérési útvonal az alkalmazásunk telepített helye a fájlrendszeren. Majd létrehozzuk a kapcsolatot az adatbázishoz és megnyitjuk azt, SQLite esetén ez az a file amit megadunk neki, egy file &#8211; egy adatbázis.</p>
<p>Létrehozunk egy <em>SQLConnection </em>objektumot, majd megnyitjuk vele az adatbázist. Az <a href="http://help.adobe.com/en_US/AIR/1.1/jslr/flash/data/SQLConnection.html">SQLConnection</a>-nek van sok eseménye, amit érdemes figyelni, leginkább talán az <em>air.SQLErrorEvent.ERROR</em> -t, ha hiba van. Az adatbázis megnyitása történhet az <em>open </em>metódussal, ha szinkron, és az <em>openAsync </em>metódussal, ha aszinkron műveletekkel szeretnénk dolgozni.</p>
<p>Aszinkron műveletek során minden lefuttatott kérést figyeltetni kell majd egy a<em>ir.SQLEvent.RESULT</em> eseményre, de most időhiányában nem térek ki az aszinkron műveletekre.</p>
<h3>SQL műveletek</h3>
<p>Miután alkalmazásunk csatlakozott az adatbázishoz, az SQL műveletek nagy része már nem sokban különbözik a más nyelvekben megszokott módoktól. Létrehozunk egy <em>SQLStatement </em>objektumot, megadjuk neki melyik adatbázist használja, és hogy mi a művelet.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>4
5
6
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> statement <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> air.<span style="color: #660066;">SQLStatement</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
statement.<span style="color: #660066;">sqlConnection</span> <span style="color: #339933;">=</span> db<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// az adatbázis</span>
statement.<span style="color: #660066;">text</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;SELECT name, value FROM options&quot;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// a művelet</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">statement.<span style="color: #660066;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
<span style="color: #003366; font-weight: bold;">var</span> results <span style="color: #339933;">=</span> statement.<span style="color: #660066;">getResult</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// eredmények kiolvasása az SQLStatement objektumból</span>
<span style="color: #003366; font-weight: bold;">var</span> numResults <span style="color: #339933;">=</span> results.<span style="color: #660066;">data</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> 
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> numResults<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> 
<span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> row <span style="color: #339933;">=</span> result.<span style="color: #660066;">data</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    row.<span style="color: #000066;">name</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// a mezőértékek asszociatív tömbben</span>
    row.<span style="color: #660066;">value</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Aszinkron műveletek során egy <em>air.SQLEvent.RESULT</em> eseményt kell figyeltetni az <em>SQLStatement </em>objektumon, de az eseménykezelőben a kód már ugyanez.<br />
 <br />
INSERT, UPDATE és DELETE műveleteknél nincs különbség, ha a statement.execute(); lefut, illetve van<br />
<em>air.SQLEvent.RESULT</em> esemény, akkor volt sikeres a művelet.</p>
<h3>Hibakezelés</h3>
<p>Aszinkron műveleteknél az <em>air.SQLErrorEvent.ERROR</em> esemény figyelésekor kapott esemény-objektum hordozza a hibaüzenetet, szinkron műveletek esetén használjuk a <em>try-catch</em> szerkezetet, az elkapott kivétel tartalmazza majd a hiba okát.</p>
<h3>Tippek, optimalizálás</h3>
<p><strong>AUTOINCREMENT </strong>- ilyen típusu oszlopoknál INSERT után az eredményobjektum <em>lastInsertRowID </em>paramétere hordozza az új ID-t</p>
<p><strong>Paraméterezett műveletek</strong> &#8211; az AIR minden SQL műveletet alacsonyabb szintű műveleti kódra fordít, és úgy tárol, amíg nem változik a művelet szerkezete. Sok, hasonló szerkezetű művelet esetén ezt érdemes kihasználni a művelet paraméterezésével.</p>
<p>Ilyenkor az SQL művelet kódját felkészítjük változók fogadására, s azokat később adhatjuk hozzá vagy módosíthatjuk ahelyett, hogy újraírnánk vagy újra példányosítanánk egy <em>SQLStatement </em>objektumot.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>17
18
19
20
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">statement.<span style="color: #660066;">text</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;INSERT INTO options(name, value)&quot;</span> <span style="color: #339933;">+</span> 
                 <span style="color: #3366CC;">&quot;VALUES (:optionName, :optionValue)&quot;</span><span style="color: #339933;">;</span> 
statement.<span style="color: #660066;">parameters</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;:optionName&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;title&quot;</span><span style="color: #339933;">;</span>
statement.<span style="color: #660066;">parameters</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;:optionValue&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;Adobe AIR #6 SQLite JavaScriptből&quot;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Később, ha ugyanerre a műveletere van szükség, csak a már példányosított <em>SQLStatement </em>objektumot kell újra elővenni, és módosítani a paramétereket az <em>execute()</em> előtt. Ennek a módszernek előnye az erőforrás kímélésen és a műveletek gyorsaságán kívül az, hogy védelmet nyújt az esetleges sql-injection sebezhetőségek ellen.</p>
<p><strong>Tranzakciók</strong> &#8211; sok, logikailag valamilyen szinten összetartozó műveletet (írás/olvasás) érdemes egy tranzakcióba helyezni, összességében gyorsabb lesz a művelet.</p>
<p>Tranzakciókat az <a href="http://help.adobe.com/en_US/AIR/1.1/jslr/flash/data/SQLConnection.html#begin()">air.SQLConnection.begin()</a> &#8211; <a href="http://help.adobe.com/en_US/AIR/1.1/jslr/flash/data/SQLConnection.html#commit()">.commit()</a> &#8211; illetve <a href="http://help.adobe.com/en_US/AIR/1.1/jslr/flash/data/SQLConnection.html#rollback()">.rollback()</a> metódusaival tudunk kezelni.</p>
<h3>Előre csomagolt adatbázisok, külső segédeszközök</h3>
<p>Természetesen nem kell minden adatbázist helyben elkészíteni és kezdeti adatokkal, struktúrával feltölteni, lehetséges előre csomagolni az adatbázis állományt a letöltött AIR csomaggal. Csak ügyeljünk arra, hogy updatek esetén ne legyen gond esetleges felülírásból.</p>
<p>Az adatbázis kezeléséhez érdemes valami SQLmanager programot szerezni, vannak kifejezetten SQLitehoz kiadott programok, illetve AIRben is írtak már ilyen eszközt.</p>
<p>Nekem az <a href="http://www.sqlmaestro.com/products/sqlite/maestro/">SQLite Maestro</a> nevű vállt be, igaz csak 30napos verziót néztem, de egész használhatónak bizonyult. </p>
<p><strong>Eddig az Adobe AIR-ről:</strong></p>
<ul>
<li><a href=" http://nec.shell8.net/2008/10/14/eval-adobe-air-ben/">Eval(); Adobe AIR-ben</a></li>
<li><a href="http://nec.shell8.net/2008/07/11/adobe-air-nativ-menukezeles/">#5 Natív menükezelés</a></li>
<li><a href="http://nec.shell8.net/2008/07/05/adobe-air-dragndrop-filefeltoltes/">#4 Drag’n&#8217;Drop és Filefeltöltés</a></li>
<li><a href="http://nec.shell8.net/2008/06/25/adobe-air-esemenyek">#3 Események</a></li>
<li><a href="http://nec.shell8.net/2008/06/23/adobe-air-ablakkezeles">#2 Ablakkezelés</a></li>
<li><a href="http://nec.shell8.net/2008/06/19/adobe-air-alapok">#1 Az alapok</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://nec.shell8.net/2008/10/22/adobe-air-sqlite-javascript/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Eval() Adobe AIR -ben?</title>
		<link>http://nec.shell8.net/2008/10/14/eval-adobe-air-ben/</link>
		<comments>http://nec.shell8.net/2008/10/14/eval-adobe-air-ben/#comments</comments>
		<pubDate>Tue, 14 Oct 2008 08:15:01 +0000</pubDate>
		<dc:creator>_nec</dc:creator>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[air]]></category>
		<category><![CDATA[eval]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[workaround]]></category>

		<guid isPermaLink="false">http://nec.shell8.net/?p=125</guid>
		<description><![CDATA[Leggyakrabban talán JSON stringek objektumokká alakításakor jön elő ez a probléma. Az Adobe AIR környezet biztonsági okokból korlátozza az eval() javascript metódust. Ez a szigor erősen indokolt, de nem okoz megoldhatatlan problémát. Nézzük a megoldást, de előbb az okokat, amiért így lett kialakítva a futtatókörnyezet. Valamit valamiért, avagy amiért nincs eval(). MIt csinál az eval()? [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-140 noborder" title="air_vent" src="http://nec.shell8.net/wp-content/uploads/2008/10/air_vent.jpg" alt="" width="240" height="130" />Leggyakrabban talán JSON stringek objektumokká alakításakor jön elő ez a probléma. Az Adobe AIR környezet biztonsági okokból korlátozza az <em><a href="http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/eval">eval()</a></em> javascript metódust. Ez a szigor erősen indokolt, de nem okoz megoldhatatlan problémát.</p>
<p>Nézzük a megoldást, de előbb az okokat, amiért így lett kialakítva a futtatókörnyezet.</p>
<p><span id="more-125"></span><strong>Valamit valamiért, avagy amiért nincs eval().</strong></p>
<p>MIt csinál az eval()? Végrehajt egy string formában megadott javascript kódsort, minden előztetes cécó nélkül.</p>
<p>Az AIRből pedig kivették azt a biztonsági szigorítást, hogy AJAX kérések csak azon a domainen futhatnak, ahol az oldal amit látogatunk. Bárhonnan fogadhatunk akármilyen javascript kódokat, akár fileszinten is betáplálva az alkalmazásunkba.</p>
<p>Ez eléggé hasznos, révén így igazi, online forrásokra támaszkodó, nyitott API-kat nyújtó webszolgáltatásokat kihasználó alkalmazást alkothatunk. De veszélyeket is rejt, révén az AIR alkalmazásunk hozzáfér a kliens filerendszeréhez. Nem lenne túl jó, ha egy pl egy chatprogram evalozott JSON stringjeiben tudatlanul kiadnánk személyesebb adatokat tartalmazó fájljainkat.</p>
<p>Az alkalmazásunk egy izolált környezetben fut, angol nevén ez a <em>sandbox</em>. Ezen belül vezették be az Adobe fejlesztői az alábbi szigorításokat:</p>
<ul>
<li><strong>eval() futtatások</strong> csak az onLoad előtt működnek</li>
<li><strong>szinkron XMLHttpRequests</strong> kérések onLoad előtt nem adnak választ, <strong>aszinkron XMLHttpRequests</strong> kéréseket el lehet küldeni onLoad előtt, de azok válasza csak onLoad után érkezhet meg</li>
<li>onLoad után a <strong>document.write()</strong> és a <strong>document.writeln()</strong> függvények nem kerülnek lefutásra</li>
<li>htmlből hivatkozva <strong>scripteket</strong> nem lehet <strong>betölteni </strong>a <em>sandbox</em>-on <strong>kívülről</strong></li>
<li>dinamikusan létrehozott <strong>&lt;script&gt; elemek</strong> nem kerülnek lefutásra.</li>
</ul>
<p> <br />
<strong>Karantén, avagy a non-application sandbox</strong></p>
<p>Lehetőségünk van több ilyen <em>sandbox</em>-ot létrehozni, hogy ne akadjanak össze esetleg a használt rendszerek. Ezekben a &#8220;karanténokban&#8221; ismét visszakapjuk az eval()-t, újra megvan a domainre vonatkozó szigor, de semmit se láthatunk magából az AIR futtatókörnyezetből.</p>
<p>Ezeket például IFRAME -ek segítségével valósíthatjuk meg, az alkalmazás html kódjába helyezve valami hasonlót:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;">	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;iframe</span> </span>
<span style="color: #009900;">		<span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;frameId&quot;</span></span>
<span style="color: #009900;">		<span style="color: #000066;">sandboxRoot</span>=<span style="color: #ff0000;">&quot;http://plurk.com/&quot;</span> </span>
<span style="color: #009900;">		<span style="color: #000066;">documentRoot</span>=<span style="color: #ff0000;">&quot;app:/&quot;</span> </span>
<span style="color: #009900;">		<span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;nonapp_sandbox.html&quot;</span> </span>
<span style="color: #009900;">		<span style="color: #000066;">frameborder</span>=<span style="color: #ff0000;">&quot;0&quot;</span> </span>
<span style="color: #009900;">		<span style="color: #000066;">height</span>=<span style="color: #ff0000;">&quot;0&quot;</span> </span>
<span style="color: #009900;">		<span style="color: #000066;">width</span>=<span style="color: #ff0000;">&quot;0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/iframe<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>ID &#8211; amivel majd DOMon keresztül hivatkozunk rá<br />
sandboxRoot &#8211; az a domain amire a karanténon belül szűkítjük a lekéréseket<br />
documentRoot &#8211; amennyiben ez &#8220;app:/&#8221;, akkor kapunk megfelelő <em>non-application sandbox</em> -ot<br />
src &#8211; a html amit betöltünk majd az IFRAME-be</p>
<p><img class="alignnone size-full wp-image-136" title="Air Application Sandboxes" src="http://nec.shell8.net/wp-content/uploads/2008/10/air_abra.jpg" alt="" width="500" height="235" /></p>
<p>Most, hogy van egy szeparált környezetünk, ahol működik az <em>eval(),</em> már csak össze kell kötni a két <em>sandbox</em>-ot. Ezt az AIR egy <em><strong>childSandboxBridge </strong></em>nevű interfészen keresztül tudja megvalósítani.</p>
<p>Az IFRAME-be dugott htmlben hozzunk létre pár függvényt. Először definiálni kell mit akarunk az IFRAME-en kívülre adni a childSandboxBridge-en keresztül.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">	<span style="color: #009966; font-style: italic;">/* nonapp_sandbox.html */</span>
	window.<span style="color: #000066;">onLoad</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>		    
		window.<span style="color: #660066;">childSandboxBridge</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'myEval'</span><span style="color: #339933;">:</span> myEval<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>			
	<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Majd definiáljuk magát a függvényt amit átadunk.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>4
5
6
7
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">	<span style="color: #009966; font-style: italic;">/* nonapp_sandbox.html */</span>
	<span style="color: #003366; font-weight: bold;">function</span> myEval<span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Tehát maga az eval() ebben a zárt környezetben fut le, a végeredményt adja át az alkalmazásnak. Bármi ártalmas kód ami itt végrehajtódik, próbálhozhat, nem fér hozzá az AIR környezethez, s azon keresztül a rendszerhez.</p>
<p>Az alkalmazásunkban onLoad eseménykor definiáljuk a childSandboxBridge interfészen át kapott függvényt.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">	<span style="color: #009966; font-style: italic;">/* application.html */</span>
	window.<span style="color: #000066;">onLoad</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		window.<span style="color: #660066;">myEval</span> <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'frameId'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">contentWindow</span>.<span style="color: #660066;">childSandboxBridge</span>.<span style="color: #660066;">myEval</span><span style="color: #339933;">;</span>		
	<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>És ennyi, most már használhatjuk eval helyett ezt a saját függvényt. Még kényelmesebb, ha pl az általunk használt javascript keretrendszer érzékenyebb részeit módosítjuk úgy, hogy működjenek ezen az interfészen keresztül, és akkor későbbiekben már észre se vesszük ezt a problémát.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>10
11
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">	<span style="color: #009966; font-style: italic;">/* application.html */</span>
	<span style="color: #003366; font-weight: bold;">var</span> evaledCode <span style="color: #339933;">=</span> window.<span style="color: #660066;">myEval</span><span style="color: #009900;">&#40;</span> code_string <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><strong>Eddig az Adobe AIR-ről:</strong></p>
<ul>
<li><a href="http://nec.shell8.net/2008/10/22/adobe-air-sqlite-javascript/">#6 SQLite JavaScriptből</a></li>
<li><a href="http://nec.shell8.net/2008/07/11/adobe-air-nativ-menukezeles/">#5 Natív menükezelés</a></li>
<li><a href="http://nec.shell8.net/2008/07/05/adobe-air-dragndrop-filefeltoltes/">#4 Drag’n&#8217;Drop és Filefeltöltés</a></li>
<li><a href="http://nec.shell8.net/2008/06/25/adobe-air-esemenyek">#3 Események</a></li>
<li><a href="http://nec.shell8.net/2008/06/23/adobe-air-ablakkezeles">#2 Ablakkezelés</a></li>
<li><a href="http://nec.shell8.net/2008/06/19/adobe-air-alapok">#1 Az alapok</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://nec.shell8.net/2008/10/14/eval-adobe-air-ben/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Plurker béta</title>
		<link>http://nec.shell8.net/2008/08/06/plurker-beta/</link>
		<comments>http://nec.shell8.net/2008/08/06/plurker-beta/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 15:03:14 +0000</pubDate>
		<dc:creator>_nec</dc:creator>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[air]]></category>
		<category><![CDATA[client]]></category>
		<category><![CDATA[desktop]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[plurk]]></category>

		<guid isPermaLink="false">http://nec.shell8.net/?p=65</guid>
		<description><![CDATA[Lehet tesztelni, valamennyire épkézláb állapotba került a plurk desktop kliens, amit csinálgatok pár napja. Erősen béta, alapfunkciókat tud már, a többi meg majd szépen fejlődik, nyáriszünet után. Augusztus végén folytköv.]]></description>
			<content:encoded><![CDATA[<p>Lehet tesztelni, valamennyire épkézláb állapotba került a <a href="http://nec.shell8.net/plurker/">plurk desktop kliens</a>, amit csinálgatok pár napja.</p>
<p>Erősen béta, alapfunkciókat tud már, a többi meg majd szépen fejlődik,<br />
nyáriszünet után.</p>
<p>Augusztus végén folytköv.</p>
<p><span id="more-65"></span><br />
<a href="http://nec.shell8.net/plurker/"><img class="size-full wp-image-64" title="Plurker" src="http://nec.shell8.net/wp-content/uploads/2008/08/plurker.gif" alt="Plurker is a desktop client for Plurk, created with Adobe® AIR™." width="500" height="153" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://nec.shell8.net/2008/08/06/plurker-beta/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Plurk desktop kliens AIR-ben &#8211; sneak peak</title>
		<link>http://nec.shell8.net/2008/07/25/plurk-desktop-kliens-air-ben-sneak-peak/</link>
		<comments>http://nec.shell8.net/2008/07/25/plurk-desktop-kliens-air-ben-sneak-peak/#comments</comments>
		<pubDate>Fri, 25 Jul 2008 16:18:13 +0000</pubDate>
		<dc:creator>_nec</dc:creator>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[air]]></category>
		<category><![CDATA[client]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[desktop]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[plurk]]></category>
		<category><![CDATA[RIA]]></category>

		<guid isPermaLink="false">http://nec.shell8.net/?p=44</guid>
		<description><![CDATA[Hiánypótló alkalmazás, eddig csak a plurk mobil verziója létezett AIRbe tuszkolt iframe-ben, ami eléggé ronda volt. Még visszavan sok apróság, és egy rendes update motor hozzá. Kép lejjebb&#8230; Ő lesz az, hamarosan lehet bétateszelni.]]></description>
			<content:encoded><![CDATA[<p>Hiánypótló alkalmazás, eddig csak a plurk mobil verziója létezett AIRbe tuszkolt iframe-ben, ami eléggé ronda volt. Még visszavan sok apróság, és egy rendes update motor hozzá. Kép lejjebb&#8230;</p>
<p><span id="more-44"></span></p>
<p>Ő lesz az, hamarosan lehet bétateszelni.</p>
<p><img class="alignnone size-full wp-image-45" title="plurk desktop client in Adobe AIR" src="http://nec.shell8.net/wp-content/uploads/2008/07/plurker.jpg" alt="" width="441" height="546" /></p>
]]></content:encoded>
			<wfw:commentRss>http://nec.shell8.net/2008/07/25/plurk-desktop-kliens-air-ben-sneak-peak/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>8bites arcade játék egy faviconban</title>
		<link>http://nec.shell8.net/2008/07/16/8bites-arcade-jatek-egy-faviconban/</link>
		<comments>http://nec.shell8.net/2008/07/16/8bites-arcade-jatek-egy-faviconban/#comments</comments>
		<pubDate>Wed, 16 Jul 2008 14:22:17 +0000</pubDate>
		<dc:creator>_nec</dc:creator>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[favicon]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[pixel]]></category>

		<guid isPermaLink="false">http://nec.shell8.net/?p=35</guid>
		<description><![CDATA[Totálisan értelmetlen, de hatalmas villantás. A játék 16&#215;16 pixelét CANVAS-ba renderelik, mentik png-be, majd kifrissítik a favikonba. N új játék, WASD vagy nyilak (nálam az előbbi jobban bevált) az irányítás, ENTER kiteszi egy nagyobb canvas elembe.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.p01.org/releases/DHTML_contests/files/DEFENDER_of_the_favicon/">Totálisan értelmetlen, de hatalmas villantás</a>. A játék 16&#215;16 pixelét CANVAS-ba renderelik, mentik png-be, majd kifrissítik a favikonba. <span id="more-35"></span></p>
<p><a href="http://nec.shell8.net/wp-content/uploads/2008/07/defender.gif"><img class="alignnone size-full wp-image-36" title="defender of the favicon" src="http://nec.shell8.net/wp-content/uploads/2008/07/defender.gif" alt="" width="500" height="237" /></a></p>
<p><strong>N</strong> új játék, <strong>WASD</strong> vagy nyilak (nálam az előbbi jobban bevált) az irányítás, <strong>ENTER</strong> kiteszi egy nagyobb <em>canvas </em>elembe.</p>
]]></content:encoded>
			<wfw:commentRss>http://nec.shell8.net/2008/07/16/8bites-arcade-jatek-egy-faviconban/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adobe AIR #5 Natív menükezelés</title>
		<link>http://nec.shell8.net/2008/07/11/adobe-air-nativ-menukezeles/</link>
		<comments>http://nec.shell8.net/2008/07/11/adobe-air-nativ-menukezeles/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 11:48:23 +0000</pubDate>
		<dc:creator>_nec</dc:creator>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[air]]></category>
		<category><![CDATA[contextmenu]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[menu]]></category>
		<category><![CDATA[nativemenu]]></category>

		<guid isPermaLink="false">http://nec.shell8.net/?p=26</guid>
		<description><![CDATA[Talán az egyik legnagyobb nyűg egy RIA fejlesztésénél a menük lekezelése. Alkalmazás menükkel, context menükkel sokat lendíthetünk az alkalmazásunk használhatóságán és kezelhetőségén. Ha böngészőbe szánt alkalmazást fejlesztesz, valamilyen js/html/css kombót kell alkalmazni, felülbírálni a létező context-menüt, ráhúzni egy designt, ami szép, érthető és használható, ráadásul mindezt böngészőfüggetlenül. Mivel az AIR segítségével írt alkalmazás asztali alkalmazás, [...]]]></description>
			<content:encoded><![CDATA[<p>Talán az egyik legnagyobb nyűg egy RIA fejlesztésénél a menük lekezelése. Alkalmazás menükkel, context menükkel sokat lendíthetünk az alkalmazásunk használhatóságán és kezelhetőségén. Ha böngészőbe szánt alkalmazást fejlesztesz, valamilyen js/html/css kombót kell alkalmazni, felülbírálni a létező context-menüt, ráhúzni egy designt, ami szép, érthető és használható, ráadásul mindezt böngészőfüggetlenül.</p>
<p>Mivel az AIR segítségével írt alkalmazás asztali alkalmazás, rendelkezik az alatta található oprendszer egykét képességével. Egyik ezek közül a natív menükezelés. Nem kell a designra, viselkedésre, különböző böngészőkre időt vesztegetni, használjuk azt a GUI kinézetet menüinkre amit az adott rendszer hagy nekünk.<br />
<span id="more-26"></span><br />
<a href="http://nec.shell8.net/wp-content/uploads/2008/06/air_context.jpg"><img class="alignnone size-full wp-image-27" title="Adobe AIR kontext menü" src="http://nec.shell8.net/wp-content/uploads/2008/06/air_context.jpg" alt="" width="530" height="176" /></a></p>
<h4><a href="http://help.adobe.com/en_US/AIR/1.1/jslr/flash/display/NativeMenu.html">air.NativeMenu</a></h4>
<p>Egy egyszerű menü létrehozásával kezdjük, azt, hogy ez hol jelenik majd meg, majd később döntjük el.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> createFileMenu<span style="color: #009900;">&#40;</span>menuType<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #003366; font-weight: bold;">var</span> temp<span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> menu <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> air.<span style="color: #660066;">NativeMenu</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
temp <span style="color: #339933;">=</span> menu.<span style="color: #660066;">addItem</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> air.<span style="color: #660066;">NativeMenuItem</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Új&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
temp.<span style="color: #660066;">keyEquivalent</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'n'</span><span style="color: #339933;">;</span>
temp.<span style="color: #660066;">data</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'new'</span><span style="color: #339933;">;</span>
&nbsp;
temp <span style="color: #339933;">=</span> menu.<span style="color: #660066;">addItem</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> air.<span style="color: #660066;">NativeMenuItem</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Megnyitás&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
temp.<span style="color: #660066;">keyEquivalent</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'o'</span><span style="color: #339933;">;</span>
temp.<span style="color: #660066;">data</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'open'</span><span style="color: #339933;">;</span>
&nbsp;
temp <span style="color: #339933;">=</span> menu.<span style="color: #660066;">addItem</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> air.<span style="color: #660066;">NativeMenuItem</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Mentés&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
temp.<span style="color: #660066;">keyEquivalent</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'s'</span><span style="color: #339933;">;</span>
temp.<span style="color: #660066;">data</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'save'</span><span style="color: #339933;">;</span>
&nbsp;
menu.<span style="color: #660066;">addItem</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> air.<span style="color: #660066;">NativeMenuItem</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//szeparátor</span>
&nbsp;
temp <span style="color: #339933;">=</span> menu.<span style="color: #660066;">addItem</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> air.<span style="color: #660066;">NativeMenuItem</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Kilépés&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
temp.<span style="color: #660066;">keyEquivalent</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'q'</span><span style="color: #339933;">;</span>
temp.<span style="color: #660066;">data</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'quit'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> <span style="color: #000066; font-weight: bold;">item</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">item</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> menu.<span style="color: #660066;">items</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
menu.<span style="color: #660066;">items</span><span style="color: #009900;">&#91;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span>air.<span style="color: #660066;">Event</span>.<span style="color: #660066;">SELECT</span><span style="color: #339933;">,</span> menuItemSelectHandler <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000066; font-weight: bold;">return</span> menu<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> menu <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> air.<span style="color: #660066;">NativeMenu</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
menu.<span style="color: #660066;">addSubmenu</span><span style="color: #009900;">&#40;</span>createFileMenu<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;File&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Menüt tehát az air.NativeMenu példányosításával készíthetünk és utána lehet almenüt és/vagy funkciót hozzákötni. A példában látszik hogy még a menü struktúrálására is lehetőség van, szeparátorokkal.</p>
<p>Az <a href="http://help.adobe.com/en_US/AIR/1.1/jslr/flash/display/NativeMenuItem.html">air.NativeMenuItem</a> még további lehetőségeket ad amit elvárhatunk egy menütől pl.:</p>
<ul>
<li>aktív / inaktív menü</li>
<li>pipálható menü</li>
<li>billentyű vezérlés</li>
</ul>
<p>Ezek mellett kell még egy metódus, ami figyeli a menü eseményeket, egyelőre elég ha csak konzolon jelez, onnan már látható milyen adatokat hordoz az esemény.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> itemSelected<span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #003366; font-weight: bold;">var</span> message <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;Kiválasztott menü: <span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span> <span style="color: #339933;">+</span> event.<span style="color: #660066;">target</span>.<span style="color: #660066;">label</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\&quot;</span> adat: &quot;</span> <span style="color: #339933;">+</span> event.<span style="color: #660066;">target</span>.<span style="color: #660066;">data</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;.&quot;</span><span style="color: #339933;">;</span>
air.<span style="color: #660066;">Introspector</span>.<span style="color: #660066;">Console</span>.<span style="color: #660066;">dump</span><span style="color: #009900;">&#40;</span>message<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Most már csak a menüt kell elérhetővé tenni. Itt kell figyelembe venni, hogy milyen rendszeren fut az alkalmazásunk. Windows alatt a hagyományos rendszermenük az ablakhoz kapcsolódnak, OSX alatt az alkalmazás menüje a menüsorba kerül az asztal tetején. Ezt a futtatókörnyezet képességeivel tesztelhetjük mielőtt megjelenítenénk a menüt.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>air.<span style="color: #660066;">NativeApplication</span>.<span style="color: #660066;">supportsMenu</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #006600; font-style: italic;">// OSX</span>
    air.<span style="color: #660066;">NativeApplication</span>.<span style="color: #660066;">nativeApplication</span>.<span style="color: #660066;">menu</span> <span style="color: #339933;">=</span> menu<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>air.<span style="color: #660066;">NativeWindow</span>.<span style="color: #660066;">supportsMenu</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #006600; font-style: italic;">// windows</span>
    window.<span style="color: #660066;">nativeWindow</span>.<span style="color: #660066;">menu</span> <span style="color: #339933;">=</span> menu<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Ne felejtsük el, hogy windows alatt a transparent és chrome mentes ablakokra nem lehetséges igy menüt csatolni &#8211; révén az ablak láthatatlan. Ami lehetőség marad ilyenkor az az ikonra helyezett menü, vagy a context menü, melyekre amúgy is szükség lehet. Az ikonra helyezett menü ismét az oprendszer tesztelésére kényszerít minket, erre a környezet az <em>air.NativeApplication.supportsDockIcon</em> és az <em>air.NativeApplication.supportsSystemTrayIcon</em> vizsgálatát teszi lehetővé.</p>
<p>Context menü esetén ilyenekre nincs szükség, ott a menü előhívásának az eseményét kell kezelnünk. Mivel használattól függően szükség lehet tetszőleges elemekre, kontrollokra saját menüt kötni, az eseményt ezeken a HTML elemeken kell figyeltetni. Ezt egy e célra fenntartott <em>contextmenu</em> esemény jelzi nekünk.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'hasContextMenu'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">'contextmenu'</span> <span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    menu.<span style="color: #660066;">display</span><span style="color: #009900;">&#40;</span>window.<span style="color: #660066;">nativeWindow</span>.<span style="color: #660066;">stage</span><span style="color: #339933;">,</span> event.<span style="color: #660066;">clientX</span><span style="color: #339933;">,</span> event.<span style="color: #660066;">clientY</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Ennyi a pozícionálás, és megjelenítés. A kívánt menü kiválasztásakor eltűnik.</p>
<p>Következő alkalommal az AIR-be épített SQLite adatbázist veszem elő.</p>
<h3>Update: menük egyenesen XMLből és JSONból</h3>
<p>Úgynézki gondoltak a komplexebb alkalmazásokra, és lehetséges XML és JSON adatformátumokból is menüket generálni. Dokumentációt érdekes módon nem találtam rá, de példát igen, a kipróbálás még hátravan.</p>
<p>Az XML <em>(textContextMenu.xml)</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></span> 
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;root<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;menuitem</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Első menü&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span> 
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;menuitem</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Második menü&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;check&quot;</span> <span style="color: #000066;">toggled</span>=<span style="color: #ff0000;">&quot;true&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span> 
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;menuitem</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Harmadik menü&quot;</span> <span style="color: #000066;">enabled</span>=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span> 
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;menuitem</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;separator&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span> 
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;menuitem</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Negyedik menü&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span> 
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;menuitem</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Almenu 1, 4&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span> 
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;menuitem</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Almenu 2, 4&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span> 
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;menuitem</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Almenu 3, 4&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span> 
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/menuitem<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/root<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>És a beemelése:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">            <span style="color: #003366; font-weight: bold;">var</span> textMenu <span style="color: #339933;">=</span> air.<span style="color: #660066;">ui</span>.<span style="color: #660066;">Menu</span>.<span style="color: #660066;">createFromXML</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;textContextMenu.xml&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
            air.<span style="color: #660066;">ui</span>.<span style="color: #660066;">Menu</span>.<span style="color: #660066;">setAsContextMenu</span><span style="color: #009900;">&#40;</span>textMenu<span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;contextEnabledText&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
            <span style="color: #006600; font-style: italic;">// az alapértelmezett context menü kikapcsolása</span>
            air.<span style="color: #660066;">ui</span>.<span style="color: #660066;">Menu</span>.<span style="color: #660066;">setAsContextMenu</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><strong>Eddig az Adobe AIR-ről:</strong></p>
<ul>
<li><a href=" http://nec.shell8.net/2008/10/14/eval-adobe-air-ben/">Eval(); Adobe AIR-ben</a></li>
<li><a href="http://nec.shell8.net/2008/10/22/adobe-air-sqlite-javascript/">#6 SQLite JavaScriptből</a></li>
<li><a href="http://nec.shell8.net/2008/07/05/adobe-air-dragndrop-filefeltoltes/">#4 Drag’n&#8217;Drop és Filefeltöltés</a></li>
<li><a href="http://nec.shell8.net/2008/06/25/adobe-air-esemenyek">#3 Események</a></li>
<li><a href="http://nec.shell8.net/2008/06/23/adobe-air-ablakkezeles">#2 Ablakkezelés</a></li>
<li><a href="http://nec.shell8.net/2008/06/19/adobe-air-alapok">#1 Az alapok</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://nec.shell8.net/2008/07/11/adobe-air-nativ-menukezeles/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

