NilColor

Guess what? You're on my site!

Archive for the ‘Tech’ Category

Explain to me what JavaScript is…

without comments

Одно из самых литературных объяснений – “что такое JavaScript и причем тут Java”.

Here is something else you should know about Javascript that seems like it was almost designed to be confusing as possible:

  • There is a programming language called Javascript.
  • There is a programming language called Java.
  • There is an interpreter (‘thing that makes it go’) for the programming language Javascript built into most web browsers
  • There is an interpreter for the programming language Java that is sort of built in to most web browsers, or was.
  • THESE TWO PROGRAMMING LANGUAGES HAVE ALMOST NOTHING TO DO WITH EACH OTHER

Кратко и ёмко. Затрагивается даже история создания JavaScript

So Netscape said to a guy named Brendan, who worked at Netscape, “Please make us a programming language.
Also, you have to call it Javascript.
Also, if you can make some of it kind-of sort-of look a bit like Java, that would be even better.
Also, you have only 10 days to do this so get cracking!”

В общем почитайте.

ɹoןoɔןıu

Written by NilColor

September 14th, 2011 at 3:08 pm

Posted in javascript

Tagged with ,

`!` в имени события

without comments

Следующий код довольно часто можно видеть, если используется библиотека jQuery:

$('#foo')
  .bind('click', function(){ console.log('click event') })
  .bind('click.my', function(){ console.log('click.my event') }); //namespaced event
//потом это обработчики могут вызываться...
console.log('step 1');
$('#foo').trigger('click');
console.log('step 2');
$('#foo').trigger('click.my');

Результатом этих вызовов будет вывод в консоль следующего:

step 1
click event
click.my event
step 2
click.my event

Это хорошо известно, про это написано в доках по jQuery и это понятно. А вот про что там не написано, это про то, что можно написать так:

console.log('step 3');
$('#foo').trigger('click!');

(обратите внимание на восклицательный знак в имени ивента). И вот тогда в консоле мы увидем такое:

step 2
click event

И все. Т.е. вывода click.my event мы не увидим. Если посмотерть в исходники jQuery, то там это выглядит так:

...
if ( type.indexOf("!") >= 0 ) {
    event.type = type = type.slice(0, -1);
    event.exclusive = true;
}
...

т.е. это некий вариант exclusive событий. И этим, в частности, пользуется плагин DataLink, изучение исходников которого (на предмет “переделать для себя”) и всплыло это странное exclusive.

Written by NilColor

February 22nd, 2011 at 5:13 pm

Posted in jquery

Tagged with , ,

Шаблон Node.js сервера

without comments

Если сейчас пойти в поисковик и поискать там что-то типа “как сделать приложение на Node.js”, то там будет много чего… И практически везде будет что-то типа этого: “…ставим Express/Connect, пишем лиснеры…”. Да, можно и так. Но если вам нужно что-то маленькое, простое. Где не хочется подключать лишнего. Или хочется сделать все с нуля… В общем вот простой серверочек, который реагирует на урл http://server/- отвечая “Thanks!”. На остальные урлы он просто отвечает кодом 200.
Глядеть тут, на guthub’е

P.S.
Надо как-то побороть markdown… а то не дает эмбедить gist’ы сюда.

Written by NilColor

February 6th, 2011 at 12:24 am

Posted in Node.js

Tagged with , ,

jQueryUI custom widget

with 3 comments

Куда ж еще записать, как не сюда?
Итак, есть идея – сделать свой виджет для jQueryUI. Почему именно эта библиотека? А не важно. Просто мне она нравится. Итак, виджет. Вот “скелет” для виджета плюс несколько забавностей, на которые я набрел:

