@@ -409,7 +409,7 @@ export function remove() {
409409 * {@link module:engine/view/attributeelement~AttributeElement} created from provided descriptor.
410410 * See {link module:engine/conversion/model-to-view-converters~highlightDescriptorToAttributeElement}.
411411 *
412- * @param {module:engine/conversion/buildmodelconverter ~HighlightDescriptor|Function } highlightDescriptor
412+ * @param {module:engine/conversion/model-to-view-converters ~HighlightDescriptor|Function } highlightDescriptor
413413 * @return {Function }
414414 */
415415export function highlightText ( highlightDescriptor ) {
@@ -428,7 +428,11 @@ export function highlightText( highlightDescriptor ) {
428428 return ;
429429 }
430430
431- const viewElement = highlightDescriptorToAttributeElement ( descriptor ) ;
431+ if ( ! descriptor . id ) {
432+ descriptor . id = data . markerName ;
433+ }
434+
435+ const viewElement = createViewElementFromHighlightDescriptor ( descriptor ) ;
432436 const viewRange = conversionApi . mapper . toViewRange ( data . range ) ;
433437
434438 if ( evt . name . split ( ':' ) [ 0 ] == 'addMarker' ) {
@@ -442,16 +446,17 @@ export function highlightText( highlightDescriptor ) {
442446/**
443447 * Function factory, creates converter that converts all elements inside marker's range. Converter checks if element has
444448 * functions stored under `addHighlight` and `removeHighlight` custom properties and calls them passing
445- * {@link module:engine/conversion/buildmodelconverter ~HighlightDescriptor}. In such case converter will consume
449+ * {@link module:engine/conversion/model-to-view-converters ~HighlightDescriptor}. In such case converter will consume
446450 * all element's children, assuming that they were handled by element itself. If highlight descriptor will not provide
447- * priority, priority 10 will be used as default, to be compliant with
451+ * priority, priority `10` will be used as default, to be compliant with
448452 * {@link module:engine/conversion/model-to-view-converters~highlightText} method which uses default priority of
449453 * {@link module:engine/view/attributeelement~AttributeElement}.
450- * If highlight descriptor will not provide id property, name of the marker will be used.
454+ *
455+ * If highlight descriptor will not provide `id` property, name of the marker will be used.
451456 * When `addHighlight` and `removeHighlight` custom properties are not present, element is not converted
452457 * in any special way. This means that converters will proceed to convert element's child nodes.
453458 *
454- * @param {module:engine/conversion/buildmodelconverter ~HighlightDescriptor|Function } highlightDescriptor
459+ * @param {module:engine/conversion/model-to-view-converters ~HighlightDescriptor|Function } highlightDescriptor
455460 * @return {Function }
456461 */
457462export function highlightElement ( highlightDescriptor ) {
@@ -562,29 +567,6 @@ export function eventNameToConsumableType( evtName ) {
562567 return parts [ 0 ] + ':' + parts [ 1 ] ;
563568}
564569
565- /**
566- * Creates `span` {@link module:engine/view/attributeelement~AttributeElement view attribute element} from information
567- * provided by {@link module:engine/conversion/buildmodelconverter~HighlightDescriptor} object. If priority
568- * is not provided in descriptor - default priority will be used.
569- *
570- * @param {module:engine/conversion/buildmodelconverter~HighlightDescriptor } descriptor
571- * @return {module:engine/view/attributeelement~AttributeElement }
572- */
573- export function highlightDescriptorToAttributeElement ( descriptor ) {
574- const attributeElement = new ViewAttributeElement ( 'span' , descriptor . attributes ) ;
575-
576- if ( descriptor . class ) {
577- const cssClasses = Array . isArray ( descriptor . class ) ? descriptor . class : [ descriptor . class ] ;
578- attributeElement . addClass ( ...cssClasses ) ;
579- }
580-
581- if ( descriptor . priority ) {
582- attributeElement . priority = descriptor . priority ;
583- }
584-
585- return attributeElement ;
586- }
587-
588570// Helper function that shifts given view `position` in a way that returned position is after `howMany` characters compared
589571// to the original `position`.
590572// Because in view there might be view ui elements splitting text nodes, we cannot simply use `ViewPosition#getShiftedBy()`.
@@ -604,3 +586,79 @@ function _shiftViewPositionByCharacters( position, howMany ) {
604586 }
605587 }
606588}
589+
590+ /**
591+ * Creates `span` {@link module:engine/view/attributeelement~AttributeElement view attribute element} from information
592+ * provided by {@link module:engine/conversion/model-to-view-converters~HighlightDescriptor} object. If priority
593+ * is not provided in descriptor - default priority will be used.
594+ *
595+ * @param {module:engine/conversion/model-to-view-converters~HighlightDescriptor } descriptor
596+ * @return {module:engine/conversion/model-to-view-converters~HighlightAttributeElement }
597+ */
598+ export function createViewElementFromHighlightDescriptor ( descriptor ) {
599+ const viewElement = new HighlightAttributeElement ( 'span' , descriptor . attributes ) ;
600+
601+ if ( descriptor . class ) {
602+ const cssClasses = Array . isArray ( descriptor . class ) ? descriptor . class : [ descriptor . class ] ;
603+ viewElement . addClass ( ...cssClasses ) ;
604+ }
605+
606+ if ( descriptor . priority ) {
607+ viewElement . priority = descriptor . priority ;
608+ }
609+
610+ viewElement . setCustomProperty ( 'highlightDescriptorId' , descriptor . id ) ;
611+
612+ return viewElement ;
613+ }
614+
615+ /**
616+ * Special kind of {@link module:engine/view/attributeelement~AttributeElement} that is created and used in
617+ * marker-to-highlight conversion.
618+ *
619+ * The difference between `HighlightAttributeElement` and {@link module:engine/view/attributeelement~AttributeElement}
620+ * is {@link module:engine/view/attributeelement~AttributeElement#isSimilar} method.
621+ *
622+ * For `HighlightAttributeElement` it checks just `highlightDescriptorId` custom property, that is set during marker-to-highlight
623+ * conversion basing on {@link module:engine/conversion/model-to-view-converters~HighlightDescriptor} object.
624+ * `HighlightAttributeElement`s with same `highlightDescriptorId` property are considered similar.
625+ */
626+ class HighlightAttributeElement extends ViewAttributeElement {
627+ isSimilar ( otherElement ) {
628+ if ( otherElement . is ( 'attributeElement' ) ) {
629+ return this . getCustomProperty ( 'highlightDescriptorId' ) === otherElement . getCustomProperty ( 'highlightDescriptorId' ) ;
630+ }
631+
632+ return false ;
633+ }
634+ }
635+
636+ /**
637+ * Object describing how content highlight should be created in the view.
638+ *
639+ * Each text node contained in highlight will be wrapped with `span` element with CSS class(es), attributes and priority
640+ * described by this object.
641+ *
642+ * Each element can handle displaying highlight separately by providing `addHighlight` and `removeHighlight` custom
643+ * properties. Those properties are passed `HighlightDescriptor` object upon conversion and should use it to
644+ * change the element.
645+ *
646+ * @typedef {Object } module:engine/conversion/model-to-view-converters~HighlightDescriptor
647+ *
648+ * @property {String|Array.<String> } class CSS class or array of classes to set. If descriptor is used to
649+ * create {@link module:engine/view/attributeelement~AttributeElement} over text nodes, those classes will be set
650+ * on that {@link module:engine/view/attributeelement~AttributeElement}. If descriptor is applied to an element,
651+ * usually those class will be set on that element, however this depends on how the element converts the descriptor.
652+ *
653+ * @property {String } [id] Descriptor identifier. If not provided, defaults to converted marker's name.
654+ *
655+ * @property {Number } [priority] Descriptor priority. If not provided, defaults to `10`. If descriptor is used to create
656+ * {@link module:engine/view/attributeelement~AttributeElement}, it will be that element's
657+ * {@link module:engine/view/attributeelement~AttributeElement#priority}. If descriptor is applied to an element,
658+ * the priority will be used to determine which descriptor is more important.
659+ *
660+ * @property {Object } [attributes] Attributes to set. If descriptor is used to create
661+ * {@link module:engine/view/attributeelement~AttributeElement} over text nodes, those attributes will be set on that
662+ * {@link module:engine/view/attributeelement~AttributeElement}. If descriptor is applied to an element, usually those
663+ * attributes will be set on that element, however this depends on how the element converts the descriptor.
664+ */
0 commit comments