﻿<?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>Дневна доза нонсенс... &#187; Web</title>
	<atom:link href="http://dailyffs.com/category/web/feed/" rel="self" type="application/rss+xml" />
	<link>http://dailyffs.com</link>
	<description>Софтуерно-инженерна му работа</description>
	<lastBuildDate>Tue, 03 Jan 2012 01:34:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Game of Life (javascript + html5&#8242;s canvas)</title>
		<link>http://dailyffs.com/2011/game-of-life-javascript-html5/</link>
		<comments>http://dailyffs.com/2011/game-of-life-javascript-html5/#comments</comments>
		<pubDate>Sun, 24 Jul 2011 20:55:57 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[game of life]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=907</guid>
		<description><![CDATA[Тези дни отново ме загриза съвестта, че не работя по някакъв сайд-проект - мой собствен или open source и за това днес реших да почета и понапиша Game of Life.<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/game-of-life-javascript-html5/' addthis:title='Game of Life (javascript + html5&#8242;s canvas) '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>Тези дни отново ме загриза съвестта, че не работя по някакъв сайд-проект &#8211; мой собствен или open source и за това днес реших да почета и понапиша <a href="http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Game of Life</a>.</p>
<p>Оказа се доста прост алгоритъм с доста интересна история, която и сами може да си прочетете <img src='http://dailyffs.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Демо може да видите тук: <a href="http://dailyffs.com/life/">http://dailyffs.com/life/</a></p>
<p>Сорсът е тук: <a href="https://gist.github.com/1102964">https://gist.github.com/1102964</a></p>
<p>Коментарът към сорса от страна на @skanev е тук: <a href="https://twitter.com/skanev/status/95213748092026880">https://twitter.com/skanev/status/95213748092026880</a></p>
<p>Това, което искам да кажа в тази статия е, че колкото и да са бързи съвремените Javascript engine-и и колкото и разни светила и икони на браузър вендорите да се хвалят, че производителността скача многократно от версия до версия, това не значи че не може да забързате всичко още <del>малко</del> много. Цената на &#8222;забързването&#8220; е &#8222;угрозняване&#8220; и оптимизиране на кода. В моя конкретен случай &#8211; на една функция, която се вика 60000 пъти на преизчисление.</p>
<p>Въпросната фунцкия:</p>
<pre class="brush: jscript; title: ; notranslate">

function getLiveNeighbours(id, data) {
  var x = id % canvas.width;
  var y = parseInt(id / canvas.width);

  var cnt = 0;
  for (var i = -1; i &lt; 2; i++) {
    for (var j = -1; j &lt; 2; j++) {
      if ((i != 0 || j != 0) &amp;&amp;
        !(x+i &lt; 0 || x+i &gt;= canvas.width || y+j &lt; 0 || y+j &gt;= canvas.height) &amp;&amp;
        data.data[4*((y+j)*canvas.width+(x+i))] != THE_BLACK) {
        cnt++;
      }
    }
  }
  return cnt;
}
</pre>
<p>Простата оптимизация на кода включва:</p>
<ol>
<li>Премахване на извикването на функцията (тялото на функцията се ползва директно) &#8211; спестява 60000 извиквания и времето за изпълнение на една итерация пада от 500ms на 270ms</li>
<li>Заменяне на двата вложени цикъла проверяващи за броя на съседни клетки &#8211; от 270ms на 150ms</li>
<li>Опростяване на пресмятанията (премахване на умножения) &#8211; от 150ms на 60ms</li>
<li>Създаване на локални референции към често използваните данни (вместо постоянни извиквания от типа &#8222;obj.data&#8220; при изчисленията се създава и използва локална променлива) &#8211; от 60ms на 50ms</li>
</ol>
<pre class="brush: jscript; title: ; notranslate">
// (4)
var width = canvas.width*4;
var d = data.data;
var nd = newdata.data;
var cw = canvas.width;
var ch = canvas.height;
var base = 0;

for (var i = 0; i &lt; d.length/4; i++) {
  var x = i % cw;
  var y = parseInt(i / cw);

  var cnt = 0;
  // (1), (2), (3)
  if (x &gt; 0 &amp;&amp; d[base-4] != THE_BLACK) cnt++;
  if (x &lt; cw-1 &amp;&amp; d[base+4] != THE_BLACK) cnt++;
  if (x &gt; 0 &amp;&amp; y &gt; 0 &amp;&amp; d[base-4-width] != THE_BLACK) cnt++;
  if (y &gt; 0 &amp;&amp; d[base-width] != THE_BLACK) cnt++;
  if (x &lt; cw-1 &amp;&amp; y &gt; 0 &amp;&amp; d[base+4-width] != THE_BLACK) cnt++;
  if (x &gt; 0 &amp;&amp; y &lt; ch-1 &amp;&amp; d[base-4+width] != THE_BLACK) cnt++;
  if (y &lt; ch-1 &amp;&amp; d[base+width] != THE_BLACK) cnt++;
  if (x &lt; cw-1 &amp;&amp; y &lt; ch-1 &amp;&amp; d[base+4+width] != THE_BLACK) cnt++;
  ...
</pre>
<p>В крайна сметка производителността скочи 10 пъти, макар логиката на кода да изглежда по-зле от преди. Не, че преди изглеждаше много красива, но все пак <img src='http://dailyffs.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Разбира се има и още един доста по-умен начин за техническа оптимизация &#8211; Web Workers. Те са панацеята на всички проблеми, началото и края, давид и голиат, содом и гомор, ин и ян&#8230; за тях може да почетете тази статия -<a href="../2011/mandelbrot-web-workers/" rel="bookmark"> Mandelbrot + Web Workers</a></p>
<p><em>Забележка: </em></p>
<ul>
<li><em>става дума за проста техническа оптимизация на кода, а не за подобрения на алгоритъма!</em></li>
<li><em>вероятно оптимизациите в javascript engine-ите не се фокусират върху случаи на извикване на функция 60 хиляди пъти&#8230; а би трябвало.</em></li>
</ul>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/game-of-life-javascript-html5/' addthis:title='Game of Life (javascript + html5&#8242;s canvas) '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/game-of-life-javascript-html5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Прозрение</title>
		<link>http://dailyffs.com/2011/%d0%bf%d1%80%d0%be%d0%b7%d1%80%d0%b5%d0%bd%d0%b8%d0%b5/</link>
		<comments>http://dailyffs.com/2011/%d0%bf%d1%80%d0%be%d0%b7%d1%80%d0%b5%d0%bd%d0%b8%d0%b5/#comments</comments>
		<pubDate>Sat, 23 Jul 2011 12:17:32 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=904</guid>
		<description><![CDATA[Преди няколко дни започнах да пиша малко плъгинче (първия ми плъгин акшуъли) за Django, което да филтрира браузъри в зависимост от useragent-а им. Идеята ми беше филтрирането да става в зависимост от версията на браузъра&#8230; идея, която работеше преди 5 години. Останах си с тази идея до момента, в който видях няколко useragent-a от мобилни [...]<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/%d0%bf%d1%80%d0%be%d0%b7%d1%80%d0%b5%d0%bd%d0%b8%d0%b5/' addthis:title='Прозрение '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>Преди няколко дни започнах да пиша малко плъгинче (първия ми плъгин акшуъли) за Django, което да филтрира браузъри в зависимост от useragent-а им. Идеята ми беше филтрирането да става в зависимост от версията на браузъра&#8230; идея, която работеше преди 5 години. Останах си с тази идея до момента, в който видях няколко useragent-a от мобилни устройства и таблети. Накратко един с един нямат общо, но това което си остава при всички е версията на layout engine-a.</p>
<p>Това е хора. Забравете за IE X или Firefox Y и  т.н., това което ще направи сайта ви да работи на десктоп, телефон и таблет е версията на layout engine-a в комбинация с данните от тези таблички: <a href="http://en.wikipedia.org/wiki/Comparison_of_layout_engines_%28Cascading_Style_Sheets%29">http://en.wikipedia.org/wiki/Comparison_of_layout_engines_%28Cascading_Style_Sheets%29</a> и <a href="http://caniuse.com/">http://caniuse.com/</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/%d0%bf%d1%80%d0%be%d0%b7%d1%80%d0%b5%d0%bd%d0%b8%d0%b5/' addthis:title='Прозрение '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/%d0%bf%d1%80%d0%be%d0%b7%d1%80%d0%b5%d0%bd%d0%b8%d0%b5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upload на blob като файл чрез AJAX</title>
		<link>http://dailyffs.com/2011/upload-blob-as-file-ajax/</link>
		<comments>http://dailyffs.com/2011/upload-blob-as-file-ajax/#comments</comments>
		<pubDate>Thu, 14 Jul 2011 07:10:15 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[blob]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=888</guid>
		<description><![CDATA[Наскоро забелязах, че при изпращането на голям скрийншот в http://screenshoot.me се случват някакви неприятни неща. По-точно грешка 413 Request entity too large. Оказа се, че хостингът ми не позволява изпращане на POST заявки с параметри по-големи от 1-2мб. За сметка на това пък позволява качване на файлове до 20мб. До тук единственото нещо, което ме притесняваше е дали може да "симулирам" изпращане на файл чрез AJAX. Оказа се че може. FUCK YEAH!<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/upload-blob-as-file-ajax/' addthis:title='Upload на blob като файл чрез AJAX '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p><em>Заглавието и на мен не ми говори нищо, за това ще се опитам да обясня с прости думи казуса.</em></p>
<p>Наскоро забелязах, че при изпращането на голям скрийншот в <a href="http://screenshoot.me">http://screenshoot.me</a> се случват някакви неприятни неща. По-точно грешка <em>413 Request entity too large</em>. Оказа се, че хостингът ми не позволява изпращане на POST заявки с параметри по-големи от 1-2мб. За сметка на това пък позволява качване на файлове до 20мб. До тук единственото нещо, което ме притесняваше е дали може да &#8222;симулирам&#8220; изпращане на файл чрез AJAX. Оказа се че може. FUCK YEAH!</p>
<p>Всъщност може да си префасонирате цялата заявка както ви скимне, което е много готино и същевремено много жалко, защото десетките хиляди фронт-енд дивелъпъри, ползващи jQuery и нямащи понятие от javascript никога няма да узнаят за този факт. <em></em></p>
<p><em>Вероятно бъркам, просто се опитвам да си обясня защо на всяко интервю винаги питат &#8222;а ти с jQuery знаеш ли как да работиш&#8220; все едно манюъла е 500 страници и ти трябва висше <img src='http://dailyffs.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</em></p>
<p>Та реших да разширя <a href="http://www.openjs.com/scripts/jx/">леката библиотечка</a> (&#8222;парче код&#8220; е правилната дума), която ползвам за AJAX обаждания и съответно резултата е тук &#8211; <a href="https://github.com/lucho870601/ajax-blob-upload">https://github.com/lucho870601/ajax-blob-upload</a></p>
<p>Накратко:</p>
<pre class="brush: jscript; title: ; notranslate">
jx.generateBoundary = function(fieldsData) { // Функция, която генерира уникален разделител валиден за всеки фрагмент
  var boundary = parseInt(Math.random()*Math.pow(10, 16)).toString(36) + '' + parseInt(Math.random()*Math.pow(10, 16)).toString(36);
  for (var i = 0; i &lt; fieldsData.length; i++) {
    if (fieldsData[i].indexOf(boundary) &gt; -1) {
      // generate new boundary and check all fields again
      boundary = parseInt(Math.random()*Math.pow(10, 16)).toString(36) + '' + parseInt(Math.random()*Math.pow(10, 16)).toString(36);
      i = 0;
    }
  }
  return boundary;
};

jx.loadFile = function(url, fileData, fileName, callback, opt) {
  var http = this.init(); //The XMLHttpRequest object is recreated at every call - to defeat Cache problem in IE
  if(!http||!url) return;
  var parts = url.split('?');
  var url = parts[0];
  var parameters = parts[1] ? parts[1].split('&amp;') : [];

  var fieldsData = [fileData];
  for (var i = 0; i &lt; parameters.length; i++) {
    fieldsData.push(parameter[i][1]);
  }

  var boundary = this.generateBoundary(fieldsData);
  var body = '';
  for (var i = 0; i &lt; parameters.length; i++) {
    // строим фрагментите за данни
    var p = parameters[i].split('=');
    body += &quot;--&quot; + boundary + &quot;\r\n\
Content-Disposition: form-data; name='&quot;+p[0]+&quot;'\r\n\
\r\n\
&quot;+(p[1] || '')+&quot;\r\n&quot;;
  }

  // фрагмента за псевдо-файла
  body += &quot;--&quot; + boundary + &quot;\r\n\
Content-Disposition: form-data; name='&quot; + fileName + &quot;'; filename='&quot; + fileName + &quot;'\r\n\
Content-Type: application/octet-stream\r\n\
\r\n\
&quot;+ fileData + &quot;\r\n\
--&quot; + boundary + &quot;--\r\n&quot;;

  http.open(&quot;POST&quot;, url, true);
  http.setRequestHeader(&quot;Content-Type&quot;, &quot;multipart/form-data; boundary=&quot;+boundary);
  http.setRequestHeader(&quot;Content-Length&quot;, body.length);
  http.setRequestHeader(&quot;Connection&quot;, &quot;close&quot;);
  ...
  http.send(body);
};
</pre>
<p>&#8230; и получавате данните си като файл накрая.</p>
<p>Кофтито в цялата история е, че не мога да убедя браузъра ми да не слага &#8222;charset&#8220; и вероятно заради това blob-а пристига в съвсем друг вид. За това пък решението е доста лесно &#8211; кодиране на бинарните данни в base64. Неприятно е, че request-а ще набъбне с 1/3 повече и ще трябва да отворите и decode-нете файла сами. На теория декодирането на файла трябва да стане автоматично с <em>Content-Transfer-Encoding </em>директива, но на практика не стана <img src='http://dailyffs.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Удачно е да ползвате този подход не само при гореописания проблем, но и винаги, когато пращате индустриални количества бинарни данни, защото получаването на файл е по-бързо и ангажира по-малко ресурси отколкото получаването на данните като параметър.  Поне така ми се струва <img src='http://dailyffs.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> </p>
<p><a href="http://dailyffs.com/wp-content/uploads/2011/07/ajax.jpg"><img class="aligncenter size-full wp-image-895" title="ajax" src="http://dailyffs.com/wp-content/uploads/2011/07/ajax.jpg" alt="" width="300" height="404" /></a></p>
<p><em>П.П. Преди да имплементирам алтернативното решение се помъчих да увелича лимита на размера на POST заявките с конфигуриране на .htaccess и ini_set на разни магически PHP параметри, но непотръгна.</em></p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/upload-blob-as-file-ajax/' addthis:title='Upload на blob като файл чрез AJAX '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/upload-blob-as-file-ajax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mandelbrot + Web Workers</title>
		<link>http://dailyffs.com/2011/mandelbrot-web-workers/</link>
		<comments>http://dailyffs.com/2011/mandelbrot-web-workers/#comments</comments>
		<pubDate>Mon, 13 Jun 2011 19:28:20 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[mandelbrot]]></category>
		<category><![CDATA[webworkers]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=860</guid>
		<description><![CDATA[Обичам фрактална графика и поради липса на по-смислено занимание тези дни, реших да напиша визуализатор за Mandelbrot. Имплементацията ползва готините Web Workers, за да се справи с тоновете сметки и Canvas за да изобрази резултатът на екрана.

48 web worker-a се борят да запълнят 800х600 пиксела пространство и да си призная се справят по-добре от очакваното... е, все още си е бавно, но е 48 пъти по-добре отколкото без възможност за паралелно изпълнение на алгоритъма :D.<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/mandelbrot-web-workers/' addthis:title='Mandelbrot + Web Workers '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://dailyffs.com/mandelbrot/"><img class="aligncenter" title="Mandelbrot + Web Workers" src="http://screenshoot.me/Ao7vyS" alt="" width="531" height="422" /></a></p>
<p>Обичам фрактална графика и поради липса на по-смислено занимание тези дни, реших да напиша визуализатор за <a href="http://en.wikipedia.org/wiki/Mandelbrot_set">Mandelbrot</a>. Имплементацията ползва готините <a href="http://www.whatwg.org/specs/web-workers/current-work/">Web Workers</a>, за да се справи с тоновете сметки и <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html">Canvas</a> за да изобрази резултатът на екрана.</p>
<p>48 web worker-a се борят да запълнят 800х600 пиксела пространство и да си призная се справят по-добре от очакваното&#8230; е, все още си е бавно, но е 48 пъти по-добре отколкото без възможност за паралелно изпълнение на алгоритъма <img src='http://dailyffs.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> .</p>
<p><strong>Резултатът може да видите тук &#8211; <a href="http://dailyffs.com/mandelbrot/">http://dailyffs.com/mandelbrot/</a></strong></p>
<p><strong>А кодът е достъпен тук &#8211; <a href="https://gist.github.com/1023445">https://gist.github.com/1023445</a></strong></p>
<p><em>Забележка: работи само с Firefox, защото другите браузъри или нямат web workers или не поддържат предаването на по-сложни обекти от/към worker-ите. </em></p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/mandelbrot-web-workers/' addthis:title='Mandelbrot + Web Workers '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/mandelbrot-web-workers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jslinux</title>
		<link>http://dailyffs.com/2011/jslinux/</link>
		<comments>http://dailyffs.com/2011/jslinux/#comments</comments>
		<pubDate>Tue, 17 May 2011 13:56:53 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=808</guid>
		<description><![CDATA[Не съм сигурен как точно работи това, но очевидно javascript енджините вече са ненормално бързи, за да е възможно емиулирането на операционна система в браузър. Ако още не вярвате, най-добре го разгледайте сами - http://bellard.org/jslinux/

Let the time of browser-based VMs begin!<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/jslinux/' addthis:title='jslinux '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>How cool is that&#8230;</p>
<p><img class="aligncenter" title="Javascript Linux" src="http://screenshoot.me/cIWZtD" alt="" width="710" height="388" /></p>
<p>Не съм сигурен как точно работи това, но очевидно javascript енджините вече са ненормално бързи, за да е възможно емиулирането на операционна система в браузър. Ако още не вярвате на очите си, най-добре го разгледайте сами &#8211; <a href="http://bellard.org/jslinux/">http://bellard.org/jslinux/</a></p>
<p><em>Let the time of browser-based VMs begin!</em></p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/jslinux/' addthis:title='jslinux '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/jslinux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learn to love Javascript</title>
		<link>http://dailyffs.com/2011/learn-to-love-javascript/</link>
		<comments>http://dailyffs.com/2011/learn-to-love-javascript/#comments</comments>
		<pubDate>Sat, 14 May 2011 10:43:34 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Google IO]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=802</guid>
		<description><![CDATA[Дойде това време от годината, когато човек може да се наслади на изобилие от качествени презентации, благодарение на Google IO. Първото видео, което изгледах беше от Alex Russell, който говори за бъдещия стандарт на Javascript - Harmony.<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/learn-to-love-javascript/' addthis:title='Learn to love Javascript '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p><object width="500" height="306"><param name="movie" value="http://www.youtube.com/v/seX7jYI96GE?version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/seX7jYI96GE?version=3" type="application/x-shockwave-flash" width="500" height="306" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>Дойде това време от годината, когато човек може да се наслади на изобилие от качествени презентации, благодарение на Google IO. Първото видео, което изгледах беше от <a href="http://www.linkedin.com/pub/alex-russell/0/842/320">Alex Russell</a>, който говори за бъдещия стандарт на Javascript &#8211; <a href="http://en.wikipedia.org/wiki/ECMAScript#Future_development">Harmony</a>. Harmony ще направи опит да очовечи езика, чрез оператори и похвати, които са дефакто-стандарт на повечето функционалните скриптови езици. Все пак не става дума за кардинална промяна, а за &#8222;захаросване&#8220; на синтаксиса, така че кодът написан за предни версии на езика да си е напълно валиден.</p>
<p>Както и да е, това не е най-интересното от презентацията. Най-интересното от нея е едно изречение, което характеризира перфектно Javascript и очертава основното различие между този език и останалите скриптови езици:</p>
<blockquote><p>You don&#8217;t create classes that are state with behaivour attached,<br />
you create behaivour that holds the state that it needs.</p></blockquote>
<p>Enjoy <img src='http://dailyffs.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><img class="aligncenter" title="javascript" src="http://webtablab.com/wp-content/uploads/2011/02/best-javascript-resources1.jpg" alt="" width="437" height="352" /></p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/learn-to-love-javascript/' addthis:title='Learn to love Javascript '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/learn-to-love-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django за ненормални хора</title>
		<link>http://dailyffs.com/2011/django/</link>
		<comments>http://dailyffs.com/2011/django/#comments</comments>
		<pubDate>Wed, 11 May 2011 20:07:50 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[metaclasses]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=788</guid>
		<description><![CDATA[Какво ще направите ако ви трябва динамично създаден модел?

Първосигналното решение е да създадете класа на модела и под него да добавяте полетата. Това е погрешно поради ред причини, но най-основната е, че базовия клас на моделите (models.Model) се създава посредством метаклас (models.base.ModelBase), който е отговорен за магиите под капака и веднъж щом е създаден класа няма как да добавяте нови атрибути и магиите да сработят с тях.<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/django/' addthis:title='Django за ненормални хора '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p><em>Говорим за Python 2.5+ и Django</em> 1.2+</p>
<p>Какво ще направите ако ви трябва динамично създаден модел?</p>
<p>Първосигналното решение е да създадете класа на модела и под него да добавяте полетата. Това е погрешно поради ред причини, но най-основната е, че базовия клас на моделите (models.Model) се създава посредством метаклас (models.base.ModelBase), който е отговорен за магиите под капака и веднъж щом е създаден класа няма как да добавяте нови атрибути и магиите да сработят с тях.</p>
<p>Второсигналното решение е да създадете наследник на метакласа, който да е отговорен за динамичното създаване на желания модел. Това е доста по-елегантно и в стила на Python, а и ще можете да използвате метакласове най-накрая и да се похвалите на приятелите си <img src='http://dailyffs.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> .</p>
<pre class="brush: python; title: ; notranslate">

class MetaDynamicData(models.base.ModelBase):

 def __new__(cls, name, bases, attrs):

   newattrs = {'__module__': 'myapp.models'}

   # Да речем, че искате да добавите динамично по един атрибут за всеки месец
   months = [datetime.datetime(2000, x, 1).strftime('%b').lower() for x in range(1, 13)]
   for m in months:
     newattrs[m] = models.IntegerField()

   return super(MetaDynamicData, cls).__new__(cls, name, (models.Model,), newattrs)

class DynamicData(models.Model):
 &quot;&quot;&quot;
 Dynamic data is cool!
 &quot;&quot;&quot;
 __metaclass__ = MetaDynamicData
</pre>
<p>Ако не сте чували за метакласове, най-добре си прочетете <a href="http://docs.python.org/reference/datamodel.html#customizing-class-creation">документацията</a>, за да разберете какво се случва.</p>
<p>Дотук добре, но какво става ако използвате <a href="http://sphinx.pocoo.org/">Sphinx</a>, за да си генерирате автоматично документация за кода?!<br />
Рано или късно ще забележите, че документацията за DynamicData липсва. Липсва, защото Python държи описанието на всеки обект (за по-просто <em>docstring</em>) в магическия атрибут __doc__, а класът DynamicData се генерира динамично от метаклас. За това е нужно да създадем docstring-a в __new__ на метакласа.</p>
<pre class="brush: python; title: ; notranslate">

class MetaDynamicData(models.base.ModelBase):

 def __new__(cls, name, bases, attrs):

   newattrs = {'__module__': 'myapp.models'}

   newattrs['__doc__'] = &quot;Dynamic data is cool!&quot;

   # Да речем, че искате да добавите динамично по един атрибут за всеки месец
   months = [datetime.datetime(2000, x, 1).strftime('%b').lower() for x in range(1, 13)]
   for m in months:
     newattrs[m] = models.IntegerField()

   return super(MetaDynamicData, cls).__new__(cls, name, (models.Model,), newattrs)

class DynamicData(models.Model):

 __metaclass__ = MetaDynamicData
</pre>
<p>Сега вече всичко ще е наред и ще може да се похвалите на приятелите си, че знаете какво е <em>__doc__</em>, което ви отрежда място в челната петица на най-образованите Python програмисти и завинаги ви прави по-skilled, от който и да е PHP програмист (самият факт, че пишете на Python стига, май).</p>
<p><em>За съжаление Джанго не е кръстен на този филм, но пък е горе-долу толкова силен&#8230;<br />
</em></p>
<p><object width="500" height="400"><param name="movie" value="http://www.youtube.com/v/w8Ge2hmSTbo?version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/w8Ge2hmSTbo?version=3" type="application/x-shockwave-flash" width="500" height="400" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/django/' addthis:title='Django за ненормални хора '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ontwik</title>
		<link>http://dailyffs.com/2011/ontwik/</link>
		<comments>http://dailyffs.com/2011/ontwik/#comments</comments>
		<pubDate>Tue, 11 Jan 2011 09:38:30 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[Конференция]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=720</guid>
		<description><![CDATA[Ако сте мързелив програмист и не обичате да четете книги или пък харесвате dev конференции и искате да слушате лекции на любимите си гурута, то на драго сърце ще ви препоръчам Ontwik.<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/ontwik/' addthis:title='Ontwik '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>Ако сте мързелив програмист и не обичате да четете книги или пък харесвате dev конференции и искате да слушате лекции на любимите си гурута, то на драго сърце ще ви препоръчам <a href="http://ontwik.com/" target="_blank">Ontwik</a>.</p>
<p><a href="http://dailyffs.com/wp-content/uploads/2011/01/ontwik.png"><img class="aligncenter size-full wp-image-721" title="ontwik" src="http://dailyffs.com/wp-content/uploads/2011/01/ontwik.png" alt="" width="481" height="152" /></a></p>
<p><a href="http://ontwik.com/" target="_blank">Ontwik</a> е сайт, който събира в себе си записи от различни конференции на web тематика и дава възможност на всеки да ги гледа&#8230; безплатно. Темите, които следя са предимно Javascript, Ruby, Rails, Python, Django, Git, HTML5, но има още много други. Голямата част от лекциите са наистина качествени и интересни, като има записи на web гурута като David Hansson &#8211; създателят на Rails,  Tom Werner &#8211; един от създателите на Github, Линус Торвалдс, Brendan Eich &#8211; създателят на Javascript, и още много други.</p>
<p>Оставям ви с една много готина презентация на David Hansson:<br />
<iframe src="http://player.vimeo.com/video/17420638" width="601" height="338" frameborder="0"></iframe>
<p><a href="http://vimeo.com/17420638">&#8222;Why Ruby?&#8220; &#8211; RubyConf X Keynote</a> from <a href="http://vimeo.com/user2454935">David Heinemeier Hansson</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2011/ontwik/' addthis:title='Ontwik '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2011/ontwik/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Firefox 4 идва без WebSockets</title>
		<link>http://dailyffs.com/2010/firefox-4-comes-without-websockets/</link>
		<comments>http://dailyffs.com/2010/firefox-4-comes-without-websockets/#comments</comments>
		<pubDate>Wed, 08 Dec 2010 11:49:50 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Firefox]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[WebSockets]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=695</guid>
		<description><![CDATA[За съжаление най-якият фичър на HTML5 - WebSockets ще бъде изключен по подразбиране от Firefox 4. Причините са евентуални пробиви на сигурността в проксита и всичко, което е между браузъра и крайния сървър.<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2010/firefox-4-comes-without-websockets/' addthis:title='Firefox 4 идва без WebSockets '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>За съжаление най-якият фичър на HTML5 &#8211; WebSockets ще бъде изключен по подразбиране от Firefox 4. Причините са евентуални пробиви на сигурността в проксита и всичко, което е между браузъра и крайния сървър.</p>
<p>Тестове показват, че е напълно възможно да се създаде proxy cache poisoning (да се вкара вреден код в кеша на проксито), защото прокситат не разбират от Upgrade handshake-а, който WebSockets ползва. Това дефакто е проблем на прокситата, а не на протокола на WebSocket-ите, но за жалост не е възможно да се оправят всички прокси сървъри по света <img src='http://dailyffs.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> , за това се налага да се префасонира протокола на сокетите <img src='http://dailyffs.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> . Препоръката за сега е да се промени стандарта и да се полза CONNECT handshake-a вместо Upgrade handshake, тъй като прокситата го интерпретират правилно.</p>
<p>Най-вероятно няма да видим WebSocket-и във Firefox скоро, поне докато проблемът не бъде разрешен и стандартът не дефинира нов метод за handshake.</p>
<p>Повече подробности може да прочетете на <a href="http://www.0xdeadbeef.com/weblog/2010/12/disabling-websockets-for-firefox-4/" target="_blank">http://www.0xdeadbeef.com/weblog/2010/12/disabling-websockets-for-firefox-4/</a> и <a href="http://www.ietf.org/mail-archive/web/hybi/current/msg04744.html" target="_blank">http://www.ietf.org/mail-archive/web/hybi/current/msg04744.html</a></p>
<p><strong>Update:</strong> Opera спира поддръжката на WebSockets също &#8211; <a href="http://annevankesteren.nl/2010/12/websocket-protocol-vulnerability" target="_blank">http://annevankesteren.nl/2010/12/websocket-protocol-vulnerability</a></p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2010/firefox-4-comes-without-websockets/' addthis:title='Firefox 4 идва без WebSockets '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2010/firefox-4-comes-without-websockets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Блогът ми е нов</title>
		<link>http://dailyffs.com/2010/blogat-mi-e-no/</link>
		<comments>http://dailyffs.com/2010/blogat-mi-e-no/#comments</comments>
		<pubDate>Wed, 01 Dec 2010 01:02:15 +0000</pubDate>
		<dc:creator>Lucho</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Социални]]></category>
		<category><![CDATA[lolcats]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[тема]]></category>

		<guid isPermaLink="false">http://dailyffs.com/?p=681</guid>
		<description><![CDATA[Избрах темата Stardust 2.7 от Tommaso Baldovino и определено съм доволен, макар че тя няма възможност за лесно настройване (т.е. трябва да се бърка по кода). Досега не вярвах, че червено, черно и бяло могат да се съчетаят толкова добре в композиция. В резултат дизайнът е приятен, минималистичен, същевременно и малко агресивен.<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2010/blogat-mi-e-no/' addthis:title='Блогът ми е нов '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>&#8230; с нова визия по-точно.</p>
<p>Избрах темата Stardust 2.7 от <a title="Интернет страницата на автора" href="http://www.tomstardust.com/">Tommaso Baldovino</a> и определено съм доволен, макар че тя няма възможност за лесно настройване (т.е. трябва да се бърка по кода). Досега не вярвах, че червено, черно и бяло могат да се съчетаят толкова добре в композиция. В резултат дизайнът е приятен, минималистичен, същевременно и малко агресивен.</p>
<p>Но една хубава тема е нищо&#8230;</p>
<p style="text-align: center;"><img class="alignnone" src="http://arkarthick.com/wp-content/uploads/2010/10/lolcat-reading-blog-comments.jpg" alt="" width="520" height="360" /></p>
<p style="text-align: center;">
<p>&#8230; ако е с неподходящи шрифтове.</p>
<p>Sans-serif е много хубава фамилия от шрифтове за четене, но не изглежда добре при по-големи размери &#8211; например за заглавия. Затова и реших, че е време да опитам <a href="http://code.google.com/webfonts" target="_blank">Google Fonts API-то</a> и да сложа някакви по-разчупени и приятни букви. За моя изненада Google Fonts поддържа цели 4 кирилски шрифта, което несъмнено е повече от 0, за което съм благодарен.</p>
<p style="text-align: center;"><img class="aligncenter" src="http://icanhascheezburger.files.wordpress.com/2009/03/funny-pictures-cat-is-excited-you-got-him-a-nice-butt-warmer.jpg" alt="" width="363" height="508" /></p>
<p>Избрах <a href="http://code.google.com/webfonts/family?family=Neucha&amp;subset=cyrillic" target="_blank">Neucha</a>, който изглеждаше най-шантав и някак си се вписа добре в създалата се обстановка. Най-странното е, че си пасна и с Arial, който оставих за текстовете с нормална големина и менютата. Дано само да не се появят много уеб специалисти, които да ми обясняват колко е лошо да имаш 2 или повече шрифта на една страница <img src='http://dailyffs.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p>За внедряването на Google Fonts ползвах помощта на <a href="http://adrian3.com/projects/wordpress-plugins/wordpress-google-fonts-plugin/" target="_blank">WordPress Google Fonts plugin</a>, но все пак ми се наложи да пипам и по CSS-а, така че не мога да го препоръчам с чиста съвест.</p>
<p>Препратките към социални мрежи (горе в дясно) изкопирах и преработих от <a href="http://forums.idontlikethisgame.com/viewforum.php?f=3"><strong>Social Media Widget</strong></a>, тъй като не намерих нещо, което да ми свърши работа отраз. Може би аз не мога да търся, а може би и няма как да се добавят такива иконки в хедъра, ако това не е предвидено в самата тема.</p>
<p style="text-align: center;"><a href="http://dailyffs.com/wp-content/uploads/2010/12/lolrus_kthxbye.jpg"><img class="aligncenter size-full wp-image-686" title="lolrus_kthxbye" src="http://dailyffs.com/wp-content/uploads/2010/12/lolrus_kthxbye.jpg" alt="" width="575" height="404" /></a></p>
<p style="text-align: left;">И за финал &#8211; вероятно се питате защо статията е придружена от снимки на котки (и морж) с надписи. Ами няма конкретна причина, просто са забавни и ако са ви харесали, може да намерите още в сайта на <a href="http://icanhascheezburger.com/" target="_blank">Lolcats</a> <img src='http://dailyffs.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://dailyffs.com/2010/blogat-mi-e-no/' addthis:title='Блогът ми е нов '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://dailyffs.com/2010/blogat-mi-e-no/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

