@ckeditor/ckeditor5-engine
Advanced tools
Comparing version 17.0.0 to 18.0.0
{ | ||
"name": "@ckeditor/ckeditor5-engine", | ||
"version": "17.0.0", | ||
"version": "18.0.0", | ||
"description": "The editing engine of CKEditor 5 – the best browser-based rich text editor.", | ||
@@ -24,20 +24,20 @@ "keywords": [ | ||
"dependencies": { | ||
"@ckeditor/ckeditor5-utils": "^17.0.0", | ||
"@ckeditor/ckeditor5-utils": "^18.0.0", | ||
"lodash-es": "^4.17.10" | ||
}, | ||
"devDependencies": { | ||
"@ckeditor/ckeditor5-basic-styles": "^17.0.0", | ||
"@ckeditor/ckeditor5-block-quote": "^17.0.0", | ||
"@ckeditor/ckeditor5-core": "^17.0.0", | ||
"@ckeditor/ckeditor5-editor-classic": "^17.0.0", | ||
"@ckeditor/ckeditor5-enter": "^17.0.0", | ||
"@ckeditor/ckeditor5-essentials": "^17.0.0", | ||
"@ckeditor/ckeditor5-heading": "^17.0.0", | ||
"@ckeditor/ckeditor5-link": "^17.0.0", | ||
"@ckeditor/ckeditor5-list": "^17.0.0", | ||
"@ckeditor/ckeditor5-paragraph": "^17.0.0", | ||
"@ckeditor/ckeditor5-theme-lark": "^17.0.0", | ||
"@ckeditor/ckeditor5-typing": "^17.0.0", | ||
"@ckeditor/ckeditor5-undo": "^17.0.0", | ||
"@ckeditor/ckeditor5-widget": "^17.0.0", | ||
"@ckeditor/ckeditor5-basic-styles": "^18.0.0", | ||
"@ckeditor/ckeditor5-block-quote": "^18.0.0", | ||
"@ckeditor/ckeditor5-core": "^18.0.0", | ||
"@ckeditor/ckeditor5-editor-classic": "^18.0.0", | ||
"@ckeditor/ckeditor5-enter": "^18.0.0", | ||
"@ckeditor/ckeditor5-essentials": "^18.0.0", | ||
"@ckeditor/ckeditor5-heading": "^18.0.0", | ||
"@ckeditor/ckeditor5-link": "^18.0.0", | ||
"@ckeditor/ckeditor5-list": "^18.0.0", | ||
"@ckeditor/ckeditor5-paragraph": "^18.0.0", | ||
"@ckeditor/ckeditor5-theme-lark": "^18.0.0", | ||
"@ckeditor/ckeditor5-typing": "^18.0.0", | ||
"@ckeditor/ckeditor5-undo": "^18.0.0", | ||
"@ckeditor/ckeditor5-widget": "^18.0.0", | ||
"eslint": "^5.5.0", | ||
@@ -44,0 +44,0 @@ "eslint-config-ckeditor5": "^2.0.0", |
@@ -50,6 +50,5 @@ /** | ||
* @param {module:engine/model/model~Model} model Data model. | ||
* @param {module:engine/dataprocessor/dataprocessor~DataProcessor} [dataProcessor] Data processor that should be used | ||
* by the controller. | ||
* @param {module:engine/view/stylesmap~StylesProcessor} stylesProcessor The styles processor instance. | ||
*/ | ||
constructor( model, dataProcessor ) { | ||
constructor( model, stylesProcessor ) { | ||
/** | ||
@@ -64,10 +63,17 @@ * Data model. | ||
/** | ||
* Data processor used during the conversion. | ||
* Styles processor used during the conversion. | ||
* | ||
* @readonly | ||
* @member {module:engine/dataprocessor/dataprocessor~DataProcessor} | ||
* @member {module:engine/view/stylesmap~StylesProcessor} | ||
*/ | ||
this.processor = dataProcessor; | ||
this.stylesProcessor = stylesProcessor; | ||
/** | ||
* Data processor used during the conversion. | ||
* | ||
* @member {module:engine/dataprocessor/dataprocessor~DataProcessor} #processor | ||
*/ | ||
this.processor; | ||
/** | ||
* Mapper used for the conversion. It has no permanent bindings, because they are created when getting data and | ||
@@ -103,2 +109,20 @@ * cleared directly after the data are converted. However, the mapper is defined as a class property, because | ||
/** | ||
* The view document used by the data controller. | ||
* | ||
* @readonly | ||
* @member {module:engine/view/document~Document} | ||
*/ | ||
this.viewDocument = new ViewDocument( stylesProcessor ); | ||
/** | ||
* The view downcast writer just for data conversion purposes, i.e. to modify | ||
* the {@link #viewDocument}. | ||
* | ||
* @private | ||
* @readonly | ||
* @member {module:engine/view/downcastwriter~DowncastWriter} | ||
*/ | ||
this._viewWriter = new ViewDowncastWriter( this.viewDocument ); | ||
// Define default converters for text and elements. | ||
@@ -188,2 +212,5 @@ // | ||
toView( modelElementOrFragment ) { | ||
const viewDocument = this.viewDocument; | ||
const viewWriter = this._viewWriter; | ||
// Clear bindings so the call to this method gives correct results. | ||
@@ -194,10 +221,7 @@ this.mapper.clearBindings(); | ||
const modelRange = ModelRange._createIn( modelElementOrFragment ); | ||
const viewDocumentFragment = new ViewDocumentFragment( viewDocument ); | ||
const viewDocumentFragment = new ViewDocumentFragment(); | ||
this.mapper.bindElements( modelElementOrFragment, viewDocumentFragment ); | ||
// Create separate ViewDowncastWriter just for data conversion purposes. | ||
// We have no view controller and rendering do DOM in DataController so view.change() block is not used here. | ||
const viewWriter = new ViewDowncastWriter( new ViewDocument() ); | ||
this.mapper.bindElements( modelElementOrFragment, viewDocumentFragment ); | ||
this.downcastDispatcher.convertInsert( modelRange, viewWriter ); | ||
@@ -380,2 +404,18 @@ | ||
/** | ||
* Adds a style processor normalization rules. | ||
* | ||
* You can implement your own rules as well as use one of the available processor rules: | ||
* | ||
* * background: {@link module:engine/view/styles/background~addBackgroundRules} | ||
* * border: {@link module:engine/view/styles/border~addBorderRules} | ||
* * margin: {@link module:engine/view/styles/margin~addMarginRules} | ||
* * padding: {@link module:engine/view/styles/padding~addPaddingRules} | ||
* | ||
* @param {Function} callback | ||
*/ | ||
addStyleProcessorRules( callback ) { | ||
callback( this.stylesProcessor ); | ||
} | ||
/** | ||
* Removes all event listeners set by the DataController. | ||
@@ -382,0 +422,0 @@ */ |
@@ -34,4 +34,5 @@ /** | ||
* @param {module:engine/model/model~Model} model Editing model. | ||
* @param {module:engine/view/stylesmap~StylesProcessor} stylesProcessor The styles processor instance. | ||
*/ | ||
constructor( model ) { | ||
constructor( model, stylesProcessor ) { | ||
/** | ||
@@ -51,3 +52,3 @@ * Editor model. | ||
*/ | ||
this.view = new View(); | ||
this.view = new View( stylesProcessor ); | ||
@@ -120,6 +121,5 @@ /** | ||
const viewRoot = new RootEditableElement( root.name ); | ||
const viewRoot = new RootEditableElement( this.view.document, root.name ); | ||
viewRoot.rootName = root.rootName; | ||
viewRoot._document = this.view.document; | ||
this.mapper.bindElements( root, viewRoot ); | ||
@@ -126,0 +126,0 @@ |
@@ -419,7 +419,8 @@ /** | ||
* | ||
* @param {module:engine/view/downcastwriter~DowncastWriter} writer | ||
* @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} descriptor | ||
* @returns {module:engine/view/attributeelement~AttributeElement} | ||
*/ | ||
export function createViewElementFromHighlightDescriptor( descriptor ) { | ||
const viewElement = new ViewAttributeElement( 'span', descriptor.attributes ); | ||
export function createViewElementFromHighlightDescriptor( writer, descriptor ) { | ||
const viewElement = writer.createAttributeElement( 'span', descriptor.attributes ); | ||
@@ -547,3 +548,3 @@ if ( descriptor.classes ) { | ||
// Position might be in the node removed by the view writer. | ||
if ( range.end.parent.document ) { | ||
if ( range.end.parent.isAttached() ) { | ||
conversionApi.writer.mergeAttributes( range.start ); | ||
@@ -924,4 +925,4 @@ } | ||
const viewElement = createViewElementFromHighlightDescriptor( descriptor ); | ||
const viewWriter = conversionApi.writer; | ||
const viewElement = createViewElementFromHighlightDescriptor( viewWriter, descriptor ); | ||
const viewSelection = viewWriter.document.selection; | ||
@@ -1040,3 +1041,3 @@ | ||
// View element that will be used to unwrap `AttributeElement`s. | ||
const viewHighlightElement = createViewElementFromHighlightDescriptor( descriptor ); | ||
const viewHighlightElement = createViewElementFromHighlightDescriptor( conversionApi.writer, descriptor ); | ||
@@ -1043,0 +1044,0 @@ // Get all elements bound with given marker name. |
@@ -12,3 +12,2 @@ /** | ||
import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; | ||
import StylesMap from '../view/stylesmap'; | ||
@@ -93,3 +92,3 @@ /** | ||
if ( !this._consumables.has( element ) ) { | ||
elementConsumables = new ViewElementConsumables(); | ||
elementConsumables = new ViewElementConsumables( element ); | ||
this._consumables.set( element, elementConsumables ); | ||
@@ -244,2 +243,3 @@ } else { | ||
const consumables = { | ||
element, | ||
name: true, | ||
@@ -290,3 +290,3 @@ attributes: [], | ||
if ( !instance ) { | ||
instance = new ViewConsumable(); | ||
instance = new ViewConsumable( from ); | ||
} | ||
@@ -326,5 +326,14 @@ | ||
* Creates ViewElementConsumables instance. | ||
* | ||
* @param {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment} from View node or document fragment | ||
* from which `ViewElementConsumables` is being created. | ||
*/ | ||
constructor() { | ||
constructor( from ) { | ||
/** | ||
* @readonly | ||
* @member {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment} | ||
*/ | ||
this.element = from; | ||
/** | ||
* Flag indicating if name of the element can be consumed. | ||
@@ -518,3 +527,3 @@ * | ||
if ( type === 'styles' ) { | ||
for ( const alsoName of StylesMap.getRelatedStyles( name ) ) { | ||
for ( const alsoName of this.element.document.stylesProcessor.getRelatedStyles( name ) ) { | ||
consumables.set( alsoName, true ); | ||
@@ -586,3 +595,3 @@ } | ||
if ( type == 'styles' ) { | ||
for ( const toConsume of StylesMap.getRelatedStyles( name ) ) { | ||
for ( const toConsume of this.element.document.stylesProcessor.getRelatedStyles( name ) ) { | ||
consumables.set( toConsume, false ); | ||
@@ -589,0 +598,0 @@ } |
@@ -24,4 +24,6 @@ /** | ||
* Creates a new instance of the HTML data processor class. | ||
* | ||
* @param {module:engine/view/document~Document} document The view document instance. | ||
*/ | ||
constructor() { | ||
constructor( document ) { | ||
/** | ||
@@ -41,3 +43,3 @@ * A DOM parser instance used to parse an HTML string to an HTML document. | ||
*/ | ||
this._domConverter = new DomConverter( { blockFillerMode: 'nbsp' } ); | ||
this._domConverter = new DomConverter( document, { blockFillerMode: 'nbsp' } ); | ||
@@ -44,0 +46,0 @@ /** |
@@ -27,6 +27,7 @@ /** | ||
* | ||
* @param {module:engine/view/document~Document} document The view document instance. | ||
* @param {Object} options Configuration options. | ||
* @param {Array<String>} [options.namespaces=[]] A list of namespaces allowed to use in the XML input. | ||
*/ | ||
constructor( options = {} ) { | ||
constructor( document, options = {} ) { | ||
/** | ||
@@ -57,3 +58,3 @@ * A list of namespaces allowed to use in the XML input. | ||
*/ | ||
this._domConverter = new DomConverter( { blockFillerMode: 'nbsp' } ); | ||
this._domConverter = new DomConverter( document, { blockFillerMode: 'nbsp' } ); | ||
@@ -60,0 +61,0 @@ /** |
@@ -42,2 +42,3 @@ /** | ||
import toMap from '@ckeditor/ckeditor5-utils/src/tomap'; | ||
import { StylesProcessor } from '../view/stylesmap'; | ||
@@ -214,8 +215,8 @@ /** | ||
// Create a temporary view controller. | ||
const view = new View(); | ||
const stylesProcessor = new StylesProcessor(); | ||
const view = new View( stylesProcessor ); | ||
const viewDocument = view.document; | ||
const viewRoot = new ViewRootEditableElement( 'div' ); | ||
const viewRoot = new ViewRootEditableElement( viewDocument, 'div' ); | ||
// Create a temporary root element in view document. | ||
viewRoot._document = view.document; | ||
viewRoot.rootName = 'main'; | ||
@@ -247,3 +248,3 @@ viewDocument.roots.add( viewRoot ); | ||
return new ViewContainerElement( modelItem.name, attributes ); | ||
return new ViewContainerElement( viewDocument, modelItem.name, attributes ); | ||
} ) ); | ||
@@ -250,0 +251,0 @@ |
@@ -17,2 +17,3 @@ /** | ||
import View from '../view/view'; | ||
import ViewDocument from '../view/document'; | ||
import ViewDocumentFragment from '../view/documentfragment'; | ||
@@ -28,2 +29,3 @@ import XmlDataProcessor from '../dataprocessor/xmldataprocessor'; | ||
import UIElement from '../view/uielement'; | ||
import { StylesProcessor } from '../view/stylesmap'; | ||
@@ -326,2 +328,3 @@ const ELEMENT_RANGE_START_TOKEN = '['; | ||
* `{` and `}` and the selection outside the ext using `[` and `]`. When set to `true`, both should be marked with `[` and `]` only. | ||
* @param {module:engine/view/stylesmap~StylesProcessor} [options.stylesProcessor] Styles processor. | ||
* @returns {module:engine/view/text~Text|module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment|Object} | ||
@@ -332,2 +335,4 @@ * Returns the parsed view node or an object with two fields: `view` and `selection` when selection ranges were included in the data | ||
export function parse( data, options = {} ) { | ||
const viewDocument = new ViewDocument( new StylesProcessor() ); | ||
options.order = options.order || []; | ||
@@ -337,3 +342,3 @@ const rangeParser = new RangeParser( { | ||
} ); | ||
const processor = new XmlDataProcessor( { | ||
const processor = new XmlDataProcessor( viewDocument, { | ||
namespaces: Object.keys( allowedTypes ) | ||
@@ -935,4 +940,7 @@ } ); | ||
// Convert element or leave document fragment. | ||
const convertedElement = rootNode.is( 'documentFragment' ) ? new ViewDocumentFragment() : _convertElement( rootNode ); | ||
const convertedElement = rootNode.is( 'documentFragment' ) ? | ||
new ViewDocumentFragment( rootNode.document ) : | ||
_convertElement( rootNode.document, rootNode ); | ||
// Convert all child nodes. | ||
@@ -982,6 +990,6 @@ // Cache the nodes in array. Otherwise, we would skip some nodes because during iteration we move nodes | ||
// element converted according to its name. | ||
function _convertElement( viewElement ) { | ||
function _convertElement( viewDocument, viewElement ) { | ||
const info = _convertElementNameAndInfo( viewElement ); | ||
const ElementConstructor = allowedTypes[ info.type ]; | ||
const newElement = ElementConstructor ? new ElementConstructor( info.name ) : new ViewElement( info.name ); | ||
const newElement = ElementConstructor ? new ElementConstructor( viewDocument, info.name ) : new ViewElement( viewDocument, info.name ); | ||
@@ -988,0 +996,0 @@ if ( newElement.is( 'attributeElement' ) ) { |
@@ -62,3 +62,2 @@ /** | ||
* | ||
* @readonly | ||
* @type {Number} | ||
@@ -65,0 +64,0 @@ */ |
@@ -337,3 +337,3 @@ /** | ||
* // if you have not overridden the default one (which is the HtmlDataProcessor instance). | ||
* const htmlDP = new HtmlDataProcessor(); | ||
* const htmlDP = new HtmlDataProcessor( viewDocument ); | ||
* | ||
@@ -442,2 +442,6 @@ * // Convert an HTML string to a view document fragment: | ||
* `[<image src="foo.jpg"></image>]` -> `<paragraph>[]</paragraph>`. | ||
* | ||
* @param {'forward'|'backward'} [options.direction='backward'] The direction in which the content is being consumed. | ||
* Deleting backward corresponds to using the <kbd>Backspace</kbd> key, while deleting content forward corresponds to | ||
* the <kbd>Shift</kbd>+<kbd>Backspace</kbd> keystroke. | ||
*/ | ||
@@ -444,0 +448,0 @@ deleteContent( selection, options ) { |
@@ -192,16 +192,8 @@ /** | ||
/** | ||
* {@link module:engine/model/document~Document Document} that owns this node or `null` if the node has no parent or is inside | ||
* a {@link module:engine/model/documentfragment~DocumentFragment DocumentFragment}. | ||
* Returns true if the node is in a tree rooted in the document (is a descendant of one of its roots). | ||
* | ||
* @readonly | ||
* @type {module:engine/model/document~Document|null} | ||
* @returns {Boolean} | ||
*/ | ||
get document() { | ||
// This is a top element of a sub-tree. | ||
if ( this.root == this ) { | ||
return null; | ||
} | ||
// Root may be `DocumentFragment` which does not have document property. | ||
return this.root.document || null; | ||
isAttached() { | ||
return this.root.is( 'rootElement' ); | ||
} | ||
@@ -208,0 +200,0 @@ |
@@ -505,2 +505,24 @@ /** | ||
/** | ||
* Returns an {@link module:engine/model/element~Element Element} contained by the range. | ||
* The element will be returned when it is the **only** node within the range and **fully–contained** | ||
* at the same time. | ||
* | ||
* @returns {module:engine/model/element~Element|null} | ||
*/ | ||
getContainedElement() { | ||
if ( this.isCollapsed ) { | ||
return null; | ||
} | ||
const nodeAfterStart = this.start.nodeAfter; | ||
const nodeBeforeEnd = this.end.nodeBefore; | ||
if ( nodeAfterStart && nodeAfterStart.is( 'element' ) && nodeAfterStart === nodeBeforeEnd ) { | ||
return nodeAfterStart; | ||
} | ||
return null; | ||
} | ||
/** | ||
* Converts `Range` to plain object and returns it. | ||
@@ -507,0 +529,0 @@ * |
@@ -20,3 +20,3 @@ /** | ||
* | ||
* @param {module:engine/model/document~Document} doc Document that is an owner of this root. | ||
* @param {module:engine/model/document~Document} document Document that is an owner of this root. | ||
* @param {String} name Node name. | ||
@@ -26,3 +26,3 @@ * @param {String} [rootName='main'] Unique root name used to identify this root | ||
*/ | ||
constructor( doc, name, rootName = 'main' ) { | ||
constructor( document, name, rootName = 'main' ) { | ||
super( name ); | ||
@@ -36,3 +36,3 @@ | ||
*/ | ||
this._doc = doc; | ||
this._document = document; | ||
@@ -51,4 +51,2 @@ /** | ||
* | ||
* In contrary, to {@link module:engine/model/node~Node node}, root element always have a `document`. | ||
* | ||
* @readonly | ||
@@ -58,3 +56,3 @@ * @type {module:engine/model/document~Document|null} | ||
get document() { | ||
return this._doc; | ||
return this._document; | ||
} | ||
@@ -61,0 +59,0 @@ |
@@ -675,8 +675,18 @@ /** | ||
// Never leave a limit element. | ||
const limitElement = position.getAncestors().reverse().find( item => this.isLimit( item ) ) || position.root; | ||
if ( direction == 'both' || direction == 'backward' ) { | ||
backwardWalker = new TreeWalker( { startPosition: position, direction: 'backward' } ); | ||
backwardWalker = new TreeWalker( { | ||
boundaries: Range._createIn( limitElement ), | ||
startPosition: position, | ||
direction: 'backward' | ||
} ); | ||
} | ||
if ( direction == 'both' || direction == 'forward' ) { | ||
forwardWalker = new TreeWalker( { startPosition: position } ); | ||
forwardWalker = new TreeWalker( { | ||
boundaries: Range._createIn( limitElement ), | ||
startPosition: position | ||
} ); | ||
} | ||
@@ -683,0 +693,0 @@ |
@@ -11,3 +11,2 @@ /** | ||
import Position from './position'; | ||
import Element from './element'; | ||
import Node from './node'; | ||
@@ -619,7 +618,3 @@ import Range from './range'; | ||
const range = this.getFirstRange(); | ||
const nodeAfterStart = range.start.nodeAfter; | ||
const nodeBeforeEnd = range.end.nodeBefore; | ||
return ( nodeAfterStart instanceof Element && nodeAfterStart == nodeBeforeEnd ) ? nodeAfterStart : null; | ||
return this.getFirstRange().getContainedElement(); | ||
} | ||
@@ -834,3 +829,3 @@ | ||
return element.document.model.schema.isBlock( element ) && element.parent; | ||
return element.root.document.model.schema.isBlock( element ) && element.parent; | ||
} | ||
@@ -847,3 +842,4 @@ | ||
function getParentBlock( position, visited ) { | ||
const schema = position.parent.document.model.schema; | ||
const element = position.parent; | ||
const schema = element.root.document.model.schema; | ||
@@ -894,3 +890,3 @@ const ancestors = position.parent.getAncestors( { parentFirst: true, includeSelf: true } ); | ||
function findAncestorBlock( node ) { | ||
const schema = node.document.model.schema; | ||
const schema = node.root.document.model.schema; | ||
@@ -897,0 +893,0 @@ let parent = node.parent; |
@@ -167,13 +167,2 @@ /** | ||
/** | ||
* {@link module:engine/model/document~Document Document} that owns text node represented by this text proxy or `null` if the text node | ||
* has no parent or is inside a {@link module:engine/model/documentfragment~DocumentFragment DocumentFragment}. | ||
* | ||
* @readonly | ||
* @type {module:engine/model/document~Document|null} | ||
*/ | ||
get document() { | ||
return this.textNode.document; | ||
} | ||
/** | ||
* Checks whether this object is of the given. | ||
@@ -180,0 +169,0 @@ * |
@@ -51,4 +51,7 @@ /** | ||
* * `<paragraph>x</paragraph><paragraph>[]</paragraph>` with the option disabled (`doNotAutoparagraph == false`) | ||
* * `<paragraph>x[]</paragraph>` with the option enabled (`doNotAutoparagraph == true`). | ||
* * `<paragraph>x</paragraph>[]` with the option enabled (`doNotAutoparagraph == true`). | ||
* | ||
* If you use this option you need to make sure to handle invalid selections yourself or leave | ||
* them to the selection post-fixer (may not always work). | ||
* | ||
* **Note:** if there is no valid position for the selection, the paragraph will always be created: | ||
@@ -113,12 +116,5 @@ * | ||
// Check if a text is allowed in the new container. If not, try to create a new paragraph (if it's allowed here). | ||
if ( shouldAutoparagraph( schema, startPos ) ) { | ||
// If auto-paragraphing is off, find the closest valid selection range and collapse the selection there. | ||
// If there is no valid selection range, create paragraph anyway and set selection there. | ||
const validSelectionRange = schema.getNearestSelectionRange( startPos ); | ||
if ( options.doNotAutoparagraph && validSelectionRange ) { | ||
collapseSelectionAt( writer, selection, validSelectionRange ); | ||
} else { | ||
insertParagraph( writer, startPos, selection ); | ||
} | ||
// If autoparagraphing is off, we assume that you know what you do so we leave the selection wherever it was. | ||
if ( !options.doNotAutoparagraph && shouldAutoparagraph( schema, startPos ) ) { | ||
insertParagraph( writer, startPos, selection ); | ||
} | ||
@@ -125,0 +121,0 @@ |
@@ -53,4 +53,2 @@ /** | ||
const insertionPosition = selection.getFirstPosition(); | ||
if ( !selection.isCollapsed ) { | ||
@@ -60,3 +58,3 @@ model.deleteContent( selection, { doNotAutoparagraph: true } ); | ||
const insertion = new Insertion( model, writer, insertionPosition ); | ||
const insertion = new Insertion( model, writer, selection.anchor ); | ||
@@ -94,3 +92,3 @@ let nodesToInsert; | ||
const affectedRange = insertion.getAffectedRange() || model.createRange( insertionPosition ); | ||
const affectedRange = insertion.getAffectedRange() || model.createRange( selection.anchor ); | ||
@@ -97,0 +95,0 @@ insertion.destroy(); |
@@ -1133,3 +1133,3 @@ /** | ||
* const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ]; | ||
* writer.setSelection( range ); | ||
* writer.setSelection( ranges ); | ||
* | ||
@@ -1136,0 +1136,0 @@ * // Sets selection to other selection. |
@@ -36,5 +36,10 @@ /** | ||
* @protected | ||
* @param {module:engine/view/document~Document} document The document instance to which this element belongs. | ||
* @param {String} name Node name. | ||
* @param {Object|Iterable} [attrs] Collection of attributes. | ||
* @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children] | ||
* A list of nodes to be inserted into created element. | ||
*/ | ||
constructor( name, attrs, children ) { | ||
super( name, attrs, children ); | ||
constructor( document, name, attrs, children ) { | ||
super( document, name, attrs, children ); | ||
@@ -41,0 +46,0 @@ /** |
@@ -40,5 +40,10 @@ /** | ||
* @protected | ||
* @param {module:engine/view/document~Document} document The document instance to which this element belongs. | ||
* @param {String} name Node name. | ||
* @param {Object|Iterable} [attrs] Collection of attributes. | ||
* @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children] | ||
* A list of nodes to be inserted into created element. | ||
*/ | ||
constructor( name, attrs, children ) { | ||
super( name, attrs, children ); | ||
constructor( document, name, attrs, children ) { | ||
super( document, name, attrs, children ); | ||
@@ -45,0 +50,0 @@ /** |
@@ -14,3 +14,2 @@ /** | ||
import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin'; | ||
import StylesMap from './stylesmap'; | ||
@@ -28,4 +27,6 @@ // @if CK_DEBUG_ENGINE // const { logDocument } = require( '../dev-utils/utils' ); | ||
* Creates a Document instance. | ||
* | ||
* @param {module:engine/view/stylesmap~StylesProcessor} stylesProcessor The styles processor instance. | ||
*/ | ||
constructor() { | ||
constructor( stylesProcessor ) { | ||
/** | ||
@@ -53,2 +54,10 @@ * Selection done on this document. | ||
/** | ||
* The styles processor instance used by this document when normalizing styles. | ||
* | ||
* @readonly | ||
* @member {module:engine/view/stylesmap~StylesProcessor} | ||
*/ | ||
this.stylesProcessor = stylesProcessor; | ||
/** | ||
* Defines whether document is in read-only mode. | ||
@@ -168,18 +177,2 @@ * | ||
/** | ||
* Adds a style processor normalization rules. | ||
* | ||
* The available style processors: | ||
* | ||
* * background: {@link module:engine/view/styles/background~addBackgroundRules} | ||
* * border: {@link module:engine/view/styles/border~addBorderRules} | ||
* * margin: {@link module:engine/view/styles/margin~addMarginRules} | ||
* * padding: {@link module:engine/view/styles/padding~addPaddingRules} | ||
* | ||
* @param {Function} callback | ||
*/ | ||
addStyleProcessorRules( callback ) { | ||
callback( StylesMap._styleProcessor ); | ||
} | ||
/** | ||
* Performs post-fixer loops. Executes post-fixer callbacks as long as none of them has done any changes to the model. | ||
@@ -186,0 +179,0 @@ * |
@@ -28,7 +28,16 @@ /** | ||
* @protected | ||
* @param {module:engine/view/document~Document} document The document to which this document fragment belongs. | ||
* @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children] | ||
* A list of nodes to be inserted into the created document fragment. | ||
*/ | ||
constructor( children ) { | ||
constructor( document, children ) { | ||
/** | ||
* The document to which this document fragment belongs. | ||
* | ||
* @readonly | ||
* @member {module:engine/view/document~Document} | ||
*/ | ||
this.document = document; | ||
/** | ||
* Array of child nodes. | ||
@@ -168,3 +177,3 @@ * | ||
const nodes = normalize( items ); | ||
const nodes = normalize( this.document, items ); | ||
@@ -243,6 +252,6 @@ for ( const node of nodes ) { | ||
// @returns {Iterable.<module:engine/view/node~Node>} | ||
function normalize( nodes ) { | ||
function normalize( document, nodes ) { | ||
// Separate condition because string is iterable. | ||
if ( typeof nodes == 'string' ) { | ||
return [ new Text( nodes ) ]; | ||
return [ new Text( document, nodes ) ]; | ||
} | ||
@@ -258,7 +267,7 @@ | ||
if ( typeof node == 'string' ) { | ||
return new Text( node ); | ||
return new Text( document, node ); | ||
} | ||
if ( node instanceof TextProxy ) { | ||
return new Text( node.data ); | ||
return new Text( document, node.data ); | ||
} | ||
@@ -265,0 +274,0 @@ |
@@ -47,7 +47,14 @@ /** | ||
* | ||
* @param {module:engine/view/document~Document} document The view document instance. | ||
* @param {Object} options Object with configuration options. | ||
* @param {module:engine/view/filler~BlockFillerMode} [options.blockFillerMode='br'] The type of the block filler to use. | ||
*/ | ||
constructor( options = {} ) { | ||
constructor( document, options = {} ) { | ||
/** | ||
* @readonly | ||
* @type {module:engine/view/document~Document} | ||
*/ | ||
this.document = document; | ||
/** | ||
* The mode of a block filler used by DOM converter. | ||
@@ -403,3 +410,3 @@ * | ||
return textData === '' ? null : new ViewText( textData ); | ||
return textData === '' ? null : new ViewText( this.document, textData ); | ||
} | ||
@@ -417,3 +424,3 @@ } else if ( this.isComment( domNode ) ) { | ||
// Create view document fragment. | ||
viewElement = new ViewDocumentFragment(); | ||
viewElement = new ViewDocumentFragment( this.document ); | ||
@@ -426,3 +433,3 @@ if ( options.bind ) { | ||
const viewName = options.keepOriginalCase ? domNode.tagName : domNode.tagName.toLowerCase(); | ||
viewElement = new ViewElement( viewName ); | ||
viewElement = new ViewElement( this.document, viewName ); | ||
@@ -807,3 +814,3 @@ if ( options.bind ) { | ||
* | ||
* const converter = new DomConverter( { blockFillerMode: 'br' } ); | ||
* const converter = new DomConverter( viewDocument, { blockFillerMode: 'br' } ); | ||
* | ||
@@ -810,0 +817,0 @@ * converter.isBlockFiller( BR_FILLER( document ) ); // true |
@@ -11,8 +11,5 @@ /** | ||
import ContainerElement from './containerelement'; | ||
import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; | ||
import mix from '@ckeditor/ckeditor5-utils/src/mix'; | ||
import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin'; | ||
const documentSymbol = Symbol( 'document' ); | ||
/** | ||
@@ -37,4 +34,4 @@ * Editable element which can be a {@link module:engine/view/rooteditableelement~RootEditableElement root} | ||
*/ | ||
constructor( name, attrs, children ) { | ||
super( name, attrs, children ); | ||
constructor( document, name, attrs, children ) { | ||
super( document, name, attrs, children ); | ||
@@ -61,10 +58,14 @@ /** | ||
/** | ||
* The {@link module:engine/view/document~Document} which is an owner of this root. | ||
* Can only by set once. | ||
* Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-editableelement-document-already-set` | ||
* when document is already set. | ||
* | ||
* @member {module:engine/view/document~Document} #document | ||
*/ | ||
this.bind( 'isReadOnly' ).to( document ); | ||
this.bind( 'isFocused' ).to( | ||
document, | ||
'isFocused', | ||
isFocused => isFocused && document.selection.editableElement == this | ||
); | ||
// Update focus state based on selection changes. | ||
this.listenTo( document.selection, 'change', () => { | ||
this.isFocused = document.isFocused && document.selection.editableElement == this; | ||
} ); | ||
} | ||
@@ -111,46 +112,4 @@ | ||
} | ||
/** | ||
* Returns document associated with the editable. | ||
* | ||
* @readonly | ||
* @returns {module:engine/view/document~Document} | ||
*/ | ||
get document() { | ||
return this.getCustomProperty( documentSymbol ); | ||
} | ||
/** | ||
* Sets document of this editable element. | ||
* | ||
* @protected | ||
* @param {module:engine/view/document~Document} document | ||
*/ | ||
set _document( document ) { | ||
if ( this.getCustomProperty( documentSymbol ) ) { | ||
/** | ||
* View document is already set. It can only be set once. | ||
* | ||
* @error view-editableelement-document-already-set | ||
*/ | ||
throw new CKEditorError( 'view-editableelement-document-already-set: View document is already set.', this ); | ||
} | ||
this._setCustomProperty( documentSymbol, document ); | ||
this.bind( 'isReadOnly' ).to( document ); | ||
this.bind( 'isFocused' ).to( | ||
document, | ||
'isFocused', | ||
isFocused => isFocused && document.selection.editableElement == this | ||
); | ||
// Update focus state based on selection changes. | ||
this.listenTo( document.selection, 'change', () => { | ||
this.isFocused = document.isFocused && document.selection.editableElement == this; | ||
} ); | ||
} | ||
} | ||
mix( EditableElement, ObservableMixin ); |
@@ -51,7 +51,8 @@ /** | ||
* | ||
* new Element( 'div', { class: 'editor', contentEditable: 'true' } ); // object | ||
* new Element( 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator | ||
* new Element( 'div', mapOfAttributes ); // map | ||
* new Element( viewDocument, 'div', { class: 'editor', contentEditable: 'true' } ); // object | ||
* new Element( viewDocument, 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator | ||
* new Element( viewDocument, 'div', mapOfAttributes ); // map | ||
* | ||
* @protected | ||
* @param {module:engine/view/document~Document} document The document instance to which this element belongs. | ||
* @param {String} name Node name. | ||
@@ -62,4 +63,4 @@ * @param {Object|Iterable} [attrs] Collection of attributes. | ||
*/ | ||
constructor( name, attrs, children ) { | ||
super(); | ||
constructor( document, name, attrs, children ) { | ||
super( document ); | ||
@@ -115,3 +116,3 @@ /** | ||
*/ | ||
this._styles = new StylesMap(); | ||
this._styles = new StylesMap( this.document.stylesProcessor ); | ||
@@ -386,3 +387,3 @@ if ( this._attrs.has( 'style' ) ) { | ||
* **Note**: This method can work with normalized style names if | ||
* {@link module:engine/view/document~Document#addStyleProcessorRules a particular style processor rule is enabled}. | ||
* {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}. | ||
* See {@link module:engine/view/stylesmap~StylesMap#getAsString `StylesMap#getAsString()`} for details. | ||
@@ -393,3 +394,3 @@ * | ||
* // Enable 'margin' shorthand processing: | ||
* editor.editing.view.document.addStyleProcessorRules( addMarginRules ); | ||
* editor.data.addStyleProcessorRules( addMarginRules ); | ||
* | ||
@@ -436,3 +437,3 @@ * const element = view.change( writer => { | ||
* **Note**: This method will return normalized values only if | ||
* {@link module:engine/view/document~Document#addStyleProcessorRules a particular style processor rule is enabled}. | ||
* {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}. | ||
* See {@link module:engine/view/stylesmap~StylesMap#getNormalized `StylesMap#getNormalized()`} for details. | ||
@@ -572,3 +573,3 @@ * | ||
// ContainerElement and AttributeElement should be also cloned properly. | ||
const cloned = new this.constructor( this.name, this._attrs, childrenClone ); | ||
const cloned = new this.constructor( this.document, this.name, this._attrs, childrenClone ); | ||
@@ -620,3 +621,3 @@ // Classes and styles are cloned separately - this solution is faster than adding them back to attributes and | ||
const nodes = normalize( items ); | ||
const nodes = normalize( this.document, items ); | ||
@@ -630,2 +631,3 @@ for ( const node of nodes ) { | ||
node.parent = this; | ||
node.document = this.document; | ||
@@ -767,3 +769,3 @@ this._children.splice( index, 0, node ); | ||
* **Note**: This method can work with normalized style names if | ||
* {@link module:engine/view/document~Document#addStyleProcessorRules a particular style processor rule is enabled}. | ||
* {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}. | ||
* See {@link module:engine/view/stylesmap~StylesMap#set `StylesMap#set()`} for details. | ||
@@ -790,3 +792,3 @@ * | ||
* **Note**: This method can work with normalized style names if | ||
* {@link module:engine/view/document~Document#addStyleProcessorRules a particular style processor rule is enabled}. | ||
* {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}. | ||
* See {@link module:engine/view/stylesmap~StylesMap#remove `StylesMap#remove()`} for details. | ||
@@ -900,6 +902,6 @@ * | ||
// @returns {Iterable.<module:engine/view/node~Node>} | ||
function normalize( nodes ) { | ||
function normalize( document, nodes ) { | ||
// Separate condition because string is iterable. | ||
if ( typeof nodes == 'string' ) { | ||
return [ new Text( nodes ) ]; | ||
return [ new Text( document, nodes ) ]; | ||
} | ||
@@ -915,7 +917,7 @@ | ||
if ( typeof node == 'string' ) { | ||
return new Text( node ); | ||
return new Text( document, node ); | ||
} | ||
if ( node instanceof TextProxy ) { | ||
return new Text( node.data ); | ||
return new Text( document, node.data ); | ||
} | ||
@@ -922,0 +924,0 @@ |
@@ -31,7 +31,10 @@ /** | ||
* @protected | ||
* @param {module:engine/view/document~Document} document The document instance to which this element belongs. | ||
* @param {String} name Node name. | ||
* @param {Object|Iterable} [attributes] Collection of attributes. | ||
* @param {Object|Iterable} [attrs] Collection of attributes. | ||
* @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children] | ||
* A list of nodes to be inserted into created element. | ||
*/ | ||
constructor( name, attributes, children ) { | ||
super( name, attributes, children ); | ||
constructor( document, name, attrs, children ) { | ||
super( document, name, attrs, children ); | ||
@@ -38,0 +41,0 @@ /** |
@@ -20,7 +20,7 @@ /** | ||
/** | ||
* Abstract tree view node class. | ||
* Abstract view node class. | ||
* | ||
* This is an abstract class. Its constructor should not be used directly. | ||
* Use the {@link module:engine/view/element~Element} class to create view elements | ||
* or {@link module:engine/view/text~Text} class to create view text nodes. | ||
* Use the {@link module:engine/view/downcastwriter~DowncastWriter} or {@link module:engine/view/upcastwriter~UpcastWriter} | ||
* to create new instances of view nodes. | ||
* | ||
@@ -32,5 +32,16 @@ * @abstract | ||
* Creates a tree view node. | ||
* | ||
* @protected | ||
* @param {module:engine/view/document~Document} document The document instance to which this node belongs. | ||
*/ | ||
constructor() { | ||
constructor( document ) { | ||
/** | ||
* The document instance to which this node belongs. | ||
* | ||
* @readonly | ||
* @member {module:engine/view/document~Document} | ||
*/ | ||
this.document = document; | ||
/** | ||
* Parent element. Null by default. Set by {@link module:engine/view/element~Element#_insertChild}. | ||
@@ -114,15 +125,8 @@ * | ||
/** | ||
* {@link module:engine/view/document~Document View document} that owns this node, or `null` if the node is inside | ||
* {@link module:engine/view/documentfragment~DocumentFragment document fragment}. | ||
* Returns true if the node is in a tree rooted in the document (is a descendant of one of its roots). | ||
* | ||
* @readonly | ||
* @type {module:engine/view/document~Document|null} | ||
* @returns {Boolean} | ||
*/ | ||
get document() { | ||
// Parent might be Node, null or DocumentFragment. | ||
if ( this.parent instanceof Node ) { | ||
return this.parent.document; | ||
} else { | ||
return null; | ||
} | ||
isAttached() { | ||
return this.root.is( 'rootElement' ); | ||
} | ||
@@ -129,0 +133,0 @@ |
@@ -147,6 +147,3 @@ /** | ||
export function needsPlaceholder( element ) { | ||
const doc = element.document; | ||
// The element was removed from document. | ||
if ( !doc ) { | ||
if ( !element.isAttached() ) { | ||
return false; | ||
@@ -159,2 +156,4 @@ } | ||
const doc = element.document; | ||
// If the element is empty and the document is blurred. | ||
@@ -206,2 +205,3 @@ if ( !doc.isFocused && isEmptyish ) { | ||
const { text, isDirectHost } = config; | ||
const hostElement = isDirectHost ? element : getChildPlaceholderHostSubstitute( element ); | ||
@@ -208,0 +208,0 @@ let wasViewModified = false; |
@@ -339,2 +339,41 @@ /** | ||
/** | ||
* Returns an {@link module:engine/view/element~Element Element} contained by the range. | ||
* The element will be returned when it is the **only** node within the range and **fully–contained** | ||
* at the same time. | ||
* | ||
* @returns {module:engine/view/element~Element|null} | ||
*/ | ||
getContainedElement() { | ||
if ( this.isCollapsed ) { | ||
return null; | ||
} | ||
let nodeAfterStart = this.start.nodeAfter; | ||
let nodeBeforeEnd = this.end.nodeBefore; | ||
// Handle the situation when the range position is at the beginning / at the end of a text node. | ||
// In such situation `.nodeAfter` and `.nodeBefore` are `null` but the range still might be spanning | ||
// over one element. | ||
// | ||
// <p>Foo{<span class="widget"></span>}bar</p> vs <p>Foo[<span class="widget"></span>]bar</p> | ||
// | ||
// These are basically the same range, only the difference is if the range position is at | ||
// at the end/at the beginning of a text node or just before/just after the text node. | ||
// | ||
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 ) { | ||
nodeBeforeEnd = this.end.parent.previousSibling; | ||
} | ||
if ( nodeAfterStart && nodeAfterStart.is( 'element' ) && nodeAfterStart === nodeBeforeEnd ) { | ||
return nodeAfterStart; | ||
} | ||
return null; | ||
} | ||
/** | ||
* Clones this range. | ||
@@ -341,0 +380,0 @@ * |
@@ -551,11 +551,26 @@ /** | ||
// Handle deletions first. | ||
// This is to prevent a situation where an element that already exists in `actualDomChildren` is inserted at a different | ||
// index in `actualDomChildren`. Since `actualDomChildren` is a `NodeList`, this works like move, not like an insert, | ||
// and it disrupts the whole algorithm. See https://github.com/ckeditor/ckeditor5/issues/6367. | ||
// | ||
// It doesn't matter in what order we remove or add nodes, as long as we remove and add correct nodes at correct indexes. | ||
for ( const action of diff ) { | ||
if ( action === 'delete' ) { | ||
nodesToUnbind.add( actualDomChildren[ i ] ); | ||
remove( actualDomChildren[ i ] ); | ||
} else if ( action === 'equal' ) { | ||
i++; | ||
} | ||
} | ||
i = 0; | ||
for ( const action of diff ) { | ||
if ( action === 'insert' ) { | ||
insertAt( domElement, i, expectedDomChildren[ i ] ); | ||
i++; | ||
} else if ( action === 'delete' ) { | ||
nodesToUnbind.add( actualDomChildren[ i ] ); | ||
remove( actualDomChildren[ i ] ); | ||
} else { // 'equal' | ||
} else if ( action === 'equal' ) { | ||
// Force updating text nodes inside elements which did not change and do not need to be re-rendered (#1125). | ||
// Do it here (not in the loop above) because only after insertions the `i` index is correct. | ||
this._markDescendantTextToSync( this.domConverter.domToView( expectedDomChildren[ i ] ) ); | ||
@@ -562,0 +577,0 @@ i++; |
@@ -25,6 +25,7 @@ /** | ||
* | ||
* @param {module:engine/view/document~Document} document The document instance to which this element belongs. | ||
* @param {String} name Node name. | ||
*/ | ||
constructor( name ) { | ||
super( name ); | ||
constructor( document, name ) { | ||
super( document, name ); | ||
@@ -31,0 +32,0 @@ /** |
@@ -16,3 +16,2 @@ /** | ||
import Node from './node'; | ||
import Element from './element'; | ||
import count from '@ckeditor/ckeditor5-utils/src/count'; | ||
@@ -417,25 +416,3 @@ import isIterable from '@ckeditor/ckeditor5-utils/src/isiterable'; | ||
const range = this.getFirstRange(); | ||
let nodeAfterStart = range.start.nodeAfter; | ||
let nodeBeforeEnd = range.end.nodeBefore; | ||
// Handle the situation when selection position is at the beginning / at the end of a text node. | ||
// In such situation `.nodeAfter` and `.nodeBefore` are `null` but the selection still might be spanning | ||
// over one element. | ||
// | ||
// <p>Foo{<span class="widget"></span>}bar</p> vs <p>Foo[<span class="widget"></span>]bar</p> | ||
// | ||
// These are basically the same selections, only the difference is if the selection position is at | ||
// at the end/at the beginning of a text node or just before/just after the text node. | ||
// | ||
if ( range.start.parent.is( 'text' ) && range.start.isAtEnd && range.start.parent.nextSibling ) { | ||
nodeAfterStart = range.start.parent.nextSibling; | ||
} | ||
if ( range.end.parent.is( 'text' ) && range.end.isAtStart && range.end.parent.previousSibling ) { | ||
nodeBeforeEnd = range.end.parent.previousSibling; | ||
} | ||
return ( nodeAfterStart instanceof Element && nodeAfterStart == nodeBeforeEnd ) ? nodeAfterStart : null; | ||
return this.getFirstRange().getContainedElement(); | ||
} | ||
@@ -442,0 +419,0 @@ |
@@ -15,3 +15,3 @@ /** | ||
* | ||
* editor.editing.view.document.addStyleProcessorRules( addBackgroundRules ); | ||
* editor.data.addStyleProcessorRules( addBackgroundRules ); | ||
* | ||
@@ -18,0 +18,0 @@ * The normalized value is stored as: |
@@ -15,3 +15,3 @@ /** | ||
* | ||
* editor.editing.view.document.addStyleProcessorRules( addBorderRules ); | ||
* editor.data.addStyleProcessorRules( addBorderRules ); | ||
* | ||
@@ -18,0 +18,0 @@ * This rules merges all [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border) styles notation shorthands: |
@@ -15,3 +15,3 @@ /** | ||
* | ||
* editor.editing.view.document.addStyleProcessorRules( addMarginRules ); | ||
* editor.data.addStyleProcessorRules( addMarginRules ); | ||
* | ||
@@ -18,0 +18,0 @@ * The normalized value is stored as: |
@@ -15,3 +15,3 @@ /** | ||
* | ||
* editor.editing.view.document.addStyleProcessorRules( addPaddingRules ); | ||
* editor.data.addStyleProcessorRules( addPaddingRules ); | ||
* | ||
@@ -18,0 +18,0 @@ * The normalized value is stored as: |
@@ -20,4 +20,6 @@ /** | ||
* Creates Styles instance. | ||
* | ||
* @param {module:engine/view/stylesmap~StylesProcessor} styleProcessor | ||
*/ | ||
constructor() { | ||
constructor( styleProcessor ) { | ||
/** | ||
@@ -29,16 +31,14 @@ * Keeps an internal representation of styles map. Normalized styles are kept as object tree to allow unified modification and | ||
* | ||
* @private | ||
* @type {Object} | ||
* @private | ||
*/ | ||
this._styles = {}; | ||
// Hide _styleProcessor from the watchdog by making this property non-enumarable. Watchdog checks errors for their editor origin | ||
// by checking if two objects are connected through properties. Using singleton is against this check as it would detect | ||
// that two editors are connected through single style processor instance. | ||
Object.defineProperty( this, '_styleProcessor', { | ||
get() { | ||
return StylesMap._styleProcessor; | ||
}, | ||
enumerable: false | ||
} ); | ||
/** | ||
* An instance of the {@link module:engine/view/stylesmap~StylesProcessor}. | ||
* | ||
* @private | ||
* @member {module:engine/view/stylesmap~StylesProcessor} | ||
*/ | ||
this._styleProcessor = styleProcessor; | ||
} | ||
@@ -99,3 +99,3 @@ | ||
* // Enable 'margin' shorthand processing: | ||
* editor.editing.view.document.addStyleProcessorRules( addMarginRules ); | ||
* editor.data.addStyleProcessorRules( addMarginRules ); | ||
* | ||
@@ -145,7 +145,7 @@ * styles.setTo( 'margin:2px;' ); | ||
* | ||
* ***Note**:* This method uses {@link module:engine/view/document~Document#addStyleProcessorRules enabled style processor rules} | ||
* to normalize passed values. | ||
* ***Note**:* This method uses {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules | ||
* enabled style processor rules} to normalize passed values. | ||
* | ||
* // Enable 'margin' shorthand processing: | ||
* editor.editing.view.document.addStyleProcessorRules( addMarginRules ); | ||
* editor.data.addStyleProcessorRules( addMarginRules ); | ||
* | ||
@@ -199,7 +199,7 @@ * styles.set( 'margin', '2px' ); | ||
* | ||
* ***Note**:* This method uses {@link module:engine/view/document~Document#addStyleProcessorRules enabled style processor rules} | ||
* to normalize passed values. | ||
* ***Note**:* This method uses {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules | ||
* enabled style processor rules} to normalize passed values. | ||
* | ||
* // Enable 'margin' shorthand processing: | ||
* editor.editing.view.document.addStyleProcessorRules( addMarginRules ); | ||
* editor.data.addStyleProcessorRules( addMarginRules ); | ||
* | ||
@@ -228,3 +228,3 @@ * styles.setTo( 'margin:1px' ); | ||
* // Enable 'margin' shorthand processing: | ||
* editor.editing.view.document.addStyleProcessorRules( addMarginRules ); | ||
* editor.data.addStyleProcessorRules( addMarginRules ); | ||
* | ||
@@ -265,3 +265,3 @@ * const styles = new Styles(); | ||
* // Enable 'margin' shorthand processing: | ||
* editor.editing.view.document.addStyleProcessorRules( addMarginRules ); | ||
* editor.data.addStyleProcessorRules( addMarginRules ); | ||
* | ||
@@ -292,3 +292,3 @@ * styles.set( 'margin' , '1px' ); | ||
* // Enable 'margin' shorthand processing: | ||
* editor.editing.view.document.addStyleProcessorRules( addMarginRules ); | ||
* editor.data.addStyleProcessorRules( addMarginRules ); | ||
* | ||
@@ -383,24 +383,2 @@ * const styles = new Styles(); | ||
/** | ||
* Returns related style names. | ||
* | ||
* // Enable 'margin' shorthand processing: | ||
* editor.editing.view.document.addStyleProcessorRules( addMarginRules ); | ||
* | ||
* StylesMap.getRelatedStyles( 'margin' ); | ||
* // will return: [ 'margin-top', 'margin-right', 'margin-bottom', 'margin-left' ]; | ||
* | ||
* StylesMap.getRelatedStyles( 'margin-top' ); | ||
* // will return: [ 'margin' ]; | ||
* | ||
* **Note**: To define new style relations load an existing style processor (as shown above) or use | ||
* {@link module:engine/view/stylesmap~StylesProcessor#setStyleRelation `StylesProcessor.setStyleRelation()`}. | ||
* | ||
* @param {String} name | ||
* @returns {Array.<String>} | ||
*/ | ||
static getRelatedStyles( name ) { | ||
return this._styleProcessor.getRelatedStyles( name ); | ||
} | ||
/** | ||
* Returns normalized styles entries for further processing. | ||
@@ -451,28 +429,2 @@ * | ||
} | ||
/** | ||
* Returns global StylesProcessor instance. | ||
* | ||
* @returns {module:engine/view/stylesmap~StylesProcessor} | ||
* @private | ||
*/ | ||
static get _styleProcessor() { | ||
if ( !this._processor ) { | ||
this._processor = new StylesProcessor(); | ||
} | ||
return this._processor; | ||
} | ||
/** | ||
* Set new StylesProcessor instance. | ||
* | ||
* This is an internal method used mostly in tests. | ||
* | ||
* @param processor | ||
* @protected | ||
*/ | ||
static _setProcessor( processor ) { | ||
this._processor = processor; | ||
} | ||
} | ||
@@ -479,0 +431,0 @@ |
@@ -15,3 +15,3 @@ /** | ||
* | ||
* The constructor of this class shouldn't be used directly. To create new Text instances | ||
* The constructor of this class should not be used directly. To create a new text node instance | ||
* use the {@link module:engine/view/downcastwriter~DowncastWriter#createText `DowncastWriter#createText()`} | ||
@@ -29,6 +29,7 @@ * method when working on data downcasted from the model or the | ||
* @protected | ||
* @param {module:engine/view/document~Document} document The document instance to which this text node belongs. | ||
* @param {String} data The text's data. | ||
*/ | ||
constructor( data ) { | ||
super(); | ||
constructor( document, data ) { | ||
super( document ); | ||
@@ -130,3 +131,3 @@ /** | ||
_clone() { | ||
return new Text( this.data ); | ||
return new Text( this.document, this.data ); | ||
} | ||
@@ -133,0 +134,0 @@ |
@@ -44,7 +44,10 @@ /** | ||
* @protected | ||
* @param {module:engine/view/document~Document} document The document instance to which this element belongs. | ||
* @param {String} name Node name. | ||
* @param {Object|Iterable} [attributes] Collection of attributes. | ||
* @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children] | ||
* A list of nodes to be inserted into created element. | ||
*/ | ||
constructor( name, attributes, children ) { | ||
super( name, attributes, children ); | ||
constructor( document, name, attributes, children ) { | ||
super( document, name, attributes, children ); | ||
@@ -51,0 +54,0 @@ /** |
@@ -32,3 +32,3 @@ /** | ||
* | ||
* const writer = new UpcastWriter(); | ||
* const writer = new UpcastWriter( viewDocument ); | ||
* const text = writer.createText( 'foo!' ); | ||
@@ -40,2 +40,15 @@ * | ||
/** | ||
* @param {module:engine/view/document~Document} document The view document instance in which this upcast writer operates. | ||
*/ | ||
constructor( document ) { | ||
/** | ||
* The view document instance in which this upcast writer operates. | ||
* | ||
* @readonly | ||
* @type {module:engine/view/document~Document} | ||
*/ | ||
this.document = document; | ||
} | ||
/** | ||
* Creates a new {@link module:engine/view/documentfragment~DocumentFragment} instance. | ||
@@ -48,3 +61,3 @@ * | ||
createDocumentFragment( children ) { | ||
return new DocumentFragment( children ); | ||
return new DocumentFragment( this.document, children ); | ||
} | ||
@@ -68,3 +81,3 @@ | ||
createElement( name, attrs, children ) { | ||
return new Element( name, attrs, children ); | ||
return new Element( this.document, name, attrs, children ); | ||
} | ||
@@ -79,3 +92,3 @@ | ||
createText( data ) { | ||
return new Text( data ); | ||
return new Text( this.document, data ); | ||
} | ||
@@ -209,3 +222,3 @@ | ||
rename( newName, element ) { | ||
const newElement = new Element( newName, element.getAttributes(), element.getChildren() ); | ||
const newElement = new Element( this.document, newName, element.getAttributes(), element.getChildren() ); | ||
@@ -280,3 +293,3 @@ return this.replace( element, newElement ) ? newElement : null; | ||
* **Note**: This method can work with normalized style names if | ||
* {@link module:engine/view/document~Document#addStyleProcessorRules a particular style processor rule is enabled}. | ||
* {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}. | ||
* See {@link module:engine/view/stylesmap~StylesMap#set `StylesMap#set()`} for details. | ||
@@ -303,3 +316,3 @@ * | ||
* **Note**: This method can work with normalized style names if | ||
* {@link module:engine/view/document~Document#addStyleProcessorRules a particular style processor rule is enabled}. | ||
* {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}. | ||
* See {@link module:engine/view/stylesmap~StylesMap#remove `StylesMap#remove()`} for details. | ||
@@ -306,0 +319,0 @@ * |
@@ -65,3 +65,6 @@ /** | ||
export default class View { | ||
constructor() { | ||
/** | ||
* @param {module:engine/view/stylesmap~StylesProcessor} stylesProcessor The styles processor instance. | ||
*/ | ||
constructor( stylesProcessor ) { | ||
/** | ||
@@ -73,3 +76,3 @@ * Instance of the {@link module:engine/view/document~Document} associated with this view controller. | ||
*/ | ||
this.document = new Document(); | ||
this.document = new Document( stylesProcessor ); | ||
@@ -84,3 +87,3 @@ /** | ||
*/ | ||
this.domConverter = new DomConverter(); | ||
this.domConverter = new DomConverter( this.document ); | ||
@@ -87,0 +90,0 @@ /** |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1697178
38411
+ Added@ckeditor/ckeditor5-utils@18.0.0(transitive)
- Removed@ckeditor/ckeditor5-utils@17.0.0(transitive)