mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	Add '_regroup/ckeditor5-admonition/' from commit 'c3a95822085abd4c38c46c4999342ecfebd5ac7b'
git-subtree-dir: _regroup/ckeditor5-admonition git-subtree-mainline:07c2f1805egit-subtree-split:c3a9582208
This commit is contained in:
		| @@ -0,0 +1,4 @@ | |||||||
|  | Changelog | ||||||
|  | ========= | ||||||
|  |  | ||||||
|  | All changes in the package are documented in https://github.com/ckeditor/ckeditor5/blob/master/CHANGELOG.md. | ||||||
| @@ -0,0 +1,4 @@ | |||||||
|  | Contributing | ||||||
|  | ======================================== | ||||||
|  |  | ||||||
|  | See the [official contributors' guide to CKEditor 5](https://ckeditor.com/docs/ckeditor5/latest/framework/contributing/contributing.html) to learn more. | ||||||
| @@ -0,0 +1,17 @@ | |||||||
|  | Software License Agreement | ||||||
|  | ========================== | ||||||
|  |  | ||||||
|  | **CKEditor 5 block quote feature** – https://github.com/ckeditor/ckeditor5-block-quote <br> | ||||||
|  | Copyright (c) 2003–2024, [CKSource Holding sp. z o.o.](https://cksource.com) All rights reserved. | ||||||
|  |  | ||||||
|  | Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html). | ||||||
|  |  | ||||||
|  | Sources of Intellectual Property Included in CKEditor | ||||||
|  | ----------------------------------------------------- | ||||||
|  |  | ||||||
|  | Where not otherwise indicated, all CKEditor content is authored by CKSource engineers and consists of CKSource-owned intellectual property. In some specific instances, CKEditor will incorporate work done by developers outside of CKSource with their express permission. | ||||||
|  |  | ||||||
|  | Trademarks | ||||||
|  | ---------- | ||||||
|  |  | ||||||
|  | **CKEditor** is a trademark of [CKSource Holding sp. z o.o.](https://cksource.com) All other brand and product names are trademarks, registered trademarks, or service marks of their respective holders. | ||||||
| @@ -0,0 +1,26 @@ | |||||||
|  | CKEditor 5 block quote feature | ||||||
|  | ======================================== | ||||||
|  |  | ||||||
|  | [](https://www.npmjs.com/package/@ckeditor/ckeditor5-block-quote) | ||||||
|  | [](https://coveralls.io/github/ckeditor/ckeditor5?branch=master) | ||||||
|  | [](https://app.travis-ci.com/github/ckeditor/ckeditor5) | ||||||
|  |  | ||||||
|  | This package implements block quote support for CKEditor 5. | ||||||
|  |  | ||||||
|  | ## Demo | ||||||
|  |  | ||||||
|  | Check out the [demo in the block quote feature guide](https://ckeditor.com/docs/ckeditor5/latest/features/block-quote.html#demo). | ||||||
|  |  | ||||||
|  | ## Documentation | ||||||
|  |  | ||||||
|  | See the [`@ckeditor/ckeditor5-block-quote` package](https://ckeditor.com/docs/ckeditor5/latest/api/block-quote.html) page in [CKEditor 5 documentation](https://ckeditor.com/docs/ckeditor5/latest/). | ||||||
|  |  | ||||||
|  | ## Installation | ||||||
|  |  | ||||||
|  | ```bash | ||||||
|  | npm install ckeditor5 | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## License | ||||||
|  |  | ||||||
|  | Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html). For full details about the license, please check the `LICENSE.md` file or [https://ckeditor.com/legal/ckeditor-oss-license](https://ckeditor.com/legal/ckeditor-oss-license). | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | { | ||||||
|  | 	"plugins": [ | ||||||
|  | 		{ | ||||||
|  | 			"name": "Admonitions", | ||||||
|  | 			"className": "Admonition", | ||||||
|  | 			"description": "Implements admonitions (warning, info boxes) in a similar fashion to blockquotes", | ||||||
|  | 			"docs": "features/block-quote.html", | ||||||
|  | 			"path": "src/admonition.js", | ||||||
|  | 			"uiComponents": [ | ||||||
|  | 				{ | ||||||
|  | 					"type": "Button", | ||||||
|  | 					"name": "admonition", | ||||||
|  | 					"iconPath": "theme/icons/admonition.svg" | ||||||
|  | 				} | ||||||
|  | 			], | ||||||
|  | 			"htmlOutput": [ | ||||||
|  | 				{ | ||||||
|  | 					"elements": "aside" | ||||||
|  | 				} | ||||||
|  | 			] | ||||||
|  | 		} | ||||||
|  | 	] | ||||||
|  | } | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | { | ||||||
|  | 	"Admonition": "Toolbar button tooltip for the Admonition feature." | ||||||
|  | } | ||||||
| @@ -0,0 +1,22 @@ | |||||||
|  | # Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. | ||||||
|  | # | ||||||
|  | #                                     !!! IMPORTANT !!! | ||||||
|  | # | ||||||
|  | #         Before you edit this file, please keep in mind that contributing to the project | ||||||
|  | #                translations is possible ONLY via the Transifex online service. | ||||||
|  | # | ||||||
|  | #         To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5. | ||||||
|  | # | ||||||
|  | #                   To learn more, check out the official contributor's guide: | ||||||
|  | #     https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html | ||||||
|  | # | ||||||
|  | msgid "" | ||||||
|  | msgstr "" | ||||||
|  | "Language: \n" | ||||||
|  | "Language-Team: \n" | ||||||
|  | "Plural-Forms: \n" | ||||||
|  | "Content-Type: text/plain; charset=UTF-8\n" | ||||||
|  |  | ||||||
|  | msgctxt "Toolbar button tooltip for the Admoniton feature." | ||||||
|  | msgid "Admonition" | ||||||
|  | msgstr "Admonition" | ||||||
| @@ -0,0 +1,62 @@ | |||||||
|  | { | ||||||
|  |   "name": "@ckeditor/ckeditor5-admonition", | ||||||
|  |   "version": "43.2.0", | ||||||
|  |   "description": "Admonition (info box, warning box) feature for CKEditor 5.", | ||||||
|  |   "keywords": [ | ||||||
|  |     "ckeditor", | ||||||
|  |     "ckeditor5", | ||||||
|  |     "ckeditor 5", | ||||||
|  |     "ckeditor5-feature", | ||||||
|  |     "ckeditor5-plugin", | ||||||
|  |     "ckeditor5-dll" | ||||||
|  |   ], | ||||||
|  |   "type": "module", | ||||||
|  |   "main": "src/index.ts", | ||||||
|  |   "dependencies": { | ||||||
|  |     "@ckeditor/ckeditor5-core": "43.2.0", | ||||||
|  |     "@ckeditor/ckeditor5-enter": "43.2.0", | ||||||
|  |     "@ckeditor/ckeditor5-typing": "43.2.0", | ||||||
|  |     "@ckeditor/ckeditor5-ui": "43.2.0", | ||||||
|  |     "@ckeditor/ckeditor5-utils": "43.2.0", | ||||||
|  |     "ckeditor5": "43.2.0" | ||||||
|  |   }, | ||||||
|  |   "devDependencies": { | ||||||
|  |     "@ckeditor/ckeditor5-basic-styles": "43.2.0", | ||||||
|  |     "@ckeditor/ckeditor5-dev-utils": "^43.0.0", | ||||||
|  |     "@ckeditor/ckeditor5-editor-classic": "43.2.0", | ||||||
|  |     "@ckeditor/ckeditor5-engine": "43.2.0", | ||||||
|  |     "@ckeditor/ckeditor5-heading": "43.2.0", | ||||||
|  |     "@ckeditor/ckeditor5-image": "43.2.0", | ||||||
|  |     "@ckeditor/ckeditor5-list": "43.2.0", | ||||||
|  |     "@ckeditor/ckeditor5-paragraph": "43.2.0", | ||||||
|  |     "@ckeditor/ckeditor5-table": "43.2.0", | ||||||
|  |     "@ckeditor/ckeditor5-theme-lark": "43.2.0", | ||||||
|  |     "typescript": "5.0.4", | ||||||
|  |     "webpack": "^5.94.0", | ||||||
|  |     "webpack-cli": "^5.1.4" | ||||||
|  |   }, | ||||||
|  |   "author": "CKSource (http://cksource.com/)", | ||||||
|  |   "license": "GPL-2.0-or-later", | ||||||
|  |   "homepage": "https://ckeditor.com/ckeditor-5", | ||||||
|  |   "bugs": "https://github.com/ckeditor/ckeditor5/issues", | ||||||
|  |   "repository": { | ||||||
|  |     "type": "git", | ||||||
|  |     "url": "https://github.com/ckeditor/ckeditor5.git", | ||||||
|  |     "directory": "packages/ckeditor5-admonition" | ||||||
|  |   }, | ||||||
|  |   "files": [ | ||||||
|  |     "dist", | ||||||
|  |     "lang", | ||||||
|  |     "src/**/*.js", | ||||||
|  |     "src/**/*.d.ts", | ||||||
|  |     "theme", | ||||||
|  |     "build", | ||||||
|  |     "ckeditor5-metadata.json", | ||||||
|  |     "CHANGELOG.md" | ||||||
|  |   ], | ||||||
|  |   "scripts": { | ||||||
|  |     "dll:build": "webpack", | ||||||
|  |     "build": "tsc -p ./tsconfig.json", | ||||||
|  |     "build:dist": "node ../../scripts/build-package.mjs" | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,40 @@ | |||||||
|  | /** | ||||||
|  |  * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. | ||||||
|  |  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @module admonition/admonition | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | import { Plugin } from 'ckeditor5/src/core.js'; | ||||||
|  |  | ||||||
|  | import AdmonitionEditing from './admonitionediting.js'; | ||||||
|  | import AdmonitionUI from './admonitionui.js'; | ||||||
|  | import AdmonitionAutoformat from './admonitionautoformat.js'; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * The block quote plugin. | ||||||
|  |  * | ||||||
|  |  * For more information about this feature check the {@glink api/block-quote package page}. | ||||||
|  |  * | ||||||
|  |  * This is a "glue" plugin which loads the {@link module:block-quote/blockquoteediting~BlockQuoteEditing block quote editing feature} | ||||||
|  |  * and {@link module:block-quote/blockquoteui~BlockQuoteUI block quote UI feature}. | ||||||
|  |  * | ||||||
|  |  * @extends module:core/plugin~Plugin | ||||||
|  |  */ | ||||||
|  | export default class Admonition extends Plugin { | ||||||
|  | 	/** | ||||||
|  | 	 * @inheritDoc | ||||||
|  | 	 */ | ||||||
|  | 	public static get requires() { | ||||||
|  | 		return [ AdmonitionEditing, AdmonitionUI, AdmonitionAutoformat ] as const; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @inheritDoc | ||||||
|  | 	 */ | ||||||
|  | 	public static get pluginName() { | ||||||
|  | 		return 'Admonition' as const; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,42 @@ | |||||||
|  | import Plugin from "@ckeditor/ckeditor5-core/src/plugin"; | ||||||
|  | import Autoformat from "@ckeditor/ckeditor5-autoformat/src/autoformat"; | ||||||
|  | import blockAutoformatEditing from "@ckeditor/ckeditor5-autoformat/src/blockautoformatediting"; | ||||||
|  | import { AdmonitionType, ADMONITION_TYPES } from "./admonitioncommand"; | ||||||
|  |  | ||||||
|  | function tryParseAdmonitionType(match: RegExpMatchArray) { | ||||||
|  | 	if (match.length !== 2) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if ((ADMONITION_TYPES as readonly string[]).includes(match[1])) { | ||||||
|  | 		return match[1] as AdmonitionType; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export default class AdmonitionAutoformat extends Plugin { | ||||||
|  | 	static get requires() { | ||||||
|  | 		return [ Autoformat ]; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	afterInit() { | ||||||
|  | 		if (!this.editor.commands.get("admonition")) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		const instance = (this as any); | ||||||
|  | 		blockAutoformatEditing(this.editor, instance, /^\!\!\[*\! (.+) $/, ({ match }) => { | ||||||
|  | 			const type = tryParseAdmonitionType(match); | ||||||
|  |  | ||||||
|  | 			if (type) { | ||||||
|  | 				// User has entered the admonition type, so we insert as-is. | ||||||
|  | 				this.editor.execute("admonition", { forceValue: type }); | ||||||
|  | 			} else { | ||||||
|  | 				// User has not entered a valid type, assume it's part of the text of the admonition. | ||||||
|  | 				this.editor.execute("admonition"); | ||||||
|  | 				if (match.length > 1) { | ||||||
|  | 					this.editor.execute("insertText", { text: (match[1] ?? "") + " " }); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,276 @@ | |||||||
|  | /** | ||||||
|  |  * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. | ||||||
|  |  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @module admonition/admonitioncommand | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | import { Command } from 'ckeditor5/src/core.js'; | ||||||
|  | import { first } from 'ckeditor5/src/utils.js'; | ||||||
|  | import type { DocumentFragment, Element, Position, Range, Schema, Writer } from 'ckeditor5/src/engine.js'; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * The block quote command plugin. | ||||||
|  |  * | ||||||
|  |  * @extends module:core/command~Command | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | export const ADMONITION_TYPES = [ "note", "tip", "important", "caution", "warning" ] as const; | ||||||
|  | export const ADMONITION_TYPE_ATTRIBUTE = "admonitionType"; | ||||||
|  | export const DEFAULT_ADMONITION_TYPE = ADMONITION_TYPES[0]; | ||||||
|  | export type AdmonitionType = typeof ADMONITION_TYPES[number]; | ||||||
|  |  | ||||||
|  | interface ExecuteOpts { | ||||||
|  | 	/** | ||||||
|  | 	 * If set, it will force the command behavior. If `true`, the command will apply a block quote, | ||||||
|  | 	 * otherwise the command will remove the block quote. If not set, the command will act basing on its current value. | ||||||
|  | 	 */ | ||||||
|  | 	forceValue?: AdmonitionType; | ||||||
|  | 	/** | ||||||
|  | 	 * If set to true and `forceValue` is not specified, the command will apply the previous admonition type (if the command was already executed). | ||||||
|  | 	 */ | ||||||
|  | 	usePreviousChoice?: boolean | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export default class AdmonitionCommand extends Command { | ||||||
|  | 	/** | ||||||
|  | 	 * Whether the selection starts in a block quote. | ||||||
|  | 	 * | ||||||
|  | 	 * @observable | ||||||
|  | 	 * @readonly | ||||||
|  | 	 */ | ||||||
|  | 	declare public value: AdmonitionType | false; | ||||||
|  |  | ||||||
|  | 	private _lastType?: AdmonitionType; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @inheritDoc | ||||||
|  | 	 */ | ||||||
|  | 	public override refresh(): void { | ||||||
|  | 		this.value = this._getValue(); | ||||||
|  | 		this.isEnabled = this._checkEnabled(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Executes the command. When the command {@link #value is on}, all top-most block quotes within | ||||||
|  | 	 * the selection will be removed. If it is off, all selected blocks will be wrapped with | ||||||
|  | 	 * a block quote. | ||||||
|  | 	 * | ||||||
|  | 	 * @fires execute | ||||||
|  | 	 * @param options Command options. | ||||||
|  | 	 */ | ||||||
|  | 	public override execute( options: ExecuteOpts = {} ): void { | ||||||
|  | 		const model = this.editor.model; | ||||||
|  | 		const schema = model.schema; | ||||||
|  | 		const selection = model.document.selection; | ||||||
|  |  | ||||||
|  | 		const blocks = Array.from( selection.getSelectedBlocks() ); | ||||||
|  |  | ||||||
|  | 		const value = this._getType(options); | ||||||
|  |  | ||||||
|  | 		model.change( writer => { | ||||||
|  | 			if ( !value ) { | ||||||
|  | 				this._removeQuote( writer, blocks.filter( findQuote ) ); | ||||||
|  | 			} else { | ||||||
|  | 				const blocksToQuote = blocks.filter( block => { | ||||||
|  | 					// Already quoted blocks needs to be considered while quoting too | ||||||
|  | 					// in order to reuse their <bQ> elements. | ||||||
|  | 					return findQuote( block ) || checkCanBeQuoted( schema, block ); | ||||||
|  | 				} ); | ||||||
|  |  | ||||||
|  | 				this._applyQuote( writer, blocksToQuote, value); | ||||||
|  | 			} | ||||||
|  | 		} ); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	private _getType(options: ExecuteOpts): AdmonitionType | false { | ||||||
|  | 		const value = (options.forceValue === undefined) ? !this.value : options.forceValue; | ||||||
|  |  | ||||||
|  | 		// Allow removing the admonition. | ||||||
|  | 		if (!value) { | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Prefer the type from the command, if any. | ||||||
|  | 		if (typeof value === "string") { | ||||||
|  | 			return value; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// See if we can restore the previous language. | ||||||
|  | 		if (options.usePreviousChoice && this._lastType) { | ||||||
|  | 			return this._lastType; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Otherwise return a default. | ||||||
|  | 		return "note"; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Checks the command's {@link #value}. | ||||||
|  | 	 */ | ||||||
|  | 	private _getValue(): AdmonitionType | false { | ||||||
|  | 		const selection = this.editor.model.document.selection; | ||||||
|  | 		const firstBlock = first( selection.getSelectedBlocks() ); | ||||||
|  | 		if (!firstBlock) { | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// In the current implementation, the admonition must be an immediate parent of a block element. | ||||||
|  | 		const firstQuote = findQuote( firstBlock ); | ||||||
|  | 		if (firstQuote?.is("element")) { | ||||||
|  | 			return firstQuote.getAttribute(ADMONITION_TYPE_ATTRIBUTE) as AdmonitionType; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Checks whether the command can be enabled in the current context. | ||||||
|  | 	 * | ||||||
|  | 	 * @returns Whether the command should be enabled. | ||||||
|  | 	 */ | ||||||
|  | 	private _checkEnabled(): boolean { | ||||||
|  | 		if ( this.value ) { | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		const selection = this.editor.model.document.selection; | ||||||
|  | 		const schema = this.editor.model.schema; | ||||||
|  |  | ||||||
|  | 		const firstBlock = first( selection.getSelectedBlocks() ); | ||||||
|  |  | ||||||
|  | 		if ( !firstBlock ) { | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return checkCanBeQuoted( schema, firstBlock ); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Removes the quote from given blocks. | ||||||
|  | 	 * | ||||||
|  | 	 * If blocks which are supposed to be "unquoted" are in the middle of a quote, | ||||||
|  | 	 * start it or end it, then the quote will be split (if needed) and the blocks | ||||||
|  | 	 * will be moved out of it, so other quoted blocks remained quoted. | ||||||
|  | 	 */ | ||||||
|  | 	private _removeQuote( writer: Writer, blocks: Array<Element> ): void { | ||||||
|  | 		// Unquote all groups of block. Iterate in the reverse order to not break following ranges. | ||||||
|  | 		getRangesOfBlockGroups( writer, blocks ).reverse().forEach( groupRange => { | ||||||
|  | 			if ( groupRange.start.isAtStart && groupRange.end.isAtEnd ) { | ||||||
|  | 				writer.unwrap( groupRange.start.parent as Element ); | ||||||
|  |  | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// The group of blocks are at the beginning of an <bQ> so let's move them left (out of the <bQ>). | ||||||
|  | 			if ( groupRange.start.isAtStart ) { | ||||||
|  | 				const positionBefore = writer.createPositionBefore( groupRange.start.parent as Element ); | ||||||
|  |  | ||||||
|  | 				writer.move( groupRange, positionBefore ); | ||||||
|  |  | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// The blocks are in the middle of an <bQ> so we need to split the <bQ> after the last block | ||||||
|  | 			// so we move the items there. | ||||||
|  | 			if ( !groupRange.end.isAtEnd ) { | ||||||
|  | 				writer.split( groupRange.end ); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// Now we are sure that groupRange.end.isAtEnd is true, so let's move the blocks right. | ||||||
|  |  | ||||||
|  | 			const positionAfter = writer.createPositionAfter( groupRange.end.parent as Element ); | ||||||
|  |  | ||||||
|  | 			writer.move( groupRange, positionAfter ); | ||||||
|  | 		} ); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Applies the quote to given blocks. | ||||||
|  | 	 */ | ||||||
|  | 	private _applyQuote( writer: Writer, blocks: Array<Element>, type?: AdmonitionType): void { | ||||||
|  | 		this._lastType = type; | ||||||
|  | 		const quotesToMerge: Array<Element | DocumentFragment> = []; | ||||||
|  |  | ||||||
|  | 		// Quote all groups of block. Iterate in the reverse order to not break following ranges. | ||||||
|  | 		getRangesOfBlockGroups( writer, blocks ).reverse().forEach( groupRange => { | ||||||
|  | 			let quote = findQuote( groupRange.start ); | ||||||
|  |  | ||||||
|  | 			if ( !quote ) { | ||||||
|  | 				const attributes: Record<string, unknown> = {}; | ||||||
|  | 				attributes[ADMONITION_TYPE_ATTRIBUTE] = type; | ||||||
|  | 				quote = writer.createElement( 'aside', attributes); | ||||||
|  |  | ||||||
|  | 				writer.wrap( groupRange, quote ); | ||||||
|  | 			} else if (quote.is("element")) { | ||||||
|  | 				this.editor.model.change((writer) => { | ||||||
|  | 					writer.setAttribute(ADMONITION_TYPE_ATTRIBUTE, type, quote as Element); | ||||||
|  | 				}); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			quotesToMerge.push( quote ); | ||||||
|  | 		} ); | ||||||
|  |  | ||||||
|  | 		// Merge subsequent <bQ> elements. Reverse the order again because this time we want to go through | ||||||
|  | 		// the <bQ> elements in the source order (due to how merge works – it moves the right element's content | ||||||
|  | 		// to the first element and removes the right one. Since we may need to merge a couple of subsequent `<bQ>` elements | ||||||
|  | 		// we want to keep the reference to the first (furthest left) one. | ||||||
|  | 		quotesToMerge.reverse().reduce( ( currentQuote, nextQuote ) => { | ||||||
|  | 			if ( currentQuote.nextSibling == nextQuote ) { | ||||||
|  | 				writer.merge( writer.createPositionAfter( currentQuote ) ); | ||||||
|  |  | ||||||
|  | 				return currentQuote; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			return nextQuote; | ||||||
|  | 		} ); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function findQuote( elementOrPosition: Element | Position ): Element | DocumentFragment | null { | ||||||
|  | 	return elementOrPosition.parent!.name == 'aside' ? elementOrPosition.parent : null; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Returns a minimal array of ranges containing groups of subsequent blocks. | ||||||
|  |  * | ||||||
|  |  * content:         abcdefgh | ||||||
|  |  * blocks:          [ a, b, d, f, g, h ] | ||||||
|  |  * output ranges:   [ab]c[d]e[fgh] | ||||||
|  |  */ | ||||||
|  | function getRangesOfBlockGroups( writer: Writer, blocks: Array<Element> ): Array<Range> { | ||||||
|  | 	let startPosition; | ||||||
|  | 	let i = 0; | ||||||
|  | 	const ranges = []; | ||||||
|  |  | ||||||
|  | 	while ( i < blocks.length ) { | ||||||
|  | 		const block = blocks[ i ]; | ||||||
|  | 		const nextBlock = blocks[ i + 1 ]; | ||||||
|  |  | ||||||
|  | 		if ( !startPosition ) { | ||||||
|  | 			startPosition = writer.createPositionBefore( block ); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if ( !nextBlock || block.nextSibling != nextBlock ) { | ||||||
|  | 			ranges.push( writer.createRange( startPosition, writer.createPositionAfter( block ) ) ); | ||||||
|  | 			startPosition = null; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		i++; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return ranges; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Checks whether <bQ> can wrap the block. | ||||||
|  |  */ | ||||||
|  | function checkCanBeQuoted( schema: Schema, block: Element ): boolean { | ||||||
|  | 	// TMP will be replaced with schema.checkWrap(). | ||||||
|  | 	const isBQAllowed = schema.checkChild( block.parent as Element, 'aside' ); | ||||||
|  | 	const isBlockAllowedInBQ = schema.checkChild( [ '$root', 'aside' ], block ); | ||||||
|  |  | ||||||
|  | 	return isBQAllowed && isBlockAllowedInBQ; | ||||||
|  | } | ||||||
| @@ -0,0 +1,177 @@ | |||||||
|  | /** | ||||||
|  |  * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. | ||||||
|  |  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @module admonition/admonitionediting | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | import { Plugin } from 'ckeditor5/src/core.js'; | ||||||
|  | import { Enter, type ViewDocumentEnterEvent } from 'ckeditor5/src/enter.js'; | ||||||
|  | import { Delete, type ViewDocumentDeleteEvent } from 'ckeditor5/src/typing.js'; | ||||||
|  |  | ||||||
|  | import AdmonitionCommand, { AdmonitionType, ADMONITION_TYPES, DEFAULT_ADMONITION_TYPE, ADMONITION_TYPE_ATTRIBUTE } from './admonitioncommand.js'; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * The block quote editing. | ||||||
|  |  * | ||||||
|  |  * Introduces the `'admonition'` command and the `'aside'` model element. | ||||||
|  |  * | ||||||
|  |  * @extends module:core/plugin~Plugin | ||||||
|  |  */ | ||||||
|  | export default class AdmonitionEditing extends Plugin { | ||||||
|  | 	/** | ||||||
|  | 	 * @inheritDoc | ||||||
|  | 	 */ | ||||||
|  | 	public static get pluginName() { | ||||||
|  | 		return 'AdmonitionEditing' as const; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @inheritDoc | ||||||
|  | 	 */ | ||||||
|  | 	public static get requires() { | ||||||
|  | 		return [ Enter, Delete ] as const; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @inheritDoc | ||||||
|  | 	 */ | ||||||
|  | 	public init(): void { | ||||||
|  | 		const editor = this.editor; | ||||||
|  | 		const schema = editor.model.schema; | ||||||
|  |  | ||||||
|  | 		editor.commands.add( 'admonition', new AdmonitionCommand( editor ) ); | ||||||
|  |  | ||||||
|  | 		schema.register( 'aside', { | ||||||
|  | 			inheritAllFrom: '$container', | ||||||
|  | 			allowAttributes: ADMONITION_TYPE_ATTRIBUTE | ||||||
|  | 		} ); | ||||||
|  |  | ||||||
|  | 		editor.conversion.for("upcast").elementToElement({ | ||||||
|  | 			view: { | ||||||
|  | 				name: "aside", | ||||||
|  | 				classes: "admonition", | ||||||
|  | 			}, | ||||||
|  | 			model: (viewElement, { writer }) => { | ||||||
|  | 				let type: AdmonitionType = DEFAULT_ADMONITION_TYPE; | ||||||
|  | 				for (const className of viewElement.getClassNames()) { | ||||||
|  | 					if (className !== "admonition" && (ADMONITION_TYPES as readonly string[]).includes(className)) { | ||||||
|  | 						type = className as AdmonitionType; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				const attributes: Record<string, unknown> = {}; | ||||||
|  | 				attributes[ADMONITION_TYPE_ATTRIBUTE] = type; | ||||||
|  | 				return writer.createElement("aside", attributes); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		editor.conversion.for("downcast") | ||||||
|  | 			.elementToElement( { | ||||||
|  | 				model: 'aside', | ||||||
|  | 				view: "aside" | ||||||
|  | 			}) | ||||||
|  | 			.attributeToAttribute({ | ||||||
|  | 				model: ADMONITION_TYPE_ATTRIBUTE, | ||||||
|  | 				view: (value) => ({ | ||||||
|  | 					key: "class", | ||||||
|  | 					value: [ "admonition", value as string ] | ||||||
|  | 				}) | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 		// Postfixer which cleans incorrect model states connected with block quotes. | ||||||
|  | 		editor.model.document.registerPostFixer( writer => { | ||||||
|  | 			const changes = editor.model.document.differ.getChanges(); | ||||||
|  |  | ||||||
|  | 			for ( const entry of changes ) { | ||||||
|  | 				if ( entry.type == 'insert' ) { | ||||||
|  | 					const element = entry.position.nodeAfter; | ||||||
|  |  | ||||||
|  | 					if ( !element ) { | ||||||
|  | 						// We are inside a text node. | ||||||
|  | 						continue; | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					if ( element.is( 'element', 'aside' ) && element.isEmpty ) { | ||||||
|  | 						// Added an empty aside - remove it. | ||||||
|  | 						writer.remove( element ); | ||||||
|  |  | ||||||
|  | 						return true; | ||||||
|  | 					} else if ( element.is( 'element', 'aside' ) && !schema.checkChild( entry.position, element ) ) { | ||||||
|  | 						// Added a aside in incorrect place. Unwrap it so the content inside is not lost. | ||||||
|  | 						writer.unwrap( element ); | ||||||
|  |  | ||||||
|  | 						return true; | ||||||
|  | 					} else if ( element.is( 'element' ) ) { | ||||||
|  | 						// Just added an element. Check that all children meet the scheme rules. | ||||||
|  | 						const range = writer.createRangeIn( element ); | ||||||
|  |  | ||||||
|  | 						for ( const child of range.getItems() ) { | ||||||
|  | 							if ( | ||||||
|  | 								child.is( 'element', 'aside' ) && | ||||||
|  | 								!schema.checkChild( writer.createPositionBefore( child ), child ) | ||||||
|  | 							) { | ||||||
|  | 								writer.unwrap( child ); | ||||||
|  |  | ||||||
|  | 								return true; | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} else if ( entry.type == 'remove' ) { | ||||||
|  | 					const parent = entry.position.parent; | ||||||
|  |  | ||||||
|  | 					if ( parent.is( 'element', 'aside' ) && parent.isEmpty ) { | ||||||
|  | 						// Something got removed and now aside is empty. Remove the aside as well. | ||||||
|  | 						writer.remove( parent ); | ||||||
|  |  | ||||||
|  | 						return true; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			return false; | ||||||
|  | 		} ); | ||||||
|  |  | ||||||
|  | 		const viewDocument = this.editor.editing.view.document; | ||||||
|  | 		const selection = editor.model.document.selection; | ||||||
|  | 		const admonitionCommand: AdmonitionCommand = editor.commands.get( 'admonition' )!; | ||||||
|  |  | ||||||
|  | 		// Overwrite default Enter key behavior. | ||||||
|  | 		// If Enter key is pressed with selection collapsed in empty block inside a quote, break the quote. | ||||||
|  | 		this.listenTo<ViewDocumentEnterEvent>( viewDocument, 'enter', ( evt, data ) => { | ||||||
|  | 			if ( !selection.isCollapsed || !admonitionCommand.value ) { | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			const positionParent = selection.getLastPosition()!.parent; | ||||||
|  |  | ||||||
|  | 			if ( positionParent.isEmpty ) { | ||||||
|  | 				editor.execute( 'admonition' ); | ||||||
|  | 				editor.editing.view.scrollToTheSelection(); | ||||||
|  |  | ||||||
|  | 				data.preventDefault(); | ||||||
|  | 				evt.stop(); | ||||||
|  | 			} | ||||||
|  | 		}, { context: 'aside' } ); | ||||||
|  |  | ||||||
|  | 		// Overwrite default Backspace key behavior. | ||||||
|  | 		// If Backspace key is pressed with selection collapsed in first empty block inside a quote, break the quote. | ||||||
|  | 		this.listenTo<ViewDocumentDeleteEvent>( viewDocument, 'delete', ( evt, data ) => { | ||||||
|  | 			if ( data.direction != 'backward' || !selection.isCollapsed || !admonitionCommand!.value ) { | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			const positionParent = selection.getLastPosition()!.parent; | ||||||
|  |  | ||||||
|  | 			if ( positionParent.isEmpty && !positionParent.previousSibling ) { | ||||||
|  | 				editor.execute( 'admonition' ); | ||||||
|  | 				editor.editing.view.scrollToTheSelection(); | ||||||
|  |  | ||||||
|  | 				data.preventDefault(); | ||||||
|  | 				evt.stop(); | ||||||
|  | 			} | ||||||
|  | 		}, { context: 'aside' } ); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,125 @@ | |||||||
|  | /** | ||||||
|  |  * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. | ||||||
|  |  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @module admonition/admonitionui | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | import { Plugin, } from 'ckeditor5/src/core.js'; | ||||||
|  | import { addListToDropdown, createDropdown, ListDropdownButtonDefinition, SplitButtonView, ViewModel } from 'ckeditor5/src/ui.js'; | ||||||
|  |  | ||||||
|  | import '../theme/blockquote.css'; | ||||||
|  | import admonitionIcon from '../theme/icons/admonition.svg'; | ||||||
|  | import { Collection } from '@ckeditor/ckeditor5-utils'; | ||||||
|  | import AdmonitionCommand, { AdmonitionType } from './admonitioncommand'; | ||||||
|  |  | ||||||
|  | interface AdmonitionDefinition { | ||||||
|  | 	title: string; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export const ADMONITION_TYPES: Record<AdmonitionType, AdmonitionDefinition> = { | ||||||
|  | 	note: { | ||||||
|  | 		title: "Note" | ||||||
|  | 	}, | ||||||
|  | 	tip: { | ||||||
|  | 		title: "Tip" | ||||||
|  | 	}, | ||||||
|  | 	important: { | ||||||
|  | 		title: "Important" | ||||||
|  | 	}, | ||||||
|  | 	caution: { | ||||||
|  | 		title: "Caution" | ||||||
|  | 	}, | ||||||
|  | 	warning: { | ||||||
|  | 		title: "Warning" | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * The block quote UI plugin. | ||||||
|  |  * | ||||||
|  |  * It introduces the `'admonition'` button. | ||||||
|  |  * | ||||||
|  |  * @extends module:core/plugin~Plugin | ||||||
|  |  */ | ||||||
|  | export default class AdmonitionUI extends Plugin { | ||||||
|  | 	/** | ||||||
|  | 	 * @inheritDoc | ||||||
|  | 	 */ | ||||||
|  | 	public static get pluginName() { | ||||||
|  | 		return 'AdmonitionUI' as const; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @inheritDoc | ||||||
|  | 	 */ | ||||||
|  | 	public init(): void { | ||||||
|  | 		const editor = this.editor; | ||||||
|  |  | ||||||
|  | 		editor.ui.componentFactory.add( 'admonition', () => { | ||||||
|  | 			const buttonView = this._createButton(); | ||||||
|  |  | ||||||
|  | 			return buttonView; | ||||||
|  | 		} ); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Creates a button for admonition command to use either in toolbar or in menu bar. | ||||||
|  | 	 */ | ||||||
|  | 	private _createButton() { | ||||||
|  | 		const editor = this.editor; | ||||||
|  | 		const locale = editor.locale; | ||||||
|  | 		const command = editor.commands.get( 'admonition' )!; | ||||||
|  | 		const dropdownView = createDropdown(locale, SplitButtonView); | ||||||
|  | 		const splitButtonView = dropdownView.buttonView; | ||||||
|  | 		const t = locale.t; | ||||||
|  |  | ||||||
|  | 		addListToDropdown(dropdownView, this._getDropdownItems()) | ||||||
|  |  | ||||||
|  | 		// Button configuration. | ||||||
|  | 		splitButtonView.set( { | ||||||
|  | 			label: t( 'Admonition' ), | ||||||
|  | 			icon: admonitionIcon, | ||||||
|  | 			isToggleable: true, | ||||||
|  | 			tooltip: true | ||||||
|  | 		} ); | ||||||
|  | 		splitButtonView.on("execute", () => { | ||||||
|  | 			editor.execute("admonition", { usePreviousChoice: true }); | ||||||
|  | 			editor.editing.view.focus(); | ||||||
|  | 		}); | ||||||
|  | 		splitButtonView.bind( 'isOn' ).to( command, 'value', value => (!!value) as boolean); | ||||||
|  |  | ||||||
|  | 		// Dropdown configuration | ||||||
|  | 		dropdownView.bind( 'isEnabled' ).to( command, 'isEnabled' ); | ||||||
|  | 		dropdownView.on("execute", evt => { | ||||||
|  | 			editor.execute("admonition", { forceValue: ( evt.source as any ).commandParam } ); | ||||||
|  | 			editor.editing.view.focus(); | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		return dropdownView; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	private _getDropdownItems() { | ||||||
|  | 		const itemDefinitions = new Collection<ListDropdownButtonDefinition>(); | ||||||
|  | 		const command = this.editor.commands.get("admonition") as AdmonitionCommand | ||||||
|  |  | ||||||
|  | 		for (const [ type, admonition ] of Object.entries(ADMONITION_TYPES)) { | ||||||
|  | 			const definition: ListDropdownButtonDefinition = { | ||||||
|  | 				type: "button", | ||||||
|  | 				model: new ViewModel({ | ||||||
|  | 					commandParam: type, | ||||||
|  | 					label: admonition.title, | ||||||
|  | 					role: 'menuitemradio', | ||||||
|  | 					withText: true | ||||||
|  | 				}) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			definition.model.bind("isOn").to(command, "value", currentType => currentType === type); | ||||||
|  | 			itemDefinitions.add(definition); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return itemDefinitions; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | /** | ||||||
|  |  * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. | ||||||
|  |  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | import type { | ||||||
|  | 	Admonition, | ||||||
|  | 	AdmonitionCommand, | ||||||
|  | 	AdmonitionEditing, | ||||||
|  | 	AdmonitionUI | ||||||
|  | } from './index.js'; | ||||||
|  |  | ||||||
|  | declare module '@ckeditor/ckeditor5-core' { | ||||||
|  | 	interface PluginsMap { | ||||||
|  | 		[ Admonition.pluginName ]: Admonition; | ||||||
|  | 		[ AdmonitionEditing.pluginName ]: AdmonitionEditing; | ||||||
|  | 		[ AdmonitionUI.pluginName ]: AdmonitionUI; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	interface CommandsMap { | ||||||
|  | 		admonition: AdmonitionCommand; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | /** | ||||||
|  |  * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. | ||||||
|  |  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @module admonition | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | export { default as Admonition } from './admonition.js'; | ||||||
|  | export { default as AdmonitionEditing } from './admonitionediting.js'; | ||||||
|  | export { default as AdmonitionUI } from './admonitionui.js'; | ||||||
|  | export { default as AdmonitionAutoformat } from './admonitionautoformat.js'; | ||||||
|  | export type { default as AdmonitionCommand } from './admonitioncommand.js'; | ||||||
|  |  | ||||||
|  | import './augmentation.js'; | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. | ||||||
|  |  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | .ck-content blockquote { | ||||||
|  | 	/* See #12 */ | ||||||
|  | 	overflow: hidden; | ||||||
|  |  | ||||||
|  | 	/* https://github.com/ckeditor/ckeditor5-block-quote/issues/15 */ | ||||||
|  | 	padding-right: 1.5em; | ||||||
|  | 	padding-left: 1.5em; | ||||||
|  |  | ||||||
|  | 	margin-left: 0; | ||||||
|  | 	margin-right: 0; | ||||||
|  | 	font-style: italic; | ||||||
|  | 	border-left: solid 5px hsl(0, 0%, 80%); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .ck-content[dir="rtl"] blockquote { | ||||||
|  | 	border-left: 0; | ||||||
|  | 	border-right: solid 5px hsl(0, 0%, 80%); | ||||||
|  | } | ||||||
| @@ -0,0 +1,52 @@ | |||||||
|  | <?xml version="1.0" encoding="iso-8859-1"?> | ||||||
|  | <!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> | ||||||
|  | <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | ||||||
|  | 	 viewBox="0 0 511.936 511.936" style="enable-background:new 0 0 511.936 511.936;" xml:space="preserve"> | ||||||
|  | <g> | ||||||
|  | 	<g> | ||||||
|  | 		<g> | ||||||
|  | 			<path d="M255.959,128c11.776,0,21.333-9.557,21.333-21.333s-9.557-21.333-21.333-21.333s-21.333,9.557-21.333,21.333 | ||||||
|  | 				S244.183,128,255.959,128z"/> | ||||||
|  | 			<path d="M383.968,0h-256C80.907,0,42.635,38.272,42.635,85.333v213.333c0,47.061,38.272,85.333,85.333,85.333h64l0.085,92.075 | ||||||
|  | 				c0,14.571,8.683,27.584,22.165,33.173c4.331,1.792,8.875,2.688,13.397,2.688c9.557,0,19.157-3.968,27.051-11.968L350.475,384 | ||||||
|  | 				h33.493c47.061,0,85.333-38.272,85.333-85.333V85.333C469.301,38.272,431.029,0,383.968,0z M426.635,298.667 | ||||||
|  | 				c0,23.531-19.157,42.667-42.667,42.667h-36.629c-9.621,0-18.645,3.755-26.752,12.011l-85.888,103.979l-0.064-80.085 | ||||||
|  | 				c0-19.797-16.107-35.904-35.904-35.904h-70.763c-23.531,0-42.667-19.136-42.667-42.667V85.333 | ||||||
|  | 				c0-23.531,19.136-42.667,42.667-42.667h256c23.509,0,42.667,19.136,42.667,42.667V298.667z"/> | ||||||
|  | 			<path d="M298.626,256h-21.333v-85.333c0-11.776-9.536-21.333-21.333-21.333h-21.333c-11.797,0-21.333,9.557-21.333,21.333 | ||||||
|  | 				S222.829,192,234.626,192v64h-21.333c-11.797,0-21.333,9.557-21.333,21.333s9.536,21.333,21.333,21.333h85.333 | ||||||
|  | 				c11.797,0,21.333-9.557,21.333-21.333S310.423,256,298.626,256z"/> | ||||||
|  | 		</g> | ||||||
|  | 	</g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 1.6 KiB | 
| @@ -0,0 +1,12 @@ | |||||||
|  | { | ||||||
|  | 	"extends": "../../tsconfig.dist.json", | ||||||
|  | 	"compilerOptions": { | ||||||
|  | 		"rootDir": "src", | ||||||
|  | 		"types": [ | ||||||
|  | 			"../../typings/types" | ||||||
|  | 		] | ||||||
|  | 	}, | ||||||
|  | 	"include": [ | ||||||
|  | 		"src" | ||||||
|  | 	] | ||||||
|  | } | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | { | ||||||
|  | 	"extends": "../../tsconfig.release.json", | ||||||
|  | 	"include": [ | ||||||
|  | 		"src", | ||||||
|  | 		"../../typings" | ||||||
|  | 	], | ||||||
|  | 	"exclude": [ | ||||||
|  | 		"tests" | ||||||
|  | 	] | ||||||
|  | } | ||||||
| @@ -0,0 +1,19 @@ | |||||||
|  | /** | ||||||
|  |  * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. | ||||||
|  |  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | 'use strict'; | ||||||
|  |  | ||||||
|  | /* eslint-env node */ | ||||||
|  |  | ||||||
|  | const { builds } = require( '@ckeditor/ckeditor5-dev-utils' ); | ||||||
|  | const webpack = require( 'webpack' ); | ||||||
|  |  | ||||||
|  | module.exports = builds.getDllPluginWebpackConfig( webpack, { | ||||||
|  | 	themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' ), | ||||||
|  | 	packagePath: __dirname, | ||||||
|  | 	manifestPath: require.resolve( 'ckeditor5/build/ckeditor5-dll.manifest.json' ), | ||||||
|  | 	isDevelopmentMode: process.argv.includes( '--mode=development' ), | ||||||
|  | 	tsconfigPath: require.resolve( 'ckeditor5/tsconfig.dll.json' ) | ||||||
|  | } ); | ||||||
		Reference in New Issue
	
	Block a user