Как стать автором
Обновить

Комментарии 41

Имхо демо для rich application фрэймворка в виде калькулятора не показательна.
Интересная вещь, вот только демо-то в общем показывает не возможности фреймворка, а возможности Heliwidgets. По сравнению с Heliwidgets у самого фреймворка достаточно бедная функциональность. Виджеты понравились, планируется ли документация к ним?
Документация естественно планируется, пока не успел.

Само ядро фреймворка содержит только то, что мне нужно — возможность делать include. Всё остальное — библиотеки.

С Heliwidgets у меня тоже связано много разных идей, которые я постепенно буду воплощать. Эта демка ещё далека до продакшна и даже до альфы, имеет своей целью привлечь тех, кому это м.б. интересно.
Интересно, но непонятно:
— что побудило автора к созданию (какие-то недочеты в существующих фреймворках? что-то другое?)
— чем принципиально отличается от конкурентов? что может предложить разработчикам?
Я попытался реализовать некоторые мои идеи, которых, на мой взгляд, очень не хватало для толковой разработки. На домашней страничке есть подробный дескрипшн. Вкратце: основная идея — это разделение клиентской и серверной части веб-приложения. Юзер один раз загружает целиком приложение, которое по мере надобности общается с сервером посредством ajax. На сервере кто-то отвечает, например набор пхп-скриптов, но эти скрипты уже не занимаются генерацией лейаута, а просто передают необходимую информацию. Классический клиент-сервер.

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

chiaroscuro, каких конкурентов вы имеете в виду?
> The main idea of the project is to provide a way for creating rich web applications with client and server code being completely split (forget that painful javascript inside html inside php).

Хорошая идея, но такое уже есть в qooxdoo. :) Идея с модулями тоже хороша, но на самом деле она сложнее, чем кажется, как быть с:
— qualified import (то бишь отучить include() работать с window, а вместо этого взять новый объект)
— prepackaged modules (например, хочется репозитарий вроде CheeseShop, PLaneT, Hackage, etc.)
— сжатием, распаковкой, развертыванием, etc.

> have once seen a solution which implemented include using ajax and required running server to work, this is not the case

А как же оно тогда работает?

> chiaroscuro, каких конкурентов вы имеете в виду?

Qooxdoo, YUI, Dojo+Dijit, jQuery UI.

Как обстоят дела с модульностью и аддитивностью? Хочется, чтобы, например, CSS можно было бы задавать для каждого виджета *отдельно* (и разделять тогда, когда необходимо) — и чтобы правка CSS у одного виджета никак не воздействовала на страницу в целом. В CSS бывает так, что, наложив один хак, ломается что-нибудь совсем в другом месте. И в JS тоже бывает. Как с этим быть? :)

PS используйте кнопку «ответить», удобно ведь. :)
> > The main idea of the project is to provide a way for creating rich web applications with client and server code being completely split (forget that painful javascript inside html inside php).

> Хорошая идея, но такое уже есть в qooxdoo. :)

Кстати, qooxdoo на мой взгляд самый близкий проект к тому, чем я занимаюсь. На самом деле, узнал о нём совсем недавно :) Но вот хоть будет с кем поконкурировать, надеюсь это пойдёт обоим на пользу. И, да, в qooxdoo есть настоящий безсерверный инклюд, как у меня? ;) Тут же:

> А как же оно тогда работает?

Оно работает полностью на клиенте, в этом то и фишка. Можете загрузить кодкаст с калькулятором, раззипить и открыть в броузере index.html у себя на локальной машине без всяких серверов. В самом index.html нет ничего, кроме реквеста подгрузить kernel.js. Это ядро, и единственный скрипт, не являющийся модулем для гелиоса. там происходит много всяких таинственных вещей, но вкратце — первым делом подключается main.js (где программер начинает свой код). в каждом модуле есть набор инклюдов в шапке, и функция init(). ядро сначала подключает все эти скрипты (создавая объект <script> в ДОМе), составляет граф зависимостей, а потом в обратном порядке вызывает инициализаторы для каждого модуля. Но это очень упрощённо, на самом деле там ещё есть всякие навороты потипу динамической загрузки/выгрузки модуля и всех зависимостей, отслеживание циклических зависимостей и пр.

> Qooxdoo, YUI, Dojo+Dijit, jQuery UI.

