-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12647 from ckeditor/ck/12609-ts-paragraph
Other (paragraph): Rewrites ckeditor5-paragraph to TypeScript. Closes #12609.
- Loading branch information
Showing
14 changed files
with
366 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/** | ||
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved. | ||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license | ||
*/ | ||
|
||
/** | ||
* @module paragraph | ||
*/ | ||
|
||
export { default as Paragraph } from './paragraph'; | ||
export { default as ParagraphButtonUI } from './paragraphbuttonui'; |
73 changes: 73 additions & 0 deletions
73
packages/ckeditor5-paragraph/src/insertparagraphcommand.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/** | ||
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved. | ||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license | ||
*/ | ||
|
||
/** | ||
* @module paragraph/insertparagraphcommand | ||
*/ | ||
|
||
import Command from '@ckeditor/ckeditor5-core/src/command'; | ||
import type { Element, Position } from '@ckeditor/ckeditor5-engine'; | ||
|
||
/** | ||
* The insert paragraph command. It inserts a new paragraph at a specific | ||
* {@link module:engine/model/position~Position document position}. | ||
* | ||
* // Insert a new paragraph before an element in the document. | ||
* editor.execute( 'insertParagraph', { | ||
* position: editor.model.createPositionBefore( element ) | ||
* } ); | ||
* | ||
* If a paragraph is disallowed in the context of the specific position, the command | ||
* will attempt to split position ancestors to find a place where it is possible | ||
* to insert a paragraph. | ||
* | ||
* **Note**: This command moves the selection to the inserted paragraph. | ||
* | ||
* @extends module:core/command~Command | ||
*/ | ||
export default class InsertParagraphCommand extends Command { | ||
/** | ||
* Executes the command. | ||
* | ||
* @param {Object} options Options for the executed command. | ||
* @param {module:engine/model/position~Position} options.position The model position at which | ||
* the new paragraph will be inserted. | ||
* @param {Object} attributes Attributes keys and values to set on a inserted paragraph | ||
* @fires execute | ||
*/ | ||
public override execute( options: { | ||
position: Position; | ||
attributes: Record<string, unknown>; | ||
} ): void { | ||
const model = this.editor.model; | ||
const attributes = options.attributes; | ||
|
||
let position = options.position; | ||
|
||
model.change( writer => { | ||
const paragraph = writer.createElement( 'paragraph' ); | ||
|
||
if ( attributes ) { | ||
model.schema.setAllowedAttributes( paragraph, attributes, writer ); | ||
} | ||
|
||
if ( !model.schema.checkChild( position.parent as Element, paragraph ) ) { | ||
const allowedParent = model.schema.findAllowedParent( position, paragraph ); | ||
|
||
// It could be there's no ancestor limit that would allow paragraph. | ||
// In theory, "paragraph" could be disallowed even in the "$root". | ||
if ( !allowedParent ) { | ||
return; | ||
} | ||
|
||
position = writer.split( position, allowedParent ).position; | ||
} | ||
|
||
model.insertContent( paragraph, position ); | ||
|
||
writer.setSelection( paragraph, 'in' ); | ||
} ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
/** | ||
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved. | ||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license | ||
*/ | ||
|
||
/** | ||
* @module paragraph/paragraph | ||
*/ | ||
|
||
import ParagraphCommand from './paragraphcommand'; | ||
import InsertParagraphCommand from './insertparagraphcommand'; | ||
|
||
import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; | ||
|
||
/** | ||
* The paragraph feature for the editor. | ||
* | ||
* It introduces the `<paragraph>` element in the model which renders as a `<p>` element in the DOM and data. | ||
* | ||
* It also brings two editors commands: | ||
* | ||
* * The {@link module:paragraph/paragraphcommand~ParagraphCommand `'paragraph'`} command that converts all | ||
* blocks in the model selection into paragraphs. | ||
* * The {@link module:paragraph/insertparagraphcommand~InsertParagraphCommand `'insertParagraph'`} command | ||
* that inserts a new paragraph at a specified location in the model. | ||
* | ||
* @extends module:core/plugin~Plugin | ||
*/ | ||
export default class Paragraph extends Plugin { | ||
/** | ||
* @inheritDoc | ||
*/ | ||
public static get pluginName(): string { | ||
return 'Paragraph'; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public init(): void { | ||
const editor = this.editor; | ||
const model = editor.model; | ||
|
||
editor.commands.add( 'paragraph', new ParagraphCommand( editor ) ); | ||
editor.commands.add( 'insertParagraph', new InsertParagraphCommand( editor ) ); | ||
|
||
// Schema. | ||
model.schema.register( 'paragraph', { inheritAllFrom: '$block' } ); | ||
|
||
editor.conversion.elementToElement( { model: 'paragraph', view: 'p' } ); | ||
|
||
// Conversion for paragraph-like elements which has not been converted by any plugin. | ||
editor.conversion.for( 'upcast' ).elementToElement( { | ||
model: ( viewElement, { writer } ) => { | ||
if ( !Paragraph.paragraphLikeElements.has( viewElement.name ) ) { | ||
return null; | ||
} | ||
|
||
// Do not auto-paragraph empty elements. | ||
if ( viewElement.isEmpty ) { | ||
return null; | ||
} | ||
|
||
return writer.createElement( 'paragraph' ); | ||
}, | ||
view: /.+/, | ||
converterPriority: 'low' | ||
} ); | ||
} | ||
|
||
/** | ||
* A list of element names which should be treated by the autoparagraphing algorithms as | ||
* paragraph-like. This means that e.g. the following content: | ||
* | ||
* <h1>Foo</h1> | ||
* <table> | ||
* <tr> | ||
* <td>X</td> | ||
* <td> | ||
* <ul> | ||
* <li>Y</li> | ||
* <li>Z</li> | ||
* </ul> | ||
* </td> | ||
* </tr> | ||
* </table> | ||
* | ||
* contains five paragraph-like elements: `<h1>`, two `<td>`s and two `<li>`s. | ||
* Hence, if none of the features is going to convert those elements the above content will be automatically handled | ||
* by the paragraph feature and converted to: | ||
* | ||
* <p>Foo</p> | ||
* <p>X</p> | ||
* <p>Y</p> | ||
* <p>Z</p> | ||
* | ||
* Note: The `<td>` containing two `<li>` elements was ignored as the innermost paragraph-like elements | ||
* have a priority upon conversion. | ||
* | ||
* @member {Set.<String>} module:paragraph/paragraph~Paragraph.paragraphLikeElements | ||
*/ | ||
public static paragraphLikeElements = new Set( [ | ||
'blockquote', | ||
'dd', | ||
'div', | ||
'dt', | ||
'h1', | ||
'h2', | ||
'h3', | ||
'h4', | ||
'h5', | ||
'h6', | ||
'li', | ||
'p', | ||
'td', | ||
'th' | ||
] ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/** | ||
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved. | ||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license | ||
*/ | ||
|
||
/** | ||
* @module paragraph/paragraphbuttonui | ||
*/ | ||
|
||
import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; | ||
import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; | ||
import icon from '@ckeditor/ckeditor5-core/theme/icons/paragraph.svg'; | ||
import type ParagraphCommand from './paragraphcommand'; | ||
|
||
/** | ||
* This plugin defines the `'paragraph'` button. It can be used together with | ||
* {@link module:heading/headingbuttonsui~HeadingButtonsUI} to replace the standard heading dropdown. | ||
* | ||
* This plugin is not loaded automatically by the {@link module:paragraph/paragraph~Paragraph} plugin. It must | ||
* be added manually. | ||
* | ||
* ClassicEditor | ||
* .create( { | ||
* plugins: [ ..., Heading, Paragraph, HeadingButtonsUI, ParagraphButtonUI ] | ||
* toolbar: [ 'paragraph', 'heading1', 'heading2', 'heading3' ] | ||
* } ) | ||
* .then( ... ) | ||
* .catch( ... ); | ||
* | ||
* @extends module:core/plugin~Plugin | ||
*/ | ||
export default class ParagraphButtonUI extends Plugin { | ||
public init(): void { | ||
const editor = this.editor; | ||
const t = editor.t; | ||
|
||
editor.ui.componentFactory.add( 'paragraph', locale => { | ||
const view = new ButtonView( locale ); | ||
const command = editor.commands.get( 'paragraph' ) as ParagraphCommand; | ||
|
||
view.label = t( 'Paragraph' ); | ||
view.icon = icon; | ||
view.tooltip = true; | ||
view.isToggleable = true; | ||
view.bind( 'isEnabled' ).to( command ); | ||
view.bind( 'isOn' ).to( command, 'value' ); | ||
|
||
view.on( 'execute', () => { | ||
editor.execute( 'paragraph' ); | ||
} ); | ||
|
||
return view; | ||
} ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/** | ||
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved. | ||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license | ||
*/ | ||
|
||
/** | ||
* @module paragraph/paragraphcommand | ||
*/ | ||
|
||
import Command from '@ckeditor/ckeditor5-core/src/command'; | ||
import first from '@ckeditor/ckeditor5-utils/src/first'; | ||
|
||
import type { Schema, Selection, DocumentSelection, Element } from '@ckeditor/ckeditor5-engine'; | ||
|
||
/** | ||
* The paragraph command. | ||
* | ||
* @extends module:core/command~Command | ||
*/ | ||
export default class ParagraphCommand extends Command { | ||
/** | ||
* The value of the command. Indicates whether the selection start is placed in a paragraph. | ||
* | ||
* @readonly | ||
* @observable | ||
* @member {Boolean} #value | ||
*/ | ||
declare public value: boolean; | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public override refresh(): void { | ||
const model = this.editor.model; | ||
const document = model.document; | ||
const block = first( document.selection.getSelectedBlocks() ); | ||
|
||
this.value = !!block && block.is( 'element', 'paragraph' ); | ||
this.isEnabled = !!block && checkCanBecomeParagraph( block, model.schema ); | ||
} | ||
|
||
/** | ||
* Executes the command. All the blocks (see {@link module:engine/model/schema~Schema}) in the selection | ||
* will be turned to paragraphs. | ||
* | ||
* @fires execute | ||
* @param {Object} [options] Options for the executed command. | ||
* @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} [options.selection] | ||
* The selection that the command should be applied to. | ||
* By default, if not provided, the command is applied to the {@link module:engine/model/document~Document#selection}. | ||
*/ | ||
public override execute( options: { | ||
selection?: Selection | DocumentSelection; | ||
} = {} ): void { | ||
const model = this.editor.model; | ||
const document = model.document; | ||
|
||
model.change( writer => { | ||
const blocks = ( options.selection || document.selection ).getSelectedBlocks(); | ||
|
||
for ( const block of blocks ) { | ||
if ( !block.is( 'element', 'paragraph' ) && checkCanBecomeParagraph( block, model.schema ) ) { | ||
writer.rename( block, 'paragraph' ); | ||
} | ||
} | ||
} ); | ||
} | ||
} | ||
|
||
// Checks whether the given block can be replaced by a paragraph. | ||
// | ||
// @private | ||
// @param {module:engine/model/element~Element} block A block to be tested. | ||
// @param {module:engine/model/schema~Schema} schema The schema of the document. | ||
// @returns {Boolean} | ||
function checkCanBecomeParagraph( block: Element, schema: Schema ) { | ||
return schema.checkChild( block.parent as Element, 'paragraph' ) && !schema.isObject( block ); | ||
} |
Oops, something went wrong.