# widget/utils

module

<a id="constants">

## Constants

<a id="constant-WIDGET_CLASS_NAME">

### `WIDGET_CLASS_NAME: 'ck-widget'`

CSS class added to each widget element.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-widget/src/utils.ts#L44)

<a id="constant-WIDGET_SELECTED_CLASS_NAME">

### `WIDGET_SELECTED_CLASS_NAME: 'ck-widget_selected'`

CSS class added to currently selected widget element.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-widget/src/utils.ts#L49)

<a id="functions">

## Functions

<a id="function-calculateResizeHostAncestorWidth">

### `calculateResizeHostAncestorWidth( domResizeHost ) → number`

Starting from a DOM resize host element (an element that receives dimensions as a result of resizing), this helper returns the width of the found ancestor element.

```
* It searches up to 5 levels of ancestors only.
```

The search crosses shadow DOM boundaries, so for a resize host inside a shadow root it continues through the host into the surrounding (light) DOM instead of stopping at the boundary.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-widget/src/utils.ts#L484)

#### Parameters

* `domResizeHost: HTMLElement`

  Resize host DOM element that receives dimensions as a result of resizing.

#### Returns

* `number`

  Width of ancestor element in pixels or 0 if no ancestor with a computed width has been found.

<a id="function-calculateResizeHostPercentageWidth">

### `calculateResizeHostPercentageWidth( domResizeHost, resizeHostRect ) → number`

Calculates a relative width of a `domResizeHost` compared to its ancestor in percents.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-widget/src/utils.ts#L527)

#### Parameters

* `domResizeHost: HTMLElement`

  Resize host DOM element.

* `resizeHostRect: Rect`

  Defaults to `...`

#### Returns

* `number`

  Percentage value between 0 and 100.

<a id="function-findOptimalInsertionRange">

### `findOptimalInsertionRange( selection, model ) → ModelRange`

Returns a model range which is optimal (in terms of UX) for inserting a widget block.

For instance, if a selection is in the middle of a paragraph, the collapsed range before this paragraph will be returned so that it is not split. If the selection is at the end of a paragraph, the collapsed range after this paragraph will be returned.

