vanilla-beans
Version:
Thin layer on top of HTML and DOM API, dramatically simplify development of SPA using Vanilla Js.
258 lines (170 loc) • 15.6 kB
Markdown
# vanilla-beans спецификация
> Этот документ разъясняет понятия и сущности.
## Назначение библиотеки
**vanilla-beans** - нормализованная библиотека, предназначена для разработки пользовательских интерфейсов любой сложности и динамичности. Предоставляет возможность создания собственных компонентов - **beans** и объединения их в сложные композиты, непосредственно используя возможности HTML, Javascript и DOM API.
## Краткое описание
**vanilla-beans** - это тонкая надстройка над HTML и DOM API, не создаэт своего собственного окружения, не диктует правила и не изолирует Вас от возможностей WEB платформы. Всё, что можно делать с HTML и Javascript, можно делать с компонентами **vanilla-beans**. Декларация компонента, - это HTML для описания структуры компонента и Javascript для описания его поведения.
Компонент описывается наиболее очевидным для связки HTML и Javascript образом.
Библиотека экстремально лёгкая и быстрая.
Крайне проста в освоении, достаточно знания основ HTML, Javascript и DOM API.
Декларацию компонента может без подготовки понять любой человек, знакомый с этими основами.
Библиотека и идеи, на которых она построена просты и очевидны.
Идеальна для обучения.
**vanilla-beans, не является альтернативой Web Components, прекрасно с ними совмещается в обе стороны.**
- [Термины и определения](#термины-и-определения)
- [Состав библиотеки](#состав-библиотеки)
- [Расширение HTML](#расширение-html) для использования в BeansModule declaration
- [Жизненный цикл бина](#жизненный-цикл-бина) - хэндлеры и коллбэки
- [Init script](#init-script) - скрипт инициализации
- [Built-in beans](#built-in-beans) - втроенные компоненты
## Термины и определения
### Bean
Композитный компонент, - основной строительный блок для построения пользовательского интерфейса, имеет своё дерево DOM, поведение и [жизненный цикл](#жизненный-цикл-бина). Может составляться из стандартных элементов, Custom Elements и других бинов.
### Bean declaration
Декларация бина - HTML разметка и (опционально) скрипт инициализации, описывающий поведение и обработчики событий жизненного цикла.
Минимальая декларация бина на базе элемента DIV:
```html
<div beans-as="my-bean"></div>
```
Парсинг декларации осуществляется штатными средствами браузера. HTML комментарии игнрируются при парсинге.
### BeanDescriptor
Дескриптор бина - внутреннее представление бина в репозитории, создаётся библиотекой из декларации бина.
### BeanInstance
Экземпляр бина, - DOM Node с подмешанными методами и обработчиками событий жизненного цикла, не содержит специфичных **beans-ххх** атрибутов. Создаётся библиотекой из BeanDescriptor
### BeansModule declaration
Текстовый файл или строка с набором деклараций бинов и импортом других BeansModule (аналогично модулям ESM), так-же может импортировать модули CommonJs (без зависимостей) и CSS файлы.
### BeansModule
Набор BeanDescriptor's в репозитории, создаётся бибиотекой из BeansModule declaration.
### Factory
Фабрика, связанная с конкретным BeansModule, готовая к инициализации контекстом приложения. Имеет интерфейс:
```ts
{
with: ($context: any) => {
create: (
tag: string,
attributes: {[name]: string}
) => BeanInstance | Element
}
}
```
### FactoryInitiated
Фабрика, связанная с конкретным BeansModule, инициированная контекстом приложения.
### Application
Приложение, в котором используются бины. Объединяется через **Application context**
### Application context
Произвольный объект, определяемый разработчиком приложения, который передаётся во все бины одного приложения через аргумент [скрипта инициализации](#init-script) **$context**.
**$context** может содержать, например, ссылку на контроллер, общий диспетчер сообщений, менеджер состояний, набор настроек, всё что полезно, - в зависимости от реализуемой архитектуры приложения.
## Состав библиотеки
### Модули
- [factory/factory.mjs](../lib/factory/factory.mjs) экспортирует по умолчанию фабричный метод **factory**, возвращающий экземпляр [Factory](#factory), принимает в качестве аргумента ключ (src) зарегистрированного модуля.
- [loader/load-vanilla-beans.mjs](../lib/loader/load-vanilla-beans.mjs) асинхронный загрузчик модулей, имеет интерфейс
```
(src: string, callback: (factory: Factory) => void) => void
```
в аргументе коллбэка возвращается экземпляр [Factory](#factory), соответствуюший аргументу **src**.
### Сборки
## Расширение HTML
> **для использования в BeansModule declaration**
Библиотека расширяет HTML, вводя специальные тэги и атрибуты для использования в [BeansModule declaration](#beansmodule-declaration).
**Ни тэги, ни аттрибуты из ниже перечисленных не попадают в результирующее дерево DOM.**
### Tags
Добавлен только один тэг
#### <a name="BEANS-IMPORT"><BEANS-IMPORT></a> используется в [BeansModule declaration](#beansnodule-declaration) для подключения зависимостей. должен располагаться на верхнем уровне декларации модуля.
```html
--imports
<beans-import type="html" src="./module.html" beans-as="my-module"></beans-import>
<beans-import type="cjs" src="../js/module.js" beans-as="my-script"></beans-import>
<beans-import type="css" src="../css/module.css" beans-as="my-stylesheet"></beans-import>
--beans declarations
.......
```
Настраивается атрибутами
- **type** - тип подключаемого ресурса, может принимать значения
- **html** - для подключения [BeansModule declaration](#beansmodule-declaration)
- **cjs** - для подключения модуля CommonJs, модуль CJS не должен иметь зависимостей.
- **css** - для подключения файла css
не обязательный, по умолчанию **"html"**
- **src** - относительный или абсолютный адрес подключаемого ресурса (URL или имя файла)
обязательный
- **beans-as** - имя подключаемого ресурса для использования в декларациях бинов и скриптах инициализации
обязательный, значение должно быть уникальным для тэгов BEANS-IMPORT в пределах [BeansModule declaration](#beansmodule-declaration), значение должно быть допустимым для использования в тэгах XML и не содержать символ "**.**" (точка)
Допускаются рекурсивные зависимости, при обнаружении такой зависимости в консоли браузера будет выведено предупреждение.
### Атрибуты, используемые в [Bean declaration](#bean-declaration)
В декларациях бинов могут применяться семь дополнительных атрибутов
- **beans-as** - объявляет имя декларируемого бина для использования в других декларациях, располагается в корневом элементе декларируемого бина, значение не чувствительно к регистру. Значение может быть любой строкой.
обязателен для [декларации нового бина](#bean-declaration).
- **beans-tagname** - может применяться в корневом элементе [Bean declaration](#bean-declaration) и в любом элементе внутри [Bean declaration](#bean-declaration), используется для подмены базового тэга, на основе которго создаётся бин, может принимать имя бина, имя станартного или пользовательского элемента, применяется в [BeanDescriptor](#beandescriptor) вместо **element.tagName**. Нужен для того, чтобы можно было использовать любой тэг в любом месте декларации.
Значение не чувствительно к регистру, если указывает на имя бина или тэг HTML.
- **beans-usetag** - может применяться так-же как и **beans-tagname**, но не перекрывает имя бина, применяется в момент создания [экземпляра](#beaninstance). Нужен для того, чтобы из любого компонента создавать любые тэги.
- **beans-ref** - имя ссылки на элемент, для использования в [скрипте инициализации](#init-script)
- **beans-body** - указывает элемент в поддереве бина, в который будут монтироваться ноды извне, в бине может располагаться только один элемент с тэгом **beans-body**
- **beans-shadow** - атрибут указвает на то, что данный элемент будет иметь теневое дерево, значение атрибута - параметры теневого дерева в форме "param1=value1;param2=value2". Может создавать теневое дерево как для всего бина, так и для любого элемента в его поддереве.
- **beans-style** - используется только совместно с **beans-shadow**, значение - список имён импортированных файлов CSS, разделённых ";" (точка с запятой). Стили подключаются по возможности в **adoptedStyleSheets**, при невозможности подключения в **adoptedStyleSheets** добавляются как элементы **<STYLE>**
В декларациях бинов могут применяться любые другие атрибуты.
Использование атрибута **xmlns** означает, что элемент и его поддерево будут создаваться с соответсвующим **NAMESPACE**.
Пример декларации BeansModule с одним Bean, по имени "**root**" и теневым деревом.
```xml
-- импорты
<beans-import type="css" beans-as="mystyle" src="../css/my-style.css"></beans-import>
<beans-import type="css" beans-as="nextstyle" src="../css/next-style.css"></beans-import>
<beans-import type="html" beans-as="module1" src="./module1.html"></beans-import>
<beans-import type="html" beans-as="module2" src="./module2.html"></beans-import>
-- декларации бинов
<div beans-as="root"
beans-shadow="
mode = closed;
delegatesFocus = true;
"
beans-style="mystyle; nextstyle;">
<h1>Title!</h1>
<ul>
<module1.root beans-ref="first" beans-usetag="li">
</module1.root>
<module2.root beans-ref="second" beans-usetag="li">
</module2.root>
</ul>
<script>
```
- **[Init script](#init-script)**
```xml
</script>
</div>
```
## Жизненный цикл бина
Vanilla Bean в течении своей жизни проходит через следующие этвпы:
- Создание - create
- Монтирование в документ - mount
- Начала обслуживания - start
- Обновление данных - update
- Окончание обслуживания - stop
- Демонтирование из документа - unmount
- Уничтожение - destroy
Для того, чтобы Bean мог реагировать на эти события предусмотрены хендлеры жизненного цикла
- mount -
```js
beanMount: (target: Node, before?: Node | number) => void
```
- unmount -
```ts
beanUnmount: () => void
```
- start -
```ts
beanStart: () => void
```
- stop -
```ts
beanStop: () => void
```
- update -
```ts
beanUpdate: (data: any, options?: any, additional?: any) => void
```
- drstroy -
```ts
beanDestroy: () => void
```
- create - Для этого события нет специального хендлера, всё что нужно сделать при создании экземпляра Bean можно сделать в **Init script**, он вызывается автоматически, когда Вы вызываете
factory.create('your-bean-name')
## Init script
## Built-in beans