Про куксду сказал выше, про остальное — честно, я не специалист по этим вещам, только лишь читал некоторые описания. Знаю, что, например подходы GWT и Eclipse RAP предлагают юзать джаву в IDE со всеми наворотами языка и фичами среды разработки, а потом всё это транслируется в HTML+JS+CSS+PHP+чтоугодно. Eclipse RAP, кстати, использует тот же куксду для виджетов в клиенте.

Ещё хочу сказать про DOM. Это — наполовину ответ на вопрос выше, и наполовину — на следующий:

> Как обстоят дела с модульностью и аддитивностью? Хочется, чтобы, например, CSS можно было бы задавать для каждого виджета *отдельно*…

Взаимодействие с DOM я постарался исключить полностью. Наличие как такового «документа» накладывает существенные ограничения. Возможно, чересчур опрометчиво с моей стороны, но с точки зрения разработчика на гелиосе — нет ни CSS, ни DOM. Лучше всего это увидеть, посмотрев код. Есть так называемые «свойства стиля», которые наследуются по виджетам и зависят ещё и друг от друга. Например, можно поменять цвет тени для какого-то фрейма, тогда он поменяется и у дочерних виджетов. Вот ещё пример: поменяв свойство primaryColor у виджета rootWidget на #112233 в калькуляторе, можно заставить его выглядеть так:

home.gna.org/helios/helioscalc_dark/

об этом есть на дом. страничке, но повторюсь ещё раз — покуда нет документации и покуда я не умею «грамотно составлять рекламные проспекты» :) лучше всего читать код, чтоб понять идею.

> В CSS бывает так, что, наложив один хак, ломается что-нибудь совсем в другом месте. И в JS тоже бывает. Как с этим быть? :)

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

> PS используйте кнопку «ответить», удобно ведь. :)

я с утра на хабре, ещё не сориентировался :)
> в каждом модуле есть набор инклюдов в шапке

> и функция init().

Значит ли это, что порядок подключения модулей играет роль? Допустим, имеет ли значение

include(«a.js»);include(«b.js») vs include(«b.js»);include(«a.js»)

если a и b выполняют какие-то изменения в модуле c в своих init()?

> Оно работает полностью на клиенте, в этом то и фишка.

Окей, это вроде более-менее понятно. Но как быть с отложенной загрузкой модулей в такой ситуации? Допустим, приложению может понадобиться какая-то новая функциональность, которую оно запросит с сервера. (С такой ситуацией не встречался, но читал презентацию, где такое описывалось.)

> Взаимодействие с DOM я постарался исключить полностью.

И это просто замечательно! В целом, побочные эффекты следует изолировать для упрощения своей же собственной жизни. :)

> Есть так называемые «свойства стиля», которые наследуются по виджетам и зависят ещё и друг от друга.

Как описывается это взаимодействие? Явно (constraints) или неявно (destructive update)? И зачем, интересно, наследовать эти свойства по виджетам?

> покуда нет документации и покуда я не умею «грамотно составлять рекламные проспекты» :) лучше всего читать код, чтоб понять идею.

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

На самом деле, я тут тоже кое-что педалирую потихоньку; даже имеются свежие (для мейнстримовых тулкитов) идеи. Только вот пока документации нет, заставлять читать код было бы нехорошо. :)
> Значит ли это, что порядок подключения модулей играет роль?

Модули инициализируются в порядке зависимостей. Если Вы указываете, что модуль c.js требует a.js и b.js, тогда ядро гелиоса гарантирует, что init() в a.js и b.js будет запущен раньше, чем init() в c.js, но не более того. Предполагается, что в a.js и b.js Вы определяете какие-то объекты, которые используются в c.js. Конечно, инициализирующие функции в модулях a и b вызываются по очереди, я даже могу сказать, что в простом случае они будут вызваны в том порядке, в котором они инклудятся. Но не нужно этот факт использовать для всяких хитростей. Честно говоря, я не вижу смысла в упомянутых Вами манипуляциях (с практической точки зрения). И, кроме того, если модуль b.js был подключен (востребован) где-то ранее, и уже был инициализирован, то он не будет инициализироваться повторно. Таким образом порядок может нарушиться.

> Но как быть с отложенной загрузкой модулей в такой ситуации?

