widget/utils
Constants
WIDGET_CLASS_NAME : 'ck-widget'module:widget/utils~WIDGET_CLASS_NAMECSS class added to each widget element.
WIDGET_SELECTED_CLASS_NAME : 'ck-widget_selected'module:widget/utils~WIDGET_SELECTED_CLASS_NAMECSS class added to currently selected widget element.
Functions
calculateResizeHostAncestorWidth( domResizeHost ) → numbermodule:widget/utils~calculateResizeHostAncestorWidthStarting 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.Copy codeParameters
domResizeHost : HTMLElementResize host DOM element that receives dimensions as a result of resizing.
Returns
numberWidth of ancestor element in pixels or 0 if no ancestor with a computed width has been found.
calculateResizeHostPercentageWidth( domResizeHost, resizeHostRect ) → numbermodule:widget/utils~calculateResizeHostPercentageWidthCalculates a relative width of a
domResizeHostcompared to its ancestor in percents.Parameters
domResizeHost : HTMLElementResize host DOM element.
resizeHostRect : RectDefaults to
...
Returns
numberPercentage value between 0 and 100.
findOptimalInsertionRange( selection, model ) → ModelRangemodule:widget/utils~findOptimalInsertionRangeReturns 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, the block will be fully replaced by the inserted widget block.Parameters
selection : ModelSelection | ModelDocumentSelectionThe selection based on which the insertion position should be calculated.
model : ModelModel instance.
Returns
ModelRangeThe optimal range.
getLabel( element ) → stringmodule:widget/utils~getLabelisWidget( node ) → booleanmodule:widget/utils~isWidgetReturns
trueif givenViewNodeis anViewElementand a widget.Parameters
node : ViewTypeCheckable
Returns
boolean
setHighlightHandling( element, writer, add, remove ) → voidmodule:widget/utils~setHighlightHandlingSets highlight handling methods. Uses
WidgetHighlightStackto properly determine which highlight descriptor should be used at given time.Parameters
element : ViewElementwriter : ViewDowncastWriteradd : ( element: ViewElement, descriptor: DowncastHighlightDescriptor, writer: ViewDowncastWriter ) => voidDefaults to
addHighlightremove : ( element: ViewElement, descriptor: DowncastHighlightDescriptor, writer: ViewDowncastWriter ) => voidDefaults to
removeHighlight
Returns
void
setLabel( element, labelOrCreator ) → voidmodule:widget/utils~setLabelSets 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().Parameters
element : ViewElementlabelOrCreator : string | () => string
Returns
void
toWidget( element, writer, options = { [options.hasSelectionHandle], [options.label] } ) → ViewElementmodule:widget/utils~toWidgetConverts the given
ViewElementto a widget in the following way:- sets the
contenteditableattribute to"false", - adds the
ck-widgetCSS class, - adds a custom
getFillerOffset()method returningnull, - adds a custom property allowing to recognize widget elements by using
isWidget(), - implements the view highlight on widgets.
This function needs to be used in conjunction with downcast conversion helpers like
elementToElement(). Moreover, typically you will want to usetoWidget()only foreditingDowncast, while keeping thedataDowncastclean.For example, in order to convert a
<widget>model element to<div class="widget">in the view, you can define such converters: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' } ); } } );Copy codeSee the full source code of the widget (with a nested editable) schema definition and converters in this sample.
Parameters
element : ViewElementwriter : ViewDowncastWriteroptions : objectAdditional options.
Properties[ options.hasSelectionHandle ] : booleanIf
true, the widget will have a selection handle added.[ options.label ] : string | () => stringElement's label provided to the
setLabelfunction. 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
ViewElementReturns the same element.
- sets the
toWidgetEditable( editable, writer, options = { [options.label], [options.withAriaRole] } ) → ViewEditableElementmodule:widget/utils~toWidgetEditableAdds functionality to the provided
ViewEditableElementto act as a widget's editable:- sets the
contenteditableattribute totruewhenisReadOnlyisfalse, otherwise sets it tofalse, - adds the
ck-editor__editableandck-editor__nested-editableCSS classes, - adds the
ck-editor__nested-editable_focusedCSS class when the editable is focused and removes it when it is blurred. - implements the view highlight on widget's editable.
- sets the
roleattribute totextboxfor accessibility purposes.
Similarly to
toWidget()this function should be used ineditingDowncastonly and it is usually used together withelementToElement().For example, in order to convert a
<nested>model element to<div class="nested">in the view, you can define such converters: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' } ); } } );Copy codeSee the full source code of the widget (with nested editable) schema definition and converters in this sample.
Parameters
editable : ViewEditableElementwriter : ViewDowncastWriteroptions : objectAdditional options.
Properties[ options.label ] : stringEditable's label used by assistive technologies (e.g. screen readers).
[ options.withAriaRole ] : booleanWhether to add the role="textbox" attribute on the editable. Defaults to
true.
Defaults to
{}
Returns
ViewEditableElementReturns the same element that was provided in the
editableparameter
- sets the
viewToModelPositionOutsideModelElement( model, viewElementMatcher ) → GetCallback<MapperViewToModelPositionEvent>module:widget/utils~viewToModelPositionOutsideModelElementA 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>Copy codeIn 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:editor.editing.mapper.on( 'viewToModelPosition', viewToModelPositionOutsideModelElement( model, viewElement => viewElement.hasClass( 'placeholder' ) ) );Copy codeThe callback will try to map the view offset of selection to an expected model position.
- 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>Copy code- 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>Copy codeParameters
model : ModelModel instance on which the callback operates.
viewElementMatcher : ( element: ViewElement ) => booleanFunction that is passed a view element and should return
trueif the custom mapping should be applied to the given view element.
Returns