(function($, window, document, undefined){
  //handy log function
  window.log = function(){
    log.history = log.history || [];
    log.history.push(arguments);
    if(this.console)
      console.log( Array.prototype.slice.call(arguments) );
  };

  $.extend($.expr[':'], {
    lookup: function(a){return a.getAttribute('t2-ui-role') === 'lookup';}
  });

  var Lookup = {
    options: {
      version: '0',
      icon: 'search'
    },
    currentlyActiveLookup: null,
    _create: function(){
      var self = this,
          el = self.element;
      self.options.icons.primary = self.icon;
      //log('element IS'+(el.jquery?'':' NOT')+' jQuery object');

      $.ui.button.prototype._create.apply(self);

      self._setOption('icons', {
        primary:'ui-icon-'+self.options.icon,
        secondary:null
      });

      el.bind('click', function(e){
        e.preventDefault();
        e.stopPropagation();
        $(e.target).trigger('lookup.t2', {lookup:this});
        self._trigger('activated', null, {lookup:this});
        return false;
      });
    },
    _init: function(){ log('_init'); },
    boom: function(){ log('nice, you boom me!'); }
  };

  $.widget('t2.lookup', $.ui.button, Lookup);//NS doesn't mean something yet

  //====================== RUN CODE HERE ======================
  $('#id_ref_button').button({icons:{primary: "ui-icon-search"}});

  var l1 = $(':lookup').lookup({
    activated: function(e, data){ //tightly coupled
      log('activated callback fired');
      log('  '+data, data.lookup);
    }
  });
  // a-la Observer Pattern
  $('body').bind('lookup.t2', function(e, data){ //loosely coupled v.1
    log('lookup.t2 event catched');
    log('  '+data, data ? data.lookup : 'nope');
  });
  $('body').bind('lookupactivated', function(e, data){ //loosely coupled v.2
    log('lookupactivated event catched');              //why not activated.lookup?
    log('  '+data, data.lookup);
  });

  l1.lookup('boom');

})(jQuery, window, window.document)

Самое странное – это то, как виджет может общаться с внешним миром… Итак, есть конечно стандартный (для пользователей jQuery) способ .trigger(). Ловить такие события можно тоже стандартным способом – .bind(). Тут вроде все просто и все понятно. Далее, jQueryUI предлагает свой способ: this._trigger(type, event, data). Где первый параметр это имя события, второй – это jQuery.Even object. Третий – это что-то, что вы еще хотите передать в это событие. Учтите, что третий параметр передается используя .apply(), так что если там будет массив — он развернется в список аргументов. Это влияет на то, как писать сигнатуру колбэка и обсервера событий
А вот такие события уже можно ловить 2мя способами:

  1. callback — .lookup({ activated: function(){} })
  2. observer — .bind('lookupactivated', function(){} )

Мне больше нравится второй вариант. Во-первых, Event Bubbling позволяет навесить обработчик на контейнер, где эти виджеты появляются и убрать код из инициализации этих виджетов при получении данных с помощью AJAX. Во-вторых это просто красиво.
Единственный тут минус – это название этого события… Оно строится самим jQueryUI и представляет собой widget_name + event_nameбез точек и пробелов… Ну… зато плюсы хороши и приятны. Среди плюсов также то, что третий параметр для данного способа не развернется (в случае, если это массив) в аргументы.
Кстати, в данном примере я “наследовался” от уже существующего виджета $.ui.button, но если без этого – просто не указывайте второй параметр при регистрации виджета $.widget('t2.lookup', $.ui.button, Lookup);. Кстати, namespace, указываемый при регистрации ничего не значит. По крайней мере пока ничего. Так что можно делать свой или использовать тот, что использует сама jQueryUI ($.widget('ui.lookup', Lookup);) — выбирайте сами. Как это все работает и вообще попробовать самому можно на мега полезном ресурсе JSBin.

P.S.
Надо бы кстати написать про мега удобный кусок кода… В след. раз.

(function($, window, document, undefined){
  //code goes here
})(jQuery, window, window.document)