Я здесь не писал, но в гелиосе есть поддержка динамической загрузки (и, кстати, выгрузки) модулей по требованию. Для этого используются функции load() и unload(). В какой-то момент Вы говорите load(a.js) и ядро подключает этот модуль (вместе с его новыми зависимостями) и так же инициализирует. unload() действует в обратную сторону, но при этом оставляет загруженными те модули, которые используются где-то ещё. Об этом подробно написано в туториале по ядру на домашней страничке.

>> Есть так называемые «свойства стиля», которые наследуются по виджетам и зависят ещё и друг от друга.

> Как описывается это взаимодействие? Явно (constraints) или неявно (destructive update)?

Я не знаком с такими понятиями и не очень понимаю, что значит «явно» и «неявно», так что приведу пример. Но прежде скажу пару слов о том, как устроена библиотека heliwidgets. Сам тулкит содержит объекты (Button, Label, etc) для виджетов, которые обладают некоторым интерфейсом. В этот интерфейс входят т.н. свойства виджетов (надпись на кнопке, ориентация «селектора» — горизонтальный или вертикальный, геометрия — обратите внимание, что она относится не к «свойствам стилей», о которых ниже), различные сигналы, извещающие о том, что, например, кнопка нажата, и некоторые методы (например, добавить новый элемент в селекторе). Никакого кода по отображению виджетов на экране и по взаимодействию с броузером (поимка сообщений о нажатии кнопки мыши, например), в этих объектах нет. Такими вещами занимается движок (rendering engine), который полностью отделён от логики виджетов. Сейчас единственный существующий движок использует canvas для отрисовки виджетов на экране, это то что Вы видели на демке с калькулятором. В принципе, ничто не мешает сделать движок, который будет рендерить виджеты, например, во флэш-апплете, сообщаясь через LocalConnection. Или даже можно написать плагин для фаерфокса, который будет предоставлять некоторый js объект с интерфейсом движка для heliwidgets, который будет рендерить виджеты используя десктопный тулкит, хоть тот же GTK, это наверняка будет работать быстрее. Так вот на самом деле, упомянутые свойства стиля (StyleProperty) — это сущность, которая относится к движку. Совокупность свойств стиля можно воспринимать как «скин» для конкретного движка. Движок сам определяет, какие свойства стиля у него есть. Например, в helianthus (это так называется единственный пока написанный движок) есть свойства стиля, которые определяют основной цвет, цвет подсветки, цвет тени (которые зависят от основного, но их можно переопределить), и есть ещё, например, «извратное» свойство стиля cornerRoundness, которое определяет радиус закругления углов во всех прямоугольных объектах. Вот почему геометрия не относится к свойствам стиля, а относится к самому тулкиту. Наследование по виджетам нужно вот для чего. Например, есть виджет Frame (прямоугольная рамка с виджетами внутри). И если ей установить какое-нибудь свойство стиля, например цвет тени, то это изменение будет так же применено и ко всем внутренним виджетам, потому что это логично, и это поведение, которое ожидает получить программист.

> Только вот пока документации нет, заставлять читать код было бы нехорошо. :)

В архиве с калькулятором (линк на дом.страничке) есть ридми, в котором кое-что сказано, а вообще калькулятор писался как codecast, то есть это с одной стороны реально работающее приложение, которое можно запустить, а с другой — если открыть исходник, то комментарий представляет собой по сути документацию, где есть описание с самого начала всего, что происходит, и где подробно объяснён каждый вызов, что он делает и какие у него параметры. Так что рекомендую всё же.
> Честно говоря, я не вижу смысла в упомянутых Вами манипуляциях (с практической точки зрения)

Смысла и нету. :) Просто как-то нехорошо было бы, если бы один вариант заработал, а второй — нет. Спасибо за развернутый ответ.

> Я не знаком с такими понятиями и не очень понимаю, что значит «явно» и «неявно», так что приведу пример.

«Явно» было бы примерно так:

color = hoveredOver? «black»: «white»; (1)

а неявно было бы

onfocus = function() {color = «black»;} (2)
onblur = function() {color = «white»;}

Как видно, зависимости разворачиваются вспять: мы хотим (1), получаем (2), в котором все наоборот. В первом случае цвет определяется в одном месте, во втором же размазан по всему объекту-модулю, что затрудняет отладку и сопровождение.

> Но прежде скажу пару слов о том, как устроена библиотека heliwidgets.

Ну в общем, как у всех. :)

> Никакого кода по отображению виджетов на экране и по взаимодействию с броузером (поимка сообщений о нажатии кнопки мыши, например), в этих объектах нет.

И правильно, не место ему там.

> Такими вещами занимается движок (rendering engine), который полностью отделён от логики виджетов. Сейчас единственный существующий движок использует canvas для отрисовки виджетов на экране, это то что Вы видели на демке с калькулятором.

Single responsibility principle, классика модульного программирования. :)

> Наследование по виджетам нужно вот для чего. Например, есть виджет Frame (прямоугольная рамка с виджетами внутри). И если ей установить какое-нибудь свойство стиля, например цвет тени, то это изменение будет так же применено и ко всем внутренним виджетам, потому что это логично, и это поведение, которое ожидает получить программист.

А как быть, когда зависимости подымаются снизу вверх? Например, при размещении элементов так оно и есть: позиция элемента определяется сверху вниз, а размер занятой области снизу вверх (и пр. вариации). Стили тоже могут подыматься: примером будет text input, предок которого подсвечивается особым цветом тогда, когда
— text input не проходит проверку
— text input находится под фокусом ввода

Бывает еще, когда зависимости распространяются слева направо и справа налево, и другими способами.

> В архиве с калькулятором (линк на дом.страничке) есть ридми, в котором кое-что сказано, а вообще калькулятор писался как codecast, то есть это с одной стороны реально работающее приложение, которое можно запустить, а с другой — если открыть исходник, то комментарий представляет собой по сути документацию, где есть описание с самого начала всего, что происходит, и где подробно объяснён каждый вызов, что он делает и какие у него параметры. Так что рекомендую всё же.

Хорошо, убедили. Почитаю на досуге.

PS к сожалению не смогу там быть, но выкладывайте записи/презентацию в интернеты, почитаю. также могу открыть свои доки с идеями, а сорцы здесь: patch-tag.com/r/fjwt/home (если они, конечно, интересны)
> «Явно» было бы примерно так:…

свойство стиля предоставляет сеттер и геттер, и я бы подписал его на сигнал, примерно так:

myWidget.sigMouseOver.listen( myWidget.setStyleProp( «color», "#ffffff" ) );
myWidget.sigMouseOut.listen( myWidget.setStyleProp( «color», "#000000" ) );

по-вашему, это, похоже неявный способ. это плохо? :)

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

> А как быть, когда зависимости подымаются снизу вверх? Например, при размещении элементов так оно и есть: позиция элемента определяется сверху вниз, а размер занятой области снизу вверх (и пр. вариации).

Геометрия, как уже писал, не есть свойство стиля (тут, похоже, будет путаница, потому что слово «стиль» сразу же ассоциируется с css, надо бы не забыть описать это в мануале :) ). Кстати говоря, в heliwidgets я как раз сейчас остановился на реализации этой фичи, так что я пока даже не могу сделать обычный скроллинг :). Думаю, как снова появится время займусь как раз этим.

> Стили тоже могут подыматься: примером будет text input, предок которого подсвечивается особым цветом

Я думаю, что в этом случае будет подсвечиваться сам виджет, а не его предок. Сложные древовидные формы — это редкий случай, я такого не видел.

> Бывает еще, когда зависимости распространяются слева направо и справа налево, и другими способами.

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

> но выкладывайте записи/презентацию в интернеты, почитаю.

Я думаю, что в скором времени обновлю домашнюю страничку в соответствии с комментариями и частозадаваемыми вопросами здесь и на мероприятии. То, как я всё описываю часто не совпадает с тем, что хочет увидеть потенциальный читатель :) В частности, Вам я благодарен за комментарий номер 4 (http://xpostman.habrahabr.ru/blog/68291/#comment_1935958), постараюсь на него ответить в ближайшие дни.

> также могу открыть свои доки с идеями, а сорцы здесь

постараюсь поглядеть в ближайшее время, если оно найдётся. хотя я с эгоистической точки зрения рассуждаю :) (то есть, у меня в голове вопросы, из серии, «что полезного я могу извлечь оттуда для гелиоса» :) ). но совместный брейншторм может оказаться взаимовыгодным.

> по-вашему, это, похоже неявный способ. это плохо? :)

