copy vendor
This commit is contained in:
parent
836a45f364
commit
576b129cc9
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
exec "$basedir/node" "$basedir/../nanoid/bin/nanoid.cjs" "$@"
|
||||||
|
else
|
||||||
|
exec node "$basedir/../nanoid/bin/nanoid.cjs" "$@"
|
||||||
|
fi
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
@ECHO off
|
||||||
|
GOTO start
|
||||||
|
:find_dp0
|
||||||
|
SET dp0=%~dp0
|
||||||
|
EXIT /b
|
||||||
|
:start
|
||||||
|
SETLOCAL
|
||||||
|
CALL :find_dp0
|
||||||
|
|
||||||
|
IF EXIST "%dp0%\node.exe" (
|
||||||
|
SET "_prog=%dp0%\node.exe"
|
||||||
|
) ELSE (
|
||||||
|
SET "_prog=node"
|
||||||
|
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||||
|
)
|
||||||
|
|
||||||
|
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\nanoid\bin\nanoid.cjs" %*
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env pwsh
|
||||||
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
|
|
||||||
|
$exe=""
|
||||||
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||||
|
# Fix case when both the Windows and Linux builds of Node
|
||||||
|
# are installed in the same directory
|
||||||
|
$exe=".exe"
|
||||||
|
}
|
||||||
|
$ret=0
|
||||||
|
if (Test-Path "$basedir/node$exe") {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "$basedir/node$exe" "$basedir/../nanoid/bin/nanoid.cjs" $args
|
||||||
|
} else {
|
||||||
|
& "$basedir/node$exe" "$basedir/../nanoid/bin/nanoid.cjs" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
} else {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "node$exe" "$basedir/../nanoid/bin/nanoid.cjs" $args
|
||||||
|
} else {
|
||||||
|
& "node$exe" "$basedir/../nanoid/bin/nanoid.cjs" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
}
|
||||||
|
exit $ret
|
||||||
|
|
@ -2,11 +2,7 @@
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
case `uname` in
|
case `uname` in
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
if [ -x "$basedir/node" ]; then
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,7 @@
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
case `uname` in
|
case `uname` in
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
if [ -x "$basedir/node" ]; then
|
||||||
|
|
|
||||||
|
|
@ -1,180 +0,0 @@
|
||||||
Changelog
|
|
||||||
=========
|
|
||||||
|
|
||||||
All changes in the package are documented in the main repository. See: https://github.com/ckeditor/ckeditor5/blob/master/CHANGELOG.md.
|
|
||||||
|
|
||||||
Changes for the past releases are available below.
|
|
||||||
|
|
||||||
## [19.0.0](https://github.com/ckeditor/ckeditor5-clipboard/compare/v18.0.0...v19.0.0) (April 29, 2020)
|
|
||||||
|
|
||||||
### Other changes
|
|
||||||
|
|
||||||
* Handled `paste` and `drop` events no longer propagate up the DOM tree. Closes [ckeditor/ckeditor5#6464](https://github.com/ckeditor/ckeditor5/issues/6464). ([70aa7ba](https://github.com/ckeditor/ckeditor5-clipboard/commit/70aa7ba))
|
|
||||||
|
|
||||||
|
|
||||||
## [18.0.0](https://github.com/ckeditor/ckeditor5-clipboard/compare/v17.0.0...v18.0.0) (March 19, 2020)
|
|
||||||
|
|
||||||
Internal changes only (updated dependencies, documentation, etc.).
|
|
||||||
|
|
||||||
|
|
||||||
## [17.0.0](https://github.com/ckeditor/ckeditor5-clipboard/compare/v16.0.0...v17.0.0) (February 19, 2020)
|
|
||||||
|
|
||||||
Internal changes only (updated dependencies, documentation, etc.).
|
|
||||||
|
|
||||||
|
|
||||||
## [16.0.0](https://github.com/ckeditor/ckeditor5-clipboard/compare/v15.0.0...v16.0.0) (December 4, 2019)
|
|
||||||
|
|
||||||
Internal changes only (updated dependencies, documentation, etc.).
|
|
||||||
|
|
||||||
|
|
||||||
## [15.0.0](https://github.com/ckeditor/ckeditor5-clipboard/compare/v12.0.2...v15.0.0) (October 23, 2019)
|
|
||||||
|
|
||||||
Internal changes only (updated dependencies, documentation, etc.).
|
|
||||||
|
|
||||||
|
|
||||||
## [12.0.2](https://github.com/ckeditor/ckeditor5-clipboard/compare/v12.0.1...v12.0.2) (August 26, 2019)
|
|
||||||
|
|
||||||
### Other changes
|
|
||||||
|
|
||||||
* The issue tracker for this package was moved to https://github.com/ckeditor/ckeditor5/issues. See [ckeditor/ckeditor5#1988](https://github.com/ckeditor/ckeditor5/issues/1988). ([b1782bb](https://github.com/ckeditor/ckeditor5-clipboard/commit/b1782bb))
|
|
||||||
|
|
||||||
|
|
||||||
## [12.0.1](https://github.com/ckeditor/ckeditor5-clipboard/compare/v12.0.0...v12.0.1) (July 10, 2019)
|
|
||||||
|
|
||||||
Internal changes only (updated dependencies, documentation, etc.).
|
|
||||||
|
|
||||||
|
|
||||||
## [12.0.0](https://github.com/ckeditor/ckeditor5-clipboard/compare/v11.0.2...v12.0.0) (July 4, 2019)
|
|
||||||
|
|
||||||
### Other changes
|
|
||||||
|
|
||||||
* New lines pasted as a plain text will always create a new paragraph. Closes [ckeditor/ckeditor5#1727](https://github.com/ckeditor/ckeditor5/issues/1727). ([f0eb3a0](https://github.com/ckeditor/ckeditor5-clipboard/commit/f0eb3a0))
|
|
||||||
|
|
||||||
### BREAKING CHANGES
|
|
||||||
|
|
||||||
* From now on, every new line pasted in the editor as a plain text, will create a new paragraph. Read more at [ckeditor/ckeditor5#1727](https://github.com/ckeditor/ckeditor5/issues/1727).
|
|
||||||
|
|
||||||
|
|
||||||
## [11.0.2](https://github.com/ckeditor/ckeditor5-clipboard/compare/v11.0.1...v11.0.2) (June 6, 2019)
|
|
||||||
|
|
||||||
Internal changes only (updated dependencies, documentation, etc.).
|
|
||||||
|
|
||||||
|
|
||||||
## [11.0.1](https://github.com/ckeditor/ckeditor5-clipboard/compare/v11.0.0...v11.0.1) (April 4, 2019)
|
|
||||||
|
|
||||||
### Bug fixes
|
|
||||||
|
|
||||||
* The DOM `drop` event will not bubble up if the `clipboardInput` event was handled. Closes [ckeditor/ckeditor5-upload#92](https://github.com/ckeditor/ckeditor5-upload/issues/92). ([5d14697](https://github.com/ckeditor/ckeditor5-clipboard/commit/5d14697))
|
|
||||||
|
|
||||||
|
|
||||||
## [11.0.0](https://github.com/ckeditor/ckeditor5-clipboard/compare/v10.0.4...v11.0.0) (February 28, 2019)
|
|
||||||
|
|
||||||
### BREAKING CHANGES
|
|
||||||
|
|
||||||
* Upgraded minimal versions of Node to `8.0.0` and npm to `5.7.1`. See: [ckeditor/ckeditor5#1507](https://github.com/ckeditor/ckeditor5/issues/1507). ([612ea3c](https://github.com/ckeditor/ckeditor5-cloud-services/commit/612ea3c))
|
|
||||||
|
|
||||||
|
|
||||||
## [10.0.4](https://github.com/ckeditor/ckeditor5-clipboard/compare/v10.0.3...v10.0.4) (December 5, 2018)
|
|
||||||
|
|
||||||
Internal changes only (updated dependencies, documentation, etc.).
|
|
||||||
|
|
||||||
|
|
||||||
## [10.0.3](https://github.com/ckeditor/ckeditor5-clipboard/compare/v10.0.2...v10.0.3) (October 8, 2018)
|
|
||||||
|
|
||||||
### Other changes
|
|
||||||
|
|
||||||
* The `Clipboard#inputTransformation` event is now emitted with an additional `dataTransfer` object. Closes [#54](https://github.com/ckeditor/ckeditor5-clipboard/issues/54) . ([f3589b4](https://github.com/ckeditor/ckeditor5-clipboard/commit/f3589b4))
|
|
||||||
|
|
||||||
|
|
||||||
## [10.0.2](https://github.com/ckeditor/ckeditor5-clipboard/compare/v10.0.1...v10.0.2) (July 18, 2018)
|
|
||||||
|
|
||||||
Internal changes only (updated dependencies, documentation, etc.).
|
|
||||||
|
|
||||||
|
|
||||||
## [10.0.1](https://github.com/ckeditor/ckeditor5-clipboard/compare/v10.0.0...v10.0.1) (June 21, 2018)
|
|
||||||
|
|
||||||
### Bug fixes
|
|
||||||
|
|
||||||
* Disabled the entire clipboard input pipeline when the editor is read-only. Closes [#48](https://github.com/ckeditor/ckeditor5-clipboard/issues/48). ([b40ec4b](https://github.com/ckeditor/ckeditor5-clipboard/commit/b40ec4b))
|
|
||||||
* When pasting a plain text, single new line characters should be converted to `<br>`s. Closes [ckeditor/ckeditor5#766](https://github.com/ckeditor/ckeditor5/issues/766). ([be21676](https://github.com/ckeditor/ckeditor5-clipboard/commit/be21676))
|
|
||||||
|
|
||||||
|
|
||||||
## [10.0.0](https://github.com/ckeditor/ckeditor5-clipboard/compare/v1.0.0-beta.4...v10.0.0) (April 25, 2018)
|
|
||||||
|
|
||||||
### Other changes
|
|
||||||
|
|
||||||
* Changed the license to GPL2+ only. See [ckeditor/ckeditor5#991](https://github.com/ckeditor/ckeditor5/issues/991). ([8c092af](https://github.com/ckeditor/ckeditor5-clipboard/commit/8c092af))
|
|
||||||
|
|
||||||
### BREAKING CHANGES
|
|
||||||
|
|
||||||
* The license under which CKEditor 5 is released has been changed from a triple GPL, LGPL and MPL license to a GPL2+ only. See [ckeditor/ckeditor5#991](https://github.com/ckeditor/ckeditor5/issues/991) for more information.
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.0-beta.4](https://github.com/ckeditor/ckeditor5-clipboard/compare/v1.0.0-beta.2...v1.0.0-beta.4) (April 19, 2018)
|
|
||||||
|
|
||||||
Internal changes only (updated dependencies, documentation, etc.).
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.0-beta.2](https://github.com/ckeditor/ckeditor5-clipboard/compare/v1.0.0-beta.1...v1.0.0-beta.2) (April 10, 2018)
|
|
||||||
|
|
||||||
Internal changes only (updated dependencies, documentation, etc.).
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.0-beta.1](https://github.com/ckeditor/ckeditor5-clipboard/compare/v1.0.0-alpha.2...v1.0.0-beta.1) (March 15, 2018)
|
|
||||||
|
|
||||||
Internal changes only (updated dependencies, documentation, etc.).
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.0-alpha.2](https://github.com/ckeditor/ckeditor5-clipboard/compare/v1.0.0-alpha.1...v1.0.0-alpha.2) (November 14, 2017)
|
|
||||||
|
|
||||||
Internal changes only (updated dependencies, documentation, etc.).
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.0-alpha.1](https://github.com/ckeditor/ckeditor5-clipboard/compare/v0.7.0...v1.0.0-alpha.1) (October 3, 2017)
|
|
||||||
|
|
||||||
Internal changes only (updated dependencies, documentation, etc.).
|
|
||||||
|
|
||||||
|
|
||||||
## [0.7.0](https://github.com/ckeditor/ckeditor5-clipboard/compare/v0.6.0...v0.7.0) (September 3, 2017)
|
|
||||||
|
|
||||||
### Bug fixes
|
|
||||||
|
|
||||||
* Whitespaces around inline elements will not be lost upon pasting. Closes [#24](https://github.com/ckeditor/ckeditor5-clipboard/issues/24). ([5888743](https://github.com/ckeditor/ckeditor5-clipboard/commit/5888743))
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* Added the `'dragover'` event to ClipboardObserver. ([00c7567](https://github.com/ckeditor/ckeditor5-clipboard/commit/00c7567))
|
|
||||||
* Added `dropRange` to the `drop` event and `targetRanges` to the `clipboardInput` event. Closes [#29](https://github.com/ckeditor/ckeditor5-clipboard/issues/29). ([86daed9](https://github.com/ckeditor/ckeditor5-clipboard/commit/86daed9))
|
|
||||||
* Disable pasting and cutting when the editor is read-only. Closes [#26](https://github.com/ckeditor/ckeditor5-clipboard/issues/26). ([0ba74d5](https://github.com/ckeditor/ckeditor5-clipboard/commit/0ba74d5))
|
|
||||||
* The viewport will be scrolled to the selection on paste. See ckeditor/ckeditor5-engine#660. ([9a0e20f](https://github.com/ckeditor/ckeditor5-clipboard/commit/9a0e20f))
|
|
||||||
|
|
||||||
|
|
||||||
## [0.6.0](https://github.com/ckeditor/ckeditor5-clipboard/compare/v0.5.0...v0.6.0) (May 7, 2017)
|
|
||||||
|
|
||||||
### Bug fixes
|
|
||||||
|
|
||||||
* Plain text data is now available in the clipboard when copying or cutting the editor contents. Closes [#11](https://github.com/ckeditor/ckeditor5-clipboard/issues/11). ([8a01e0f](https://github.com/ckeditor/ckeditor5-clipboard/commit/8a01e0f))
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* Introduced `DataTransfer#files` property. Change the clipboard input pipeline. Closes [#16](https://github.com/ckeditor/ckeditor5-clipboard/issues/16). ([e4e7e10](https://github.com/ckeditor/ckeditor5-clipboard/commit/e4e7e10))
|
|
||||||
|
|
||||||
### BREAKING CHANGES
|
|
||||||
|
|
||||||
* The `clipboardInput` event now contains only the `dataTransfer` property (`content` was removed). The separate `inputTransformation` event was introduced for the content transformations.
|
|
||||||
|
|
||||||
|
|
||||||
## [0.5.0](https://github.com/ckeditor/ckeditor5-clipboard/compare/v0.4.1...v0.5.0) (April 5, 2017)
|
|
||||||
|
|
||||||
### Other changes
|
|
||||||
|
|
||||||
* Aligned use of the `DataController` to the latest API. Closes [#14](https://github.com/ckeditor/ckeditor5-clipboard/issues/14). ([8f98e2b](https://github.com/ckeditor/ckeditor5-clipboard/commit/8f98e2b))
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* Named existing plugin(s). ([3d37f53](https://github.com/ckeditor/ckeditor5-clipboard/commit/3d37f53))
|
|
||||||
|
|
||||||
|
|
||||||
## [0.4.1](https://github.com/ckeditor/ckeditor5-clipboard/compare/v0.4.0...v0.4.1) (March 6, 2017)
|
|
||||||
|
|
||||||
Internal changes only (updated dependencies, documentation, etc.).
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
Software License Agreement
|
|
||||||
==========================
|
|
||||||
|
|
||||||
**CKEditor 5 clipboard feature** – https://github.com/ckeditor/ckeditor5-clipboard <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.
|
|
||||||
|
|
||||||
The following libraries are included in CKEditor under the [MIT license](https://opensource.org/licenses/MIT):
|
|
||||||
|
|
||||||
* Lodash - Copyright (c) JS Foundation and other contributors https://js.foundation/. Based on Underscore.js, copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors http://underscorejs.org/.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
CKEditor 5 clipboard feature
|
|
||||||
========================================
|
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard)
|
|
||||||
[](https://coveralls.io/github/ckeditor/ckeditor5?branch=master)
|
|
||||||
[](https://app.travis-ci.com/github/ckeditor/ckeditor5)
|
|
||||||
|
|
||||||
This package implements the clipboard (copy, cut, paste) support for CKEditor 5.
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
See the [`@ckeditor/ckeditor5-clipboard` package](https://ckeditor.com/docs/ckeditor5/latest/api/clipboard.html) page in [CKEditor 5 documentation](https://ckeditor.com/docs/ckeditor5/latest/).
|
|
||||||
|
|
||||||
## 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).
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"Copy selected content": "Keystroke description for assistive technologies: keystroke for copying selected content.",
|
|
||||||
"Paste content": "Keystroke description for assistive technologies: keystroke for pasting content.",
|
|
||||||
"Paste content as plain text": "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Arabic (https://app.transifex.com/ckeditor/teams/11143/ar/)\n"
|
|
||||||
"Language: ar\n"
|
|
||||||
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "انسخْ المحتوى المحدد"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "الصقْ المحتوى"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "الصقْ المحتوى كنص عادي"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Bulgarian (https://app.transifex.com/ckeditor/teams/11143/bg/)\n"
|
|
||||||
"Language: bg\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Копиране на избраното съдържание"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Поставяне на съдържанието"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Поставяне на съдържанието като обикновен текст"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Bengali (https://app.transifex.com/ckeditor/teams/11143/bn/)\n"
|
|
||||||
"Language: bn\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "সিলেক্ট করা কন্টেন্ট কপি করুন"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "কন্টেন্ট পেস্ট করুন"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "প্লেইন টেক্সট হিসেবে কন্টেন্ট পেস্ট করুন"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Catalan (https://app.transifex.com/ckeditor/teams/11143/ca/)\n"
|
|
||||||
"Language: ca\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Copia el contingut seleccionat"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Enganxa el contingut"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Enganxa el contingut com a text pla"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Czech (https://app.transifex.com/ckeditor/teams/11143/cs/)\n"
|
|
||||||
"Language: cs\n"
|
|
||||||
"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Zkopírovat vybraný obsah"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Vložit obsah"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Vyložit obsah jako prostý text"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Danish (https://app.transifex.com/ckeditor/teams/11143/da/)\n"
|
|
||||||
"Language: da\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Kopier markeret indhold"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Indsæt indhold"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Indsæt indhold som ren tekst"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: German (https://app.transifex.com/ckeditor/teams/11143/de/)\n"
|
|
||||||
"Language: de\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Markierten Inhalt kopieren"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Inhalt einfügen"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Inhalt als Klartext einfügen"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Greek (https://app.transifex.com/ckeditor/teams/11143/el/)\n"
|
|
||||||
"Language: el\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Αντιγραφή επιλεγμένου περιεχομένου"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Επικόλληση περιεχομένου"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Επικόλληση περιεχομένου ως απλό κείμενο"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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 "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Copy selected content"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Paste content"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Paste content as plain text"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Spanish (Colombia) (https://app.transifex.com/ckeditor/teams/11143/es_CO/)\n"
|
|
||||||
"Language: es_CO\n"
|
|
||||||
"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Copiar contenido seleccionado"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Pegar contenido"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Pegar contenido como texto plano"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Spanish (https://app.transifex.com/ckeditor/teams/11143/es/)\n"
|
|
||||||
"Language: es\n"
|
|
||||||
"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Copia el contenido seleccionado"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Pega el contenido"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Pega el contenido como texto sin formato"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Estonian (https://app.transifex.com/ckeditor/teams/11143/et/)\n"
|
|
||||||
"Language: et\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Kopeeri valitud sisu"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Kleebi sisu"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Kleebi sisu lihttekstina"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Finnish (https://app.transifex.com/ckeditor/teams/11143/fi/)\n"
|
|
||||||
"Language: fi\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Kopioi valittu sisältö"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Liitä sisältö"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Liitä sisältö pelkkänä tekstinä"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: French (https://app.transifex.com/ckeditor/teams/11143/fr/)\n"
|
|
||||||
"Language: fr\n"
|
|
||||||
"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Copier le contenu sélectionné"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Coller le contenu"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Coller le contenu sous forme de texte brut"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Hebrew (https://app.transifex.com/ckeditor/teams/11143/he/)\n"
|
|
||||||
"Language: he\n"
|
|
||||||
"Plural-Forms: nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "העתקת התוכן שנבחר"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "הדבקת תוכן"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "הדבקת תוכן כטקסט רגיל"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Hindi (https://app.transifex.com/ckeditor/teams/11143/hi/)\n"
|
|
||||||
"Language: hi\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "सेलेक्ट किए गए कॉन्टेंट को कॉपी करें"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "कॉन्टेंट पेस्ट करें"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "कॉन्टेंट को प्लेन टेक्स्ट के रूप में पेस्ट करें"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Croatian (https://app.transifex.com/ckeditor/teams/11143/hr/)\n"
|
|
||||||
"Language: hr\n"
|
|
||||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Kopiraj odabrani sadržaj"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Zalijepi sadržaj"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Zalijepi sadržaj kao čisti tekst"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Hungarian (https://app.transifex.com/ckeditor/teams/11143/hu/)\n"
|
|
||||||
"Language: hu\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Kiválasztott tartalom másolása"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Tartalom beillesztése"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Tartalom másolása egyszerű szövegként"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Indonesian (https://app.transifex.com/ckeditor/teams/11143/id/)\n"
|
|
||||||
"Language: id\n"
|
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Salin konten yang dipilih"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Tempelkan konten"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Tempelkan konten sebagai teks biasa"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Italian (https://app.transifex.com/ckeditor/teams/11143/it/)\n"
|
|
||||||
"Language: it\n"
|
|
||||||
"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Copia il contenuto selezionato"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Incolla il contenuto"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Incolla il contenuto come testo normale"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Japanese (https://app.transifex.com/ckeditor/teams/11143/ja/)\n"
|
|
||||||
"Language: ja\n"
|
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "選択したコンテンツをコピーする"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "コンテンツを貼り付ける"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "コンテンツをプレーンテキストとして貼り付ける"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Korean (https://app.transifex.com/ckeditor/teams/11143/ko/)\n"
|
|
||||||
"Language: ko\n"
|
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "선택된 콘텐츠 복사"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "콘텐츠 붙여넣기"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "콘텐츠를 일반 텍스트로 붙여넣기"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Lithuanian (https://app.transifex.com/ckeditor/teams/11143/lt/)\n"
|
|
||||||
"Language: lt\n"
|
|
||||||
"Plural-Forms: nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Kopijuoti pasirinktą turinį"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Įklijuoti turinį"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Įklijuoti turinį kaip paprastą tekstą"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Latvian (https://app.transifex.com/ckeditor/teams/11143/lv/)\n"
|
|
||||||
"Language: lv\n"
|
|
||||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Kopēt atlasīto saturu"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Ielīmēt saturu"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Ielīmēt saturu kā tekstu"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Malay (https://app.transifex.com/ckeditor/teams/11143/ms/)\n"
|
|
||||||
"Language: ms\n"
|
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Salin kandungan yang dipilih"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Tampal kandungan"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Tampal kandungan sebagai teks kosong"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Dutch (https://app.transifex.com/ckeditor/teams/11143/nl/)\n"
|
|
||||||
"Language: nl\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Kopieer geselecteerde inhoud"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Plak inhoud"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Plak inhoud als onbewerkte tekst"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Norwegian (https://app.transifex.com/ckeditor/teams/11143/no/)\n"
|
|
||||||
"Language: no\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Kopier valgt innhold"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Lim inn innhold"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Lim inn innhold som vanlig tekst"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Polish (https://app.transifex.com/ckeditor/teams/11143/pl/)\n"
|
|
||||||
"Language: pl\n"
|
|
||||||
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Kopiuje zaznaczoną zawartość"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Wkleja zawartość"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Wkleja zawartość jako zwykły tekst"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Portuguese (Brazil) (https://app.transifex.com/ckeditor/teams/11143/pt_BR/)\n"
|
|
||||||
"Language: pt_BR\n"
|
|
||||||
"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Copiar conteúdo selecionado"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Colar conteúdo"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Colar conteúdo como texto simples"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Portuguese (https://app.transifex.com/ckeditor/teams/11143/pt/)\n"
|
|
||||||
"Language: pt\n"
|
|
||||||
"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Copiar o conteúdo selecionado"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Colar o conteúdo"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Colar o conteúdo como texto sem formatação"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Romanian (https://app.transifex.com/ckeditor/teams/11143/ro/)\n"
|
|
||||||
"Language: ro\n"
|
|
||||||
"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Copiază conținutul selectat"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Lipește conținut"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Lipește conținutul ca text simplu"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Russian (https://app.transifex.com/ckeditor/teams/11143/ru/)\n"
|
|
||||||
"Language: ru\n"
|
|
||||||
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Копировать выбранное содержание"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Вставить содержание"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Вставить содержанрие в виде обычного текста"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Slovak (https://app.transifex.com/ckeditor/teams/11143/sk/)\n"
|
|
||||||
"Language: sk\n"
|
|
||||||
"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Skopírovať vybraný obsah"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Prilepiť obsah"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Prilepiť obsah iba ako text"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Serbian (https://app.transifex.com/ckeditor/teams/11143/sr/)\n"
|
|
||||||
"Language: sr\n"
|
|
||||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Kopiraj odabrani sadržaj"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Nalepi sadržaj"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Nalepi sadržaj kao običan tekst"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Swedish (https://app.transifex.com/ckeditor/teams/11143/sv/)\n"
|
|
||||||
"Language: sv\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Kopiera markerat innehåll"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Klistra in innehåll"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Klistra in innehåll som vanlig text"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Thai (https://app.transifex.com/ckeditor/teams/11143/th/)\n"
|
|
||||||
"Language: th\n"
|
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "คัดลอกเนื้อหาที่เลือกเอาไว้"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "วางเนื้อหา"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "วางเนื้อหาเป็นข้อความธรรมดา"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Turkish (https://app.transifex.com/ckeditor/teams/11143/tr/)\n"
|
|
||||||
"Language: tr\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Seçilen içeriği kopyala"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "İçeriği yapıştır"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "İçeriği düz metin olarak yapıştır"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Ukrainian (https://app.transifex.com/ckeditor/teams/11143/uk/)\n"
|
|
||||||
"Language: uk\n"
|
|
||||||
"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Копіювати вибраний вміст"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Вставити вміст"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Вставити вміст як простий текст"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Vietnamese (https://app.transifex.com/ckeditor/teams/11143/vi/)\n"
|
|
||||||
"Language: vi\n"
|
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "Sao chép nội dung đã chọn"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "Dán nội dung"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "Dán nội dung dưới dạng văn bản thuần túy"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Chinese (China) (https://app.transifex.com/ckeditor/teams/11143/zh_CN/)\n"
|
|
||||||
"Language: zh_CN\n"
|
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "复制选定的内容"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "粘贴内容"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "将内容粘贴为纯文本"
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# 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-Team: Chinese (Taiwan) (https://app.transifex.com/ckeditor/teams/11143/zh_TW/)\n"
|
|
||||||
"Language: zh_TW\n"
|
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for copying selected content."
|
|
||||||
msgid "Copy selected content"
|
|
||||||
msgstr "複製所選內容"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content."
|
|
||||||
msgid "Paste content"
|
|
||||||
msgstr "貼上內容"
|
|
||||||
|
|
||||||
msgctxt "Keystroke description for assistive technologies: keystroke for pasting content as plain text."
|
|
||||||
msgid "Paste content as plain text"
|
|
||||||
msgstr "將內容貼上為純文字"
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@ckeditor/ckeditor5-clipboard",
|
|
||||||
"version": "41.3.1",
|
|
||||||
"description": "Clipboard integration feature for CKEditor 5.",
|
|
||||||
"keywords": [
|
|
||||||
"ckeditor",
|
|
||||||
"ckeditor5",
|
|
||||||
"ckeditor 5",
|
|
||||||
"ckeditor5-feature",
|
|
||||||
"ckeditor5-plugin",
|
|
||||||
"ckeditor5-dll"
|
|
||||||
],
|
|
||||||
"type": "module",
|
|
||||||
"main": "src/index.js",
|
|
||||||
"dependencies": {
|
|
||||||
"@ckeditor/ckeditor5-core": "41.3.1",
|
|
||||||
"@ckeditor/ckeditor5-engine": "41.3.1",
|
|
||||||
"@ckeditor/ckeditor5-ui": "41.3.1",
|
|
||||||
"@ckeditor/ckeditor5-utils": "41.3.1",
|
|
||||||
"@ckeditor/ckeditor5-widget": "41.3.1",
|
|
||||||
"lodash-es": "4.17.21"
|
|
||||||
},
|
|
||||||
"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-clipboard"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"lang",
|
|
||||||
"src/**/*.js",
|
|
||||||
"src/**/*.d.ts",
|
|
||||||
"theme",
|
|
||||||
"ckeditor5-metadata.json",
|
|
||||||
"CHANGELOG.md"
|
|
||||||
],
|
|
||||||
"types": "src/index.d.ts"
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 { Clipboard, ClipboardPipeline, PastePlainText, DragDrop, DragDropTarget, DragDropBlockToolbar, ClipboardMarkersUtils } from './index.js';
|
|
||||||
declare module '@ckeditor/ckeditor5-core' {
|
|
||||||
interface PluginsMap {
|
|
||||||
[Clipboard.pluginName]: Clipboard;
|
|
||||||
[ClipboardPipeline.pluginName]: ClipboardPipeline;
|
|
||||||
[ClipboardMarkersUtils.pluginName]: ClipboardMarkersUtils;
|
|
||||||
[PastePlainText.pluginName]: PastePlainText;
|
|
||||||
[DragDrop.pluginName]: DragDrop;
|
|
||||||
[DragDropTarget.pluginName]: DragDropTarget;
|
|
||||||
[DragDropBlockToolbar.pluginName]: DragDropBlockToolbar;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/clipboard
|
|
||||||
*/
|
|
||||||
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
||||||
import ClipboardPipeline from './clipboardpipeline.js';
|
|
||||||
import DragDrop from './dragdrop.js';
|
|
||||||
import PastePlainText from './pasteplaintext.js';
|
|
||||||
import ClipboardMarkersUtils from './clipboardmarkersutils.js';
|
|
||||||
/**
|
|
||||||
* The clipboard feature.
|
|
||||||
*
|
|
||||||
* Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.
|
|
||||||
*
|
|
||||||
* This is a "glue" plugin which loads the following plugins:
|
|
||||||
* * {@link module:clipboard/clipboardpipeline~ClipboardPipeline}
|
|
||||||
* * {@link module:clipboard/dragdrop~DragDrop}
|
|
||||||
* * {@link module:clipboard/pasteplaintext~PastePlainText}
|
|
||||||
*/
|
|
||||||
export default class Clipboard extends Plugin {
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get pluginName(): "Clipboard";
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get requires(): readonly [typeof ClipboardMarkersUtils, typeof ClipboardPipeline, typeof DragDrop, typeof PastePlainText];
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
init(): void;
|
|
||||||
}
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/clipboard
|
|
||||||
*/
|
|
||||||
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
||||||
import ClipboardPipeline from './clipboardpipeline.js';
|
|
||||||
import DragDrop from './dragdrop.js';
|
|
||||||
import PastePlainText from './pasteplaintext.js';
|
|
||||||
import ClipboardMarkersUtils from './clipboardmarkersutils.js';
|
|
||||||
/**
|
|
||||||
* The clipboard feature.
|
|
||||||
*
|
|
||||||
* Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.
|
|
||||||
*
|
|
||||||
* This is a "glue" plugin which loads the following plugins:
|
|
||||||
* * {@link module:clipboard/clipboardpipeline~ClipboardPipeline}
|
|
||||||
* * {@link module:clipboard/dragdrop~DragDrop}
|
|
||||||
* * {@link module:clipboard/pasteplaintext~PastePlainText}
|
|
||||||
*/
|
|
||||||
export default class Clipboard extends Plugin {
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get pluginName() {
|
|
||||||
return 'Clipboard';
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get requires() {
|
|
||||||
return [ClipboardMarkersUtils, ClipboardPipeline, DragDrop, PastePlainText];
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
init() {
|
|
||||||
const editor = this.editor;
|
|
||||||
const t = this.editor.t;
|
|
||||||
// Add the information about the keystrokes to the accessibility database.
|
|
||||||
editor.accessibility.addKeystrokeInfos({
|
|
||||||
keystrokes: [
|
|
||||||
{
|
|
||||||
label: t('Copy selected content'),
|
|
||||||
keystroke: 'CTRL+C'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t('Paste content'),
|
|
||||||
keystroke: 'CTRL+V'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t('Paste content as plain text'),
|
|
||||||
keystroke: 'CTRL+SHIFT+V'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,200 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 { Plugin, type NonEmptyArray } from '@ckeditor/ckeditor5-core';
|
|
||||||
import { Range, type DocumentFragment, type Element, type DocumentSelection, type Selection, type Writer } from '@ckeditor/ckeditor5-engine';
|
|
||||||
/**
|
|
||||||
* Part of the clipboard logic. Responsible for collecting markers from selected fragments
|
|
||||||
* and restoring them with proper positions in pasted elements.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export default class ClipboardMarkersUtils extends Plugin {
|
|
||||||
/**
|
|
||||||
* Map of marker names that can be copied.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
private _markersToCopy;
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get pluginName(): "ClipboardMarkersUtils";
|
|
||||||
/**
|
|
||||||
* Registers marker name as copyable in clipboard pipeline.
|
|
||||||
*
|
|
||||||
* @param markerName Name of marker that can be copied.
|
|
||||||
* @param config Configuration that describes what can be performed on specified marker.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_registerMarkerToCopy(markerName: string, config: ClipboardMarkerConfiguration): void;
|
|
||||||
/**
|
|
||||||
* Performs copy markers on provided selection and paste it to fragment returned from `getCopiedFragment`.
|
|
||||||
*
|
|
||||||
* 1. Picks all markers in provided selection.
|
|
||||||
* 2. Inserts fake markers to document.
|
|
||||||
* 3. Gets copied selection fragment from document.
|
|
||||||
* 4. Removes fake elements from fragment and document.
|
|
||||||
* 5. Inserts markers in the place of removed fake markers.
|
|
||||||
*
|
|
||||||
* Due to selection modification, when inserting items, `getCopiedFragment` must *always* operate on `writer.model.document.selection'.
|
|
||||||
* Do not use any other custom selection object within callback, as this will lead to out-of-bounds exceptions in rare scenarios.
|
|
||||||
*
|
|
||||||
* @param action Type of clipboard action.
|
|
||||||
* @param writer An instance of the model writer.
|
|
||||||
* @param selection Selection to be checked.
|
|
||||||
* @param getCopiedFragment Callback that performs copy of selection and returns it as fragment.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_copySelectedFragmentWithMarkers(action: ClipboardMarkerRestrictedAction, selection: Selection | DocumentSelection, getCopiedFragment?: (writer: Writer) => DocumentFragment): DocumentFragment;
|
|
||||||
/**
|
|
||||||
* Performs paste of markers on already pasted element.
|
|
||||||
*
|
|
||||||
* 1. Inserts fake markers that are present in fragment element (such fragment will be processed in `getPastedDocumentElement`).
|
|
||||||
* 2. Calls `getPastedDocumentElement` and gets element that is inserted into root model.
|
|
||||||
* 3. Removes all fake markers present in transformed element.
|
|
||||||
* 4. Inserts new markers with removed fake markers ranges into pasted fragment.
|
|
||||||
*
|
|
||||||
* There are multiple edge cases that have to be considered before calling this function:
|
|
||||||
*
|
|
||||||
* * `markers` are inserted into the same element that must be later transformed inside `getPastedDocumentElement`.
|
|
||||||
* * Fake marker elements inside `getPastedDocumentElement` can be cloned, but their ranges cannot overlap.
|
|
||||||
* * If `duplicateOnPaste` is `true` in marker config then associated marker ID is regenerated before pasting.
|
|
||||||
*
|
|
||||||
* @param action Type of clipboard action.
|
|
||||||
* @param markers Object that maps marker name to corresponding range.
|
|
||||||
* @param getPastedDocumentElement Getter used to get target markers element.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_pasteMarkersIntoTransformedElement(markers: Record<string, Range> | Map<string, Range>, getPastedDocumentElement: (writer: Writer) => Element): Element;
|
|
||||||
/**
|
|
||||||
* Pastes document fragment with markers to document.
|
|
||||||
* If `duplicateOnPaste` is `true` in marker config then associated markers IDs
|
|
||||||
* are regenerated before pasting to avoid markers duplications in content.
|
|
||||||
*
|
|
||||||
* @param fragment Document fragment that should contain already processed by pipeline markers.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_pasteFragmentWithMarkers(fragment: DocumentFragment): Range;
|
|
||||||
/**
|
|
||||||
* In some situations we have to perform copy on selected fragment with certain markers. This function allows to temporarily bypass
|
|
||||||
* restrictions on markers that we want to copy.
|
|
||||||
*
|
|
||||||
* This function executes `executor()` callback. For the duration of the callback, if the clipboard pipeline is used to copy
|
|
||||||
* content, markers with the specified name will be copied to the clipboard as well.
|
|
||||||
*
|
|
||||||
* @param markerName Which markers should be copied.
|
|
||||||
* @param executor Callback executed.
|
|
||||||
* @param config Optional configuration flags used to copy (such like partial copy flag).
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_forceMarkersCopy(markerName: string, executor: VoidFunction, config?: ClipboardMarkerConfiguration): void;
|
|
||||||
/**
|
|
||||||
* Checks if marker can be copied.
|
|
||||||
*
|
|
||||||
* @param markerName Name of checked marker.
|
|
||||||
* @param action Type of clipboard action. If null then checks only if marker is registered as copyable.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_isMarkerCopyable(markerName: string, action: ClipboardMarkerRestrictedAction | null): boolean;
|
|
||||||
/**
|
|
||||||
* Checks if marker has any clipboard copy behavior configuration.
|
|
||||||
*
|
|
||||||
* @param markerName Name of checked marker.
|
|
||||||
*/
|
|
||||||
_hasMarkerConfiguration(markerName: string): boolean;
|
|
||||||
/**
|
|
||||||
* Returns marker's configuration flags passed during registration.
|
|
||||||
*
|
|
||||||
* @param markerName Name of marker that should be returned.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_getMarkerClipboardConfig(markerName: string): ClipboardMarkerConfiguration | null;
|
|
||||||
/**
|
|
||||||
* First step of copying markers. It looks for markers intersecting with given selection and inserts `$marker` elements
|
|
||||||
* at positions where document markers start or end. This way `$marker` elements can be easily copied together with
|
|
||||||
* the rest of the content of the selection.
|
|
||||||
*
|
|
||||||
* @param writer An instance of the model writer.
|
|
||||||
* @param selection Selection to be checked.
|
|
||||||
* @param action Type of clipboard action.
|
|
||||||
*/
|
|
||||||
private _insertFakeMarkersIntoSelection;
|
|
||||||
/**
|
|
||||||
* Returns array of markers that can be copied in specified selection.
|
|
||||||
*
|
|
||||||
* If marker cannot be copied partially (according to `copyPartiallySelected` configuration flag) and
|
|
||||||
* is not present entirely in any selection range then it will be skipped.
|
|
||||||
*
|
|
||||||
* @param writer An instance of the model writer.
|
|
||||||
* @param selection Selection which will be checked.
|
|
||||||
* @param action Type of clipboard action. If null then checks only if marker is registered as copyable.
|
|
||||||
*/
|
|
||||||
private _getCopyableMarkersFromSelection;
|
|
||||||
/**
|
|
||||||
* Picks all markers from markers map that can be pasted.
|
|
||||||
* If `duplicateOnPaste` is `true`, it regenerates their IDs to ensure uniqueness.
|
|
||||||
* If marker is not registered, it will be kept in the array anyway.
|
|
||||||
*
|
|
||||||
* @param markers Object that maps marker name to corresponding range.
|
|
||||||
* @param action Type of clipboard action. If null then checks only if marker is registered as copyable.
|
|
||||||
*/
|
|
||||||
private _getPasteMarkersFromRangeMap;
|
|
||||||
/**
|
|
||||||
* Inserts specified array of fake markers elements to document and assigns them `type` and `name` attributes.
|
|
||||||
* Fake markers elements are used to calculate position of markers on pasted fragment that were transformed during
|
|
||||||
* steps between copy and paste.
|
|
||||||
*
|
|
||||||
* @param writer An instance of the model writer.
|
|
||||||
* @param markers Array of markers that will be inserted.
|
|
||||||
*/
|
|
||||||
private _insertFakeMarkersElements;
|
|
||||||
/**
|
|
||||||
* Removes all `$marker` elements from the given document fragment.
|
|
||||||
*
|
|
||||||
* Returns an object where keys are marker names, and values are ranges corresponding to positions
|
|
||||||
* where `$marker` elements were inserted.
|
|
||||||
*
|
|
||||||
* If the document fragment had only one `$marker` element for given marker (start or end) the other boundary is set automatically
|
|
||||||
* (to the end or start of the document fragment, respectively).
|
|
||||||
*
|
|
||||||
* @param writer An instance of the model writer.
|
|
||||||
* @param rootElement The element to be checked.
|
|
||||||
*/
|
|
||||||
private _removeFakeMarkersInsideElement;
|
|
||||||
/**
|
|
||||||
* Returns array that contains list of fake markers with corresponding `$marker` elements.
|
|
||||||
*
|
|
||||||
* For each marker, there can be two `$marker` elements or only one (if the document fragment contained
|
|
||||||
* only the beginning or only the end of a marker).
|
|
||||||
*
|
|
||||||
* @param writer An instance of the model writer.
|
|
||||||
* @param rootElement The element to be checked.
|
|
||||||
*/
|
|
||||||
private _getAllFakeMarkersFromElement;
|
|
||||||
/**
|
|
||||||
* When copy of markers occurs we have to make sure that pasted markers have different names
|
|
||||||
* than source markers. This functions helps with assigning unique part to marker name to
|
|
||||||
* prevent duplicated markers error.
|
|
||||||
*
|
|
||||||
* @param name Name of marker
|
|
||||||
*/
|
|
||||||
private _getUniqueMarkerName;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Specifies which action is performed during clipboard event.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export type ClipboardMarkerRestrictedAction = 'copy' | 'cut' | 'dragstart';
|
|
||||||
/**
|
|
||||||
* Specifies behavior of markers during clipboard actions.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export type ClipboardMarkerConfiguration = {
|
|
||||||
allowedActions: NonEmptyArray<ClipboardMarkerRestrictedAction> | 'all';
|
|
||||||
copyPartiallySelected?: boolean;
|
|
||||||
duplicateOnPaste?: boolean;
|
|
||||||
};
|
|
||||||
|
|
@ -1,499 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/clipboardmarkersutils
|
|
||||||
*/
|
|
||||||
import { mapValues } from 'lodash-es';
|
|
||||||
import { uid } from '@ckeditor/ckeditor5-utils';
|
|
||||||
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
||||||
import { Range } from '@ckeditor/ckeditor5-engine';
|
|
||||||
/**
|
|
||||||
* Part of the clipboard logic. Responsible for collecting markers from selected fragments
|
|
||||||
* and restoring them with proper positions in pasted elements.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export default class ClipboardMarkersUtils extends Plugin {
|
|
||||||
constructor() {
|
|
||||||
super(...arguments);
|
|
||||||
/**
|
|
||||||
* Map of marker names that can be copied.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
this._markersToCopy = new Map();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get pluginName() {
|
|
||||||
return 'ClipboardMarkersUtils';
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Registers marker name as copyable in clipboard pipeline.
|
|
||||||
*
|
|
||||||
* @param markerName Name of marker that can be copied.
|
|
||||||
* @param config Configuration that describes what can be performed on specified marker.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_registerMarkerToCopy(markerName, config) {
|
|
||||||
this._markersToCopy.set(markerName, config);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Performs copy markers on provided selection and paste it to fragment returned from `getCopiedFragment`.
|
|
||||||
*
|
|
||||||
* 1. Picks all markers in provided selection.
|
|
||||||
* 2. Inserts fake markers to document.
|
|
||||||
* 3. Gets copied selection fragment from document.
|
|
||||||
* 4. Removes fake elements from fragment and document.
|
|
||||||
* 5. Inserts markers in the place of removed fake markers.
|
|
||||||
*
|
|
||||||
* Due to selection modification, when inserting items, `getCopiedFragment` must *always* operate on `writer.model.document.selection'.
|
|
||||||
* Do not use any other custom selection object within callback, as this will lead to out-of-bounds exceptions in rare scenarios.
|
|
||||||
*
|
|
||||||
* @param action Type of clipboard action.
|
|
||||||
* @param writer An instance of the model writer.
|
|
||||||
* @param selection Selection to be checked.
|
|
||||||
* @param getCopiedFragment Callback that performs copy of selection and returns it as fragment.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_copySelectedFragmentWithMarkers(action, selection, getCopiedFragment = writer => writer.model.getSelectedContent(writer.model.document.selection)) {
|
|
||||||
return this.editor.model.change(writer => {
|
|
||||||
const oldSelection = writer.model.document.selection;
|
|
||||||
// In some scenarios, such like in drag & drop, passed `selection` parameter is not actually
|
|
||||||
// the same `selection` as the `writer.model.document.selection` which means that `_insertFakeMarkersToSelection`
|
|
||||||
// is not affecting passed `selection` `start` and `end` positions but rather modifies `writer.model.document.selection`.
|
|
||||||
//
|
|
||||||
// It is critical due to fact that when we have selection that starts [ 0, 0 ] and ends at [ 1, 0 ]
|
|
||||||
// and after inserting fake marker it will point to such marker instead of new widget position at start: [ 1, 0 ] end: [2, 0 ].
|
|
||||||
// `writer.insert` modifies only original `writer.model.document.selection`.
|
|
||||||
writer.setSelection(selection);
|
|
||||||
const sourceSelectionInsertedMarkers = this._insertFakeMarkersIntoSelection(writer, writer.model.document.selection, action);
|
|
||||||
const fragment = getCopiedFragment(writer);
|
|
||||||
const fakeMarkersRangesInsideRange = this._removeFakeMarkersInsideElement(writer, fragment);
|
|
||||||
// <fake-marker> [Foo] Bar</fake-marker>
|
|
||||||
// ^ ^
|
|
||||||
// In `_insertFakeMarkersIntoSelection` call we inserted fake marker just before first element.
|
|
||||||
// The problem is that the first element can be start position of selection so insertion fake-marker
|
|
||||||
// before such element shifts selection (so selection that was at [0, 0] now is at [0, 1]).
|
|
||||||
// It means that inserted fake-marker is no longer present inside such selection and is orphaned.
|
|
||||||
// This function checks special case of such problem. Markers that are orphaned at the start position
|
|
||||||
// and end position in the same time. Basically it means that they overlaps whole element.
|
|
||||||
for (const [markerName, elements] of Object.entries(sourceSelectionInsertedMarkers)) {
|
|
||||||
fakeMarkersRangesInsideRange[markerName] || (fakeMarkersRangesInsideRange[markerName] = writer.createRangeIn(fragment));
|
|
||||||
for (const element of elements) {
|
|
||||||
writer.remove(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fragment.markers.clear();
|
|
||||||
for (const [markerName, range] of Object.entries(fakeMarkersRangesInsideRange)) {
|
|
||||||
fragment.markers.set(markerName, range);
|
|
||||||
}
|
|
||||||
// Revert back selection to previous one.
|
|
||||||
writer.setSelection(oldSelection);
|
|
||||||
return fragment;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Performs paste of markers on already pasted element.
|
|
||||||
*
|
|
||||||
* 1. Inserts fake markers that are present in fragment element (such fragment will be processed in `getPastedDocumentElement`).
|
|
||||||
* 2. Calls `getPastedDocumentElement` and gets element that is inserted into root model.
|
|
||||||
* 3. Removes all fake markers present in transformed element.
|
|
||||||
* 4. Inserts new markers with removed fake markers ranges into pasted fragment.
|
|
||||||
*
|
|
||||||
* There are multiple edge cases that have to be considered before calling this function:
|
|
||||||
*
|
|
||||||
* * `markers` are inserted into the same element that must be later transformed inside `getPastedDocumentElement`.
|
|
||||||
* * Fake marker elements inside `getPastedDocumentElement` can be cloned, but their ranges cannot overlap.
|
|
||||||
* * If `duplicateOnPaste` is `true` in marker config then associated marker ID is regenerated before pasting.
|
|
||||||
*
|
|
||||||
* @param action Type of clipboard action.
|
|
||||||
* @param markers Object that maps marker name to corresponding range.
|
|
||||||
* @param getPastedDocumentElement Getter used to get target markers element.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_pasteMarkersIntoTransformedElement(markers, getPastedDocumentElement) {
|
|
||||||
const pasteMarkers = this._getPasteMarkersFromRangeMap(markers);
|
|
||||||
return this.editor.model.change(writer => {
|
|
||||||
// Inserts fake markers into source fragment / element that is later transformed inside `getPastedDocumentElement`.
|
|
||||||
const sourceFragmentFakeMarkers = this._insertFakeMarkersElements(writer, pasteMarkers);
|
|
||||||
// Modifies document fragment (for example, cloning table cells) and then inserts it into the document.
|
|
||||||
const transformedElement = getPastedDocumentElement(writer);
|
|
||||||
// Removes markers in pasted and transformed fragment in root document.
|
|
||||||
const removedFakeMarkers = this._removeFakeMarkersInsideElement(writer, transformedElement);
|
|
||||||
// Cleans up fake markers inserted into source fragment (that one before transformation which is not pasted).
|
|
||||||
for (const element of Object.values(sourceFragmentFakeMarkers).flat()) {
|
|
||||||
writer.remove(element);
|
|
||||||
}
|
|
||||||
// Inserts to root document fake markers.
|
|
||||||
for (const [markerName, range] of Object.entries(removedFakeMarkers)) {
|
|
||||||
if (!writer.model.markers.has(markerName)) {
|
|
||||||
writer.addMarker(markerName, {
|
|
||||||
usingOperation: true,
|
|
||||||
affectsData: true,
|
|
||||||
range
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return transformedElement;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Pastes document fragment with markers to document.
|
|
||||||
* If `duplicateOnPaste` is `true` in marker config then associated markers IDs
|
|
||||||
* are regenerated before pasting to avoid markers duplications in content.
|
|
||||||
*
|
|
||||||
* @param fragment Document fragment that should contain already processed by pipeline markers.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_pasteFragmentWithMarkers(fragment) {
|
|
||||||
const pasteMarkers = this._getPasteMarkersFromRangeMap(fragment.markers);
|
|
||||||
fragment.markers.clear();
|
|
||||||
for (const copyableMarker of pasteMarkers) {
|
|
||||||
fragment.markers.set(copyableMarker.name, copyableMarker.range);
|
|
||||||
}
|
|
||||||
return this.editor.model.insertContent(fragment);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* In some situations we have to perform copy on selected fragment with certain markers. This function allows to temporarily bypass
|
|
||||||
* restrictions on markers that we want to copy.
|
|
||||||
*
|
|
||||||
* This function executes `executor()` callback. For the duration of the callback, if the clipboard pipeline is used to copy
|
|
||||||
* content, markers with the specified name will be copied to the clipboard as well.
|
|
||||||
*
|
|
||||||
* @param markerName Which markers should be copied.
|
|
||||||
* @param executor Callback executed.
|
|
||||||
* @param config Optional configuration flags used to copy (such like partial copy flag).
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_forceMarkersCopy(markerName, executor, config = {
|
|
||||||
allowedActions: 'all',
|
|
||||||
copyPartiallySelected: true,
|
|
||||||
duplicateOnPaste: true
|
|
||||||
}) {
|
|
||||||
const before = this._markersToCopy.get(markerName);
|
|
||||||
this._markersToCopy.set(markerName, config);
|
|
||||||
executor();
|
|
||||||
if (before) {
|
|
||||||
this._markersToCopy.set(markerName, before);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this._markersToCopy.delete(markerName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Checks if marker can be copied.
|
|
||||||
*
|
|
||||||
* @param markerName Name of checked marker.
|
|
||||||
* @param action Type of clipboard action. If null then checks only if marker is registered as copyable.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_isMarkerCopyable(markerName, action) {
|
|
||||||
const config = this._getMarkerClipboardConfig(markerName);
|
|
||||||
if (!config) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// If there is no action provided then only presence of marker is checked.
|
|
||||||
if (!action) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const { allowedActions } = config;
|
|
||||||
return allowedActions === 'all' || allowedActions.includes(action);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Checks if marker has any clipboard copy behavior configuration.
|
|
||||||
*
|
|
||||||
* @param markerName Name of checked marker.
|
|
||||||
*/
|
|
||||||
_hasMarkerConfiguration(markerName) {
|
|
||||||
return !!this._getMarkerClipboardConfig(markerName);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns marker's configuration flags passed during registration.
|
|
||||||
*
|
|
||||||
* @param markerName Name of marker that should be returned.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_getMarkerClipboardConfig(markerName) {
|
|
||||||
const [markerNamePrefix] = markerName.split(':');
|
|
||||||
return this._markersToCopy.get(markerNamePrefix) || null;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* First step of copying markers. It looks for markers intersecting with given selection and inserts `$marker` elements
|
|
||||||
* at positions where document markers start or end. This way `$marker` elements can be easily copied together with
|
|
||||||
* the rest of the content of the selection.
|
|
||||||
*
|
|
||||||
* @param writer An instance of the model writer.
|
|
||||||
* @param selection Selection to be checked.
|
|
||||||
* @param action Type of clipboard action.
|
|
||||||
*/
|
|
||||||
_insertFakeMarkersIntoSelection(writer, selection, action) {
|
|
||||||
const copyableMarkers = this._getCopyableMarkersFromSelection(writer, selection, action);
|
|
||||||
return this._insertFakeMarkersElements(writer, copyableMarkers);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns array of markers that can be copied in specified selection.
|
|
||||||
*
|
|
||||||
* If marker cannot be copied partially (according to `copyPartiallySelected` configuration flag) and
|
|
||||||
* is not present entirely in any selection range then it will be skipped.
|
|
||||||
*
|
|
||||||
* @param writer An instance of the model writer.
|
|
||||||
* @param selection Selection which will be checked.
|
|
||||||
* @param action Type of clipboard action. If null then checks only if marker is registered as copyable.
|
|
||||||
*/
|
|
||||||
_getCopyableMarkersFromSelection(writer, selection, action) {
|
|
||||||
const selectionRanges = Array.from(selection.getRanges());
|
|
||||||
// Picks all markers in provided ranges. Ensures that there are no duplications if
|
|
||||||
// there are multiple ranges that intersects with the same marker.
|
|
||||||
const markersInRanges = new Set(selectionRanges.flatMap(selectionRange => Array.from(writer.model.markers.getMarkersIntersectingRange(selectionRange))));
|
|
||||||
const isSelectionMarkerCopyable = (marker) => {
|
|
||||||
// Check if marker exists in configuration and provided action can be performed on it.
|
|
||||||
const isCopyable = this._isMarkerCopyable(marker.name, action);
|
|
||||||
if (!isCopyable) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Checks if configuration disallows to copy marker only if part of its content is selected.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// <marker-a> Hello [ World ] </marker-a>
|
|
||||||
// ^ selection
|
|
||||||
//
|
|
||||||
// In this scenario `marker-a` won't be copied because selection doesn't overlap its content entirely.
|
|
||||||
const { copyPartiallySelected } = this._getMarkerClipboardConfig(marker.name);
|
|
||||||
if (!copyPartiallySelected) {
|
|
||||||
const markerRange = marker.getRange();
|
|
||||||
return selectionRanges.some(selectionRange => selectionRange.containsRange(markerRange, true));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
return Array
|
|
||||||
.from(markersInRanges)
|
|
||||||
.filter(isSelectionMarkerCopyable)
|
|
||||||
.map((copyableMarker) => {
|
|
||||||
// During `dragstart` event original marker is still present in tree.
|
|
||||||
// It is removed after the clipboard drop event, so none of the copied markers are inserted at the end.
|
|
||||||
// It happens because there already markers with specified `marker.name` when clipboard is trying to insert data
|
|
||||||
// and it aborts inserting.
|
|
||||||
const name = action === 'dragstart' ? this._getUniqueMarkerName(copyableMarker.name) : copyableMarker.name;
|
|
||||||
return {
|
|
||||||
name,
|
|
||||||
range: copyableMarker.getRange()
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Picks all markers from markers map that can be pasted.
|
|
||||||
* If `duplicateOnPaste` is `true`, it regenerates their IDs to ensure uniqueness.
|
|
||||||
* If marker is not registered, it will be kept in the array anyway.
|
|
||||||
*
|
|
||||||
* @param markers Object that maps marker name to corresponding range.
|
|
||||||
* @param action Type of clipboard action. If null then checks only if marker is registered as copyable.
|
|
||||||
*/
|
|
||||||
_getPasteMarkersFromRangeMap(markers, action = null) {
|
|
||||||
const { model } = this.editor;
|
|
||||||
const entries = markers instanceof Map ? Array.from(markers.entries()) : Object.entries(markers);
|
|
||||||
return entries.flatMap(([markerName, range]) => {
|
|
||||||
if (!this._hasMarkerConfiguration(markerName)) {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
name: markerName,
|
|
||||||
range
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
if (this._isMarkerCopyable(markerName, action)) {
|
|
||||||
const copyMarkerConfig = this._getMarkerClipboardConfig(markerName);
|
|
||||||
const isInGraveyard = model.markers.has(markerName) &&
|
|
||||||
model.markers.get(markerName).getRange().root.rootName === '$graveyard';
|
|
||||||
if (copyMarkerConfig.duplicateOnPaste || isInGraveyard) {
|
|
||||||
markerName = this._getUniqueMarkerName(markerName);
|
|
||||||
}
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
name: markerName,
|
|
||||||
range
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Inserts specified array of fake markers elements to document and assigns them `type` and `name` attributes.
|
|
||||||
* Fake markers elements are used to calculate position of markers on pasted fragment that were transformed during
|
|
||||||
* steps between copy and paste.
|
|
||||||
*
|
|
||||||
* @param writer An instance of the model writer.
|
|
||||||
* @param markers Array of markers that will be inserted.
|
|
||||||
*/
|
|
||||||
_insertFakeMarkersElements(writer, markers) {
|
|
||||||
const mappedMarkers = {};
|
|
||||||
const sortedMarkers = markers
|
|
||||||
.flatMap(marker => {
|
|
||||||
const { start, end } = marker.range;
|
|
||||||
return [
|
|
||||||
{ position: start, marker, type: 'start' },
|
|
||||||
{ position: end, marker, type: 'end' }
|
|
||||||
];
|
|
||||||
})
|
|
||||||
// Markers position is sorted backwards to ensure that the insertion of fake markers will not change
|
|
||||||
// the position of the next markers.
|
|
||||||
.sort(({ position: posA }, { position: posB }) => posA.isBefore(posB) ? 1 : -1);
|
|
||||||
for (const { position, marker, type } of sortedMarkers) {
|
|
||||||
const fakeMarker = writer.createElement('$marker', {
|
|
||||||
'data-name': marker.name,
|
|
||||||
'data-type': type
|
|
||||||
});
|
|
||||||
if (!mappedMarkers[marker.name]) {
|
|
||||||
mappedMarkers[marker.name] = [];
|
|
||||||
}
|
|
||||||
mappedMarkers[marker.name].push(fakeMarker);
|
|
||||||
writer.insert(fakeMarker, position);
|
|
||||||
}
|
|
||||||
return mappedMarkers;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Removes all `$marker` elements from the given document fragment.
|
|
||||||
*
|
|
||||||
* Returns an object where keys are marker names, and values are ranges corresponding to positions
|
|
||||||
* where `$marker` elements were inserted.
|
|
||||||
*
|
|
||||||
* If the document fragment had only one `$marker` element for given marker (start or end) the other boundary is set automatically
|
|
||||||
* (to the end or start of the document fragment, respectively).
|
|
||||||
*
|
|
||||||
* @param writer An instance of the model writer.
|
|
||||||
* @param rootElement The element to be checked.
|
|
||||||
*/
|
|
||||||
_removeFakeMarkersInsideElement(writer, rootElement) {
|
|
||||||
const fakeMarkersElements = this._getAllFakeMarkersFromElement(writer, rootElement);
|
|
||||||
const fakeMarkersRanges = fakeMarkersElements.reduce((acc, fakeMarker) => {
|
|
||||||
const position = fakeMarker.markerElement && writer.createPositionBefore(fakeMarker.markerElement);
|
|
||||||
let prevFakeMarker = acc[fakeMarker.name];
|
|
||||||
// Handle scenario when tables clone cells with the same fake node. Example:
|
|
||||||
//
|
|
||||||
// <cell><fake-marker-a></cell> <cell><fake-marker-a></cell> <cell><fake-marker-a></cell>
|
|
||||||
// ^ cloned ^ cloned
|
|
||||||
//
|
|
||||||
// The easiest way to bypass this issue is to rename already existing in map nodes and
|
|
||||||
// set them new unique name.
|
|
||||||
let skipAssign = false;
|
|
||||||
if (prevFakeMarker && prevFakeMarker.start && prevFakeMarker.end) {
|
|
||||||
const config = this._getMarkerClipboardConfig(fakeMarker.name);
|
|
||||||
if (config.duplicateOnPaste) {
|
|
||||||
acc[this._getUniqueMarkerName(fakeMarker.name)] = acc[fakeMarker.name];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
skipAssign = true;
|
|
||||||
}
|
|
||||||
prevFakeMarker = null;
|
|
||||||
}
|
|
||||||
if (!skipAssign) {
|
|
||||||
acc[fakeMarker.name] = {
|
|
||||||
...prevFakeMarker,
|
|
||||||
[fakeMarker.type]: position
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (fakeMarker.markerElement) {
|
|
||||||
writer.remove(fakeMarker.markerElement);
|
|
||||||
}
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
// We cannot construct ranges directly in previous reduce because element ranges can overlap.
|
|
||||||
// In other words lets assume we have such scenario:
|
|
||||||
// <fake-marker-start /> <paragraph /> <fake-marker-2-start /> <fake-marker-end /> <fake-marker-2-end />
|
|
||||||
//
|
|
||||||
// We have to remove `fake-marker-start` firstly and then remove `fake-marker-2-start`.
|
|
||||||
// Removal of `fake-marker-2-start` affects `fake-marker-end` position so we cannot create
|
|
||||||
// connection between `fake-marker-start` and `fake-marker-end` without iterating whole set firstly.
|
|
||||||
return mapValues(fakeMarkersRanges, range => new Range(range.start || writer.createPositionFromPath(rootElement, [0]), range.end || writer.createPositionAt(rootElement, 'end')));
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns array that contains list of fake markers with corresponding `$marker` elements.
|
|
||||||
*
|
|
||||||
* For each marker, there can be two `$marker` elements or only one (if the document fragment contained
|
|
||||||
* only the beginning or only the end of a marker).
|
|
||||||
*
|
|
||||||
* @param writer An instance of the model writer.
|
|
||||||
* @param rootElement The element to be checked.
|
|
||||||
*/
|
|
||||||
_getAllFakeMarkersFromElement(writer, rootElement) {
|
|
||||||
const foundFakeMarkers = Array
|
|
||||||
.from(writer.createRangeIn(rootElement))
|
|
||||||
.flatMap(({ item }) => {
|
|
||||||
if (!item.is('element', '$marker')) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
const name = item.getAttribute('data-name');
|
|
||||||
const type = item.getAttribute('data-type');
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
markerElement: item,
|
|
||||||
name,
|
|
||||||
type
|
|
||||||
}
|
|
||||||
];
|
|
||||||
});
|
|
||||||
const prependFakeMarkers = [];
|
|
||||||
const appendFakeMarkers = [];
|
|
||||||
for (const fakeMarker of foundFakeMarkers) {
|
|
||||||
if (fakeMarker.type === 'end') {
|
|
||||||
// <fake-marker> [ phrase</fake-marker> phrase ]
|
|
||||||
// ^
|
|
||||||
// Handle case when marker is just before start of selection.
|
|
||||||
// Only end marker is inside selection.
|
|
||||||
const hasMatchingStartMarker = foundFakeMarkers.some(otherFakeMarker => otherFakeMarker.name === fakeMarker.name && otherFakeMarker.type === 'start');
|
|
||||||
if (!hasMatchingStartMarker) {
|
|
||||||
prependFakeMarkers.push({
|
|
||||||
markerElement: null,
|
|
||||||
name: fakeMarker.name,
|
|
||||||
type: 'start'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fakeMarker.type === 'start') {
|
|
||||||
// [<fake-marker>phrase]</fake-marker>
|
|
||||||
// ^
|
|
||||||
// Handle case when fake marker is after selection.
|
|
||||||
// Only start marker is inside selection.
|
|
||||||
const hasMatchingEndMarker = foundFakeMarkers.some(otherFakeMarker => otherFakeMarker.name === fakeMarker.name && otherFakeMarker.type === 'end');
|
|
||||||
if (!hasMatchingEndMarker) {
|
|
||||||
appendFakeMarkers.unshift({
|
|
||||||
markerElement: null,
|
|
||||||
name: fakeMarker.name,
|
|
||||||
type: 'end'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [
|
|
||||||
...prependFakeMarkers,
|
|
||||||
...foundFakeMarkers,
|
|
||||||
...appendFakeMarkers
|
|
||||||
];
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* When copy of markers occurs we have to make sure that pasted markers have different names
|
|
||||||
* than source markers. This functions helps with assigning unique part to marker name to
|
|
||||||
* prevent duplicated markers error.
|
|
||||||
*
|
|
||||||
* @param name Name of marker
|
|
||||||
*/
|
|
||||||
_getUniqueMarkerName(name) {
|
|
||||||
const parts = name.split(':');
|
|
||||||
const newId = uid().substring(1, 6);
|
|
||||||
// It looks like the marker already is UID marker so in this scenario just swap
|
|
||||||
// last part of marker name and assign new UID.
|
|
||||||
//
|
|
||||||
// example: comment:{ threadId }:{ id } => comment:{ threadId }:{ newId }
|
|
||||||
if (parts.length === 3) {
|
|
||||||
return `${parts.slice(0, 2).join(':')}:${newId}`;
|
|
||||||
}
|
|
||||||
// Assign new segment to marker name with id.
|
|
||||||
//
|
|
||||||
// example: comment => comment:{ newId }
|
|
||||||
return `${parts.join(':')}:${newId}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,312 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 { DataTransfer, DomEventObserver, type DomEventData, type EditingView, type ViewDocumentFragment, type ViewElement, type ViewRange } from '@ckeditor/ckeditor5-engine';
|
|
||||||
/**
|
|
||||||
* Clipboard events observer.
|
|
||||||
*
|
|
||||||
* Fires the following events:
|
|
||||||
*
|
|
||||||
* * {@link module:engine/view/document~Document#event:clipboardInput},
|
|
||||||
* * {@link module:engine/view/document~Document#event:paste},
|
|
||||||
* * {@link module:engine/view/document~Document#event:copy},
|
|
||||||
* * {@link module:engine/view/document~Document#event:cut},
|
|
||||||
* * {@link module:engine/view/document~Document#event:drop},
|
|
||||||
* * {@link module:engine/view/document~Document#event:dragover},
|
|
||||||
* * {@link module:engine/view/document~Document#event:dragging},
|
|
||||||
* * {@link module:engine/view/document~Document#event:dragstart},
|
|
||||||
* * {@link module:engine/view/document~Document#event:dragend},
|
|
||||||
* * {@link module:engine/view/document~Document#event:dragenter},
|
|
||||||
* * {@link module:engine/view/document~Document#event:dragleave}.
|
|
||||||
*
|
|
||||||
* **Note**: This observer is not available by default (ckeditor5-engine does not add it on its own).
|
|
||||||
* To make it available, it needs to be added to {@link module:engine/view/document~Document} by using
|
|
||||||
* the {@link module:engine/view/view~View#addObserver `View#addObserver()`} method. Alternatively, you can load the
|
|
||||||
* {@link module:clipboard/clipboard~Clipboard} plugin which adds this observer automatically (because it uses it).
|
|
||||||
*/
|
|
||||||
export default class ClipboardObserver extends DomEventObserver<'paste' | 'copy' | 'cut' | 'drop' | 'dragover' | 'dragstart' | 'dragend' | 'dragenter' | 'dragleave', ClipboardEventData> {
|
|
||||||
readonly domEventType: readonly ["paste", "copy", "cut", "drop", "dragover", "dragstart", "dragend", "dragenter", "dragleave"];
|
|
||||||
constructor(view: EditingView);
|
|
||||||
onDomEvent(domEvent: ClipboardEvent | DragEvent): void;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* The data of 'paste', 'copy', 'cut', 'drop', 'dragover', 'dragstart', 'dragend', 'dragenter' and 'dragleave' events.
|
|
||||||
*/
|
|
||||||
export interface ClipboardEventData {
|
|
||||||
/**
|
|
||||||
* The data transfer instance.
|
|
||||||
*/
|
|
||||||
dataTransfer: DataTransfer;
|
|
||||||
/**
|
|
||||||
* The position into which the content is dropped.
|
|
||||||
*/
|
|
||||||
dropRange?: ViewRange | null;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Fired as a continuation of the {@link module:engine/view/document~Document#event:paste} and
|
|
||||||
* {@link module:engine/view/document~Document#event:drop} events.
|
|
||||||
*
|
|
||||||
* It is a part of the {@glink framework/deep-dive/clipboard#input-pipeline clipboard input pipeline}.
|
|
||||||
*
|
|
||||||
* This event carries a `dataTransfer` object which comes from the clipboard and whose content should be processed
|
|
||||||
* and inserted into the editor.
|
|
||||||
*
|
|
||||||
* **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}
|
|
||||||
* needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}
|
|
||||||
* method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,
|
|
||||||
* the observer must be added manually.
|
|
||||||
*
|
|
||||||
* @see module:clipboard/clipboardobserver~ClipboardObserver
|
|
||||||
* @see module:clipboard/clipboard~Clipboard
|
|
||||||
*
|
|
||||||
* @eventName module:engine/view/document~Document#clipboardInput
|
|
||||||
* @param data The event data.
|
|
||||||
*/
|
|
||||||
export type ViewDocumentClipboardInputEvent = {
|
|
||||||
name: 'clipboardInput';
|
|
||||||
args: [data: DomEventData<ClipboardEvent | DragEvent> & ClipboardInputEventData];
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* The value of the {@link module:engine/view/document~Document#event:paste},
|
|
||||||
* {@link module:engine/view/document~Document#event:copy} and {@link module:engine/view/document~Document#event:cut} events.
|
|
||||||
*
|
|
||||||
* In order to access the clipboard data, use the `dataTransfer` property.
|
|
||||||
*/
|
|
||||||
export interface ClipboardInputEventData {
|
|
||||||
/**
|
|
||||||
* Data transfer instance.
|
|
||||||
*/
|
|
||||||
dataTransfer: DataTransfer;
|
|
||||||
/**
|
|
||||||
* Whether the event was triggered by a paste or a drop operation.
|
|
||||||
*/
|
|
||||||
method: 'paste' | 'drop';
|
|
||||||
/**
|
|
||||||
* The tree view element representing the target.
|
|
||||||
*/
|
|
||||||
target: ViewElement;
|
|
||||||
/**
|
|
||||||
* The ranges which are the target of the operation (usually – into which the content should be inserted).
|
|
||||||
* If the clipboard input was triggered by a paste operation, this property is not set. If by a drop operation,
|
|
||||||
* then it is the drop position (which can be different than the selection at the moment of the drop).
|
|
||||||
*/
|
|
||||||
targetRanges: Array<ViewRange> | null;
|
|
||||||
/**
|
|
||||||
* The content of clipboard input.
|
|
||||||
*/
|
|
||||||
content?: ViewDocumentFragment;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Fired when the user drags the content over one of the editing roots of the editor.
|
|
||||||
*
|
|
||||||
* Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.
|
|
||||||
*
|
|
||||||
* **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}
|
|
||||||
* needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}
|
|
||||||
* method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,
|
|
||||||
* the observer must be added manually.
|
|
||||||
*
|
|
||||||
* @see module:engine/view/document~Document#event:clipboardInput
|
|
||||||
*
|
|
||||||
* @eventName module:engine/view/document~Document#dragover
|
|
||||||
* @param data The event data.
|
|
||||||
*/
|
|
||||||
export type ViewDocumentDragOverEvent = {
|
|
||||||
name: 'dragover';
|
|
||||||
args: [data: DomEventData<DragEvent> & ClipboardEventData];
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Fired when the user dropped the content into one of the editing roots of the editor.
|
|
||||||
*
|
|
||||||
* Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.
|
|
||||||
*
|
|
||||||
* **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}
|
|
||||||
* needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}
|
|
||||||
* method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,
|
|
||||||
* the observer must be added manually.
|
|
||||||
*
|
|
||||||
* @see module:engine/view/document~Document#event:clipboardInput
|
|
||||||
*
|
|
||||||
* @eventName module:engine/view/document~Document#drop
|
|
||||||
* @param data The event data.
|
|
||||||
*/
|
|
||||||
export type ViewDocumentDropEvent = {
|
|
||||||
name: 'drop';
|
|
||||||
args: [data: DomEventData<DragEvent> & ClipboardEventData];
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Fired when the user pasted the content into one of the editing roots of the editor.
|
|
||||||
*
|
|
||||||
* Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.
|
|
||||||
*
|
|
||||||
* **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}
|
|
||||||
* needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}
|
|
||||||
* method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,
|
|
||||||
* the observer must be added manually.
|
|
||||||
*
|
|
||||||
* @see module:engine/view/document~Document#event:clipboardInput
|
|
||||||
*
|
|
||||||
* @eventName module:engine/view/document~Document#paste
|
|
||||||
* @param {module:clipboard/clipboardobserver~ClipboardEventData} data The event data.
|
|
||||||
*/
|
|
||||||
export type ViewDocumentPasteEvent = {
|
|
||||||
name: 'paste';
|
|
||||||
args: [data: DomEventData<ClipboardEvent> & ClipboardEventData];
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Fired when the user copied the content from one of the editing roots of the editor.
|
|
||||||
*
|
|
||||||
* Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.
|
|
||||||
*
|
|
||||||
* **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}
|
|
||||||
* needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}
|
|
||||||
* method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,
|
|
||||||
* the observer must be added manually.
|
|
||||||
*
|
|
||||||
* @see module:clipboard/clipboardobserver~ClipboardObserver
|
|
||||||
*
|
|
||||||
* @eventName module:engine/view/document~Document#copy
|
|
||||||
* @param data The event data.
|
|
||||||
*/
|
|
||||||
export type ViewDocumentCopyEvent = {
|
|
||||||
name: 'copy';
|
|
||||||
args: [data: DomEventData<ClipboardEvent> & ClipboardEventData];
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Fired when the user cut the content from one of the editing roots of the editor.
|
|
||||||
*
|
|
||||||
* Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.
|
|
||||||
*
|
|
||||||
* **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}
|
|
||||||
* needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}
|
|
||||||
* method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,
|
|
||||||
* the observer must be added manually.
|
|
||||||
*
|
|
||||||
* @see module:clipboard/clipboardobserver~ClipboardObserver
|
|
||||||
*
|
|
||||||
* @eventName module:engine/view/document~Document#cut
|
|
||||||
* @param data The event data.
|
|
||||||
*/
|
|
||||||
export type ViewDocumentCutEvent = {
|
|
||||||
name: 'cut';
|
|
||||||
args: [data: DomEventData<ClipboardEvent> & ClipboardEventData];
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Fired as a continuation of the {@link module:engine/view/document~Document#event:dragover} event.
|
|
||||||
*
|
|
||||||
* It is a part of the {@glink framework/deep-dive/clipboard#input-pipeline clipboard input pipeline}.
|
|
||||||
*
|
|
||||||
* This event carries a `dataTransfer` object which comes from the clipboard and whose content should be processed
|
|
||||||
* and inserted into the editor.
|
|
||||||
*
|
|
||||||
* **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}
|
|
||||||
* needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}
|
|
||||||
* method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,
|
|
||||||
* the observer must be added manually.
|
|
||||||
*
|
|
||||||
* @see module:clipboard/clipboardobserver~ClipboardObserver
|
|
||||||
* @see module:clipboard/clipboard~Clipboard
|
|
||||||
*
|
|
||||||
* @eventName module:engine/view/document~Document#dragging
|
|
||||||
* @param data The event data.
|
|
||||||
*/
|
|
||||||
export type ViewDocumentDraggingEvent = {
|
|
||||||
name: 'dragging';
|
|
||||||
args: [data: DomEventData<DragEvent> & DraggingEventData];
|
|
||||||
};
|
|
||||||
export interface DraggingEventData {
|
|
||||||
/**
|
|
||||||
* The data transfer instance.
|
|
||||||
*/
|
|
||||||
dataTransfer: DataTransfer;
|
|
||||||
/**
|
|
||||||
* Whether the event was triggered by a paste or a drop operation.
|
|
||||||
*/
|
|
||||||
method: 'dragover';
|
|
||||||
/**
|
|
||||||
* The tree view element representing the target.
|
|
||||||
*/
|
|
||||||
target: Element;
|
|
||||||
/**
|
|
||||||
* Ranges which are the target of the operation (usually – into which the content should be inserted).
|
|
||||||
* It is the drop position (which can be different than the selection at the moment of drop).
|
|
||||||
*/
|
|
||||||
targetRanges: Array<ViewRange> | null;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Fired when the user starts dragging the content in one of the editing roots of the editor.
|
|
||||||
*
|
|
||||||
* Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.
|
|
||||||
*
|
|
||||||
* **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}
|
|
||||||
* needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}
|
|
||||||
* method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,
|
|
||||||
* the observer must be added manually.
|
|
||||||
*
|
|
||||||
* @see module:engine/view/document~Document#event:clipboardInput
|
|
||||||
*
|
|
||||||
* @eventName module:engine/view/document~Document#dragstart
|
|
||||||
* @param data The event data.
|
|
||||||
*/
|
|
||||||
export type ViewDocumentDragStartEvent = {
|
|
||||||
name: 'dragstart';
|
|
||||||
args: [data: DomEventData<DragEvent> & ClipboardEventData];
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Fired when the user ended dragging the content.
|
|
||||||
*
|
|
||||||
* Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.
|
|
||||||
*
|
|
||||||
* **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}
|
|
||||||
* needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}
|
|
||||||
* method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,
|
|
||||||
* the observer must be added manually.
|
|
||||||
*
|
|
||||||
* @see module:engine/view/document~Document#event:clipboardInput
|
|
||||||
*
|
|
||||||
* @eventName module:engine/view/document~Document#dragend
|
|
||||||
* @param data The event data.
|
|
||||||
*/
|
|
||||||
export type ViewDocumentDragEndEvent = {
|
|
||||||
name: 'dragend';
|
|
||||||
args: [data: DomEventData<DragEvent> & ClipboardEventData];
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Fired when the user drags the content into one of the editing roots of the editor.
|
|
||||||
*
|
|
||||||
* Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.
|
|
||||||
*
|
|
||||||
* **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}
|
|
||||||
* needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}
|
|
||||||
* method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,
|
|
||||||
* the observer must be added manually.
|
|
||||||
*
|
|
||||||
* @see module:engine/view/document~Document#event:clipboardInput
|
|
||||||
*
|
|
||||||
* @eventName module:engine/view/document~Document#dragenter
|
|
||||||
* @param data The event data.
|
|
||||||
*/
|
|
||||||
export type ViewDocumentDragEnterEvent = {
|
|
||||||
name: 'dragenter';
|
|
||||||
args: [data: DomEventData<DragEvent> & ClipboardEventData];
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Fired when the user drags the content out of one of the editing roots of the editor.
|
|
||||||
*
|
|
||||||
* Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.
|
|
||||||
*
|
|
||||||
* **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}
|
|
||||||
* needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}
|
|
||||||
* method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,
|
|
||||||
* the observer must be added manually.
|
|
||||||
*
|
|
||||||
* @see module:engine/view/document~Document#event:clipboardInput
|
|
||||||
*
|
|
||||||
* @eventName module:engine/view/document~Document#dragleave
|
|
||||||
* @param data The event data.
|
|
||||||
*/
|
|
||||||
export type ViewDocumentDragLeaveEvent = {
|
|
||||||
name: 'dragleave';
|
|
||||||
args: [data: DomEventData<DragEvent> & ClipboardEventData];
|
|
||||||
};
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/clipboardobserver
|
|
||||||
*/
|
|
||||||
import { EventInfo } from '@ckeditor/ckeditor5-utils';
|
|
||||||
import { DataTransfer, DomEventObserver } from '@ckeditor/ckeditor5-engine';
|
|
||||||
/**
|
|
||||||
* Clipboard events observer.
|
|
||||||
*
|
|
||||||
* Fires the following events:
|
|
||||||
*
|
|
||||||
* * {@link module:engine/view/document~Document#event:clipboardInput},
|
|
||||||
* * {@link module:engine/view/document~Document#event:paste},
|
|
||||||
* * {@link module:engine/view/document~Document#event:copy},
|
|
||||||
* * {@link module:engine/view/document~Document#event:cut},
|
|
||||||
* * {@link module:engine/view/document~Document#event:drop},
|
|
||||||
* * {@link module:engine/view/document~Document#event:dragover},
|
|
||||||
* * {@link module:engine/view/document~Document#event:dragging},
|
|
||||||
* * {@link module:engine/view/document~Document#event:dragstart},
|
|
||||||
* * {@link module:engine/view/document~Document#event:dragend},
|
|
||||||
* * {@link module:engine/view/document~Document#event:dragenter},
|
|
||||||
* * {@link module:engine/view/document~Document#event:dragleave}.
|
|
||||||
*
|
|
||||||
* **Note**: This observer is not available by default (ckeditor5-engine does not add it on its own).
|
|
||||||
* To make it available, it needs to be added to {@link module:engine/view/document~Document} by using
|
|
||||||
* the {@link module:engine/view/view~View#addObserver `View#addObserver()`} method. Alternatively, you can load the
|
|
||||||
* {@link module:clipboard/clipboard~Clipboard} plugin which adds this observer automatically (because it uses it).
|
|
||||||
*/
|
|
||||||
export default class ClipboardObserver extends DomEventObserver {
|
|
||||||
constructor(view) {
|
|
||||||
super(view);
|
|
||||||
this.domEventType = [
|
|
||||||
'paste', 'copy', 'cut', 'drop', 'dragover', 'dragstart', 'dragend', 'dragenter', 'dragleave'
|
|
||||||
];
|
|
||||||
const viewDocument = this.document;
|
|
||||||
this.listenTo(viewDocument, 'paste', handleInput('clipboardInput'), { priority: 'low' });
|
|
||||||
this.listenTo(viewDocument, 'drop', handleInput('clipboardInput'), { priority: 'low' });
|
|
||||||
this.listenTo(viewDocument, 'dragover', handleInput('dragging'), { priority: 'low' });
|
|
||||||
function handleInput(type) {
|
|
||||||
return (evt, data) => {
|
|
||||||
data.preventDefault();
|
|
||||||
const targetRanges = data.dropRange ? [data.dropRange] : null;
|
|
||||||
const eventInfo = new EventInfo(viewDocument, type);
|
|
||||||
viewDocument.fire(eventInfo, {
|
|
||||||
dataTransfer: data.dataTransfer,
|
|
||||||
method: evt.name,
|
|
||||||
targetRanges,
|
|
||||||
target: data.target,
|
|
||||||
domEvent: data.domEvent
|
|
||||||
});
|
|
||||||
// If CKEditor handled the input, do not bubble the original event any further.
|
|
||||||
// This helps external integrations recognize that fact and act accordingly.
|
|
||||||
// https://github.com/ckeditor/ckeditor5-upload/issues/92
|
|
||||||
if (eventInfo.stop.called) {
|
|
||||||
data.stopPropagation();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onDomEvent(domEvent) {
|
|
||||||
const nativeDataTransfer = 'clipboardData' in domEvent ? domEvent.clipboardData : domEvent.dataTransfer;
|
|
||||||
const cacheFiles = domEvent.type == 'drop' || domEvent.type == 'paste';
|
|
||||||
const evtData = {
|
|
||||||
dataTransfer: new DataTransfer(nativeDataTransfer, { cacheFiles })
|
|
||||||
};
|
|
||||||
if (domEvent.type == 'drop' || domEvent.type == 'dragover') {
|
|
||||||
evtData.dropRange = getDropViewRange(this.view, domEvent);
|
|
||||||
}
|
|
||||||
this.fire(domEvent.type, domEvent, evtData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function getDropViewRange(view, domEvent) {
|
|
||||||
const domDoc = domEvent.target.ownerDocument;
|
|
||||||
const x = domEvent.clientX;
|
|
||||||
const y = domEvent.clientY;
|
|
||||||
let domRange;
|
|
||||||
// Webkit & Blink.
|
|
||||||
if (domDoc.caretRangeFromPoint && domDoc.caretRangeFromPoint(x, y)) {
|
|
||||||
domRange = domDoc.caretRangeFromPoint(x, y);
|
|
||||||
}
|
|
||||||
// FF.
|
|
||||||
else if (domEvent.rangeParent) {
|
|
||||||
domRange = domDoc.createRange();
|
|
||||||
domRange.setStart(domEvent.rangeParent, domEvent.rangeOffset);
|
|
||||||
domRange.collapse(true);
|
|
||||||
}
|
|
||||||
if (domRange) {
|
|
||||||
return view.domConverter.domRangeToView(domRange);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
@ -1,265 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/clipboardpipeline
|
|
||||||
*/
|
|
||||||
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
||||||
import type { DataTransfer, DocumentFragment, Range, ViewDocumentFragment, ViewRange, Selection, DocumentSelection } from '@ckeditor/ckeditor5-engine';
|
|
||||||
import ClipboardMarkersUtils from './clipboardmarkersutils.js';
|
|
||||||
/**
|
|
||||||
* The clipboard pipeline feature. It is responsible for intercepting the `paste` and `drop` events and
|
|
||||||
* passing the pasted content through a series of events in order to insert it into the editor's content.
|
|
||||||
* It also handles the `cut` and `copy` events to fill the native clipboard with the serialized editor's data.
|
|
||||||
*
|
|
||||||
* # Input pipeline
|
|
||||||
*
|
|
||||||
* The behavior of the default handlers (all at a `low` priority):
|
|
||||||
*
|
|
||||||
* ## Event: `paste` or `drop`
|
|
||||||
*
|
|
||||||
* 1. Translates the event data.
|
|
||||||
* 2. Fires the {@link module:engine/view/document~Document#event:clipboardInput `view.Document#clipboardInput`} event.
|
|
||||||
*
|
|
||||||
* ## Event: `view.Document#clipboardInput`
|
|
||||||
*
|
|
||||||
* 1. If the `data.content` event field is already set (by some listener on a higher priority), it takes this content and fires the event
|
|
||||||
* from the last point.
|
|
||||||
* 2. Otherwise, it retrieves `text/html` or `text/plain` from `data.dataTransfer`.
|
|
||||||
* 3. Normalizes the raw data by applying simple filters on string data.
|
|
||||||
* 4. Processes the raw data to {@link module:engine/view/documentfragment~DocumentFragment `view.DocumentFragment`} with the
|
|
||||||
* {@link module:engine/controller/datacontroller~DataController#htmlProcessor `DataController#htmlProcessor`}.
|
|
||||||
* 5. Fires the {@link module:clipboard/clipboardpipeline~ClipboardPipeline#event:inputTransformation
|
|
||||||
* `ClipboardPipeline#inputTransformation`} event with the view document fragment in the `data.content` event field.
|
|
||||||
*
|
|
||||||
* ## Event: `ClipboardPipeline#inputTransformation`
|
|
||||||
*
|
|
||||||
* 1. Converts {@link module:engine/view/documentfragment~DocumentFragment `view.DocumentFragment`} from the `data.content` field to
|
|
||||||
* {@link module:engine/model/documentfragment~DocumentFragment `model.DocumentFragment`}.
|
|
||||||
* 2. Fires the {@link module:clipboard/clipboardpipeline~ClipboardPipeline#event:contentInsertion `ClipboardPipeline#contentInsertion`}
|
|
||||||
* event with the model document fragment in the `data.content` event field.
|
|
||||||
* **Note**: The `ClipboardPipeline#contentInsertion` event is fired within a model change block to allow other handlers
|
|
||||||
* to run in the same block without post-fixers called in between (i.e., the selection post-fixer).
|
|
||||||
*
|
|
||||||
* ## Event: `ClipboardPipeline#contentInsertion`
|
|
||||||
*
|
|
||||||
* 1. Calls {@link module:engine/model/model~Model#insertContent `model.insertContent()`} to insert `data.content`
|
|
||||||
* at the current selection position.
|
|
||||||
*
|
|
||||||
* # Output pipeline
|
|
||||||
*
|
|
||||||
* The behavior of the default handlers (all at a `low` priority):
|
|
||||||
*
|
|
||||||
* ## Event: `copy`, `cut` or `dragstart`
|
|
||||||
*
|
|
||||||
* 1. Retrieves the selected {@link module:engine/model/documentfragment~DocumentFragment `model.DocumentFragment`} by calling
|
|
||||||
* {@link module:engine/model/model~Model#getSelectedContent `model#getSelectedContent()`}.
|
|
||||||
* 2. Converts the model document fragment to {@link module:engine/view/documentfragment~DocumentFragment `view.DocumentFragment`}.
|
|
||||||
* 3. Fires the {@link module:engine/view/document~Document#event:clipboardOutput `view.Document#clipboardOutput`} event
|
|
||||||
* with the view document fragment in the `data.content` event field.
|
|
||||||
*
|
|
||||||
* ## Event: `view.Document#clipboardOutput`
|
|
||||||
*
|
|
||||||
* 1. Processes `data.content` to HTML and plain text with the
|
|
||||||
* {@link module:engine/controller/datacontroller~DataController#htmlProcessor `DataController#htmlProcessor`}.
|
|
||||||
* 2. Updates the `data.dataTransfer` data for `text/html` and `text/plain` with the processed data.
|
|
||||||
* 3. For the `cut` method, calls {@link module:engine/model/model~Model#deleteContent `model.deleteContent()`}
|
|
||||||
* on the current selection.
|
|
||||||
*
|
|
||||||
* Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.
|
|
||||||
*/
|
|
||||||
export default class ClipboardPipeline extends Plugin {
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get pluginName(): "ClipboardPipeline";
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get requires(): readonly [typeof ClipboardMarkersUtils];
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
init(): void;
|
|
||||||
/**
|
|
||||||
* Fires Clipboard `'outputTransformation'` event for given parameters.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_fireOutputTransformationEvent(dataTransfer: DataTransfer, selection: Selection | DocumentSelection, method: 'copy' | 'cut' | 'dragstart'): void;
|
|
||||||
/**
|
|
||||||
* The clipboard paste pipeline.
|
|
||||||
*/
|
|
||||||
private _setupPasteDrop;
|
|
||||||
/**
|
|
||||||
* The clipboard copy/cut pipeline.
|
|
||||||
*/
|
|
||||||
private _setupCopyCut;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Fired with the `content`, `dataTransfer`, `method`, and `targetRanges` properties:
|
|
||||||
*
|
|
||||||
* * The `content` which comes from the clipboard (it was pasted or dropped) should be processed in order to be inserted into the editor.
|
|
||||||
* * The `dataTransfer` object is available in case the transformation functions need access to the raw clipboard data.
|
|
||||||
* * The `method` indicates the original DOM event (for example `'drop'` or `'paste'`).
|
|
||||||
* * The `targetRanges` property is an array of view ranges (it is available only for `'drop'`).
|
|
||||||
*
|
|
||||||
* It is a part of the {@glink framework/deep-dive/clipboard#input-pipeline clipboard input pipeline}.
|
|
||||||
*
|
|
||||||
* **Note**: You should not stop this event if you want to change the input data. You should modify the `content` property instead.
|
|
||||||
*
|
|
||||||
* @see module:clipboard/clipboardobserver~ClipboardObserver
|
|
||||||
* @see module:clipboard/clipboardpipeline~ClipboardPipeline
|
|
||||||
*
|
|
||||||
* @eventName ~ClipboardPipeline#inputTransformation
|
|
||||||
* @param data The event data.
|
|
||||||
*/
|
|
||||||
export type ClipboardInputTransformationEvent = {
|
|
||||||
name: 'inputTransformation';
|
|
||||||
args: [data: ClipboardInputTransformationData];
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* The data of 'inputTransformation' event.
|
|
||||||
*/
|
|
||||||
export interface ClipboardInputTransformationData {
|
|
||||||
/**
|
|
||||||
* The event data.
|
|
||||||
* The content to be inserted into the editor. It can be modified by event listeners. Read more about the clipboard pipelines in
|
|
||||||
* the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.
|
|
||||||
*/
|
|
||||||
content: ViewDocumentFragment;
|
|
||||||
/**
|
|
||||||
* The data transfer instance.
|
|
||||||
*/
|
|
||||||
dataTransfer: DataTransfer;
|
|
||||||
/**
|
|
||||||
* The target drop ranges.
|
|
||||||
*/
|
|
||||||
targetRanges: Array<ViewRange> | null;
|
|
||||||
/**
|
|
||||||
* Whether the event was triggered by a paste or a drop operation.
|
|
||||||
*/
|
|
||||||
method: 'paste' | 'drop';
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Fired with the `content`, `dataTransfer`, `method`, and `targetRanges` properties:
|
|
||||||
*
|
|
||||||
* * The `content` which comes from the clipboard (was pasted or dropped) should be processed in order to be inserted into the editor.
|
|
||||||
* * The `dataTransfer` object is available in case the transformation functions need access to the raw clipboard data.
|
|
||||||
* * The `method` indicates the original DOM event (for example `'drop'` or `'paste'`).
|
|
||||||
* * The `targetRanges` property is an array of view ranges (it is available only for `'drop'`).
|
|
||||||
*
|
|
||||||
* Event handlers can modify the content according to the final insertion position.
|
|
||||||
*
|
|
||||||
* It is a part of the {@glink framework/deep-dive/clipboard#input-pipeline clipboard input pipeline}.
|
|
||||||
*
|
|
||||||
* **Note**: You should not stop this event if you want to change the input data. You should modify the `content` property instead.
|
|
||||||
*
|
|
||||||
* @see module:clipboard/clipboardobserver~ClipboardObserver
|
|
||||||
* @see module:clipboard/clipboardpipeline~ClipboardPipeline
|
|
||||||
* @see module:clipboard/clipboardpipeline~ClipboardPipeline#event:inputTransformation
|
|
||||||
*
|
|
||||||
* @eventName ~ClipboardPipeline#contentInsertion
|
|
||||||
* @param data The event data.
|
|
||||||
*/
|
|
||||||
export type ClipboardContentInsertionEvent = {
|
|
||||||
name: 'contentInsertion';
|
|
||||||
args: [data: ClipboardContentInsertionData];
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* The data of 'contentInsertion' event.
|
|
||||||
*/
|
|
||||||
export interface ClipboardContentInsertionData {
|
|
||||||
/**
|
|
||||||
* The content to be inserted into the editor.
|
|
||||||
* Read more about the clipboard pipelines in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.
|
|
||||||
*/
|
|
||||||
content: DocumentFragment;
|
|
||||||
/**
|
|
||||||
* Whether the event was triggered by a paste or a drop operation.
|
|
||||||
*/
|
|
||||||
method: 'paste' | 'drop';
|
|
||||||
/**
|
|
||||||
* The data transfer instance.
|
|
||||||
*/
|
|
||||||
dataTransfer: DataTransfer;
|
|
||||||
/**
|
|
||||||
* The target drop ranges.
|
|
||||||
*/
|
|
||||||
targetRanges: Array<ViewRange> | null;
|
|
||||||
/**
|
|
||||||
* The result of the `model.insertContent()` call
|
|
||||||
* (inserted by the event handler at a low priority).
|
|
||||||
*/
|
|
||||||
resultRange?: Range;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Fired on {@link module:engine/view/document~Document#event:copy} and {@link module:engine/view/document~Document#event:cut}
|
|
||||||
* with a copy of the selected content. The content can be processed before it ends up in the clipboard.
|
|
||||||
*
|
|
||||||
* It is a part of the {@glink framework/deep-dive/clipboard#output-pipeline clipboard output pipeline}.
|
|
||||||
*
|
|
||||||
* @see module:clipboard/clipboardobserver~ClipboardObserver
|
|
||||||
* @see module:clipboard/clipboardpipeline~ClipboardPipeline
|
|
||||||
*
|
|
||||||
* @eventName module:engine/view/document~Document#clipboardOutput
|
|
||||||
* @param data The event data.
|
|
||||||
*/
|
|
||||||
export type ViewDocumentClipboardOutputEvent = {
|
|
||||||
name: 'clipboardOutput';
|
|
||||||
args: [data: ViewDocumentClipboardOutputEventData];
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* The value of the 'clipboardOutput' event.
|
|
||||||
*/
|
|
||||||
export interface ViewDocumentClipboardOutputEventData {
|
|
||||||
/**
|
|
||||||
* The data transfer instance.
|
|
||||||
*
|
|
||||||
* @readonly
|
|
||||||
*/
|
|
||||||
dataTransfer: DataTransfer;
|
|
||||||
/**
|
|
||||||
* Content to be put into the clipboard. It can be modified by the event listeners.
|
|
||||||
* Read more about the clipboard pipelines in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.
|
|
||||||
*/
|
|
||||||
content: ViewDocumentFragment;
|
|
||||||
/**
|
|
||||||
* Whether the event was triggered by a copy or cut operation.
|
|
||||||
*/
|
|
||||||
method: 'copy' | 'cut' | 'dragstart';
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Fired on {@link module:engine/view/document~Document#event:copy}, {@link module:engine/view/document~Document#event:cut}
|
|
||||||
* and {@link module:engine/view/document~Document#event:dragstart}. The content can be processed before it ends up in the clipboard.
|
|
||||||
*
|
|
||||||
* It is a part of the {@glink framework/deep-dive/clipboard#output-pipeline clipboard output pipeline}.
|
|
||||||
*
|
|
||||||
* @eventName ~ClipboardPipeline#outputTransformation
|
|
||||||
* @param data The event data.
|
|
||||||
*/
|
|
||||||
export type ClipboardOutputTransformationEvent = {
|
|
||||||
name: 'outputTransformation';
|
|
||||||
args: [data: ClipboardOutputTransformationData];
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* The value of the 'outputTransformation' event.
|
|
||||||
*/
|
|
||||||
export interface ClipboardOutputTransformationData {
|
|
||||||
/**
|
|
||||||
* The data transfer instance.
|
|
||||||
*
|
|
||||||
* @readonly
|
|
||||||
*/
|
|
||||||
dataTransfer: DataTransfer;
|
|
||||||
/**
|
|
||||||
* Content to be put into the clipboard. It can be modified by the event listeners.
|
|
||||||
* Read more about the clipboard pipelines in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.
|
|
||||||
*/
|
|
||||||
content: DocumentFragment;
|
|
||||||
/**
|
|
||||||
* Whether the event was triggered by a copy or cut operation.
|
|
||||||
*/
|
|
||||||
method: 'copy' | 'cut' | 'dragstart';
|
|
||||||
}
|
|
||||||
|
|
@ -1,277 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/clipboardpipeline
|
|
||||||
*/
|
|
||||||
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
||||||
import { EventInfo } from '@ckeditor/ckeditor5-utils';
|
|
||||||
import ClipboardObserver from './clipboardobserver.js';
|
|
||||||
import plainTextToHtml from './utils/plaintexttohtml.js';
|
|
||||||
import normalizeClipboardHtml from './utils/normalizeclipboarddata.js';
|
|
||||||
import viewToPlainText from './utils/viewtoplaintext.js';
|
|
||||||
import ClipboardMarkersUtils from './clipboardmarkersutils.js';
|
|
||||||
// Input pipeline events overview:
|
|
||||||
//
|
|
||||||
// ┌──────────────────────┐ ┌──────────────────────┐
|
|
||||||
// │ view.Document │ │ view.Document │
|
|
||||||
// │ paste │ │ drop │
|
|
||||||
// └───────────┬──────────┘ └───────────┬──────────┘
|
|
||||||
// │ │
|
|
||||||
// └────────────────┌────────────────┘
|
|
||||||
// │
|
|
||||||
// ┌─────────V────────┐
|
|
||||||
// │ view.Document │ Retrieves text/html or text/plain from data.dataTransfer
|
|
||||||
// │ clipboardInput │ and processes it to view.DocumentFragment.
|
|
||||||
// └─────────┬────────┘
|
|
||||||
// │
|
|
||||||
// ┌───────────V───────────┐
|
|
||||||
// │ ClipboardPipeline │ Converts view.DocumentFragment to model.DocumentFragment.
|
|
||||||
// │ inputTransformation │
|
|
||||||
// └───────────┬───────────┘
|
|
||||||
// │
|
|
||||||
// ┌──────────V──────────┐
|
|
||||||
// │ ClipboardPipeline │ Calls model.insertContent().
|
|
||||||
// │ contentInsertion │
|
|
||||||
// └─────────────────────┘
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Output pipeline events overview:
|
|
||||||
//
|
|
||||||
// ┌──────────────────────┐ ┌──────────────────────┐
|
|
||||||
// │ view.Document │ │ view.Document │ Retrieves the selected model.DocumentFragment
|
|
||||||
// │ copy │ │ cut │ and fires the `outputTransformation` event.
|
|
||||||
// └───────────┬──────────┘ └───────────┬──────────┘
|
|
||||||
// │ │
|
|
||||||
// └────────────────┌────────────────┘
|
|
||||||
// │
|
|
||||||
// ┌───────────V───────────┐
|
|
||||||
// │ ClipboardPipeline │ Processes model.DocumentFragment and converts it to
|
|
||||||
// │ outputTransformation │ view.DocumentFragment.
|
|
||||||
// └───────────┬───────────┘
|
|
||||||
// │
|
|
||||||
// ┌─────────V────────┐
|
|
||||||
// │ view.Document │ Processes view.DocumentFragment to text/html and text/plain
|
|
||||||
// │ clipboardOutput │ and stores the results in data.dataTransfer.
|
|
||||||
// └──────────────────┘
|
|
||||||
//
|
|
||||||
/**
|
|
||||||
* The clipboard pipeline feature. It is responsible for intercepting the `paste` and `drop` events and
|
|
||||||
* passing the pasted content through a series of events in order to insert it into the editor's content.
|
|
||||||
* It also handles the `cut` and `copy` events to fill the native clipboard with the serialized editor's data.
|
|
||||||
*
|
|
||||||
* # Input pipeline
|
|
||||||
*
|
|
||||||
* The behavior of the default handlers (all at a `low` priority):
|
|
||||||
*
|
|
||||||
* ## Event: `paste` or `drop`
|
|
||||||
*
|
|
||||||
* 1. Translates the event data.
|
|
||||||
* 2. Fires the {@link module:engine/view/document~Document#event:clipboardInput `view.Document#clipboardInput`} event.
|
|
||||||
*
|
|
||||||
* ## Event: `view.Document#clipboardInput`
|
|
||||||
*
|
|
||||||
* 1. If the `data.content` event field is already set (by some listener on a higher priority), it takes this content and fires the event
|
|
||||||
* from the last point.
|
|
||||||
* 2. Otherwise, it retrieves `text/html` or `text/plain` from `data.dataTransfer`.
|
|
||||||
* 3. Normalizes the raw data by applying simple filters on string data.
|
|
||||||
* 4. Processes the raw data to {@link module:engine/view/documentfragment~DocumentFragment `view.DocumentFragment`} with the
|
|
||||||
* {@link module:engine/controller/datacontroller~DataController#htmlProcessor `DataController#htmlProcessor`}.
|
|
||||||
* 5. Fires the {@link module:clipboard/clipboardpipeline~ClipboardPipeline#event:inputTransformation
|
|
||||||
* `ClipboardPipeline#inputTransformation`} event with the view document fragment in the `data.content` event field.
|
|
||||||
*
|
|
||||||
* ## Event: `ClipboardPipeline#inputTransformation`
|
|
||||||
*
|
|
||||||
* 1. Converts {@link module:engine/view/documentfragment~DocumentFragment `view.DocumentFragment`} from the `data.content` field to
|
|
||||||
* {@link module:engine/model/documentfragment~DocumentFragment `model.DocumentFragment`}.
|
|
||||||
* 2. Fires the {@link module:clipboard/clipboardpipeline~ClipboardPipeline#event:contentInsertion `ClipboardPipeline#contentInsertion`}
|
|
||||||
* event with the model document fragment in the `data.content` event field.
|
|
||||||
* **Note**: The `ClipboardPipeline#contentInsertion` event is fired within a model change block to allow other handlers
|
|
||||||
* to run in the same block without post-fixers called in between (i.e., the selection post-fixer).
|
|
||||||
*
|
|
||||||
* ## Event: `ClipboardPipeline#contentInsertion`
|
|
||||||
*
|
|
||||||
* 1. Calls {@link module:engine/model/model~Model#insertContent `model.insertContent()`} to insert `data.content`
|
|
||||||
* at the current selection position.
|
|
||||||
*
|
|
||||||
* # Output pipeline
|
|
||||||
*
|
|
||||||
* The behavior of the default handlers (all at a `low` priority):
|
|
||||||
*
|
|
||||||
* ## Event: `copy`, `cut` or `dragstart`
|
|
||||||
*
|
|
||||||
* 1. Retrieves the selected {@link module:engine/model/documentfragment~DocumentFragment `model.DocumentFragment`} by calling
|
|
||||||
* {@link module:engine/model/model~Model#getSelectedContent `model#getSelectedContent()`}.
|
|
||||||
* 2. Converts the model document fragment to {@link module:engine/view/documentfragment~DocumentFragment `view.DocumentFragment`}.
|
|
||||||
* 3. Fires the {@link module:engine/view/document~Document#event:clipboardOutput `view.Document#clipboardOutput`} event
|
|
||||||
* with the view document fragment in the `data.content` event field.
|
|
||||||
*
|
|
||||||
* ## Event: `view.Document#clipboardOutput`
|
|
||||||
*
|
|
||||||
* 1. Processes `data.content` to HTML and plain text with the
|
|
||||||
* {@link module:engine/controller/datacontroller~DataController#htmlProcessor `DataController#htmlProcessor`}.
|
|
||||||
* 2. Updates the `data.dataTransfer` data for `text/html` and `text/plain` with the processed data.
|
|
||||||
* 3. For the `cut` method, calls {@link module:engine/model/model~Model#deleteContent `model.deleteContent()`}
|
|
||||||
* on the current selection.
|
|
||||||
*
|
|
||||||
* Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.
|
|
||||||
*/
|
|
||||||
export default class ClipboardPipeline extends Plugin {
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get pluginName() {
|
|
||||||
return 'ClipboardPipeline';
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get requires() {
|
|
||||||
return [ClipboardMarkersUtils];
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
init() {
|
|
||||||
const editor = this.editor;
|
|
||||||
const view = editor.editing.view;
|
|
||||||
view.addObserver(ClipboardObserver);
|
|
||||||
this._setupPasteDrop();
|
|
||||||
this._setupCopyCut();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Fires Clipboard `'outputTransformation'` event for given parameters.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_fireOutputTransformationEvent(dataTransfer, selection, method) {
|
|
||||||
const clipboardMarkersUtils = this.editor.plugins.get('ClipboardMarkersUtils');
|
|
||||||
this.editor.model.enqueueChange({ isUndoable: method === 'cut' }, () => {
|
|
||||||
const documentFragment = clipboardMarkersUtils._copySelectedFragmentWithMarkers(method, selection);
|
|
||||||
this.fire('outputTransformation', {
|
|
||||||
dataTransfer,
|
|
||||||
content: documentFragment,
|
|
||||||
method
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* The clipboard paste pipeline.
|
|
||||||
*/
|
|
||||||
_setupPasteDrop() {
|
|
||||||
const editor = this.editor;
|
|
||||||
const model = editor.model;
|
|
||||||
const view = editor.editing.view;
|
|
||||||
const viewDocument = view.document;
|
|
||||||
const clipboardMarkersUtils = this.editor.plugins.get('ClipboardMarkersUtils');
|
|
||||||
// Pasting is disabled when selection is in non-editable place.
|
|
||||||
// Dropping is disabled in drag and drop handler.
|
|
||||||
this.listenTo(viewDocument, 'clipboardInput', (evt, data) => {
|
|
||||||
if (data.method == 'paste' && !editor.model.canEditAt(editor.model.document.selection)) {
|
|
||||||
evt.stop();
|
|
||||||
}
|
|
||||||
}, { priority: 'highest' });
|
|
||||||
this.listenTo(viewDocument, 'clipboardInput', (evt, data) => {
|
|
||||||
const dataTransfer = data.dataTransfer;
|
|
||||||
let content;
|
|
||||||
// Some feature could already inject content in the higher priority event handler (i.e., codeBlock).
|
|
||||||
if (data.content) {
|
|
||||||
content = data.content;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let contentData = '';
|
|
||||||
if (dataTransfer.getData('text/html')) {
|
|
||||||
contentData = normalizeClipboardHtml(dataTransfer.getData('text/html'));
|
|
||||||
}
|
|
||||||
else if (dataTransfer.getData('text/plain')) {
|
|
||||||
contentData = plainTextToHtml(dataTransfer.getData('text/plain'));
|
|
||||||
}
|
|
||||||
content = this.editor.data.htmlProcessor.toView(contentData);
|
|
||||||
}
|
|
||||||
const eventInfo = new EventInfo(this, 'inputTransformation');
|
|
||||||
this.fire(eventInfo, {
|
|
||||||
content,
|
|
||||||
dataTransfer,
|
|
||||||
targetRanges: data.targetRanges,
|
|
||||||
method: data.method
|
|
||||||
});
|
|
||||||
// If CKEditor handled the input, do not bubble the original event any further.
|
|
||||||
// This helps external integrations recognize this fact and act accordingly.
|
|
||||||
// https://github.com/ckeditor/ckeditor5-upload/issues/92
|
|
||||||
if (eventInfo.stop.called) {
|
|
||||||
evt.stop();
|
|
||||||
}
|
|
||||||
view.scrollToTheSelection();
|
|
||||||
}, { priority: 'low' });
|
|
||||||
this.listenTo(this, 'inputTransformation', (evt, data) => {
|
|
||||||
if (data.content.isEmpty) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const dataController = this.editor.data;
|
|
||||||
// Convert the pasted content into a model document fragment.
|
|
||||||
// The conversion is contextual, but in this case an "all allowed" context is needed
|
|
||||||
// and for that we use the $clipboardHolder item.
|
|
||||||
const modelFragment = dataController.toModel(data.content, '$clipboardHolder');
|
|
||||||
if (modelFragment.childCount == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
evt.stop();
|
|
||||||
// Fire content insertion event in a single change block to allow other handlers to run in the same block
|
|
||||||
// without post-fixers called in between (i.e., the selection post-fixer).
|
|
||||||
model.change(() => {
|
|
||||||
this.fire('contentInsertion', {
|
|
||||||
content: modelFragment,
|
|
||||||
method: data.method,
|
|
||||||
dataTransfer: data.dataTransfer,
|
|
||||||
targetRanges: data.targetRanges
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}, { priority: 'low' });
|
|
||||||
this.listenTo(this, 'contentInsertion', (evt, data) => {
|
|
||||||
data.resultRange = clipboardMarkersUtils._pasteFragmentWithMarkers(data.content);
|
|
||||||
}, { priority: 'low' });
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* The clipboard copy/cut pipeline.
|
|
||||||
*/
|
|
||||||
_setupCopyCut() {
|
|
||||||
const editor = this.editor;
|
|
||||||
const modelDocument = editor.model.document;
|
|
||||||
const view = editor.editing.view;
|
|
||||||
const viewDocument = view.document;
|
|
||||||
const onCopyCut = (evt, data) => {
|
|
||||||
const dataTransfer = data.dataTransfer;
|
|
||||||
data.preventDefault();
|
|
||||||
this._fireOutputTransformationEvent(dataTransfer, modelDocument.selection, evt.name);
|
|
||||||
};
|
|
||||||
this.listenTo(viewDocument, 'copy', onCopyCut, { priority: 'low' });
|
|
||||||
this.listenTo(viewDocument, 'cut', (evt, data) => {
|
|
||||||
// Cutting is disabled when selection is in non-editable place.
|
|
||||||
// See: https://github.com/ckeditor/ckeditor5-clipboard/issues/26.
|
|
||||||
if (!editor.model.canEditAt(editor.model.document.selection)) {
|
|
||||||
data.preventDefault();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
onCopyCut(evt, data);
|
|
||||||
}
|
|
||||||
}, { priority: 'low' });
|
|
||||||
this.listenTo(this, 'outputTransformation', (evt, data) => {
|
|
||||||
const content = editor.data.toView(data.content);
|
|
||||||
viewDocument.fire('clipboardOutput', {
|
|
||||||
dataTransfer: data.dataTransfer,
|
|
||||||
content,
|
|
||||||
method: data.method
|
|
||||||
});
|
|
||||||
}, { priority: 'low' });
|
|
||||||
this.listenTo(viewDocument, 'clipboardOutput', (evt, data) => {
|
|
||||||
if (!data.content.isEmpty) {
|
|
||||||
data.dataTransfer.setData('text/html', this.editor.data.htmlProcessor.toData(data.content));
|
|
||||||
data.dataTransfer.setData('text/plain', viewToPlainText(data.content));
|
|
||||||
}
|
|
||||||
if (data.method == 'cut') {
|
|
||||||
editor.model.deleteContent(modelDocument.selection);
|
|
||||||
}
|
|
||||||
}, { priority: 'low' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,102 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/dragdrop
|
|
||||||
*/
|
|
||||||
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
||||||
import { Widget } from '@ckeditor/ckeditor5-widget';
|
|
||||||
import ClipboardPipeline from './clipboardpipeline.js';
|
|
||||||
import DragDropTarget from './dragdroptarget.js';
|
|
||||||
import DragDropBlockToolbar from './dragdropblocktoolbar.js';
|
|
||||||
import '../theme/clipboard.css';
|
|
||||||
/**
|
|
||||||
* The drag and drop feature. It works on top of the {@link module:clipboard/clipboardpipeline~ClipboardPipeline}.
|
|
||||||
*
|
|
||||||
* Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export default class DragDrop extends Plugin {
|
|
||||||
/**
|
|
||||||
* The live range over the original content that is being dragged.
|
|
||||||
*/
|
|
||||||
private _draggedRange;
|
|
||||||
/**
|
|
||||||
* The UID of current dragging that is used to verify if the drop started in the same editor as the drag start.
|
|
||||||
*
|
|
||||||
* **Note**: This is a workaround for broken 'dragend' events (they are not fired if the source text node got removed).
|
|
||||||
*/
|
|
||||||
private _draggingUid;
|
|
||||||
/**
|
|
||||||
* The reference to the model element that currently has a `draggable` attribute set (it is set while dragging).
|
|
||||||
*/
|
|
||||||
private _draggableElement;
|
|
||||||
/**
|
|
||||||
* A delayed callback removing draggable attributes.
|
|
||||||
*/
|
|
||||||
private _clearDraggableAttributesDelayed;
|
|
||||||
/**
|
|
||||||
* Whether the dragged content can be dropped only in block context.
|
|
||||||
*/
|
|
||||||
private _blockMode;
|
|
||||||
/**
|
|
||||||
* DOM Emitter.
|
|
||||||
*/
|
|
||||||
private _domEmitter;
|
|
||||||
/**
|
|
||||||
* The DOM element used to generate dragged preview image.
|
|
||||||
*/
|
|
||||||
private _previewContainer?;
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get pluginName(): "DragDrop";
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get requires(): readonly [typeof ClipboardPipeline, typeof Widget, typeof DragDropTarget, typeof DragDropBlockToolbar];
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
init(): void;
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
destroy(): void;
|
|
||||||
/**
|
|
||||||
* Drag and drop events handling.
|
|
||||||
*/
|
|
||||||
private _setupDragging;
|
|
||||||
/**
|
|
||||||
* Integration with the `clipboardInput` event.
|
|
||||||
*/
|
|
||||||
private _setupClipboardInputIntegration;
|
|
||||||
/**
|
|
||||||
* Integration with the `contentInsertion` event of the clipboard pipeline.
|
|
||||||
*/
|
|
||||||
private _setupContentInsertionIntegration;
|
|
||||||
/**
|
|
||||||
* Adds listeners that add the `draggable` attribute to the elements while the mouse button is down so the dragging could start.
|
|
||||||
*/
|
|
||||||
private _setupDraggableAttributeHandling;
|
|
||||||
/**
|
|
||||||
* Removes the `draggable` attribute from the element that was used for dragging.
|
|
||||||
*/
|
|
||||||
private _clearDraggableAttributes;
|
|
||||||
/**
|
|
||||||
* Deletes the dragged content from its original range and clears the dragging state.
|
|
||||||
*
|
|
||||||
* @param moved Whether the move succeeded.
|
|
||||||
*/
|
|
||||||
private _finalizeDragging;
|
|
||||||
/**
|
|
||||||
* Sets the dragged source range based on event target and document selection.
|
|
||||||
*/
|
|
||||||
private _prepareDraggedRange;
|
|
||||||
/**
|
|
||||||
* Updates the dragged preview image.
|
|
||||||
*/
|
|
||||||
private _updatePreview;
|
|
||||||
}
|
|
||||||
|
|
@ -1,577 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/dragdrop
|
|
||||||
*/
|
|
||||||
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
||||||
import { LiveRange, MouseObserver } from '@ckeditor/ckeditor5-engine';
|
|
||||||
import { Widget, isWidget } from '@ckeditor/ckeditor5-widget';
|
|
||||||
import { env, uid, global, createElement, DomEmitterMixin, delay, Rect } from '@ckeditor/ckeditor5-utils';
|
|
||||||
import ClipboardPipeline from './clipboardpipeline.js';
|
|
||||||
import ClipboardObserver from './clipboardobserver.js';
|
|
||||||
import DragDropTarget from './dragdroptarget.js';
|
|
||||||
import DragDropBlockToolbar from './dragdropblocktoolbar.js';
|
|
||||||
import '../theme/clipboard.css';
|
|
||||||
// Drag and drop events overview:
|
|
||||||
//
|
|
||||||
// ┌──────────────────┐
|
|
||||||
// │ mousedown │ Sets the draggable attribute.
|
|
||||||
// └─────────┬────────┘
|
|
||||||
// │
|
|
||||||
// └─────────────────────┐
|
|
||||||
// │ │
|
|
||||||
// │ ┌─────────V────────┐
|
|
||||||
// │ │ mouseup │ Dragging did not start, removes the draggable attribute.
|
|
||||||
// │ └──────────────────┘
|
|
||||||
// │
|
|
||||||
// ┌─────────V────────┐ Retrieves the selected model.DocumentFragment
|
|
||||||
// │ dragstart │ and converts it to view.DocumentFragment.
|
|
||||||
// └─────────┬────────┘
|
|
||||||
// │
|
|
||||||
// ┌─────────V────────┐ Processes view.DocumentFragment to text/html and text/plain
|
|
||||||
// │ clipboardOutput │ and stores the results in data.dataTransfer.
|
|
||||||
// └─────────┬────────┘
|
|
||||||
// │
|
|
||||||
// │ DOM dragover
|
|
||||||
// ┌────────────┐
|
|
||||||
// │ │
|
|
||||||
// ┌─────────V────────┐ │
|
|
||||||
// │ dragging │ │ Updates the drop target marker.
|
|
||||||
// └─────────┬────────┘ │
|
|
||||||
// │ │
|
|
||||||
// ┌─────────────└────────────┘
|
|
||||||
// │ │ │
|
|
||||||
// │ ┌─────────V────────┐ │
|
|
||||||
// │ │ dragleave │ │ Removes the drop target marker.
|
|
||||||
// │ └─────────┬────────┘ │
|
|
||||||
// │ │ │
|
|
||||||
// ┌───│─────────────┘ │
|
|
||||||
// │ │ │ │
|
|
||||||
// │ │ ┌─────────V────────┐ │
|
|
||||||
// │ │ │ dragenter │ │ Focuses the editor view.
|
|
||||||
// │ │ └─────────┬────────┘ │
|
|
||||||
// │ │ │ │
|
|
||||||
// │ │ └────────────┘
|
|
||||||
// │ │
|
|
||||||
// │ └─────────────┐
|
|
||||||
// │ │ │
|
|
||||||
// │ │ ┌─────────V────────┐
|
|
||||||
// └───┐ │ drop │ (The default handler of the clipboard pipeline).
|
|
||||||
// │ └─────────┬────────┘
|
|
||||||
// │ │
|
|
||||||
// │ ┌─────────V────────┐ Resolves the final data.targetRanges.
|
|
||||||
// │ │ clipboardInput │ Aborts if dropping on dragged content.
|
|
||||||
// │ └─────────┬────────┘
|
|
||||||
// │ │
|
|
||||||
// │ ┌─────────V────────┐
|
|
||||||
// │ │ clipboardInput │ (The default handler of the clipboard pipeline).
|
|
||||||
// │ └─────────┬────────┘
|
|
||||||
// │ │
|
|
||||||
// │ ┌───────────V───────────┐
|
|
||||||
// │ │ inputTransformation │ (The default handler of the clipboard pipeline).
|
|
||||||
// │ └───────────┬───────────┘
|
|
||||||
// │ │
|
|
||||||
// │ ┌──────────V──────────┐
|
|
||||||
// │ │ contentInsertion │ Updates the document selection to drop range.
|
|
||||||
// │ └──────────┬──────────┘
|
|
||||||
// │ │
|
|
||||||
// │ ┌──────────V──────────┐
|
|
||||||
// │ │ contentInsertion │ (The default handler of the clipboard pipeline).
|
|
||||||
// │ └──────────┬──────────┘
|
|
||||||
// │ │
|
|
||||||
// │ ┌──────────V──────────┐
|
|
||||||
// │ │ contentInsertion │ Removes the content from the original range if the insertion was successful.
|
|
||||||
// │ └──────────┬──────────┘
|
|
||||||
// │ │
|
|
||||||
// └─────────────┐
|
|
||||||
// │
|
|
||||||
// ┌─────────V────────┐
|
|
||||||
// │ dragend │ Removes the drop marker and cleans the state.
|
|
||||||
// └──────────────────┘
|
|
||||||
//
|
|
||||||
/**
|
|
||||||
* The drag and drop feature. It works on top of the {@link module:clipboard/clipboardpipeline~ClipboardPipeline}.
|
|
||||||
*
|
|
||||||
* Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export default class DragDrop extends Plugin {
|
|
||||||
constructor() {
|
|
||||||
super(...arguments);
|
|
||||||
/**
|
|
||||||
* A delayed callback removing draggable attributes.
|
|
||||||
*/
|
|
||||||
this._clearDraggableAttributesDelayed = delay(() => this._clearDraggableAttributes(), 40);
|
|
||||||
/**
|
|
||||||
* Whether the dragged content can be dropped only in block context.
|
|
||||||
*/
|
|
||||||
// TODO handle drag from other editor instance
|
|
||||||
// TODO configure to use block, inline or both
|
|
||||||
this._blockMode = false;
|
|
||||||
/**
|
|
||||||
* DOM Emitter.
|
|
||||||
*/
|
|
||||||
this._domEmitter = new (DomEmitterMixin())();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get pluginName() {
|
|
||||||
return 'DragDrop';
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get requires() {
|
|
||||||
return [ClipboardPipeline, Widget, DragDropTarget, DragDropBlockToolbar];
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
init() {
|
|
||||||
const editor = this.editor;
|
|
||||||
const view = editor.editing.view;
|
|
||||||
this._draggedRange = null;
|
|
||||||
this._draggingUid = '';
|
|
||||||
this._draggableElement = null;
|
|
||||||
view.addObserver(ClipboardObserver);
|
|
||||||
view.addObserver(MouseObserver);
|
|
||||||
this._setupDragging();
|
|
||||||
this._setupContentInsertionIntegration();
|
|
||||||
this._setupClipboardInputIntegration();
|
|
||||||
this._setupDraggableAttributeHandling();
|
|
||||||
this.listenTo(editor, 'change:isReadOnly', (evt, name, isReadOnly) => {
|
|
||||||
if (isReadOnly) {
|
|
||||||
this.forceDisabled('readOnlyMode');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.clearForceDisabled('readOnlyMode');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.on('change:isEnabled', (evt, name, isEnabled) => {
|
|
||||||
if (!isEnabled) {
|
|
||||||
this._finalizeDragging(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (env.isAndroid) {
|
|
||||||
this.forceDisabled('noAndroidSupport');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
destroy() {
|
|
||||||
if (this._draggedRange) {
|
|
||||||
this._draggedRange.detach();
|
|
||||||
this._draggedRange = null;
|
|
||||||
}
|
|
||||||
if (this._previewContainer) {
|
|
||||||
this._previewContainer.remove();
|
|
||||||
}
|
|
||||||
this._domEmitter.stopListening();
|
|
||||||
this._clearDraggableAttributesDelayed.cancel();
|
|
||||||
return super.destroy();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Drag and drop events handling.
|
|
||||||
*/
|
|
||||||
_setupDragging() {
|
|
||||||
const editor = this.editor;
|
|
||||||
const model = editor.model;
|
|
||||||
const view = editor.editing.view;
|
|
||||||
const viewDocument = view.document;
|
|
||||||
const dragDropTarget = editor.plugins.get(DragDropTarget);
|
|
||||||
// The handler for the drag start; it is responsible for setting data transfer object.
|
|
||||||
this.listenTo(viewDocument, 'dragstart', (evt, data) => {
|
|
||||||
// Don't drag the editable element itself.
|
|
||||||
if (data.target && data.target.is('editableElement')) {
|
|
||||||
data.preventDefault();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._prepareDraggedRange(data.target);
|
|
||||||
if (!this._draggedRange) {
|
|
||||||
data.preventDefault();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._draggingUid = uid();
|
|
||||||
data.dataTransfer.effectAllowed = this.isEnabled ? 'copyMove' : 'copy';
|
|
||||||
data.dataTransfer.setData('application/ckeditor5-dragging-uid', this._draggingUid);
|
|
||||||
const draggedSelection = model.createSelection(this._draggedRange.toRange());
|
|
||||||
const clipboardPipeline = this.editor.plugins.get('ClipboardPipeline');
|
|
||||||
clipboardPipeline._fireOutputTransformationEvent(data.dataTransfer, draggedSelection, 'dragstart');
|
|
||||||
const { dataTransfer, domTarget, domEvent } = data;
|
|
||||||
const { clientX } = domEvent;
|
|
||||||
this._updatePreview({ dataTransfer, domTarget, clientX });
|
|
||||||
data.stopPropagation();
|
|
||||||
if (!this.isEnabled) {
|
|
||||||
this._draggedRange.detach();
|
|
||||||
this._draggedRange = null;
|
|
||||||
this._draggingUid = '';
|
|
||||||
}
|
|
||||||
}, { priority: 'low' });
|
|
||||||
// The handler for finalizing drag and drop. It should always be triggered after dragging completes
|
|
||||||
// even if it was completed in a different application.
|
|
||||||
// Note: This is not fired if source text node got removed while downcasting a marker.
|
|
||||||
this.listenTo(viewDocument, 'dragend', (evt, data) => {
|
|
||||||
this._finalizeDragging(!data.dataTransfer.isCanceled && data.dataTransfer.dropEffect == 'move');
|
|
||||||
}, { priority: 'low' });
|
|
||||||
// Reset block dragging mode even if dropped outside the editable.
|
|
||||||
this._domEmitter.listenTo(global.document, 'dragend', () => {
|
|
||||||
this._blockMode = false;
|
|
||||||
}, { useCapture: true });
|
|
||||||
// Dragging over the editable.
|
|
||||||
this.listenTo(viewDocument, 'dragenter', () => {
|
|
||||||
if (!this.isEnabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
view.focus();
|
|
||||||
});
|
|
||||||
// Dragging out of the editable.
|
|
||||||
this.listenTo(viewDocument, 'dragleave', () => {
|
|
||||||
// We do not know if the mouse left the editor or just some element in it, so let us wait a few milliseconds
|
|
||||||
// to check if 'dragover' is not fired.
|
|
||||||
dragDropTarget.removeDropMarkerDelayed();
|
|
||||||
});
|
|
||||||
// Handler for moving dragged content over the target area.
|
|
||||||
this.listenTo(viewDocument, 'dragging', (evt, data) => {
|
|
||||||
if (!this.isEnabled) {
|
|
||||||
data.dataTransfer.dropEffect = 'none';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { clientX, clientY } = data.domEvent;
|
|
||||||
dragDropTarget.updateDropMarker(data.target, data.targetRanges, clientX, clientY, this._blockMode, this._draggedRange);
|
|
||||||
// If this is content being dragged from another editor, moving out of current editor instance
|
|
||||||
// is not possible until 'dragend' event case will be fixed.
|
|
||||||
if (!this._draggedRange) {
|
|
||||||
data.dataTransfer.dropEffect = 'copy';
|
|
||||||
}
|
|
||||||
// In Firefox it is already set and effect allowed remains the same as originally set.
|
|
||||||
if (!env.isGecko) {
|
|
||||||
if (data.dataTransfer.effectAllowed == 'copy') {
|
|
||||||
data.dataTransfer.dropEffect = 'copy';
|
|
||||||
}
|
|
||||||
else if (['all', 'copyMove'].includes(data.dataTransfer.effectAllowed)) {
|
|
||||||
data.dataTransfer.dropEffect = 'move';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
evt.stop();
|
|
||||||
}, { priority: 'low' });
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Integration with the `clipboardInput` event.
|
|
||||||
*/
|
|
||||||
_setupClipboardInputIntegration() {
|
|
||||||
const editor = this.editor;
|
|
||||||
const view = editor.editing.view;
|
|
||||||
const viewDocument = view.document;
|
|
||||||
const dragDropTarget = editor.plugins.get(DragDropTarget);
|
|
||||||
// Update the event target ranges and abort dropping if dropping over itself.
|
|
||||||
this.listenTo(viewDocument, 'clipboardInput', (evt, data) => {
|
|
||||||
if (data.method != 'drop') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { clientX, clientY } = data.domEvent;
|
|
||||||
const targetRange = dragDropTarget.getFinalDropRange(data.target, data.targetRanges, clientX, clientY, this._blockMode, this._draggedRange);
|
|
||||||
if (!targetRange) {
|
|
||||||
this._finalizeDragging(false);
|
|
||||||
evt.stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Since we cannot rely on the drag end event, we must check if the local drag range is from the current drag and drop
|
|
||||||
// or it is from some previous not cleared one.
|
|
||||||
if (this._draggedRange && this._draggingUid != data.dataTransfer.getData('application/ckeditor5-dragging-uid')) {
|
|
||||||
this._draggedRange.detach();
|
|
||||||
this._draggedRange = null;
|
|
||||||
this._draggingUid = '';
|
|
||||||
}
|
|
||||||
// Do not do anything if some content was dragged within the same document to the same position.
|
|
||||||
const isMove = getFinalDropEffect(data.dataTransfer) == 'move';
|
|
||||||
if (isMove && this._draggedRange && this._draggedRange.containsRange(targetRange, true)) {
|
|
||||||
this._finalizeDragging(false);
|
|
||||||
evt.stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Override the target ranges with the one adjusted to the best one for a drop.
|
|
||||||
data.targetRanges = [editor.editing.mapper.toViewRange(targetRange)];
|
|
||||||
}, { priority: 'high' });
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Integration with the `contentInsertion` event of the clipboard pipeline.
|
|
||||||
*/
|
|
||||||
_setupContentInsertionIntegration() {
|
|
||||||
const clipboardPipeline = this.editor.plugins.get(ClipboardPipeline);
|
|
||||||
clipboardPipeline.on('contentInsertion', (evt, data) => {
|
|
||||||
if (!this.isEnabled || data.method !== 'drop') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Update the selection to the target range in the same change block to avoid selection post-fixing
|
|
||||||
// and to be able to clone text attributes for plain text dropping.
|
|
||||||
const ranges = data.targetRanges.map(viewRange => this.editor.editing.mapper.toModelRange(viewRange));
|
|
||||||
this.editor.model.change(writer => writer.setSelection(ranges));
|
|
||||||
}, { priority: 'high' });
|
|
||||||
clipboardPipeline.on('contentInsertion', (evt, data) => {
|
|
||||||
if (!this.isEnabled || data.method !== 'drop') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Remove dragged range content, remove markers, clean after dragging.
|
|
||||||
const isMove = getFinalDropEffect(data.dataTransfer) == 'move';
|
|
||||||
// Whether any content was inserted (insertion might fail if the schema is disallowing some elements
|
|
||||||
// (for example an image caption allows only the content of a block but not blocks themselves.
|
|
||||||
// Some integrations might not return valid range (i.e., table pasting).
|
|
||||||
const isSuccess = !data.resultRange || !data.resultRange.isCollapsed;
|
|
||||||
this._finalizeDragging(isSuccess && isMove);
|
|
||||||
}, { priority: 'lowest' });
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Adds listeners that add the `draggable` attribute to the elements while the mouse button is down so the dragging could start.
|
|
||||||
*/
|
|
||||||
_setupDraggableAttributeHandling() {
|
|
||||||
const editor = this.editor;
|
|
||||||
const view = editor.editing.view;
|
|
||||||
const viewDocument = view.document;
|
|
||||||
// Add the 'draggable' attribute to the widget while pressing the selection handle.
|
|
||||||
// This is required for widgets to be draggable. In Chrome it will enable dragging text nodes.
|
|
||||||
this.listenTo(viewDocument, 'mousedown', (evt, data) => {
|
|
||||||
// The lack of data can be caused by editor tests firing fake mouse events. This should not occur
|
|
||||||
// in real-life scenarios but this greatly simplifies editor tests that would otherwise fail a lot.
|
|
||||||
if (env.isAndroid || !data) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._clearDraggableAttributesDelayed.cancel();
|
|
||||||
// Check if this is a mousedown over the widget (but not a nested editable).
|
|
||||||
let draggableElement = findDraggableWidget(data.target);
|
|
||||||
// Note: There is a limitation that if more than a widget is selected (a widget and some text)
|
|
||||||
// and dragging starts on the widget, then only the widget is dragged.
|
|
||||||
// If this was not a widget then we should check if we need to drag some text content.
|
|
||||||
// In Chrome set a 'draggable' attribute on closest editable to allow immediate dragging of the selected text range.
|
|
||||||
// In Firefox this is not needed. In Safari it makes the whole editable draggable (not just textual content).
|
|
||||||
// Disabled in read-only mode because draggable="true" + contenteditable="false" results
|
|
||||||
// in not firing selectionchange event ever, which makes the selection stuck in read-only mode.
|
|
||||||
if (env.isBlink && !editor.isReadOnly && !draggableElement && !viewDocument.selection.isCollapsed) {
|
|
||||||
const selectedElement = viewDocument.selection.getSelectedElement();
|
|
||||||
if (!selectedElement || !isWidget(selectedElement)) {
|
|
||||||
draggableElement = viewDocument.selection.editableElement;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (draggableElement) {
|
|
||||||
view.change(writer => {
|
|
||||||
writer.setAttribute('draggable', 'true', draggableElement);
|
|
||||||
});
|
|
||||||
// Keep the reference to the model element in case the view element gets removed while dragging.
|
|
||||||
this._draggableElement = editor.editing.mapper.toModelElement(draggableElement);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Remove the draggable attribute in case no dragging started (only mousedown + mouseup).
|
|
||||||
this.listenTo(viewDocument, 'mouseup', () => {
|
|
||||||
if (!env.isAndroid) {
|
|
||||||
this._clearDraggableAttributesDelayed();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Removes the `draggable` attribute from the element that was used for dragging.
|
|
||||||
*/
|
|
||||||
_clearDraggableAttributes() {
|
|
||||||
const editing = this.editor.editing;
|
|
||||||
editing.view.change(writer => {
|
|
||||||
// Remove 'draggable' attribute.
|
|
||||||
if (this._draggableElement && this._draggableElement.root.rootName != '$graveyard') {
|
|
||||||
writer.removeAttribute('draggable', editing.mapper.toViewElement(this._draggableElement));
|
|
||||||
}
|
|
||||||
this._draggableElement = null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Deletes the dragged content from its original range and clears the dragging state.
|
|
||||||
*
|
|
||||||
* @param moved Whether the move succeeded.
|
|
||||||
*/
|
|
||||||
_finalizeDragging(moved) {
|
|
||||||
const editor = this.editor;
|
|
||||||
const model = editor.model;
|
|
||||||
const dragDropTarget = editor.plugins.get(DragDropTarget);
|
|
||||||
dragDropTarget.removeDropMarker();
|
|
||||||
this._clearDraggableAttributes();
|
|
||||||
if (editor.plugins.has('WidgetToolbarRepository')) {
|
|
||||||
const widgetToolbarRepository = editor.plugins.get('WidgetToolbarRepository');
|
|
||||||
widgetToolbarRepository.clearForceDisabled('dragDrop');
|
|
||||||
}
|
|
||||||
this._draggingUid = '';
|
|
||||||
if (this._previewContainer) {
|
|
||||||
this._previewContainer.remove();
|
|
||||||
this._previewContainer = undefined;
|
|
||||||
}
|
|
||||||
if (!this._draggedRange) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Delete moved content.
|
|
||||||
if (moved && this.isEnabled) {
|
|
||||||
model.change(writer => {
|
|
||||||
const selection = model.createSelection(this._draggedRange);
|
|
||||||
model.deleteContent(selection, { doNotAutoparagraph: true });
|
|
||||||
// Check result selection if it does not require auto-paragraphing of empty container.
|
|
||||||
const selectionParent = selection.getFirstPosition().parent;
|
|
||||||
if (selectionParent.isEmpty &&
|
|
||||||
!model.schema.checkChild(selectionParent, '$text') &&
|
|
||||||
model.schema.checkChild(selectionParent, 'paragraph')) {
|
|
||||||
writer.insertElement('paragraph', selectionParent, 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this._draggedRange.detach();
|
|
||||||
this._draggedRange = null;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Sets the dragged source range based on event target and document selection.
|
|
||||||
*/
|
|
||||||
_prepareDraggedRange(target) {
|
|
||||||
const editor = this.editor;
|
|
||||||
const model = editor.model;
|
|
||||||
const selection = model.document.selection;
|
|
||||||
// Check if this is dragstart over the widget (but not a nested editable).
|
|
||||||
const draggableWidget = target ? findDraggableWidget(target) : null;
|
|
||||||
if (draggableWidget) {
|
|
||||||
const modelElement = editor.editing.mapper.toModelElement(draggableWidget);
|
|
||||||
this._draggedRange = LiveRange.fromRange(model.createRangeOn(modelElement));
|
|
||||||
this._blockMode = model.schema.isBlock(modelElement);
|
|
||||||
// Disable toolbars so they won't obscure the drop area.
|
|
||||||
if (editor.plugins.has('WidgetToolbarRepository')) {
|
|
||||||
const widgetToolbarRepository = editor.plugins.get('WidgetToolbarRepository');
|
|
||||||
widgetToolbarRepository.forceDisabled('dragDrop');
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// If this was not a widget we should check if we need to drag some text content.
|
|
||||||
if (selection.isCollapsed && !selection.getFirstPosition().parent.isEmpty) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const blocks = Array.from(selection.getSelectedBlocks());
|
|
||||||
const draggedRange = selection.getFirstRange();
|
|
||||||
if (blocks.length == 0) {
|
|
||||||
this._draggedRange = LiveRange.fromRange(draggedRange);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const blockRange = getRangeIncludingFullySelectedParents(model, blocks);
|
|
||||||
if (blocks.length > 1) {
|
|
||||||
this._draggedRange = LiveRange.fromRange(blockRange);
|
|
||||||
this._blockMode = true;
|
|
||||||
// TODO block mode for dragging from outside editor? or inline? or both?
|
|
||||||
}
|
|
||||||
else if (blocks.length == 1) {
|
|
||||||
const touchesBlockEdges = draggedRange.start.isTouching(blockRange.start) &&
|
|
||||||
draggedRange.end.isTouching(blockRange.end);
|
|
||||||
this._draggedRange = LiveRange.fromRange(touchesBlockEdges ? blockRange : draggedRange);
|
|
||||||
this._blockMode = touchesBlockEdges;
|
|
||||||
}
|
|
||||||
model.change(writer => writer.setSelection(this._draggedRange.toRange()));
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Updates the dragged preview image.
|
|
||||||
*/
|
|
||||||
_updatePreview({ dataTransfer, domTarget, clientX }) {
|
|
||||||
const view = this.editor.editing.view;
|
|
||||||
const editable = view.document.selection.editableElement;
|
|
||||||
const domEditable = view.domConverter.mapViewToDom(editable);
|
|
||||||
const computedStyle = global.window.getComputedStyle(domEditable);
|
|
||||||
if (!this._previewContainer) {
|
|
||||||
this._previewContainer = createElement(global.document, 'div', {
|
|
||||||
style: 'position: fixed; left: -999999px;'
|
|
||||||
});
|
|
||||||
global.document.body.appendChild(this._previewContainer);
|
|
||||||
}
|
|
||||||
else if (this._previewContainer.firstElementChild) {
|
|
||||||
this._previewContainer.removeChild(this._previewContainer.firstElementChild);
|
|
||||||
}
|
|
||||||
const domRect = new Rect(domEditable);
|
|
||||||
// If domTarget is inside the editable root, browsers will display the preview correctly by themselves.
|
|
||||||
if (domEditable.contains(domTarget)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const domEditablePaddingLeft = parseFloat(computedStyle.paddingLeft);
|
|
||||||
const preview = createElement(global.document, 'div');
|
|
||||||
preview.className = 'ck ck-content';
|
|
||||||
preview.style.width = computedStyle.width;
|
|
||||||
preview.style.paddingLeft = `${domRect.left - clientX + domEditablePaddingLeft}px`;
|
|
||||||
/**
|
|
||||||
* Set white background in drag and drop preview if iOS.
|
|
||||||
* Check: https://github.com/ckeditor/ckeditor5/issues/15085
|
|
||||||
*/
|
|
||||||
if (env.isiOS) {
|
|
||||||
preview.style.backgroundColor = 'white';
|
|
||||||
}
|
|
||||||
preview.innerHTML = dataTransfer.getData('text/html');
|
|
||||||
dataTransfer.setDragImage(preview, 0, 0);
|
|
||||||
this._previewContainer.appendChild(preview);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns the drop effect that should be a result of dragging the content.
|
|
||||||
* This function is handling a quirk when checking the effect in the 'drop' DOM event.
|
|
||||||
*/
|
|
||||||
function getFinalDropEffect(dataTransfer) {
|
|
||||||
if (env.isGecko) {
|
|
||||||
return dataTransfer.dropEffect;
|
|
||||||
}
|
|
||||||
return ['all', 'copyMove'].includes(dataTransfer.effectAllowed) ? 'move' : 'copy';
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns a widget element that should be dragged.
|
|
||||||
*/
|
|
||||||
function findDraggableWidget(target) {
|
|
||||||
// This is directly an editable so not a widget for sure.
|
|
||||||
if (target.is('editableElement')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// TODO: Let's have a isWidgetSelectionHandleDomElement() helper in ckeditor5-widget utils.
|
|
||||||
if (target.hasClass('ck-widget__selection-handle')) {
|
|
||||||
return target.findAncestor(isWidget);
|
|
||||||
}
|
|
||||||
// Direct hit on a widget.
|
|
||||||
if (isWidget(target)) {
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
// Find closest ancestor that is either a widget or an editable element...
|
|
||||||
const ancestor = target.findAncestor(node => isWidget(node) || node.is('editableElement'));
|
|
||||||
// ...and if closer was the widget then enable dragging it.
|
|
||||||
if (isWidget(ancestor)) {
|
|
||||||
return ancestor;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Recursively checks if common parent of provided elements doesn't have any other children. If that's the case,
|
|
||||||
* it returns range including this parent. Otherwise, it returns only the range from first to last element.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
*
|
|
||||||
* <blockQuote>
|
|
||||||
* <paragraph>[Test 1</paragraph>
|
|
||||||
* <paragraph>Test 2</paragraph>
|
|
||||||
* <paragraph>Test 3]</paragraph>
|
|
||||||
* <blockQuote>
|
|
||||||
*
|
|
||||||
* Because all elements inside the `blockQuote` are selected, the range is extended to include the `blockQuote` too.
|
|
||||||
* If only first and second paragraphs would be selected, the range would not include it.
|
|
||||||
*/
|
|
||||||
function getRangeIncludingFullySelectedParents(model, elements) {
|
|
||||||
const firstElement = elements[0];
|
|
||||||
const lastElement = elements[elements.length - 1];
|
|
||||||
const parent = firstElement.getCommonAncestor(lastElement);
|
|
||||||
const startPosition = model.createPositionBefore(firstElement);
|
|
||||||
const endPosition = model.createPositionAfter(lastElement);
|
|
||||||
if (parent &&
|
|
||||||
parent.is('element') &&
|
|
||||||
!model.schema.isLimit(parent)) {
|
|
||||||
const parentRange = model.createRangeOn(parent);
|
|
||||||
const touchesStart = startPosition.isTouching(parentRange.start);
|
|
||||||
const touchesEnd = endPosition.isTouching(parentRange.end);
|
|
||||||
if (touchesStart && touchesEnd) {
|
|
||||||
// Selection includes all elements in the parent.
|
|
||||||
return getRangeIncludingFullySelectedParents(model, [parent]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return model.createRange(startPosition, endPosition);
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/dragdropblocktoolbar
|
|
||||||
*/
|
|
||||||
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
||||||
/**
|
|
||||||
* Integration of a block Drag and Drop support with the block toolbar.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export default class DragDropBlockToolbar extends Plugin {
|
|
||||||
/**
|
|
||||||
* Whether current dragging is started by block toolbar button dragging.
|
|
||||||
*/
|
|
||||||
private _isBlockDragging;
|
|
||||||
/**
|
|
||||||
* DOM Emitter.
|
|
||||||
*/
|
|
||||||
private _domEmitter;
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get pluginName(): "DragDropBlockToolbar";
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
init(): void;
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
destroy(): void;
|
|
||||||
/**
|
|
||||||
* The `dragstart` event handler.
|
|
||||||
*/
|
|
||||||
private _handleBlockDragStart;
|
|
||||||
/**
|
|
||||||
* The `dragover` and `drop` event handler.
|
|
||||||
*/
|
|
||||||
private _handleBlockDragging;
|
|
||||||
/**
|
|
||||||
* The `dragend` event handler.
|
|
||||||
*/
|
|
||||||
private _handleBlockDragEnd;
|
|
||||||
}
|
|
||||||
|
|
@ -1,121 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/dragdropblocktoolbar
|
|
||||||
*/
|
|
||||||
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
||||||
import { env, global, DomEmitterMixin } from '@ckeditor/ckeditor5-utils';
|
|
||||||
import ClipboardObserver from './clipboardobserver.js';
|
|
||||||
/**
|
|
||||||
* Integration of a block Drag and Drop support with the block toolbar.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export default class DragDropBlockToolbar extends Plugin {
|
|
||||||
constructor() {
|
|
||||||
super(...arguments);
|
|
||||||
/**
|
|
||||||
* Whether current dragging is started by block toolbar button dragging.
|
|
||||||
*/
|
|
||||||
this._isBlockDragging = false;
|
|
||||||
/**
|
|
||||||
* DOM Emitter.
|
|
||||||
*/
|
|
||||||
this._domEmitter = new (DomEmitterMixin())();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get pluginName() {
|
|
||||||
return 'DragDropBlockToolbar';
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
init() {
|
|
||||||
const editor = this.editor;
|
|
||||||
this.listenTo(editor, 'change:isReadOnly', (evt, name, isReadOnly) => {
|
|
||||||
if (isReadOnly) {
|
|
||||||
this.forceDisabled('readOnlyMode');
|
|
||||||
this._isBlockDragging = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.clearForceDisabled('readOnlyMode');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (env.isAndroid) {
|
|
||||||
this.forceDisabled('noAndroidSupport');
|
|
||||||
}
|
|
||||||
if (editor.plugins.has('BlockToolbar')) {
|
|
||||||
const blockToolbar = editor.plugins.get('BlockToolbar');
|
|
||||||
const element = blockToolbar.buttonView.element;
|
|
||||||
this._domEmitter.listenTo(element, 'dragstart', (evt, data) => this._handleBlockDragStart(data));
|
|
||||||
this._domEmitter.listenTo(global.document, 'dragover', (evt, data) => this._handleBlockDragging(data));
|
|
||||||
this._domEmitter.listenTo(global.document, 'drop', (evt, data) => this._handleBlockDragging(data));
|
|
||||||
this._domEmitter.listenTo(global.document, 'dragend', () => this._handleBlockDragEnd(), { useCapture: true });
|
|
||||||
if (this.isEnabled) {
|
|
||||||
element.setAttribute('draggable', 'true');
|
|
||||||
}
|
|
||||||
this.on('change:isEnabled', (evt, name, isEnabled) => {
|
|
||||||
element.setAttribute('draggable', isEnabled ? 'true' : 'false');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
destroy() {
|
|
||||||
this._domEmitter.stopListening();
|
|
||||||
return super.destroy();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* The `dragstart` event handler.
|
|
||||||
*/
|
|
||||||
_handleBlockDragStart(domEvent) {
|
|
||||||
if (!this.isEnabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const model = this.editor.model;
|
|
||||||
const selection = model.document.selection;
|
|
||||||
const view = this.editor.editing.view;
|
|
||||||
const blocks = Array.from(selection.getSelectedBlocks());
|
|
||||||
const draggedRange = model.createRange(model.createPositionBefore(blocks[0]), model.createPositionAfter(blocks[blocks.length - 1]));
|
|
||||||
model.change(writer => writer.setSelection(draggedRange));
|
|
||||||
this._isBlockDragging = true;
|
|
||||||
view.focus();
|
|
||||||
view.getObserver(ClipboardObserver).onDomEvent(domEvent);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* The `dragover` and `drop` event handler.
|
|
||||||
*/
|
|
||||||
_handleBlockDragging(domEvent) {
|
|
||||||
if (!this.isEnabled || !this._isBlockDragging) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const clientX = domEvent.clientX + (this.editor.locale.contentLanguageDirection == 'ltr' ? 100 : -100);
|
|
||||||
const clientY = domEvent.clientY;
|
|
||||||
const target = document.elementFromPoint(clientX, clientY);
|
|
||||||
const view = this.editor.editing.view;
|
|
||||||
if (!target || !target.closest('.ck-editor__editable')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
view.getObserver(ClipboardObserver).onDomEvent({
|
|
||||||
...domEvent,
|
|
||||||
type: domEvent.type,
|
|
||||||
dataTransfer: domEvent.dataTransfer,
|
|
||||||
target,
|
|
||||||
clientX,
|
|
||||||
clientY,
|
|
||||||
preventDefault: () => domEvent.preventDefault(),
|
|
||||||
stopPropagation: () => domEvent.stopPropagation()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* The `dragend` event handler.
|
|
||||||
*/
|
|
||||||
_handleBlockDragEnd() {
|
|
||||||
this._isBlockDragging = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/dragdroptarget
|
|
||||||
*/
|
|
||||||
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
||||||
import { type Range, type LiveRange, type ViewElement, type ViewRange } from '@ckeditor/ckeditor5-engine';
|
|
||||||
/**
|
|
||||||
* Part of the Drag and Drop handling. Responsible for finding and displaying the drop target.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export default class DragDropTarget extends Plugin {
|
|
||||||
/**
|
|
||||||
* A delayed callback removing the drop marker.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
readonly removeDropMarkerDelayed: import("@ckeditor/ckeditor5-utils").DelayedFunc<() => void>;
|
|
||||||
/**
|
|
||||||
* A throttled callback updating the drop marker.
|
|
||||||
*/
|
|
||||||
private readonly _updateDropMarkerThrottled;
|
|
||||||
/**
|
|
||||||
* A throttled callback reconverting the drop parker.
|
|
||||||
*/
|
|
||||||
private readonly _reconvertMarkerThrottled;
|
|
||||||
/**
|
|
||||||
* The horizontal drop target line view.
|
|
||||||
*/
|
|
||||||
private _dropTargetLineView;
|
|
||||||
/**
|
|
||||||
* DOM Emitter.
|
|
||||||
*/
|
|
||||||
private _domEmitter;
|
|
||||||
/**
|
|
||||||
* Map of document scrollable elements.
|
|
||||||
*/
|
|
||||||
private _scrollables;
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get pluginName(): "DragDropTarget";
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
init(): void;
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
destroy(): void;
|
|
||||||
/**
|
|
||||||
* Finds the drop target range and updates the drop marker.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
updateDropMarker(targetViewElement: ViewElement, targetViewRanges: Array<ViewRange> | null, clientX: number, clientY: number, blockMode: boolean, draggedRange: LiveRange | null): void;
|
|
||||||
/**
|
|
||||||
* Finds the final drop target range.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
getFinalDropRange(targetViewElement: ViewElement, targetViewRanges: Array<ViewRange> | null, clientX: number, clientY: number, blockMode: boolean, draggedRange: LiveRange | null): Range | null;
|
|
||||||
/**
|
|
||||||
* Removes the drop target marker.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
removeDropMarker(): void;
|
|
||||||
/**
|
|
||||||
* Creates downcast conversion for the drop target marker.
|
|
||||||
*/
|
|
||||||
private _setupDropMarker;
|
|
||||||
/**
|
|
||||||
* Updates the drop target marker to the provided range.
|
|
||||||
*
|
|
||||||
* @param targetRange The range to set the marker to.
|
|
||||||
*/
|
|
||||||
private _updateDropMarker;
|
|
||||||
/**
|
|
||||||
* Creates the UI element for vertical (in-line) drop target.
|
|
||||||
*/
|
|
||||||
private _createDropTargetPosition;
|
|
||||||
/**
|
|
||||||
* Updates the horizontal drop target line.
|
|
||||||
*/
|
|
||||||
private _updateDropTargetLine;
|
|
||||||
/**
|
|
||||||
* Finds the closest scrollable element rect for the given view element.
|
|
||||||
*/
|
|
||||||
private _getScrollableRect;
|
|
||||||
}
|
|
||||||
|
|
@ -1,379 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/dragdroptarget
|
|
||||||
*/
|
|
||||||
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
||||||
import { global, Rect, DomEmitterMixin, delay, ResizeObserver } from '@ckeditor/ckeditor5-utils';
|
|
||||||
import LineView from './lineview.js';
|
|
||||||
import { throttle } from 'lodash-es';
|
|
||||||
/**
|
|
||||||
* Part of the Drag and Drop handling. Responsible for finding and displaying the drop target.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export default class DragDropTarget extends Plugin {
|
|
||||||
constructor() {
|
|
||||||
super(...arguments);
|
|
||||||
/**
|
|
||||||
* A delayed callback removing the drop marker.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
this.removeDropMarkerDelayed = delay(() => this.removeDropMarker(), 40);
|
|
||||||
/**
|
|
||||||
* A throttled callback updating the drop marker.
|
|
||||||
*/
|
|
||||||
this._updateDropMarkerThrottled = throttle(targetRange => this._updateDropMarker(targetRange), 40);
|
|
||||||
/**
|
|
||||||
* A throttled callback reconverting the drop parker.
|
|
||||||
*/
|
|
||||||
this._reconvertMarkerThrottled = throttle(() => {
|
|
||||||
if (this.editor.model.markers.has('drop-target')) {
|
|
||||||
this.editor.editing.reconvertMarker('drop-target');
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
/**
|
|
||||||
* The horizontal drop target line view.
|
|
||||||
*/
|
|
||||||
this._dropTargetLineView = new LineView();
|
|
||||||
/**
|
|
||||||
* DOM Emitter.
|
|
||||||
*/
|
|
||||||
this._domEmitter = new (DomEmitterMixin())();
|
|
||||||
/**
|
|
||||||
* Map of document scrollable elements.
|
|
||||||
*/
|
|
||||||
this._scrollables = new Map();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get pluginName() {
|
|
||||||
return 'DragDropTarget';
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
init() {
|
|
||||||
this._setupDropMarker();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
destroy() {
|
|
||||||
this._domEmitter.stopListening();
|
|
||||||
for (const { resizeObserver } of this._scrollables.values()) {
|
|
||||||
resizeObserver.destroy();
|
|
||||||
}
|
|
||||||
this._updateDropMarkerThrottled.cancel();
|
|
||||||
this.removeDropMarkerDelayed.cancel();
|
|
||||||
this._reconvertMarkerThrottled.cancel();
|
|
||||||
return super.destroy();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Finds the drop target range and updates the drop marker.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
updateDropMarker(targetViewElement, targetViewRanges, clientX, clientY, blockMode, draggedRange) {
|
|
||||||
this.removeDropMarkerDelayed.cancel();
|
|
||||||
const targetRange = findDropTargetRange(this.editor, targetViewElement, targetViewRanges, clientX, clientY, blockMode, draggedRange);
|
|
||||||
/* istanbul ignore next -- @preserve */
|
|
||||||
if (!targetRange) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (draggedRange && draggedRange.containsRange(targetRange)) {
|
|
||||||
// Target range is inside the dragged range.
|
|
||||||
return this.removeDropMarker();
|
|
||||||
}
|
|
||||||
this._updateDropMarkerThrottled(targetRange);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Finds the final drop target range.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
getFinalDropRange(targetViewElement, targetViewRanges, clientX, clientY, blockMode, draggedRange) {
|
|
||||||
const targetRange = findDropTargetRange(this.editor, targetViewElement, targetViewRanges, clientX, clientY, blockMode, draggedRange);
|
|
||||||
// The dragging markers must be removed after searching for the target range because sometimes
|
|
||||||
// the target lands on the marker itself.
|
|
||||||
this.removeDropMarker();
|
|
||||||
return targetRange;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Removes the drop target marker.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
removeDropMarker() {
|
|
||||||
const model = this.editor.model;
|
|
||||||
this.removeDropMarkerDelayed.cancel();
|
|
||||||
this._updateDropMarkerThrottled.cancel();
|
|
||||||
this._dropTargetLineView.isVisible = false;
|
|
||||||
if (model.markers.has('drop-target')) {
|
|
||||||
model.change(writer => {
|
|
||||||
writer.removeMarker('drop-target');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Creates downcast conversion for the drop target marker.
|
|
||||||
*/
|
|
||||||
_setupDropMarker() {
|
|
||||||
const editor = this.editor;
|
|
||||||
editor.ui.view.body.add(this._dropTargetLineView);
|
|
||||||
// Drop marker conversion for hovering over widgets.
|
|
||||||
editor.conversion.for('editingDowncast').markerToHighlight({
|
|
||||||
model: 'drop-target',
|
|
||||||
view: {
|
|
||||||
classes: ['ck-clipboard-drop-target-range']
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Drop marker conversion for in text and block drop target.
|
|
||||||
editor.conversion.for('editingDowncast').markerToElement({
|
|
||||||
model: 'drop-target',
|
|
||||||
view: (data, { writer }) => {
|
|
||||||
// Inline drop.
|
|
||||||
if (editor.model.schema.checkChild(data.markerRange.start, '$text')) {
|
|
||||||
this._dropTargetLineView.isVisible = false;
|
|
||||||
return this._createDropTargetPosition(writer);
|
|
||||||
}
|
|
||||||
// Block drop.
|
|
||||||
else {
|
|
||||||
if (data.markerRange.isCollapsed) {
|
|
||||||
this._updateDropTargetLine(data.markerRange);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this._dropTargetLineView.isVisible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Updates the drop target marker to the provided range.
|
|
||||||
*
|
|
||||||
* @param targetRange The range to set the marker to.
|
|
||||||
*/
|
|
||||||
_updateDropMarker(targetRange) {
|
|
||||||
const editor = this.editor;
|
|
||||||
const markers = editor.model.markers;
|
|
||||||
editor.model.change(writer => {
|
|
||||||
if (markers.has('drop-target')) {
|
|
||||||
if (!markers.get('drop-target').getRange().isEqual(targetRange)) {
|
|
||||||
writer.updateMarker('drop-target', { range: targetRange });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
writer.addMarker('drop-target', {
|
|
||||||
range: targetRange,
|
|
||||||
usingOperation: false,
|
|
||||||
affectsData: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Creates the UI element for vertical (in-line) drop target.
|
|
||||||
*/
|
|
||||||
_createDropTargetPosition(writer) {
|
|
||||||
return writer.createUIElement('span', { class: 'ck ck-clipboard-drop-target-position' }, function (domDocument) {
|
|
||||||
const domElement = this.toDomElement(domDocument);
|
|
||||||
// Using word joiner to make this marker as high as text and also making text not break on marker.
|
|
||||||
domElement.append('\u2060', domDocument.createElement('span'), '\u2060');
|
|
||||||
return domElement;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Updates the horizontal drop target line.
|
|
||||||
*/
|
|
||||||
_updateDropTargetLine(range) {
|
|
||||||
const editing = this.editor.editing;
|
|
||||||
const nodeBefore = range.start.nodeBefore;
|
|
||||||
const nodeAfter = range.start.nodeAfter;
|
|
||||||
const nodeParent = range.start.parent;
|
|
||||||
const viewElementBefore = nodeBefore ? editing.mapper.toViewElement(nodeBefore) : null;
|
|
||||||
const domElementBefore = viewElementBefore ? editing.view.domConverter.mapViewToDom(viewElementBefore) : null;
|
|
||||||
const viewElementAfter = nodeAfter ? editing.mapper.toViewElement(nodeAfter) : null;
|
|
||||||
const domElementAfter = viewElementAfter ? editing.view.domConverter.mapViewToDom(viewElementAfter) : null;
|
|
||||||
const viewElementParent = editing.mapper.toViewElement(nodeParent);
|
|
||||||
if (!viewElementParent) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const domElementParent = editing.view.domConverter.mapViewToDom(viewElementParent);
|
|
||||||
const domScrollableRect = this._getScrollableRect(viewElementParent);
|
|
||||||
const { scrollX, scrollY } = global.window;
|
|
||||||
const rectBefore = domElementBefore ? new Rect(domElementBefore) : null;
|
|
||||||
const rectAfter = domElementAfter ? new Rect(domElementAfter) : null;
|
|
||||||
const rectParent = new Rect(domElementParent).excludeScrollbarsAndBorders();
|
|
||||||
const above = rectBefore ? rectBefore.bottom : rectParent.top;
|
|
||||||
const below = rectAfter ? rectAfter.top : rectParent.bottom;
|
|
||||||
const parentStyle = global.window.getComputedStyle(domElementParent);
|
|
||||||
const top = (above <= below ? (above + below) / 2 : below);
|
|
||||||
if (domScrollableRect.top < top && top < domScrollableRect.bottom) {
|
|
||||||
const left = rectParent.left + parseFloat(parentStyle.paddingLeft);
|
|
||||||
const right = rectParent.right - parseFloat(parentStyle.paddingRight);
|
|
||||||
const leftClamped = Math.max(left + scrollX, domScrollableRect.left);
|
|
||||||
const rightClamped = Math.min(right + scrollX, domScrollableRect.right);
|
|
||||||
this._dropTargetLineView.set({
|
|
||||||
isVisible: true,
|
|
||||||
left: leftClamped,
|
|
||||||
top: top + scrollY,
|
|
||||||
width: rightClamped - leftClamped
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this._dropTargetLineView.isVisible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Finds the closest scrollable element rect for the given view element.
|
|
||||||
*/
|
|
||||||
_getScrollableRect(viewElement) {
|
|
||||||
const rootName = viewElement.root.rootName;
|
|
||||||
let domScrollable;
|
|
||||||
if (this._scrollables.has(rootName)) {
|
|
||||||
domScrollable = this._scrollables.get(rootName).domElement;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const domElement = this.editor.editing.view.domConverter.mapViewToDom(viewElement);
|
|
||||||
domScrollable = findScrollableElement(domElement);
|
|
||||||
this._domEmitter.listenTo(domScrollable, 'scroll', this._reconvertMarkerThrottled, { usePassive: true });
|
|
||||||
const resizeObserver = new ResizeObserver(domScrollable, this._reconvertMarkerThrottled);
|
|
||||||
this._scrollables.set(rootName, {
|
|
||||||
domElement: domScrollable,
|
|
||||||
resizeObserver
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return new Rect(domScrollable).excludeScrollbarsAndBorders();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns fixed selection range for given position and target element.
|
|
||||||
*/
|
|
||||||
function findDropTargetRange(editor, targetViewElement, targetViewRanges, clientX, clientY, blockMode, draggedRange) {
|
|
||||||
const model = editor.model;
|
|
||||||
const mapper = editor.editing.mapper;
|
|
||||||
const targetModelElement = getClosestMappedModelElement(editor, targetViewElement);
|
|
||||||
let modelElement = targetModelElement;
|
|
||||||
while (modelElement) {
|
|
||||||
if (!blockMode) {
|
|
||||||
if (model.schema.checkChild(modelElement, '$text')) {
|
|
||||||
if (targetViewRanges) {
|
|
||||||
const targetViewPosition = targetViewRanges[0].start;
|
|
||||||
const targetModelPosition = mapper.toModelPosition(targetViewPosition);
|
|
||||||
const canDropOnPosition = !draggedRange || Array
|
|
||||||
.from(draggedRange.getItems())
|
|
||||||
.every(item => model.schema.checkChild(targetModelPosition, item));
|
|
||||||
if (canDropOnPosition) {
|
|
||||||
if (model.schema.checkChild(targetModelPosition, '$text')) {
|
|
||||||
return model.createRange(targetModelPosition);
|
|
||||||
}
|
|
||||||
else if (targetViewPosition) {
|
|
||||||
// This is the case of dropping inside a span wrapper of an inline image.
|
|
||||||
return findDropTargetRangeForElement(editor, getClosestMappedModelElement(editor, targetViewPosition.parent), clientX, clientY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (model.schema.isInline(modelElement)) {
|
|
||||||
return findDropTargetRangeForElement(editor, modelElement, clientX, clientY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (model.schema.isBlock(modelElement)) {
|
|
||||||
return findDropTargetRangeForElement(editor, modelElement, clientX, clientY);
|
|
||||||
}
|
|
||||||
else if (model.schema.checkChild(modelElement, '$block')) {
|
|
||||||
const childNodes = Array.from(modelElement.getChildren())
|
|
||||||
.filter((node) => node.is('element') && !shouldIgnoreElement(editor, node));
|
|
||||||
let startIndex = 0;
|
|
||||||
let endIndex = childNodes.length;
|
|
||||||
if (endIndex == 0) {
|
|
||||||
return model.createRange(model.createPositionAt(modelElement, 'end'));
|
|
||||||
}
|
|
||||||
while (startIndex < endIndex - 1) {
|
|
||||||
const middleIndex = Math.floor((startIndex + endIndex) / 2);
|
|
||||||
const side = findElementSide(editor, childNodes[middleIndex], clientX, clientY);
|
|
||||||
if (side == 'before') {
|
|
||||||
endIndex = middleIndex;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
startIndex = middleIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return findDropTargetRangeForElement(editor, childNodes[startIndex], clientX, clientY);
|
|
||||||
}
|
|
||||||
modelElement = modelElement.parent;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns true for elements which should be ignored.
|
|
||||||
*/
|
|
||||||
function shouldIgnoreElement(editor, modelElement) {
|
|
||||||
const mapper = editor.editing.mapper;
|
|
||||||
const domConverter = editor.editing.view.domConverter;
|
|
||||||
const viewElement = mapper.toViewElement(modelElement);
|
|
||||||
if (!viewElement) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const domElement = domConverter.mapViewToDom(viewElement);
|
|
||||||
return global.window.getComputedStyle(domElement).float != 'none';
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns target range relative to the given element.
|
|
||||||
*/
|
|
||||||
function findDropTargetRangeForElement(editor, modelElement, clientX, clientY) {
|
|
||||||
const model = editor.model;
|
|
||||||
return model.createRange(model.createPositionAt(modelElement, findElementSide(editor, modelElement, clientX, clientY)));
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Resolves whether drop marker should be before or after the given element.
|
|
||||||
*/
|
|
||||||
function findElementSide(editor, modelElement, clientX, clientY) {
|
|
||||||
const mapper = editor.editing.mapper;
|
|
||||||
const domConverter = editor.editing.view.domConverter;
|
|
||||||
const viewElement = mapper.toViewElement(modelElement);
|
|
||||||
const domElement = domConverter.mapViewToDom(viewElement);
|
|
||||||
const rect = new Rect(domElement);
|
|
||||||
if (editor.model.schema.isInline(modelElement)) {
|
|
||||||
return clientX < (rect.left + rect.right) / 2 ? 'before' : 'after';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return clientY < (rect.top + rect.bottom) / 2 ? 'before' : 'after';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns the closest model element for the specified view element.
|
|
||||||
*/
|
|
||||||
function getClosestMappedModelElement(editor, element) {
|
|
||||||
const mapper = editor.editing.mapper;
|
|
||||||
const view = editor.editing.view;
|
|
||||||
const targetModelElement = mapper.toModelElement(element);
|
|
||||||
if (targetModelElement) {
|
|
||||||
return targetModelElement;
|
|
||||||
}
|
|
||||||
// Find mapped ancestor if the target is inside not mapped element (for example inline code element).
|
|
||||||
const viewPosition = view.createPositionBefore(element);
|
|
||||||
const viewElement = mapper.findMappedViewAncestor(viewPosition);
|
|
||||||
return mapper.toModelElement(viewElement);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns the closest scrollable ancestor DOM element.
|
|
||||||
*
|
|
||||||
* It is assumed that `domNode` is attached to the document.
|
|
||||||
*/
|
|
||||||
function findScrollableElement(domNode) {
|
|
||||||
let domElement = domNode;
|
|
||||||
do {
|
|
||||||
domElement = domElement.parentElement;
|
|
||||||
const overflow = global.window.getComputedStyle(domElement).overflowY;
|
|
||||||
if (overflow == 'auto' || overflow == 'scroll') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (domElement.tagName != 'BODY');
|
|
||||||
return domElement;
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard
|
|
||||||
*/
|
|
||||||
export { default as Clipboard } from './clipboard.js';
|
|
||||||
export { default as ClipboardPipeline, type ClipboardContentInsertionEvent, type ClipboardContentInsertionData, type ClipboardInputTransformationEvent, type ClipboardInputTransformationData, type ClipboardOutputTransformationEvent, type ClipboardOutputTransformationData, type ViewDocumentClipboardOutputEvent } from './clipboardpipeline.js';
|
|
||||||
export { default as ClipboardMarkersUtils, type ClipboardMarkerRestrictedAction, type ClipboardMarkerConfiguration } from './clipboardmarkersutils.js';
|
|
||||||
export type { ClipboardEventData } from './clipboardobserver.js';
|
|
||||||
export { default as DragDrop } from './dragdrop.js';
|
|
||||||
export { default as PastePlainText } from './pasteplaintext.js';
|
|
||||||
export { default as DragDropTarget } from './dragdroptarget.js';
|
|
||||||
export { default as DragDropBlockToolbar } from './dragdropblocktoolbar.js';
|
|
||||||
export type { ViewDocumentClipboardInputEvent, ViewDocumentCopyEvent, ViewDocumentCutEvent } from './clipboardobserver.js';
|
|
||||||
import './augmentation.js';
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard
|
|
||||||
*/
|
|
||||||
export { default as Clipboard } from './clipboard.js';
|
|
||||||
export { default as ClipboardPipeline } from './clipboardpipeline.js';
|
|
||||||
export { default as ClipboardMarkersUtils } from './clipboardmarkersutils.js';
|
|
||||||
export { default as DragDrop } from './dragdrop.js';
|
|
||||||
export { default as PastePlainText } from './pasteplaintext.js';
|
|
||||||
export { default as DragDropTarget } from './dragdroptarget.js';
|
|
||||||
export { default as DragDropBlockToolbar } from './dragdropblocktoolbar.js';
|
|
||||||
import './augmentation.js';
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/lineview
|
|
||||||
*/
|
|
||||||
import { View } from '@ckeditor/ckeditor5-ui';
|
|
||||||
/**
|
|
||||||
* The horizontal drop target line view.
|
|
||||||
*/
|
|
||||||
export default class LineView extends View {
|
|
||||||
/**
|
|
||||||
* Controls whether the line is visible.
|
|
||||||
*
|
|
||||||
* @observable
|
|
||||||
* @default false
|
|
||||||
*/
|
|
||||||
isVisible: boolean;
|
|
||||||
/**
|
|
||||||
* Controls the line position x coordinate.
|
|
||||||
*
|
|
||||||
* @observable
|
|
||||||
* @default null
|
|
||||||
*/
|
|
||||||
left: number | null;
|
|
||||||
/**
|
|
||||||
* Controls the line width.
|
|
||||||
*
|
|
||||||
* @observable
|
|
||||||
* @default null
|
|
||||||
*/
|
|
||||||
width: number | null;
|
|
||||||
/**
|
|
||||||
* Controls the line position y coordinate.
|
|
||||||
*
|
|
||||||
* @observable
|
|
||||||
* @default null
|
|
||||||
*/
|
|
||||||
top: number | null;
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
constructor();
|
|
||||||
}
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/lineview
|
|
||||||
*/
|
|
||||||
/* istanbul ignore file -- @preserve */
|
|
||||||
import { View } from '@ckeditor/ckeditor5-ui';
|
|
||||||
import { toUnit } from '@ckeditor/ckeditor5-utils';
|
|
||||||
const toPx = toUnit('px');
|
|
||||||
/**
|
|
||||||
* The horizontal drop target line view.
|
|
||||||
*/
|
|
||||||
export default class LineView extends View {
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
const bind = this.bindTemplate;
|
|
||||||
this.set({
|
|
||||||
isVisible: false,
|
|
||||||
left: null,
|
|
||||||
top: null,
|
|
||||||
width: null
|
|
||||||
});
|
|
||||||
this.setTemplate({
|
|
||||||
tag: 'div',
|
|
||||||
attributes: {
|
|
||||||
class: [
|
|
||||||
'ck',
|
|
||||||
'ck-clipboard-drop-target-line',
|
|
||||||
bind.if('isVisible', 'ck-hidden', value => !value)
|
|
||||||
],
|
|
||||||
style: {
|
|
||||||
left: bind.to('left', left => toPx(left)),
|
|
||||||
top: bind.to('top', top => toPx(top)),
|
|
||||||
width: bind.to('width', width => toPx(width))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/pasteplaintext
|
|
||||||
*/
|
|
||||||
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
||||||
import ClipboardPipeline from './clipboardpipeline.js';
|
|
||||||
/**
|
|
||||||
* The plugin detects the user's intention to paste plain text.
|
|
||||||
*
|
|
||||||
* For example, it detects the <kbd>Ctrl/Cmd</kbd> + <kbd>Shift</kbd> + <kbd>V</kbd> keystroke.
|
|
||||||
*/
|
|
||||||
export default class PastePlainText extends Plugin {
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get pluginName(): "PastePlainText";
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get requires(): readonly [typeof ClipboardPipeline];
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
init(): void;
|
|
||||||
}
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/pasteplaintext
|
|
||||||
*/
|
|
||||||
import { Plugin } from '@ckeditor/ckeditor5-core';
|
|
||||||
import ClipboardObserver from './clipboardobserver.js';
|
|
||||||
import ClipboardPipeline from './clipboardpipeline.js';
|
|
||||||
/**
|
|
||||||
* The plugin detects the user's intention to paste plain text.
|
|
||||||
*
|
|
||||||
* For example, it detects the <kbd>Ctrl/Cmd</kbd> + <kbd>Shift</kbd> + <kbd>V</kbd> keystroke.
|
|
||||||
*/
|
|
||||||
export default class PastePlainText extends Plugin {
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get pluginName() {
|
|
||||||
return 'PastePlainText';
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
static get requires() {
|
|
||||||
return [ClipboardPipeline];
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
init() {
|
|
||||||
const editor = this.editor;
|
|
||||||
const model = editor.model;
|
|
||||||
const view = editor.editing.view;
|
|
||||||
const viewDocument = view.document;
|
|
||||||
const selection = model.document.selection;
|
|
||||||
let shiftPressed = false;
|
|
||||||
view.addObserver(ClipboardObserver);
|
|
||||||
this.listenTo(viewDocument, 'keydown', (evt, data) => {
|
|
||||||
shiftPressed = data.shiftKey;
|
|
||||||
});
|
|
||||||
editor.plugins.get(ClipboardPipeline).on('contentInsertion', (evt, data) => {
|
|
||||||
// Plain text can be determined based on the event flag (#7799) or auto-detection (#1006). If detected,
|
|
||||||
// preserve selection attributes on pasted items.
|
|
||||||
if (!shiftPressed && !isPlainTextFragment(data.content, model.schema)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
model.change(writer => {
|
|
||||||
// Formatting attributes should be preserved.
|
|
||||||
const textAttributes = Array.from(selection.getAttributes())
|
|
||||||
.filter(([key]) => model.schema.getAttributeProperties(key).isFormatting);
|
|
||||||
if (!selection.isCollapsed) {
|
|
||||||
model.deleteContent(selection, { doNotAutoparagraph: true });
|
|
||||||
}
|
|
||||||
// Also preserve other attributes if they survived the content deletion (because they were not fully selected).
|
|
||||||
// For example linkHref is not a formatting attribute but it should be preserved if pasted text was in the middle
|
|
||||||
// of a link.
|
|
||||||
textAttributes.push(...selection.getAttributes());
|
|
||||||
const range = writer.createRangeIn(data.content);
|
|
||||||
for (const item of range.getItems()) {
|
|
||||||
if (item.is('$textProxy')) {
|
|
||||||
writer.setAttributes(textAttributes, item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns true if specified `documentFragment` represents a plain text.
|
|
||||||
*/
|
|
||||||
function isPlainTextFragment(documentFragment, schema) {
|
|
||||||
if (documentFragment.childCount > 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const child = documentFragment.getChild(0);
|
|
||||||
if (schema.isObject(child)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Array.from(child.getAttributeKeys()).length == 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/utils/normalizeclipboarddata
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Removes some popular browser quirks out of the clipboard data (HTML).
|
|
||||||
* Removes all HTML comments. These are considered an internal thing and it makes little sense if they leak into the editor data.
|
|
||||||
*
|
|
||||||
* @param data The HTML data to normalize.
|
|
||||||
* @returns Normalized HTML.
|
|
||||||
*/
|
|
||||||
export default function normalizeClipboardData(data: string): string;
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/utils/normalizeclipboarddata
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Removes some popular browser quirks out of the clipboard data (HTML).
|
|
||||||
* Removes all HTML comments. These are considered an internal thing and it makes little sense if they leak into the editor data.
|
|
||||||
*
|
|
||||||
* @param data The HTML data to normalize.
|
|
||||||
* @returns Normalized HTML.
|
|
||||||
*/
|
|
||||||
export default function normalizeClipboardData(data) {
|
|
||||||
return data
|
|
||||||
.replace(/<span(?: class="Apple-converted-space"|)>(\s+)<\/span>/g, (fullMatch, spaces) => {
|
|
||||||
// Handle the most popular and problematic case when even a single space becomes an nbsp;.
|
|
||||||
// Decode those to normal spaces. Read more in https://github.com/ckeditor/ckeditor5-clipboard/issues/2.
|
|
||||||
if (spaces.length == 1) {
|
|
||||||
return ' ';
|
|
||||||
}
|
|
||||||
return spaces;
|
|
||||||
})
|
|
||||||
// Remove all HTML comments.
|
|
||||||
.replace(/<!--[\s\S]*?-->/g, '');
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/utils/plaintexttohtml
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Converts plain text to its HTML-ized version.
|
|
||||||
*
|
|
||||||
* @param text The plain text to convert.
|
|
||||||
* @returns HTML generated from the plain text.
|
|
||||||
*/
|
|
||||||
export default function plainTextToHtml(text: string): string;
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/utils/plaintexttohtml
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Converts plain text to its HTML-ized version.
|
|
||||||
*
|
|
||||||
* @param text The plain text to convert.
|
|
||||||
* @returns HTML generated from the plain text.
|
|
||||||
*/
|
|
||||||
export default function plainTextToHtml(text) {
|
|
||||||
text = text
|
|
||||||
// Encode &.
|
|
||||||
.replace(/&/g, '&')
|
|
||||||
// Encode <>.
|
|
||||||
.replace(/</g, '<')
|
|
||||||
.replace(/>/g, '>')
|
|
||||||
// Creates a paragraph for each double line break.
|
|
||||||
.replace(/\r?\n\r?\n/g, '</p><p>')
|
|
||||||
// Creates a line break for each single line break.
|
|
||||||
.replace(/\r?\n/g, '<br>')
|
|
||||||
// Replace tabs with four spaces.
|
|
||||||
.replace(/\t/g, ' ')
|
|
||||||
// Preserve trailing spaces (only the first and last one – the rest is handled below).
|
|
||||||
.replace(/^\s/, ' ')
|
|
||||||
.replace(/\s$/, ' ')
|
|
||||||
// Preserve other subsequent spaces now.
|
|
||||||
.replace(/\s\s/g, ' ');
|
|
||||||
if (text.includes('</p><p>') || text.includes('<br>')) {
|
|
||||||
// If we created paragraphs above, add the trailing ones.
|
|
||||||
text = `<p>${text}</p>`;
|
|
||||||
}
|
|
||||||
// TODO:
|
|
||||||
// * What about '\nfoo' vs ' foo'?
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 clipboard/utils/viewtoplaintext
|
|
||||||
*/
|
|
||||||
import type { ViewDocumentFragment, ViewItem } from '@ckeditor/ckeditor5-engine';
|
|
||||||
/**
|
|
||||||
* Converts {@link module:engine/view/item~Item view item} and all of its children to plain text.
|
|
||||||
*
|
|
||||||
* @param viewItem View item to convert.
|
|
||||||
* @returns Plain text representation of `viewItem`.
|
|
||||||
*/
|
|
||||||
export default function viewToPlainText(viewItem: ViewItem | ViewDocumentFragment): string;
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
/**
|
|
||||||
* @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
|
|
||||||
*/
|
|
||||||
// Elements which should not have empty-line padding.
|
|
||||||
// Most `view.ContainerElement` want to be separate by new-line, but some are creating one structure
|
|
||||||
// together (like `<li>`) so it is better to separate them by only one "\n".
|
|
||||||
const smallPaddingElements = ['figcaption', 'li'];
|
|
||||||
const listElements = ['ol', 'ul'];
|
|
||||||
/**
|
|
||||||
* Converts {@link module:engine/view/item~Item view item} and all of its children to plain text.
|
|
||||||
*
|
|
||||||
* @param viewItem View item to convert.
|
|
||||||
* @returns Plain text representation of `viewItem`.
|
|
||||||
*/
|
|
||||||
export default function viewToPlainText(viewItem) {
|
|
||||||
if (viewItem.is('$text') || viewItem.is('$textProxy')) {
|
|
||||||
return viewItem.data;
|
|
||||||
}
|
|
||||||
if (viewItem.is('element', 'img') && viewItem.hasAttribute('alt')) {
|
|
||||||
return viewItem.getAttribute('alt');
|
|
||||||
}
|
|
||||||
if (viewItem.is('element', 'br')) {
|
|
||||||
return '\n'; // Convert soft breaks to single line break (#8045).
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Item is a document fragment, attribute element or container element. It doesn't
|
|
||||||
* have it's own text value, so we need to convert its children elements.
|
|
||||||
*/
|
|
||||||
let text = '';
|
|
||||||
let prev = null;
|
|
||||||
for (const child of viewItem.getChildren()) {
|
|
||||||
text += newLinePadding(child, prev) + viewToPlainText(child);
|
|
||||||
prev = child;
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns new line padding to prefix the given elements with.
|
|
||||||
*/
|
|
||||||
function newLinePadding(element, previous) {
|
|
||||||
if (!previous) {
|
|
||||||
// Don't add padding to first elements in a level.
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
if (element.is('element', 'li') && !element.isEmpty && element.getChild(0).is('containerElement')) {
|
|
||||||
// Separate document list items with empty lines.
|
|
||||||
return '\n\n';
|
|
||||||
}
|
|
||||||
if (listElements.includes(element.name) && listElements.includes(previous.name)) {
|
|
||||||
/**
|
|
||||||
* Because `<ul>` and `<ol>` are AttributeElements, two consecutive lists will not have any padding between
|
|
||||||
* them (see the `if` statement below). To fix this, we need to make an exception for this case.
|
|
||||||
*/
|
|
||||||
return '\n\n';
|
|
||||||
}
|
|
||||||
if (!element.is('containerElement') && !previous.is('containerElement')) {
|
|
||||||
// Don't add padding between non-container elements.
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
if (smallPaddingElements.includes(element.name) || smallPaddingElements.includes(previous.name)) {
|
|
||||||
// Add small padding between selected container elements.
|
|
||||||
return '\n';
|
|
||||||
}
|
|
||||||
// Add empty lines between container elements.
|
|
||||||
return '\n\n';
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.ck-editor__editable {
|
|
||||||
/*
|
|
||||||
* Vertical drop target (in text).
|
|
||||||
*/
|
|
||||||
& .ck.ck-clipboard-drop-target-position {
|
|
||||||
display: inline;
|
|
||||||
position: relative;
|
|
||||||
pointer-events: none;
|
|
||||||
|
|
||||||
& span {
|
|
||||||
position: absolute;
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Styles of the widget being dragged (its preview).
|
|
||||||
*/
|
|
||||||
& .ck-widget:-webkit-drag {
|
|
||||||
& > .ck-widget__selection-handle {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .ck-widget__type-around {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ck.ck-clipboard-drop-target-line {
|
|
||||||
position: absolute;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
@ -1,610 +0,0 @@
|
||||||
Changelog
|
|
||||||
=========
|
|
||||||
|
|
||||||
## [41.3.1](https://github.com/ckeditor/ckeditor5/compare/v41.3.0...v41.3.1) (April 16, 2024)
|
|
||||||
|
|
||||||
We are happy to announce the release of CKEditor 5 v41.3.1.
|
|
||||||
|
|
||||||
The release addresses a vulnerability identified in the [`protobuf.js`](https://www.npmjs.com/package/protobufjs) package ([`CVE-2023-36665`](https://nvd.nist.gov/vuln/detail/CVE-2023-36665)), used within our **[`@ckeditor/ckeditor5-operations-compressor`](https://www.npmjs.com/package/@ckeditor/ckeditor5-operations-compressor)** package for real-time collaboration.
|
|
||||||
|
|
||||||
Our analysis confirms that **this vulnerability does not affect CKEditor 5**. None of the vulnerable code in the `protobuf.js` package is utilized in CKEditor 5, as we use protobuf’s `minimal` build type.
|
|
||||||
|
|
||||||
This release primarily aims to ensure that our customers using real-time collaboration features do not encounter unnecessary security alerts from their scanning tools. We are committed to maintaining the highest security standards, and this update reflects our ongoing efforts to safeguard user environments proactively.
|
|
||||||
|
|
||||||
### Bug fixes
|
|
||||||
|
|
||||||
* **[template](https://www.npmjs.com/package/@ckeditor/ckeditor5-template)**: Fixed the `TemplateDefinition#data` type in the `@ckeditor/ckeditor5-template` config. Now, it should be possible to define a string or a function returning a string instead of just a function returning a string.
|
|
||||||
|
|
||||||
### Released packages
|
|
||||||
|
|
||||||
Check out the [Versioning policy](https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/versioning-policy.html) guide for more information.
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Released packages (summary)</summary>
|
|
||||||
|
|
||||||
Other releases:
|
|
||||||
|
|
||||||
* [@ckeditor/ckeditor5-adapter-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-adapter-ckfinder/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-ai](https://www.npmjs.com/package/@ckeditor/ckeditor5-ai/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-alignment](https://www.npmjs.com/package/@ckeditor/ckeditor5-alignment/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-autoformat](https://www.npmjs.com/package/@ckeditor/ckeditor5-autoformat/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-autosave](https://www.npmjs.com/package/@ckeditor/ckeditor5-autosave/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-basic-styles](https://www.npmjs.com/package/@ckeditor/ckeditor5-basic-styles/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-block-quote](https://www.npmjs.com/package/@ckeditor/ckeditor5-block-quote/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-build-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-build-balloon-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon-block/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-build-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-build-decoupled-document](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-decoupled-document/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-build-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-inline/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-build-multi-root](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-multi-root/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-case-change](https://www.npmjs.com/package/@ckeditor/ckeditor5-case-change/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-ckbox](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckbox/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckfinder/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-clipboard](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-cloud-services](https://www.npmjs.com/package/@ckeditor/ckeditor5-cloud-services/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-code-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-code-block/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-collaboration-core](https://www.npmjs.com/package/@ckeditor/ckeditor5-collaboration-core/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-comments](https://www.npmjs.com/package/@ckeditor/ckeditor5-comments/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-core](https://www.npmjs.com/package/@ckeditor/ckeditor5-core/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-document-outline](https://www.npmjs.com/package/@ckeditor/ckeditor5-document-outline/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-easy-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-easy-image/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-editor-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-balloon/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-editor-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-classic/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-editor-decoupled](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-decoupled/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-editor-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-inline/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-editor-multi-root](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-multi-root/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-enter](https://www.npmjs.com/package/@ckeditor/ckeditor5-enter/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-essentials](https://www.npmjs.com/package/@ckeditor/ckeditor5-essentials/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-export-pdf](https://www.npmjs.com/package/@ckeditor/ckeditor5-export-pdf/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-export-word](https://www.npmjs.com/package/@ckeditor/ckeditor5-export-word/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-find-and-replace](https://www.npmjs.com/package/@ckeditor/ckeditor5-find-and-replace/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-font](https://www.npmjs.com/package/@ckeditor/ckeditor5-font/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-format-painter](https://www.npmjs.com/package/@ckeditor/ckeditor5-format-painter/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-heading](https://www.npmjs.com/package/@ckeditor/ckeditor5-heading/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-highlight](https://www.npmjs.com/package/@ckeditor/ckeditor5-highlight/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-horizontal-line](https://www.npmjs.com/package/@ckeditor/ckeditor5-horizontal-line/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-html-embed](https://www.npmjs.com/package/@ckeditor/ckeditor5-html-embed/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-html-support](https://www.npmjs.com/package/@ckeditor/ckeditor5-html-support/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-import-word](https://www.npmjs.com/package/@ckeditor/ckeditor5-import-word/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-indent](https://www.npmjs.com/package/@ckeditor/ckeditor5-indent/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-language](https://www.npmjs.com/package/@ckeditor/ckeditor5-language/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-list-multi-level](https://www.npmjs.com/package/@ckeditor/ckeditor5-list-multi-level/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-markdown-gfm](https://www.npmjs.com/package/@ckeditor/ckeditor5-markdown-gfm/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-media-embed](https://www.npmjs.com/package/@ckeditor/ckeditor5-media-embed/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-mention](https://www.npmjs.com/package/@ckeditor/ckeditor5-mention/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-minimap](https://www.npmjs.com/package/@ckeditor/ckeditor5-minimap/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-operations-compressor](https://www.npmjs.com/package/@ckeditor/ckeditor5-operations-compressor/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-page-break](https://www.npmjs.com/package/@ckeditor/ckeditor5-page-break/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-pagination](https://www.npmjs.com/package/@ckeditor/ckeditor5-pagination/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-paragraph](https://www.npmjs.com/package/@ckeditor/ckeditor5-paragraph/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-paste-from-office](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-paste-from-office-enhanced](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office-enhanced/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-real-time-collaboration](https://www.npmjs.com/package/@ckeditor/ckeditor5-real-time-collaboration/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-remove-format](https://www.npmjs.com/package/@ckeditor/ckeditor5-remove-format/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-restricted-editing](https://www.npmjs.com/package/@ckeditor/ckeditor5-restricted-editing/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-revision-history](https://www.npmjs.com/package/@ckeditor/ckeditor5-revision-history/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-select-all](https://www.npmjs.com/package/@ckeditor/ckeditor5-select-all/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-show-blocks](https://www.npmjs.com/package/@ckeditor/ckeditor5-show-blocks/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-slash-command](https://www.npmjs.com/package/@ckeditor/ckeditor5-slash-command/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-source-editing](https://www.npmjs.com/package/@ckeditor/ckeditor5-source-editing/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-special-characters](https://www.npmjs.com/package/@ckeditor/ckeditor5-special-characters/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-style](https://www.npmjs.com/package/@ckeditor/ckeditor5-style/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-table](https://www.npmjs.com/package/@ckeditor/ckeditor5-table/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-template](https://www.npmjs.com/package/@ckeditor/ckeditor5-template/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-theme-lark](https://www.npmjs.com/package/@ckeditor/ckeditor5-theme-lark/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-track-changes](https://www.npmjs.com/package/@ckeditor/ckeditor5-track-changes/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-typing](https://www.npmjs.com/package/@ckeditor/ckeditor5-typing/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-undo](https://www.npmjs.com/package/@ckeditor/ckeditor5-undo/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-upload](https://www.npmjs.com/package/@ckeditor/ckeditor5-upload/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-watchdog](https://www.npmjs.com/package/@ckeditor/ckeditor5-watchdog/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-widget](https://www.npmjs.com/package/@ckeditor/ckeditor5-widget/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [@ckeditor/ckeditor5-word-count](https://www.npmjs.com/package/@ckeditor/ckeditor5-word-count/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
* [ckeditor5-collaboration](https://www.npmjs.com/package/ckeditor5-collaboration/v/41.3.1): v41.3.0 => v41.3.1
|
|
||||||
</details>
|
|
||||||
|
|
||||||
|
|
||||||
## [41.3.0](https://github.com/ckeditor/ckeditor5/compare/v41.2.1...v41.3.0) (April 10, 2024)
|
|
||||||
|
|
||||||
We are happy to announce the release of CKEditor 5 v41.3.0.
|
|
||||||
|
|
||||||
### Release highlights
|
|
||||||
|
|
||||||
#### Multi-level lists ⭐️
|
|
||||||
|
|
||||||
CKEditor 5's latest update brings a new premium feature: the [Multi-level lists](https://ckeditor.com/docs/ckeditor5/latest/features/lists/multi-level-lists.html) feature. It allows for easy creation and modification of numbered lists with counters (`1., 1.1., 1.1.1`), crucial for clear referencing and hierarchical organization in complex documents. The feature ensures compatibility with Microsoft Word. When lists with such formatting are pasted to the editor, the numbering format and counters are retained.
|
|
||||||
|
|
||||||
#### Paste from Office improvements for lists
|
|
||||||
|
|
||||||
No more breaking numbering of lists when they are pasted from Office. Previously whenever a list were split by paragraphs, the counter started again from 1. With our latest improvement, the counter is correctly preserved. Moreover, if you use Paste from Office Enhanced ⭐️, the paragraphs will be merged into list items, to ensure proper, semantic content.
|
|
||||||
|
|
||||||
⚠️ If you use the `LegacyList` plugin to prolong the migration to the new list implementation, bear in mind that from this release Paste from Office stops working for the lists' implementation you are using. Migrate to `List` to maintain pasting lists functionality.
|
|
||||||
|
|
||||||
#### Menu bar
|
|
||||||
|
|
||||||
The menu bar is a user interface component popular in large editing desktop and online packages. It gives you access to all features provided by the editor, organized in menus and categories and improves usability of the editor, keeping the toolbar can be simple and tidy. This is especially welcome in heavily-featured editor integrations.
|
|
||||||
|
|
||||||
Current release bring this battle-hardened solution to CKEditor 5! The [menu bar](https://ckeditor.com/docs/ckeditor5/latest/features/toolbar/menubar.html) can easily be enabled in selected editor types, comes with a handy features preset and is also highly configurable.
|
|
||||||
|
|
||||||
### MINOR BREAKING CHANGES [ℹ️](https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/versioning-policy.html#major-and-minor-breaking-changes)
|
|
||||||
|
|
||||||
* **[image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image)**: The CSS custom property `--ck-color-image-caption-highligted-background` has been renamed to `--ck-color-image-caption-highlighted-background`. Please make sure to update your custom CSS accordingly.
|
|
||||||
* **[real-time-collaboration](https://www.npmjs.com/package/@ckeditor/ckeditor5-real-time-collaboration)**: The username displayed next to the user marker in the edited content is no longer a CSS pseudo-element. Use the `.ck-user__marker-tooltip` CSS class to customize usernames instead.
|
|
||||||
* **[ai](https://www.npmjs.com/package/@ckeditor/ckeditor5-ai)**: When `config.ai.openAI.requestParameters` or `config.ai.aws.requestParameters` are set, the set value will fully overwrite the default value. Most importantly, if you do not specify some properties in `requestParameters` they will not be set to default. For example, if you set `openAI.requestParameters` to `{ max_tokens: 1000 }`, the request parameters will be set exactly to that object. Make sure that you pass all necessary parameters in `requestParameters`. Important: this change happened in version 41.2.0 but has not been previously announced in the changelog.
|
|
||||||
* **[upload](https://www.npmjs.com/package/@ckeditor/ckeditor5-upload)**: The `FileDialogButtonView` class has been moved from `ckeditor5-upload` to `ckeditor5-ui`. Please update your import paths accordingly (was: `import { FileDialogButtonView } from 'ckeditor5/src/upload.js';`, is: `import { FileDialogButtonView } from 'ckeditor5/src/ui.js';`).
|
|
||||||
* **[theme-lark](https://www.npmjs.com/package/@ckeditor/ckeditor5-theme-lark)**: The default vertical spacing around `ButtonView` in `ListItemView` (`--ck-list-button-padding`) has been reduced for better readability. This affects the presentation of various editor features that use this type of UI (headings, font size, font family, etc.). You can restore the previous value by setting `--ck-list-button-padding: calc(.2 * var(--ck-line-height-base) * var(--ck-font-size-base)) calc(.4 * var(--ck-line-height-base) * var(--ck-font-size-base));` in your custom styles sheet.
|
|
||||||
* **[comments](https://www.npmjs.com/package/@ckeditor/ckeditor5-comments)**: From this release on, the UI of the Comments Archive feature is displayed in a dialog instead of a dropdown.
|
|
||||||
* **[revision-history](https://www.npmjs.com/package/@ckeditor/ckeditor5-revision-history)**: The UI for saving the new revision is displayed in a dialog instead of a dropdown.
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **[comments](https://www.npmjs.com/package/@ckeditor/ckeditor5-comments)**: Partially selected comment markers will no longer be copied unless fully selected, regardless of the copy mode set in the configuration.
|
|
||||||
* **[list-multi-level](https://www.npmjs.com/package/@ckeditor/ckeditor5-list-multi-level)**: Introduced the multi-level list with legal style list numbering.
|
|
||||||
* **[track-changes](https://www.npmjs.com/package/@ckeditor/ckeditor5-track-changes)**: Introduced the multi-level list with legal style list numbering.
|
|
||||||
* **[ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui)**: Added the `[tabindex]` DOM attribute support to the `InputBase` class. ([commit](https://github.com/ckeditor/ckeditor5/commit/5a399811c3c21644f1b6e782236b60e6d2097add))
|
|
||||||
* **[ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui)**: Added the `[aria-label]` attribute support to the `InputBase` class. ([commit](https://github.com/ckeditor/ckeditor5/commit/952cd7599bf623ea2a9be92dbde1a01e8ff73daa))
|
|
||||||
* **[ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui)**: Implemented the application menu bar that contains various options and commands for controlling and navigating the editor. Closes [#15894](https://github.com/ckeditor/ckeditor5/issues/15894). ([commit](https://github.com/ckeditor/ckeditor5/commit/f072048026c5407467e343c116c71ff5a9d236b4))
|
|
||||||
* **[utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils)**: Added the <kbd>Page Up</kbd> and <kbd>Page Down</kbd> keys to the keyboard utilities (`keyCodes`, `getEnvKeystrokeText()`). ([commit](https://github.com/ckeditor/ckeditor5/commit/0c64f2abda6a25ca0cd76c3ca7995b75f57d3104))
|
|
||||||
|
|
||||||
### Bug fixes
|
|
||||||
|
|
||||||
* **[ai](https://www.npmjs.com/package/@ckeditor/ckeditor5-ai)**: Increased the priority of AI selection markers to display them over the overlapping comments.
|
|
||||||
* **[alignment](https://www.npmjs.com/package/@ckeditor/ckeditor5-alignment)**: Tooltips for buttons inside the alignment dropdown should not obscure adjacent buttons. Closes [#16109](https://github.com/ckeditor/ckeditor5/issues/16109). ([commit](https://github.com/ckeditor/ckeditor5/commit/64b51c47fe27354aac4795c699f7a19a86ac5242))
|
|
||||||
* **[comments](https://www.npmjs.com/package/@ckeditor/ckeditor5-comments)**: Fixed issue causing the editor to throw `collection-add-item-invalid-index` error in some scenarios when some comment threads were resolved and some were unlinked (removed from content).
|
|
||||||
* **[document-outline](https://www.npmjs.com/package/@ckeditor/ckeditor5-document-outline)**: Should not throw errors while pasting and cutting in document outline feature.
|
|
||||||
* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: Copying the content with markers will no longer trigger the `change:data` event. Closes [#15943](https://github.com/ckeditor/ckeditor5/issues/15943). ([commit](https://github.com/ckeditor/ckeditor5/commit/39a77912905694a61e8da4c42dd1b36f76fde400))
|
|
||||||
* **[heading](https://www.npmjs.com/package/@ckeditor/ckeditor5-heading)**: An accessible button label should describe the state and the name of the feature for optimal UX. ([commit](https://github.com/ckeditor/ckeditor5/commit/571bcf5d0224ffe97037c92391cab3c78dc54820))
|
|
||||||
* **[language](https://www.npmjs.com/package/@ckeditor/ckeditor5-language)**: An accessible button label should describe the state and the name of the feature for optimal UX. ([commit](https://github.com/ckeditor/ckeditor5/commit/571bcf5d0224ffe97037c92391cab3c78dc54820))
|
|
||||||
* **[minimap](https://www.npmjs.com/package/@ckeditor/ckeditor5-minimap)**: The minimap should not steal DOM focus while tabbing across the document. ([commit](https://github.com/ckeditor/ckeditor5/commit/54eae6a1bb1a72d42f00b43fcf7f7f0b167507ba))
|
|
||||||
* **[pagination](https://www.npmjs.com/package/@ckeditor/ckeditor5-pagination)**: The pagination navigation buttons should both scroll the document and move the selection (accessibility). Added keyboard shortcuts for navigating through the document.
|
|
||||||
* **[pagination](https://www.npmjs.com/package/@ckeditor/ckeditor5-pagination)**: The pagination page number input should not participate in web page navigation on tab key press to comply with WCAG recommendations (see [ckeditor/ckeditor5#16025](https://github.com/ckeditor/ckeditor5/issues/16025)).
|
|
||||||
* **[pagination](https://www.npmjs.com/package/@ckeditor/ckeditor5-pagination)**: The current page input in the toolbar should be accessible to screen readers. See [ckeditor/ckeditor5#16028](https://github.com/ckeditor/ckeditor5/issues/16028).
|
|
||||||
* **[paste-from-office](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office)**: The paste from Office feature should not break the list on the following blocks in the same list item or deduce a start attribute for a split list. Closes [#11210](https://github.com/ckeditor/ckeditor5/issues/11210), [#15964](https://github.com/ckeditor/ckeditor5/issues/15964). ([commit](https://github.com/ckeditor/ckeditor5/commit/a25e3f2a7e3c3d94ac04bbf900ff2de739c1939f))
|
|
||||||
* **[real-time-collaboration](https://www.npmjs.com/package/@ckeditor/ckeditor5-real-time-collaboration)**: Users should be able to move the mouse cursor to the user name displayed next to the user marker and dismiss it using the <kbd>Esc</kbd> key.
|
|
||||||
* **[restricted-editing](https://www.npmjs.com/package/@ckeditor/ckeditor5-restricted-editing)**: It should be possible to remove an image placed inside an editable field in restricted editing mode. Closes [#15521](https://github.com/ckeditor/ckeditor5/issues/15521). ([commit](https://github.com/ckeditor/ckeditor5/commit/b4f159c00831fefd3b99afd4c362a2f1d8f4aa63))
|
|
||||||
* **[ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui)**: Users should be able to move the mouse cursor to a UI tooltip without closing it. ([commit](https://github.com/ckeditor/ckeditor5/commit/7df13e970b56542b43b723bec8b4cbcb877a32a4))
|
|
||||||
* **[ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui)**: Users should be able to close UI tooltips using the <kbd>Esc</kbd> key. ([commit](https://github.com/ckeditor/ckeditor5/commit/7df13e970b56542b43b723bec8b4cbcb877a32a4))
|
|
||||||
* **[watchdog](https://www.npmjs.com/package/@ckeditor/ckeditor5-watchdog)**: `EditorWatchdog` will no longer crash when the application is refreshed before completing the editor initialization or destruction. Closes [#15980](https://github.com/ckeditor/ckeditor5/issues/15980). ([commit](https://github.com/ckeditor/ckeditor5/commit/90aeb2765b1f34f3894b4299ae805ef27869b6ff))
|
|
||||||
* **[widget](https://www.npmjs.com/package/@ckeditor/ckeditor5-widget)**: Native browser `tab` key support should be disabled for cycling nested editable elements inside the editor. Closes [#15506](https://github.com/ckeditor/ckeditor5/issues/15506). ([commit](https://github.com/ckeditor/ckeditor5/commit/e55c6c1cf7309584fa6babc214e6fa339f6b0798))
|
|
||||||
|
|
||||||
### Other changes
|
|
||||||
|
|
||||||
* **[clipboard](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard)**: By default, markers will not be copied if they are only partially selected. ([commit](https://github.com/ckeditor/ckeditor5/commit/39a77912905694a61e8da4c42dd1b36f76fde400))
|
|
||||||
* **[comments](https://www.npmjs.com/package/@ckeditor/ckeditor5-comments)**: In the default copy comments mode, markers that have been copied will not be pasted if they already exist in the document.
|
|
||||||
* **[core](https://www.npmjs.com/package/@ckeditor/ckeditor5-core)**: Clarified the description of keystrokes that execute various buttons (Space, Enter) in the accessibility help dialog. ([commit](https://github.com/ckeditor/ckeditor5/commit/2b908136e567723ed7de86fb5642d22643be6c65))
|
|
||||||
* **[html-support](https://www.npmjs.com/package/@ckeditor/ckeditor5-html-support)**: Introduced the multi-level list with legal style list numbering. Closes [#10859](https://github.com/ckeditor/ckeditor5/issues/10859). ([commit](https://github.com/ckeditor/ckeditor5/commit/45a4a8e5c91224f34088f8f38b5d489fa4c37d0a))
|
|
||||||
* **[image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image)**: Fixed a typo in the name of CSS custom property for the highlighted state of an image caption. ([commit](https://github.com/ckeditor/ckeditor5/commit/e9f0c137619b828ccb5a8e1611f4076f2ec852a6))
|
|
||||||
* **[list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list)**: Introduced the multi-level list with legal style list numbering. Closes [#10859](https://github.com/ckeditor/ckeditor5/issues/10859). ([commit](https://github.com/ckeditor/ckeditor5/commit/45a4a8e5c91224f34088f8f38b5d489fa4c37d0a))
|
|
||||||
* **[mention](https://www.npmjs.com/package/@ckeditor/ckeditor5-mention)**: Export MentionsView, MentionListItemView, DomWrapperView classes and MentionFeedObjectItem type. Closes [#16044](https://github.com/ckeditor/ckeditor5/issues/16044). ([commit](https://github.com/ckeditor/ckeditor5/commit/9a62fc866f34bf5846fabe9afa5069546e9b582a))
|
|
||||||
* **[paste-from-office](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office)**: Introduced the multi-level list with legal style list numbering. Closes [#10859](https://github.com/ckeditor/ckeditor5/issues/10859). ([commit](https://github.com/ckeditor/ckeditor5/commit/45a4a8e5c91224f34088f8f38b5d489fa4c37d0a))
|
|
||||||
* **[style](https://www.npmjs.com/package/@ckeditor/ckeditor5-style)**: Introduced the multi-level list with legal style list numbering. Closes [#10859](https://github.com/ckeditor/ckeditor5/issues/10859). ([commit](https://github.com/ckeditor/ckeditor5/commit/45a4a8e5c91224f34088f8f38b5d489fa4c37d0a))
|
|
||||||
* Updated translations. ([commit](https://github.com/ckeditor/ckeditor5/commit/3e535fd8762313e74d5701b2e3da8b1656d011b2), [commit](https://github.com/ckeditor/ckeditor5/commit/f4c1dfca44f78409b8ee5de6be99921fcecb6f9c))
|
|
||||||
|
|
||||||
### Released packages
|
|
||||||
|
|
||||||
Check out the [Versioning policy](https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/versioning-policy.html) guide for more information.
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Released packages (summary)</summary>
|
|
||||||
|
|
||||||
New packages:
|
|
||||||
|
|
||||||
* [@ckeditor/ckeditor5-list-multi-level](https://www.npmjs.com/package/@ckeditor/ckeditor5-list-multi-level/v/41.3.0): v41.3.0
|
|
||||||
|
|
||||||
Minor releases (contain minor breaking changes):
|
|
||||||
|
|
||||||
* [@ckeditor/ckeditor5-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-real-time-collaboration](https://www.npmjs.com/package/@ckeditor/ckeditor5-real-time-collaboration/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
|
|
||||||
Releases containing new features:
|
|
||||||
|
|
||||||
* [@ckeditor/ckeditor5-alignment](https://www.npmjs.com/package/@ckeditor/ckeditor5-alignment/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-basic-styles](https://www.npmjs.com/package/@ckeditor/ckeditor5-basic-styles/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-block-quote](https://www.npmjs.com/package/@ckeditor/ckeditor5-block-quote/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-ckbox](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckbox/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckfinder/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-code-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-code-block/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-core](https://www.npmjs.com/package/@ckeditor/ckeditor5-core/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-editor-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-classic/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-editor-decoupled](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-decoupled/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-find-and-replace](https://www.npmjs.com/package/@ckeditor/ckeditor5-find-and-replace/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-font](https://www.npmjs.com/package/@ckeditor/ckeditor5-font/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-heading](https://www.npmjs.com/package/@ckeditor/ckeditor5-heading/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-highlight](https://www.npmjs.com/package/@ckeditor/ckeditor5-highlight/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-horizontal-line](https://www.npmjs.com/package/@ckeditor/ckeditor5-horizontal-line/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-html-embed](https://www.npmjs.com/package/@ckeditor/ckeditor5-html-embed/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-indent](https://www.npmjs.com/package/@ckeditor/ckeditor5-indent/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-language](https://www.npmjs.com/package/@ckeditor/ckeditor5-language/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-page-break](https://www.npmjs.com/package/@ckeditor/ckeditor5-page-break/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-remove-format](https://www.npmjs.com/package/@ckeditor/ckeditor5-remove-format/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-restricted-editing](https://www.npmjs.com/package/@ckeditor/ckeditor5-restricted-editing/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-select-all](https://www.npmjs.com/package/@ckeditor/ckeditor5-select-all/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-show-blocks](https://www.npmjs.com/package/@ckeditor/ckeditor5-show-blocks/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-source-editing](https://www.npmjs.com/package/@ckeditor/ckeditor5-source-editing/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-table](https://www.npmjs.com/package/@ckeditor/ckeditor5-table/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-theme-lark](https://www.npmjs.com/package/@ckeditor/ckeditor5-theme-lark/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-undo](https://www.npmjs.com/package/@ckeditor/ckeditor5-undo/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-upload](https://www.npmjs.com/package/@ckeditor/ckeditor5-upload/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
|
|
||||||
Other releases:
|
|
||||||
|
|
||||||
* [@ckeditor/ckeditor5-adapter-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-adapter-ckfinder/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-ai](https://www.npmjs.com/package/@ckeditor/ckeditor5-ai/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-autoformat](https://www.npmjs.com/package/@ckeditor/ckeditor5-autoformat/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-autosave](https://www.npmjs.com/package/@ckeditor/ckeditor5-autosave/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-build-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-build-balloon-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon-block/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-build-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-build-decoupled-document](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-decoupled-document/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-build-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-inline/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-build-multi-root](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-multi-root/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-case-change](https://www.npmjs.com/package/@ckeditor/ckeditor5-case-change/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-clipboard](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-cloud-services](https://www.npmjs.com/package/@ckeditor/ckeditor5-cloud-services/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-collaboration-core](https://www.npmjs.com/package/@ckeditor/ckeditor5-collaboration-core/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-comments](https://www.npmjs.com/package/@ckeditor/ckeditor5-comments/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-document-outline](https://www.npmjs.com/package/@ckeditor/ckeditor5-document-outline/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-easy-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-easy-image/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-editor-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-balloon/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-editor-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-inline/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-editor-multi-root](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-multi-root/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-enter](https://www.npmjs.com/package/@ckeditor/ckeditor5-enter/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-essentials](https://www.npmjs.com/package/@ckeditor/ckeditor5-essentials/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-export-pdf](https://www.npmjs.com/package/@ckeditor/ckeditor5-export-pdf/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-export-word](https://www.npmjs.com/package/@ckeditor/ckeditor5-export-word/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-format-painter](https://www.npmjs.com/package/@ckeditor/ckeditor5-format-painter/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-html-support](https://www.npmjs.com/package/@ckeditor/ckeditor5-html-support/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-import-word](https://www.npmjs.com/package/@ckeditor/ckeditor5-import-word/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-markdown-gfm](https://www.npmjs.com/package/@ckeditor/ckeditor5-markdown-gfm/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-media-embed](https://www.npmjs.com/package/@ckeditor/ckeditor5-media-embed/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-mention](https://www.npmjs.com/package/@ckeditor/ckeditor5-mention/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-minimap](https://www.npmjs.com/package/@ckeditor/ckeditor5-minimap/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-operations-compressor](https://www.npmjs.com/package/@ckeditor/ckeditor5-operations-compressor/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-pagination](https://www.npmjs.com/package/@ckeditor/ckeditor5-pagination/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-paragraph](https://www.npmjs.com/package/@ckeditor/ckeditor5-paragraph/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-paste-from-office](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-paste-from-office-enhanced](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office-enhanced/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-revision-history](https://www.npmjs.com/package/@ckeditor/ckeditor5-revision-history/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-slash-command](https://www.npmjs.com/package/@ckeditor/ckeditor5-slash-command/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-special-characters](https://www.npmjs.com/package/@ckeditor/ckeditor5-special-characters/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-style](https://www.npmjs.com/package/@ckeditor/ckeditor5-style/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-template](https://www.npmjs.com/package/@ckeditor/ckeditor5-template/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-track-changes](https://www.npmjs.com/package/@ckeditor/ckeditor5-track-changes/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-typing](https://www.npmjs.com/package/@ckeditor/ckeditor5-typing/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-watchdog](https://www.npmjs.com/package/@ckeditor/ckeditor5-watchdog/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-widget](https://www.npmjs.com/package/@ckeditor/ckeditor5-widget/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [@ckeditor/ckeditor5-word-count](https://www.npmjs.com/package/@ckeditor/ckeditor5-word-count/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
* [ckeditor5-collaboration](https://www.npmjs.com/package/ckeditor5-collaboration/v/41.3.0): v41.2.1 => v41.3.0
|
|
||||||
</details>
|
|
||||||
|
|
||||||
|
|
||||||
## [41.3.0-alpha.4](https://github.com/ckeditor/ckeditor5/compare/v41.3.0-alpha.1...v41.3.0-alpha.4) (April 2, 2024)
|
|
||||||
|
|
||||||
We are happy to announce the release of CKEditor 5 v41.3.0-alpha.4.
|
|
||||||
|
|
||||||
This release is intended to improve the build speed in bundlers when using the `ckeditor5` npm package and to improve typings for translations.
|
|
||||||
|
|
||||||
For instructions on how to use the new installation methods, see the [v41.3.0-alpha.0 Release Notes](https://github.com/ckeditor/ckeditor5/releases/tag/v41.3.0-alpha.0).
|
|
||||||
|
|
||||||
For more general information about the new installation methods, see the [announcement post](https://github.com/ckeditor/ckeditor5/issues/15502).
|
|
||||||
|
|
||||||
### Released packages
|
|
||||||
|
|
||||||
Check out the [Versioning policy](https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/versioning-policy.html) guide for more information.
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Released packages (summary)</summary>
|
|
||||||
|
|
||||||
New packages:
|
|
||||||
|
|
||||||
* [ckeditor5-premium-features](https://www.npmjs.com/package/ckeditor5-premium-features/v/41.3.0-alpha.4): v41.3.0-alpha.4
|
|
||||||
|
|
||||||
Other releases:
|
|
||||||
|
|
||||||
* [@ckeditor/ckeditor5-adapter-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-adapter-ckfinder/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-ai](https://www.npmjs.com/package/@ckeditor/ckeditor5-ai/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-alignment](https://www.npmjs.com/package/@ckeditor/ckeditor5-alignment/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-autoformat](https://www.npmjs.com/package/@ckeditor/ckeditor5-autoformat/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-autosave](https://www.npmjs.com/package/@ckeditor/ckeditor5-autosave/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-basic-styles](https://www.npmjs.com/package/@ckeditor/ckeditor5-basic-styles/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-block-quote](https://www.npmjs.com/package/@ckeditor/ckeditor5-block-quote/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-build-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-build-balloon-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon-block/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-build-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-build-decoupled-document](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-decoupled-document/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-build-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-inline/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-build-multi-root](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-multi-root/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-case-change](https://www.npmjs.com/package/@ckeditor/ckeditor5-case-change/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-ckbox](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckbox/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckfinder/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-clipboard](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-cloud-services](https://www.npmjs.com/package/@ckeditor/ckeditor5-cloud-services/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-code-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-code-block/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-collaboration-core](https://www.npmjs.com/package/@ckeditor/ckeditor5-collaboration-core/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-comments](https://www.npmjs.com/package/@ckeditor/ckeditor5-comments/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-core](https://www.npmjs.com/package/@ckeditor/ckeditor5-core/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-document-outline](https://www.npmjs.com/package/@ckeditor/ckeditor5-document-outline/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-easy-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-easy-image/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-editor-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-balloon/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-editor-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-classic/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-editor-decoupled](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-decoupled/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-editor-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-inline/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-editor-multi-root](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-multi-root/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-enter](https://www.npmjs.com/package/@ckeditor/ckeditor5-enter/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-essentials](https://www.npmjs.com/package/@ckeditor/ckeditor5-essentials/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-export-pdf](https://www.npmjs.com/package/@ckeditor/ckeditor5-export-pdf/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-export-word](https://www.npmjs.com/package/@ckeditor/ckeditor5-export-word/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-find-and-replace](https://www.npmjs.com/package/@ckeditor/ckeditor5-find-and-replace/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-font](https://www.npmjs.com/package/@ckeditor/ckeditor5-font/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-format-painter](https://www.npmjs.com/package/@ckeditor/ckeditor5-format-painter/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-heading](https://www.npmjs.com/package/@ckeditor/ckeditor5-heading/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-highlight](https://www.npmjs.com/package/@ckeditor/ckeditor5-highlight/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-horizontal-line](https://www.npmjs.com/package/@ckeditor/ckeditor5-horizontal-line/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-html-embed](https://www.npmjs.com/package/@ckeditor/ckeditor5-html-embed/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-html-support](https://www.npmjs.com/package/@ckeditor/ckeditor5-html-support/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-import-word](https://www.npmjs.com/package/@ckeditor/ckeditor5-import-word/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-indent](https://www.npmjs.com/package/@ckeditor/ckeditor5-indent/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-language](https://www.npmjs.com/package/@ckeditor/ckeditor5-language/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-markdown-gfm](https://www.npmjs.com/package/@ckeditor/ckeditor5-markdown-gfm/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-media-embed](https://www.npmjs.com/package/@ckeditor/ckeditor5-media-embed/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-mention](https://www.npmjs.com/package/@ckeditor/ckeditor5-mention/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-minimap](https://www.npmjs.com/package/@ckeditor/ckeditor5-minimap/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-operations-compressor](https://www.npmjs.com/package/@ckeditor/ckeditor5-operations-compressor/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-page-break](https://www.npmjs.com/package/@ckeditor/ckeditor5-page-break/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-pagination](https://www.npmjs.com/package/@ckeditor/ckeditor5-pagination/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-paragraph](https://www.npmjs.com/package/@ckeditor/ckeditor5-paragraph/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-paste-from-office](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-paste-from-office-enhanced](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office-enhanced/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-real-time-collaboration](https://www.npmjs.com/package/@ckeditor/ckeditor5-real-time-collaboration/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-remove-format](https://www.npmjs.com/package/@ckeditor/ckeditor5-remove-format/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-restricted-editing](https://www.npmjs.com/package/@ckeditor/ckeditor5-restricted-editing/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-revision-history](https://www.npmjs.com/package/@ckeditor/ckeditor5-revision-history/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-select-all](https://www.npmjs.com/package/@ckeditor/ckeditor5-select-all/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-show-blocks](https://www.npmjs.com/package/@ckeditor/ckeditor5-show-blocks/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-slash-command](https://www.npmjs.com/package/@ckeditor/ckeditor5-slash-command/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-source-editing](https://www.npmjs.com/package/@ckeditor/ckeditor5-source-editing/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-special-characters](https://www.npmjs.com/package/@ckeditor/ckeditor5-special-characters/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-style](https://www.npmjs.com/package/@ckeditor/ckeditor5-style/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-table](https://www.npmjs.com/package/@ckeditor/ckeditor5-table/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-template](https://www.npmjs.com/package/@ckeditor/ckeditor5-template/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-theme-lark](https://www.npmjs.com/package/@ckeditor/ckeditor5-theme-lark/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-track-changes](https://www.npmjs.com/package/@ckeditor/ckeditor5-track-changes/v/41.3.0-alpha.4): v41.2.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-typing](https://www.npmjs.com/package/@ckeditor/ckeditor5-typing/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-undo](https://www.npmjs.com/package/@ckeditor/ckeditor5-undo/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-upload](https://www.npmjs.com/package/@ckeditor/ckeditor5-upload/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-watchdog](https://www.npmjs.com/package/@ckeditor/ckeditor5-watchdog/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-widget](https://www.npmjs.com/package/@ckeditor/ckeditor5-widget/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
* [@ckeditor/ckeditor5-word-count](https://www.npmjs.com/package/@ckeditor/ckeditor5-word-count/v/41.3.0-alpha.4): v41.3.0-alpha.1 => v41.3.0-alpha.4
|
|
||||||
</details>
|
|
||||||
|
|
||||||
|
|
||||||
## [41.3.0-alpha.3](https://github.com/ckeditor/ckeditor5/compare/v41.3.0-alpha.1...v41.3.0-alpha.3) (April 2, 2024)
|
|
||||||
|
|
||||||
We are happy to announce the release of CKEditor 5 v41.3.0-alpha.3.
|
|
||||||
|
|
||||||
This release is intended to improve the build speed in bundlers when using the `ckeditor5` npm package and to improve typings for translations.
|
|
||||||
|
|
||||||
For instructions on how to use the new installation methods, see the [v41.3.0-alpha.0 Release Notes](https://github.com/ckeditor/ckeditor5/releases/tag/v41.3.0-alpha.0).
|
|
||||||
|
|
||||||
For more general information about the new installation methods, see the [announcement post](https://github.com/ckeditor/ckeditor5/issues/15502).
|
|
||||||
|
|
||||||
### Released packages
|
|
||||||
|
|
||||||
Check out the [Versioning policy](https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/versioning-policy.html) guide for more information.
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Released packages (summary)</summary>
|
|
||||||
|
|
||||||
New packages:
|
|
||||||
|
|
||||||
* [ckeditor5-premium-features](https://www.npmjs.com/package/ckeditor5-premium-features/v/41.3.0-alpha.3): v41.3.0-alpha.3
|
|
||||||
|
|
||||||
Other releases:
|
|
||||||
|
|
||||||
* [@ckeditor/ckeditor5-adapter-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-adapter-ckfinder/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-ai](https://www.npmjs.com/package/@ckeditor/ckeditor5-ai/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-alignment](https://www.npmjs.com/package/@ckeditor/ckeditor5-alignment/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-autoformat](https://www.npmjs.com/package/@ckeditor/ckeditor5-autoformat/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-autosave](https://www.npmjs.com/package/@ckeditor/ckeditor5-autosave/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-basic-styles](https://www.npmjs.com/package/@ckeditor/ckeditor5-basic-styles/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-block-quote](https://www.npmjs.com/package/@ckeditor/ckeditor5-block-quote/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-build-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-build-balloon-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon-block/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-build-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-build-decoupled-document](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-decoupled-document/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-build-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-inline/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-build-multi-root](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-multi-root/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-case-change](https://www.npmjs.com/package/@ckeditor/ckeditor5-case-change/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-ckbox](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckbox/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckfinder/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-clipboard](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-cloud-services](https://www.npmjs.com/package/@ckeditor/ckeditor5-cloud-services/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-code-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-code-block/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-collaboration-core](https://www.npmjs.com/package/@ckeditor/ckeditor5-collaboration-core/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-comments](https://www.npmjs.com/package/@ckeditor/ckeditor5-comments/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-core](https://www.npmjs.com/package/@ckeditor/ckeditor5-core/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-document-outline](https://www.npmjs.com/package/@ckeditor/ckeditor5-document-outline/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-easy-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-easy-image/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-editor-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-balloon/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-editor-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-classic/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-editor-decoupled](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-decoupled/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-editor-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-inline/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-editor-multi-root](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-multi-root/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-enter](https://www.npmjs.com/package/@ckeditor/ckeditor5-enter/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-essentials](https://www.npmjs.com/package/@ckeditor/ckeditor5-essentials/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-export-pdf](https://www.npmjs.com/package/@ckeditor/ckeditor5-export-pdf/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-export-word](https://www.npmjs.com/package/@ckeditor/ckeditor5-export-word/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-find-and-replace](https://www.npmjs.com/package/@ckeditor/ckeditor5-find-and-replace/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-font](https://www.npmjs.com/package/@ckeditor/ckeditor5-font/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-format-painter](https://www.npmjs.com/package/@ckeditor/ckeditor5-format-painter/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-heading](https://www.npmjs.com/package/@ckeditor/ckeditor5-heading/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-highlight](https://www.npmjs.com/package/@ckeditor/ckeditor5-highlight/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-horizontal-line](https://www.npmjs.com/package/@ckeditor/ckeditor5-horizontal-line/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-html-embed](https://www.npmjs.com/package/@ckeditor/ckeditor5-html-embed/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-html-support](https://www.npmjs.com/package/@ckeditor/ckeditor5-html-support/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-import-word](https://www.npmjs.com/package/@ckeditor/ckeditor5-import-word/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-indent](https://www.npmjs.com/package/@ckeditor/ckeditor5-indent/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-language](https://www.npmjs.com/package/@ckeditor/ckeditor5-language/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-markdown-gfm](https://www.npmjs.com/package/@ckeditor/ckeditor5-markdown-gfm/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-media-embed](https://www.npmjs.com/package/@ckeditor/ckeditor5-media-embed/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-mention](https://www.npmjs.com/package/@ckeditor/ckeditor5-mention/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-minimap](https://www.npmjs.com/package/@ckeditor/ckeditor5-minimap/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-operations-compressor](https://www.npmjs.com/package/@ckeditor/ckeditor5-operations-compressor/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-page-break](https://www.npmjs.com/package/@ckeditor/ckeditor5-page-break/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-pagination](https://www.npmjs.com/package/@ckeditor/ckeditor5-pagination/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-paragraph](https://www.npmjs.com/package/@ckeditor/ckeditor5-paragraph/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-paste-from-office](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-paste-from-office-enhanced](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office-enhanced/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-real-time-collaboration](https://www.npmjs.com/package/@ckeditor/ckeditor5-real-time-collaboration/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-remove-format](https://www.npmjs.com/package/@ckeditor/ckeditor5-remove-format/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-restricted-editing](https://www.npmjs.com/package/@ckeditor/ckeditor5-restricted-editing/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-revision-history](https://www.npmjs.com/package/@ckeditor/ckeditor5-revision-history/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-select-all](https://www.npmjs.com/package/@ckeditor/ckeditor5-select-all/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-show-blocks](https://www.npmjs.com/package/@ckeditor/ckeditor5-show-blocks/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-slash-command](https://www.npmjs.com/package/@ckeditor/ckeditor5-slash-command/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-source-editing](https://www.npmjs.com/package/@ckeditor/ckeditor5-source-editing/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-special-characters](https://www.npmjs.com/package/@ckeditor/ckeditor5-special-characters/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-style](https://www.npmjs.com/package/@ckeditor/ckeditor5-style/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-table](https://www.npmjs.com/package/@ckeditor/ckeditor5-table/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-template](https://www.npmjs.com/package/@ckeditor/ckeditor5-template/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-theme-lark](https://www.npmjs.com/package/@ckeditor/ckeditor5-theme-lark/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-track-changes](https://www.npmjs.com/package/@ckeditor/ckeditor5-track-changes/v/41.3.0-alpha.3): v41.2.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-typing](https://www.npmjs.com/package/@ckeditor/ckeditor5-typing/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-undo](https://www.npmjs.com/package/@ckeditor/ckeditor5-undo/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-upload](https://www.npmjs.com/package/@ckeditor/ckeditor5-upload/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-watchdog](https://www.npmjs.com/package/@ckeditor/ckeditor5-watchdog/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-widget](https://www.npmjs.com/package/@ckeditor/ckeditor5-widget/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
* [@ckeditor/ckeditor5-word-count](https://www.npmjs.com/package/@ckeditor/ckeditor5-word-count/v/41.3.0-alpha.3): v41.3.0-alpha.1 => v41.3.0-alpha.3
|
|
||||||
</details>
|
|
||||||
|
|
||||||
|
|
||||||
## [41.3.0-alpha.2](https://github.com/ckeditor/ckeditor5/compare/v41.3.0-alpha.1...v41.3.0-alpha.2) (April 2, 2024)
|
|
||||||
|
|
||||||
We are happy to announce the release of CKEditor 5 v41.3.0-alpha.2.
|
|
||||||
|
|
||||||
This release is intended to improve the build speed in bundlers when using the `ckeditor5` npm package and to improve typings for translations.
|
|
||||||
|
|
||||||
For instructions on how to use the new installation methods, see the [v41.3.0-alpha.0 Release Notes](https://github.com/ckeditor/ckeditor5/releases/tag/v41.3.0-alpha.0).
|
|
||||||
|
|
||||||
For more general information about the new installation methods, see the [announcement post](https://github.com/ckeditor/ckeditor5/issues/15502).
|
|
||||||
|
|
||||||
### Released packages
|
|
||||||
|
|
||||||
Check out the [Versioning policy](https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/versioning-policy.html) guide for more information.
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Released packages (summary)</summary>
|
|
||||||
|
|
||||||
New packages:
|
|
||||||
|
|
||||||
* [ckeditor5-premium-features](https://www.npmjs.com/package/ckeditor5-premium-features/v/41.3.0-alpha.2): v41.3.0-alpha.2
|
|
||||||
|
|
||||||
Other releases:
|
|
||||||
|
|
||||||
* [@ckeditor/ckeditor5-adapter-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-adapter-ckfinder/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-ai](https://www.npmjs.com/package/@ckeditor/ckeditor5-ai/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-alignment](https://www.npmjs.com/package/@ckeditor/ckeditor5-alignment/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-autoformat](https://www.npmjs.com/package/@ckeditor/ckeditor5-autoformat/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-autosave](https://www.npmjs.com/package/@ckeditor/ckeditor5-autosave/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-basic-styles](https://www.npmjs.com/package/@ckeditor/ckeditor5-basic-styles/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-block-quote](https://www.npmjs.com/package/@ckeditor/ckeditor5-block-quote/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-build-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-build-balloon-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon-block/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-build-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-build-decoupled-document](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-decoupled-document/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-build-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-inline/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-build-multi-root](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-multi-root/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-case-change](https://www.npmjs.com/package/@ckeditor/ckeditor5-case-change/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-ckbox](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckbox/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckfinder/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-clipboard](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-cloud-services](https://www.npmjs.com/package/@ckeditor/ckeditor5-cloud-services/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-code-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-code-block/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-collaboration-core](https://www.npmjs.com/package/@ckeditor/ckeditor5-collaboration-core/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-comments](https://www.npmjs.com/package/@ckeditor/ckeditor5-comments/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-core](https://www.npmjs.com/package/@ckeditor/ckeditor5-core/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-document-outline](https://www.npmjs.com/package/@ckeditor/ckeditor5-document-outline/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-easy-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-easy-image/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-editor-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-balloon/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-editor-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-classic/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-editor-decoupled](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-decoupled/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-editor-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-inline/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-editor-multi-root](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-multi-root/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-enter](https://www.npmjs.com/package/@ckeditor/ckeditor5-enter/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-essentials](https://www.npmjs.com/package/@ckeditor/ckeditor5-essentials/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-export-pdf](https://www.npmjs.com/package/@ckeditor/ckeditor5-export-pdf/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-export-word](https://www.npmjs.com/package/@ckeditor/ckeditor5-export-word/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-find-and-replace](https://www.npmjs.com/package/@ckeditor/ckeditor5-find-and-replace/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-font](https://www.npmjs.com/package/@ckeditor/ckeditor5-font/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-format-painter](https://www.npmjs.com/package/@ckeditor/ckeditor5-format-painter/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-heading](https://www.npmjs.com/package/@ckeditor/ckeditor5-heading/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-highlight](https://www.npmjs.com/package/@ckeditor/ckeditor5-highlight/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-horizontal-line](https://www.npmjs.com/package/@ckeditor/ckeditor5-horizontal-line/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-html-embed](https://www.npmjs.com/package/@ckeditor/ckeditor5-html-embed/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-html-support](https://www.npmjs.com/package/@ckeditor/ckeditor5-html-support/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-import-word](https://www.npmjs.com/package/@ckeditor/ckeditor5-import-word/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-indent](https://www.npmjs.com/package/@ckeditor/ckeditor5-indent/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-language](https://www.npmjs.com/package/@ckeditor/ckeditor5-language/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-markdown-gfm](https://www.npmjs.com/package/@ckeditor/ckeditor5-markdown-gfm/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-media-embed](https://www.npmjs.com/package/@ckeditor/ckeditor5-media-embed/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-mention](https://www.npmjs.com/package/@ckeditor/ckeditor5-mention/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-minimap](https://www.npmjs.com/package/@ckeditor/ckeditor5-minimap/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-operations-compressor](https://www.npmjs.com/package/@ckeditor/ckeditor5-operations-compressor/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-page-break](https://www.npmjs.com/package/@ckeditor/ckeditor5-page-break/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-pagination](https://www.npmjs.com/package/@ckeditor/ckeditor5-pagination/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-paragraph](https://www.npmjs.com/package/@ckeditor/ckeditor5-paragraph/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-paste-from-office](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-paste-from-office-enhanced](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office-enhanced/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-real-time-collaboration](https://www.npmjs.com/package/@ckeditor/ckeditor5-real-time-collaboration/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-remove-format](https://www.npmjs.com/package/@ckeditor/ckeditor5-remove-format/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-restricted-editing](https://www.npmjs.com/package/@ckeditor/ckeditor5-restricted-editing/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-revision-history](https://www.npmjs.com/package/@ckeditor/ckeditor5-revision-history/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-select-all](https://www.npmjs.com/package/@ckeditor/ckeditor5-select-all/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-show-blocks](https://www.npmjs.com/package/@ckeditor/ckeditor5-show-blocks/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-slash-command](https://www.npmjs.com/package/@ckeditor/ckeditor5-slash-command/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-source-editing](https://www.npmjs.com/package/@ckeditor/ckeditor5-source-editing/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-special-characters](https://www.npmjs.com/package/@ckeditor/ckeditor5-special-characters/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-style](https://www.npmjs.com/package/@ckeditor/ckeditor5-style/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-table](https://www.npmjs.com/package/@ckeditor/ckeditor5-table/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-template](https://www.npmjs.com/package/@ckeditor/ckeditor5-template/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-theme-lark](https://www.npmjs.com/package/@ckeditor/ckeditor5-theme-lark/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-track-changes](https://www.npmjs.com/package/@ckeditor/ckeditor5-track-changes/v/41.3.0-alpha.2): v41.2.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-typing](https://www.npmjs.com/package/@ckeditor/ckeditor5-typing/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-undo](https://www.npmjs.com/package/@ckeditor/ckeditor5-undo/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-upload](https://www.npmjs.com/package/@ckeditor/ckeditor5-upload/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-watchdog](https://www.npmjs.com/package/@ckeditor/ckeditor5-watchdog/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-widget](https://www.npmjs.com/package/@ckeditor/ckeditor5-widget/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
* [@ckeditor/ckeditor5-word-count](https://www.npmjs.com/package/@ckeditor/ckeditor5-word-count/v/41.3.0-alpha.2): v41.3.0-alpha.1 => v41.3.0-alpha.2
|
|
||||||
</details>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
To see all releases, visit the [release page](https://github.com/ckeditor/ckeditor5/releases).
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
Software License Agreement
|
|
||||||
==========================
|
|
||||||
|
|
||||||
**CKEditor 5** – https://github.com/ckeditor/ckeditor5 <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.
|
|
||||||
|
|
||||||
The following libraries are included in CKEditor under the [MIT license](https://opensource.org/licenses/MIT):
|
|
||||||
|
|
||||||
* BlurHash - Copyright (c) 2018 Wolt Enterprises (MIT license).
|
|
||||||
* color-convert - Copyright (c) 2011–2016 Heather Arthur <fayearthur@gmail.com>, copyright (c) 2016–2021 Josh Junon <josh@junon.me>.
|
|
||||||
* color-parse - Copyright (c) 2015 Dmitry Ivanov.
|
|
||||||
* Lodash - Copyright (c) JS Foundation and other contributors https://js.foundation/. Based on Underscore.js, copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors http://underscorejs.org/.
|
|
||||||
* Marked - Copyright (c) 2018+, MarkedJS (https://github.com/markedjs/), copyright (c) 2011–2018, Christopher Jeffrey (https://github.com/chjj/).
|
|
||||||
* Turndown - Copyright (c) 2017+ Dom Christie.
|
|
||||||
* turndown-plugin-gfm - Copyright (c) 2017+ Dom Christie.
|
|
||||||
* vanilla-colorful - Copyright (c) 2020 Serhii Kulykov <iamkulykov@gmail.com>.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
@ -1,158 +0,0 @@
|
||||||
CKEditor 5 [](https://twitter.com/intent/tweet?text=Check%20out%20CKEditor%205%20on%20GitHub&url=https%3A%2F%2Fgithub.com%2Fckeditor%2Fckeditor5)
|
|
||||||
===================================
|
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/ckeditor5)
|
|
||||||
[](https://coveralls.io/github/ckeditor/ckeditor5?branch=master)
|
|
||||||
[](https://app.circleci.com/pipelines/github/ckeditor/ckeditor5?branch=master)
|
|
||||||

|
|
||||||
|
|
||||||
[](http://eepurl.com/c3zRPr)
|
|
||||||
[](https://twitter.com/ckeditor)
|
|
||||||
|
|
||||||
CKEditor 5 is an ultra-modern JavaScript rich-text editor with MVC architecture, a custom data model, and virtual DOM. It is written from scratch in TypeScript and has excellent webpack and Vite support. It provides every type of WYSIWYG editing solution imaginable with extensive collaboration support. From editors similar to Google Docs and Medium to Slack or Twitter-like applications, all is possible within a single editing framework. As a market leader, it is constantly expanded and updated.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Table of contents
|
|
||||||
|
|
||||||
- [CKEditor 5 ](#ckeditor5-)
|
|
||||||
- [Table of contents](#table-of-contents)
|
|
||||||
- [Quick start](#quick-start)
|
|
||||||
- [CKEditor 5 online builder](#ckeditor5-online-builder)
|
|
||||||
- [CKEditor 5 predefined builds](#ckeditor5-predefined-builds)
|
|
||||||
- [Example installation](#example-installation)
|
|
||||||
- [TypeScript support](#typescript-support)
|
|
||||||
- [CKEditor 5 advanced installation](#ckeditor5-advanced-installation)
|
|
||||||
- [CKEditor 5 Framework](#ckeditor5-framework)
|
|
||||||
- [Documentation and FAQ](#documentation-and-faq)
|
|
||||||
- [Releases](#releases)
|
|
||||||
- [Editing and collaboration features](#editing-and-collaboration-features)
|
|
||||||
- [Contributing and project organization](#contributing-and-project-organization)
|
|
||||||
- [Ideas and discussions](#ideas-and-discussions)
|
|
||||||
- [Development](#development)
|
|
||||||
- [Reporting issues and feature requests](#reporting-issues-and-feature-requests)
|
|
||||||
- [License](#license)
|
|
||||||
|
|
||||||
## Quick start
|
|
||||||
|
|
||||||
### CKEditor 5 online builder
|
|
||||||
|
|
||||||
The easiest way to start using CKEditor 5 with all the features you need is to prepare a customized build with the [online builder](https://ckeditor.com/ckeditor-5/online-builder/). All you need to do is choose the preferred predefined build as a base, add all the required plugins, and download the ready-to-use package. Refer to the [Online builder Quick start](https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/quick-start.html#creating-custom-builds-with-online-builder) guide to follow this installation path.
|
|
||||||
|
|
||||||
### CKEditor 5 predefined builds
|
|
||||||
|
|
||||||
CKEditor 5 predefined builds are a set of ready-to-use rich text editors. Every build provides a single type of editor with a set of features and a default configuration.
|
|
||||||
|
|
||||||
The following CKEditor 5 predefined builds are currently available:
|
|
||||||
|
|
||||||
* [Classic editor](https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/predefined-builds.html#classic-editor)
|
|
||||||
* [Inline editor](https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/predefined-builds.html#inline-editor)
|
|
||||||
* [Balloon editor](https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/predefined-builds.html#balloon-editor)
|
|
||||||
* [Balloon block editor](https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/predefined-builds.html#balloon-block-editor)
|
|
||||||
* [Document editor](https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/predefined-builds.html#document-editor)
|
|
||||||
|
|
||||||
#### Example installation
|
|
||||||
|
|
||||||
Creating an editor using a CKEditor 5 build is simple and can be described in two steps:
|
|
||||||
|
|
||||||
1. Load the desired editor via the `<script>` tag.
|
|
||||||
2. Call the static `create()` method to create the editor.
|
|
||||||
|
|
||||||
In your HTML page, add an element that CKEditor should replace:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<div id="editor"></div>
|
|
||||||
```
|
|
||||||
|
|
||||||
Load the classic editor build (you can choose between the [CDN](https://cdn.ckeditor.com/#ckeditor5), [npm](https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/predefined-builds.html#npm), and [zip downloads](https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/predefined-builds.html#zip-download)):
|
|
||||||
|
|
||||||
```html
|
|
||||||
<script src="https://cdn.ckeditor.com/ckeditor5/41.3.1/classic/ckeditor.js"></script>
|
|
||||||
```
|
|
||||||
|
|
||||||
Call the [`ClassicEditor.create()`](https://ckeditor.com/docs/ckeditor5/latest/api/module_editor-classic_classiceditor-ClassicEditor.html#static-function-create) method:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<script>
|
|
||||||
ClassicEditor
|
|
||||||
.create( document.querySelector( '#editor' ) )
|
|
||||||
.catch( error => {
|
|
||||||
console.error( error );
|
|
||||||
} );
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
You’re ready to go!
|
|
||||||
|
|
||||||
To find out how to start with other builds, check the [Predefined builds](https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/predefined-builds.html) guide in the CKEditor 5 documentation.
|
|
||||||
|
|
||||||
### TypeScript support
|
|
||||||
|
|
||||||
CKEditor 5 is a TypeScript project. Starting from v37.0.0, it offers native type definitions. Check out our dedicated guide to read more about [TypeScript support](https://ckeditor.com/docs/ckeditor5/latest/installation/working-with-typescript.html).
|
|
||||||
|
|
||||||
### CKEditor 5 advanced installation
|
|
||||||
|
|
||||||
For more advanced users or those who need to integrate CKEditor 5 with their applications, we have prepared several other, advanced methods to do it. You can:
|
|
||||||
* Integrate the editor from source [using webpack](https://ckeditor.com/docs/ckeditor5/latest/installation/advanced/alternative-setups/integrating-from-source-webpack.html) or [Vite](https://ckeditor.com/docs/ckeditor5/latest/installation/advanced/alternative-setups/integrating-from-source-vite.html)
|
|
||||||
* Use [DLL builds](https://ckeditor.com/docs/ckeditor5/latest/installation/advanced/alternative-setups/dll-builds.html)
|
|
||||||
* Use some of the pre-made integrations with popular [JavaScript frameworks](https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/frameworks/overview.html):
|
|
||||||
* [Angular](https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/frameworks/angular.html)
|
|
||||||
* [React](https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/frameworks/react.html)
|
|
||||||
* [Vue](https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/frameworks/vuejs-v3.html)
|
|
||||||
|
|
||||||
#### CKEditor 5 Framework
|
|
||||||
|
|
||||||
CKEditor 5 builds allow you to quickly and easily initialize one of the many types of editors in your application. At the same time, CKEditor 5 is also a framework for creating custom-made rich text editing solutions.
|
|
||||||
|
|
||||||
To find out how to start building your editor from scratch go to the [CKEditor 5 Framework overview](https://ckeditor.com/docs/ckeditor5/latest/framework/index.html) section of the CKEditor 5 documentation.
|
|
||||||
|
|
||||||
## Documentation and FAQ
|
|
||||||
|
|
||||||
Extensive documentation dedicated to all things CKEditor 5-related is available. You will find basic guides that will help you kick off your project, advanced deep-dive tutorials to tailor the editor to your specific needs, and help sections with solutions and answers to any of your possible questions. To find out more refer to the following [CKEditor 5 documentation](https://ckeditor.com/docs/ckeditor5/latest/index.html) sections:
|
|
||||||
|
|
||||||
* [Installing CKEditor 5](https://ckeditor.com/docs/ckeditor5/latest/installation/index.html)
|
|
||||||
* [CKEditor 5 features](https://ckeditor.com/docs/ckeditor5/latest/features/index.html)
|
|
||||||
* [CKEditor 5 examples](https://ckeditor.com/docs/ckeditor5/latest/examples/index.html)
|
|
||||||
* [Updating CKEditor 5](https://ckeditor.com/docs/ckeditor5/latest/updating/index.html)
|
|
||||||
* [Getting CKEditor 5 support](https://ckeditor.com/docs/ckeditor5/latest/support/index.html)
|
|
||||||
* [CKEditor 5 Framework](https://ckeditor.com/docs/ckeditor5/latest/framework/index.html)
|
|
||||||
* [API documentation](https://ckeditor.com/docs/ckeditor5/latest/api/index.html)
|
|
||||||
|
|
||||||
For FAQ please go to the [CKEditor Ecosystem help center](https://support.ckeditor.com/hc/en-us).
|
|
||||||
For a high-level overview of the project see the [CKEditor Ecosystem website](https://ckeditor.com).
|
|
||||||
|
|
||||||
## Releases
|
|
||||||
|
|
||||||
Follow the [CKEditor 5 changelog](https://github.com/ckeditor/ckeditor5/blob/stable/CHANGELOG.md) for release details and check out the CKEditor 5 release blog posts on the [CKSource blog](https://ckeditor.com/blog/?category=releases&tags=CKEditor-5) for important release highlights and additional information.
|
|
||||||
|
|
||||||
## Editing and collaboration features
|
|
||||||
|
|
||||||
The CKEditor 5 Framework offers access to a plethora of various plugins, supporting [all kinds of editing features](https://ckeditor.com/docs/ckeditor5/latest/features/index.html).
|
|
||||||
|
|
||||||
From collaborative editing support providing comments and tracking changes, through editing tools that let users control the content looks and structure such as tables, lists, and font styles, to accessibility helpers and multi-language support - CKEditor 5 is easily extensible and customizable. Special duty features like Markdown input and output and source editing, or export to PDF and Word provide solutions for users with diverse and specialized needs. Images and videos are easily supported and CKEditor 5 offers various upload and storage systems to manage these.
|
|
||||||
|
|
||||||
The number of options and the ease of customization and adding new ones make the editing experience even better for any environment and professional background.
|
|
||||||
|
|
||||||
Refer to the [CKEditor 5 Features](https://ckeditor.com/docs/ckeditor5/latest/features/index.html) documentation for details.
|
|
||||||
|
|
||||||
## Contributing and project organization
|
|
||||||
|
|
||||||
### Ideas and discussions
|
|
||||||
|
|
||||||
The development repository of CKEditor 5 is located at [https://github.com/ckeditor/ckeditor5](https://github.com/ckeditor/ckeditor5). This is the best place for bringing opinions and contributions. Letting the core team know if they are going in the right or wrong direction is great feedback and will be much appreciated!
|
|
||||||
|
|
||||||
### Development
|
|
||||||
|
|
||||||
CKEditor 5 is a modular, multi-package, [monorepo](https://en.wikipedia.org/wiki/Monorepo) project. It consists of several packages that create the editing framework, based on which the feature packages are implemented.
|
|
||||||
|
|
||||||
The [`ckeditor5`](https://github.com/ckeditor/ckeditor5) repository is the place that centralizes the development of CKEditor 5. It bundles different packages into a single place, adding the necessary helper tools for the development workflow, like the builder and the test runner. [Basic information on how to set up the development environment](https://ckeditor.com/docs/ckeditor5/latest/framework/contributing/development-environment.html) can be found in the documentation.
|
|
||||||
|
|
||||||
See the [official contributors' guide](https://ckeditor.com/docs/ckeditor5/latest/framework/contributing/contributing.html) to learn how to contribute your code to the project.
|
|
||||||
|
|
||||||
### Reporting issues and feature requests
|
|
||||||
|
|
||||||
Report issues in [the `ckeditor5` repository](https://github.com/ckeditor/ckeditor5/issues). Read more in the [Getting support](https://ckeditor.com/docs/ckeditor5/latest/support/reporting-issues.html) section of the CKEditor 5 documentation.
|
|
||||||
|
|
||||||
## 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).
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,420 +0,0 @@
|
||||||
{
|
|
||||||
"name": "CKEditor5.dll",
|
|
||||||
"content": {
|
|
||||||
"./clipboard.js": {
|
|
||||||
"id": "./src/clipboard.js",
|
|
||||||
"buildMeta": {
|
|
||||||
"exportsType": "namespace",
|
|
||||||
"sideEffectFree": true
|
|
||||||
},
|
|
||||||
"exports": [
|
|
||||||
"Clipboard",
|
|
||||||
"ClipboardMarkersUtils",
|
|
||||||
"ClipboardPipeline",
|
|
||||||
"DragDrop",
|
|
||||||
"DragDropBlockToolbar",
|
|
||||||
"DragDropTarget",
|
|
||||||
"PastePlainText"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"./core.js": {
|
|
||||||
"id": "./src/core.js",
|
|
||||||
"buildMeta": {
|
|
||||||
"exportsType": "namespace",
|
|
||||||
"sideEffectFree": true
|
|
||||||
},
|
|
||||||
"exports": [
|
|
||||||
"Command",
|
|
||||||
"Context",
|
|
||||||
"ContextPlugin",
|
|
||||||
"DataApiMixin",
|
|
||||||
"Editor",
|
|
||||||
"ElementApiMixin",
|
|
||||||
"MultiCommand",
|
|
||||||
"PendingActions",
|
|
||||||
"Plugin",
|
|
||||||
"attachToForm",
|
|
||||||
"icons",
|
|
||||||
"secureSourceElement"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"./engine.js": {
|
|
||||||
"id": "./src/engine.js",
|
|
||||||
"buildMeta": {
|
|
||||||
"exportsType": "namespace",
|
|
||||||
"sideEffectFree": true
|
|
||||||
},
|
|
||||||
"exports": [
|
|
||||||
"AttributeElement",
|
|
||||||
"AttributeOperation",
|
|
||||||
"BubblingEventInfo",
|
|
||||||
"ClickObserver",
|
|
||||||
"Conversion",
|
|
||||||
"DataController",
|
|
||||||
"DataTransfer",
|
|
||||||
"DocumentFragment",
|
|
||||||
"DocumentSelection",
|
|
||||||
"DomConverter",
|
|
||||||
"DomEventData",
|
|
||||||
"DomEventObserver",
|
|
||||||
"DowncastWriter",
|
|
||||||
"EditingController",
|
|
||||||
"EditingView",
|
|
||||||
"Element",
|
|
||||||
"FocusObserver",
|
|
||||||
"History",
|
|
||||||
"HtmlDataProcessor",
|
|
||||||
"InsertOperation",
|
|
||||||
"LivePosition",
|
|
||||||
"LiveRange",
|
|
||||||
"MarkerOperation",
|
|
||||||
"Matcher",
|
|
||||||
"MergeOperation",
|
|
||||||
"Model",
|
|
||||||
"MouseObserver",
|
|
||||||
"MoveOperation",
|
|
||||||
"NoOperation",
|
|
||||||
"Observer",
|
|
||||||
"OperationFactory",
|
|
||||||
"Position",
|
|
||||||
"Range",
|
|
||||||
"RenameOperation",
|
|
||||||
"Renderer",
|
|
||||||
"RootAttributeOperation",
|
|
||||||
"RootOperation",
|
|
||||||
"SplitOperation",
|
|
||||||
"StylesMap",
|
|
||||||
"StylesProcessor",
|
|
||||||
"TabObserver",
|
|
||||||
"Text",
|
|
||||||
"TextProxy",
|
|
||||||
"TreeWalker",
|
|
||||||
"UpcastWriter",
|
|
||||||
"ViewAttributeElement",
|
|
||||||
"ViewContainerElement",
|
|
||||||
"ViewDocument",
|
|
||||||
"ViewDocumentFragment",
|
|
||||||
"ViewEditableElement",
|
|
||||||
"ViewElement",
|
|
||||||
"ViewEmptyElement",
|
|
||||||
"ViewRawElement",
|
|
||||||
"ViewRootEditableElement",
|
|
||||||
"ViewText",
|
|
||||||
"ViewTreeWalker",
|
|
||||||
"ViewUIElement",
|
|
||||||
"addBackgroundRules",
|
|
||||||
"addBorderRules",
|
|
||||||
"addMarginRules",
|
|
||||||
"addPaddingRules",
|
|
||||||
"disablePlaceholder",
|
|
||||||
"enablePlaceholder",
|
|
||||||
"getBoxSidesShorthandValue",
|
|
||||||
"getBoxSidesValueReducer",
|
|
||||||
"getBoxSidesValues",
|
|
||||||
"getFillerOffset",
|
|
||||||
"getPositionShorthandNormalizer",
|
|
||||||
"getShorthandValues",
|
|
||||||
"hidePlaceholder",
|
|
||||||
"isAttachment",
|
|
||||||
"isColor",
|
|
||||||
"isLength",
|
|
||||||
"isLineStyle",
|
|
||||||
"isPercentage",
|
|
||||||
"isPosition",
|
|
||||||
"isRepeat",
|
|
||||||
"isURL",
|
|
||||||
"needsPlaceholder",
|
|
||||||
"showPlaceholder",
|
|
||||||
"transformSets"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"./enter.js": {
|
|
||||||
"id": "./src/enter.js",
|
|
||||||
"buildMeta": {
|
|
||||||
"exportsType": "namespace",
|
|
||||||
"sideEffectFree": true
|
|
||||||
},
|
|
||||||
"exports": [
|
|
||||||
"Enter",
|
|
||||||
"ShiftEnter"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"./paragraph.js": {
|
|
||||||
"id": "./src/paragraph.js",
|
|
||||||
"buildMeta": {
|
|
||||||
"exportsType": "namespace",
|
|
||||||
"sideEffectFree": true
|
|
||||||
},
|
|
||||||
"exports": [
|
|
||||||
"Paragraph",
|
|
||||||
"ParagraphButtonUI"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"./select-all.js": {
|
|
||||||
"id": "./src/select-all.js",
|
|
||||||
"buildMeta": {
|
|
||||||
"exportsType": "namespace",
|
|
||||||
"sideEffectFree": true
|
|
||||||
},
|
|
||||||
"exports": [
|
|
||||||
"SelectAll",
|
|
||||||
"SelectAllEditing",
|
|
||||||
"SelectAllUI"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"./typing.js": {
|
|
||||||
"id": "./src/typing.js",
|
|
||||||
"buildMeta": {
|
|
||||||
"exportsType": "namespace",
|
|
||||||
"sideEffectFree": true
|
|
||||||
},
|
|
||||||
"exports": [
|
|
||||||
"Delete",
|
|
||||||
"Input",
|
|
||||||
"InsertTextCommand",
|
|
||||||
"TextTransformation",
|
|
||||||
"TextWatcher",
|
|
||||||
"TwoStepCaretMovement",
|
|
||||||
"Typing",
|
|
||||||
"findAttributeRange",
|
|
||||||
"findAttributeRangeBound",
|
|
||||||
"getLastTextLine",
|
|
||||||
"inlineHighlight"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"./ui.js": {
|
|
||||||
"id": "./src/ui.js",
|
|
||||||
"buildMeta": {
|
|
||||||
"exportsType": "namespace",
|
|
||||||
"sideEffectFree": true
|
|
||||||
},
|
|
||||||
"exports": [
|
|
||||||
"AccessibilityHelp",
|
|
||||||
"AutocompleteView",
|
|
||||||
"BalloonPanelView",
|
|
||||||
"BalloonToolbar",
|
|
||||||
"BlockToolbar",
|
|
||||||
"BodyCollection",
|
|
||||||
"BoxedEditorUIView",
|
|
||||||
"Button",
|
|
||||||
"ButtonLabelView",
|
|
||||||
"ButtonView",
|
|
||||||
"CollapsibleView",
|
|
||||||
"ColorGridView",
|
|
||||||
"ColorPickerView",
|
|
||||||
"ColorSelectorView",
|
|
||||||
"ColorTileView",
|
|
||||||
"ComponentFactory",
|
|
||||||
"ContextualBalloon",
|
|
||||||
"CssTransitionDisablerMixin",
|
|
||||||
"DefaultMenuBarItems",
|
|
||||||
"Dialog",
|
|
||||||
"DialogView",
|
|
||||||
"DialogViewPosition",
|
|
||||||
"DropdownButtonView",
|
|
||||||
"DropdownPanelView",
|
|
||||||
"DropdownView",
|
|
||||||
"EditorUI",
|
|
||||||
"EditorUIView",
|
|
||||||
"FileDialogButtonView",
|
|
||||||
"FilteredView",
|
|
||||||
"FocusCycler",
|
|
||||||
"FormHeaderView",
|
|
||||||
"HighlightedTextView",
|
|
||||||
"IconView",
|
|
||||||
"IframeView",
|
|
||||||
"InlineEditableUIView",
|
|
||||||
"InputNumberView",
|
|
||||||
"InputTextView",
|
|
||||||
"InputView",
|
|
||||||
"LabelView",
|
|
||||||
"LabeledFieldView",
|
|
||||||
"ListItemGroupView",
|
|
||||||
"ListItemView",
|
|
||||||
"ListSeparatorView",
|
|
||||||
"ListView",
|
|
||||||
"MenuBarMenuListItemButtonView",
|
|
||||||
"MenuBarMenuListItemFileDialogButtonView",
|
|
||||||
"MenuBarMenuListItemView",
|
|
||||||
"MenuBarMenuListView",
|
|
||||||
"MenuBarMenuView",
|
|
||||||
"MenuBarView",
|
|
||||||
"Notification",
|
|
||||||
"SearchInfoView",
|
|
||||||
"SearchTextView",
|
|
||||||
"SpinnerView",
|
|
||||||
"SplitButtonView",
|
|
||||||
"StickyPanelView",
|
|
||||||
"SwitchButtonView",
|
|
||||||
"Template",
|
|
||||||
"TextareaView",
|
|
||||||
"ToolbarLineBreakView",
|
|
||||||
"ToolbarSeparatorView",
|
|
||||||
"ToolbarView",
|
|
||||||
"TooltipManager",
|
|
||||||
"View",
|
|
||||||
"ViewCollection",
|
|
||||||
"ViewModel",
|
|
||||||
"addKeyboardHandlingForGrid",
|
|
||||||
"addListToDropdown",
|
|
||||||
"addToolbarToDropdown",
|
|
||||||
"clickOutsideHandler",
|
|
||||||
"createDropdown",
|
|
||||||
"createLabeledDropdown",
|
|
||||||
"createLabeledInputNumber",
|
|
||||||
"createLabeledInputText",
|
|
||||||
"createLabeledTextarea",
|
|
||||||
"focusChildOnDropdownOpen",
|
|
||||||
"getLocalizedColorOptions",
|
|
||||||
"injectCssTransitionDisabler",
|
|
||||||
"isFocusable",
|
|
||||||
"isViewWithFocusCycler",
|
|
||||||
"normalizeColorOptions",
|
|
||||||
"normalizeMenuBarConfig",
|
|
||||||
"normalizeSingleColorDefinition",
|
|
||||||
"normalizeToolbarConfig",
|
|
||||||
"submitHandler"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"./undo.js": {
|
|
||||||
"id": "./src/undo.js",
|
|
||||||
"buildMeta": {
|
|
||||||
"exportsType": "namespace",
|
|
||||||
"sideEffectFree": true
|
|
||||||
},
|
|
||||||
"exports": [
|
|
||||||
"Undo",
|
|
||||||
"UndoEditing",
|
|
||||||
"UndoUI"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"./upload.js": {
|
|
||||||
"id": "./src/upload.js",
|
|
||||||
"buildMeta": {
|
|
||||||
"exportsType": "namespace",
|
|
||||||
"sideEffectFree": true
|
|
||||||
},
|
|
||||||
"exports": [
|
|
||||||
"Base64UploadAdapter",
|
|
||||||
"FileRepository",
|
|
||||||
"SimpleUploadAdapter"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"./utils.js": {
|
|
||||||
"id": "./src/utils.js",
|
|
||||||
"buildMeta": {
|
|
||||||
"exportsType": "namespace",
|
|
||||||
"sideEffectFree": true
|
|
||||||
},
|
|
||||||
"exports": [
|
|
||||||
"CKEditorError",
|
|
||||||
"Collection",
|
|
||||||
"Config",
|
|
||||||
"DomEmitterMixin",
|
|
||||||
"ElementReplacer",
|
|
||||||
"EmitterMixin",
|
|
||||||
"EventInfo",
|
|
||||||
"FocusTracker",
|
|
||||||
"KeystrokeHandler",
|
|
||||||
"Locale",
|
|
||||||
"ObservableMixin",
|
|
||||||
"Rect",
|
|
||||||
"ResizeObserver",
|
|
||||||
"abortableDebounce",
|
|
||||||
"compareArrays",
|
|
||||||
"count",
|
|
||||||
"createElement",
|
|
||||||
"delay",
|
|
||||||
"diff",
|
|
||||||
"diffToChanges",
|
|
||||||
"env",
|
|
||||||
"exponentialDelay",
|
|
||||||
"fastDiff",
|
|
||||||
"findClosestScrollableAncestor",
|
|
||||||
"first",
|
|
||||||
"getAncestors",
|
|
||||||
"getBorderWidths",
|
|
||||||
"getCode",
|
|
||||||
"getDataFromElement",
|
|
||||||
"getEnvKeystrokeText",
|
|
||||||
"getLanguageDirection",
|
|
||||||
"getLocalizedArrowKeyCodeDirection",
|
|
||||||
"getOptimalPosition",
|
|
||||||
"global",
|
|
||||||
"indexOf",
|
|
||||||
"insertAt",
|
|
||||||
"insertToPriorityArray",
|
|
||||||
"isArrowKeyCode",
|
|
||||||
"isCombiningMark",
|
|
||||||
"isComment",
|
|
||||||
"isForwardArrowKeyCode",
|
|
||||||
"isHighSurrogateHalf",
|
|
||||||
"isInsideCombinedSymbol",
|
|
||||||
"isInsideEmojiSequence",
|
|
||||||
"isInsideSurrogatePair",
|
|
||||||
"isIterable",
|
|
||||||
"isLowSurrogateHalf",
|
|
||||||
"isNode",
|
|
||||||
"isRange",
|
|
||||||
"isText",
|
|
||||||
"isValidAttributeName",
|
|
||||||
"isVisible",
|
|
||||||
"keyCodes",
|
|
||||||
"logError",
|
|
||||||
"logWarning",
|
|
||||||
"mix",
|
|
||||||
"parseKeystroke",
|
|
||||||
"priorities",
|
|
||||||
"releaseDate",
|
|
||||||
"remove",
|
|
||||||
"retry",
|
|
||||||
"scrollAncestorsToShowTarget",
|
|
||||||
"scrollViewportToShowTarget",
|
|
||||||
"setDataInElement",
|
|
||||||
"spliceArray",
|
|
||||||
"toArray",
|
|
||||||
"toMap",
|
|
||||||
"toUnit",
|
|
||||||
"uid",
|
|
||||||
"verifyLicense",
|
|
||||||
"version",
|
|
||||||
"wait"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"./watchdog.js": {
|
|
||||||
"id": "./src/watchdog.js",
|
|
||||||
"buildMeta": {
|
|
||||||
"exportsType": "namespace",
|
|
||||||
"sideEffectFree": true
|
|
||||||
},
|
|
||||||
"exports": [
|
|
||||||
"ContextWatchdog",
|
|
||||||
"EditorWatchdog",
|
|
||||||
"Watchdog"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"./widget.js": {
|
|
||||||
"id": "./src/widget.js",
|
|
||||||
"buildMeta": {
|
|
||||||
"exportsType": "namespace",
|
|
||||||
"sideEffectFree": true
|
|
||||||
},
|
|
||||||
"exports": [
|
|
||||||
"WIDGET_CLASS_NAME",
|
|
||||||
"WIDGET_SELECTED_CLASS_NAME",
|
|
||||||
"Widget",
|
|
||||||
"WidgetResize",
|
|
||||||
"WidgetToolbarRepository",
|
|
||||||
"WidgetTypeAround",
|
|
||||||
"findOptimalInsertionRange",
|
|
||||||
"getLabel",
|
|
||||||
"isWidget",
|
|
||||||
"setHighlightHandling",
|
|
||||||
"setLabel",
|
|
||||||
"toWidget",
|
|
||||||
"toWidgetEditable",
|
|
||||||
"viewToModelPositionOutsideModelElement"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
!function(e){const t=e.af=e.af||{};t.dictionary=Object.assign(t.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"%0 van %1",Accept:"",Accessibility:"","Accessibility help":"",Aquamarine:"","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Black:"",Blue:"",Cancel:"Kanselleer","Cannot upload file:":"Lêer nie opgelaai nie:",Clear:"","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"","Content editing keystrokes":"","Dim grey":"","Drag to move":"","Dropdown toolbar":"","Edit block":"","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor menu bar":"","Editor toolbar":"","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"",Green:"",Grey:"","Help Contents. To close this dialog press ESC.":"",HEX:"","Insert image with file manager":"","Insert with file manager":"","Light blue":"","Light green":"","Light grey":"",MENU_BAR_MENU_EDIT:"Wysig",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"",MENU_BAR_MENU_TEXT:"",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Navigate through the toolbar or menu bar":"",Next:"","No results found":"","No searchable items":"","Open the accessibility help dialog":"",Orange:"","Press %0 for help.":"",Previous:"",Purple:"",Red:"","Remove color":"Verwyder kleur","Replace image with file manager":"","Replace with file manager":"","Restore default":"Herstel verstek","Rich Text Editor":"","Rich Text Editor. Editing area: %0":"",Save:"Stoor","Show more items":"Wys meer items","These keyboard shortcuts allow for quick access to content editing features.":"","Toggle caption off":"","Toggle caption on":"",Turquoise:"","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"",White:"",Yellow:""}),t.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
||||||
!function(e){const t=e.ast=e.ast||{};t.dictionary=Object.assign(t.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"",Accept:"",Accessibility:"","Accessibility help":"",Aquamarine:"","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Black:"",Blue:"",Cancel:"Encaboxar","Cannot upload file:":"",Clear:"","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"","Content editing keystrokes":"","Dim grey":"","Drag to move":"","Dropdown toolbar":"","Edit block":"","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor menu bar":"","Editor toolbar":"","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"",Green:"",Grey:"","Help Contents. To close this dialog press ESC.":"",HEX:"","Insert image with file manager":"","Insert with file manager":"","Light blue":"","Light green":"","Light grey":"",MENU_BAR_MENU_EDIT:"",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"",MENU_BAR_MENU_TEXT:"",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Navigate through the toolbar or menu bar":"",Next:"","No results found":"","No searchable items":"","Open the accessibility help dialog":"",Orange:"","Press %0 for help.":"",Previous:"",Purple:"",Red:"",Redo:"Refacer","Remove color":"","Replace image with file manager":"","Replace with file manager":"","Restore default":"","Rich Text Editor":"Editor de testu arriquecíu","Rich Text Editor. Editing area: %0":"",Save:"Guardar","Show more items":"","These keyboard shortcuts allow for quick access to content editing features.":"","Toggle caption off":"","Toggle caption on":"",Turquoise:"",Undo:"Desfacer","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"",White:"",Yellow:""}),t.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
!function(e){const t=e.az=e.az||{};t.dictionary=Object.assign(t.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"%1-dən %0",Accept:"",Accessibility:"","Accessibility help":"",Aquamarine:"Akvamarin","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Black:"Qara",Blue:"Mavi",Cancel:"İmtina et","Cannot upload file:":"Fayl yüklənə bilmir",Clear:"","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"","Content editing keystrokes":"","Dim grey":"Tünd boz","Drag to move":"","Dropdown toolbar":"Açılan paneli","Edit block":"Redaktə etmək bloku","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor menu bar":"","Editor toolbar":"Redaktorun paneli","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"",Green:"Yaşıl",Grey:"Boz","Help Contents. To close this dialog press ESC.":"",HEX:"","Insert a new paragraph directly after a widget":"","Insert a new paragraph directly before a widget":"","Insert image with file manager":"","Insert paragraph after block":"","Insert paragraph before block":"","Insert with file manager":"","Keystrokes that can be used when a widget is selected (for example: image, table, etc.)":"","Light blue":"Açıq mavi","Light green":"Açıq yaşıl","Light grey":"Açıq boz",MENU_BAR_MENU_EDIT:"",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"",MENU_BAR_MENU_TEXT:"",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Move the caret to allow typing directly after a widget":"","Move the caret to allow typing directly before a widget":"","Navigate through the toolbar or menu bar":"",Next:"Növbəti","No results found":"","No searchable items":"","Open the accessibility help dialog":"",Orange:"Narıncı","Press %0 for help.":"","Press Enter to type after or press Shift + Enter to type before the widget":"",Previous:"Əvvəlki",Purple:"Bənövşəyi",Red:"Qırmızı",Redo:"Təkrar et","Remove color":"Rəngi ləğv et","Replace image with file manager":"","Replace with file manager":"","Restore default":"","Rich Text Editor":"Rich Text Redaktoru","Rich Text Editor. Editing area: %0":"",Save:"Yadda saxla","Show more items":"Daha çox əşyanı göstərin","These keyboard shortcuts allow for quick access to content editing features.":"","Toggle caption off":"","Toggle caption on":"",Turquoise:"Firuzəyi",Undo:"İmtina et","Upload in progress":"Yüklənir","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"",White:"Ağ","Widget toolbar":"Vidgetin paneli",Yellow:"Sarı"}),t.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
||||||
!function(e){const t=e.bs=e.bs||{};t.dictionary=Object.assign(t.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"%0 od %1",Accept:"",Accessibility:"","Accessibility help":"",Aquamarine:"","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Black:"",Blue:"",Cancel:"Poništi","Cannot upload file:":"Nije moguće učitati fajl:",Clear:"","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"","Content editing keystrokes":"","Dim grey":"","Drag to move":"","Dropdown toolbar":"","Edit block":"","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor menu bar":"","Editor toolbar":"","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"",Green:"",Grey:"","Help Contents. To close this dialog press ESC.":"",HEX:"","Insert image with file manager":"","Insert with file manager":"","Light blue":"","Light green":"","Light grey":"",MENU_BAR_MENU_EDIT:"Uredi",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"Umetni",MENU_BAR_MENU_TEXT:"",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Navigate through the toolbar or menu bar":"",Next:"","No results found":"","No searchable items":"","Open the accessibility help dialog":"",Orange:"","Press %0 for help.":"",Previous:"",Purple:"",Red:"","Remove color":"Ukloni boju","Replace image with file manager":"","Replace with file manager":"","Restore default":"Vrati na zadano","Rich Text Editor":"","Rich Text Editor. Editing area: %0":"",Save:"Sačuvaj","Show more items":"Prikaži više stavki","These keyboard shortcuts allow for quick access to content editing features.":"","Toggle caption off":"","Toggle caption on":"",Turquoise:"","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"",White:"",Yellow:""}),t.getPluralForm=function(e){return e%10==1&&e%100!=11?0:e%10>=2&&e%10<=4&&(e%100<10||e%100>=20)?1:2}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
||||||
!function(e){const t=e["de-ch"]=e["de-ch"]||{};t.dictionary=Object.assign(t.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"",Accept:"",Accessibility:"","Accessibility help":"",Aquamarine:"","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Black:"",Blue:"",Cancel:"Abbrechen","Cannot upload file:":"Datei kann nicht hochgeladen werden:",Clear:"","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"","Content editing keystrokes":"","Dim grey":"","Drag to move":"","Dropdown toolbar":"","Edit block":"","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor menu bar":"","Editor toolbar":"","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"",Green:"",Grey:"","Help Contents. To close this dialog press ESC.":"",HEX:"","Insert a new paragraph directly after a widget":"","Insert a new paragraph directly before a widget":"","Insert image with file manager":"","Insert paragraph after block":"Absatz nach Block einfügen","Insert paragraph before block":"Absatz vor Block einfügen","Insert with file manager":"","Keystrokes that can be used when a widget is selected (for example: image, table, etc.)":"","Light blue":"","Light green":"","Light grey":"",MENU_BAR_MENU_EDIT:"Bearbeiten",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"Einfügen",MENU_BAR_MENU_TEXT:"",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Move the caret to allow typing directly after a widget":"","Move the caret to allow typing directly before a widget":"","Navigate through the toolbar or menu bar":"",Next:"","No results found":"","No searchable items":"","Open the accessibility help dialog":"",Orange:"","Press %0 for help.":"","Press Enter to type after or press Shift + Enter to type before the widget":"",Previous:"",Purple:"",Red:"",Redo:"Wiederherstellen","Remove color":"Farbe entfernen","Replace image with file manager":"","Replace with file manager":"","Restore default":"","Rich Text Editor":"Rich-Text-Edito","Rich Text Editor. Editing area: %0":"",Save:"Speichern","Select all":"Alles auswählen","Show more items":"","These keyboard shortcuts allow for quick access to content editing features.":"","Toggle caption off":"","Toggle caption on":"",Turquoise:"",Undo:"Rückgängig","Upload in progress":"Upload läuft","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"",White:"","Widget toolbar":"Widget Werkzeugleiste",Yellow:""}),t.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
||||||
!function(e){const t=e["en-au"]=e["en-au"]||{};t.dictionary=Object.assign(t.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"%0 of %1",Accept:"",Accessibility:"","Accessibility help":"",Aquamarine:"Aquamarine","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Black:"Black",Blue:"Blue",Cancel:"Cancel","Cannot upload file:":"Cannot upload file:",Clear:"Clear","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"","Content editing keystrokes":"","Dim grey":"Dim grey","Drag to move":"","Dropdown toolbar":"Dropdown toolbar","Edit block":"Edit block","Editor block content toolbar":"Editor block content toolbar","Editor contextual toolbar":"Editor contextual toolbar","Editor dialog":"","Editor editing area: %0":"Editor editing area: %0","Editor menu bar":"","Editor toolbar":"Editor toolbar","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"",Green:"Green",Grey:"Grey","Help Contents. To close this dialog press ESC.":"",HEX:"","Insert a new paragraph directly after a widget":"","Insert a new paragraph directly before a widget":"","Insert image with file manager":"","Insert paragraph after block":"Insert paragraph after block","Insert paragraph before block":"Insert paragraph before block","Insert with file manager":"","Keystrokes that can be used when a widget is selected (for example: image, table, etc.)":"","Light blue":"Light blue","Light green":"Light green","Light grey":"Light grey",MENU_BAR_MENU_EDIT:"Edit",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"Insert",MENU_BAR_MENU_TEXT:"Text",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Move the caret to allow typing directly after a widget":"","Move the caret to allow typing directly before a widget":"","Navigate through the toolbar or menu bar":"",Next:"Next","No results found":"","No searchable items":"","Open the accessibility help dialog":"",Orange:"Orange","Press %0 for help.":"","Press Enter to type after or press Shift + Enter to type before the widget":"Press Enter to type after or press Shift + Enter to type before the widget",Previous:"Previous",Purple:"Purple",Red:"Red",Redo:"Redo","Remove color":"Remove colour","Replace image with file manager":"","Replace with file manager":"","Restore default":"Restore default","Rich Text Editor":"Rich Text Editor","Rich Text Editor. Editing area: %0":"Rich Text Editor. Editing area: %0",Save:"Save","Select all":"Select all","Show more items":"Show more items","These keyboard shortcuts allow for quick access to content editing features.":"","Toggle caption off":"Toggle caption off","Toggle caption on":"Toggle caption on",Turquoise:"Turquoise",Undo:"Undo","Upload in progress":"Upload in progress","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"",White:"White","Widget toolbar":"Widget toolbar",Yellow:"Yellow"}),t.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
!function(e){const o=e["en-gb"]=e["en-gb"]||{};o.dictionary=Object.assign(o.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"%0 of %1",Accept:"",Accessibility:"","Accessibility help":"",Aquamarine:"Aquamarine","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Black:"Black",Blue:"Blue",Cancel:"Cancel","Cannot upload file:":"Cannot upload file:",Clear:"","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"","Content editing keystrokes":"","Dim grey":"Dim grey","Drag to move":"","Dropdown toolbar":"","Edit block":"Edit block","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor menu bar":"","Editor toolbar":"","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"",Green:"Green",Grey:"Grey","Help Contents. To close this dialog press ESC.":"",HEX:"","Insert image with file manager":"","Insert with file manager":"","Light blue":"Light blue","Light green":"Light green","Light grey":"Light grey",MENU_BAR_MENU_EDIT:"",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"",MENU_BAR_MENU_TEXT:"",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Navigate through the toolbar or menu bar":"",Next:"Next","No results found":"","No searchable items":"","Open the accessibility help dialog":"",Orange:"Orange","Press %0 for help.":"",Previous:"Previous",Purple:"Purple",Red:"Red",Redo:"Redo","Remove color":"Remove colour","Replace image with file manager":"","Replace with file manager":"","Restore default":"","Rich Text Editor":"Rich Text Editor","Rich Text Editor. Editing area: %0":"",Save:"Save","Show more items":"","These keyboard shortcuts allow for quick access to content editing features.":"","Toggle caption off":"","Toggle caption on":"",Turquoise:"Turquoise",Undo:"Undo","Upload in progress":"Upload in progress","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"",White:"White",Yellow:"Yellow"}),o.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
!function(e){const t=e.eo=e.eo||{};t.dictionary=Object.assign(t.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"",Accept:"",Accessibility:"","Accessibility help":"",Aquamarine:"","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Black:"",Blue:"",Cancel:"Nuligi","Cannot upload file:":"",Clear:"","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"","Content editing keystrokes":"","Dim grey":"","Drag to move":"","Dropdown toolbar":"","Edit block":"","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor menu bar":"","Editor toolbar":"","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"",Green:"",Grey:"","Help Contents. To close this dialog press ESC.":"",HEX:"","Insert image with file manager":"","Insert with file manager":"","Light blue":"","Light green":"","Light grey":"",MENU_BAR_MENU_EDIT:"",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"",MENU_BAR_MENU_TEXT:"",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Navigate through the toolbar or menu bar":"",Next:"","No results found":"","No searchable items":"","Open the accessibility help dialog":"",Orange:"","Press %0 for help.":"",Previous:"",Purple:"",Red:"",Redo:"Refari","Remove color":"","Replace image with file manager":"","Replace with file manager":"","Restore default":"","Rich Text Editor":"Redaktilo de Riĉa Teksto","Rich Text Editor. Editing area: %0":"",Save:"Konservi","Show more items":"","These keyboard shortcuts allow for quick access to content editing features.":"","Toggle caption off":"","Toggle caption on":"",Turquoise:"",Undo:"Malfari","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"",White:"",Yellow:""}),t.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue