JavaScript

индекс
246,38

Притча о шаблонах

 — Здравствуй *с широко развевающейся по лицу улыбкой* дружок.
 — Ваа! *с ярким блеском в широко распахнутых глазах* Тётя Ася приехала!
 — Да, и у меня есть для тебя новая сказка *присела и взяла малыша за руки* хочешь послушать?
 — Конечно! *слегка смутился и отвёл взгляд* Мне тут дядя такие страшные истории рассказывал…
 — Ну, надеюсь моя история тебя не испугает *потрепала его по волосам* Она должна научить тебя мыслить шаблонно.
 — Эээ? *лицо перекосилось от недопонимания* Это как?
 — М… сейчас узнаешь *подмигнула и взяла на ручки* Вот когда тебе нужно вставить переменные в строку — ты как поступишь?
 — Ну… *взял карандаш и чирканул на лежащей рядом бумажке* примерно так:
var query= 'xxx'
var resultCount= 512
var message= 'По запросу <kbd>' + query + '</kbd> найдено страниц: ' + resultCount

 — Ты ничего не забыл? *победоносно подняла голову*
 — Да вроде нет… *уткнулся носом в код, ещё раз внимательно его проверяя*
 — Что, если пользователь введёт… *выдержала многозначительную паузу и добавила*
<iframe src="javascript:alert('ahtung')"></iframe>

 — А, ну да *виновато приписал экранирование*
var message= 'По запросу <kbd>' + query.escapeHTML() + '</kbd> найдено страниц: ' + resultCount

 — Молодец… *разочарованно выдохнула* Только вот боюсь — это не последний раз, когда ты забыл обезвредить данные.., а как будешь прикручивать к этому коду языковую локализацию?
 — Ну… *напряжённая работа мысли скукожила некогда миленький лобик* Вынесу в отдельный массив:
var texts= [ 'По запросу <kbd>', '</kbd> найдено страниц: ' ]
var message= texts[0] + query.escapeHTML() + texts[1] + resultCount

 — И не влом же тебе будет писать каждый раз эти texts[n], чередуя их с данными? *взяла карандаш и, зачеркнув его писанину, нарисовала свою* Смотри, так использовать гораздо проще:
var template= TT.template( 'По запросу <kbd>{0}</kbd> найдено страниц: {1}' )
var message= template([ query.escapeHTML(), resultCount ])

 — Да *пытается переварить* Наверно…
 — Но когда параметров больше одного — лучше давать им говорящие имена *ещё несколько движений карандашом* для наглядности:
var template= TT.template( 'По запросу <kbd>{query}</kbd> найдено страниц: {count}' )
var message= template({ query: query.escapeHTML(), count: resultCount })

 — Ха! *радостно вскочил* Получилось даже длинее чем у меня!
 — Не проблема! *уверенно позачёркивала лишнее* Воспользуемся автоэкранированием:
var template= TT.html( 'По запросу <kbd>{query}</kbd> найдено страниц: {count}' )
var message= template({ query: query, count: resultCount })

 — То есть теперь… *призадумался над последним кодом* Мне даже не придётся заботиться об экранировании данных?!7
 — Точно! *коснулась пальцем кончика его носа* Все данные будут проэкранированы, кроме тех, для которых ты явным образом не скажешь отключить фильтрацию:
var message= template({ query: TT.value( highLightedQuery ), count: resultCount })

 — А что за функция такая *широким жестом тыкнул пальцем в лист* TT.value?
 — Она просто создаёт функцию *слегка запнулась, решив проиллюстрировать свои слова* которая всегда возвращает определённое значение:
TT.value= function( data ){
        return function( ){
                return data
        }
}

 — То есть, если вместо данных передать функцию, возвращающую данные, то шаблонизатор будет считать, что данные возвращаемые функцией безопасны для вставки в шаблон? *сам офигел, что сказал такую сложную фразу* Да?
 — Именно! *раскинула руками* А вот, смотри, ещё интересная функция:
