@ckeditor/ckeditor5-engine
Advanced tools
Comparing version
{ | ||
"name": "@ckeditor/ckeditor5-engine", | ||
"version": "20.0.0", | ||
"version": "21.0.0", | ||
"description": "The editing engine of CKEditor 5 – the best browser-based rich text editor.", | ||
@@ -24,21 +24,21 @@ "keywords": [ | ||
"dependencies": { | ||
"@ckeditor/ckeditor5-utils": "^20.0.0", | ||
"@ckeditor/ckeditor5-utils": "^21.0.0", | ||
"lodash-es": "^4.17.15" | ||
}, | ||
"devDependencies": { | ||
"@ckeditor/ckeditor5-basic-styles": "^20.0.0", | ||
"@ckeditor/ckeditor5-block-quote": "^20.0.0", | ||
"@ckeditor/ckeditor5-core": "^20.0.0", | ||
"@ckeditor/ckeditor5-editor-classic": "^20.0.0", | ||
"@ckeditor/ckeditor5-enter": "^20.0.0", | ||
"@ckeditor/ckeditor5-essentials": "^20.0.0", | ||
"@ckeditor/ckeditor5-heading": "^20.0.0", | ||
"@ckeditor/ckeditor5-link": "^20.0.0", | ||
"@ckeditor/ckeditor5-list": "^20.0.0", | ||
"@ckeditor/ckeditor5-paragraph": "^20.0.0", | ||
"@ckeditor/ckeditor5-table": "^20.0.0", | ||
"@ckeditor/ckeditor5-theme-lark": "^20.0.0", | ||
"@ckeditor/ckeditor5-typing": "^20.0.0", | ||
"@ckeditor/ckeditor5-undo": "^20.0.0", | ||
"@ckeditor/ckeditor5-widget": "^20.0.0" | ||
"@ckeditor/ckeditor5-basic-styles": "^21.0.0", | ||
"@ckeditor/ckeditor5-block-quote": "^21.0.0", | ||
"@ckeditor/ckeditor5-core": "^21.0.0", | ||
"@ckeditor/ckeditor5-editor-classic": "^21.0.0", | ||
"@ckeditor/ckeditor5-enter": "^21.0.0", | ||
"@ckeditor/ckeditor5-essentials": "^21.0.0", | ||
"@ckeditor/ckeditor5-heading": "^21.0.0", | ||
"@ckeditor/ckeditor5-link": "^21.0.0", | ||
"@ckeditor/ckeditor5-list": "^21.0.0", | ||
"@ckeditor/ckeditor5-paragraph": "^21.0.0", | ||
"@ckeditor/ckeditor5-table": "^21.0.0", | ||
"@ckeditor/ckeditor5-theme-lark": "^21.0.0", | ||
"@ckeditor/ckeditor5-typing": "^21.0.0", | ||
"@ckeditor/ckeditor5-undo": "^21.0.0", | ||
"@ckeditor/ckeditor5-widget": "^21.0.0" | ||
}, | ||
@@ -45,0 +45,0 @@ "engines": { |
@@ -93,3 +93,4 @@ /** | ||
this.downcastDispatcher = new DowncastDispatcher( { | ||
mapper: this.mapper | ||
mapper: this.mapper, | ||
schema: model.schema | ||
} ); | ||
@@ -136,2 +137,3 @@ this.downcastDispatcher.on( 'insert:$text', insertText(), { priority: 'lowest' } ); | ||
this.decorate( 'init' ); | ||
this.decorate( 'set' ); | ||
@@ -321,2 +323,3 @@ // Fire `ready` event when initialisation has completed. Such low level listener gives possibility | ||
* | ||
* @fires set | ||
* @param {String|Object.<String,String>} data Input data as a string or an object containing `rootName` - `data` | ||
@@ -457,2 +460,11 @@ * pairs to set data on multiple roots at once. | ||
*/ | ||
/** | ||
* Event fired after {@link #set set() method} has been run. | ||
* | ||
* The `set` event is fired by decorated {@link #set} method. | ||
* See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples. | ||
* | ||
* @event set | ||
*/ | ||
} | ||
@@ -459,0 +471,0 @@ |
@@ -68,3 +68,4 @@ /** | ||
this.downcastDispatcher = new DowncastDispatcher( { | ||
mapper: this.mapper | ||
mapper: this.mapper, | ||
schema: model.schema | ||
} ); | ||
@@ -71,0 +72,0 @@ |
@@ -340,3 +340,3 @@ /** | ||
* | ||
* if ( viewElement.is( 'span' ) && fontWeight && /\d+/.test() && Number( fontWeight ) > 500 ) { | ||
* if ( viewElement.is( 'element', 'span' ) && fontWeight && /\d+/.test() && Number( fontWeight ) > 500 ) { | ||
* // Returned value can be an object with the matched properties. | ||
@@ -392,3 +392,3 @@ * // These properties will be "consumed" during the conversion. | ||
* | ||
* if ( viewElement.is( 'span' ) && size > 10 ) { | ||
* if ( viewElement.is( 'element', 'span' ) && size > 10 ) { | ||
* // Returned value can be an object with the matched properties. | ||
@@ -418,3 +418,3 @@ * // These properties will be "consumed" during the conversion. | ||
* | ||
* if ( viewElement.is( 'span' ) && size < 10 ) { | ||
* if ( viewElement.is( 'element', 'span' ) && size < 10 ) { | ||
* // Returned value can be an object with the matched properties. | ||
@@ -421,0 +421,0 @@ * // These properties will be "consumed" during the conversion. |
@@ -662,2 +662,8 @@ /** | ||
/** | ||
* The {@link module:engine/model/schema~Schema} instance set for the model that is downcast. | ||
* | ||
* @member {module:engine/model/schema~Schema} #schema | ||
*/ | ||
/** | ||
* The {@link module:engine/view/downcastwriter~DowncastWriter} instance used to manipulate data during conversion. | ||
@@ -664,0 +670,0 @@ * |
@@ -107,3 +107,3 @@ /** | ||
data.viewPosition = this._findPositionIn( viewContainer, data.modelPosition.offset ); | ||
data.viewPosition = this.findPositionIn( viewContainer, data.modelPosition.offset ); | ||
}, { priority: 'low' } ); | ||
@@ -449,3 +449,3 @@ | ||
// If the position is a text it is simple ("ba|r" -> 2). | ||
if ( viewParent.is( 'text' ) ) { | ||
if ( viewParent.is( '$text' ) ) { | ||
return viewOffset; | ||
@@ -493,3 +493,3 @@ } | ||
return 1; | ||
} else if ( viewNode.is( 'text' ) ) { | ||
} else if ( viewNode.is( '$text' ) ) { | ||
return viewNode.data.length; | ||
@@ -516,3 +516,3 @@ } else if ( viewNode.is( 'uiElement' ) ) { | ||
* | ||
* _findPositionIn( p, 4 ): | ||
* findPositionIn( p, 4 ): | ||
* <p>|fo<b>bar</b>bom</p> -> expected offset: 4, actual offset: 0 | ||
@@ -522,11 +522,10 @@ * <p>fo|<b>bar</b>bom</p> -> expected offset: 4, actual offset: 2 | ||
* | ||
* _findPositionIn( b, 4 - ( 5 - 3 ) ): | ||
* findPositionIn( b, 4 - ( 5 - 3 ) ): | ||
* <p>fo<b>|bar</b>bom</p> -> expected offset: 2, actual offset: 0 | ||
* <p>fo<b>bar|</b>bom</p> -> expected offset: 2, actual offset: 3 -> we are too far | ||
* | ||
* _findPositionIn( bar, 2 - ( 3 - 3 ) ): | ||
* findPositionIn( bar, 2 - ( 3 - 3 ) ): | ||
* We are in the text node so we can simple find the offset. | ||
* <p>fo<b>ba|r</b>bom</p> -> expected offset: 2, actual offset: 2 -> position found | ||
* | ||
* @private | ||
* @param {module:engine/view/element~Element} viewParent Tree view element in which we are looking for the position. | ||
@@ -536,3 +535,3 @@ * @param {Number} expectedOffset Expected offset. | ||
*/ | ||
_findPositionIn( viewParent, expectedOffset ) { | ||
findPositionIn( viewParent, expectedOffset ) { | ||
// Last scanned view node. | ||
@@ -547,3 +546,3 @@ let viewNode; | ||
// In the text node it is simple: offset in the model equals offset in the text. | ||
if ( viewParent.is( 'text' ) ) { | ||
if ( viewParent.is( '$text' ) ) { | ||
return new ViewPosition( viewParent, expectedOffset ); | ||
@@ -570,3 +569,3 @@ } | ||
// so we subtract it from the expected offset to fine the offset in the child. | ||
return this._findPositionIn( viewNode, expectedOffset - ( modelOffset - lastLength ) ); | ||
return this.findPositionIn( viewNode, expectedOffset - ( modelOffset - lastLength ) ); | ||
} | ||
@@ -643,3 +642,3 @@ } | ||
* // Check if this is the element we are interested in. | ||
* if ( !sibling.is( 'customElement' ) ) { | ||
* if ( !sibling.is( 'element', 'customElement' ) ) { | ||
* return; | ||
@@ -646,0 +645,0 @@ * } |
@@ -240,3 +240,3 @@ /** | ||
this.fire( 'element:' + viewItem.name, data, this.conversionApi ); | ||
} else if ( viewItem.is( 'text' ) ) { | ||
} else if ( viewItem.is( '$text' ) ) { | ||
this.fire( 'text', data, this.conversionApi ); | ||
@@ -243,0 +243,0 @@ } else { |
@@ -12,3 +12,8 @@ /** | ||
import ModelSelection from '../model/selection'; | ||
import { attachLinkToDocumentation } from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; | ||
import priorities from '@ckeditor/ckeditor5-utils/src/priorities'; | ||
/* global console */ | ||
/** | ||
@@ -291,2 +296,4 @@ * Contains {@link module:engine/view/view view} to {@link module:engine/model/model model} converters for | ||
* | ||
* **Note**: This method was deprecated. Please use {@link #dataToMarker} instead. | ||
* | ||
* This conversion results in creating a model marker. For example, if the marker was stored in a view as an element: | ||
@@ -326,2 +333,3 @@ * `<p>Fo<span data-marker="comment" data-comment-id="7"></span>o</p><p>B<span data-marker="comment" data-comment-id="7"></span>ar</p>`, | ||
* | ||
* @deprecated | ||
* @method #elementToMarker | ||
@@ -336,4 +344,89 @@ * @param {Object} config Conversion configuration. | ||
elementToMarker( config ) { | ||
/** | ||
* The {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToMarker `UpcastHelpers#elementToMarker()`} | ||
* method has been deprecated and will be removed in the near future. | ||
* Please use {@link module:engine/conversion/upcasthelpers~UpcastHelpers#dataToMarker `UpcastHelpers#dataToMarker()`} instead. | ||
* | ||
* @error upcast-helpers-element-to-marker-deprecated | ||
*/ | ||
console.warn( | ||
attachLinkToDocumentation( | ||
'upcast-helpers-element-to-marker-deprecated: ' + | ||
'The UpcastHelpers#elementToMarker() method has been deprecated and will be removed in the near future. ' + | ||
'Please use UpcastHelpers#dataToMarker() instead.' | ||
) | ||
); | ||
return this.add( upcastElementToMarker( config ) ); | ||
} | ||
/** | ||
* View to model marker conversion helper. | ||
* | ||
* Converts view data created by {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToData `#markerToData()`} | ||
* back to a model marker. | ||
* | ||
* This converter looks for specific view elements and view attributes that mark marker boundaries. See | ||
* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToData `#markerToData()`} to learn what view data | ||
* is expected by this converter. | ||
* | ||
* The `config.view` property is equal to the marker group name to convert. | ||
* | ||
* By default, this converter creates markers with `group:name` name convention (to match the default `markerToData` conversion). | ||
* | ||
* The conversion configuration can take a function that will generate a marker name. | ||
* If such function is set as the `config.model` parameter, it is passed the `name` part from the view element or attribute and it is | ||
* expected to return a string with the marker name. | ||
* | ||
* Basic usage: | ||
* | ||
* // Using the default conversion. | ||
* // In this case, all markers from `comment` group will be converted. | ||
* // The conversion will look for `<comment-start>` and `<comment-end>` tags and | ||
* // `data-comment-start-before`, `data-comment-start-after`, | ||
* // `data-comment-end-before` and `data-comment-end-after` attributes. | ||
* editor.conversion.for( 'upcast' ).dataToMarker( { | ||
* view: 'comment' | ||
* } ); | ||
* | ||
* An example of a model that may be generated by this conversion: | ||
* | ||
* // View: | ||
* <p>Foo<comment-start name="commentId:uid"></comment-start>bar</p> | ||
* <figure data-comment-end-after="commentId:uid" class="image"><img src="abc.jpg" /></figure> | ||
* | ||
* // Model: | ||
* <paragraph>Foo[bar</paragraph> | ||
* <image src="abc.jpg"></image>] | ||
* | ||
* Where `[]` are boundaries of a marker that will receive `comment:commentId:uid` name. | ||
* | ||
* Other examples of usage: | ||
* | ||
* // Using custom function which is the same as the default conversion: | ||
* editor.conversion.for( 'upcast' ).dataToMarker( { | ||
* view: 'comment', | ||
* model: name => 'comment:' + name, | ||
* } ); | ||
* | ||
* // Using converter priority: | ||
* editor.conversion.for( 'upcast' ).dataToMarker( { | ||
* view: 'comment', | ||
* model: name => 'comment:' + name, | ||
* converterPriority: 'high' | ||
* } ); | ||
* | ||
* See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter | ||
* to the conversion process. | ||
* | ||
* @method #dataToMarker | ||
* @param {Object} config Conversion configuration. | ||
* @param {String} config.view Marker group name to convert. | ||
* @param {Function} [config.model] Function that takes `name` part from the view element or attribute and returns the marker name. | ||
* @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] Converter priority. | ||
* @returns {module:engine/conversion/upcasthelpers~UpcastHelpers} | ||
*/ | ||
dataToMarker( config ) { | ||
return this.add( upcastDataToMarker( config ) ); | ||
} | ||
} | ||
@@ -519,3 +612,3 @@ | ||
normalizeToMarkerConfig( config ); | ||
normalizeElementToMarkerConfig( config ); | ||
@@ -525,2 +618,105 @@ return upcastElementToElement( config ); | ||
// View data to model marker conversion helper. | ||
// | ||
// See {@link ~UpcastHelpers#dataToMarker} to learn more. | ||
// | ||
// @param {Object} config | ||
// @param {String} config.view | ||
// @param {Function} [config.model] | ||
// @param {module:utils/priorities~PriorityString} [config.converterPriority='normal'] | ||
// @returns {Function} Conversion helper. | ||
function upcastDataToMarker( config ) { | ||
config = cloneDeep( config ); | ||
// Default conversion. | ||
if ( !config.model ) { | ||
config.model = name => { | ||
return name ? config.view + ':' + name : config.view; | ||
}; | ||
} | ||
const converterStart = prepareToElementConverter( normalizeDataToMarkerConfig( config, 'start' ) ); | ||
const converterEnd = prepareToElementConverter( normalizeDataToMarkerConfig( config, 'end' ) ); | ||
return dispatcher => { | ||
dispatcher.on( 'element:' + config.view + '-start', converterStart, { priority: config.converterPriority || 'normal' } ); | ||
dispatcher.on( 'element:' + config.view + '-end', converterEnd, { priority: config.converterPriority || 'normal' } ); | ||
// Below is a hack that is needed to properly handle `converterPriority` for both elements and attributes. | ||
// Attribute conversion needs to be performed *after* element conversion. | ||
// This converter handles both element conversion and attribute conversion, which means that if a single | ||
// `config.converterPriority` is used, it will lead to problems. For example, if `'high'` priority is used, | ||
// then attribute conversion will be performed before a lot of element upcast converters. | ||
// On the other hand we want to support `config.converterPriority` and overwriting conveters. | ||
// | ||
// To have it work, we need to do some extra processing for priority for attribute converter. | ||
// Priority `'low'` value should be the base value and then we will change it depending on `config.converterPriority` value. | ||
// | ||
// This hack probably would not be needed if attributes are upcasted separately. | ||
// | ||
const basePriority = priorities.get( 'low' ); | ||
const maxPriority = priorities.get( 'highest' ); | ||
const priorityFactor = priorities.get( config.converterPriority ) / maxPriority; // Number in range [ -1, 1 ]. | ||
dispatcher.on( 'element', upcastAttributeToMarker( config ), { priority: basePriority + priorityFactor } ); | ||
}; | ||
} | ||
// Function factory, returns a callback function which converts view attributes to a model marker. | ||
// | ||
// The converter looks for elements with `data-group-start-before`, `data-group-start-after`, `data-group-end-before` | ||
// and `data-group-end-after` attributes and inserts `$marker` model elements before/after those elements. | ||
// `group` part is specified in `config.view`. | ||
// | ||
// @param {Object} config | ||
// @param {String} config.view | ||
// @param {Function} [config.model] | ||
// @returns {Function} Marker converter. | ||
function upcastAttributeToMarker( config ) { | ||
return ( evt, data, conversionApi ) => { | ||
const attrName = `data-${ config.view }`; | ||
// This converter wants to add a model element, marking a marker, before/after an element (or maybe even group of elements). | ||
// To do that, we can use `data.modelRange` which is set on an element (or a group of elements) that has been upcasted. | ||
// But, if the processed view element has not been upcasted yet (it does not have been converted), we need to | ||
// fire conversion for its children first, then we will have `data.modelRange` available. | ||
if ( !data.modelRange ) { | ||
data = Object.assign( data, conversionApi.convertChildren( data.viewItem, data.modelCursor ) ); | ||
} | ||
if ( conversionApi.consumable.consume( data.viewItem, { attributes: attrName + '-end-after' } ) ) { | ||
addMarkerElements( data.modelRange.end, data.viewItem.getAttribute( attrName + '-end-after' ).split( ',' ) ); | ||
} | ||
if ( conversionApi.consumable.consume( data.viewItem, { attributes: attrName + '-start-after' } ) ) { | ||
addMarkerElements( data.modelRange.end, data.viewItem.getAttribute( attrName + '-start-after' ).split( ',' ) ); | ||
} | ||
if ( conversionApi.consumable.consume( data.viewItem, { attributes: attrName + '-end-before' } ) ) { | ||
addMarkerElements( data.modelRange.start, data.viewItem.getAttribute( attrName + '-end-before' ).split( ',' ) ); | ||
} | ||
if ( conversionApi.consumable.consume( data.viewItem, { attributes: attrName + '-start-before' } ) ) { | ||
addMarkerElements( data.modelRange.start, data.viewItem.getAttribute( attrName + '-start-before' ).split( ',' ) ); | ||
} | ||
function addMarkerElements( position, markerViewNames ) { | ||
for ( const markerViewName of markerViewNames ) { | ||
const markerName = config.model( markerViewName ); | ||
const element = conversionApi.writer.createElement( '$marker', { 'data-name': markerName } ); | ||
conversionApi.writer.insert( element, position ); | ||
if ( data.modelCursor.isEqual( position ) ) { | ||
data.modelCursor = data.modelCursor.getShiftedBy( 1 ); | ||
} else { | ||
data.modelCursor = data.modelCursor._getTransformedByInsertion( position, 1 ); | ||
} | ||
data.modelRange = data.modelRange._getTransformedByInsertion( position, 1 )[ 0 ]; | ||
} | ||
} | ||
}; | ||
} | ||
// Helper function for from-view-element conversion. Checks if `config.view` directly specifies converted view element's name | ||
@@ -788,6 +984,6 @@ // and if so, returns it. | ||
// Helper function for upcasting-to-marker conversion. Takes the config in a format requested by `upcastElementToMarker()` | ||
// function and converts it to a format that is supported by `_upcastElementToElement()` function. | ||
// function and converts it to a format that is supported by `upcastElementToElement()` function. | ||
// | ||
// @param {Object} config Conversion configuration. | ||
function normalizeToMarkerConfig( config ) { | ||
function normalizeElementToMarkerConfig( config ) { | ||
const oldModel = config.model; | ||
@@ -801,1 +997,21 @@ | ||
} | ||
// Helper function for upcasting-to-marker conversion. Takes the config in a format requested by `upcastDataToMarker()` | ||
// function and converts it to a format that is supported by `upcastElementToElement()` function. | ||
// | ||
// @param {Object} config Conversion configuration. | ||
function normalizeDataToMarkerConfig( config, type ) { | ||
const configForElements = {}; | ||
// Upcast <markerGroup-start> and <markerGroup-end> elements. | ||
configForElements.view = config.view + '-' + type; | ||
configForElements.model = ( viewElement, modelWriter ) => { | ||
const viewName = viewElement.getAttribute( 'name' ); | ||
const markerName = config.model( viewName ); | ||
return modelWriter.createElement( '$marker', { 'data-name': markerName } ); | ||
}; | ||
return configForElements; | ||
} |
@@ -83,3 +83,3 @@ /** | ||
// For text nodes and document fragments just mark them as consumable. | ||
if ( element.is( 'text' ) || element.is( 'documentFragment' ) ) { | ||
if ( element.is( '$text' ) || element.is( 'documentFragment' ) ) { | ||
this._consumables.set( element, true ); | ||
@@ -138,3 +138,3 @@ | ||
// For text nodes and document fragments return stored boolean value. | ||
if ( element.is( 'text' ) || element.is( 'documentFragment' ) ) { | ||
if ( element.is( '$text' ) || element.is( 'documentFragment' ) ) { | ||
return elementConsumables; | ||
@@ -177,3 +177,3 @@ } | ||
if ( this.test( element, consumables ) ) { | ||
if ( element.is( 'text' ) || element.is( 'documentFragment' ) ) { | ||
if ( element.is( '$text' ) || element.is( 'documentFragment' ) ) { | ||
// For text nodes and document fragments set value to false. | ||
@@ -224,3 +224,3 @@ this._consumables.set( element, false ); | ||
if ( elementConsumables !== undefined ) { | ||
if ( element.is( 'text' ) || element.is( 'documentFragment' ) ) { | ||
if ( element.is( '$text' ) || element.is( 'documentFragment' ) ) { | ||
// For text nodes and document fragments - set consumable to true. | ||
@@ -294,3 +294,3 @@ this._consumables.set( element, true ); | ||
if ( from.is( 'text' ) ) { | ||
if ( from.is( '$text' ) ) { | ||
instance.add( from ); | ||
@@ -297,0 +297,0 @@ |
@@ -231,3 +231,3 @@ /** | ||
downcastDispatcher.on( 'attribute', ( evt, data, conversionApi ) => { | ||
if ( data.item instanceof ModelSelection || data.item instanceof DocumentSelection || data.item.is( 'textProxy' ) ) { | ||
if ( data.item instanceof ModelSelection || data.item instanceof DocumentSelection || data.item.is( '$textProxy' ) ) { | ||
const converter = wrap( ( modelAttributeValue, viewWriter ) => { | ||
@@ -234,0 +234,0 @@ return viewWriter.createAttributeElement( |
@@ -28,2 +28,3 @@ /** | ||
import UIElement from '../view/uielement'; | ||
import RawElement from '../view/rawelement'; | ||
import { StylesProcessor } from '../view/stylesmap'; | ||
@@ -39,3 +40,4 @@ | ||
'empty': EmptyElement, | ||
'ui': UIElement | ||
'ui': UIElement, | ||
'raw': RawElement | ||
}; | ||
@@ -60,2 +62,4 @@ | ||
* {@link module:engine/view/uielement~UIElement} will be printed. | ||
* @param {Boolean} [options.renderRawElements=false] When set to `true`, the inner content of each | ||
* {@link module:engine/view/rawelement~RawElement} will be printed. | ||
* @returns {String} The stringified data. | ||
@@ -76,2 +80,3 @@ */ | ||
renderUIElements: options.renderUIElements, | ||
renderRawElements: options.renderRawElements, | ||
ignoreRoot: true | ||
@@ -241,2 +246,4 @@ }; | ||
* {@link module:engine/view/uielement~UIElement} will be printed. | ||
* @param {Boolean} [options.renderRawElements=false] When set to `true`, the inner content of each | ||
* {@link module:engine/view/rawelement~RawElement} will be printed. | ||
* @returns {String} An HTML-like string representing the view. | ||
@@ -460,3 +467,3 @@ */ | ||
if ( node.is( 'text' ) ) { | ||
if ( node.is( '$text' ) ) { | ||
const regexp = new RegExp( | ||
@@ -631,2 +638,4 @@ `[${ TEXT_RANGE_START_TOKEN }${ TEXT_RANGE_END_TOKEN }\\${ ELEMENT_RANGE_END_TOKEN }\\${ ELEMENT_RANGE_START_TOKEN }]`, | ||
* {@link module:engine/view/uielement~UIElement} will be printed. | ||
* @param {Boolean} [options.renderRawElements=false] When set to `true`, the inner content of each | ||
* {@link module:engine/view/rawelement~RawElement} will be printed. | ||
*/ | ||
@@ -648,2 +657,3 @@ constructor( root, selection, options ) { | ||
this.renderUIElements = !!options.renderUIElements; | ||
this.renderRawElements = !!options.renderRawElements; | ||
} | ||
@@ -681,4 +691,11 @@ | ||
if ( this.renderUIElements && root.is( 'uiElement' ) ) { | ||
if ( ( this.renderUIElements && root.is( 'uiElement' ) ) ) { | ||
callback( root.render( document ).innerHTML ); | ||
} else if ( this.renderRawElements && root.is( 'rawElement' ) ) { | ||
// There's no DOM element for "root" to pass to render(). Creating | ||
// a surrogate container to render the children instead. | ||
const rawContentContainer = document.createElement( 'div' ); | ||
root.render( rawContentContainer ); | ||
callback( rawContentContainer.innerHTML ); | ||
} else { | ||
@@ -700,3 +717,3 @@ let offset = 0; | ||
if ( root.is( 'text' ) ) { | ||
if ( root.is( '$text' ) ) { | ||
callback( this._stringifyTextRanges( root ) ); | ||
@@ -837,4 +854,5 @@ } | ||
* * 'container' for {@link module:engine/view/containerelement~ContainerElement container elements}, | ||
* * 'empty' for {@link module:engine/view/emptyelement~EmptyElement empty elements}. | ||
* * 'ui' for {@link module:engine/view/uielement~UIElement UI elements}. | ||
* * 'empty' for {@link module:engine/view/emptyelement~EmptyElement empty elements}, | ||
* * 'ui' for {@link module:engine/view/uielement~UIElement UI elements}, | ||
* * 'raw' for {@link module:engine/view/rawelement~RawElement raw elements}, | ||
* * an empty string when the current configuration is preventing showing elements' types. | ||
@@ -957,6 +975,6 @@ * | ||
throw new Error( 'Parse error - cannot parse inside EmptyElement.' ); | ||
} | ||
if ( convertedElement.is( 'uiElement' ) ) { | ||
} else if ( convertedElement.is( 'uiElement' ) ) { | ||
throw new Error( 'Parse error - cannot parse inside UIElement.' ); | ||
} else if ( convertedElement.is( 'rawElement' ) ) { | ||
throw new Error( 'Parse error - cannot parse inside RawElement.' ); | ||
} | ||
@@ -963,0 +981,0 @@ |
@@ -1042,3 +1042,3 @@ /** | ||
for ( const child of children ) { | ||
if ( child.is( 'text' ) ) { | ||
if ( child.is( '$text' ) ) { | ||
for ( let i = 0; i < child.data.length; i++ ) { | ||
@@ -1045,0 +1045,0 @@ snapshot.push( { |
@@ -338,3 +338,3 @@ /** | ||
// @if CK_DEBUG_ENGINE // if ( child.is( 'text' ) ) { | ||
// @if CK_DEBUG_ENGINE // if ( child.is( '$text' ) ) { | ||
// @if CK_DEBUG_ENGINE // const textAttrs = stringifyMap( child._attrs ); | ||
@@ -341,0 +341,0 @@ |
@@ -570,3 +570,2 @@ /** | ||
// | ||
class LiveSelection extends Selection { | ||
@@ -606,6 +605,6 @@ // Creates an empty live selection for given {@link module:engine/model/document~Document}. | ||
// Contains data required to fix ranges which have been moved to the graveyard. | ||
// Position to which the selection should be set if the last selection range was moved to the graveyard. | ||
// @private | ||
// @member {Array} module:engine/model/liveselection~LiveSelection#_fixGraveyardRangesData | ||
this._fixGraveyardRangesData = []; | ||
// @member {module:engine/model/position~Position} module:engine/model/liveselection~LiveSelection#_selectionRestorePosition | ||
this._selectionRestorePosition = null; | ||
@@ -633,8 +632,10 @@ // Flag that informs whether the selection ranges have changed. It is changed on true when `LiveRange#change:range` event is fired. | ||
while ( this._fixGraveyardRangesData.length ) { | ||
const { liveRange, sourcePosition } = this._fixGraveyardRangesData.shift(); | ||
this._fixGraveyardSelection( liveRange, sourcePosition ); | ||
// Fix selection if the last range was removed from it and we have a position to which we can restore the selection. | ||
if ( this._ranges.length == 0 && this._selectionRestorePosition ) { | ||
this._fixGraveyardSelection( this._selectionRestorePosition ); | ||
} | ||
// "Forget" the restore position even if it was not "used". | ||
this._selectionRestorePosition = null; | ||
if ( this._hasChangedRange ) { | ||
@@ -833,11 +834,13 @@ this._hasChangedRange = false; | ||
// If selection range is moved to the graveyard remove it from the selection object. | ||
// Also, save some data that can be used to restore selection later, on `Model#applyOperation` event. | ||
liveRange.on( 'change:range', ( evt, oldRange, data ) => { | ||
this._hasChangedRange = true; | ||
// If `LiveRange` is in whole moved to the graveyard, save necessary data. It will be fixed on `Model#applyOperation` event. | ||
if ( liveRange.root == this._document.graveyard ) { | ||
this._fixGraveyardRangesData.push( { | ||
liveRange, | ||
sourcePosition: data.deletionPosition | ||
} ); | ||
this._selectionRestorePosition = data.deletionPosition; | ||
const index = this._ranges.indexOf( liveRange ); | ||
this._ranges.splice( index, 1 ); | ||
liveRange.detach(); | ||
} | ||
@@ -1124,32 +1127,16 @@ } ); | ||
// Fixes a selection range after it ends up in graveyard root. | ||
// Fixes the selection after all its ranges got removed. | ||
// | ||
// @private | ||
// @param {module:engine/model/liverange~LiveRange} liveRange The range from selection, that ended up in the graveyard root. | ||
// @param {module:engine/model/position~Position} removedRangeStart Start position of a range which was removed. | ||
_fixGraveyardSelection( liveRange, removedRangeStart ) { | ||
// The start of the removed range is the closest position to the `liveRange` - the original selection range. | ||
// This is a good candidate for a fixed selection range. | ||
const positionCandidate = removedRangeStart.clone(); | ||
// @param {module:engine/model/position~Position} deletionPosition Position where the deletion happened. | ||
_fixGraveyardSelection( deletionPosition ) { | ||
// Find a range that is a correct selection range and is closest to the position where the deletion happened. | ||
const selectionRange = this._model.schema.getNearestSelectionRange( deletionPosition ); | ||
// Find a range that is a correct selection range and is closest to the start of removed range. | ||
const selectionRange = this._model.schema.getNearestSelectionRange( positionCandidate ); | ||
// Remove the old selection range before preparing and adding new selection range. This order is important, | ||
// because new range, in some cases, may intersect with old range (it depends on `getNearestSelectionRange()` result). | ||
const index = this._ranges.indexOf( liveRange ); | ||
this._ranges.splice( index, 1 ); | ||
liveRange.detach(); | ||
// If nearest valid selection range has been found - add it in the place of old range. | ||
// If range is equal to any other selection ranges then it is probably due to contents | ||
// of a multi-range selection being removed. See ckeditor/ckeditor5#6501. | ||
if ( selectionRange && !isRangeCollidingWithSelection( selectionRange, this ) ) { | ||
if ( selectionRange ) { | ||
// Check the range, convert it to live range, bind events, etc. | ||
const newRange = this._prepareRange( selectionRange ); | ||
// Add new range in the place of old range. | ||
this._ranges.splice( index, 0, newRange ); | ||
this._pushRange( selectionRange ); | ||
} | ||
// If nearest valid selection range cannot be found or is intersecting with other selection ranges removing the old range is fine. | ||
// If nearest valid selection range cannot be found don't add any range. Selection will be set to the default range. | ||
} | ||
@@ -1199,6 +1186,1 @@ } | ||
} | ||
// Checks if range collides with any of selection ranges. | ||
function isRangeCollidingWithSelection( range, selection ) { | ||
return !selection._ranges.every( selectionRange => !range.isEqual( selectionRange ) ); | ||
} |
@@ -107,10 +107,9 @@ /** | ||
* | ||
* element.is( 'image' ); // -> true if this is an <image> element | ||
* element.is( 'element', 'image' ); // -> true if this is an <image> element | ||
* element.is( 'element', 'image' ); // -> same as above | ||
* text.is( 'image' ); -> false | ||
* text.is( 'element', 'image' ); -> false | ||
* | ||
* {@link module:engine/model/node~Node#is Check the entire list of model objects} which implement the `is()` method. | ||
* | ||
* @param {String} type Type to check when `name` parameter is present. | ||
* Otherwise, it acts like the `name` parameter. | ||
* @param {String} type Type to check. | ||
* @param {String} [name] Element name. | ||
@@ -122,3 +121,2 @@ * @returns {Boolean} | ||
return type === 'element' || type === 'model:element' || | ||
type === this.name || type === 'model:' + this.name || | ||
// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529. | ||
@@ -215,2 +213,24 @@ type === 'node' || type === 'model:node'; | ||
/** | ||
* Returns the parent element of the given name. Returns null if the element is not inside the desired parent. | ||
* | ||
* @param {String} parentName The name of the parent element to find. | ||
* @param {Object} [options] Options object. | ||
* @param {Boolean} [options.includeSelf=false] When set to `true` this node will be also included while searching. | ||
* @returns {module:engine/model/element~Element|null} | ||
*/ | ||
findAncestor( parentName, options = { includeSelf: false } ) { | ||
let parent = options.includeSelf ? this : this.parent; | ||
while ( parent ) { | ||
if ( parent.name === parentName ) { | ||
return parent; | ||
} | ||
parent = parent.parent; | ||
} | ||
return null; | ||
} | ||
/** | ||
* Converts `Element` instance to plain object and returns it. Takes care of converting all of this element's children. | ||
@@ -365,3 +385,3 @@ * | ||
// @if CK_DEBUG_ENGINE // if ( child.is( 'text' ) ) { | ||
// @if CK_DEBUG_ENGINE // if ( child.is( '$text' ) ) { | ||
// @if CK_DEBUG_ENGINE // const textAttrs = convertMapToTags( child._attrs ); | ||
@@ -368,0 +388,0 @@ |
@@ -95,2 +95,12 @@ /** | ||
const markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName; | ||
if ( markerName.includes( ',' ) ) { | ||
/** | ||
* Marker name cannot contain the "," character. | ||
* | ||
* @error markercollection-incorrect-marker-name | ||
*/ | ||
throw new CKEditorError( 'markercollection-incorrect-marker-name: Marker name cannot contain "," character.', this ); | ||
} | ||
const oldMarker = this._markers.get( markerName ); | ||
@@ -97,0 +107,0 @@ |
@@ -576,3 +576,3 @@ /** | ||
for ( const item of range.getItems() ) { | ||
if ( item.is( 'textProxy' ) ) { | ||
if ( item.is( '$textProxy' ) ) { | ||
if ( !ignoreWhitespaces ) { | ||
@@ -579,0 +579,0 @@ return true; |
@@ -409,3 +409,3 @@ /** | ||
* | ||
* imageElement.is( 'image' ); // -> true | ||
* imageElement.is( 'element', 'image' ); // -> true | ||
* imageElement.is( 'element', 'image' ); // -> same as above | ||
@@ -431,3 +431,3 @@ * imageElement.is( 'model:element', 'image' ); // -> same as above, but more precise | ||
* @method #is | ||
* @param {String} type | ||
* @param {String} type Type to check. | ||
* @returns {Boolean} | ||
@@ -434,0 +434,0 @@ */ |
@@ -146,3 +146,3 @@ /** | ||
// So, we can operate on those text proxies' text nodes. | ||
const node = item.is( 'textProxy' ) ? item.textNode : item; | ||
const node = item.is( '$textProxy' ) ? item.textNode : item; | ||
@@ -223,3 +223,3 @@ if ( value !== null ) { | ||
// Check if both of those nodes are text objects with same attributes. | ||
if ( nodeBefore && nodeAfter && nodeBefore.is( 'text' ) && nodeAfter.is( 'text' ) && _haveSameAttributes( nodeBefore, nodeAfter ) ) { | ||
if ( nodeBefore && nodeAfter && nodeBefore.is( '$text' ) && nodeAfter.is( '$text' ) && _haveSameAttributes( nodeBefore, nodeAfter ) ) { | ||
// Append text of text node after index to the before one. | ||
@@ -226,0 +226,0 @@ const mergedNode = new Text( nodeBefore.data + nodeAfter.data, nodeBefore.getAttributes() ); |
@@ -149,5 +149,2 @@ /** | ||
/** | ||
* @param {Number} newOffset | ||
*/ | ||
set offset( newOffset ) { | ||
@@ -180,3 +177,3 @@ this.path[ this.path.length - 1 ] = newOffset; | ||
if ( parent.is( 'text' ) ) { | ||
if ( parent.is( '$text' ) ) { | ||
/** | ||
@@ -360,2 +357,18 @@ * The position's path is incorrect. This means that a position does not point to | ||
/** | ||
* Returns the parent element of the given name. Returns null if the position is not inside the desired parent. | ||
* | ||
* @param {String} parentName The name of the parent element to find. | ||
* @returns {module:engine/model/element~Element|null} | ||
*/ | ||
findAncestor( parentName ) { | ||
const parent = this.parent; | ||
if ( parent.is( 'element' ) ) { | ||
return parent.findAncestor( parentName, { includeSelf: true } ); | ||
} | ||
return null; | ||
} | ||
/** | ||
* Returns the slice of two position {@link #path paths} which is identical. The {@link #root roots} | ||
@@ -1096,3 +1109,3 @@ * of these two paths must be identical. | ||
if ( node && node.is( 'text' ) && node.startOffset < position.offset ) { | ||
if ( node && node.is( '$text' ) && node.startOffset < position.offset ) { | ||
return node; | ||
@@ -1099,0 +1112,0 @@ } |
@@ -280,2 +280,59 @@ /** | ||
/** | ||
* Returns a range created by joining this {@link ~Range range} with the given {@link ~Range range}. | ||
* If ranges have no common part, returns `null`. | ||
* | ||
* Examples: | ||
* | ||
* let range = model.createRange( | ||
* model.createPositionFromPath( root, [ 2, 7 ] ), | ||
* model.createPositionFromPath( root, [ 4, 0, 1 ] ) | ||
* ); | ||
* let otherRange = model.createRange( | ||
* model.createPositionFromPath( root, [ 1 ] ), | ||
* model.createPositionFromPath( root, [ 2 ] ) | ||
* ); | ||
* let transformed = range.getJoined( otherRange ); // null - ranges have no common part | ||
* | ||
* otherRange = model.createRange( | ||
* model.createPositionFromPath( root, [ 3 ] ), | ||
* model.createPositionFromPath( root, [ 5 ] ) | ||
* ); | ||
* transformed = range.getJoined( otherRange ); // range from [ 2, 7 ] to [ 5 ] | ||
* | ||
* @param {module:engine/model/range~Range} otherRange Range to be joined. | ||
* @param {Boolean} [loose=false] Whether the intersection check is loose or strict. If the check is strict (`false`), | ||
* ranges are tested for intersection or whether start/end positions are equal. If the check is loose (`true`), | ||
* compared range is also checked if it's {@link module:engine/model/position~Position#isTouching touching} current range. | ||
* @returns {module:engine/model/range~Range|null} A sum of given ranges or `null` if ranges have no common part. | ||
*/ | ||
getJoined( otherRange, loose = false ) { | ||
let shouldJoin = this.isIntersecting( otherRange ); | ||
if ( !shouldJoin ) { | ||
if ( this.start.isBefore( otherRange.start ) ) { | ||
shouldJoin = loose ? this.end.isTouching( otherRange.start ) : this.end.isEqual( otherRange.start ); | ||
} else { | ||
shouldJoin = loose ? otherRange.end.isTouching( this.start ) : otherRange.end.isEqual( this.start ); | ||
} | ||
} | ||
if ( !shouldJoin ) { | ||
return null; | ||
} | ||
let startPosition = this.start; | ||
let endPosition = this.end; | ||
if ( otherRange.start.isBefore( startPosition ) ) { | ||
startPosition = otherRange.start; | ||
} | ||
if ( otherRange.end.isAfter( endPosition ) ) { | ||
endPosition = otherRange.end; | ||
} | ||
return new Range( startPosition, endPosition ); | ||
} | ||
/** | ||
* Computes and returns the smallest set of {@link #isFlat flat} ranges, that covers this range in whole. | ||
@@ -282,0 +339,0 @@ * |
@@ -71,10 +71,7 @@ /** | ||
* | ||
* rootElement.is( '$root' ); // -> true if this is a $root element | ||
* rootElement.is( 'rootElement', '$root' ); // -> same as above | ||
* text.is( '$root' ); -> false | ||
* | ||
* {@link module:engine/model/node~Node#is Check the entire list of model objects} which implement the `is()` method. | ||
* | ||
* @param {String} type Type to check when `name` parameter is present. | ||
* Otherwise, it acts like the `name` parameter. | ||
* @param {String} type Type to check. | ||
* @param {String} [name] Element name. | ||
@@ -88,3 +85,2 @@ * @returns {Boolean} | ||
type === 'element' || type === 'model:element' || | ||
type === this.name || type === 'model:' + this.name || | ||
type === 'node' || type === 'model:node'; | ||
@@ -91,0 +87,0 @@ } |
@@ -189,3 +189,3 @@ /** | ||
itemName = item; | ||
} else if ( item.is && ( item.is( 'text' ) || item.is( 'textProxy' ) ) ) { | ||
} else if ( item.is && ( item.is( '$text' ) || item.is( '$textProxy' ) ) ) { | ||
itemName = '$text'; | ||
@@ -224,3 +224,3 @@ } | ||
* | ||
* See the {@glink framework/guides/deep-dive/schema#block-elements Block elements} section of the Schema deep dive} | ||
* See the {@glink framework/guides/deep-dive/schema#block-elements Block elements} section of the Schema deep dive | ||
* guide for more details. | ||
@@ -250,3 +250,3 @@ * | ||
* | ||
* See the {@glink framework/guides/deep-dive/schema#limit-elements Limit elements} section of the Schema deep dive} | ||
* See the {@glink framework/guides/deep-dive/schema#limit-elements Limit elements} section of the Schema deep dive | ||
* guide for more details. | ||
@@ -280,3 +280,3 @@ * | ||
* | ||
* See the {@glink framework/guides/deep-dive/schema#object-elements Object elements} section of the Schema deep dive} | ||
* See the {@glink framework/guides/deep-dive/schema#object-elements Object elements} section of the Schema deep dive | ||
* guide for more details. | ||
@@ -302,3 +302,3 @@ * | ||
* | ||
* See the {@glink framework/guides/deep-dive/schema#inline-elements Inline elements} section of the Schema deep dive} | ||
* See the {@glink framework/guides/deep-dive/schema#inline-elements Inline elements} section of the Schema deep dive | ||
* guide for more details. | ||
@@ -782,3 +782,3 @@ * | ||
// When node is a `Text` it has no children, so just filter it out. | ||
if ( node.is( 'text' ) ) { | ||
if ( node.is( '$text' ) ) { | ||
removeDisallowedAttributeFromNode( this, node, writer ); | ||
@@ -785,0 +785,0 @@ } |
@@ -70,8 +70,8 @@ /** | ||
* | ||
* text.is( 'text' ); // -> true | ||
* text.is( '$text' ); // -> true | ||
* text.is( 'node' ); // -> true | ||
* text.is( 'model:text' ); // -> true | ||
* text.is( 'model:$text' ); // -> true | ||
* text.is( 'model:node' ); // -> true | ||
* | ||
* text.is( 'view:text' ); // -> false | ||
* text.is( 'view:$text' ); // -> false | ||
* text.is( 'documentSelection' ); // -> false | ||
@@ -81,8 +81,12 @@ * | ||
* | ||
* @param {String} type Type to check when `name` parameter is present. | ||
* Otherwise, it acts like the `name` parameter. | ||
* **Note:** Until version 20.0.0 this method wasn't accepting `'$text'` type. The legacy `'text'` type is still | ||
* accepted for backward compatibility. | ||
* | ||
* @param {String} type Type to check. | ||
* @returns {Boolean} | ||
*/ | ||
is( type ) { | ||
return type === 'text' || type === 'model:text' || | ||
return type === '$text' || type === 'model:$text' || | ||
// This are legacy values kept for backward compatibility. | ||
type === 'text' || type === 'model:text' || | ||
// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529. | ||
@@ -89,0 +93,0 @@ type === 'node' || type === 'model:node'; |
@@ -169,6 +169,6 @@ /** | ||
* | ||
* textProxy.is( 'textProxy' ); // -> true | ||
* textProxy.is( 'model:textProxy' ); // -> true | ||
* textProxy.is( '$textProxy' ); // -> true | ||
* textProxy.is( 'model:$textProxy' ); // -> true | ||
* | ||
* textProxy.is( 'view:textProxy' ); // -> false | ||
* textProxy.is( 'view:$textProxy' ); // -> false | ||
* textProxy.is( 'range' ); // -> false | ||
@@ -178,7 +178,12 @@ * | ||
* | ||
* @param {String} type | ||
* **Note:** Until version 20.0.0 this method wasn't accepting `'$textProxy'` type. The legacy `'textProxt'` type is still | ||
* accepted for backward compatibility. | ||
* | ||
* @param {String} type Type to check. | ||
* @returns {Boolean} | ||
*/ | ||
is( type ) { | ||
return type === 'textProxy' || type === 'model:textProxy'; | ||
return type === '$textProxy' || type === 'model:$textProxy' || | ||
// This are legacy values kept for backward compatibility. | ||
type === 'textProxy' || type === 'model:textProxy'; | ||
} | ||
@@ -185,0 +190,0 @@ |
@@ -413,3 +413,3 @@ /** | ||
* | ||
* @typedef {'forward'|'backward'} module:engine/view/treewalker~TreeWalkerDirection | ||
* @typedef {'forward'|'backward'} module:engine/model/treewalker~TreeWalkerDirection | ||
*/ |
@@ -73,3 +73,3 @@ /** | ||
for ( const item of flatSubtreeRange.getItems( { shallow: true } ) ) { | ||
if ( item.is( 'textProxy' ) ) { | ||
if ( item.is( '$textProxy' ) ) { | ||
writer.appendText( item.data, item.getAttributes(), frag ); | ||
@@ -76,0 +76,0 @@ } else { |
@@ -176,3 +176,3 @@ /** | ||
// Scan only text nodes. Ignore inline elements (like `<softBreak>`). | ||
if ( nextNode && nextNode.is( 'text' ) ) { | ||
if ( nextNode && nextNode.is( '$text' ) ) { | ||
// Check boundary char of an adjacent text node. | ||
@@ -179,0 +179,0 @@ const boundaryChar = nextNode.data.charAt( isForward ? 0 : nextNode.data.length - 1 ); |
@@ -148,10 +148,9 @@ /** | ||
* | ||
* attributeElement.is( 'b' ); // -> true if this is a bold element | ||
* attributeElement.is( 'element', 'b' ); // -> true if this is a bold element | ||
* attributeElement.is( 'attributeElement', 'b' ); // -> same as above | ||
* text.is( 'b' ); -> false | ||
* text.is( 'element', 'b' ); -> false | ||
* | ||
* {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method. | ||
* | ||
* @param {String} type Type to check when `name` parameter is present. | ||
* Otherwise, it acts like the `name` parameter. | ||
* @param {String} type Type to check. | ||
* @param {String} [name] Element name. | ||
@@ -164,3 +163,2 @@ * @returns {Boolean} | ||
// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529. | ||
type === this.name || type === 'view:' + this.name || | ||
type === 'element' || type === 'view:element' || | ||
@@ -167,0 +165,0 @@ type === 'node' || type === 'view:node'; |
@@ -74,10 +74,9 @@ /** | ||
* | ||
* containerElement.is( 'div' ); // -> true if this is a div container element | ||
* containerElement.is( 'element', 'div' ); // -> true if this is a div container element | ||
* containerElement.is( 'contaienrElement', 'div' ); // -> same as above | ||
* text.is( 'div' ); -> false | ||
* text.is( 'element', 'div' ); -> false | ||
* | ||
* {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method. | ||
* | ||
* @param {String} type Type to check when `name` parameter is present. | ||
* Otherwise, it acts like the `name` parameter. | ||
* @param {String} type Type to check. | ||
* @param {String} [name] Element name. | ||
@@ -90,3 +89,2 @@ * @returns {Boolean} | ||
// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529. | ||
type === this.name || type === 'view:' + this.name || | ||
type === 'element' || type === 'view:element' || | ||
@@ -93,0 +91,0 @@ type === 'node' || type === 'view:node'; |
@@ -227,3 +227,3 @@ /** | ||
// @if CK_DEBUG_ENGINE // for ( const child of this.getChildren() ) { | ||
// @if CK_DEBUG_ENGINE // if ( child.is( 'text' ) ) { | ||
// @if CK_DEBUG_ENGINE // if ( child.is( '$text' ) ) { | ||
// @if CK_DEBUG_ENGINE // string += '\n' + '\t'.repeat( 1 ) + child.data; | ||
@@ -230,0 +230,0 @@ // @if CK_DEBUG_ENGINE // } else { |
@@ -32,12 +32,12 @@ /** | ||
/** | ||
* DomConverter is a set of tools to do transformations between DOM nodes and view nodes. It also handles | ||
* {@link module:engine/view/domconverter~DomConverter#bindElements binding} these nodes. | ||
* `DomConverter` is a set of tools to do transformations between DOM nodes and view nodes. It also handles | ||
* {@link module:engine/view/domconverter~DomConverter#bindElements bindings} between these nodes. | ||
* | ||
* The instance of DOMConverter is available in {@link module:engine/view/view~View#domConverter `editor.editing.view.domConverter`}. | ||
* The instance of `DOMConverter` is available under {@link module:engine/view/view~View#domConverter `editor.editing.view.domConverter`}. | ||
* | ||
* DomConverter does not check which nodes should be rendered (use {@link module:engine/view/renderer~Renderer}), does not keep a | ||
* `DomConverter` does not check which nodes should be rendered (use {@link module:engine/view/renderer~Renderer}), does not keep a | ||
* state of a tree nor keeps synchronization between tree view and DOM tree (use {@link module:engine/view/document~Document}). | ||
* | ||
* DomConverter keeps DOM elements to View element bindings, so when the converter will be destroyed, the binding will | ||
* be lost. Two converters will keep separate binding maps, so one tree view can be bound with two DOM trees. | ||
* `DomConverter` keeps DOM elements to View element bindings, so when the converter gets destroyed, the bindings are lost. | ||
* Two converters will keep separate binding maps, so one tree view can be bound with two DOM trees. | ||
*/ | ||
@@ -86,3 +86,3 @@ export default class DomConverter { | ||
*/ | ||
this.blockElements = [ 'p', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li', 'dd', 'dt', 'figcaption' ]; | ||
this.blockElements = [ 'p', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li', 'dd', 'dt', 'figcaption', 'td', 'th' ]; | ||
@@ -206,3 +206,3 @@ /** | ||
viewToDom( viewNode, domDocument, options = {} ) { | ||
if ( viewNode.is( 'text' ) ) { | ||
if ( viewNode.is( '$text' ) ) { | ||
const textData = this._processDataFromViewText( viewNode ); | ||
@@ -242,2 +242,8 @@ | ||
// RawElement take care of their children in RawElement#render() method which can be customized | ||
// (see https://github.com/ckeditor/ckeditor5/issues/4469). | ||
if ( viewNode.is( 'rawElement' ) ) { | ||
viewNode.render( domElement ); | ||
} | ||
if ( options.bind ) { | ||
@@ -324,3 +330,3 @@ this.bindElements( domElement, viewNode ); | ||
if ( viewParent.is( 'text' ) ) { | ||
if ( viewParent.is( '$text' ) ) { | ||
const domParent = this.findCorrespondingDomText( viewParent ); | ||
@@ -356,3 +362,3 @@ | ||
domBefore = nodeBefore.is( 'text' ) ? | ||
domBefore = nodeBefore.is( '$text' ) ? | ||
this.findCorrespondingDomText( nodeBefore ) : | ||
@@ -401,7 +407,7 @@ this.mapViewToDom( viewPosition.nodeBefore ); | ||
// When node is inside UIElement return that UIElement as it's view representation. | ||
const uiElement = this.getParentUIElement( domNode, this._domToViewMapping ); | ||
// When node is inside a UIElement or a RawElement return that parent as it's view representation. | ||
const hostElement = this.getHostViewElement( domNode, this._domToViewMapping ); | ||
if ( uiElement ) { | ||
return uiElement; | ||
if ( hostElement ) { | ||
return hostElement; | ||
} | ||
@@ -560,6 +566,6 @@ | ||
// If position is somewhere inside UIElement - return position before that element. | ||
// If position is somewhere inside UIElement or a RawElement - return position before that element. | ||
const viewElement = this.mapDomToView( domParent ); | ||
if ( viewElement && viewElement.is( 'uiElement' ) ) { | ||
if ( viewElement && ( viewElement.is( 'uiElement' ) || viewElement.is( 'rawElement' ) ) ) { | ||
return ViewPosition._createBefore( viewElement ); | ||
@@ -616,4 +622,6 @@ } | ||
* to the given DOM - `undefined` is returned. | ||
* For all DOM elements rendered by {@link module:engine/view/uielement~UIElement} that UIElement will be returned. | ||
* | ||
* For all DOM elements rendered by a {@link module:engine/view/uielement~UIElement} or | ||
* a {@link module:engine/view/rawelement~RawElement}, the parent `UIElement` or `RawElement` will be returned. | ||
* | ||
* @param {DocumentFragment|Element} domElementOrDocumentFragment DOM element or document fragment. | ||
@@ -624,3 +632,5 @@ * @returns {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment|undefined} | ||
mapDomToView( domElementOrDocumentFragment ) { | ||
return this.getParentUIElement( domElementOrDocumentFragment ) || this._domToViewMapping.get( domElementOrDocumentFragment ); | ||
const hostElement = this.getHostViewElement( domElementOrDocumentFragment ); | ||
return hostElement || this._domToViewMapping.get( domElementOrDocumentFragment ); | ||
} | ||
@@ -638,3 +648,4 @@ | ||
* | ||
* For all text nodes rendered by {@link module:engine/view/uielement~UIElement} that UIElement will be returned. | ||
* For all text nodes rendered by a {@link module:engine/view/uielement~UIElement} or | ||
* a {@link module:engine/view/rawelement~RawElement}, the parent `UIElement` or `RawElement` will be returned. | ||
* | ||
@@ -654,7 +665,7 @@ * Otherwise `null` is returned. | ||
// If DOM text was rendered by UIElement - return that element. | ||
const uiElement = this.getParentUIElement( domText ); | ||
// If DOM text was rendered by a UIElement or a RawElement - return this parent element. | ||
const hostElement = this.getHostViewElement( domText ); | ||
if ( uiElement ) { | ||
return uiElement; | ||
if ( hostElement ) { | ||
return hostElement; | ||
} | ||
@@ -873,9 +884,9 @@ | ||
/** | ||
* Returns parent {@link module:engine/view/uielement~UIElement} for provided DOM node. Returns `null` if there is no | ||
* parent UIElement. | ||
* Returns a parent {@link module:engine/view/uielement~UIElement} or {@link module:engine/view/rawelement~RawElement} | ||
* that hosts the provided DOM node. Returns `null` if there is no such parent. | ||
* | ||
* @param {Node} domNode | ||
* @returns {module:engine/view/uielement~UIElement|null} | ||
* @returns {module:engine/view/uielement~UIElement|module:engine/view/rawelement~RawElement|null} | ||
*/ | ||
getParentUIElement( domNode ) { | ||
getHostViewElement( domNode ) { | ||
const ancestors = getAncestors( domNode ); | ||
@@ -890,3 +901,3 @@ | ||
if ( viewNode && viewNode.is( 'uiElement' ) ) { | ||
if ( viewNode && ( viewNode.is( 'uiElement' ) || viewNode.is( 'rawElement' ) ) ) { | ||
return viewNode; | ||
@@ -903,4 +914,6 @@ } | ||
* The following places are considered as incorrect for selection boundaries: | ||
* | ||
* * before or in the middle of the inline filler sequence, | ||
* * inside the DOM element which represents {@link module:engine/view/uielement~UIElement a view ui element}. | ||
* * inside a DOM element which represents {@link module:engine/view/uielement~UIElement a view UI element}, | ||
* * inside a DOM element which represents {@link module:engine/view/rawelement~RawElement a view raw element}. | ||
* | ||
@@ -937,5 +950,6 @@ * @param {Selection} domSelection DOM Selection object to be checked. | ||
// If selection is in `view.UIElement`, it is incorrect. Note that `mapDomToView()` returns `view.UIElement` | ||
// also for any dom element that is inside the view ui element (so we don't need to perform any additional checks). | ||
if ( viewParent && viewParent.is( 'uiElement' ) ) { | ||
// The position is incorrect when anchored inside a UIElement or a RawElement. | ||
// Note: In case of UIElement and RawElement, mapDomToView() returns a parent element for any DOM child | ||
// so there's no need to perform any additional checks. | ||
if ( viewParent && ( viewParent.is( 'uiElement' ) || viewParent.is( 'rawElement' ) ) ) { | ||
return false; | ||
@@ -1154,7 +1168,7 @@ } | ||
// <br> found – it works like a block boundary, so do not scan further. | ||
else if ( value.item.is( 'br' ) ) { | ||
else if ( value.item.is( 'element', 'br' ) ) { | ||
return null; | ||
} | ||
// Found a text node in the same container element. | ||
else if ( value.item.is( 'textProxy' ) ) { | ||
else if ( value.item.is( '$textProxy' ) ) { | ||
return value.item; | ||
@@ -1161,0 +1175,0 @@ } |
@@ -86,10 +86,9 @@ /** | ||
* | ||
* editableElement.is( 'div' ); // -> true if this is a div element | ||
* editableElement.is( 'element', 'div' ); // -> true if this is a div element | ||
* editableElement.is( 'editableElement', 'div' ); // -> same as above | ||
* text.is( 'div' ); -> false | ||
* text.is( 'element', 'div' ); -> false | ||
* | ||
* {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method. | ||
* | ||
* @param {String} type Type to check when `name` parameter is present. | ||
* Otherwise, it acts like the `name` parameter. | ||
* @param {String} type Type to check. | ||
* @param {String} [name] Element name. | ||
@@ -103,3 +102,2 @@ * @returns {Boolean} | ||
type === 'containerElement' || type === 'view:containerElement' || | ||
type === this.name || type === 'view:' + this.name || | ||
type === 'element' || type === 'view:element' || | ||
@@ -106,0 +104,0 @@ type === 'node' || type === 'view:node'; |
@@ -167,10 +167,8 @@ /** | ||
* | ||
* element.is( 'img' ); // -> true if this is an <img> element | ||
* element.is( 'element', 'img' ); // -> same as above | ||
* text.is( 'img' ); -> false | ||
* element.is( 'element', 'img' ); // -> true if this is an <img> element | ||
* text.is( 'element', 'img' ); -> false | ||
* | ||
* {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method. | ||
* | ||
* @param {String} type Type to check when `name` parameter is present. | ||
* Otherwise, it acts like the `name` parameter. | ||
* @param {String} type Type to check. | ||
* @param {String} [name] Element name. | ||
@@ -181,4 +179,3 @@ * @returns {Boolean} | ||
if ( !name ) { | ||
return type === this.name || type === 'view:' + this.name || | ||
type === 'element' || type === 'view:element' || | ||
return type === 'element' || type === 'view:element' || | ||
// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529. | ||
@@ -839,3 +836,3 @@ type === 'node' || type === 'view:node'; | ||
// @if CK_DEBUG_ENGINE // for ( const child of this.getChildren() ) { | ||
// @if CK_DEBUG_ENGINE // if ( child.is( 'text' ) ) { | ||
// @if CK_DEBUG_ENGINE // if ( child.is( '$text' ) ) { | ||
// @if CK_DEBUG_ENGINE // string += '\n' + '\t'.repeat( level + 1 ) + child.data; | ||
@@ -842,0 +839,0 @@ // @if CK_DEBUG_ENGINE // } else { |
@@ -65,10 +65,9 @@ /** | ||
* | ||
* emptyElement.is( 'img' ); // -> true if this is a img element | ||
* emptyElement.is( 'element', 'img' ); // -> true if this is a img element | ||
* emptyElement.is( 'emptyElement', 'img' ); // -> same as above | ||
* text.is( 'img' ); -> false | ||
* text.is( 'element', 'img' ); -> false | ||
* | ||
* {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method. | ||
* | ||
* @param {String} type Type to check when `name` parameter is present. | ||
* Otherwise, it acts like the `name` parameter. | ||
* @param {String} type Type to check. | ||
* @param {String} [name] Element name. | ||
@@ -81,3 +80,2 @@ * @returns {Boolean} | ||
// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529. | ||
type === this.name || type === 'view:' + this.name || | ||
type === 'element' || type === 'view:element' || | ||
@@ -84,0 +82,0 @@ type === 'node' || type === 'view:node'; |
@@ -67,2 +67,4 @@ /** | ||
* Inline filler which is a sequence of the zero width spaces. | ||
* | ||
* @type {String} | ||
*/ | ||
@@ -69,0 +71,0 @@ export const INLINE_FILLER = ( () => { |
@@ -315,4 +315,3 @@ /** | ||
* | ||
* imgElement.is( 'img' ); // -> true | ||
* imgElement.is( 'element', 'img' ); // -> same as above | ||
* imgElement.is( 'element', 'img' ); // -> true | ||
* imgElement.is( 'view:element', 'img' ); // -> same as above, but more precise | ||
@@ -339,3 +338,3 @@ * | ||
* @method #is | ||
* @param {String} type | ||
* @param {String} type Type to check. | ||
* @returns {Boolean} | ||
@@ -342,0 +341,0 @@ */ |
@@ -153,4 +153,4 @@ /** | ||
// Do not collect mutations from UIElements. | ||
if ( element && element.is( 'uiElement' ) ) { | ||
// Do not collect mutations from UIElements and RawElements. | ||
if ( element && ( element.is( 'uiElement' ) || element.is( 'rawElement' ) ) ) { | ||
continue; | ||
@@ -169,4 +169,4 @@ } | ||
// Do not collect mutations from UIElements. | ||
if ( element && element.is( 'uiElement' ) ) { | ||
// Do not collect mutations from UIElements and RawElements. | ||
if ( element && ( element.is( 'uiElement' ) || element.is( 'rawElement' ) ) ) { | ||
continue; | ||
@@ -269,3 +269,3 @@ } | ||
// Texts. | ||
else if ( child1.is( 'text' ) && child2.is( 'text' ) ) { | ||
else if ( child1.is( '$text' ) && child2.is( '$text' ) ) { | ||
return child1.data === child2.data; | ||
@@ -272,0 +272,0 @@ } |
@@ -62,3 +62,3 @@ /** | ||
get nodeAfter() { | ||
if ( this.parent.is( 'text' ) ) { | ||
if ( this.parent.is( '$text' ) ) { | ||
return null; | ||
@@ -78,3 +78,3 @@ } | ||
get nodeBefore() { | ||
if ( this.parent.is( 'text' ) ) { | ||
if ( this.parent.is( '$text' ) ) { | ||
return null; | ||
@@ -103,3 +103,3 @@ } | ||
get isAtEnd() { | ||
const endOffset = this.parent.is( 'text' ) ? this.parent.data.length : this.parent.childCount; | ||
const endOffset = this.parent.is( '$text' ) ? this.parent.data.length : this.parent.childCount; | ||
@@ -352,3 +352,3 @@ return this.offset === endOffset; | ||
if ( offset == 'end' ) { | ||
offset = node.is( 'text' ) ? node.data.length : node.childCount; | ||
offset = node.is( '$text' ) ? node.data.length : node.childCount; | ||
} else if ( offset == 'before' ) { | ||
@@ -385,3 +385,3 @@ return this._createBefore( node ); | ||
// TextProxy is not a instance of Node so we need do handle it in specific way. | ||
if ( item.is( 'textProxy' ) ) { | ||
if ( item.is( '$textProxy' ) ) { | ||
return new Position( item.textNode, item.offsetInText + item.data.length ); | ||
@@ -412,3 +412,3 @@ } | ||
// TextProxy is not a instance of Node so we need do handle it in specific way. | ||
if ( item.is( 'textProxy' ) ) { | ||
if ( item.is( '$textProxy' ) ) { | ||
return new Position( item.textNode, item.offsetInText ); | ||
@@ -415,0 +415,0 @@ } |
@@ -116,7 +116,7 @@ /** | ||
// Fix positions, in case if they are in Text node. | ||
if ( start.parent.is( 'text' ) && start.isAtStart ) { | ||
if ( start.parent.is( '$text' ) && start.isAtStart ) { | ||
start = Position._createBefore( start.parent ); | ||
} | ||
if ( end.parent.is( 'text' ) && end.isAtEnd ) { | ||
if ( end.parent.is( '$text' ) && end.isAtEnd ) { | ||
end = Position._createAfter( end.parent ); | ||
@@ -157,7 +157,7 @@ } | ||
// Because TreeWalker prefers positions next to text node, we need to move them manually into these text nodes. | ||
if ( nodeAfterStart && nodeAfterStart.is( 'text' ) ) { | ||
if ( nodeAfterStart && nodeAfterStart.is( '$text' ) ) { | ||
start = new Position( nodeAfterStart, 0 ); | ||
} | ||
if ( nodeBeforeEnd && nodeBeforeEnd.is( 'text' ) ) { | ||
if ( nodeBeforeEnd && nodeBeforeEnd.is( '$text' ) ) { | ||
end = new Position( nodeBeforeEnd, nodeBeforeEnd.data.length ); | ||
@@ -364,7 +364,7 @@ } | ||
// | ||
if ( this.start.parent.is( 'text' ) && this.start.isAtEnd && this.start.parent.nextSibling ) { | ||
if ( this.start.parent.is( '$text' ) && this.start.isAtEnd && this.start.parent.nextSibling ) { | ||
nodeAfterStart = this.start.parent.nextSibling; | ||
} | ||
if ( this.end.parent.is( 'text' ) && this.end.isAtStart && this.end.parent.previousSibling ) { | ||
if ( this.end.parent.is( '$text' ) && this.end.isAtStart && this.end.parent.previousSibling ) { | ||
nodeBeforeEnd = this.end.parent.previousSibling; | ||
@@ -523,3 +523,3 @@ } | ||
static _createOn( item ) { | ||
const size = item.is( 'textProxy' ) ? item.offsetSize : 1; | ||
const size = item.is( '$textProxy' ) ? item.offsetSize : 1; | ||
@@ -526,0 +526,0 @@ return this._createFromPositionAndShift( Position._createBefore( item ), size ); |
@@ -276,6 +276,6 @@ /** | ||
// The 'uiElement' is a special one and its children are not stored in a view (#799), | ||
// so we cannot use it with replacing flow (since it uses view children during rendering | ||
// which will always result in rendering empty element). | ||
if ( viewChild && !viewChild.is( 'uiElement' ) ) { | ||
// UIElement and RawElement are special cases. Their children are not stored in a view (#799) | ||
// so we cannot use them with replacing flow (since they use view children during rendering | ||
// which will always result in rendering empty elements). | ||
if ( viewChild && !( viewChild.is( 'uiElement' ) || viewChild.is( 'rawElement' ) ) ) { | ||
this._updateElementMappings( viewChild, actualDomChildren[ deleteIndex ] ); | ||
@@ -336,3 +336,3 @@ } | ||
if ( firstPos.parent.is( 'text' ) ) { | ||
if ( firstPos.parent.is( '$text' ) ) { | ||
return ViewPosition._createBefore( this.selection.getFirstPosition().parent ); | ||
@@ -664,3 +664,3 @@ } else { | ||
if ( viewNode.is( 'text' ) ) { | ||
if ( viewNode.is( '$text' ) ) { | ||
this.markedTexts.add( viewNode ); | ||
@@ -667,0 +667,0 @@ } else if ( viewNode.is( 'element' ) ) { |
@@ -58,10 +58,9 @@ /** | ||
* | ||
* rootEditableElement.is( 'div' ); // -> true if this is a div root editable element | ||
* rootEditableElement.is( 'element', 'div' ); // -> true if this is a div root editable element | ||
* rootEditableElement.is( 'rootElement', 'div' ); // -> same as above | ||
* text.is( 'div' ); -> false | ||
* text.is( 'element', 'div' ); -> false | ||
* | ||
* {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method. | ||
* | ||
* @param {String} type Type to check when `name` parameter is present. | ||
* Otherwise, it acts like the `name` parameter. | ||
* @param {String} type Type to check. | ||
* @param {String} [name] Element name. | ||
@@ -76,3 +75,2 @@ * @returns {Boolean} | ||
type === 'containerElement' || type === 'view:containerElement' || | ||
type === this.name || type === 'view:' + this.name || | ||
type === 'element' || type === 'view:element' || | ||
@@ -79,0 +77,0 @@ type === 'node' || type === 'view:node'; |
@@ -48,8 +48,8 @@ /** | ||
* | ||
* text.is( 'text' ); // -> true | ||
* text.is( '$text' ); // -> true | ||
* text.is( 'node' ); // -> true | ||
* text.is( 'view:text' ); // -> true | ||
* text.is( 'view:$text' ); // -> true | ||
* text.is( 'view:node' ); // -> true | ||
* | ||
* text.is( 'model:text' ); // -> false | ||
* text.is( 'model:$text' ); // -> false | ||
* text.is( 'element' ); // -> false | ||
@@ -60,7 +60,12 @@ * text.is( 'range' ); // -> false | ||
* | ||
* @param {String} type | ||
* **Note:** Until version 20.0.0 this method wasn't accepting `'$text'` type. The legacy `'text'` type is still | ||
* accepted for backward compatibility. | ||
* | ||
* @param {String} type Type to check. | ||
* @returns {Boolean} | ||
*/ | ||
is( type ) { | ||
return type === 'text' || type === 'view:text' || | ||
return type === '$text' || type === 'view:$text' || | ||
// This are legacy values kept for backward compatibility. | ||
type === 'text' || type === 'view:text' || | ||
// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529. | ||
@@ -81,4 +86,6 @@ type === 'node' || type === 'view:node'; | ||
/** | ||
* This getter is required when using the addition assignment operator on protected property: | ||
* The `_data` property is controlled by a getter and a setter. | ||
* | ||
* The getter is required when using the addition assignment operator on protected property: | ||
* | ||
* const foo = downcastWriter.createText( 'foo' ); | ||
@@ -92,2 +99,4 @@ * const bar = downcastWriter.createText( 'bar' ); | ||
* | ||
* The setter sets data and fires the {@link module:engine/view/node~Node#event:change:text change event}. | ||
* | ||
* @protected | ||
@@ -100,9 +109,2 @@ * @type {String} | ||
/** | ||
* Sets data and fires the {@link module:engine/view/node~Node#event:change:text change event}. | ||
* | ||
* @protected | ||
* @fires change:text | ||
* @param {String} data New data for the text node. | ||
*/ | ||
set _data( data ) { | ||
@@ -109,0 +111,0 @@ this._fireChange( 'text', this ); |
@@ -146,6 +146,6 @@ /** | ||
* | ||
* textProxy.is( 'textProxy' ); // -> true | ||
* textProxy.is( 'view:textProxy' ); // -> true | ||
* textProxy.is( '$textProxy' ); // -> true | ||
* textProxy.is( 'view:$textProxy' ); // -> true | ||
* | ||
* textProxy.is( 'model:textProxy' ); // -> false | ||
* textProxy.is( 'model:$textProxy' ); // -> false | ||
* textProxy.is( 'element' ); // -> false | ||
@@ -156,7 +156,12 @@ * textProxy.is( 'range' ); // -> false | ||
* | ||
* @param {String} type | ||
* **Note:** Until version 20.0.0 this method wasn't accepting `'$textProxy'` type. The legacy `'textProxy'` type is still | ||
* accepted for backward compatibility. | ||
* | ||
* @param {String} type Type to check. | ||
* @returns {Boolean} | ||
*/ | ||
is( type ) { | ||
return type === 'textProxy' || type === 'view:textProxy'; | ||
return type === '$textProxy' || type === 'view:$textProxy' || | ||
// This are legacy values kept for backward compatibility. | ||
type === 'textProxy' || type === 'view:textProxy'; | ||
} | ||
@@ -163,0 +168,0 @@ |
@@ -78,10 +78,9 @@ /** | ||
* | ||
* uiElement.is( 'span' ); // -> true if this is a span ui element | ||
* uiElement.is( 'element', 'span' ); // -> true if this is a span ui element | ||
* uiElement.is( 'uiElement', 'span' ); // -> same as above | ||
* text.is( 'span' ); -> false | ||
* text.is( 'element', 'span' ); -> false | ||
* | ||
* {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method. | ||
* | ||
* @param {String} type Type to check when `name` parameter is present. | ||
* Otherwise, it acts like the `name` parameter. | ||
* @param {String} type Type to check. | ||
* @param {String} [name] Element name. | ||
@@ -94,3 +93,2 @@ * @returns {Boolean} | ||
// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529. | ||
type === this.name || type === 'view:' + this.name || | ||
type === 'element' || type === 'view:element' || | ||
@@ -97,0 +95,0 @@ type === 'node' || type === 'view:node'; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
1740330
0.85%39112
0.51%+ Added
- Removed