Мне непонятно, как это расширить. Как с этими «сигналами» (кстати по совпадению, основными сущностями в flapjax являются сигналы и события ;)) можно замутить
1) совмещение событий по времени: flapjax-lang.org/try/index.html?edit=persistent_drafts.fx (там черновик сохраняется либо по таймауту, либо по кнопке «сохранить» — смотря что произойдет первым. таймаут замеряется либо от предыдущего нажатия кнопки, либо в самом начале, при загрузке страницы)
2) и добавить третье состояние для кнопки (хочется, чтобы текущая выбранная кнопка оставалась другого цвета):

function fun(sel,hov) { return sel? «red»: hov? «white»: «black»; }
var x = liftB(fun,selectedB,hoveredB); // цвет

Почему так лучше? Потому что в этом фрагменте кода описывается состояние системы *во все времена* (а не *здесь и сейчас*), что упрощает отладку значительно (фактически, никогда и не лазишь в дебагер ;) — все просто работает; обычно встречаются ошибки типов и опечатки).

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

Конечно, классно было бы полностью отделить содержание от оформления. Только, насколько мне известно, это возможно только в идеальных условиях. Поэтому мне кажется, что удобнее будет разделить все эти свойства просто по критерию, где они задаются: layout определяет местоположение всех элементов, а местоположение влияет на свойства CSS left/top/width/height/right/bottom выставляет position. Если не изменять эти свойства после того, как они были заданы (то есть при конструировании виджета), то легче будет отследить, что и откуда берется.

> Геометрия, как уже писал, не есть свойство стиля (тут, похоже, будет путаница, потому что слово «стиль» сразу же ассоциируется с css, надо бы не забыть описать это в мануале :) ). Кстати говоря, в heliwidgets я как раз сейчас остановился на реализации этой фичи, так что я пока даже не могу сделать обычный скроллинг :). Думаю, как снова появится время займусь как раз этим.

Я тоже еще не реализовал layout'ы. Схем много (хотя, что поразительно, почти все они могут быть довольно просто выражены через constraint'ы — посмотрите [1], там я быстро-решительно реализовал некое подобие springs'n'struts из NeXTstep/Mac OS X), часто зависимости бывают сложными (те самые top-down, bottom-up, left-to-right, right-to-left, про которые я уже упоминал).

> Я думаю, что в этом случае будет подсвечиваться сам виджет, а не его предок. Сложные древовидные формы — это редкий случай, я такого не видел.

Я имею в виду что-то вроде такого: www.unwrongest.com/projects/valid8/ (там внизу демонстрации есть, подсвечивается не сам text input, а его предок).

> постараюсь поглядеть в ближайшее время, если оно найдётся. хотя я с эгоистической точки зрения рассуждаю :) (то есть, у меня в голове вопросы, из серии, «что полезного я могу извлечь оттуда для гелиоса» :) ). но совместный брейншторм может оказаться взаимовыгодным.

Хорошо, скиньте свой email в личку. Открою документы на просмотр. Если будет что интересное — сообщайте. :) Если будут идеи, то пишите.

[1] patch-tag.com/r/fjwt/snapshot/current/content/pretty/layout
Кстати, если Вы из Питера, приходите на хакдэй (hackday.ru) на след. выходных, я планирую там подробно рассказать о проекте.
идеи-то опиши ;-)
Конечно. По копейке за дюжину ведь.

— GUI-приложения реактивны: они реагируют на события, инициируемые пользователем (поэтому нужно реактивное программирование)
— композиция важна
— механизм, а не политика

Можно еще запилить DSL со статической проверкой всего и вся (например, total FPL, который можно инлайнить и специализировать FTW — таким образом можно обогнать вручную написанный JS ;)).

Есть еще проблема модульности, которую xpostman решил своим способом (тоже нужно). Атрибутные грамматики могут пригодиться — они могут просто и ясно выразить layout, например.
ничего не понял…
я тоже не очень понимаю, о чём речь. нельзя ли для непосвящённых пояснить, что означает:

— реактивные GUI-приложения
— реактивное программирование
— композиция в данном контексте
— механизм и политика
— DSL со статической проверкой всего и вся
— total FPL
— FTW
— атрибутные грамматики
> реактивные GUI-приложения

Где же это видано, чтобы в GUI-приложении встречался такой код?

var count = 0;
var foo = false;
ask(«how much is da fish?»);
get(count);
ask(«so you wanna be a rock'n'roll star?»);
get(foo);

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