TT.pipe= function( list ){
        if( !list ) list= []
        var len= list.length
        return function( data ){
                for( var i= 0; i < len; ++i ) data= list[ i ]( data )
                return data
        }
}

 — А она что делает? *внимательно всматривается в волшебный метод*
 — Она берёт набор фильтров и выстраивает их в одну цепочку *поняла, что без примера тут не обойтись* Вот, смотри, следующие две строчки эквивалентны:
var text= decodeURIComponent( encodeURIComponent( text ) )
var text= TT.pipe([ encodeURIComponent, decodeURIComponent ])( text )

 — Брр *встряхнул головой* мистика какая-то!
 — Это ещё что! *усмехнулась* Сам шаблонизатор ещё круче:
TT.template= new function( ){
        var searcher= /((?:[^\{\}]|\{\{|\}\})*)(?:\{|$)|([^\{\}]*)(?:\})/g
        return function( str, filter ){
                if( !filter ) filter= TT.pipe()
                var parts= []
                String( str ).replace
                (       searcher
                ,       function( str, val, sel ){
                                if( sel !== void 0 ){
                                        parts.push( function( data ){
                                                data= data[ sel ]
                                                switch( typeof data ){
                                                        case 'undefined': return '{' + sel + '}'
                                                        case 'function': return data()
                                                        default: return filter( data )
                                                }
                                        })
                                } else if( val ){
                                        val= val.split( '{{' ).join( '{' ).split( '}}' ).join( '}' )
                                        parts.push( TT.value( val ) )
                                }
                        }
                )
                return TT.concater( parts )
        }
}

 — Ыыыы *чуть ли не плача* Вы же обещали не пугать!
 — Да ладно тебе! *обняла в охапку* Зато какие гламурные на его основе получаются плагинчики:
TT.uri= function( tpl ){
        return TT.template( tpl, TT.uri.encoder() )
}
TT.uri.encoder= TT.value( encodeURIComponent )
TT.uri.decoder= TT.value( decodeURIComponent )

 — Что это? *сопит, уткнувшись носом в грудь*
 — Это шаблонизатор для URI *дала ему карандаш в руку* Пиши:
var searchURI= TT.uri( '/search/?q={query}&count={count}' )
location.href= searchURI({ query: '&&&', count: 10 })

 — Эм… *повеселел даже* А как быть с html?
 — Да так же самое:
TT.html= function( tpl ){
        return TT.template( tpl, TT.html.encoder() )
}
TT.html.encoder= new function( ){
        var parent= document.createElement('div')
        var child= parent.appendChild( document.createTextNode( '' ) )
        return TT.value( function( data ){
                child.nodeValue= data
                return parent.innerHTML.split( '"' ).join( '&quot;' ).split( "'" ).join( '&apos;' )
        })
}
TT.html.decoder= new function( ){
        var parent= document.createElement('div')
        return TT.value( function( data ){
                parent.innerHTML= data
                return parent.firstChild.nodeValue
        })
}

 — Крутбл!
 — Но и это ещё не всё! *бешенно жестикулируя* Для html можно сделать ещё и так, чтобы в результате выдавался HTMLNode с соответствующим содержимым:
TT.dom= function( tpl ){
        return TT.pipe([ TT.html( tpl ), TT.dom.parser() ])
}
TT.dom.parser= new function(){
        var parent= document.createElement( 'div' )
        return TT.value( function( html ){
                parent.innerHTML= html
                var childs= parent.childNodes
                if( childs.length === 1 ) return childs[0]
                var fragment= document.createDocumentFragment()
                while( childs[0] ) fragment.appendChild( childs[0] )
                return fragment
        })
}
TT.dom.serializer= new function(){
        var parent= document.createElement( 'div' )
        var child= parent.appendChild( document.createTextNode( '' ) )
        return TT.value( function( node ){
                parent.replaceChild( node.cloneNode( true ), parent.firstChild )
                return parent.innerHTML
        })
}

 — И как это использовать? *в глазках загорелись искорки халявы*
 — Да очень просто *растеклась мыслью по листу бумаги*
var link= TT.dom( '<a href="{uri}">{title}</a>' )({ uri: '/', title: 'на старт' }) // HTMLAnchorElement
var userName= TT.dom( '<b>{head}</b>{tail}' )({ head: 'T', tail: 'enshi' }) // HTMLFragment

 — Гм… *потихоньку стаскивая исходники* Действительно не сложно…

______________________
Текст подготовлен в Редакторе Блогов от © SoftCoder.ru
+82
13 июля 2010, 16:30
210

комментарии (164)

–2
anarleen #
Крутая статья. В закладки.
+34
Hellbot #
Статья интересная, а подача требует «внезапно» сломать голову.
+93
bondbig #
подача клоунская, портит годную статью.
–13
tenshi #
кажется ты слишком напряжён :-о *массирует плечи* расслабься!
+7
can3p #
кажется, вы слишком любите говорить от третьего лица, что и превращает годную статью в кукольный театр.

А вообще, очень интересный подход к шаблонам. Фактически как у Резига в результате получаются скомпилированные шаблоны, но в гибче с точки зрения выходных данных
0
tenshi #
я люблю экспериментировать %-)

и гораздо быстрее, кстати. особенно в хроме, с его прекомпиляцией.
+60
cypok #
Мне было реально трудно ее читать из-за этих *напрягающих* вставок
+7
dinamyte #
Диалоги персонажей в стиле Web 2.0 прямо.
+20
tenshi #
настоящие джедаи делают так:
javascript: document.documentElement.innerHTML= document.documentElement.innerHTML.replace( /\*[а-я].*?[а-я]\*/g, ' ' )
0
TheMengzor #
Йода?
0
tenshi #
не, всего-лишь Зелёнка ^^'
+2
TheMengzor #
Опять я лоханулся! Как так можно?..
+4
tenshi #
Силы мало в тебе чувствую я. Качаться нужно тебе ещё.
+2
vflash #
каким образом экранировать { и }?
+1
tenshi #
никаким, но если очень хочется, то:

TT.template( '{[}{xxx}{]}' )({ '[': '{', ']': '}', xxx: 777 })
+30
Hellbot #
Выглядит как жесткое порно.
+13
tenshi #
экранирование — всегда порно…
+6
Daymz #
Экранка.
0
widowmaker #
а почему не сделать экранирование двойными скобками, например {{{variable}}} выведет {значение}
0
tenshi #
парсить это дело сложно ._.
+3
widowmaker #
Парсер пишется один раз, а использается постоянно.
Должно быть легко в использовании, а не написании парсера.
+4
tenshi #
сложный парсер медленнее работает… впрочем, я согласен.
0
tenshi #
сделал такое экранирование
0
tenshi #
теперь для экранирования достаточно удвоить фигурную скобку
+1
Hellbot #
Вычитав еще пару раз драматургический опус статью, мне понравился подход :), спасибо.
НЛО прилетело и опубликовало эту надпись здесь
0
tenshi #
а как будет понятнее, проще или красивее?
+1
SMiX #
+2
SMiX #
Очень удобно, красиво и уже сравнительно давно изобретено. И оттестировано многими разработчиками.
–1
tenshi #
значит тебе не составит труда переписать мой пример на каждый из них?
+1
SMiX #
На embeddedjs.com/ есть отличная интерактивная демка.
–1
tenshi #
я в курсе
+4
widowmaker #
Почему нету точек с запятой в конце строк?
Они, конечно, не обязательны, но крайне желательны, и без них невозможно "упаковать" скрипт
–4
tenshi #
м… а зачем его упаковывать в одну строку? х) это же не букмарклет какой-нибудь…
+2
widowmaker #
Если поставить галочку возле Shrink variables размер уменьшиться в 1.8 раза.
–3
tenshi #
а семиколоны тут при чём?
+3
widowmaker #
При том, что всё сворачивается в одну строчку для уменьшения размера почти на 30%
–5
tenshi #
ты предлагаешь добавить 30% семиколонов, чтобы можно было вырезать 30% переводов строк? х) шило на мыло…
+4
widowmaker #
Во-первых, есть еще пробелы для форматирования.
Во-вторых, не в каждой строчке надо ставить семиколон.
В-третьих, перевод строк частенько состоит из 2х байт.
–4
tenshi #
1. пробелы можно вырезать независимо от наличия семиколонов
2. как и перенос строки
3. какие проблемы редуцировать перенос строки до 1 символа?
+3
widowmaker #
Зачем изобретать велосипед?
–2
tenshi #
я и не предлагаю
+5
widowmaker #
тогда смысл экономить на семиколонах?
–4
tenshi #
потому что перевод строки необходим и достаточен.
+4
SMiX #
Замкнутый круг. Перейдите в начало ветки.
+2
dime #
Когда-то прочёл, что если точек с запятыми нет, то некоторые (многие?) движки сначала их предварительно расставляют (выглядит странно), что негативно сказывается на производительности. Или сильнее напрягаются в парсинге (что вполне объяснимо). С теми же последствиями. Зуб за эту информацию не даю, продаю за что купил, но с некоторых пор сменил бесточекасзапяточный :) стиль обратно на классический. Мне не жалко, а шансов нарваться на ошибку парсинга чуть меньше, ну и со скоростью — вдруг не соврали…
0
tenshi #
разница в скорости незначительна.
никто их при парсинге не расставляет, ибо они являются лишь разделителями операторов
+1
dime #
>разница в скорости незначительна.
Я не проверял.
>никто их при парсинге не расставляет, ибо они являются лишь разделителями операторов
Расставляет. Об этом даже есть специальный раздел в стандарте. Automatic Semicolon Insertion называется. Ну, то есть, физически можно не вставлять, но поведение должно соответствовать варианту, как будто вставляется.
0
tenshi #
это всего-лишь игра слов для простоты понимания.
+1
dime #
Это описание поведения интерпретатора. И парсер именно так и работает. Фиг с ней со скоростью, главное тут побочные эффекты.
0
tenshi #
парсер создаёт дерево инструкций. в этом дереве нет ни семиколонов, ни переводов строк.
+2
dime #
??? При чём здесь дерево инструкций? Описано поведение парсера во время парсинга исходного текста.
0
tenshi #
+1
dime #
ECMAscript Language Specification, пункт Automatic Semicolon Insertion.
Там описано как должен вести себя парсер языка ECMAscript. Как ведёт себя парсер из википедии меня совершенно не волнует. Вы полагаете, яваскриптовые движки пишут по википедии, а не по спецификации? Ну-ну.
+1
tenshi #
парсеры пишут по уму. а спецификация описывает лишь эталонную реализацию.
ни один программист не будет писать парсер автоматически вставляющий семиколоны, банально потому, что это медленно и бессмысленно.
+1
dime #
Угу, я про это тоже писал. Но анализировать ситуацию всё-равно надо — раз, и спецэффекты всё-равно остаются — два.
+5
TR4V15 #
не говорите глупостей, я лично собираю все скрипты в один пак, сжимаю. На выброс идет пакованый скрипт + gzip + кэшируется. В итоге клиент получает 57.9 KB вместо 220кб ;)
–4
tenshi #
эм… ну я рад за тебя. а теперь удали все семиколоны и удивись разнице.
+4
TR4V15 #
чему удивлятся? ошибкам после того как скрипты пройдут через Closure Compiler?
–2
tenshi #
СС настолько тупой, что ломает скрипты?
+2
Beresta #
Семиколоны в некоторых случаях должны быть по стандарту. Если их нет — движок пытается «угадать». Логично предположить, что не всегда он угадает правильно.

Именно поэтому надо их ставить везде. А убирать, для компенсации, переносы строк ;-)
–1
tenshi #
должны быть они лишь в цикле for. в остальных случаях перевод строки делает их использование бессмысленным.
+1
Beresta #
Вот пример. Падает с ошибкой из-за пропущенной ;.

<script>
var a = 5
(true)
</script>

Интерпретатор трактует это как вызов функции 5(true). Так что ставьте везде семиколоны ;-)
–1
tenshi #
это синтетический пример.
+2
Beresta #
<script>
var a = 5
(condition? obj1: obj2).callSomeFunc()
</script>

Тоже самое. Пример, более близкий к жизни, коли вам так угодно.

Если следующая строка с точки зрения синтаксиса может быть продолжением предыдущей — она станет продолжением предыдущей. Если не может — будет автоматически вставлен семиколон.
–4
tenshi #
а это говнокод :-Р надо писать так:
var a= 5
var obj= condition? obj1: obj2
obj.callSomeFunc()
+2
Beresta #
Ну говнокод это или нет — вопрос отдельный, другое дело что это конкретный, реальный пример когда точки с запятыми нужны. Сколько таких примеров можно при желании найти еще и где они всплывут — науке не известно. Именно по этому я считаю, что точки с запятыми надо ставить всегда.
–4
tenshi #
науке всё прекрасно известно :-Р именно поэтому у меня никогда из-за этого проблем не возникало.
+24
zeleniy #
такое ощущение, что статью написал педофил )))
–5
tenshi #
каждый думает в меру своей испорченности ;-)
+7
habraname #
олдфаги помнят зачин «здравствуй дружочек» и одобряют топик
+5
lany #
У меня при чтении возникло ощущение, что статью пишет анимешник. Я укрепился в этом мнении, когда дочитал до ника автора =)
0
tenshi #
все анимешники немного того х)
+1
zeleniy #
tenshi.ru/ — твоё?
–1
tenshi #
нет, конечно :-о
+1
zeleniy #
А… но всё равно, я вчера был поражён от того, сколько там музыки. Охренеть! Сколько труда потребовалось чтобы всё это собрать!
0
tenshi #
ага, и сколько хостинга…
+9
bO_oblik #
Нужно отобрать у автора как можно больше ЛСД.
0
tenshi #
не получится — я уже всё скурил %-)
+2
bO_oblik #
ЛСД даже не курят :)
+7
tenshi #
так вот почему так плохо торкает! :-о
+1
vittore #
как же
курят даже орех
+2
ZiggiPop #
клоунада, а не статья
+1
habraname #
порно^W задорно ;)
0
esenin #
И Смешно и поучительно одновременно
+1
develop7 #
обожаю Javascript
+5
hramik #
Жаль, а ведь, наверное, что–то интересное написано. Ведь правда? *обнимаю в охапку и плачу*
–1
tenshi #
правда *взаимообнимаю* (Y_Y)
+1
tiesto #
А чем отличается объявление:

TT.html= function( tpl )…

от:

TT.html.encoder= new function( )…

С какой целью в одном имеется оператор new, а в другом нет?
0
tenshi #
new используется для создания дополнительного скопа, куда помещаются статические переменные, необходимые для определяемой функции
0
tiesto #
1) скоп — что это?
2) чем переменная в функции без new будет отличаться от функции с new?

Да и вообще, можешь рассказать об этом подробнее?
А то я даже вопросов пока сформулировать не могу толком =)
+1
tenshi #
попробуй это: javascript.ru/basic/closure
0
widowmaker #
Не проще было написать что var x = new function(){}; равносильно var x = (function(){})();.
+3
tenshi #
и тогда бы он спросил, что такое (function(){})()? х)
+2
widowmaker #
Такой вариант, по моим наблюдениям, встречается чаще.
+1
tiesto #
То есть, в этом случае функция не только объявляется, но и выполняется, при этом её результат пишетя в x?
Или, другими словами, в x пишется не функция, а результат функции?
0
tenshi #
агась
+1
vittore #
а зачем кстати новый скоуп для TT.template, почему было searcher просто внутрь не положить?
0
tenshi #
чтобы не создавать его заново при каждом создании темплейта.
+1
can3p #
в первом случае просто определяется анонимная функция, а во втором случае, благодаря оператору new она еще и вызывается, что приводит к созданию нового объекта вызова, в который попадают все определяемые внутри переменные
0
ferrari #
тошно читать
+1
tenshi #
м… надо будет выпустить аудиокнигу %-)
+3
j1nn #
фильм. тогда не будет этих вставок, за которыми теряется весь смысл текста.
+2
vittore #
ага и обязательно тетю асю с 3м размером: Р
+1
j1nn #
только чтобы третий размер не отвлекал куда больше, чем вставки в тексте..:)
+6
aceventura #
Материал довольно интересен. То есть его можно кушать и нахваливать. Антураж весь вот этот лично для меня портит впечатление. То есть по итогам оценка — 0.
Но тут я вспоминаю слово «порева», меня передергивает еще разок и ставлю минус.
–1
tenshi #
ви таки порноненавистник? х)
+1
aceventura #
Таки нет, но есть вещи уместные и неуместные.
+3
tenshi #
скучный ты .-.
+3
aceventura #
Нет, просто я во всем люблю красоту. Можно сделать узбекский орнамент на ковровой рамке у портрета Путину или там украсить свой автомобиль лошадиным хвостом. Главное при этом остроумие, оригинальность изобретательность и пр.

Человек ведущий себя в разных ситуациях нестандартно может быть яркой личностью а может тупым неадекватом. Оба делают что-то «нескучное» на их субъективный взгляд, а получается по-разному. Андэстэнд?
+1
tenshi #
ты посягаешь на мою индивидуальность! т-т
+1
vittore #
а кто тебе сказал что ты правильно отличишь яркую личность от тупого неадеквата?
+3
aceventura #
Это субъективные оценки. И здесь никакого «правильно» или «неправильно» быть не может.

+1
vittore #
так и я о том
+1
yuretsz #
Если табуляцию выставить в два пробела — то уже не так страшно.
–1
tenshi #
угу, подсвечиватель невменяемый какой-то >_<
+2
variable #
тащусь от ваших js сказок)
+1
isden #
статья и особенно её подача впечатлили. ушло в избранное :)
НЛО прилетело и опубликовало эту надпись здесь
+2
dm9 #
По стилю здорово =) Разбавит немного хабрашаблоны и хабразаискивания. Так держать!
+1
mihalicyn #
Забавно все это конечно, только зачем что-либо экранировать на стороне JS?
0
tenshi #
а где ты предлагаешь экранировать?
+2
mihalicyn #
Хм, ну такие вещи вроде-как на стороне сервера делаются, не? (-:
0
tenshi #
не всегда
+1
Sannis #
Есть Javascript на стороне сервера ;)
+1
Ryav #
Перед сном детям читать
+3
TEHEK #
Вам бы JS в яслях преподавать
+1
IIIEII #
Выглядит зловеще:
.split( '"' ).join( '"' )

Это действительно делает что-то полезное?
0
tenshi #
блоо, хабралох сломал — ща починю
+1
ich #
материал неплохой, подача, соглашусь, чрез чур юморная. а так я сам нечто подобное использую для всего, что надо «отшаблонизировать»
+1
stansult #
«чрез чур» :))
0
ich #
а черт его знает как оно пишется :)
я в таких случаясь руководствуюсь правилом: как слышится, так и пишется
+1
stansult #
сколько людей — столько способов решить проблему :)
я, к примеру, когда не уверен — проверяю в словаре

а в данном случае — и слышится, видимо, всем по-разному
мне слышится как раз «чересчур»… ну, может быть, «чирисчур» (безударные «е» звучат как «и»)
+1
ItGold #
что такое ТТ?
+1
tenshi #
смайлик такой х)
TrueTemplates
+1
zantor #
Переводы строк уходят в аут после парсинга.
Замените
/(.*?)(\{|\}|$)/g
на
/([\s\S]*?)(\{|\}|$)/g
, чтоли ;)
0
tenshi #
м… интересное решение, спасибо :-о
+1
zantor #
А еще, возможно, стоит сделать так:
/([\s\S]*?)(\{|\}|$)(?!\2)/g

Тогда решится проблема с экранированием (две скобки == просто скобка):
var template= TT.html( 'По {{fake}} запросу <kbd>{query}</kbd> найдено страниц: {count}' )
var message= template({
    fake: 'этому',
    query: 'Ultimate Answer to the Ultimate Question of Life, The Universe, and Everything',
    count: 42 });
0
tenshi #
к сожалению, не всё так просто…
TT.template( 'a{{{b}}}c' )({ b: 'd' }) должно преобразовываться в 'a{d}c'
+1
zantor #
Да, действительно :(
0
tenshi #
короче, сделал экранирование %-)
+1
zantor #
Что-то теперь вообще странно. Выдает на пример
{}Ultimate Answer to the Ultimate Question of Life, The Universe, and Everything{}42{}
0
tenshi #
может ты что-то не так скопипастил? о0
+1
zantor #
Ну… скачал скрипт… searcher такой:
/((?:[^\{\}]|\{\{|\}\})*)(?:\{|$)|([^\{\}]*)(?:\})/g
0
tenshi #
опа… в лисице косячок ^^'
+1
tenshi #
в общем, поправил
+1
egorinsk #
А я вот, а я, по первым 2 строчкам догадался кто автор! Подход очень интересный, хотя конечно надо еще посмотреть насоклько это грузит браузер, все эти замыкания и прочая ересь.
0
tenshi #
замыкания — это очень быстро
+1
zantor #
главное, чтобы где-то в родитетельском scope не попались ссылки на DOM-объекты ;) Ибо ололо.
0
tenshi #
ничего страшного не будет
+1
zantor #
То есть не будет? Убиваем элемент в дереве, ссылка на него в контексте, залоченном в замыкании остается, вуаля — leak detected. Или я что-то путаю?
–1
tenshi #
а, ты про утечки… им тут не от куда взяться.
0
zantor #
тут негде. Это был ответ на
замыкания — это очень быстро
+2
tchvil #
Hi I'm the author of pure.js mentioned above (thanks SMiX for the link).
I read this post through Chrome Translate, so please be nice!

At the beginning of your post, it looks you escapeHTML for security reasons.
I don't think you have to do that. The HTML scripts are not parsed when injected into a node through innerHTML.
0
tenshi #
m… fixed ;-) (works in ie)
0
tenshi #
works in anywhere now
+1
zantor #
Кстати, а почему pipe получает массив? Лучше уж через arguments, тогда более походе на pipe ;)
0
tenshi #
это практичней, когда надо протягивать массивы через цепочку функций. arguments в массив конвертятся очень накладно.
+1
zantor #
Про цепочку я что-то не понял, поясните пожалуйста. А насчет конвертации — Array.prototype.slice.call(arguments) работает везде, насколько я помню.
0
tenshi #
this.createFilter= ТТ.pipe( TT.pipe, TT.binder( this ) )

var filter= this.createFilter([ this.trim, this.escape, this.validate ])

везде кроме ие =(
+1
zantor #
>>> везде кроме ие =(
Хм. В IE6-8 работает.
0
tenshi #
гм… что-то я напутал видимо, спасибо ._."
+1
zantor #
Пожалуйста :) Жаль только, что в IE arguments — это вроде как единственное, для чего это работает (в плане того, что с HTMLCollection так уже не поступить)
0
tenshi #
во, с ним и попутал видимо

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