(:

Written by NilColor

October 11th, 2010 at 4:12 pm

Posted in javascript

Tagged with , , , ,

Userscript для Fluid(ium) + GMail

with one comment

Обновился Fluid.app. Теперь он сделан на базе Fluidium. Пока это бета, но я ей пользуюсь. Минус один – бадж количества не прочитанных писем перестал показываться. Для этого нужен userscript. Вот тот, что я написал для себя:

(function () {
    setInterval(update, 5000);

    function update() {
        var links = document.getElementById('canvas_frame')
            .contentDocument.getElementsByTagName('a');
        var len = links.length;

        for (var i=0; i < len; i++) {
            var str = links[i].getAttribute('href');
            if (/#inbox$/.test(str)) {
                var matches = links[i].textContent.match(/\(([0-9]+)\)/),
                    str = '';
                if (matches && matches.length > 1) {
                    str = matches[1];
                }
                window.fluid.dockBadge = str;
            }
        }
    }
})();

Пробуйте, если что не так – дайте знать ;)

Written by NilColor

May 7th, 2010 at 3:06 pm

Posted in javascript

Tagged with , , ,

VMWare Fusion vmrun

without comments

Очень хорошая надо сказать утилитка, эта vmrun.
Находится сие тут — /Library/Application\ Support/VMware\ Fusion/vmrun. Так как писать это долго и вообще, делаем линк ln -s /Library/Application\ Support/VMware\ Fusion/vmrun /usr/local/bin/vmrun. Путь тоже не супер короткий, зато его можно не писать. Итак, поехали!

$ vmrun 
vmrun version 3.0.0 build-204229

Usage: vmrun [AUTHENTICATION-FLAGS] COMMAND [PARAMETERS]

AUTHENTICATION-FLAGS
--------------------
These must appear before the command and any command parameters.

   -h <hostName>  (not needed for Fusion)
   -P <hostPort>  (not needed for Fusion)
   -T <hostType> (ws|fusion)
   -u <userName in host OS>  (not needed for Fusion)
   -p <password in host OS>  (not needed for Fusion)
   -vp <password for encrypted virtual machine>
   -gu <userName in guest OS>
   -gp <password in guest OS>

POWER COMMANDS           PARAMETERS           DESCRIPTION
--------------           ----------           -----------
start                    Path to vmx file     Start a VM or Team
                         [gui|nogui]

stop                     Path to vmx file     Stop a VM or Team
                         [hard|soft]

reset                    Path to vmx file     Reset a VM or Team
                         [hard|soft]

suspend                  Path to vmx file     Suspend a VM or Team
                         [hard|soft]

pause                    Path to vmx file     Pause a VM

unpause                  Path to vmx file     Unpause a VM
...

Вообще, выдало оно много чего интересного… Мне было интересно это: vmrun start nogui. А значит, что можно запустить свои девелоперские серверочки так, что-бы они не мозолили глаза. Удобно. А делается это так:

$ vmrun -T fusion start /path/to/vm.vmwarevm/vm.vmx nogui

И все. Ваш сервер запущен. Увидеть это можно набрав vmrun list.

$ vmrun list
Total running VMs: 1
/path/to/vm.vmwarevm/vm.vmx
$ 

И на последок, как я себе это чуть упростил. Приведенный ниже код был засунут в ~/.profile и в итоге имеем 3 новых функции: vr, devrun и devstop. Первая — по идее универсальна и по-умолчанию выполняет vmrun list, вторые две очевидны. Код вот:

vr() {
    DEVVM='/Users/user/Virtual Machines/Ubuntu 8.04 dev.vmwarevm/Ubuntu 8.04 dev.vmx'
    if [ -z "$1" ]; then
        vmrun list
        return 0
    fi
    vmrun -T fusion "$1" "$DEVVM" "$2"
}
alias devrun="vr start nogui"
alias devstop="vr stop soft"

Если будут предложения по скрипту — делитесь.

P.S.
Чуть не забыл… так как это headless режим, доступ к виртуалке только через ssh либо VNC. Имейте ввиду и настройте ДО запуска в headless режиме ;)
P.P.S.
Да, не думаю, что запуск VMWare в headless режиме сильно экономит ресурсы компьютера. Я не проверял — у меня это скорее дело истетики. Парой окон меньше и плюс минус (забавно… даже оставлю так: плюс минус) одна иконка в доке. Итак не маленьком доке.

Written by NilColor

November 23rd, 2009 at 10:48 pm

Jabra STONE

without comments

Что-то накрылись мои списки, куда я записывал хотелки… Так что запишу просто сюда.
jabra-stone Jabra STONE. По картинкам и описаниям очень интересная гарнитурка. Ожидаемае цена – 5000р. Предзаказ уже есть в Евросети.


Вторая хотелка уже более из разряда хотелок… И все же:

imac-27 iMac 27″ – без коментариев.


Written by NilColor

October 27th, 2009 at 11:00 am

Posted in hardware

Tagged with , , ,

JavaScript import

without comments

В JavaScript нет директивы import. Хотя она есть даже в css (@import). Но если надо, очень надо, то можно воспользоваться следующей “заменой”

function import (url) {
    var xhr;

    if(window.XMLHttpRequest) {
        xhr = new XMLHttpRequest();
    } else {
        xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }
    if(xhr){
        xhr.open("GET",url,false);
        xhr.send(null);
        eval(xhr.responseText);
    } else {
        return false;
    }
}

Пользоваться довольно просто

import('/path/to/js/file.js');
call_function_from_file_js();

То, что код функции call_function_from_file_js будет доступен, гарантировано синхронностью XMLHttpRequest (3-й параметр). У данного решения есть маленький минус – загруженный код проходит через eval(), его многие считают злом и т.д…. Еще могу возникнуть сложности, если в загружаемом коде есть объявления типа

function foo() {
    //some code
}

Если нарветесь — попробуйте изменить определение функции на

foo = function () {
    //some code
}

Должно помочь.

Written by NilColor

October 20th, 2009 at 9:28 pm

Posted in javascript

Tagged with , , ,

GiftWrap – .deb в легкую

without comments

Было когда-нибуть желание сделать deb-пакет?
Теперь можете это попробовать. Это уже не очень сложно :)

Ролик сразу в HD – делайте на полный экран и тогда видно что и как делается.

Written by NilColor

May 29th, 2009 at 7:01 pm

JavaScript… какой он?

with 5 comments

Есть такая модная штука в наше время — AJAX/JSON/XML/WEB20 и иже с ними… Мне они тоже нравятся. И нравятся настолько, что я и сам этим балуюсь ;) Например сейчас в одном из проектов, небольшом, но очень гордом, я занят тем, что пробую сделать ему, проекту, модное UI, не в смысле дизайна – тут я пас, а в смысле “все ajax-запросам”, json туда, json обратно…
А самое веселое в этом знаете что? Это весело! Это оказалось реально интересно… Придумывать, как же рисовать все это на клиенте, где хранить шаблоны и как их заполнять… Битвы за скорость (вообще отдельная песнь)… Борьба с обработчиками событий, которые по вине их писавшего рвут even bubbling и это аукается где-то: то ссылки перестают кликаться, то в поле ввода ничего нельзя ввести ;)

Сейчас у меня стоит задача придумать, как же быть с шаблонами… Как только будет что-то — расскажу. Пока самая интересная идея это хранить их прям в коде ввиде блоков

<script type="text/html" charset="utf-8" id="tmpl-block-a">
    <div>
        ...
    </div>
</script>

Да да, тут нет ошибки ;) если вдруг вы кинулись писать это в коменте. Способ интересен, хорош и удобен. Но для мелких шаблонов. А если они большие?

Written by NilColor

March 29th, 2009 at 9:39 pm

Posted in ajax,javascript

Tagged with , , , , ,