-
-
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 #13071 from ckeditor/ck/12998
Other (basic-styles): Rewritten ckeditor5-basic-styles package to TypeScript. Closes #12998.
- Loading branch information
Showing
50 changed files
with
1,449 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.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
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
133 changes: 133 additions & 0 deletions
133
packages/ckeditor5-basic-styles/src/attributecommand.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,133 @@ | ||
/** | ||
* @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 basic-styles/attributecommand | ||
*/ | ||
|
||
import { Command, type Editor } from 'ckeditor5/src/core'; | ||
|
||
/** | ||
* An extension of the base {@link module:core/command~Command} class, which provides utilities for a command | ||
* that toggles a single attribute on a text or an element. | ||
* | ||
* `AttributeCommand` uses {@link module:engine/model/document~Document#selection} | ||
* to decide which nodes (if any) should be changed, and applies or removes the attribute from them. | ||
* | ||
* The command checks the {@link module:engine/model/model~Model#schema} to decide if it can be enabled | ||
* for the current selection and to which nodes the attribute can be applied. | ||
*/ | ||
export default class AttributeCommand extends Command { | ||
/** | ||
* Flag indicating whether the command is active. The command is active when the | ||
* {@link module:engine/model/selection~Selection#hasAttribute selection has the attribute} which means that: | ||
* | ||
* * If the selection is not empty – That the attribute is set on the first node in the selection that allows this attribute. | ||
* * If the selection is empty – That the selection has the attribute itself (which means that newly typed | ||
* text will have this attribute, too). | ||
* | ||
* @observable | ||
* @readonly | ||
*/ | ||
declare public value: boolean; | ||
|
||
/** | ||
* The attribute that will be set by the command. | ||
*/ | ||
public readonly attributeKey: string; | ||
|
||
/** | ||
* @param attributeKey Attribute that will be set by the command. | ||
*/ | ||
constructor( editor: Editor, attributeKey: string ) { | ||
super( editor ); | ||
|
||
this.attributeKey = attributeKey; | ||
} | ||
|
||
/** | ||
* Updates the command's {@link #value} and {@link #isEnabled} based on the current selection. | ||
*/ | ||
public override refresh(): void { | ||
const model = this.editor.model; | ||
const doc = model.document; | ||
|
||
this.value = this._getValueFromFirstAllowedNode(); | ||
this.isEnabled = model.schema.checkAttributeInSelection( doc.selection, this.attributeKey ); | ||
} | ||
|
||
/** | ||
* Executes the command — applies the attribute to the selection or removes it from the selection. | ||
* | ||
* If the command is active (`value == true`), it will remove attributes. Otherwise, it will set attributes. | ||
* | ||
* The execution result differs, depending on the {@link module:engine/model/document~Document#selection}: | ||
* | ||
* * If the selection is on a range, the command applies the attribute to all nodes in that range | ||
* (if they are allowed to have this attribute by the {@link module:engine/model/schema~Schema schema}). | ||
* * If the selection is collapsed in a non-empty node, the command applies the attribute to the | ||
* {@link module:engine/model/document~Document#selection} itself (note that typed characters copy attributes from the selection). | ||
* * If the selection is collapsed in an empty node, the command applies the attribute to the parent node of the selection (note | ||
* that the selection inherits all attributes from a node if it is in an empty node). | ||
* | ||
* @fires execute | ||
* @param options Command options. | ||
* @param options.forceValue If set, it will force the command behavior. If `true`, | ||
* the command will apply the attribute, otherwise the command will remove the attribute. | ||
* If not set, the command will look for its current value to decide what it should do. | ||
*/ | ||
public override execute( options: { forceValue?: boolean } = {} ): void { | ||
const model = this.editor.model; | ||
const doc = model.document; | ||
const selection = doc.selection; | ||
const value = ( options.forceValue === undefined ) ? !this.value : options.forceValue; | ||
|
||
model.change( writer => { | ||
if ( selection.isCollapsed ) { | ||
if ( value ) { | ||
writer.setSelectionAttribute( this.attributeKey, true ); | ||
} else { | ||
writer.removeSelectionAttribute( this.attributeKey ); | ||
} | ||
} else { | ||
const ranges = model.schema.getValidRanges( selection.getRanges(), this.attributeKey ); | ||
|
||
for ( const range of ranges ) { | ||
if ( value ) { | ||
writer.setAttribute( this.attributeKey, value, range ); | ||
} else { | ||
writer.removeAttribute( this.attributeKey, range ); | ||
} | ||
} | ||
} | ||
} ); | ||
} | ||
|
||
/** | ||
* Checks the attribute value of the first node in the selection that allows the attribute. | ||
* For the collapsed selection returns the selection attribute. | ||
* | ||
* @returns The attribute value. | ||
*/ | ||
private _getValueFromFirstAllowedNode(): boolean { | ||
const model = this.editor.model; | ||
const schema = model.schema; | ||
const selection = model.document.selection; | ||
|
||
if ( selection.isCollapsed ) { | ||
return selection.hasAttribute( this.attributeKey ); | ||
} | ||
|
||
for ( const range of selection.getRanges() ) { | ||
for ( const item of range.getItems() ) { | ||
if ( schema.checkAttribute( item, this.attributeKey ) ) { | ||
return item.hasAttribute( this.attributeKey ); | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
} |
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,43 @@ | ||
/** | ||
* @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 basic-styles/bold | ||
*/ | ||
|
||
import { Plugin, type PluginDependencies } from 'ckeditor5/src/core'; | ||
import BoldEditing from './bold/boldediting'; | ||
import BoldUI from './bold/boldui'; | ||
|
||
/** | ||
* The bold feature. | ||
* | ||
* For a detailed overview check the {@glink features/basic-styles Basic styles feature documentation} | ||
* and the {@glink api/basic-styles package page}. | ||
* | ||
* This is a "glue" plugin which loads the {@link module:basic-styles/bold/boldediting~BoldEditing bold editing feature} | ||
* and {@link module:basic-styles/bold/boldui~BoldUI bold UI feature}. | ||
*/ | ||
export default class Bold extends Plugin { | ||
/** | ||
* @inheritDoc | ||
*/ | ||
public static get requires(): PluginDependencies { | ||
return [ BoldEditing, BoldUI ]; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public static get pluginName(): 'Bold' { | ||
return 'Bold'; | ||
} | ||
} | ||
|
||
declare module '@ckeditor/ckeditor5-core' { | ||
interface PluginsMap { | ||
[ Bold.pluginName ]: Bold; | ||
} | ||
} |
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,83 @@ | ||
/** | ||
* @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 basic-styles/bold/boldediting | ||
*/ | ||
|
||
import { Plugin } from 'ckeditor5/src/core'; | ||
import AttributeCommand from '../attributecommand'; | ||
|
||
const BOLD = 'bold'; | ||
|
||
/** | ||
* The bold editing feature. | ||
* | ||
* It registers the `'bold'` command and introduces the `bold` attribute in the model which renders to the view | ||
* as a `<strong>` element. | ||
*/ | ||
export default class BoldEditing extends Plugin { | ||
/** | ||
* @inheritDoc | ||
*/ | ||
public static get pluginName(): 'BoldEditing' { | ||
return 'BoldEditing'; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public init(): void { | ||
const editor = this.editor; | ||
// Allow bold attribute on text nodes. | ||
editor.model.schema.extend( '$text', { allowAttributes: BOLD } ); | ||
editor.model.schema.setAttributeProperties( BOLD, { | ||
isFormatting: true, | ||
copyOnEnter: true | ||
} ); | ||
|
||
// Build converter from model to view for data and editing pipelines. | ||
editor.conversion.attributeToElement( { | ||
model: BOLD, | ||
view: 'strong', | ||
upcastAlso: [ | ||
'b', | ||
viewElement => { | ||
const fontWeight = viewElement.getStyle( 'font-weight' ); | ||
|
||
if ( !fontWeight ) { | ||
return null; | ||
} | ||
|
||
// Value of the `font-weight` attribute can be defined as a string or a number. | ||
if ( fontWeight == 'bold' || Number( fontWeight ) >= 600 ) { | ||
return { | ||
name: true, | ||
styles: [ 'font-weight' ] | ||
}; | ||
} | ||
|
||
return null; | ||
} | ||
] | ||
} ); | ||
|
||
// Create bold command. | ||
editor.commands.add( BOLD, new AttributeCommand( editor, BOLD ) ); | ||
|
||
// Set the Ctrl+B keystroke. | ||
editor.keystrokes.set( 'CTRL+B', BOLD ); | ||
} | ||
} | ||
|
||
declare module '@ckeditor/ckeditor5-core' { | ||
interface CommandsMap { | ||
bold: AttributeCommand; | ||
} | ||
|
||
interface PluginsMap { | ||
[ BoldEditing.pluginName ]: BoldEditing; | ||
} | ||
} |
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,63 @@ | ||
/** | ||
* @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 basic-styles/bold/boldui | ||
*/ | ||
|
||
import { Plugin, icons } from 'ckeditor5/src/core'; | ||
import { ButtonView } from 'ckeditor5/src/ui'; | ||
|
||
const BOLD = 'bold'; | ||
|
||
/** | ||
* The bold UI feature. It introduces the Bold button. | ||
*/ | ||
export default class BoldUI extends Plugin { | ||
/** | ||
* @inheritDoc | ||
*/ | ||
public static get pluginName(): 'BoldUI' { | ||
return 'BoldUI'; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public init(): void { | ||
const editor = this.editor; | ||
const t = editor.t; | ||
|
||
// Add bold button to feature components. | ||
editor.ui.componentFactory.add( BOLD, locale => { | ||
const command = editor.commands.get( BOLD )!; | ||
const view = new ButtonView( locale ); | ||
|
||
view.set( { | ||
label: t( 'Bold' ), | ||
icon: icons.bold, | ||
keystroke: 'CTRL+B', | ||
tooltip: true, | ||
isToggleable: true | ||
} ); | ||
|
||
view.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' ); | ||
|
||
// Execute command. | ||
this.listenTo( view, 'execute', () => { | ||
editor.execute( BOLD ); | ||
editor.editing.view.focus(); | ||
} ); | ||
|
||
return view; | ||
} ); | ||
} | ||
} | ||
|
||
declare module '@ckeditor/ckeditor5-core' { | ||
interface PluginsMap { | ||
[ BoldUI.pluginName ]: BoldUI; | ||
} | ||
} |
Oops, something went wrong.