@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
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
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