понедельник, сентября 24, 2007

а ксенофобия всё прогрессирует...

проще перечислить с кем русские не успели разжопиться...

пятница, сентября 21, 2007

\(^_^)/


d(^_^)b - в наушниках

o_0 - офигевший

^,__,^ - вампир

^_^' - смущён

\m/(^_^)\m/ - на пальцах

=^.^= - майский котик

/X\(o.o)/X\ - поучок

^(oo)^ - свинтус

@(*о*)@ - коала

(='_'=) - покемон

>^,,^< - летучая собака

*\o/* - девушка из группы поддержки

(<>..<>) - инопланетянин

__\o/__ - утопающий

(+_+) - трупик

неплохая подборка смайлов:
http://www.itc.ua/article.phtml?ID=13123&IDw=53&pid=21

ещё одна:
http://smayly.net.ru/static/txt.html

вторник, сентября 18, 2007

установка обработчиков событий в javascript

Я уже говорил, что люблю яваскрипт? Если нет, то: "лучше языка я ещё не встречал!". Есть, конечно и недостатки, но многие из них можно обойти...
Но сейчас пойдёт речь не о недостатках, а наоборот, об одном элегантном решении...

Самый простой способ повесить обработчик события - это просто написать:
node.onclick= function( e ){
if( !e ) e= window.event;
alert( e );
}

Метод довольно простой и наглядный, но основной его недостаток - для одного события у одного узла можно назначить только один обработчик, что очень неудобно.

Более сложный способ, лишённый этого недостатка, - это воспользоваться методами addEventListener (DOM) и attachEvent (IE). Например: http://php.ru/forum/viewtopic.php?t=7374

Работает, конечно, замечательно, но у него есть один существенный недостаток - мы не можем создавать свои события и вешать на них обработчики. В первом варианте у нас такая возможность есть, но обработчик мы можем повесить только один и соответственно городить огород нет особого смысла.

И тут мы подходим к самому главному! В яваскрипте любая функция является объектом, а значит она может иметь дополнительные свойства. В частности, можно задать каким-нибудь свойством массив обработчиков, а функция должна просто пройтись по каждому из них и запустить. В итоге у меня получился такой код:
node.observe= function( event, func ){
if( !node[event] ){
node[event]= function f( e ){
if( !e ) e= window.event;
var funcs= node[event].funcs;
for( var i= 0; i < funcs.length; ++i ){
if( funcs[i] ) funcs[i]( e );
});
};
node[event].funcs= [];
}
var funcs= node[event].funcs;
for( var i in funcs )
if( funcs[i] == func ) return;
funcs.push( func );
}
node.unobserve= function( event, func ){
var funcs= node[event].funcs;
for( var i in funcs )
if( funcs[i] == func )
delete funcs[i];
}

то есть, мы расширяем html-ноду ( хотя, в ИЕ наврятли удастся расширить что-то отличное от html-елемента -_- ну да не суть ) двумя функциями, одна из которых добавляет обработчик, а вторая - удаляет.

Примеры использования:
function ping( e ){
alert( e );
}

node.observe( 'onclick', ping );

node.unobserve( 'onclick', ping );

node.observe( 'onmyevent', ping );

node.onmyevent( { keyCode: 1 } );


upd: кстати, на событие 'onbeforeunload' и возможно на ещё какие-то нельзя вешать обработчики с помощью addEventListener/attachEvent, ибо некроссбраузерно.

upd2: мля... не работает в мозилле в designMode... придётся оной подпорки делать...

понедельник, сентября 10, 2007

одна большая дырка

правильно, речь пойдёт об ИЕ ^_^
недавно (ну, месяца два назад) c удивлением обнаружил, что в ИЕ работает даже такая конструкция:

<img src="javascript:alert(1)" />

что тут можно сказать? только сабж ^_^

пятница, сентября 07, 2007

выделение, визивиг и изменение контента

при реализации визивига некоторые вещи приходится вытворять по схеме: сериализация->обработка->десериализация

в качестве примера - реализация динамической подсветки кода. одними только dom-функциями это реализовывать - страшный геморрой, а ещё и очень медленно. гораздо быстрее и проще пройтись парой регулярок по сериализованному документу.

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

очевидно, что метки начала и конца выделения должны быть неиспользуемой последовательностью символов юникода. также они должны иметь нулевую ширину, дабы при вводе текста не было скачков. я остановился на парах диактрических знаков: '\u0300\u0301' и '\u0302\u0303'. вроде как маловероятно, чтобы в тексте потребовалось их применить последовательно. ширины они точно не имеют. единственный недостаток: они имеют визуализацию, но с учётом того, что обработка должна быть "мгновенной" (ибо рилтаймовая подсветка) - кратковременное появление маленьких значков не должно быть заметно на глаз.

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

в ИЕ всё оказалось весьма шоколадно...

сохранение меток выглядит так:

var range= document.selection.createRange();
range.pasteHTML( '\u0300\u0301' + range.htmlText + '\u0300\u0301' );

восстановление несколько менее тривиально:

var ran= document.body.createRange();
var tr= document.body.createRange();
tr.findText( '\u0300\u0301' );
tr.text= '';
ran.setEndPoint( 'StartToStart', tr );
tr.findText( '\u0302\u0303' );
tr.text= '';
ran.setEndPoint( 'EndToEnd', tr );
ran.select( );

а вот реализуя то же самое для остальных браузеров пришлось несколько попотеть...

сохранение меток:

var ran= window.getSelection().getRangeAt(0);
var rane= ran.cloneRange( );
rane.collapse( false );
var node= document.createTextNode( '\u0302\u0303' );
rane.insertNode( node );
var node= document.createTextNode( '\u0300\u0301' );
ran.insertNode( node );

а для восстановления соответственно приходится бежать по всему дому в поисках открывающей и закрывающей пар node+offset, после чего наведение выделения с помощью функций setStart и setEnd. почему w3c не соизволила узаконить findText остаётся загадкой 8(o_0)8

воскресенье, сентября 02, 2007

Теория множеств свернула не туда

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

Приведу пример из "Что такое математика?" от Куранта, Роббинса под редакцией Колмогорова:
  • Тому же Кантору принадлежит открытие исключительной важности: множество всех действительных (рациональных и иррациональных) чисел несчетно.
О других участниках там же идёт повествование в более сухом тоне, местами даже с элементами разоблачения:
  • Евклид, громкая слава которого объясняется той частью его «Начал», которая посвящена основам геометрии (изучаемым в школе), по-видимому, сделал оригинальные открытия в области теории чисел, тогда как его геометрия в значительной степени представляет собой компиляцию ранее полученных результатов.
Ну да вернёмся к описываемому гиперболическими эпитетами "открытию"... суть его заключается в том, что Кантор показывает несчётность континуума весьма "остроумным" способом. я бы назвал его скорее софистической спекуляцией понятием "бесконечность".

Для начала хотелось бы напомнить классическое доказательство бесконечности ряда натуральных чисел:

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

Теперь перейдём собственно к Кантору... суть его "доказательства" сводится к следующему: пусть мы пересчитали все вещественные числа, тогда, мы можем выписать их в ряд:
0: 0.abc...
1: 0.def...
2: 0.ghi...
...
, а потом используя диагональный метод составить новое число, где первая цифра не равна первой цифре первого числа, вторая - второй второго и так далее.
Далее мы делаем финт ушами - предельный переход - и получаем число, которого нет в нашем списке, из чего делаем вывад о том, что множество вещественных чисел мощнее множества натуральных. Подумать только - одна бесконечность больше другой бесконечности на целый 1 элемент! ^_^ (Всем, кто не согласен с моими рассуждениями, советую крепко задуматься над последним предложением.)

Что мешает нам полученное число тут же добавить, например, в начало списка? А ничего! (надеюсь все согласны, что "бесконечность+1=бесконечность"?) Да, после этого можно повторить процедуру и найти ещё одно число. Ничего не напоминает? Та же самая схема, что и в случае доказательства бесконечности множества натуральных чисел, но вот вывод из этого Кантором сделан неверный. Фактически он доказывает бесконечность множества вещественных чисел, ибо диагональный метод всего-лишь позволяет по конечному множеству вещественных чисел найти вещественное число, которое в это множество не входит (вспоминаем индукционный переход в доказательстве бесконечности ряда натуральных чисел). На бесконечном же множестве диагональный метод будет бесконечно искать, но так и не найдёт неучтённое число. Точно также мы можем прибавлять единицу бесконечное число раз в поиске последнего натурального числа, но так никогла его и не найти.

воскресенье, августа 19, 2007

Кодестайл против собаки

- вы должны каждое слово начинать с большой буквы
- ну.. это ж тянуться к шифту без конца
- это хороший стить
- чем же он хорош?
- позволяет отделять слова друг от друга
- а пробелы разве не для этого?
- пробелы - это плохой стиль
- что за бред?
- это потенциальный источник ошибок: слова можно написать настолько близко друг к другу, что можно не заметить существование пробела, к тому же иногда межбуквенный интервал можно принять за пробел.
- а что мешает использовать интервалы нормальной длинны?
- мне лень такому дауну как ты что-либо доказывать - любой здравомыслящий человек поймёт, что пробелы нельзя использовать нигде и никогда, потому как получается говнокод - нужно использовать "синтаксический сахар" в виде заглавных букв.
- но это не удобно, ужасно смотрится и некоторые заглавные буквы можно спутать со строчными!
- бан бы тебе, с аргументом "непросветлённый"! тема закрыта.

навеяно этим: http://phpclub.ru/talk/showthread.php?s=&threadid=101915

суббота, августа 18, 2007

мой первый шедёвр

ume-hime

вот так я стал рисовать, когда заразился анимэ ^_^ пэйнт форэва!

так вот они какие - зелёные человечеки!

"джимми-червячёк. знаете такого?
единственный владелец скафандра надувного!..."

карлос маст дай

карлоса приставили к стенке за совращение малолетних...

терминатор из четвёртой части

ноги от ушей, осиная талия - красавица, а не робот 6_^

лолифокси обоина

обоина с лолифокси в главной роли. осторожно, 2 метра весом.

среда, августа 15, 2007

php и замыкания

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

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

однако, в пыхе есть и поруганное многими исключение - директива global позволяющая импортировать переменные из глобального контекста. как говорится: "мысля была хорошей, но родилась она в заднице" :) вместо директивы global лучше бы ввели директиву extern, позволяющую импортировать переменные из родительского контекста - получились бы эдакие "контролируемые замыкания".

интересно, существуют ли уже языки с "контролируемыми замыканиями"?

вторник, августа 07, 2007

смерть ORM'у

реализовал сегодня идеальную систему прав для движка. есть пользователи, каждый может состоять в нескольких группах. как для группы так и для отдельного пользователя в определённом разделе каталога можно назначить свою роль, а у каждой роли есть свой набор прав.
в итоге запрос получения привелегий доступа к определённой статье для текущего пользователя выглядит следующим образом:
$perms= $db->get1d('
select *
from
mo_cat_art as ca
,
mo_catalog as c1
,
mo_catalog as c2
,
mo_rules as ru
,
mo_roles as ro
where
ca.art_id = ',$art['art_id'],'
and
ca.cat_id = c1.cat_id
and
c1.cat_no >= c2.cat_no
and
c1.cat_sub <= c2.cat_sub
and
c2.cat_id = ru.cat_id
and
(
ru.user_id = ',$user['user_id'],'
or
ru.group_id in ',$user['grouplist'],'
)
and
ru.role_id = ro.role_id
group by
ru.rule_id
order by
c2.cat_no desc
');

сижу, думаю, а не перемудрил ли я? (o_0)`