> реактивное программирование

Это такой подвид dataflow programming. Здесь основное внимание уделяется потоку данных (обычно же наоборот — поток управления заправляет всем). То есть важным является не порядок операций (сделай то, потом сделай это — foo();bar();), а зависимости одних переменных от других (в примере, который я приводил выше, color зависит от hoveredB, selectedB).

> композиция в данном контексте

Можно читать как «комбинация». Есть какие-то a,b и операция f, которая совмещает/комбинирует их, возвращая некое c.

Ну допустим есть функция mul(a) (умножает a на 5), и add(a) (прибавляет 2 к a). Сколько комбинаций из них мы можем построить?

var x = 4;
mul(add(x))
mul(add(add(x)))
add(mul(add(x)))

etc. Вот этот паттерн mul(add(x)) называется композицией (функций). То бишь мы можем ввести операцию compose(f,g) которая принимает две функции и возвращает функцию h, которая:

function compose(f,g) {
return function(x) { return f(g(x)); }
}

Чем это полезно на практике? Тем, что мы можем выражать какие-то вычисления через другие. Иногда даже можно упростить реализацию значительно. Не пиши заново, используй повторно! :)

Но на самом деле концепция более общая. Больше [1][2].

Ну и параметризм тоже важен. Например, если бы в STL не было итераторов, то пришлось бы реализовывать алгоритмы над каждой структурой данных отдельно. m структур и n алгоритмов тогда дадут n * m реализаций. С композицией получаем n + m реализаций. ;)

> механизм и политика

Это принцип из разработки OS. Mechanism vs policy. Во фреймворках обычно политику дают, а не дают способа получить то, что хочется, посредством механизма. Больше философствовать не буду.

> DSL со статической проверкой всего и вся

Имеется в виду предметно-ориентированный язык программирования со статической проверкой типов.

> total FPL

FPL = functional programming language

«Totality» означает, что в языке программирования *все* программы будут завершаться (то есть не уйдут в бесконечный цикл или что-то подобное). Это дает возможность проводить мощные оптимизации.

FTW значит for the win. ;)

> атрибутные грамматики

Это придумка Кнута, AFAIK. Так как виджеты организуются в иерархию (дерево), то мы можем присваивать какие-то атрибуты узлам. Эти самые атрибуты могут быть чем угодно, например, цветом. ;)

Атрибутные грамматики дают возможность описывать, как атрибуты одного узла зависят от атрибутов других узлов. Например, каскад стилей можно описать посредством наследуемых (inherited) атрибутов. Больше [3].

[1] en.wikipedia.org/wiki/Function_composition_(computer_science)
[2] en.wikipedia.org/wiki/Object_composition
[3] en.wikipedia.org/wiki/Attribute_grammars
из-за «безсерверного инклуда» загрузка получается дико долгой…
я у себя сделал серверный автосборщик, в результате чего грузится только то, что реально используется в одном пакете.
здесь загружается только то, что инклудится начиная с main.js. Или ваш автосборщик работает пообъектно?
у меня регуляркой ищутся выражения вида $.node.list( ) и предварительно инклудятся зависимости вида ./$/node/list.js
./$/node/.js
./$/node.js
./$/.js
./$.js

если я правильно понял:
это накладывает соглашение об именовании объектов и модулей, где они объявлены? я думаю, что самостоятельно определять структуру модулей иногда удобнее. кроме того, если в одном модуле есть два объекта, из которых, возможно, использоваться только один, тогда имеет смысл разделить эти модули. тогда и при моём подходе ничего лишнего грузится не будет, и также не будет лишней нагрузки на сервер
солашения — это хорошо ;-) вон, в линуксе есть соглашение на структуру директорий и ничего…

к тому же, подобные солашения здорово упрощают рефакторинг…

для своих скриптов определяешь структуру, конечно же, сам. а менять структуру фреймворка… зачем? в конце концов можно наделать алиасов в духе $my.nodes= $.node.list

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

var n= $.node
var els= n.list( elements )

а вот такая сработает:

var nl= $.node.list
var els= nl( elements )
ничто не мешает юзать соглашения и в моём случае, в либах для гелиоса я тоже старался их придерживаться. я лишь считаю, что не нужно навязывать, потому что возникают исключения, когда удобней поступить по-иному.

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

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

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

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

