Локальные переменные и JS

Читал тут по диагонали стандарт ECMAScript и подумалось мне, что сэмулировать локальные переменные (да, я осознаю, что это свойства объекта) можно вот так:

var a = 10;
with ( { a : 20 }) {
    alert(a);
}
alert(a);

Ожидаемый результат: сначала код выведет «20», потом — «10». Я ещё не задумывался над тем насколько это практично и изящно, просто придумалось.

Кстати, обратите внимание, что следующий код выведет «30», «30», «10», «30»:

var a = 10, b = 10;

with ({a:20}) {
    var a = 30, b = 30;
    alert(a);
    alert(b);
}

alert(a);
alert(b);

Добавлено 10 ноября 10:55: в комментариях почему-то подумали, что я не знаю о лексических замыканиях. Знаю, конечно.

6 комментариев

Полезные rgba в IE

Вадим Макишвили описал несколько примеров применения rgba в Internet Explorer. Примеры очень и очень полезны, и я скопирую их (без картинок, за ними идите в исходный пост) к себе:

Сегодня, благодаря этому новому знанию, я понял как решить две труднорешаемые задачи. Издавна, чтобы сделать фон блока полупрозрачным, мы вынуждены были использовать или png-24 картинку в фоне или opacity-свойство.

Но в случае с png-24, для ИЕ6 нужно писать AlphaImageLoader фильтр, который катастрофически замедляет рендеринг страницы. А в случае с opacity приходилось придумывать трюки, чтобы дети блока не бледнели от родительского opacity.

