| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- /**
- * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
- */
- /**
- * @module autoformat/autoformat
- */
- import blockAutoformatEditing from './blockautoformatediting';
- import inlineAutoformatEditing from './inlineautoformatediting';
- import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
- /**
- * Enables a set of predefined autoformatting actions.
- *
- * For a detailed overview, check the {@glink features/autoformat Autoformatting feature documentation}
- * and the {@glink api/autoformat package page}.
- *
- * @extends module:core/plugin~Plugin
- */
- export default class Autoformat extends Plugin {
- /**
- * @inheritDoc
- */
- static get pluginName() {
- return 'Autoformat';
- }
- /**
- * @inheritDoc
- */
- afterInit() {
- this._addListAutoformats();
- this._addBasicStylesAutoformats();
- this._addHeadingAutoformats();
- this._addBlockQuoteAutoformats();
- this._addCodeBlockAutoformats();
- }
- /**
- * Adds autoformatting related to the {@link module:list/list~List}.
- *
- * When typed:
- * - `* ` or `- ` – A paragraph will be changed to a bulleted list.
- * - `1. ` or `1) ` – A paragraph will be changed to a numbered list ("1" can be any digit or a list of digits).
- *
- * @private
- */
- _addListAutoformats() {
- const commands = this.editor.commands;
- if ( commands.get( 'bulletedList' ) ) {
- blockAutoformatEditing( this.editor, this, /^[*-]\s$/, 'bulletedList' );
- }
- if ( commands.get( 'numberedList' ) ) {
- blockAutoformatEditing( this.editor, this, /^1[.|)]\s$/, 'numberedList' );
- }
- }
- /**
- * Adds autoformatting related to the {@link module:basic-styles/bold~Bold},
- * {@link module:basic-styles/italic~Italic}, {@link module:basic-styles/code~Code}
- * and {@link module:basic-styles/strikethrough~Strikethrough}
- *
- * When typed:
- * - `**foobar**` – `**` characters are removed and `foobar` is set to bold,
- * - `__foobar__` – `__` characters are removed and `foobar` is set to bold,
- * - `*foobar*` – `*` characters are removed and `foobar` is set to italic,
- * - `_foobar_` – `_` characters are removed and `foobar` is set to italic,
- * - ``` `foobar` – ``` ` ``` characters are removed and `foobar` is set to code,
- * - `~~foobar~~` – `~~` characters are removed and `foobar` is set to strikethrough.
- *
- * @private
- */
- _addBasicStylesAutoformats() {
- const commands = this.editor.commands;
- if ( commands.get( 'bold' ) ) {
- const boldCallback = getCallbackFunctionForInlineAutoformat( this.editor, 'bold' );
- inlineAutoformatEditing( this.editor, this, /(\*\*)([^*]+)(\*\*)$/g, boldCallback );
- inlineAutoformatEditing( this.editor, this, /(__)([^_]+)(__)$/g, boldCallback );
- }
- if ( commands.get( 'italic' ) ) {
- const italicCallback = getCallbackFunctionForInlineAutoformat( this.editor, 'italic' );
- // The italic autoformatter cannot be triggered by the bold markers, so we need to check the
- // text before the pattern (e.g. `(?:^|[^\*])`).
- inlineAutoformatEditing( this.editor, this, /(?:^|[^*])(\*)([^*_]+)(\*)$/g, italicCallback );
- inlineAutoformatEditing( this.editor, this, /(?:^|[^_])(_)([^_]+)(_)$/g, italicCallback );
- }
- if ( commands.get( 'code' ) ) {
- const codeCallback = getCallbackFunctionForInlineAutoformat( this.editor, 'code' );
- inlineAutoformatEditing( this.editor, this, /(`)([^`]+)(`)$/g, codeCallback );
- }
- if ( commands.get( 'strikethrough' ) ) {
- const strikethroughCallback = getCallbackFunctionForInlineAutoformat( this.editor, 'strikethrough' );
- inlineAutoformatEditing( this.editor, this, /(~~)([^~]+)(~~)$/g, strikethroughCallback );
- }
- }
- /**
- * Adds autoformatting related to {@link module:heading/heading~Heading}.
- *
- * It is using a number at the end of the command name to associate it with the proper trigger:
- *
- * * `heading` with value `heading1` will be executed when typing `#`,
- * * `heading` with value `heading2` will be executed when typing `##`,
- * * ... up to `heading6` and `######`.
- *
- * @private
- */
- _addHeadingAutoformats() {
- const command = this.editor.commands.get( 'heading' );
- if ( command ) {
- command.modelElements
- .filter( name => name.match( /^heading[1-6]$/ ) )
- .forEach( commandValue => {
- const level = commandValue[ 7 ];
- const pattern = new RegExp( `^(#{${ level }})\\s$` );
- blockAutoformatEditing( this.editor, this, pattern, () => {
- if ( !command.isEnabled ) {
- return false;
- }
- this.editor.execute( 'heading', { value: commandValue } );
- } );
- } );
- }
- }
- /**
- * Adds autoformatting related to {@link module:block-quote/blockquote~BlockQuote}.
- *
- * When typed:
- * * `> ` – A paragraph will be changed to a block quote.
- *
- * @private
- */
- _addBlockQuoteAutoformats() {
- if ( this.editor.commands.get( 'blockQuote' ) ) {
- blockAutoformatEditing( this.editor, this, /^>\s$/, 'blockQuote' );
- }
- }
- /**
- * Adds autoformatting related to {@link module:code-block/codeblock~CodeBlock}.
- *
- * When typed:
- * - `` ``` `` – A paragraph will be changed to a code block.
- *
- * @private
- */
- _addCodeBlockAutoformats() {
- if ( this.editor.commands.get( 'codeBlock' ) ) {
- blockAutoformatEditing( this.editor, this, /^```$/, 'codeBlock' );
- }
- }
- }
- // Helper function for getting `inlineAutoformatEditing` callbacks that checks if command is enabled.
- //
- // @param {module:core/editor/editor~Editor} editor
- // @param {String} attributeKey
- // @returns {Function}
- function getCallbackFunctionForInlineAutoformat( editor, attributeKey ) {
- return ( writer, rangesToFormat ) => {
- const command = editor.commands.get( attributeKey );
- if ( !command.isEnabled ) {
- return false;
- }
- const validRanges = editor.model.schema.getValidRanges( rangesToFormat, attributeKey );
- for ( const range of validRanges ) {
- writer.setAttribute( attributeKey, true, range );
- }
- // After applying attribute to the text, remove given attribute from the selection.
- // This way user is able to type a text without attribute used by auto formatter.
- writer.removeSelectionAttribute( attributeKey );
- };
- }
|