Note: If the selection is placed in an empty block, the range in that block will be returned. If that range is then passed to [`insertContent`](module_engine_model_model-Model.md#function-insertContent), the block will be fully replaced by the inserted widget block.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-widget/src/utils.ts#L353)

#### Parameters

* `selection: ModelSelection | ModelDocumentSelection`

  The selection based on which the insertion position should be calculated.

* `model: Model`

  Model instance.

#### Returns

* `ModelRange`

  The optimal range.

<a id="function-getLabel">

### `getLabel( element ) → string`

Returns the label of the provided element.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-widget/src/utils.ts#L227)

#### Parameters

* `element: ViewElement`

#### Returns

* `string`

<a id="function-isWidget">

### `isWidget( node ) → boolean`

Returns `true` if given [`ViewNode`](module_engine_view_node-ViewNode.md) is an [`ViewElement`](module_engine_view_element-ViewElement.md) and a widget.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-widget/src/utils.ts#L54)

#### Parameters

* `node: ViewTypeCheckable`

#### Returns

* `boolean`

<a id="function-setHighlightHandling">

### `setHighlightHandling( element, writer, add, remove ) → void`

Sets highlight handling methods. Uses [`WidgetHighlightStack`](module_widget_highlightstack-WidgetHighlightStack.md) to properly determine which highlight descriptor should be used at given time.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-widget/src/utils.ts#L188)

#### Parameters

* `element: ViewElement`

* `writer: ViewDowncastWriter`

* `add: ( element: ViewElement, descriptor: DowncastHighlightDescriptor, writer: ViewDowncastWriter ) => void`

  Defaults to `addHighlight`

* `remove: ( element: ViewElement, descriptor: DowncastHighlightDescriptor, writer: ViewDowncastWriter ) => void`

  Defaults to `removeHighlight`

#### Returns

* `void`

<a id="function-setLabel">

### `setLabel( element, labelOrCreator ) → void`

Sets label for given element. It can be passed as a plain string or a function returning a string. Function will be called each time label is retrieved by [`getLabel()`](#function-getLabel).

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-widget/src/utils.ts#L218)

#### Parameters

* `element: ViewElement`
* `labelOrCreator: string | () => string`

#### Returns

* `void`

<a id="function-toWidget">

### `toWidget( element, writer, options = { options.hasSelectionHandle?, options.label? } ) → ViewElement`

Converts the given [`ViewElement`](module_engine_view_element-ViewElement.md) to a widget in the following way:

* sets the `contenteditable` attribute to `"false"`,
* adds the `ck-widget` CSS class,
* adds a custom [`getFillerOffset()`](module_engine_view_element-ViewElement.md#function-getFillerOffset) method returning `null`,
* adds a custom property allowing to recognize widget elements by using [`isWidget()`](#function-isWidget),
* implements the [view highlight on widgets](#function-setHighlightHandling).

This function needs to be used in conjunction with [downcast conversion helpers](module_engine_conversion_downcasthelpers-DowncastHelpers.md) like [`elementToElement()`](module_engine_conversion_downcasthelpers-DowncastHelpers.md#function-elementToElement). Moreover, typically you will want to use `toWidget()` only for `editingDowncast`, while keeping the `dataDowncast` clean.

For example, in order to convert a `<widget>` model element to `<div class="widget">` in the view, you can define such converters:

```typescript
editor.conversion.for( 'editingDowncast' )
	.elementToElement( {
		model: 'widget',
		view: ( modelItem, { writer } ) => {
			const div = writer.createContainerElement( 'div', { class: 'widget' } );

			return toWidget( div, writer, { label: 'some widget' } );
		}
	} );

editor.conversion.for( 'dataDowncast' )
	.elementToElement( {
		model: 'widget',
		view: ( modelItem, { writer } ) => {
			return writer.createContainerElement( 'div', { class: 'widget' } );
		}
	} );
```

See the full source code of the widget (with a nested editable) schema definition and converters in [this sample](https://github.com/ckeditor/ckeditor5-widget/blob/master/tests/manual/widget-with-nestededitable.js).

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-widget/src/utils.ts#L108)

#### Parameters

* `element: ViewElement`

* `writer: ViewDowncastWriter`

* `options: object`

  Additional options.

  Properties

  * `options.hasSelectionHandle?: boolean`

    If `true`, the widget will have a selection handle added.

  * `options.label?: string | () => string`

    Element's label provided to the [`setLabel`](#function-setLabel) function. It can be passed as a plain string or a function returning a string. It represents the widget for assistive technologies (like screen readers).

  Defaults to `{}`

#### Returns

* `ViewElement`

  Returns the same element.

<a id="function-toWidgetEditable">

### `toWidgetEditable( editable, writer, options = { options.label?, options.withAriaRole? } ) → ViewEditableElement`

Adds functionality to the provided [`ViewEditableElement`](module_engine_view_editableelement-ViewEditableElement.md) to act as a widget's editable:

* sets the `contenteditable` attribute to `true` when [`isReadOnly`](module_engine_view_editableelement-ViewEditableElement.md#member-isReadOnly) is `false`, otherwise sets it to `false`,
* adds the `ck-editor__editable` and `ck-editor__nested-editable` CSS classes,
* adds the `ck-editor__nested-editable_focused` CSS class when the editable is focused and removes it when it is blurred.
* implements the [view highlight on widget's editable](#function-setHighlightHandling).
* sets the `role` attribute to `textbox` for accessibility purposes.

Similarly to [`toWidget()`](#function-toWidget) this function should be used in `editingDowncast` only and it is usually used together with [`elementToElement()`](module_engine_conversion_downcasthelpers-DowncastHelpers.md#function-elementToElement).

For example, in order to convert a `<nested>` model element to `<div class="nested">` in the view, you can define such converters:

```typescript
editor.conversion.for( 'editingDowncast' )
	.elementToElement( {
		model: 'nested',
		view: ( modelItem, { writer } ) => {
			const div = writer.createEditableElement( 'div', { class: 'nested' } );

			return toWidgetEditable( nested, writer, { label: 'label for editable' } );
		}
	} );

editor.conversion.for( 'dataDowncast' )
	.elementToElement( {
		model: 'nested',
		view: ( modelItem, { writer } ) => {
			return writer.createContainerElement( 'div', { class: 'nested' } );
		}
	} );
```

See the full source code of the widget (with nested editable) schema definition and converters in [this sample](https://github.com/ckeditor/ckeditor5-widget/blob/master/tests/manual/widget-with-nestededitable.js).

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-widget/src/utils.ts#L284)

#### Parameters

* `editable: ViewEditableElement`

* `writer: ViewDowncastWriter`

* `options: object`

  Additional options.

  Properties

  * `options.label?: string`

    Editable's label used by assistive technologies (e.g. screen readers).

  * `options.withAriaRole?: boolean`

    Whether to add the role="textbox" attribute on the editable. Defaults to `true`.

  Defaults to `{}`

#### Returns

* `ViewEditableElement`

  Returns the same element that was provided in the `editable` parameter

<a id="function-viewToModelPositionOutsideModelElement">

### `viewToModelPositionOutsideModelElement( model, viewElementMatcher ) → GetCallback<MapperViewToModelPositionEvent>`

A util to be used in order to map view positions to correct model positions when implementing a widget which renders non-empty view element for an empty model element.

For example:

```
// Model:
<placeholder type="name"></placeholder>

// View:
<span class="placeholder">name</span>
```

In such case, view positions inside `<span>` cannot be correctly mapped to the model (because the model element is empty). To handle mapping positions inside `<span class="placeholder">` to the model use this util as follows:

```typescript
editor.editing.mapper.on(
	'viewToModelPosition',
	viewToModelPositionOutsideModelElement( model, viewElement => viewElement.hasClass( 'placeholder' ) )
);
```

The callback will try to map the view offset of selection to an expected model position.

1. When the position is at the end (or in the middle) of the inline widget:

```
// View:
<p>foo <span class="placeholder">name|</span> bar</p>

// Model:
<paragraph>foo <placeholder type="name"></placeholder>| bar</paragraph>
```

2. When the position is at the beginning of the inline widget:

```
// View:
<p>foo <span class="placeholder">|name</span> bar</p>

// Model:
<paragraph>foo |<placeholder type="name"></placeholder> bar</paragraph>
```

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-widget/src/utils.ts#L422)

#### Parameters

* `model: Model`

  Model instance on which the callback operates.

* `viewElementMatcher: ( element: ViewElement ) => boolean`

  Function that is passed a view element and should return `true` if the custom mapping should be applied to the given view element.

#### Returns

* `GetCallback<MapperViewToModelPositionEvent>`

---

Full index of the CKEditor 5 API reference: [llms.txt](llms.txt)