А теперь проблему opacity можно забыть, как страшный сон: .block { background: #rgba } * html .block { filter:progid:DXImageTransform.Microsoft.gradient (startColorstr=#99000000, endColorstr=#99000000); }

В начальной и конечной позиции один и тот же RGB (000000) и добавляю перед ним одно и то же значение Alpha (99) Значение Alpha указывается в 16-тиричной системе, где 00 — полностью прозрачный, а ff — непрозрачный пиксел

Я протестировал скорость рендеринга страницы, на которой выливается 300 элементов с gradient-фильтром — он не замедляет рендеринг и это сильно радует.

Но этот случай описывает ситуацию, когда нужно сделать однотонный полупрозрачный цвет, как например в модальных диалогах, когда вся остальная страница затемняется.

Иногда использовать png-24 всё-таки необходимо, как например в случае, когда нужно обрезать длинную неразрывную строку, уводя ее градиентом в непрозрачность.

В этом случае можно использовать второй способ. .block { background: url(image.png) } * html .block { filter:progid:DXImageTransform.Microsoft.gradient (startColorstr=#00ffffff, endColorstr=#ffffffff, GradientType=1); }

GradientType принимает значение 1, если градиент рисуется слева-направо; и 0, если градиент сверху-вниз.

MSIE хороший браузер.

7 комментариев

Компрессоры JavaScript и точка с запятой

Точка с запятой — один байт, перевод строки — один байт. Мне тут подумал, что лучше бы компрессоры JS выкидывали при сжатии не переводы строки, а точки с запятой (там где это возможно, конечно, например, пустой return в некоторых случаях нельзя завершить только переводом строки).

Тогда читаемость кода почти не снижалась бы (об обфускатарах я сейчас не говорю) и можно было бы легко понять где произошла ошибка, пропущенная в production (такое случается).

14 комментариев

Сколько нужно людей, чтобы получился Chrome

Бобук рассказывает про количество людей, имеющих отношение к появлению Chrome:

Итого, представь себе что 10 миллионов долларов в акциях размазывается между разработчиками проекта. Такие небольшие проекты как Chrome в гугле затрагивают очень небольшую группу, скажем всего 500-600 человек разработчиков, 50-100 дизайнеров, 200-300 маркетологов, под сотню админов, сотня менеджеров. Итого на нос получается в пике 10 тысяч на лицо. Теперь подумай, что такое в Калифорнии 10 тысяч долларов _В АКЦИЯХ_, т. е. после реализации акций и уплаты налогов — у тебя на руках 5 тыщ долларов.

В ответ на вопрос откуда информация и по поводу численности:

Про команду разработки? Есть некотрые инсайдеры. Не, вообще команда разработки там примерно в 3 раза меньше, но есть же масса людей, которые учавствуют в проекте «парттайм», а доля будет такая же, как и у тех кто работал только над ним.

После недавней фразы Брина «мы ведем исследования небольшими группами по 200-300 человек», я уже ничему не удивляюсь.

Почти тысяча человек даже в самом минимальном случае!

13 комментариев

В Казань

Вылетаю сегодня (3 ноября) в Казань, в воскресенье (8 ноября) — назад.

Оставить комментарий

Web Standards Days

27 и 28 ноября (может и на выходные останусь, как срастётся) еду в Минск на «Web Standards Days».

2 комментария

IE и rgba

Век живи, век учись. Оказывается, в Internet Explorer есть возможность, через фильтры, указывать rgba-цвет:

.element{
    /*color = black, opacity = 0.6 */
    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000,endColorstr=#99000000); /*AARRGGBB*/
    zoom: 1
}

Большая часть фильтров понимает цвет в формате argb (первая компонента — прозрачность).

4 комментария

Сколько памяти съела программа на Python?

Некоторое время назад мне хотелось выяснить, сколько съедает памяти программа на Python и чем эта память занята. Тогда я не смог быстро найти решение и обошёлся без него, а вчера, совершенно случайно, наткнулся на целых два.

Приведу их у себя полностью, чтобы потом можно было быстро найти.

Следующий код (используется модуль Heapy):

from guppy import hpy
h = hpy()
print h.heap()

выведет вот такую, достаточно информативную, табличку:

Partition of a set of 132527 objects. Total size = 8301532 bytes.
Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
0  35144  27  2140412  26   2140412  26 str
1  38397  29  1309020  16   3449432  42 tuple
2    530   0   739856   9   4189288  50 dict (no owner)

Другое решение — использовать Dowser, его интересная особенность — можно наблюдать за работающим кодом через веб-браузер.

# memdebug.py

import cherrypy
import dowser

def start(port):
    cherrypy.tree.mount(dowser.Root())
    cherrypy.config.update({
        'environment': 'embedded',
        'server.socket_port': port
    })
    cherrypy.server.quickstart()
    cherrypy.engine.start(blocking=False)

Подключаем в программу memdebug и вызываем memdebug.start.

Там же упоминается модуль PySizer, но его автор забросил работу и рекомендует использовать Heapy.

Оставить комментарий

Штанга: стоп, машина

Решил одуматься и остановить погоню за весом. Сейчас я без выпученных глаз и льющейся крови из ушей могу взять 100,5 кг, но это вряд ли можно назвать рабочим весом. Остановлюсь. Решил тренировать выносливость, увеличивать число подъёмов, а не вес, потренирую суставы, кости и сердце.

Сегодня три раза за день играл в «лесенку», последний раз выглядит вот так (с минимальными паузами): 68×6, 98×2, 88×2, 78×2, 68x6, 68×6, удерживание 68 кг — 40 секунд, удерживание 68 кг — 40 секунд, 68×6, 68×6.

Оставить комментарий

Какой Минск

Смотрел билеты в Минск на 27-е ноября на сайте авиакомпании «ЮТэйр». И давно его нет?

Минск? Нет такого? (13.25КиБ)

7 комментариев

Batch-запуск

Пока писал книгу, часто приходилось пропускать по нескольку сотен, а то и тысяч картинок через различные программы-оптимизаторы. Хорошо, когда эти программы имеют пакетный режим, а если нет? Выход, в общем-то простой — подумать какую последовательность кнопок надо жать в программе, чтобы оптимизировать всю папку с файлами и как-то запрограммировать нажатие.

Я пользовался для этой цели Windows Script Host, описывал что нужно жать на языке JScript. Вот, например, обрабатываются 492 изображения программой «A Smaller GIF 1.22»:

with (WScript.CreateObject("WScript.Shell")) {
    AppActivate("A Smaller GIF 1.22")

    for (var command, j = 0; j<492; j++) {
        WScript.sleep(100)

        for (command = '^O+{TAB}{DOWN}{UP}', i = 0; i<j; i++) {
            command += '{DOWN}'
        }

        SendKeys(command+'{ENTER}^S')
        WScript.sleep(100)
        SendKeys('{ENTER}')
    }
}

Всё понятно, по-моему, почти по-английски написано. О том как отсылать приложению специфические комбинации (например, Ctrl+Alt+Backspace) можно прочитать в на сайте MSDN.

7 комментариев

Когда летим?

Transaero (30.13КиБ)

Экран выбора дня вылета и класса обслуживания сайта авиакомпании «Трансаэро», угадаете с первого раза в какой день вылет? Вы уверены?

10 комментариев

Подводная река

Подводная река (39.98КиБ)

Красиво — фотография Анатолия Белощина, сделана под водой, в Мексике, на глубине 28 метров, «река», над которой видно дайвера — это течёт сероводород (обязательно посмотрите оригинал).

3 комментария

iPhone и снимки с GPS

iPhone, который, не спрашивая, записывает в снимок информацию с GPS, чувствую, доставит ещё немало лулзов в интернетах. Одна тётечка, сфоткавшись обнажённой, уже спалилась — координаты есть, дом на Google Maps видно, тем более, что он частный. И это только начало.

14 комментариев

«Консультант» и IE

Вчера на «Хабре» люди в очередной раз подняли тему сайта «Консультанта» и Internet Explorer — первый, своей интересной частью, работает только на втором. Как я и ожидал, код завязан на особенности Internet Explorer, браузер богатый на возможности, на сайте использовано их немало. Впрочем, всё, если вдуматься, переводится и на более стандартные рельсы.

У меня давно руки чесались разобраться поподробнее как устроены userjs в «Опере» и посмотреть на отличия реализации XSLT-процессинга в IE и остальных браузерах. Userjs в «Опере» устроены исключительно удобно (даже предусмотрели патчи к выполняемому коду), а с XSLT в IE нестандартно, зато много проще.

По результатам появился userjs, который позволяет увидеть две первые страницы базы «Консультанта» в «Опере», если кому-нибудь хочется, допилите его дальше, я это делал исключительно из интереса научиться полезному, сама база мне без надобности.

Текст userjs помещаю под кат.

// ==Userscript==
// @name         Make Consultant base works
// @namespace    /
// @description  Make Consultant base works in non-IE browsers.
// @include      http://base.consultant.ru/*
// @version      1.0
// @licence      MIT
// ==/UserScript==

(function(){

    /* TODO
       saveCard — это behavior userData, сделать эмуляцию
       VBArray  — одна из переменных использует этот специфический массив
       isBaseVisible, ForEachRow — убрать заглушку, сделать нормальную функцию
       showModalDialog — дописать с передачей параметров (например, через window.name)
    */


    document.addEventListener('load', function (e) {
        showModalDialog = window.open;

        return true;
    }, false);

    DOMParser.prototype.loadXML = function (text) {
        return this.parseFromString(text,"text/xml")
    }

    opera.addEventListener('BeforeScript', 
        function(e){
                if (e.element.getAttribute('for')) {
                    var script = e.element.text
                    var id     = e.element.getAttribute('for')
                    var ev     = e.element.getAttribute('event')

                    e.element.text = ''
                    document.addEventListener('load', new Function('',                     
                        'document.getElementById("' + id +
                        '").attachEvent("' + ev +
                        '", function () {'+ script + '})'
                    ))
                }

                var repl = {
                    'document\\.body\\.attachEvent'   : 'document.attachEvent',
                    'document\\.all\\.fieldsXML\\.XMLDocument\\.transformNode': 'document.transformNode',
                    'document\\.all'                  : 'document.getElementsByTagName("*")',
                    'document\\.frames\\('            : 'document.getElementsByTagName("iframe").item(',
                    '\\.XMLDocument\\.text'           : '.textContent',
                    'document\\.body'                 : 'document.documentElement',
                    '\\.parentElement'                : '.parentNode',
                    '\\.XMLDocument\\.documentElement': '',
                    '\\.XMLDocument'                  : '',
                    'basesRow\\.all\\.basesTable'     : 'document.getElementById("basesTable")',
                    '\\.all\\.tags\\('                : '.getElementsByTagName(',
                    '\\.all\\.([^\\.;\\s]+)'          : '.getElementById("$1")',
                    '\\.all\\('                       : '.getElementById(',
                    '\\w+\\.getElementById'           : 'document.getElementById',
                    'p\\.type\\.'                     : 'p.getAttribute("type").',
                    '\\.isEnabled\\s*=([^;]+)'        : '.setAttribute("isEnabled", $1)',
                    '\\.isEnabled'                    : '.getAttribute("isEnabled")',
                    '(\\w+)\\.loadXML'                : '$1=$1.loadXML',
                }

                for (var re in repl) {
                    e.element.text = e.element.text.replace(new RegExp(re, 'g'), repl[re])
                }
            }
        ,false);

    opera.defineMagicFunction('writeInsertion', function () {});

    opera.defineMagicFunction('getBasesTable', function (a, b, tDivRow) {

        var basesRow = tDivRow && tDivRow.id ? document.getElementById("bases_" + tDivRow.id) : null;
        return basesRow == null ? null : document.getElementById('basesTable');
    })

    opera.defineMagicFunction('forEachRow', function (a, b) { return true })

    opera.defineMagicFunction('createXMLStylesheet', function (a, b, url) {
        var r = new XMLHttpRequest()
        r.open('GET', url, false)
        r.send(null)

        if (r.status == 200) {
            var xml = new DOMParser()

            return xml.parseFromString(r.responseText, "text/xml")
        }

        return null
    })

    opera.defineMagicFunction('isBaseVisible', function (a, b, code) {
        return true
    })

    HTMLElement.prototype.transformNode = XMLDocument.prototype.transformNode = function (style) {
        var xsltProcessor=new XSLTProcessor();
        xsltProcessor.importStylesheet(style);

        if (typeof this == 'HTMLElement') {
            var resultDocument = (new DOMParser()).parseFromString(this.innerHTML, 'text/xml');
        } else {
            var resultDocument = xsltProcessor.transformToDocument(this);
        }
          
        var xmls = new XMLSerializer();  
        return xmls.serializeToString(resultDocument);
    }

    HTMLHtmlElement.prototype.selectSingleNode = HTMLInputElement.prototype.selectSingleNode = function (path) {
        var xpe = new XPathEvaluator();
        var nsResolver = xpe.createNSResolver(this.ownerDocument == null ? this.documentElement : this.ownerDocument.documentElement);
        var results = xpe.evaluate(path,this,nsResolver,XPathResult.FIRST_ORDERED_NODE_TYPE, null);
        return results.singleNodeValue;
    }

    ActiveXObject = function (str) {
        return new ({
            'Microsoft.XMLDOM':  DOMParser,
            'Microsoft.XMLHTTP': XMLHttpRequest,
            'Scripting.Dictionary': Array,
        })[str]
    }

})()

Кстати, «Опере» нужно не забыть сказать, чтобы она маскировалась под Internet Explorer (правая клавиша мыши, «Настройки сайта», закладка «Сеть»).

Обращаюсь к тем, кто читает RSS и трансляцию, текст userjs по ссылке на исходный пост.

7 комментариев

Lexx

Гори в аду, попсовый доктор Хаус! Осуществляю мечту детства — смотрю полностью «Lexx». Уже посмотрел 13 серий, сериал такой же сумасшедший, каким я его помню с детства.

Сумасшедший, но, в общем-то, туповатый, как и все сериалы: герои влипают в различные ситуации по одним и тем же причинам, ничему не учатся. Если бы они хотя бы не выбрасывали оружие, то влипали куда бы реже. Но зато герои, миры, декорации,.. у авторов абсолютно травокурная фантазия.

18 комментариев

Инч би бэк

Выношу в отдельный пост комментарий хорошо иллюстрирующий мою точку зрения на перевод единиц в книгах на близкую читателю систему мер:

Читаю сейчас «Террор» Дена Симмонса. Про полярников 19-го века, вмерзших в лед на три года за полярным кругом.

800 страниц дюймов, футов, пинт, галлонов, лье, миль и еще уж даже и не помню каких единиц длины, площади, массы и объема. И они там на каждой странице. Это просто разрыв мозга.

При этом, обычно, очень хочется понять:

—убегать от медведя три полных мили — это далеко или нет? —прыжок с тороса, высотой 12 футов — это опасно или нет? —по четверти пинты грога в день — это много или нет? —меньше старого фунта еды на троих — это сколько? —спать до двух склянок — это до скольки? — на пару углов левее — это куда?

Перевод всего этого в уме в метрическую систему ну очень сильно тормозит чтение. А некоторые единицы вообще без справочника непонятны. При этом никакой «игры слов» основанной на цифрах, типа «дюймовочки», там нет. Один только геморрой.

28 комментариев

Сжатие исходящего трафика в браузере

Артель BrowserPlus выпустила плагин к браузеру («Опера», как обычно, не поддерживается, Linux — тоже), который позволяет использовать в браузере TAR и алгоритм сжатия LZMA.

TAR позволяет собрать несколько файлов в один, LZMA — упаковать их. Таким образом, файлы (или другие данные) на сервер можно отсылать уже упакованными. Ценно для заливки больших хорошо сжимаемых (например, текстовых) файлов.

Вообще говоря, работа с TAR и LZMA не единственное, что плагин позволяет делать, там очень много интересных возможностей, лучше посмотреть на сайте производителя. Тенденция, вообще-то, странная, на мой взгляд — выпускать разношестные плагины для браузеров (Google Gears, BrowserPlus) вместо того, чтобы пытаться договориться с W3C о внедрении каких-то возможностей в браузеры.

Я был бы рад увидеть браузерное хранилище от Google во всех браузерах, вместо зоопарка, который мы сейчас имеем, тем более, что этот зоопарк по возможностям сильно не дотягивает до того, что придумали в Google (по правде говоря, я был бы рад увидеть что-то ещё более мощное и интегрированное, чем Google Gears, но, видимо, возможности плагина просто ограничены — не всё можно реализовать как плагин).

4 комментария

Устал

На этой неделе новый вес брать не буду: всю первую половину проболел, вторую — не высыпаюсь, сегодня, как варёный. Куда уж там брать новый вес. Ещё работа вымотала, вроде ничего особенного, но бьюсь третью неделю над той же задачей: как не меняя код (только шаблоны) сделать ЧПУ в Testlink. Приходится много пробовать и откатываться назад, такое всегда выматывает. Ничего, победа будет за мной.

10 комментариев

Windows Powershell

Вчера ночью смотрел на Windows Powershell. Красивый, мощный, удобный язык командной строки («песню о пиве» я уже написал). Очень понравился, изучается очень быстро, позволяет многое. Основная идея — конвееры, по которым ходят не строки (как в Linux/Unix), а объекты. То есть вы можете получить список процессов, отфильтровать их не как текстовые строки, а как набор объектов — по свойствам, дальше, ну, к пример, отсортировать по какому-то свойству и выгрузить в XML.

Очень хорошо называются командлеты, например, «Get-Process», правда, сразу понятно что делает эта команда. Причём, у команд есть алиасы, которые порадуют любителей Unix: можно написать «Get-Help Get-Process» или «man ps». Где «man» — алиас для «Get-Help», «ps» — алиас для «Get-Process».

Язык слаботипизированный, но можно и жёстко задавать тип (например, в параметрах функций), если хочется.

Кардинально решена проблема с безопасностью (язык мощный, сразу спровоцирует написание вирусов) — файлы этого языка (расширение — .ps1) не запускаются, а открываются в блокноте. Запуск команд возможен или из оболочки руками или довольно нетривиальными способами (простой юзер не справится).

12 комментариев