`? If you use [native DOM Selection](https://developer.mozilla.org/en-US/docs/Web/API/Selection), you may get both positions — one anchored in `` and the other anchored in ``. In CKEditor 5 this position translates exactly to `"Foo ^bar"`.
#### Selection attributes
OK, but how to let CKEditor 5 know that I want the selection to "be bold" in the case described above? This is important information because it affects whether or not the typed text will be bold, too.
To handle that, selection also {@link module:engine/model/selection~Selection#setAttribute has attributes}. If the selection is placed in `"Foo ^bar"` and it has the attribute `bold=true`, you know that the user will type bold text.
#### Positions
However, it has just been said that inside `` there are two text nodes: `"Foo "` and `"bar"`. If you know how [native DOM Ranges](https://developer.mozilla.org/en-US/docs/Web/API/Range) work you might thus ask: "But if the selection is at the boundary of two text nodes, is it anchored in the left one, the right one, or in the containing element?"
This is, indeed, another problem with DOM APIs. Not only can positions outside and inside some element be identical visually but also they can be anchored inside or outside a text node (if the position is at a text node boundary). This all creates extreme complications when implementing editing algorithms.
To avoid such troubles, and to make collaborative editing possible for real, CKEditor 5 uses the concepts of **indexes** and **offsets**. Indexes relate to nodes (elements and text nodes) while offsets relate to positions. For example, in the following structure:
```html
"Foo "
"bar"
```
The `"Foo "` text node is at index `0` in its parent, `` is at index `1` and `"bar"` is at index `2`.
On the other hand, offset `x` in `` translates to:
| offset | position | node |
|--------|--------------------------------------------------|-----------|
| `0` | `^Foo bar` | `"Foo "` |
| `1` | `F^oo bar` | `"Foo "` |
| `4` | `Foo ^bar` | `` |
| `6` | `Foo b^ar` | `"bar"` |
The engine also defines three main classes which operate on offsets:
* A {@link module:engine/model/position~Position} instance contains an {@link module:engine/model/position~Position#path array of offsets} (which is called a "path"). See the examples in {@link module:engine/model/position~Position#path `Position#path` API documentation} to better understand how paths work.
* {@link module:engine/model/range~Range} contains two positions: {@link module:engine/model/range~Range#start start} and {@link module:engine/model/range~Range#end end} ones.
* Finally, there is {@link module:engine/model/selection~Selection} which contains one or more ranges and attributes.
### View
### Controller
## UI library
The standard UI library of CKEditor 5 is [`@ckeditor/ckeditor5-ui`](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui). It provide sbase classes and helpers that that allow building a modular UI that seamlessly integrates with other components of the ecosystem.
### Templates
{@link module:ui/template~Template Templates} render DOM elements and text nodes in the UI library. Used primarily by [views](#Views), they're the lowest layer of the UI connecting the application to the web page.
Templates are built from the {@link module:ui/template~TemplateDefinition definitions}, they support [observable attribute](#Event-system-and-observables) bindings and handle native DOM events.
A very simple template can look like this
```js
const bind = Template.bind( observable, emitter );
new Template( {
tag: 'p',
attributes: {
class: [
'foo',
bind.to( 'className' )
],
style: {
backgroundColor: 'yellow'
}
},
on: {
click: bind.to( 'clicked' )
}
children: [
'A paragraph.'
]
} ).render();
```
and renders to an HTML element
```html
A paragraph.
```
when `observable#className` is `"bar"`. The `observable` in the example above can be a [view](#Views) or any object which is {@link module:utils/observablemixin~Observable observable}. When the value of the `className` attribute changes, the template updates the `class` in attribute in DOM – from now on the element is permanently bound to the state of an application.
Similarly, when rendered, the template also takes care of DOM events. A binding to the `click` event in the definition makes the `observable` always fire the `clicked` event upon an action in DOM. This way the `observable` provides an event interface of the DOM element and all the communication should pass through it.
### Views
Views use [templates](#Templates) to build the UI. They provide observable interfaces that other features (e.g. [plugins](#Plugins), [commands](#Commands), etc.) can use to change the DOM without an any actual interaction with the native API.
Additionally, views encapsulate the DOM they render. Because the UI is organized according to the *view-per-tree* rule, it is clear which view is responsible for which part of the UI so it is unlikely that a collision occurs between two features writing to the same DOM node.
A simple input view could look like this:
```js
class SampleInputView extends View {
constructor( locale ) {
super( locale );
// A shorthand for Template.bind( this, this ).
const bind = this.bindTemplate;
// Views define their interface (state) using observable attributes.
this.set( {
isEnabled: false,
placeholder: ''
} );
this.template = new Template( {
tag: 'input',
attributes: {
class: [
'foo',
bind.if( 'isEnabled', 'ck-enabled' ),
],
placeholder: bind.to( 'placeholder' ),
type: 'text'
},
on: {
keydown: bind.to( 'input' )
}
} );
}
setValue( newValue ) {
this.element.value = newValue;
}
}
```
Views must be {@link module:ui/view~View#init initialized} before they work properly. Then, they can be injected into DOM directly or become a child of another view, a node in the [UI view tree](#View-collections-and-the-UI-tree):
```js
const view = new SampleInputView( locale );
view.init();
document.body.appendChild( view.element );
```
Features can interact with the state of the DOM via the attributes of the view:
```js
// Will append "ck-enabled" to the HTML "class" attribute.
view.isEnabled = true;
// Will change the HTML "placeholder" attribute.
view.placeholder = 'Type some text';
```
or they can [bind](#Event-system-and-observables) them directly to their own observable attributes:
```js
view.bind( 'placeholder', 'isEnabled' ).to( observable, 'placeholderText', 'isEnabled' );
// The following will be automatically reflected in the view#placeholder and
// view.element#placeholder attribute.
observable.placeholderText = 'Some placeholder';
```
Also since views propagate the DOM events, features can now react to the user actions:
```js
// Each "keydown" event in the input will execute a command.
view.on( 'input', () => {
editor.execute( 'myCommand' );
} );
```
A complete view should provide an interface for the features, encapsulating DOM nodes and attributes. Features should not touch the DOM of the view using the native API. Any kind of interaction must be handled by the view that owns an {@link module:ui/view~View#element} to avoid collisions:
```js
// Will change the value of the input.
view.setValue( 'A new value of the input.' );
// This is **NOT** the right way to interact with DOM because it collides
// with an observable binding to the #placeholderText. The value will be
// permanently overridden when the state of the observable changes.
view.element.placeholder = 'A new placeholder';
```
### View collections and the UI tree
### Keystrokes and focus management