> кстати, а что мешает kernel.js засунуть прямо в хтмл, раз больше ни для чего этот хтмл и не нужен?

хтмл код находится в .html файле, джаваскрипт — в .js. по-моему, так логично :)
логично, но медленно. ты, когда разрабатываешь, чтобы посмотреть что получилось, жмёшь ф5 и 10 секунд любуешься полосой прогресса?
однако же при разработке на C++ мне приходится ждать ещё и перекомпиляции. аналогичная ситуация, полагаю, и при использовании подхода GWT/Eclipse RAP. не считаю это недостатком.
поэтому c++ в вебе и не используется…
// text loader
this.loadingLayer = document.createElement( «div» );
this.loadingLayer.style.position = «absolute»;
this.loadingLayer.style.left = 0;
this.loadingLayer.style.top = 0;
this.loadingLayer.style.width = «100%»;
this.loadingLayer.style.height = 30;
this.loadingLayer.style.textAlign = «center»;
this.loadingLayer.style.color = this.foregroundColor;
this.loadingLayer.style.fontFamily = this.fontFamily;
this.loadingLayer.style.fontSize = this.fontSize;
this.loadingLayer.innerHTML = "" + this.loadingString;
body.appendChild( this.loadingLayer );

this.logMessage(
«Module has not been parsed for » +
this.notParsedTimeout +
" seconds. Possible reasons are: connection to the " +
«server was lost or is too slow, module source file» +
" does not exist, module source file does not conta" +
«in its initializer function (or in case of unloada» +
«ble module, does not contain its both initializer » +
«and uninitializer functions), or there were some J» +
«S errors while parsing the module (check JS errors» +
" log). After " +
(this.continueParsingTimeout-this.notParsedTimeout) +
" more seconds helios kernel will try to skip parsi" +
«ng this module and continue parsing others. Failed» +
" module path: '" +
this.activeModule.path +
"'. This module was requested to include in '" +
( (this.activeModule.children.length > 0)?
this.activeModule.children[ 0 ].path:
«unknown») +
"'."
);
Math.max3() — returns the maximum of three numbers
Math.min3() — returns the minimum of three numbers

а с max3/min3 что не так? :)
то же что и с max и min — фиксированное число параметров
действительно, спасибо за идею :)

простые вещи не всегда сразу в голову приходят. на самом деле пересматривая код я часто нахожу разные идиотизмы, которые сначала не замечал. наверное, про kernel.js это больше всего верно — как только я его дописал до такого состояния, что у меня прошли все тесткейсы на основных броузерах — я обрадовался и с головой погрузился в написание либов. а codereview мне было не с кем провести пока, среди моих знакомых прогеров, из тех, что хоть немного в теме, большинство высказывают комменты вроде «вах, вот это неимоверно круто, респект чувак». от такого фидбэка, понятное дело, толку мало :)
Из него можно вытаскивать отдельные библиотеки? Например если мне нужна только удобная работа с AJAX и больше ничего, я смогу взять нужную либу и использовать её отдельно от всего фреймворка?
я не думал над этим. пока никакого экспорта библиотек на что-то другое не планируется. я не думаю, что когда-то этим займусь, здесь процесс разработки несколько иной. сейчас в вебе на клиенте всё завязано на DOM. здесь же предполагается, что программист имеет дело только лишь с интерфейсом объектов из библиотек. DOM относится к концепции «документа», а не приложения. с его помощью и с помощью известных фреймворков легко и элегантно решаются задачи из серии «возьмём все чётные ячейки таблицы и поменяем у них фон». здесь же предлагается более системный подход. почитайте кодкаст калькулятора, там продемонстрирован процесс разработки приложения для helios (линк на домашней страничке). я пытаюсь приблизить веб-разработку к системному программированию и к решению действительно интересных задач, и уйти от траты времени на решением проблем с css и межброузерной совместимостью.
в IE8 не работает демка, даже посмотреть не получилось :(
В IE нету canvas'а, через который виджеты рендерятся в единственном существующем движке для heliwidgets. Планируется оформить гугловский excanvas в виде модуля для гелиоса, чтоб обеспечить эмуляцию через VML или Silverlight. Пока не сделано.
как мне выделить текст и скопировать его в буффер обмена? и наоборот…
пока не реализовано
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории