/*! * @license Copyright (c) 2003-2022, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md. */ (function(d){ const l = d['en'] = d['en'] || {}; l.dictionary=Object.assign( l.dictionary||{}, {"%0 of %1":"%0 of %1","Align center":"Align center","Align left":"Align left","Align right":"Align right",Aquamarine:"Aquamarine",Black:"Black","Block quote":"Block quote",Blue:"Blue",Bold:"Bold","Bulleted List":"Bulleted List",Cancel:"Cancel","Cannot upload file:":"Cannot upload file:","Centered image":"Centered image","Change image text alternative":"Change image text alternative","Choose heading":"Choose heading",Column:"Column","Could not insert image at the current position.":"Could not insert image at the current position.","Could not obtain resized image URL.":"Could not obtain resized image URL.","Decrease indent":"Decrease indent","Delete column":"Delete column","Delete row":"Delete row","Dim grey":"Dim grey","Document colors":"Document colors",Downloadable:"Downloadable","Dropdown toolbar":"Dropdown toolbar","Edit block":"Edit block","Edit link":"Edit link","Edit source":"Edit source","Editor toolbar":"Editor toolbar","Empty snippet content":"Empty snippet content","Enter image caption":"Enter image caption","Font Background Color":"Font Background Color","Font Color":"Font Color","Full size image":"Full size image",Green:"Green",Grey:"Grey","Header column":"Header column","Header row":"Header row",Heading:"Heading","Heading 1":"Heading 1","Heading 2":"Heading 2","Heading 3":"Heading 3","Heading 4":"Heading 4","Heading 5":"Heading 5","Heading 6":"Heading 6","HTML snippet":"HTML snippet","Image resize list":"Image resize list","Image toolbar":"Image toolbar","image widget":"image widget","Increase indent":"Increase indent","Insert column left":"Insert column left","Insert column right":"Insert column right","Insert HTML":"Insert HTML","Insert image":"Insert image","Insert image or file":"Insert image or file","Insert paragraph after block":"Insert paragraph after block","Insert paragraph before block":"Insert paragraph before block","Insert row above":"Insert row above","Insert row below":"Insert row below","Insert table":"Insert table","Inserting image failed":"Inserting image failed",Italic:"Italic",Justify:"Justify","Left aligned image":"Left aligned image","Light blue":"Light blue","Light green":"Light green","Light grey":"Light grey",Link:"Link","Link image":"Link image","Link URL":"Link URL","Merge cell down":"Merge cell down","Merge cell left":"Merge cell left","Merge cell right":"Merge cell right","Merge cell up":"Merge cell up","Merge cells":"Merge cells",Next:"Next","No preview available":"No preview available","Numbered List":"Numbered List","Open in a new tab":"Open in a new tab","Open link in new tab":"Open link in new tab",Orange:"Orange",Original:"Original",Paragraph:"Paragraph","Paste raw HTML here...":"Paste raw HTML here...",Previous:"Previous",Purple:"Purple",Red:"Red",Redo:"Redo","Remove color":"Remove color","Remove Format":"Remove Format","Resize image":"Resize image","Resize image to %0":"Resize image to %0","Resize image to the original size":"Resize image to the original size","Rich Text Editor":"Rich Text Editor","Rich Text Editor, %0":"Rich Text Editor, %0","Right aligned image":"Right aligned image",Row:"Row",Save:"Save","Save changes":"Save changes","Select all":"Select all","Select column":"Select column","Select row":"Select row","Selecting resized image failed":"Selecting resized image failed","Show more items":"Show more items","Side image":"Side image","Split cell horizontally":"Split cell horizontally","Split cell vertically":"Split cell vertically",Strikethrough:"Strikethrough",Subscript:"Subscript",Superscript:"Superscript","Table toolbar":"Table toolbar","Text alignment":"Text alignment","Text alignment toolbar":"Text alignment toolbar","Text alternative":"Text alternative","This link has no URL":"This link has no URL",Turquoise:"Turquoise",Underline:"Underline",Undo:"Undo",Unlink:"Unlink","Upload failed":"Upload failed","Upload in progress":"Upload in progress",White:"White","Widget toolbar":"Widget toolbar",Yellow:"Yellow"} );})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={})); (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["ClassicEditor"] = factory(); else root["ClassicEditor"] = factory(); })(window, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = "./src/ckeditor.js"); /******/ }) /************************************************************************/ /******/ ({ /***/ "./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter.js": /*!********************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter.js ***! \********************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CKFinderUploadAdapter; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var ckeditor5_src_upload__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/upload */ "./node_modules/ckeditor5/src/upload.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils */ "./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/utils.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /* globals XMLHttpRequest, FormData */ /** * @module adapter-ckfinder/uploadadapter */ /** * A plugin that enables file uploads in CKEditor 5 using the CKFinder server–side connector. * * See the {@glink features/image-upload/ckfinder "CKFinder file manager integration" guide} to learn how to configure * and use this feature as well as find out more about the full integration with the file manager * provided by the {@link module:ckfinder/ckfinder~CKFinder} plugin. * * Check out the {@glink features/image-upload/image-upload comprehensive "Image upload overview"} to learn about * other ways to upload images into CKEditor 5. * * @extends module:core/plugin~Plugin */ class CKFinderUploadAdapter extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get requires() { return [ ckeditor5_src_upload__WEBPACK_IMPORTED_MODULE_1__["FileRepository"] ]; } /** * @inheritDoc */ static get pluginName() { return 'CKFinderUploadAdapter'; } /** * @inheritDoc */ init() { const url = this.editor.config.get( 'ckfinder.uploadUrl' ); if ( !url ) { return; } // Register CKFinderAdapter this.editor.plugins.get( ckeditor5_src_upload__WEBPACK_IMPORTED_MODULE_1__["FileRepository"] ).createUploadAdapter = loader => new UploadAdapter( loader, url, this.editor.t ); } } /** * Upload adapter for CKFinder. * * @private * @implements module:upload/filerepository~UploadAdapter */ class UploadAdapter { /** * Creates a new adapter instance. * * @param {module:upload/filerepository~FileLoader} loader * @param {String} url * @param {module:utils/locale~Locale#t} t */ constructor( loader, url, t ) { /** * FileLoader instance to use during the upload. * * @member {module:upload/filerepository~FileLoader} #loader */ this.loader = loader; /** * Upload URL. * * @member {String} #url */ this.url = url; /** * Locale translation method. * * @member {module:utils/locale~Locale#t} #t */ this.t = t; } /** * Starts the upload process. * * @see module:upload/filerepository~UploadAdapter#upload * @returns {Promise.} */ upload() { return this.loader.file.then( file => { return new Promise( ( resolve, reject ) => { this._initRequest(); this._initListeners( resolve, reject, file ); this._sendRequest( file ); } ); } ); } /** * Aborts the upload process. * * @see module:upload/filerepository~UploadAdapter#abort */ abort() { if ( this.xhr ) { this.xhr.abort(); } } /** * Initializes the XMLHttpRequest object. * * @private */ _initRequest() { const xhr = this.xhr = new XMLHttpRequest(); xhr.open( 'POST', this.url, true ); xhr.responseType = 'json'; } /** * Initializes XMLHttpRequest listeners. * * @private * @param {Function} resolve Callback function to be called when the request is successful. * @param {Function} reject Callback function to be called when the request cannot be completed. * @param {File} file File instance to be uploaded. */ _initListeners( resolve, reject, file ) { const xhr = this.xhr; const loader = this.loader; const t = this.t; const genericError = t( 'Cannot upload file:' ) + ` ${ file.name }.`; xhr.addEventListener( 'error', () => reject( genericError ) ); xhr.addEventListener( 'abort', () => reject() ); xhr.addEventListener( 'load', () => { const response = xhr.response; if ( !response || !response.uploaded ) { return reject( response && response.error && response.error.message ? response.error.message : genericError ); } resolve( { default: response.url } ); } ); // Upload progress when it's supported. /* istanbul ignore else */ if ( xhr.upload ) { xhr.upload.addEventListener( 'progress', evt => { if ( evt.lengthComputable ) { loader.uploadTotal = evt.total; loader.uploaded = evt.loaded; } } ); } } /** * Prepares the data and sends the request. * * @private * @param {File} file File instance to be uploaded. */ _sendRequest( file ) { // Prepare form data. const data = new FormData(); data.append( 'upload', file ); data.append( 'ckCsrfToken', Object(_utils__WEBPACK_IMPORTED_MODULE_2__["getCsrfToken"])() ); // Send request. this.xhr.send( data ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/utils.js": /*!************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/utils.js ***! \************************************************************************/ /*! exports provided: getCsrfToken, getCookie, setCookie */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCsrfToken", function() { return getCsrfToken; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCookie", function() { return getCookie; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setCookie", function() { return setCookie; }); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /* globals window, document */ /** * @module adapter-ckfinder/utils */ const TOKEN_COOKIE_NAME = 'ckCsrfToken'; const TOKEN_LENGTH = 40; const tokenCharset = 'abcdefghijklmnopqrstuvwxyz0123456789'; /** * Returns the CSRF token value. The value is a hash stored in `document.cookie` * under the `ckCsrfToken` key. The CSRF token can be used to secure the communication * between the web browser and the CKFinder server. * * @returns {String} */ function getCsrfToken() { let token = getCookie( TOKEN_COOKIE_NAME ); if ( !token || token.length != TOKEN_LENGTH ) { token = generateToken( TOKEN_LENGTH ); setCookie( TOKEN_COOKIE_NAME, token ); } return token; } /** * Returns the value of the cookie with a given name or `null` if the cookie is not found. * * @param {String} name * @returns {String|null} */ function getCookie( name ) { name = name.toLowerCase(); const parts = document.cookie.split( ';' ); for ( const part of parts ) { const pair = part.split( '=' ); const key = decodeURIComponent( pair[ 0 ].trim().toLowerCase() ); if ( key === name ) { return decodeURIComponent( pair[ 1 ] ); } } return null; } /** * Sets the value of the cookie with a given name. * * @param {String} name * @param {String} value */ function setCookie( name, value ) { document.cookie = encodeURIComponent( name ) + '=' + encodeURIComponent( value ) + ';path=/'; } // Generates the CSRF token with the given length. // // @private // @param {Number} length // @returns {string} function generateToken( length ) { let result = ''; const randValues = new Uint8Array( length ); window.crypto.getRandomValues( randValues ); for ( let j = 0; j < randValues.length; j++ ) { const character = tokenCharset.charAt( randValues[ j ] % tokenCharset.length ); result += Math.random() > 0.5 ? character.toUpperCase() : character; } return result; } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-alignment/src/alignment.js": /*!*********************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-alignment/src/alignment.js ***! \*********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Alignment; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _alignmentediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./alignmentediting */ "./node_modules/@ckeditor/ckeditor5-alignment/src/alignmentediting.js"); /* harmony import */ var _alignmentui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./alignmentui */ "./node_modules/@ckeditor/ckeditor5-alignment/src/alignmentui.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module alignment/alignment */ /** * The text alignment plugin. * * For a detailed overview, check the {@glink features/text-alignment Text alignment feature documentation} * and the {@glink api/alignment package page}. * * This is a "glue" plugin which loads the {@link module:alignment/alignmentediting~AlignmentEditing} and * {@link module:alignment/alignmentui~AlignmentUI} plugins. * * @extends module:core/plugin~Plugin */ class Alignment extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get requires() { return [ _alignmentediting__WEBPACK_IMPORTED_MODULE_1__["default"], _alignmentui__WEBPACK_IMPORTED_MODULE_2__["default"] ]; } /** * @inheritDoc */ static get pluginName() { return 'Alignment'; } } /** * The configuration of the {@link module:alignment/alignment~Alignment alignment feature}. * * Read more in {@link module:alignment/alignment~AlignmentConfig}. * * @member {module:alignment/alignment~AlignmentConfig} module:core/editor/editorconfig~EditorConfig#alignment */ /** * The configuration of the {@link module:alignment/alignment~Alignment alignment feature}. * * ClassicEditor * .create( editorElement, { * alignment: { * options: [ 'left', 'right' ] * } * } ) * .then( ... ) * .catch( ... ); * * See {@link module:core/editor/editorconfig~EditorConfig all editor configuration options}. * * @interface AlignmentConfig */ /** * Available alignment options. * * The available options are: `'left'`, `'right'`, `'center'` and `'justify'`. Other values are ignored. * * **Note:** It is recommended to always use `'left'` or `'right'` as these are default values which the user should * normally be able to choose depending on the * {@glink features/ui-language#setting-the-language-of-the-content language of the editor content}. * * ClassicEditor * .create( editorElement, { * alignment: { * options: [ 'left', 'right' ] * } * } ) * .then( ... ) * .catch( ... ); * * By default the alignment is set inline using the `text-align` CSS property. To further customize the alignment, * you can provide names of classes for each alignment option using the `className` property. * * **Note:** Once you define the `className` property for one option, you need to specify it for all other options. * * ClassicEditor * .create( editorElement, { * alignment: { * options: [ * { name: 'left', className: 'my-align-left' }, * { name: 'right', className: 'my-align-right' } * ] * } * } ) * .then( ... ) * .catch( ... ); * * See the demo of {@glink features/text-alignment#configuring-alignment-options custom alignment options}. * * @member {Array.} module:alignment/alignment~AlignmentConfig#options */ /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-alignment/src/alignmentcommand.js": /*!****************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-alignment/src/alignmentcommand.js ***! \****************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return AlignmentCommand; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/utils */ "./node_modules/ckeditor5/src/utils.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils */ "./node_modules/@ckeditor/ckeditor5-alignment/src/utils.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module alignment/alignmentcommand */ const ALIGNMENT = 'alignment'; /** * The alignment command plugin. * * @extends module:core/command~Command */ class AlignmentCommand extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Command"] { /** * @inheritDoc */ refresh() { const editor = this.editor; const locale = editor.locale; const firstBlock = Object(ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_1__["first"])( this.editor.model.document.selection.getSelectedBlocks() ); // As first check whether to enable or disable the command as the value will always be false if the command cannot be enabled. this.isEnabled = !!firstBlock && this._canBeAligned( firstBlock ); /** * A value of the current block's alignment. * * @observable * @readonly * @member {String} #value */ if ( this.isEnabled && firstBlock.hasAttribute( 'alignment' ) ) { this.value = firstBlock.getAttribute( 'alignment' ); } else { this.value = locale.contentLanguageDirection === 'rtl' ? 'right' : 'left'; } } /** * Executes the command. Applies the alignment `value` to the selected blocks. * If no `value` is passed, the `value` is the default one or it is equal to the currently selected block's alignment attribute, * the command will remove the attribute from the selected blocks. * * @param {Object} [options] Options for the executed command. * @param {String} [options.value] The value to apply. * @fires execute */ execute( options = {} ) { const editor = this.editor; const locale = editor.locale; const model = editor.model; const doc = model.document; const value = options.value; model.change( writer => { // Get only those blocks from selected that can have alignment set const blocks = Array.from( doc.selection.getSelectedBlocks() ).filter( block => this._canBeAligned( block ) ); const currentAlignment = blocks[ 0 ].getAttribute( 'alignment' ); // Remove alignment attribute if current alignment is: // - default (should not be stored in model as it will bloat model data) // - equal to currently set // - or no value is passed - denotes default alignment. const removeAlignment = Object(_utils__WEBPACK_IMPORTED_MODULE_2__["isDefault"])( value, locale ) || currentAlignment === value || !value; if ( removeAlignment ) { removeAlignmentFromSelection( blocks, writer ); } else { setAlignmentOnSelection( blocks, writer, value ); } } ); } /** * Checks whether a block can have alignment set. * * @private * @param {module:engine/model/element~Element} block The block to be checked. * @returns {Boolean} */ _canBeAligned( block ) { return this.editor.model.schema.checkAttribute( block, ALIGNMENT ); } } // Removes the alignment attribute from blocks. // @private function removeAlignmentFromSelection( blocks, writer ) { for ( const block of blocks ) { writer.removeAttribute( ALIGNMENT, block ); } } // Sets the alignment attribute on blocks. // @private function setAlignmentOnSelection( blocks, writer, alignment ) { for ( const block of blocks ) { writer.setAttribute( ALIGNMENT, alignment, block ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-alignment/src/alignmentediting.js": /*!****************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-alignment/src/alignmentediting.js ***! \****************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return AlignmentEditing; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _alignmentcommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./alignmentcommand */ "./node_modules/@ckeditor/ckeditor5-alignment/src/alignmentcommand.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils */ "./node_modules/@ckeditor/ckeditor5-alignment/src/utils.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module alignment/alignmentediting */ /** * The alignment editing feature. It introduces the {@link module:alignment/alignmentcommand~AlignmentCommand command} and adds * the `alignment` attribute for block elements in the {@link module:engine/model/model~Model model}. * @extends module:core/plugin~Plugin */ class AlignmentEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'AlignmentEditing'; } /** * @inheritDoc */ constructor( editor ) { super( editor ); editor.config.define( 'alignment', { options: [ ..._utils__WEBPACK_IMPORTED_MODULE_2__["supportedOptions"].map( option => ( { name: option } ) ) ] } ); } /** * @inheritDoc */ init() { const editor = this.editor; const locale = editor.locale; const schema = editor.model.schema; const options = Object(_utils__WEBPACK_IMPORTED_MODULE_2__["normalizeAlignmentOptions"])( editor.config.get( 'alignment.options' ) ); // Filter out unsupported options and those that are redundant, e.g. `left` in LTR / `right` in RTL mode. const optionsToConvert = options.filter( option => Object(_utils__WEBPACK_IMPORTED_MODULE_2__["isSupported"])( option.name ) && !Object(_utils__WEBPACK_IMPORTED_MODULE_2__["isDefault"])( option.name, locale ) ); // Once there is at least one `className` defined, we switch to alignment with classes. const shouldUseClasses = optionsToConvert.some( option => !!option.className ); // Allow alignment attribute on all blocks. schema.extend( '$block', { allowAttributes: 'alignment' } ); editor.model.schema.setAttributeProperties( 'alignment', { isFormatting: true } ); if ( shouldUseClasses ) { editor.conversion.attributeToAttribute( buildClassDefinition( optionsToConvert ) ); } else { // Downcast inline styles. editor.conversion.for( 'downcast' ).attributeToAttribute( buildDowncastInlineDefinition( optionsToConvert ) ); } const upcastInlineDefinitions = buildUpcastInlineDefinitions( optionsToConvert ); // Always upcast from inline styles. for ( const definition of upcastInlineDefinitions ) { editor.conversion.for( 'upcast' ).attributeToAttribute( definition ); } const upcastCompatibilityDefinitions = buildUpcastCompatibilityDefinitions( optionsToConvert ); // Always upcast from deprecated `align` attribute. for ( const definition of upcastCompatibilityDefinitions ) { editor.conversion.for( 'upcast' ).attributeToAttribute( definition ); } editor.commands.add( 'alignment', new _alignmentcommand__WEBPACK_IMPORTED_MODULE_1__["default"]( editor ) ); } } // Prepare downcast conversion definition for inline alignment styling. // @private function buildDowncastInlineDefinition( options ) { const definition = { model: { key: 'alignment', values: options.map( option => option.name ) }, view: {} }; for ( const { name } of options ) { definition.view[ name ] = { key: 'style', value: { 'text-align': name } }; } return definition; } // Prepare upcast definitions for inline alignment styles. // @private function buildUpcastInlineDefinitions( options ) { const definitions = []; for ( const { name } of options ) { definitions.push( { view: { key: 'style', value: { 'text-align': name } }, model: { key: 'alignment', value: name } } ); } return definitions; } // Prepare upcast definitions for deprecated `align` attribute. // @private function buildUpcastCompatibilityDefinitions( options ) { const definitions = []; for ( const { name } of options ) { definitions.push( { view: { key: 'align', value: name }, model: { key: 'alignment', value: name } } ); } return definitions; } // Prepare conversion definitions for upcast and downcast alignment with classes. // @private function buildClassDefinition( options ) { const definition = { model: { key: 'alignment', values: options.map( option => option.name ) }, view: {} }; for ( const option of options ) { definition.view[ option.name ] = { key: 'class', value: option.className }; } return definition; } /** * The alignment configuration format descriptor. * * const alignmentFormat = { * name: 'right', * className: 'my-align-right-class' * } * * @typedef {Object} module:alignment/alignmentediting~AlignmentFormat * * @property {'left'|'right'|'center'|'justify'} name One of the alignment names options. * * @property {String} className The CSS class used to represent the style in the view. * Used to override default, inline styling for alignment. */ /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-alignment/src/alignmentui.js": /*!***********************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-alignment/src/alignmentui.js ***! \***********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return AlignmentUI; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils */ "./node_modules/@ckeditor/ckeditor5-alignment/src/utils.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module alignment/alignmentui */ const iconsMap = new Map( [ [ 'left', ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["icons"].alignLeft ], [ 'right', ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["icons"].alignRight ], [ 'center', ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["icons"].alignCenter ], [ 'justify', ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["icons"].alignJustify ] ] ); /** * The default alignment UI plugin. * * It introduces the `'alignment:left'`, `'alignment:right'`, `'alignment:center'` and `'alignment:justify'` buttons * and the `'alignment'` dropdown. * * @extends module:core/plugin~Plugin */ class AlignmentUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * Returns the localized option titles provided by the plugin. * * The following localized titles corresponding with * {@link module:alignment/alignment~AlignmentConfig#options} are available: * * * `'left'`, * * `'right'`, * * `'center'`, * * `'justify'`. * * @readonly * @type {Object.} */ get localizedOptionTitles() { const t = this.editor.t; return { 'left': t( 'Align left' ), 'right': t( 'Align right' ), 'center': t( 'Align center' ), 'justify': t( 'Justify' ) }; } /** * @inheritDoc */ static get pluginName() { return 'AlignmentUI'; } /** * @inheritDoc */ init() { const editor = this.editor; const componentFactory = editor.ui.componentFactory; const t = editor.t; const options = Object(_utils__WEBPACK_IMPORTED_MODULE_2__["normalizeAlignmentOptions"])( editor.config.get( 'alignment.options' ) ); options .map( option => option.name ) .filter( _utils__WEBPACK_IMPORTED_MODULE_2__["isSupported"] ) .forEach( option => this._addButton( option ) ); componentFactory.add( 'alignment', locale => { const dropdownView = Object(ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__["createDropdown"])( locale ); // Add existing alignment buttons to dropdown's toolbar. const buttons = options.map( option => componentFactory.create( `alignment:${ option.name }` ) ); Object(ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__["addToolbarToDropdown"])( dropdownView, buttons ); // Configure dropdown properties an behavior. dropdownView.buttonView.set( { label: t( 'Text alignment' ), tooltip: true } ); dropdownView.toolbarView.isVertical = true; dropdownView.toolbarView.ariaLabel = t( 'Text alignment toolbar' ); dropdownView.extendTemplate( { attributes: { class: 'ck-alignment-dropdown' } } ); // The default icon depends on the direction of the content. const defaultIcon = locale.contentLanguageDirection === 'rtl' ? iconsMap.get( 'right' ) : iconsMap.get( 'left' ); // Change icon to reflect current selection's alignment. dropdownView.buttonView.bind( 'icon' ).toMany( buttons, 'isOn', ( ...areActive ) => { // Get the index of an active button. const index = areActive.findIndex( value => value ); // If none of the commands is active, display either defaultIcon or the first button's icon. if ( index < 0 ) { return defaultIcon; } // Return active button's icon. return buttons[ index ].icon; } ); // Enable button if any of the buttons is enabled. dropdownView.bind( 'isEnabled' ).toMany( buttons, 'isEnabled', ( ...areEnabled ) => areEnabled.some( isEnabled => isEnabled ) ); return dropdownView; } ); } /** * Helper method for initializing the button and linking it with an appropriate command. * * @private * @param {String} option The name of the alignment option for which the button is added. */ _addButton( option ) { const editor = this.editor; editor.ui.componentFactory.add( `alignment:${ option }`, locale => { const command = editor.commands.get( 'alignment' ); const buttonView = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__["ButtonView"]( locale ); buttonView.set( { label: this.localizedOptionTitles[ option ], icon: iconsMap.get( option ), tooltip: true, isToggleable: true } ); // Bind button model to command. buttonView.bind( 'isEnabled' ).to( command ); buttonView.bind( 'isOn' ).to( command, 'value', value => value === option ); // Execute command. this.listenTo( buttonView, 'execute', () => { editor.execute( 'alignment', { value: option } ); editor.editing.view.focus(); } ); return buttonView; } ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-alignment/src/utils.js": /*!*****************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-alignment/src/utils.js ***! \*****************************************************************/ /*! exports provided: supportedOptions, isSupported, isDefault, normalizeAlignmentOptions */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "supportedOptions", function() { return supportedOptions; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isSupported", function() { return isSupported; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isDefault", function() { return isDefault; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "normalizeAlignmentOptions", function() { return normalizeAlignmentOptions; }); /* harmony import */ var ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/utils */ "./node_modules/ckeditor5/src/utils.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module alignment/utils */ /** * The list of supported alignment options: * * * `'left'`, * * `'right'`, * * `'center'`, * * `'justify'` */ const supportedOptions = [ 'left', 'right', 'center', 'justify' ]; /** * Checks whether the passed option is supported by {@link module:alignment/alignmentediting~AlignmentEditing}. * * @param {String} option The option value to check. * @returns {Boolean} */ function isSupported( option ) { return supportedOptions.includes( option ); } /** * Checks whether alignment is the default one considering the direction * of the editor content. * * @param {String} alignment The name of the alignment to check. * @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance. * @returns {Boolean} */ function isDefault( alignment, locale ) { // Right now only LTR is supported so the 'left' value is always the default one. if ( locale.contentLanguageDirection == 'rtl' ) { return alignment === 'right'; } else { return alignment === 'left'; } } /** * Brings the configuration to the common form, an array of objects. * * @param {Array.} configuredOptions Alignment plugin configuration. * @returns {Array.} Normalized object holding the configuration. */ function normalizeAlignmentOptions( configuredOptions ) { const normalizedOptions = configuredOptions .map( option => { let result; if ( typeof option == 'string' ) { result = { name: option }; } else { result = option; } return result; } ) // Remove all unknown options. .filter( option => { const isNameValid = !!supportedOptions.includes( option.name ); if ( !isNameValid ) { /** * The `name` in one of the `alignment.options` is not recognized. * The available options are: `'left'`, `'right'`, `'center'` and `'justify'`. * * @error alignment-config-name-not-recognized * @param {Object} option Options with unknown value of the `name` property. */ Object(ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_0__["logWarning"])( 'alignment-config-name-not-recognized', { option } ); } return isNameValid; } ); const classNameCount = normalizedOptions.filter( option => !!option.className ).length; // We either use classes for all styling options or for none. if ( classNameCount && classNameCount < normalizedOptions.length ) { /** * The `className` property has to be defined for all options once at least one option declares `className`. * * @error alignment-config-classnames-are-missing * @param {Array.} configuredOptions Contents of `alignment.options`. */ throw new ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_0__["CKEditorError"]( 'alignment-config-classnames-are-missing', { configuredOptions } ); } // Validate resulting config. normalizedOptions.forEach( ( option, index, allOptions ) => { const succeedingOptions = allOptions.slice( index + 1 ); const nameAlreadyExists = succeedingOptions.some( item => item.name == option.name ); if ( nameAlreadyExists ) { /** * The same `name` in one of the `alignment.options` was already declared. * Each `name` representing one alignment option can be set exactly once. * * @error alignment-config-name-already-defined * @param {Object} option First option that declares given `name`. * @param {Array.} configuredOptions Contents of `alignment.options`. */ throw new ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_0__["CKEditorError"]( 'alignment-config-name-already-defined', { option, configuredOptions } ); } // The `className` property is present. Check for duplicates then. if ( option.className ) { const classNameAlreadyExists = succeedingOptions.some( item => item.className == option.className ); if ( classNameAlreadyExists ) { /** * The same `className` in one of the `alignment.options` was already declared. * * @error alignment-config-classname-already-defined * @param {Object} option First option that declares given `className`. * @param {Array.} configuredOptions * Contents of `alignment.options`. */ throw new ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_0__["CKEditorError"]( 'alignment-config-classname-already-defined', { option, configuredOptions } ); } } } ); return normalizedOptions; } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-autoformat/src/autoformat.js": /*!***********************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-autoformat/src/autoformat.js ***! \***********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Autoformat; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _blockautoformatediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./blockautoformatediting */ "./node_modules/@ckeditor/ckeditor5-autoformat/src/blockautoformatediting.js"); /* harmony import */ var _inlineautoformatediting__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./inlineautoformatediting */ "./node_modules/@ckeditor/ckeditor5-autoformat/src/inlineautoformatediting.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module autoformat/autoformat */ /** * Enables a set of predefined autoformatting actions. * * For a detailed overview, check the {@glink features/autoformat Autoformatting feature documentation} * and the {@glink api/autoformat package page}. * * @extends module:core/plugin~Plugin */ class Autoformat extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'Autoformat'; } /** * @inheritDoc */ afterInit() { this._addListAutoformats(); this._addBasicStylesAutoformats(); this._addHeadingAutoformats(); this._addBlockQuoteAutoformats(); this._addCodeBlockAutoformats(); this._addHorizontalLineAutoformats(); } /** * Adds autoformatting related to the {@link module:list/list~List}. * * When typed: * - `* ` or `- ` – A paragraph will be changed to a bulleted list. * - `1. ` or `1) ` – A paragraph will be changed to a numbered list ("1" can be any digit or a list of digits). * - `[] ` or `[ ] ` – A paragraph will be changed to a to-do list. * - `[x] ` or `[ x ] ` – A paragraph will be changed to a checked to-do list. * * @private */ _addListAutoformats() { const commands = this.editor.commands; if ( commands.get( 'bulletedList' ) ) { Object(_blockautoformatediting__WEBPACK_IMPORTED_MODULE_1__["default"])( this.editor, this, /^[*-]\s$/, 'bulletedList' ); } if ( commands.get( 'numberedList' ) ) { Object(_blockautoformatediting__WEBPACK_IMPORTED_MODULE_1__["default"])( this.editor, this, /^1[.|)]\s$/, 'numberedList' ); } if ( commands.get( 'todoList' ) ) { Object(_blockautoformatediting__WEBPACK_IMPORTED_MODULE_1__["default"])( this.editor, this, /^\[\s?\]\s$/, 'todoList' ); } if ( commands.get( 'checkTodoList' ) ) { Object(_blockautoformatediting__WEBPACK_IMPORTED_MODULE_1__["default"])( this.editor, this, /^\[\s?x\s?\]\s$/, () => { this.editor.execute( 'todoList' ); this.editor.execute( 'checkTodoList' ); } ); } } /** * Adds autoformatting related to the {@link module:basic-styles/bold~Bold}, * {@link module:basic-styles/italic~Italic}, {@link module:basic-styles/code~Code} * and {@link module:basic-styles/strikethrough~Strikethrough} * * When typed: * - `**foobar**` – `**` characters are removed and `foobar` is set to bold, * - `__foobar__` – `__` characters are removed and `foobar` is set to bold, * - `*foobar*` – `*` characters are removed and `foobar` is set to italic, * - `_foobar_` – `_` characters are removed and `foobar` is set to italic, * - ``` `foobar` – ``` ` ``` characters are removed and `foobar` is set to code, * - `~~foobar~~` – `~~` characters are removed and `foobar` is set to strikethrough. * * @private */ _addBasicStylesAutoformats() { const commands = this.editor.commands; if ( commands.get( 'bold' ) ) { const boldCallback = getCallbackFunctionForInlineAutoformat( this.editor, 'bold' ); Object(_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_2__["default"])( this.editor, this, /(?:^|\s)(\*\*)([^*]+)(\*\*)$/g, boldCallback ); Object(_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_2__["default"])( this.editor, this, /(?:^|\s)(__)([^_]+)(__)$/g, boldCallback ); } if ( commands.get( 'italic' ) ) { const italicCallback = getCallbackFunctionForInlineAutoformat( this.editor, 'italic' ); // The italic autoformatter cannot be triggered by the bold markers, so we need to check the // text before the pattern (e.g. `(?:^|[^\*])`). Object(_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_2__["default"])( this.editor, this, /(?:^|\s)(\*)([^*_]+)(\*)$/g, italicCallback ); Object(_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_2__["default"])( this.editor, this, /(?:^|\s)(_)([^_]+)(_)$/g, italicCallback ); } if ( commands.get( 'code' ) ) { const codeCallback = getCallbackFunctionForInlineAutoformat( this.editor, 'code' ); Object(_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_2__["default"])( this.editor, this, /(`)([^`]+)(`)$/g, codeCallback ); } if ( commands.get( 'strikethrough' ) ) { const strikethroughCallback = getCallbackFunctionForInlineAutoformat( this.editor, 'strikethrough' ); Object(_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_2__["default"])( this.editor, this, /(~~)([^~]+)(~~)$/g, strikethroughCallback ); } } /** * Adds autoformatting related to {@link module:heading/heading~Heading}. * * It is using a number at the end of the command name to associate it with the proper trigger: * * * `heading` with value `heading1` will be executed when typing `#`, * * `heading` with value `heading2` will be executed when typing `##`, * * ... up to `heading6` and `######`. * * @private */ _addHeadingAutoformats() { const command = this.editor.commands.get( 'heading' ); if ( command ) { command.modelElements .filter( name => name.match( /^heading[1-6]$/ ) ) .forEach( modelName => { const level = modelName[ 7 ]; const pattern = new RegExp( `^(#{${ level }})\\s$` ); Object(_blockautoformatediting__WEBPACK_IMPORTED_MODULE_1__["default"])( this.editor, this, pattern, () => { // Should only be active if command is enabled and heading style associated with pattern is inactive. if ( !command.isEnabled || command.value === modelName ) { return false; } this.editor.execute( 'heading', { value: modelName } ); } ); } ); } } /** * Adds autoformatting related to {@link module:block-quote/blockquote~BlockQuote}. * * When typed: * * `> ` – A paragraph will be changed to a block quote. * * @private */ _addBlockQuoteAutoformats() { if ( this.editor.commands.get( 'blockQuote' ) ) { Object(_blockautoformatediting__WEBPACK_IMPORTED_MODULE_1__["default"])( this.editor, this, /^>\s$/, 'blockQuote' ); } } /** * Adds autoformatting related to {@link module:code-block/codeblock~CodeBlock}. * * When typed: * - `` ``` `` – A paragraph will be changed to a code block. * * @private */ _addCodeBlockAutoformats() { if ( this.editor.commands.get( 'codeBlock' ) ) { Object(_blockautoformatediting__WEBPACK_IMPORTED_MODULE_1__["default"])( this.editor, this, /^```$/, 'codeBlock' ); } } /** * Adds autoformatting related to {@link module:horizontal-line/horizontalline~HorizontalLine}. * * When typed: * - `` --- `` – Will be replaced with a horizontal line. * * @private */ _addHorizontalLineAutoformats() { if ( this.editor.commands.get( 'horizontalLine' ) ) { Object(_blockautoformatediting__WEBPACK_IMPORTED_MODULE_1__["default"])( this.editor, this, /^---$/, 'horizontalLine' ); } } } // Helper function for getting `inlineAutoformatEditing` callbacks that checks if command is enabled. // // @param {module:core/editor/editor~Editor} editor // @param {String} attributeKey // @returns {Function} function getCallbackFunctionForInlineAutoformat( editor, attributeKey ) { return ( writer, rangesToFormat ) => { const command = editor.commands.get( attributeKey ); if ( !command.isEnabled ) { return false; } const validRanges = editor.model.schema.getValidRanges( rangesToFormat, attributeKey ); for ( const range of validRanges ) { writer.setAttribute( attributeKey, true, range ); } // After applying attribute to the text, remove given attribute from the selection. // This way user is able to type a text without attribute used by auto formatter. writer.removeSelectionAttribute( attributeKey ); }; } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-autoformat/src/blockautoformatediting.js": /*!***********************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-autoformat/src/blockautoformatediting.js ***! \***********************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return blockAutoformatEditing; }); /* harmony import */ var ckeditor5_src_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/engine */ "./node_modules/ckeditor5/src/engine.js"); /* harmony import */ var ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/utils */ "./node_modules/ckeditor5/src/utils.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * The block autoformatting engine. It allows to format various block patterns. For example, * it can be configured to turn a paragraph starting with `*` and followed by a space into a list item. * * The autoformatting operation is integrated with the undo manager, * so the autoformatting step can be undone if the user's intention was not to format the text. * * See the {@link module:autoformat/blockautoformatediting~blockAutoformatEditing `blockAutoformatEditing`} documentation * to learn how to create custom block autoformatters. You can also use * the {@link module:autoformat/autoformat~Autoformat} feature which enables a set of default autoformatters * (lists, headings, bold and italic). * * @module autoformat/blockautoformatediting */ /** * Creates a listener triggered on {@link module:engine/model/document~Document#event:change:data `change:data`} event in the document. * Calls the callback when inserted text matches the regular expression or the command name * if provided instead of the callback. * * Examples of usage: * * To convert a paragraph to heading 1 when `- ` is typed, using just the command name: * * blockAutoformatEditing( editor, plugin, /^\- $/, 'heading1' ); * * To convert a paragraph to heading 1 when `- ` is typed, using just the callback: * * blockAutoformatEditing( editor, plugin, /^\- $/, ( context ) => { * const { match } = context; * const headingLevel = match[ 1 ].length; * * editor.execute( 'heading', { * formatId: `heading${ headingLevel }` * } ); * } ); * * @param {module:core/editor/editor~Editor} editor The editor instance. * @param {module:autoformat/autoformat~Autoformat} plugin The autoformat plugin instance. * @param {RegExp} pattern The regular expression to execute on just inserted text. The regular expression is tested against the text * from the beginning until the caret position. * @param {Function|String} callbackOrCommand The callback to execute or the command to run when the text is matched. * In case of providing the callback, it receives the following parameter: * * {Object} match RegExp.exec() result of matching the pattern to inserted text. */ function blockAutoformatEditing( editor, plugin, pattern, callbackOrCommand ) { let callback; let command = null; if ( typeof callbackOrCommand == 'function' ) { callback = callbackOrCommand; } else { // We assume that the actual command name was provided. command = editor.commands.get( callbackOrCommand ); callback = () => { editor.execute( callbackOrCommand ); }; } editor.model.document.on( 'change:data', ( evt, batch ) => { if ( command && !command.isEnabled || !plugin.isEnabled ) { return; } const range = Object(ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_1__["first"])( editor.model.document.selection.getRanges() ); if ( !range.isCollapsed ) { return; } if ( batch.type == 'transparent' ) { return; } const changes = Array.from( editor.model.document.differ.getChanges() ); const entry = changes[ 0 ]; // Typing is represented by only a single change. if ( changes.length != 1 || entry.type !== 'insert' || entry.name != '$text' || entry.length != 1 ) { return; } const blockToFormat = entry.position.parent; // Block formatting should be disabled in codeBlocks (#5800). if ( blockToFormat.is( 'element', 'codeBlock' ) ) { return; } // Only list commands and custom callbacks can be applied inside a list. if ( blockToFormat.is( 'element', 'listItem' ) && typeof callbackOrCommand !== 'function' && ![ 'numberedList', 'bulletedList', 'todoList' ].includes( callbackOrCommand ) ) { return; } // In case a command is bound, do not re-execute it over an existing block style which would result with a style removal. // Instead just drop processing so that autoformat trigger text is not lost. E.g. writing "# " in a level 1 heading. if ( command && command.value === true ) { return; } const firstNode = blockToFormat.getChild( 0 ); const firstNodeRange = editor.model.createRangeOn( firstNode ); // Range is only expected to be within or at the very end of the first text node. if ( !firstNodeRange.containsRange( range ) && !range.end.isEqual( firstNodeRange.end ) ) { return; } const match = pattern.exec( firstNode.data.substr( 0, range.end.offset ) ); // ...and this text node's data match the pattern. if ( !match ) { return; } // Use enqueueChange to create new batch to separate typing batch from the auto-format changes. editor.model.enqueueChange( writer => { // Matched range. const start = writer.createPositionAt( blockToFormat, 0 ); const end = writer.createPositionAt( blockToFormat, match[ 0 ].length ); const range = new ckeditor5_src_engine__WEBPACK_IMPORTED_MODULE_0__["LiveRange"]( start, end ); const wasChanged = callback( { match } ); // Remove matched text. if ( wasChanged !== false ) { writer.remove( range ); const selectionRange = editor.model.document.selection.getFirstRange(); const blockRange = writer.createRangeIn( blockToFormat ); // If the block is empty and the document selection has been moved when // applying formatting (e.g. is now in newly created block). if ( blockToFormat.isEmpty && !blockRange.isEqual( selectionRange ) && !blockRange.containsRange( selectionRange, true ) ) { writer.remove( blockToFormat ); } } range.detach(); } ); } ); } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-autoformat/src/inlineautoformatediting.js": /*!************************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-autoformat/src/inlineautoformatediting.js ***! \************************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return inlineAutoformatEditing; }); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * The inline autoformatting engine. It allows to format various inline patterns. For example, * it can be configured to make "foo" bold when typed `**foo**` (the `**` markers will be removed). * * The autoformatting operation is integrated with the undo manager, * so the autoformatting step can be undone if the user's intention was not to format the text. * * See the {@link module:autoformat/inlineautoformatediting~inlineAutoformatEditing `inlineAutoformatEditing`} documentation * to learn how to create custom inline autoformatters. You can also use * the {@link module:autoformat/autoformat~Autoformat} feature which enables a set of default autoformatters * (lists, headings, bold and italic). * * @module autoformat/inlineautoformatediting */ /** * Enables autoformatting mechanism for a given {@link module:core/editor/editor~Editor}. * * It formats the matched text by applying the given model attribute or by running the provided formatting callback. * On every {@link module:engine/model/document~Document#event:change:data data change} in the model document * the autoformatting engine checks the text on the left of the selection * and executes the provided action if the text matches given criteria (regular expression or callback). * * @param {module:core/editor/editor~Editor} editor The editor instance. * @param {module:autoformat/autoformat~Autoformat} plugin The autoformat plugin instance. * @param {Function|RegExp} testRegexpOrCallback The regular expression or callback to execute on text. * Provided regular expression *must* have three capture groups. The first and the third capture group * should match opening and closing delimiters. The second capture group should match the text to format. * * // Matches the `**bold text**` pattern. * // There are three capturing groups: * // - The first to match the starting `**` delimiter. * // - The second to match the text to format. * // - The third to match the ending `**` delimiter. * inlineAutoformatEditing( editor, plugin, /(\*\*)([^\*]+?)(\*\*)$/g, formatCallback ); * * When a function is provided instead of the regular expression, it will be executed with the text to match as a parameter. * The function should return proper "ranges" to delete and format. * * { * remove: [ * [ 0, 1 ], // Remove the first letter from the given text. * [ 5, 6 ] // Remove the 6th letter from the given text. * ], * format: [ * [ 1, 5 ] // Format all letters from 2nd to 5th. * ] * } * * @param {Function} formatCallback A callback to apply actual formatting. * It should return `false` if changes should not be applied (e.g. if a command is disabled). * * inlineAutoformatEditing( editor, plugin, /(\*\*)([^\*]+?)(\*\*)$/g, ( writer, rangesToFormat ) => { * const command = editor.commands.get( 'bold' ); * * if ( !command.isEnabled ) { * return false; * } * * const validRanges = editor.model.schema.getValidRanges( rangesToFormat, 'bold' ); * * for ( let range of validRanges ) { * writer.setAttribute( 'bold', true, range ); * } * } ); */ function inlineAutoformatEditing( editor, plugin, testRegexpOrCallback, formatCallback ) { let regExp; let testCallback; if ( testRegexpOrCallback instanceof RegExp ) { regExp = testRegexpOrCallback; } else { testCallback = testRegexpOrCallback; } // A test callback run on changed text. testCallback = testCallback || ( text => { let result; const remove = []; const format = []; while ( ( result = regExp.exec( text ) ) !== null ) { // There should be full match and 3 capture groups. if ( result && result.length < 4 ) { break; } let { index, '1': leftDel, '2': content, '3': rightDel } = result; // Real matched string - there might be some non-capturing groups so we need to recalculate starting index. const found = leftDel + content + rightDel; index += result[ 0 ].length - found.length; // Start and End offsets of delimiters to remove. const delStart = [ index, index + leftDel.length ]; const delEnd = [ index + leftDel.length + content.length, index + leftDel.length + content.length + rightDel.length ]; remove.push( delStart ); remove.push( delEnd ); format.push( [ index + leftDel.length, index + leftDel.length + content.length ] ); } return { remove, format }; } ); editor.model.document.on( 'change:data', ( evt, batch ) => { if ( batch.type == 'transparent' || !plugin.isEnabled ) { return; } const model = editor.model; const selection = model.document.selection; // Do nothing if selection is not collapsed. if ( !selection.isCollapsed ) { return; } const changes = Array.from( model.document.differ.getChanges() ); const entry = changes[ 0 ]; // Typing is represented by only a single change. if ( changes.length != 1 || entry.type !== 'insert' || entry.name != '$text' || entry.length != 1 ) { return; } const focus = selection.focus; const block = focus.parent; const { text, range } = getTextAfterCode( model.createRange( model.createPositionAt( block, 0 ), focus ), model ); const testOutput = testCallback( text ); const rangesToFormat = testOutputToRanges( range.start, testOutput.format, model ); const rangesToRemove = testOutputToRanges( range.start, testOutput.remove, model ); if ( !( rangesToFormat.length && rangesToRemove.length ) ) { return; } // Use enqueueChange to create new batch to separate typing batch from the auto-format changes. model.enqueueChange( writer => { // Apply format. const hasChanged = formatCallback( writer, rangesToFormat ); // Strict check on `false` to have backward compatibility (when callbacks were returning `undefined`). if ( hasChanged === false ) { return; } // Remove delimiters - use reversed order to not mix the offsets while removing. for ( const range of rangesToRemove.reverse() ) { writer.remove( range ); } } ); } ); } // Converts output of the test function provided to the inlineAutoformatEditing and converts it to the model ranges // inside provided block. // // @private // @param {module:engine/model/position~Position} start // @param {Array.} arrays // @param {module:engine/model/model~Model} model function testOutputToRanges( start, arrays, model ) { return arrays .filter( array => ( array[ 0 ] !== undefined && array[ 1 ] !== undefined ) ) .map( array => { return model.createRange( start.getShiftedBy( array[ 0 ] ), start.getShiftedBy( array[ 1 ] ) ); } ); } // Returns the last text line after the last code element from the given range. // It is similar to {@link module:typing/utils/getlasttextline.getLastTextLine `getLastTextLine()`}, // but it ignores any text before the last `code`. // // @param {module:engine/model/range~Range} range // @param {module:engine/model/model~Model} model // @returns {module:typing/utils/getlasttextline~LastTextLineData} function getTextAfterCode( range, model ) { let start = range.start; const text = Array.from( range.getItems() ).reduce( ( rangeText, node ) => { // Trim text to a last occurrence of an inline element and update range start. if ( !( node.is( '$text' ) || node.is( '$textProxy' ) ) || node.getAttribute( 'code' ) ) { start = model.createPositionAfter( node ); return ''; } return rangeText + node.data; }, '' ); return { text, range: model.createRange( start, range.end ) }; } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js": /*!*******************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js ***! \*******************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return AttributeCommand; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/attributecommand */ /** * An extension of the base {@link module:core/command~Command} class, which provides utilities for a command * that toggles a single attribute on a text or an element. * * `AttributeCommand` uses {@link module:engine/model/document~Document#selection} * to decide which nodes (if any) should be changed, and applies or removes the attribute from them. * * The command checks the {@link module:engine/model/model~Model#schema} to decide if it can be enabled * for the current selection and to which nodes the attribute can be applied. * * @extends module:core/command~Command */ class AttributeCommand extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Command"] { /** * @param {module:core/editor/editor~Editor} editor * @param {String} attributeKey Attribute that will be set by the command. */ constructor( editor, attributeKey ) { super( editor ); /** * The attribute that will be set by the command. * * @readonly * @member {String} */ this.attributeKey = attributeKey; /** * Flag indicating whether the command is active. The command is active when the * {@link module:engine/model/selection~Selection#hasAttribute selection has the attribute} which means that: * * * If the selection is not empty – That the attribute is set on the first node in the selection that allows this attribute. * * If the selection is empty – That the selection has the attribute itself (which means that newly typed * text will have this attribute, too). * * @observable * @readonly * @member {Boolean} #value */ } /** * Updates the command's {@link #value} and {@link #isEnabled} based on the current selection. */ refresh() { const model = this.editor.model; const doc = model.document; this.value = this._getValueFromFirstAllowedNode(); this.isEnabled = model.schema.checkAttributeInSelection( doc.selection, this.attributeKey ); } /** * Executes the command — applies the attribute to the selection or removes it from the selection. * * If the command is active (`value == true`), it will remove attributes. Otherwise, it will set attributes. * * The execution result differs, depending on the {@link module:engine/model/document~Document#selection}: * * * If the selection is on a range, the command applies the attribute to all nodes in that range * (if they are allowed to have this attribute by the {@link module:engine/model/schema~Schema schema}). * * If the selection is collapsed in a non-empty node, the command applies the attribute to the * {@link module:engine/model/document~Document#selection} itself (note that typed characters copy attributes from the selection). * * If the selection is collapsed in an empty node, the command applies the attribute to the parent node of the selection (note * that the selection inherits all attributes from a node if it is in an empty node). * * @fires execute * @param {Object} [options] Command options. * @param {Boolean} [options.forceValue] If set, it will force the command behavior. If `true`, the command will apply the attribute, * otherwise the command will remove the attribute. * If not set, the command will look for its current value to decide what it should do. */ execute( options = {} ) { const model = this.editor.model; const doc = model.document; const selection = doc.selection; const value = ( options.forceValue === undefined ) ? !this.value : options.forceValue; model.change( writer => { if ( selection.isCollapsed ) { if ( value ) { writer.setSelectionAttribute( this.attributeKey, true ); } else { writer.removeSelectionAttribute( this.attributeKey ); } } else { const ranges = model.schema.getValidRanges( selection.getRanges(), this.attributeKey ); for ( const range of ranges ) { if ( value ) { writer.setAttribute( this.attributeKey, value, range ); } else { writer.removeAttribute( this.attributeKey, range ); } } } } ); } /** * Checks the attribute value of the first node in the selection that allows the attribute. * For the collapsed selection returns the selection attribute. * * @private * @returns {Boolean} The attribute value. */ _getValueFromFirstAllowedNode() { const model = this.editor.model; const schema = model.schema; const selection = model.document.selection; if ( selection.isCollapsed ) { return selection.hasAttribute( this.attributeKey ); } for ( const range of selection.getRanges() ) { for ( const item of range.getItems() ) { if ( schema.checkAttribute( item, this.attributeKey ) ) { return item.hasAttribute( this.attributeKey ); } } } return false; } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold.js": /*!*******************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold.js ***! \*******************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Bold; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _bold_boldediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./bold/boldediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldediting.js"); /* harmony import */ var _bold_boldui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./bold/boldui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldui.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/bold */ /** * The bold feature. * * For a detailed overview check the {@glink features/basic-styles Basic styles feature documentation} * and the {@glink api/basic-styles package page}. * * This is a "glue" plugin which loads the {@link module:basic-styles/bold/boldediting~BoldEditing bold editing feature} * and {@link module:basic-styles/bold/boldui~BoldUI bold UI feature}. * * @extends module:core/plugin~Plugin */ class Bold extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get requires() { return [ _bold_boldediting__WEBPACK_IMPORTED_MODULE_1__["default"], _bold_boldui__WEBPACK_IMPORTED_MODULE_2__["default"] ]; } /** * @inheritDoc */ static get pluginName() { return 'Bold'; } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldediting.js": /*!*******************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldediting.js ***! \*******************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return BoldEditing; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/bold/boldediting */ const BOLD = 'bold'; /** * The bold editing feature. * * It registers the `'bold'` command and introduces the `bold` attribute in the model which renders to the view * as a `` element. * * @extends module:core/plugin~Plugin */ class BoldEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'BoldEditing'; } /** * @inheritDoc */ init() { const editor = this.editor; // Allow bold attribute on text nodes. editor.model.schema.extend( '$text', { allowAttributes: BOLD } ); editor.model.schema.setAttributeProperties( BOLD, { isFormatting: true, copyOnEnter: true } ); // Build converter from model to view for data and editing pipelines. editor.conversion.attributeToElement( { model: BOLD, view: 'strong', upcastAlso: [ 'b', viewElement => { const fontWeight = viewElement.getStyle( 'font-weight' ); if ( !fontWeight ) { return null; } // Value of the `font-weight` attribute can be defined as a string or a number. if ( fontWeight == 'bold' || Number( fontWeight ) >= 600 ) { return { name: true, styles: [ 'font-weight' ] }; } } ] } ); // Create bold command. editor.commands.add( BOLD, new _attributecommand__WEBPACK_IMPORTED_MODULE_1__["default"]( editor, BOLD ) ); // Set the Ctrl+B keystroke. editor.keystrokes.set( 'CTRL+B', BOLD ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldui.js": /*!**************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldui.js ***! \**************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return BoldUI; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); /* harmony import */ var _theme_icons_bold_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../theme/icons/bold.svg */ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/bold.svg"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/bold/boldui */ const BOLD = 'bold'; /** * The bold UI feature. It introduces the Bold button. * * @extends module:core/plugin~Plugin */ class BoldUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'BoldUI'; } /** * @inheritDoc */ init() { const editor = this.editor; const t = editor.t; // Add bold button to feature components. editor.ui.componentFactory.add( BOLD, locale => { const command = editor.commands.get( BOLD ); const view = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__["ButtonView"]( locale ); view.set( { label: t( 'Bold' ), icon: _theme_icons_bold_svg__WEBPACK_IMPORTED_MODULE_2__["default"], keystroke: 'CTRL+B', tooltip: true, isToggleable: true } ); view.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' ); // Execute command. this.listenTo( view, 'execute', () => { editor.execute( BOLD ); editor.editing.view.focus(); } ); return view; } ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic.js": /*!*********************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic.js ***! \*********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Italic; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _italic_italicediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./italic/italicediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicediting.js"); /* harmony import */ var _italic_italicui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./italic/italicui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicui.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/italic */ /** * The italic feature. * * For a detailed overview check the {@glink features/basic-styles Basic styles feature documentation} * and the {@glink api/basic-styles package page}. * * This is a "glue" plugin which loads the {@link module:basic-styles/italic/italicediting~ItalicEditing} and * {@link module:basic-styles/italic/italicui~ItalicUI} plugins. * * @extends module:core/plugin~Plugin */ class Italic extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get requires() { return [ _italic_italicediting__WEBPACK_IMPORTED_MODULE_1__["default"], _italic_italicui__WEBPACK_IMPORTED_MODULE_2__["default"] ]; } /** * @inheritDoc */ static get pluginName() { return 'Italic'; } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicediting.js": /*!***********************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicediting.js ***! \***********************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ItalicEditing; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/italic/italicediting */ const ITALIC = 'italic'; /** * The italic editing feature. * * It registers the `'italic'` command, the Ctrl+I keystroke and introduces the `italic` attribute in the model * which renders to the view as an `` element. * * @extends module:core/plugin~Plugin */ class ItalicEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'ItalicEditing'; } /** * @inheritDoc */ init() { const editor = this.editor; // Allow italic attribute on text nodes. editor.model.schema.extend( '$text', { allowAttributes: ITALIC } ); editor.model.schema.setAttributeProperties( ITALIC, { isFormatting: true, copyOnEnter: true } ); editor.conversion.attributeToElement( { model: ITALIC, view: 'i', upcastAlso: [ 'em', { styles: { 'font-style': 'italic' } } ] } ); // Create italic command. editor.commands.add( ITALIC, new _attributecommand__WEBPACK_IMPORTED_MODULE_1__["default"]( editor, ITALIC ) ); // Set the Ctrl+I keystroke. editor.keystrokes.set( 'CTRL+I', ITALIC ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicui.js": /*!******************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicui.js ***! \******************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ItalicUI; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); /* harmony import */ var _theme_icons_italic_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../theme/icons/italic.svg */ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/italic.svg"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/italic/italicui */ const ITALIC = 'italic'; /** * The italic UI feature. It introduces the Italic button. * * @extends module:core/plugin~Plugin */ class ItalicUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'ItalicUI'; } /** * @inheritDoc */ init() { const editor = this.editor; const t = editor.t; // Add bold button to feature components. editor.ui.componentFactory.add( ITALIC, locale => { const command = editor.commands.get( ITALIC ); const view = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__["ButtonView"]( locale ); view.set( { label: t( 'Italic' ), icon: _theme_icons_italic_svg__WEBPACK_IMPORTED_MODULE_2__["default"], keystroke: 'CTRL+I', tooltip: true, isToggleable: true } ); view.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' ); // Execute command. this.listenTo( view, 'execute', () => { editor.execute( ITALIC ); editor.editing.view.focus(); } ); return view; } ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough.js": /*!****************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough.js ***! \****************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Strikethrough; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _strikethrough_strikethroughediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./strikethrough/strikethroughediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughediting.js"); /* harmony import */ var _strikethrough_strikethroughui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./strikethrough/strikethroughui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughui.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/strikethrough */ /** * The strikethrough feature. * * For a detailed overview check the {@glink features/basic-styles Basic styles feature documentation} * and the {@glink api/basic-styles package page}. * * This is a "glue" plugin which loads the {@link module:basic-styles/strikethrough/strikethroughediting~StrikethroughEditing} and * {@link module:basic-styles/strikethrough/strikethroughui~StrikethroughUI} plugins. * * @extends module:core/plugin~Plugin */ class Strikethrough extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get requires() { return [ _strikethrough_strikethroughediting__WEBPACK_IMPORTED_MODULE_1__["default"], _strikethrough_strikethroughui__WEBPACK_IMPORTED_MODULE_2__["default"] ]; } /** * @inheritDoc */ static get pluginName() { return 'Strikethrough'; } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughediting.js": /*!*************************************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughediting.js ***! \*************************************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return StrikethroughEditing; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/strikethrough/strikethroughediting */ const STRIKETHROUGH = 'strikethrough'; /** * The strikethrough editing feature. * * It registers the `'strikethrough'` command, the Ctrl+Shift+X keystroke and introduces the * `strikethroughsthrough` attribute in the model which renders to the view * as a `` element. * * @extends module:core/plugin~Plugin */ class StrikethroughEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'StrikethroughEditing'; } /** * @inheritDoc */ init() { const editor = this.editor; // Allow strikethrough attribute on text nodes. editor.model.schema.extend( '$text', { allowAttributes: STRIKETHROUGH } ); editor.model.schema.setAttributeProperties( STRIKETHROUGH, { isFormatting: true, copyOnEnter: true } ); editor.conversion.attributeToElement( { model: STRIKETHROUGH, view: 's', upcastAlso: [ 'del', 'strike', { styles: { 'text-decoration': 'line-through' } } ] } ); // Create strikethrough command. editor.commands.add( STRIKETHROUGH, new _attributecommand__WEBPACK_IMPORTED_MODULE_1__["default"]( editor, STRIKETHROUGH ) ); // Set the Ctrl+Shift+X keystroke. editor.keystrokes.set( 'CTRL+SHIFT+X', 'strikethrough' ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughui.js": /*!********************************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughui.js ***! \********************************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return StrikethroughUI; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); /* harmony import */ var _theme_icons_strikethrough_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../theme/icons/strikethrough.svg */ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/strikethrough.svg"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/strikethrough/strikethroughui */ const STRIKETHROUGH = 'strikethrough'; /** * The strikethrough UI feature. It introduces the Strikethrough button. * * @extends module:core/plugin~Plugin */ class StrikethroughUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'StrikethroughUI'; } /** * @inheritDoc */ init() { const editor = this.editor; const t = editor.t; // Add strikethrough button to feature components. editor.ui.componentFactory.add( STRIKETHROUGH, locale => { const command = editor.commands.get( STRIKETHROUGH ); const view = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__["ButtonView"]( locale ); view.set( { label: t( 'Strikethrough' ), icon: _theme_icons_strikethrough_svg__WEBPACK_IMPORTED_MODULE_2__["default"], keystroke: 'CTRL+SHIFT+X', tooltip: true, isToggleable: true } ); view.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' ); // Execute command. this.listenTo( view, 'execute', () => { editor.execute( STRIKETHROUGH ); editor.editing.view.focus(); } ); return view; } ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript.js": /*!************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript.js ***! \************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Subscript; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _subscript_subscriptediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./subscript/subscriptediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptediting.js"); /* harmony import */ var _subscript_subscriptui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./subscript/subscriptui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptui.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/subscript */ /** * The subscript feature. * * It loads the {@link module:basic-styles/subscript/subscriptediting~SubscriptEditing} and * {@link module:basic-styles/subscript/subscriptui~SubscriptUI} plugins. * * @extends module:core/plugin~Plugin */ class Subscript extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get requires() { return [ _subscript_subscriptediting__WEBPACK_IMPORTED_MODULE_1__["default"], _subscript_subscriptui__WEBPACK_IMPORTED_MODULE_2__["default"] ]; } /** * @inheritDoc */ static get pluginName() { return 'Subscript'; } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptediting.js": /*!*****************************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptediting.js ***! \*****************************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return SubscriptEditing; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/subscript/subscriptediting */ const SUBSCRIPT = 'subscript'; /** * The subscript editing feature. * * It registers the `sub` command and introduces the `sub` attribute in the model which renders to the view * as a `` element. * * @extends module:core/plugin~Plugin */ class SubscriptEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'SubscriptEditing'; } /** * @inheritDoc */ init() { const editor = this.editor; // Allow sub attribute on text nodes. editor.model.schema.extend( '$text', { allowAttributes: SUBSCRIPT } ); editor.model.schema.setAttributeProperties( SUBSCRIPT, { isFormatting: true, copyOnEnter: true } ); // Build converter from model to view for data and editing pipelines. editor.conversion.attributeToElement( { model: SUBSCRIPT, view: 'sub', upcastAlso: [ { styles: { 'vertical-align': 'sub' } } ] } ); // Create sub command. editor.commands.add( SUBSCRIPT, new _attributecommand__WEBPACK_IMPORTED_MODULE_1__["default"]( editor, SUBSCRIPT ) ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptui.js": /*!************************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptui.js ***! \************************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return SubscriptUI; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); /* harmony import */ var _theme_icons_subscript_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../theme/icons/subscript.svg */ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/subscript.svg"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/subscript/subscriptui */ const SUBSCRIPT = 'subscript'; /** * The subscript UI feature. It introduces the Subscript button. * * @extends module:core/plugin~Plugin */ class SubscriptUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'SubscriptUI'; } /** * @inheritDoc */ init() { const editor = this.editor; const t = editor.t; // Add subscript button to feature components. editor.ui.componentFactory.add( SUBSCRIPT, locale => { const command = editor.commands.get( SUBSCRIPT ); const view = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__["ButtonView"]( locale ); view.set( { label: t( 'Subscript' ), icon: _theme_icons_subscript_svg__WEBPACK_IMPORTED_MODULE_2__["default"], tooltip: true, isToggleable: true } ); view.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' ); // Execute command. this.listenTo( view, 'execute', () => { editor.execute( SUBSCRIPT ); editor.editing.view.focus(); } ); return view; } ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript.js": /*!**************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript.js ***! \**************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Superscript; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _superscript_superscriptediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./superscript/superscriptediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptediting.js"); /* harmony import */ var _superscript_superscriptui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./superscript/superscriptui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptui.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/superscript */ /** * The superscript feature. * * It loads the {@link module:basic-styles/superscript/superscriptediting~SuperscriptEditing} and * {@link module:basic-styles/superscript/superscriptui~SuperscriptUI} plugins. * * @extends module:core/plugin~Plugin */ class Superscript extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get requires() { return [ _superscript_superscriptediting__WEBPACK_IMPORTED_MODULE_1__["default"], _superscript_superscriptui__WEBPACK_IMPORTED_MODULE_2__["default"] ]; } /** * @inheritDoc */ static get pluginName() { return 'Superscript'; } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptediting.js": /*!*********************************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptediting.js ***! \*********************************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return SuperscriptEditing; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/superscript/superscriptediting */ const SUPERSCRIPT = 'superscript'; /** * The superscript editing feature. * * It registers the `super` command and introduces the `super` attribute in the model which renders to the view * as a `` element. * * @extends module:core/plugin~Plugin */ class SuperscriptEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'SuperscriptEditing'; } /** * @inheritDoc */ init() { const editor = this.editor; // Allow super attribute on text nodes. editor.model.schema.extend( '$text', { allowAttributes: SUPERSCRIPT } ); editor.model.schema.setAttributeProperties( SUPERSCRIPT, { isFormatting: true, copyOnEnter: true } ); // Build converter from model to view for data and editing pipelines. editor.conversion.attributeToElement( { model: SUPERSCRIPT, view: 'sup', upcastAlso: [ { styles: { 'vertical-align': 'super' } } ] } ); // Create super command. editor.commands.add( SUPERSCRIPT, new _attributecommand__WEBPACK_IMPORTED_MODULE_1__["default"]( editor, SUPERSCRIPT ) ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptui.js": /*!****************************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptui.js ***! \****************************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return SuperscriptUI; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); /* harmony import */ var _theme_icons_superscript_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../theme/icons/superscript.svg */ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/superscript.svg"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/superscript/superscriptui */ const SUPERSCRIPT = 'superscript'; /** * The superscript UI feature. It introduces the Superscript button. * * @extends module:core/plugin~Plugin */ class SuperscriptUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'SuperscriptUI'; } /** * @inheritDoc */ init() { const editor = this.editor; const t = editor.t; // Add superscript button to feature components. editor.ui.componentFactory.add( SUPERSCRIPT, locale => { const command = editor.commands.get( SUPERSCRIPT ); const view = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__["ButtonView"]( locale ); view.set( { label: t( 'Superscript' ), icon: _theme_icons_superscript_svg__WEBPACK_IMPORTED_MODULE_2__["default"], tooltip: true, isToggleable: true } ); view.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' ); // Execute command. this.listenTo( view, 'execute', () => { editor.execute( SUPERSCRIPT ); editor.editing.view.focus(); } ); return view; } ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline.js": /*!************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline.js ***! \************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Underline; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _underline_underlineediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./underline/underlineediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineediting.js"); /* harmony import */ var _underline_underlineui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./underline/underlineui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineui.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/underline */ /** * The underline feature. * * For a detailed overview check the {@glink features/basic-styles Basic styles feature documentation} * and the {@glink api/basic-styles package page}. * * This is a "glue" plugin which loads the {@link module:basic-styles/underline/underlineediting~UnderlineEditing} and * {@link module:basic-styles/underline/underlineui~UnderlineUI} plugins. * * @extends module:core/plugin~Plugin */ class Underline extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get requires() { return [ _underline_underlineediting__WEBPACK_IMPORTED_MODULE_1__["default"], _underline_underlineui__WEBPACK_IMPORTED_MODULE_2__["default"] ]; } /** * @inheritDoc */ static get pluginName() { return 'Underline'; } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineediting.js": /*!*****************************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineediting.js ***! \*****************************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return UnderlineEditing; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/underline/underlineediting */ const UNDERLINE = 'underline'; /** * The underline editing feature. * * It registers the `'underline'` command, the Ctrl+U keystroke * and introduces the `underline` attribute in the model which renders to the view as an `` element. * * @extends module:core/plugin~Plugin */ class UnderlineEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'UnderlineEditing'; } /** * @inheritDoc */ init() { const editor = this.editor; // Allow strikethrough attribute on text nodes. editor.model.schema.extend( '$text', { allowAttributes: UNDERLINE } ); editor.model.schema.setAttributeProperties( UNDERLINE, { isFormatting: true, copyOnEnter: true } ); editor.conversion.attributeToElement( { model: UNDERLINE, view: 'u', upcastAlso: { styles: { 'text-decoration': 'underline' } } } ); // Create underline command. editor.commands.add( UNDERLINE, new _attributecommand__WEBPACK_IMPORTED_MODULE_1__["default"]( editor, UNDERLINE ) ); // Set the Ctrl+U keystroke. editor.keystrokes.set( 'CTRL+U', 'underline' ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineui.js": /*!************************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineui.js ***! \************************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return UnderlineUI; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); /* harmony import */ var _theme_icons_underline_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../theme/icons/underline.svg */ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/underline.svg"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module basic-styles/underline/underlineui */ const UNDERLINE = 'underline'; /** * The underline UI feature. It introduces the Underline button. * * @extends module:core/plugin~Plugin */ class UnderlineUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'UnderlineUI'; } /** * @inheritDoc */ init() { const editor = this.editor; const t = editor.t; // Add bold button to feature components. editor.ui.componentFactory.add( UNDERLINE, locale => { const command = editor.commands.get( UNDERLINE ); const view = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__["ButtonView"]( locale ); view.set( { label: t( 'Underline' ), icon: _theme_icons_underline_svg__WEBPACK_IMPORTED_MODULE_2__["default"], keystroke: 'CTRL+U', tooltip: true, isToggleable: true } ); view.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' ); // Execute command. this.listenTo( view, 'execute', () => { editor.execute( UNDERLINE ); editor.editing.view.focus(); } ); return view; } ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/bold.svg": /*!****************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/bold.svg ***! \****************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony default export */ __webpack_exports__["default"] = (""); /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/italic.svg": /*!******************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/italic.svg ***! \******************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony default export */ __webpack_exports__["default"] = (""); /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/strikethrough.svg": /*!*************************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/strikethrough.svg ***! \*************************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony default export */ __webpack_exports__["default"] = (""); /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/subscript.svg": /*!*********************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/subscript.svg ***! \*********************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony default export */ __webpack_exports__["default"] = (""); /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/superscript.svg": /*!***********************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/superscript.svg ***! \***********************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony default export */ __webpack_exports__["default"] = (""); /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/underline.svg": /*!*********************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/underline.svg ***! \*********************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony default export */ __webpack_exports__["default"] = (""); /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquote.js": /*!************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquote.js ***! \************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return BlockQuote; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _blockquoteediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./blockquoteediting */ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteediting.js"); /* harmony import */ var _blockquoteui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./blockquoteui */ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteui.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module block-quote/blockquote */ /** * The block quote plugin. * * For more information about this feature check the {@glink api/block-quote package page}. * * This is a "glue" plugin which loads the {@link module:block-quote/blockquoteediting~BlockQuoteEditing block quote editing feature} * and {@link module:block-quote/blockquoteui~BlockQuoteUI block quote UI feature}. * * @extends module:core/plugin~Plugin */ class BlockQuote extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get requires() { return [ _blockquoteediting__WEBPACK_IMPORTED_MODULE_1__["default"], _blockquoteui__WEBPACK_IMPORTED_MODULE_2__["default"] ]; } /** * @inheritDoc */ static get pluginName() { return 'BlockQuote'; } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquotecommand.js": /*!*******************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquotecommand.js ***! \*******************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return BlockQuoteCommand; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/utils */ "./node_modules/ckeditor5/src/utils.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module block-quote/blockquotecommand */ /** * The block quote command plugin. * * @extends module:core/command~Command */ class BlockQuoteCommand extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Command"] { /** * Whether the selection starts in a block quote. * * @observable * @readonly * @member {Boolean} #value */ /** * @inheritDoc */ refresh() { this.value = this._getValue(); this.isEnabled = this._checkEnabled(); } /** * Executes the command. When the command {@link #value is on}, all top-most block quotes within * the selection will be removed. If it is off, all selected blocks will be wrapped with * a block quote. * * @fires execute * @param {Object} [options] Command options. * @param {Boolean} [options.forceValue] If set, it will force the command behavior. If `true`, the command will apply a block quote, * otherwise the command will remove the block quote. If not set, the command will act basing on its current value. */ execute( options = {} ) { const model = this.editor.model; const schema = model.schema; const selection = model.document.selection; const blocks = Array.from( selection.getSelectedBlocks() ); const value = ( options.forceValue === undefined ) ? !this.value : options.forceValue; model.change( writer => { if ( !value ) { this._removeQuote( writer, blocks.filter( findQuote ) ); } else { const blocksToQuote = blocks.filter( block => { // Already quoted blocks needs to be considered while quoting too // in order to reuse their elements. return findQuote( block ) || checkCanBeQuoted( schema, block ); } ); this._applyQuote( writer, blocksToQuote ); } } ); } /** * Checks the command's {@link #value}. * * @private * @returns {Boolean} The current value. */ _getValue() { const selection = this.editor.model.document.selection; const firstBlock = Object(ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_1__["first"])( selection.getSelectedBlocks() ); // In the current implementation, the block quote must be an immediate parent of a block element. return !!( firstBlock && findQuote( firstBlock ) ); } /** * Checks whether the command can be enabled in the current context. * * @private * @returns {Boolean} Whether the command should be enabled. */ _checkEnabled() { if ( this.value ) { return true; } const selection = this.editor.model.document.selection; const schema = this.editor.model.schema; const firstBlock = Object(ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_1__["first"])( selection.getSelectedBlocks() ); if ( !firstBlock ) { return false; } return checkCanBeQuoted( schema, firstBlock ); } /** * Removes the quote from given blocks. * * If blocks which are supposed to be "unquoted" are in the middle of a quote, * start it or end it, then the quote will be split (if needed) and the blocks * will be moved out of it, so other quoted blocks remained quoted. * * @private * @param {module:engine/model/writer~Writer} writer * @param {Array.} blocks */ _removeQuote( writer, blocks ) { // Unquote all groups of block. Iterate in the reverse order to not break following ranges. getRangesOfBlockGroups( writer, blocks ).reverse().forEach( groupRange => { if ( groupRange.start.isAtStart && groupRange.end.isAtEnd ) { writer.unwrap( groupRange.start.parent ); return; } // The group of blocks are at the beginning of an so let's move them left (out of the ). if ( groupRange.start.isAtStart ) { const positionBefore = writer.createPositionBefore( groupRange.start.parent ); writer.move( groupRange, positionBefore ); return; } // The blocks are in the middle of an so we need to split the after the last block // so we move the items there. if ( !groupRange.end.isAtEnd ) { writer.split( groupRange.end ); } // Now we are sure that groupRange.end.isAtEnd is true, so let's move the blocks right. const positionAfter = writer.createPositionAfter( groupRange.end.parent ); writer.move( groupRange, positionAfter ); } ); } /** * Applies the quote to given blocks. * * @private * @param {module:engine/model/writer~Writer} writer * @param {Array.} blocks */ _applyQuote( writer, blocks ) { const quotesToMerge = []; // Quote all groups of block. Iterate in the reverse order to not break following ranges. getRangesOfBlockGroups( writer, blocks ).reverse().forEach( groupRange => { let quote = findQuote( groupRange.start ); if ( !quote ) { quote = writer.createElement( 'blockQuote' ); writer.wrap( groupRange, quote ); } quotesToMerge.push( quote ); } ); // Merge subsequent elements. Reverse the order again because this time we want to go through // the elements in the source order (due to how merge works – it moves the right element's content // to the first element and removes the right one. Since we may need to merge a couple of subsequent `` elements // we want to keep the reference to the first (furthest left) one. quotesToMerge.reverse().reduce( ( currentQuote, nextQuote ) => { if ( currentQuote.nextSibling == nextQuote ) { writer.merge( writer.createPositionAfter( currentQuote ) ); return currentQuote; } return nextQuote; } ); } } function findQuote( elementOrPosition ) { return elementOrPosition.parent.name == 'blockQuote' ? elementOrPosition.parent : null; } // Returns a minimal array of ranges containing groups of subsequent blocks. // // content: abcdefgh // blocks: [ a, b, d, f, g, h ] // output ranges: [ab]c[d]e[fgh] // // @param {Array.} blocks // @returns {Array.} function getRangesOfBlockGroups( writer, blocks ) { let startPosition; let i = 0; const ranges = []; while ( i < blocks.length ) { const block = blocks[ i ]; const nextBlock = blocks[ i + 1 ]; if ( !startPosition ) { startPosition = writer.createPositionBefore( block ); } if ( !nextBlock || block.nextSibling != nextBlock ) { ranges.push( writer.createRange( startPosition, writer.createPositionAfter( block ) ) ); startPosition = null; } i++; } return ranges; } // Checks whether can wrap the block. function checkCanBeQuoted( schema, block ) { // TMP will be replaced with schema.checkWrap(). const isBQAllowed = schema.checkChild( block.parent, 'blockQuote' ); const isBlockAllowedInBQ = schema.checkChild( [ '$root', 'blockQuote' ], block ); return isBQAllowed && isBlockAllowedInBQ; } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteediting.js": /*!*******************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteediting.js ***! \*******************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return BlockQuoteEditing; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var ckeditor5_src_enter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/enter */ "./node_modules/ckeditor5/src/enter.js"); /* harmony import */ var ckeditor5_src_typing__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ckeditor5/src/typing */ "./node_modules/ckeditor5/src/typing.js"); /* harmony import */ var _blockquotecommand__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./blockquotecommand */ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquotecommand.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module block-quote/blockquoteediting */ /** * The block quote editing. * * Introduces the `'blockQuote'` command and the `'blockQuote'` model element. * * @extends module:core/plugin~Plugin */ class BlockQuoteEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'BlockQuoteEditing'; } /** * @inheritDoc */ static get requires() { return [ ckeditor5_src_enter__WEBPACK_IMPORTED_MODULE_1__["Enter"], ckeditor5_src_typing__WEBPACK_IMPORTED_MODULE_2__["Delete"] ]; } /** * @inheritDoc */ init() { const editor = this.editor; const schema = editor.model.schema; editor.commands.add( 'blockQuote', new _blockquotecommand__WEBPACK_IMPORTED_MODULE_3__["default"]( editor ) ); schema.register( 'blockQuote', { allowWhere: '$block', allowContentOf: '$root' } ); editor.conversion.elementToElement( { model: 'blockQuote', view: 'blockquote' } ); // Postfixer which cleans incorrect model states connected with block quotes. editor.model.document.registerPostFixer( writer => { const changes = editor.model.document.differ.getChanges(); for ( const entry of changes ) { if ( entry.type == 'insert' ) { const element = entry.position.nodeAfter; if ( !element ) { // We are inside a text node. continue; } if ( element.is( 'element', 'blockQuote' ) && element.isEmpty ) { // Added an empty blockQuote - remove it. writer.remove( element ); return true; } else if ( element.is( 'element', 'blockQuote' ) && !schema.checkChild( entry.position, element ) ) { // Added a blockQuote in incorrect place. Unwrap it so the content inside is not lost. writer.unwrap( element ); return true; } else if ( element.is( 'element' ) ) { // Just added an element. Check that all children meet the scheme rules. const range = writer.createRangeIn( element ); for ( const child of range.getItems() ) { if ( child.is( 'element', 'blockQuote' ) && !schema.checkChild( writer.createPositionBefore( child ), child ) ) { writer.unwrap( child ); return true; } } } } else if ( entry.type == 'remove' ) { const parent = entry.position.parent; if ( parent.is( 'element', 'blockQuote' ) && parent.isEmpty ) { // Something got removed and now blockQuote is empty. Remove the blockQuote as well. writer.remove( parent ); return true; } } } return false; } ); const viewDocument = this.editor.editing.view.document; const selection = editor.model.document.selection; const blockQuoteCommand = editor.commands.get( 'blockQuote' ); // Overwrite default Enter key behavior. // If Enter key is pressed with selection collapsed in empty block inside a quote, break the quote. this.listenTo( viewDocument, 'enter', ( evt, data ) => { if ( !selection.isCollapsed || !blockQuoteCommand.value ) { return; } const positionParent = selection.getLastPosition().parent; if ( positionParent.isEmpty ) { editor.execute( 'blockQuote' ); editor.editing.view.scrollToTheSelection(); data.preventDefault(); evt.stop(); } }, { context: 'blockquote' } ); // Overwrite default Backspace key behavior. // If Backspace key is pressed with selection collapsed in first empty block inside a quote, break the quote. this.listenTo( viewDocument, 'delete', ( evt, data ) => { if ( data.direction != 'backward' || !selection.isCollapsed || !blockQuoteCommand.value ) { return; } const positionParent = selection.getLastPosition().parent; if ( positionParent.isEmpty && !positionParent.previousSibling ) { editor.execute( 'blockQuote' ); editor.editing.view.scrollToTheSelection(); data.preventDefault(); evt.stop(); } }, { context: 'blockquote' } ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteui.js": /*!**************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteui.js ***! \**************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return BlockQuoteUI; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); /* harmony import */ var _theme_blockquote_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../theme/blockquote.css */ "./node_modules/@ckeditor/ckeditor5-block-quote/theme/blockquote.css"); /* harmony import */ var _theme_blockquote_css__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_theme_blockquote_css__WEBPACK_IMPORTED_MODULE_2__); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module block-quote/blockquoteui */ /** * The block quote UI plugin. * * It introduces the `'blockQuote'` button. * * @extends module:core/plugin~Plugin */ class BlockQuoteUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'BlockQuoteUI'; } /** * @inheritDoc */ init() { const editor = this.editor; const t = editor.t; editor.ui.componentFactory.add( 'blockQuote', locale => { const command = editor.commands.get( 'blockQuote' ); const buttonView = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__["ButtonView"]( locale ); buttonView.set( { label: t( 'Block quote' ), icon: ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["icons"].quote, tooltip: true, isToggleable: true } ); // Bind button model to command. buttonView.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' ); // Execute command. this.listenTo( buttonView, 'execute', () => { editor.execute( 'blockQuote' ); editor.editing.view.focus(); } ); return buttonView; } ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-block-quote/theme/blockquote.css": /*!***************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-block-quote/theme/blockquote.css ***! \***************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var api = __webpack_require__(/*! ../../../style-loader/dist/runtime/injectStylesIntoStyleTag.js */ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js"); var content = __webpack_require__(/*! !../../../postcss-loader/src??ref--5-1!./blockquote.css */ "./node_modules/postcss-loader/src/index.js?!./node_modules/@ckeditor/ckeditor5-block-quote/theme/blockquote.css"); content = content.__esModule ? content.default : content; if (typeof content === 'string') { content = [[module.i, content, '']]; } var options = {"injectType":"singletonStyleTag","attributes":{"data-cke":true}}; options.insert = "head"; options.singleton = true; var update = api(content, options); module.exports = content.locals || {}; /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-ckfinder/src/ckfinder.js": /*!*******************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-ckfinder/src/ckfinder.js ***! \*******************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CKFinder; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var _ckfinderui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ckfinderui */ "./node_modules/@ckeditor/ckeditor5-ckfinder/src/ckfinderui.js"); /* harmony import */ var _ckfinderediting__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ckfinderediting */ "./node_modules/@ckeditor/ckeditor5-ckfinder/src/ckfinderediting.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module ckfinder/ckfinder */ /** * The CKFinder feature, a bridge between the CKEditor 5 WYSIWYG editor and the * [CKFinder](https://ckeditor.com/ckfinder) file manager and uploader. * * This is a "glue" plugin which enables: * * * {@link module:ckfinder/ckfinderediting~CKFinderEditing}, * * {@link module:ckfinder/ckfinderui~CKFinderUI}, * * {@link module:adapter-ckfinder/uploadadapter~CKFinderUploadAdapter}. * * See the {@glink features/image-upload/ckfinder "CKFinder integration" guide} to learn how to configure * and use this feature. * * Check out the {@glink features/image-upload/image-upload comprehensive "Image upload" guide} to learn about * other ways to upload images into CKEditor 5. * * @extends module:core/plugin~Plugin */ class CKFinder extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'CKFinder'; } /** * @inheritDoc */ static get requires() { return [ 'Image', 'Link', 'CKFinderUploadAdapter', _ckfinderediting__WEBPACK_IMPORTED_MODULE_2__["default"], _ckfinderui__WEBPACK_IMPORTED_MODULE_1__["default"] ]; } } /** * The configuration of the {@link module:ckfinder/ckfinder~CKFinder CKFinder feature}. * * Read more in {@link module:ckfinder/ckfinder~CKFinderConfig}. * * @member {module:ckfinder/ckfinder~CKFinderConfig} module:core/editor/editorconfig~EditorConfig#ckfinder */ /** * The configuration of the {@link module:ckfinder/ckfinder~CKFinder CKFinder feature} * and its {@link module:adapter-ckfinder/uploadadapter~CKFinderUploadAdapter upload adapter}. * * ClassicEditor * .create( editorElement, { * ckfinder: { * options: { * resourceType: 'Images' * } * } * } ) * .then( ... ) * .catch( ... ); * * See {@link module:core/editor/editorconfig~EditorConfig all editor options}. * * @interface CKFinderConfig */ /** * The configuration options passed to the CKFinder file manager instance. * * Check the file manager [documentation](https://ckeditor.com/docs/ckfinder/ckfinder3/#!/api/CKFinder.Config-cfg-language) * for the complete list of options. * * @member {Object} module:ckfinder/ckfinder~CKFinderConfig#options */ /** * The type of the CKFinder opener method. * * Supported types are: * * * `'modal'` – Opens CKFinder in a modal, * * `'popup'` – Opens CKFinder in a new "pop-up" window. * * Defaults to `'modal'`. * * @member {String} module:ckfinder/ckfinder~CKFinderConfig#openerMethod */ /** * The path (URL) to the connector which handles the file upload in CKFinder file manager. * When specified, it enables the automatic upload of resources such as images inserted into the content. * * For instance, to use CKFinder's * [quick upload](https://ckeditor.com/docs/ckfinder/ckfinder3-php/commands.html#command_quick_upload) * command, your can use the following (or similar) path: * * ClassicEditor * .create( editorElement, { * ckfinder: { * uploadUrl: '/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files&responseType=json' * } * } ) * .then( ... ) * .catch( ... ); * * Used by the {@link module:adapter-ckfinder/uploadadapter~CKFinderUploadAdapter upload adapter}. * * @member {String} module:ckfinder/ckfinder~CKFinderConfig#uploadUrl */ /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-ckfinder/src/ckfindercommand.js": /*!**************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-ckfinder/src/ckfindercommand.js ***! \**************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CKFinderCommand; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/utils */ "./node_modules/ckeditor5/src/utils.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /* global window */ /** * @module ckfinder/ckfindercommand */ /** * The CKFinder command. It is used by the {@link module:ckfinder/ckfinderediting~CKFinderEditing CKFinder editing feature} * to open the CKFinder file manager to insert an image or a link to a file into the editor content. * * editor.execute( 'ckfinder' ); * * **Note:** This command uses other features to perform tasks: * - To insert images the {@link module:image/image/insertimagecommand~InsertImageCommand 'insertImage'} command * from the {@link module:image/image~Image Image feature}. * - To insert links to files the {@link module:link/linkcommand~LinkCommand 'link'} command * from the {@link module:link/link~Link Link feature}. * * @extends module:core/command~Command */ class CKFinderCommand extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Command"] { /** * @inheritDoc */ constructor( editor ) { super( editor ); // Remove default document listener to lower its priority. this.stopListening( this.editor.model.document, 'change' ); // Lower this command listener priority to be sure that refresh() will be called after link & image refresh. this.listenTo( this.editor.model.document, 'change', () => this.refresh(), { priority: 'low' } ); } /** * @inheritDoc */ refresh() { const imageCommand = this.editor.commands.get( 'insertImage' ); const linkCommand = this.editor.commands.get( 'link' ); // The CKFinder command is enabled when one of image or link command is enabled. this.isEnabled = imageCommand.isEnabled || linkCommand.isEnabled; } /** * @inheritDoc */ execute() { const editor = this.editor; const openerMethod = this.editor.config.get( 'ckfinder.openerMethod' ) || 'modal'; if ( openerMethod != 'popup' && openerMethod != 'modal' ) { /** * The `ckfinder.openerMethod` must be one of: "popup" or "modal". * * @error ckfinder-unknown-openermethod */ throw new ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_1__["CKEditorError"]( 'ckfinder-unknown-openermethod', editor ); } const options = this.editor.config.get( 'ckfinder.options' ) || {}; options.chooseFiles = true; // Cache the user-defined onInit method const originalOnInit = options.onInit; // Pass the lang code to the CKFinder if not defined by user. if ( !options.language ) { options.language = editor.locale.uiLanguage; } // The onInit method allows to extend CKFinder's behavior. It is used to attach event listeners to file choosing related events. options.onInit = finder => { // Call original options.onInit if it was defined by user. if ( originalOnInit ) { originalOnInit( finder ); } finder.on( 'files:choose', evt => { const files = evt.data.files.toArray(); // Insert links const links = files.filter( file => !file.isImage() ); const images = files.filter( file => file.isImage() ); for ( const linkFile of links ) { editor.execute( 'link', linkFile.getUrl() ); } const imagesUrls = []; for ( const image of images ) { const url = image.getUrl(); imagesUrls.push( url ? url : finder.request( 'file:getProxyUrl', { file: image } ) ); } if ( imagesUrls.length ) { insertImages( editor, imagesUrls ); } } ); finder.on( 'file:choose:resizedImage', evt => { const resizedUrl = evt.data.resizedUrl; if ( !resizedUrl ) { const notification = editor.plugins.get( 'Notification' ); const t = editor.locale.t; notification.showWarning( t( 'Could not obtain resized image URL.' ), { title: t( 'Selecting resized image failed' ), namespace: 'ckfinder' } ); return; } insertImages( editor, [ resizedUrl ] ); } ); }; window.CKFinder[ openerMethod ]( options ); } } function insertImages( editor, urls ) { const imageCommand = editor.commands.get( 'insertImage' ); // Check if inserting an image is actually possible - it might be possible to only insert a link. if ( !imageCommand.isEnabled ) { const notification = editor.plugins.get( 'Notification' ); const t = editor.locale.t; notification.showWarning( t( 'Could not insert image at the current position.' ), { title: t( 'Inserting image failed' ), namespace: 'ckfinder' } ); return; } editor.execute( 'insertImage', { source: urls } ); } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-ckfinder/src/ckfinderediting.js": /*!**************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-ckfinder/src/ckfinderediting.js ***! \**************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CKFinderEditing; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); /* harmony import */ var _ckfindercommand__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ckfindercommand */ "./node_modules/@ckeditor/ckeditor5-ckfinder/src/ckfindercommand.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module ckfinder/ckfinderediting */ /** * The CKFinder editing feature. It introduces the {@link module:ckfinder/ckfindercommand~CKFinderCommand CKFinder command}. * * @extends module:core/plugin~Plugin */ class CKFinderEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'CKFinderEditing'; } /** * @inheritDoc */ static get requires() { return [ ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__["Notification"], 'ImageEditing', 'LinkEditing' ]; } /** * @inheritDoc */ init() { const editor = this.editor; editor.commands.add( 'ckfinder', new _ckfindercommand__WEBPACK_IMPORTED_MODULE_2__["default"]( editor ) ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-ckfinder/src/ckfinderui.js": /*!*********************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-ckfinder/src/ckfinderui.js ***! \*********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CKFinderUI; }); /* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); /* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); /* harmony import */ var _theme_icons_browse_files_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../theme/icons/browse-files.svg */ "./node_modules/@ckeditor/ckeditor5-ckfinder/theme/icons/browse-files.svg"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module ckfinder/ckfinderui */ /** * The CKFinder UI plugin. It introduces the `'ckfinder'` toolbar button. * * @extends module:core/plugin~Plugin */ class CKFinderUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__["Plugin"] { /** * @inheritDoc */ static get pluginName() { return 'CKFinderUI'; } /** * @inheritDoc */ init() { const editor = this.editor; const componentFactory = editor.ui.componentFactory; const t = editor.t; componentFactory.add( 'ckfinder', locale => { const command = editor.commands.get( 'ckfinder' ); const button = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__["ButtonView"]( locale ); button.set( { label: t( 'Insert image or file' ), icon: _theme_icons_browse_files_svg__WEBPACK_IMPORTED_MODULE_2__["default"], tooltip: true } ); button.bind( 'isEnabled' ).to( command ); button.on( 'execute', () => { editor.execute( 'ckfinder' ); editor.editing.view.focus(); } ); return button; } ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-ckfinder/theme/icons/browse-files.svg": /*!********************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-ckfinder/theme/icons/browse-files.svg ***! \********************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony default export */ __webpack_exports__["default"] = (""); /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboard.js": /*!*********************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboard.js ***! \*********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Clipboard; }); /* harmony import */ var _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core/src/plugin */ "./node_modules/@ckeditor/ckeditor5-core/src/plugin.js"); /* harmony import */ var _clipboardpipeline__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./clipboardpipeline */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.js"); /* harmony import */ var _dragdrop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./dragdrop */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdrop.js"); /* harmony import */ var _pasteplaintext__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./pasteplaintext */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/pasteplaintext.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module clipboard/clipboard */ /** * The clipboard feature. * * Read more about the clipboard integration in the {@glink framework/guides/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} * * @extends module:core/plugin~Plugin */ class Clipboard extends _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @inheritDoc */ static get pluginName() { return 'Clipboard'; } /** * @inheritDoc */ static get requires() { return [ _clipboardpipeline__WEBPACK_IMPORTED_MODULE_1__["default"], _dragdrop__WEBPACK_IMPORTED_MODULE_2__["default"], _pasteplaintext__WEBPACK_IMPORTED_MODULE_3__["default"] ]; } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.js": /*!*****************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.js ***! \*****************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ClipboardObserver; }); /* harmony import */ var _ckeditor_ckeditor5_engine_src_view_observer_domeventobserver__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-engine/src/view/observer/domeventobserver */ "./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/domeventobserver.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_eventinfo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/eventinfo */ "./node_modules/@ckeditor/ckeditor5-utils/src/eventinfo.js"); /* harmony import */ var _datatransfer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./datatransfer */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/datatransfer.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module clipboard/clipboardobserver */ /** * 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). * * @extends module:engine/view/observer/domeventobserver~DomEventObserver */ class ClipboardObserver extends _ckeditor_ckeditor5_engine_src_view_observer_domeventobserver__WEBPACK_IMPORTED_MODULE_0__["default"] { constructor( view ) { super( view ); const viewDocument = this.document; this.domEventType = [ 'paste', 'copy', 'cut', 'drop', 'dragover', 'dragstart', 'dragend', 'dragenter', 'dragleave' ]; 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 _ckeditor_ckeditor5_utils_src_eventinfo__WEBPACK_IMPORTED_MODULE_1__["default"]( viewDocument, type ); viewDocument.fire( eventInfo, { dataTransfer: data.dataTransfer, method: evt.name, targetRanges, target: data.target } ); // 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 evtData = { dataTransfer: new _datatransfer__WEBPACK_IMPORTED_MODULE_2__["default"]( domEvent.clipboardData ? domEvent.clipboardData : domEvent.dataTransfer ) }; 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; } /** * Fired as a continuation of the {@link #event:paste} and {@link #event:drop} events. * * It is a part of the {@glink framework/guides/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 * @event module:engine/view/document~Document#event:clipboardInput * @param {Object} data The event data. * @param {module:clipboard/datatransfer~DataTransfer} data.dataTransfer The data transfer instance. * @param {'paste'|'drop'} method Whether the event was triggered by a paste or drop operation. * @param {module:engine/view/element~Element} target The tree view element representing the target. * @param {Array.} data.targetRanges 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 drop). */ /** * 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 * @event module:engine/view/document~Document#event:dragover * @param {module:clipboard/clipboardobserver~ClipboardEventData} data The event data. */ /** * 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 * @event module:engine/view/document~Document#event:drop * @param {module:clipboard/clipboardobserver~ClipboardEventData} data The event data. * @param {module:engine/view/range~Range} dropRange The position into which the content is dropped. */ /** * 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 * @event module:engine/view/document~Document#event:paste * @param {module:clipboard/clipboardobserver~ClipboardEventData} data The event data. */ /** * 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 * @event module:engine/view/document~Document#event:copy * @param {module:clipboard/clipboardobserver~ClipboardEventData} data The event data. */ /** * 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 * @event module:engine/view/document~Document#event:cut * @param {module:clipboard/clipboardobserver~ClipboardEventData} data The event data. */ /** * 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. * * @class module:clipboard/clipboardobserver~ClipboardEventData * @extends module:engine/view/observer/domeventdata~DomEventData */ /** * The data transfer instance. * * @readonly * @member {module:clipboard/datatransfer~DataTransfer} module:clipboard/clipboardobserver~ClipboardEventData#dataTransfer */ /** * Fired as a continuation of the {@link #event:dragover} event. * * It is a part of the {@glink framework/guides/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 * @event module:engine/view/document~Document#event:dragging * @param {Object} data The event data. * @param {module:clipboard/datatransfer~DataTransfer} data.dataTransfer The data transfer instance. * @param {module:engine/view/element~Element} target The tree view element representing the target. * @param {Array.} data.targetRanges 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). */ /** * 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 * @event module:engine/view/document~Document#event:dragstart * @param {module:clipboard/clipboardobserver~ClipboardEventData} data The event data. */ /** * 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 * @event module:engine/view/document~Document#event:dragend * @param {module:clipboard/clipboardobserver~ClipboardEventData} data The event data. */ /** * 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 * @event module:engine/view/document~Document#event:dragenter * @param {module:clipboard/clipboardobserver~ClipboardEventData} data The event data. */ /** * 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 * @event module:engine/view/document~Document#event:dragleave * @param {module:clipboard/clipboardobserver~ClipboardEventData} data The event data. */ /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.js": /*!*****************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.js ***! \*****************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ClipboardPipeline; }); /* harmony import */ var _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core/src/plugin */ "./node_modules/@ckeditor/ckeditor5-core/src/plugin.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_eventinfo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/eventinfo */ "./node_modules/@ckeditor/ckeditor5-utils/src/eventinfo.js"); /* harmony import */ var _clipboardobserver__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./clipboardobserver */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.js"); /* harmony import */ var _utils_plaintexttohtml__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils/plaintexttohtml */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/plaintexttohtml.js"); /* harmony import */ var _utils_normalizeclipboarddata__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./utils/normalizeclipboarddata */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/normalizeclipboarddata.js"); /* harmony import */ var _utils_viewtoplaintext_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./utils/viewtoplaintext.js */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/viewtoplaintext.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module clipboard/clipboardpipeline */ // 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 converts it to 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/guides/deep-dive/clipboard clipboard deep dive guide}. * * @extends module:core/plugin~Plugin */ class ClipboardPipeline extends _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @inheritDoc */ static get pluginName() { return 'ClipboardPipeline'; } /** * @inheritDoc */ init() { const editor = this.editor; const view = editor.editing.view; view.addObserver( _clipboardobserver__WEBPACK_IMPORTED_MODULE_2__["default"] ); this._setupPasteDrop(); this._setupCopyCut(); } /** * The clipboard paste pipeline. * * @private */ _setupPasteDrop() { const editor = this.editor; const model = editor.model; const view = editor.editing.view; const viewDocument = view.document; // Pasting and dropping is disabled when editor is in the read-only mode. // See: https://github.com/ckeditor/ckeditor5-clipboard/issues/26. this.listenTo( viewDocument, 'clipboardInput', evt => { if ( editor.isReadOnly ) { evt.stop(); } }, { priority: 'highest' } ); this.listenTo( viewDocument, 'clipboardInput', ( evt, data ) => { const dataTransfer = data.dataTransfer; let content = data.content || ''; // Some feature could already inject content in the higher priority event handler (i.e., codeBlock). if ( !content ) { if ( dataTransfer.getData( 'text/html' ) ) { content = Object(_utils_normalizeclipboarddata__WEBPACK_IMPORTED_MODULE_4__["default"])( dataTransfer.getData( 'text/html' ) ); } else if ( dataTransfer.getData( 'text/plain' ) ) { content = Object(_utils_plaintexttohtml__WEBPACK_IMPORTED_MODULE_3__["default"])( dataTransfer.getData( 'text/plain' ) ); } content = this.editor.data.htmlProcessor.toView( content ); } const eventInfo = new _ckeditor_ckeditor5_utils_src_eventinfo__WEBPACK_IMPORTED_MODULE_1__["default"]( 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 = model.insertContent( data.content ); }, { priority: 'low' } ); } /** * The clipboard copy/cut pipeline. * * @private */ _setupCopyCut() { const editor = this.editor; const modelDocument = editor.model.document; const view = editor.editing.view; const viewDocument = view.document; function onCopyCut( evt, data ) { const dataTransfer = data.dataTransfer; data.preventDefault(); const content = editor.data.toView( editor.model.getSelectedContent( modelDocument.selection ) ); viewDocument.fire( 'clipboardOutput', { dataTransfer, content, method: evt.name } ); } this.listenTo( viewDocument, 'copy', onCopyCut, { priority: 'low' } ); this.listenTo( viewDocument, 'cut', ( evt, data ) => { // Cutting is disabled when editor is in the read-only mode. // See: https://github.com/ckeditor/ckeditor5-clipboard/issues/26. if ( editor.isReadOnly ) { data.preventDefault(); } else { onCopyCut( evt, data ); } }, { 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', Object(_utils_viewtoplaintext_js__WEBPACK_IMPORTED_MODULE_5__["default"])( data.content ) ); } if ( data.method == 'cut' ) { editor.model.deleteContent( modelDocument.selection ); } }, { priority: 'low' } ); } } /** * 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/guides/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 * @event module:clipboard/clipboardpipeline~ClipboardPipeline#event:inputTransformation * @param {Object} data The event data. * @param {module:engine/view/documentfragment~DocumentFragment} data.content 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/guides/deep-dive/clipboard clipboard deep dive guide}. * @param {module:clipboard/datatransfer~DataTransfer} data.dataTransfer The data transfer instance. * @param {'paste'|'drop'} data.method Whether the event was triggered by a paste or drop operation. * @param {Array.} data.targetRanges The target drop ranges. */ /** * 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/guides/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 * @event module:clipboard/clipboardpipeline~ClipboardPipeline#event:contentInsertion * @param {Object} data The event data. * @param {module:engine/model/documentfragment~DocumentFragment} data.content The event data. The content to be inserted into the editor. * Read more about the clipboard pipelines in the {@glink framework/guides/deep-dive/clipboard clipboard deep dive guide}. * @param {module:clipboard/datatransfer~DataTransfer} data.dataTransfer The data transfer instance. * @param {'paste'|'drop'} data.method Whether the event was triggered by a paste or drop operation. * @param {Array.} data.targetRanges The target drop ranges. * @param {module:engine/model/range~Range} data.resultRange The result of the `model.insertContent()` call * (inserted by the event handler at a low priority). */ /** * 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/guides/deep-dive/clipboard#output-pipeline clipboard output pipeline}. * * @see module:clipboard/clipboardobserver~ClipboardObserver * @see module:clipboard/clipboardpipeline~ClipboardPipeline * @event module:engine/view/document~Document#event:clipboardOutput * @param {module:clipboard/clipboardpipeline~ClipboardOutputEventData} data The event data. */ /** * The value of the {@link module:engine/view/document~Document#event:clipboardOutput} event. * * @class module:clipboard/clipboardpipeline~ClipboardOutputEventData */ /** * The data transfer instance. * * @readonly * @member {module:clipboard/datatransfer~DataTransfer} module:clipboard/clipboardpipeline~ClipboardOutputEventData#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/guides/deep-dive/clipboard clipboard deep dive guide}. * * @member {module:engine/view/documentfragment~DocumentFragment} module:clipboard/clipboardpipeline~ClipboardOutputEventData#content */ /** * Whether the event was triggered by a copy or cut operation. * * @member {'copy'|'cut'} module:clipboard/clipboardpipeline~ClipboardOutputEventData#method */ /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/datatransfer.js": /*!************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/datatransfer.js ***! \************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return DataTransfer; }); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module clipboard/datatransfer */ /** * A facade over the native [`DataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object. */ class DataTransfer { constructor( nativeDataTransfer ) { /** * The array of files created from the native `DataTransfer#files` or `DataTransfer#items`. * * @readonly * @member {Array.} #files */ this.files = getFiles( nativeDataTransfer ); /** * The native DataTransfer object. * * @private * @member {DataTransfer} #_native */ this._native = nativeDataTransfer; } /** * Returns an array of available native content types. * * @returns {Array.} */ get types() { return this._native.types; } /** * Gets the data from the data transfer by its MIME type. * * dataTransfer.getData( 'text/plain' ); * * @param {String} type The MIME type. E.g. `text/html` or `text/plain`. * @returns {String} */ getData( type ) { return this._native.getData( type ); } /** * Sets the data in the data transfer. * * @param {String} type The MIME type. E.g. `text/html` or `text/plain`. * @param {String} data */ setData( type, data ) { this._native.setData( type, data ); } /** * The effect that is allowed for a drag operation. * * @param {String} value */ set effectAllowed( value ) { this._native.effectAllowed = value; } get effectAllowed() { return this._native.effectAllowed; } /** * The actual drop effect. * * @param {String} value */ set dropEffect( value ) { this._native.dropEffect = value; } get dropEffect() { return this._native.dropEffect; } /** * Whether the dragging operation was canceled. * * @returns {Boolean} */ get isCanceled() { return this._native.dropEffect == 'none' || !!this._native.mozUserCancelled; } } function getFiles( nativeDataTransfer ) { // DataTransfer.files and items are array-like and might not have an iterable interface. const files = nativeDataTransfer.files ? Array.from( nativeDataTransfer.files ) : []; const items = nativeDataTransfer.items ? Array.from( nativeDataTransfer.items ) : []; if ( files.length ) { return files; } // Chrome has empty DataTransfer.files, but allows getting files through the items interface. return items .filter( item => item.kind === 'file' ) .map( item => item.getAsFile() ); } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdrop.js": /*!********************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdrop.js ***! \********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return DragDrop; }); /* harmony import */ var _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core/src/plugin */ "./node_modules/@ckeditor/ckeditor5-core/src/plugin.js"); /* harmony import */ var _ckeditor_ckeditor5_engine_src_model_liverange__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-engine/src/model/liverange */ "./node_modules/@ckeditor/ckeditor5-engine/src/model/liverange.js"); /* harmony import */ var _ckeditor_ckeditor5_engine_src_view_observer_mouseobserver__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @ckeditor/ckeditor5-engine/src/view/observer/mouseobserver */ "./node_modules/@ckeditor/ckeditor5-engine/src/view/observer/mouseobserver.js"); /* harmony import */ var _ckeditor_ckeditor5_widget_src_widget__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @ckeditor/ckeditor5-widget/src/widget */ "./node_modules/@ckeditor/ckeditor5-widget/src/widget.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_uid__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/uid */ "./node_modules/@ckeditor/ckeditor5-utils/src/uid.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_env__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/env */ "./node_modules/@ckeditor/ckeditor5-utils/src/env.js"); /* harmony import */ var _ckeditor_ckeditor5_widget_src_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @ckeditor/ckeditor5-widget/src/utils */ "./node_modules/@ckeditor/ckeditor5-widget/src/utils.js"); /* harmony import */ var _clipboardpipeline__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./clipboardpipeline */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.js"); /* harmony import */ var _clipboardobserver__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./clipboardobserver */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.js"); /* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! lodash-es */ "./node_modules/lodash-es/lodash.js"); /* harmony import */ var _theme_clipboard_css__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../theme/clipboard.css */ "./node_modules/@ckeditor/ckeditor5-clipboard/theme/clipboard.css"); /* harmony import */ var _theme_clipboard_css__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(_theme_clipboard_css__WEBPACK_IMPORTED_MODULE_10__); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module clipboard/dragdrop */ /* globals setTimeout, clearTimeout */ // 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/guides/deep-dive/clipboard clipboard deep dive guide}. * * @extends module:core/plugin~Plugin */ class DragDrop extends _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @inheritDoc */ static get pluginName() { return 'DragDrop'; } /** * @inheritDoc */ static get requires() { return [ _clipboardpipeline__WEBPACK_IMPORTED_MODULE_7__["default"], _ckeditor_ckeditor5_widget_src_widget__WEBPACK_IMPORTED_MODULE_3__["default"] ]; } /** * @inheritDoc */ init() { const editor = this.editor; const view = editor.editing.view; /** * The live range over the original content that is being dragged. * * @private * @type {module:engine/model/liverange~LiveRange} */ this._draggedRange = null; /** * 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 * @type {String} */ this._draggingUid = ''; /** * The reference to the model element that currently has a `draggable` attribute set (it is set while dragging). * * @private * @type {module:engine/model/element~Element} */ this._draggableElement = null; /** * A throttled callback updating the drop marker. * * @private * @type {Function} */ this._updateDropMarkerThrottled = Object(lodash_es__WEBPACK_IMPORTED_MODULE_9__["throttle"])( targetRange => this._updateDropMarker( targetRange ), 40 ); /** * A delayed callback removing the drop marker. * * @private * @type {Function} */ this._removeDropMarkerDelayed = delay( () => this._removeDropMarker(), 40 ); /** * A delayed callback removing draggable attributes. * * @private * @type {Function} */ this._clearDraggableAttributesDelayed = delay( () => this._clearDraggableAttributes(), 40 ); view.addObserver( _clipboardobserver__WEBPACK_IMPORTED_MODULE_8__["default"] ); view.addObserver( _ckeditor_ckeditor5_engine_src_view_observer_mouseobserver__WEBPACK_IMPORTED_MODULE_2__["default"] ); this._setupDragging(); this._setupContentInsertionIntegration(); this._setupClipboardInputIntegration(); this._setupDropMarker(); 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 ( _ckeditor_ckeditor5_utils_src_env__WEBPACK_IMPORTED_MODULE_5__["default"].isAndroid ) { this.forceDisabled( 'noAndroidSupport' ); } } /** * @inheritDoc */ destroy() { if ( this._draggedRange ) { this._draggedRange.detach(); this._draggedRange = null; } this._updateDropMarkerThrottled.cancel(); this._removeDropMarkerDelayed.cancel(); this._clearDraggableAttributesDelayed.cancel(); return super.destroy(); } /** * Drag and drop events handling. * * @private */ _setupDragging() { const editor = this.editor; const model = editor.model; const modelDocument = model.document; const view = editor.editing.view; const viewDocument = view.document; // The handler for the drag start; it is responsible for setting data transfer object. this.listenTo( viewDocument, 'dragstart', ( evt, data ) => { const selection = modelDocument.selection; // Don't drag the editable element itself. if ( data.target && data.target.is( 'editableElement' ) ) { data.preventDefault(); return; } // TODO we could clone this node somewhere and style it to match editing view but without handles, // selection outline, WTA buttons, etc. // data.dataTransfer._native.setDragImage( data.domTarget, 0, 0 ); // Check if this is dragstart over the widget (but not a nested editable). const draggableWidget = data.target ? findDraggableWidget( data.target ) : null; if ( draggableWidget ) { const modelElement = editor.editing.mapper.toModelElement( draggableWidget ); this._draggedRange = _ckeditor_ckeditor5_engine_src_model_liverange__WEBPACK_IMPORTED_MODULE_1__["default"].fromRange( model.createRangeOn( modelElement ) ); } // If this was not a widget we should check if we need to drag some text content. else if ( !viewDocument.selection.isCollapsed ) { const selectedElement = viewDocument.selection.getSelectedElement(); if ( !selectedElement || !Object(_ckeditor_ckeditor5_widget_src_utils__WEBPACK_IMPORTED_MODULE_6__["isWidget"])( selectedElement ) ) { this._draggedRange = _ckeditor_ckeditor5_engine_src_model_liverange__WEBPACK_IMPORTED_MODULE_1__["default"].fromRange( selection.getFirstRange() ); } } if ( !this._draggedRange ) { data.preventDefault(); return; } this._draggingUid = Object(_ckeditor_ckeditor5_utils_src_uid__WEBPACK_IMPORTED_MODULE_4__["default"])(); data.dataTransfer.effectAllowed = this.isEnabled ? 'copyMove' : 'copy'; data.dataTransfer.setData( 'application/ckeditor5-dragging-uid', this._draggingUid ); const draggedSelection = model.createSelection( this._draggedRange.toRange() ); const content = editor.data.toView( model.getSelectedContent( draggedSelection ) ); viewDocument.fire( 'clipboardOutput', { dataTransfer: data.dataTransfer, content, method: evt.name } ); 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' } ); // 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. this._removeDropMarkerDelayed(); } ); // Handler for moving dragged content over the target area. this.listenTo( viewDocument, 'dragging', ( evt, data ) => { if ( !this.isEnabled ) { data.dataTransfer.dropEffect = 'none'; return; } this._removeDropMarkerDelayed.cancel(); const targetRange = findDropTargetRange( editor, data.targetRanges, data.target ); // 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 ( !_ckeditor_ckeditor5_utils_src_env__WEBPACK_IMPORTED_MODULE_5__["default"].isGecko ) { if ( data.dataTransfer.effectAllowed == 'copy' ) { data.dataTransfer.dropEffect = 'copy'; } else if ( [ 'all', 'copyMove' ].includes( data.dataTransfer.effectAllowed ) ) { data.dataTransfer.dropEffect = 'move'; } } /* istanbul ignore else */ if ( targetRange ) { this._updateDropMarkerThrottled( targetRange ); } }, { priority: 'low' } ); } /** * Integration with the `clipboardInput` event. * * @private */ _setupClipboardInputIntegration() { const editor = this.editor; const view = editor.editing.view; const viewDocument = view.document; // Update the event target ranges and abort dropping if dropping over itself. this.listenTo( viewDocument, 'clipboardInput', ( evt, data ) => { if ( data.method != 'drop' ) { return; } const targetRange = findDropTargetRange( editor, data.targetRanges, data.target ); // The dragging markers must be removed after searching for the target range because sometimes // the target lands on the marker itself. this._removeDropMarker(); /* istanbul ignore if */ 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. * * @private */ _setupContentInsertionIntegration() { const clipboardPipeline = this.editor.plugins.get( _clipboardpipeline__WEBPACK_IMPORTED_MODULE_7__["default"] ); 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. * * @private */ _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 ( _ckeditor_ckeditor5_utils_src_env__WEBPACK_IMPORTED_MODULE_5__["default"].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 ( _ckeditor_ckeditor5_utils_src_env__WEBPACK_IMPORTED_MODULE_5__["default"].isBlink && !editor.isReadOnly && !draggableElement && !viewDocument.selection.isCollapsed ) { const selectedElement = viewDocument.selection.getSelectedElement(); if ( !selectedElement || !Object(_ckeditor_ckeditor5_widget_src_utils__WEBPACK_IMPORTED_MODULE_6__["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 ( !_ckeditor_ckeditor5_utils_src_env__WEBPACK_IMPORTED_MODULE_5__["default"].isAndroid ) { this._clearDraggableAttributesDelayed(); } } ); } /** * Removes the `draggable` attribute from the element that was used for dragging. * * @private */ _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; } ); } /** * Creates downcast conversion for the drop target marker. * * @private */ _setupDropMarker() { const editor = this.editor; // 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 drop target. editor.conversion.for( 'editingDowncast' ).markerToElement( { model: 'drop-target', view: ( data, { writer } ) => { const inText = editor.model.schema.checkChild( data.markerRange.start, '$text' ); if ( !inText ) { return; } 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.innerHTML = '⁠⁠'; return domElement; } ); } } ); } /** * Updates the drop target marker to the provided range. * * @private * @param {module:engine/model/range~Range} 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 } ); } } ); } /** * Removes the drop target marker. * * @private */ _removeDropMarker() { const model = this.editor.model; this._removeDropMarkerDelayed.cancel(); this._updateDropMarkerThrottled.cancel(); if ( model.markers.has( 'drop-target' ) ) { model.change( writer => { writer.removeMarker( 'drop-target' ); } ); } } /** * Deletes the dragged content from its original range and clears the dragging state. * * @private * @param {Boolean} moved Whether the move succeeded. */ _finalizeDragging( moved ) { const editor = this.editor; const model = editor.model; this._removeDropMarker(); this._clearDraggableAttributes(); this._draggingUid = ''; if ( !this._draggedRange ) { return; } // Delete moved content. if ( moved && this.isEnabled ) { model.deleteContent( model.createSelection( this._draggedRange ), { doNotAutoparagraph: true } ); } this._draggedRange.detach(); this._draggedRange = null; } } // Returns fixed selection range for given position and target element. // // @param {module:core/editor/editor~Editor} editor // @param {Array.} targetViewRanges // @param {module:engine/view/element~Element} targetViewElement // @returns {module:engine/model/range~Range|null} function findDropTargetRange( editor, targetViewRanges, targetViewElement ) { const model = editor.model; const mapper = editor.editing.mapper; let range = null; const targetViewPosition = targetViewRanges ? targetViewRanges[ 0 ].start : null; // A UIElement is not a valid drop element, use parent (this could be a drop marker or any other UIElement). if ( targetViewElement.is( 'uiElement' ) ) { targetViewElement = targetViewElement.parent; } // Quick win if the target is a widget (but not a nested editable). range = findDropTargetRangeOnWidget( editor, targetViewElement ); if ( range ) { return range; } // The easiest part is over, now we need to move to the model space. // Find target model element and position. const targetModelElement = getClosestMappedModelElement( editor, targetViewElement ); const targetModelPosition = targetViewPosition ? mapper.toModelPosition( targetViewPosition ) : null; // There is no target position while hovering over an empty table cell. // In Safari, target position can be empty while hovering over a widget (e.g., a page-break). // Find the drop position inside the element. if ( !targetModelPosition ) { return findDropTargetRangeInElement( editor, targetModelElement ); } // Check if target position is between blocks and adjust drop position to the next object. // This is because while hovering over a root element next to a widget the target position can jump in crazy places. range = findDropTargetRangeBetweenBlocks( editor, targetModelPosition, targetModelElement ); if ( range ) { return range; } // Try fixing selection position. // In Firefox, the target position lands before widgets but in other browsers it tends to land after a widget. range = model.schema.getNearestSelectionRange( targetModelPosition, _ckeditor_ckeditor5_utils_src_env__WEBPACK_IMPORTED_MODULE_5__["default"].isGecko ? 'forward' : 'backward' ); if ( range ) { return range; } // There is no valid selection position inside the current limit element so find a closest object ancestor. // This happens if the model position lands directly in the element itself (view target element was a `
` // so a nested editable, but view target position was directly in the `
` element). return findDropTargetRangeOnAncestorObject( editor, targetModelPosition.parent ); } // Returns fixed selection range for a given position and a target element if it is over the widget but not over its nested editable. // // @param {module:core/editor/editor~Editor} editor // @param {module:engine/view/element~Element} targetViewElement // @returns {module:engine/model/range~Range|null} function findDropTargetRangeOnWidget( editor, targetViewElement ) { const model = editor.model; const mapper = editor.editing.mapper; // Quick win if the target is a widget. if ( Object(_ckeditor_ckeditor5_widget_src_utils__WEBPACK_IMPORTED_MODULE_6__["isWidget"])( targetViewElement ) ) { return model.createRangeOn( mapper.toModelElement( targetViewElement ) ); } // Check if we are deeper over a widget (but not over a nested editable). if ( !targetViewElement.is( 'editableElement' ) ) { // Find a closest ancestor that is either a widget or an editable element... const ancestor = targetViewElement.findAncestor( node => Object(_ckeditor_ckeditor5_widget_src_utils__WEBPACK_IMPORTED_MODULE_6__["isWidget"])( node ) || node.is( 'editableElement' ) ); // ...and if the widget was closer then it is a drop target. if ( Object(_ckeditor_ckeditor5_widget_src_utils__WEBPACK_IMPORTED_MODULE_6__["isWidget"])( ancestor ) ) { return model.createRangeOn( mapper.toModelElement( ancestor ) ); } } return null; } // Returns fixed selection range inside a model element. // // @param {module:core/editor/editor~Editor} editor // @param {module:engine/model/element~Element} targetModelElement // @returns {module:engine/model/range~Range} function findDropTargetRangeInElement( editor, targetModelElement ) { const model = editor.model; const schema = model.schema; const positionAtElementStart = model.createPositionAt( targetModelElement, 0 ); return schema.getNearestSelectionRange( positionAtElementStart, 'forward' ); } // Returns fixed selection range for a given position and a target element if the drop is between blocks. // // @param {module:core/editor/editor~Editor} editor // @param {module:engine/model/position~Position} targetModelPosition // @param {module:engine/model/element~Element} targetModelElement // @returns {module:engine/model/range~Range|null} function findDropTargetRangeBetweenBlocks( editor, targetModelPosition, targetModelElement ) { const model = editor.model; // Check if target is between blocks. if ( !model.schema.checkChild( targetModelElement, '$block' ) ) { return null; } // Find position between blocks. const positionAtElementStart = model.createPositionAt( targetModelElement, 0 ); // Get the common part of the path (inside the target element and the target position). const commonPath = targetModelPosition.path.slice( 0, positionAtElementStart.path.length ); // Position between the blocks. const betweenBlocksPosition = model.createPositionFromPath( targetModelPosition.root, commonPath ); const nodeAfter = betweenBlocksPosition.nodeAfter; // Adjust drop position to the next object. // This is because while hovering over a root element next to a widget the target position can jump in crazy places. if ( nodeAfter && model.schema.isObject( nodeAfter ) ) { return model.createRangeOn( nodeAfter ); } return null; } // Returns a selection range on the ancestor object. // // @param {module:core/editor/editor~Editor} editor // @param {module:engine/model/element~Element} element // @returns {module:engine/model/range~Range} function findDropTargetRangeOnAncestorObject( editor, element ) { const model = editor.model; while ( element ) { if ( model.schema.isObject( element ) ) { return model.createRangeOn( element ); } element = element.parent; } } // Returns the closest model element for the specified view element. // // @param {module:core/editor/editor~Editor} editor // @param {module:engine/view/element~Element} element // @returns {module:engine/model/element~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 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 ( _ckeditor_ckeditor5_utils_src_env__WEBPACK_IMPORTED_MODULE_5__["default"].isGecko ) { return dataTransfer.dropEffect; } return [ 'all', 'copyMove' ].includes( dataTransfer.effectAllowed ) ? 'move' : 'copy'; } // Returns a function wrapper that will trigger a function after a specified wait time. // The timeout can be canceled by calling the cancel function on the returned wrapped function. // // @param {Function} func The function to wrap. // @param {Number} wait The timeout in ms. // @returns {Function} function delay( func, wait ) { let timer; function delayed( ...args ) { delayed.cancel(); timer = setTimeout( () => func( ...args ), wait ); } delayed.cancel = () => { clearTimeout( timer ); }; return delayed; } // Returns a widget element that should be dragged. // // @param {module:engine/view/element~Element} target // @returns {module:engine/view/element~Element} 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( _ckeditor_ckeditor5_widget_src_utils__WEBPACK_IMPORTED_MODULE_6__["isWidget"] ); } // Direct hit on a widget. if ( Object(_ckeditor_ckeditor5_widget_src_utils__WEBPACK_IMPORTED_MODULE_6__["isWidget"])( target ) ) { return target; } // Find closest ancestor that is either a widget or an editable element... const ancestor = target.findAncestor( node => Object(_ckeditor_ckeditor5_widget_src_utils__WEBPACK_IMPORTED_MODULE_6__["isWidget"])( node ) || node.is( 'editableElement' ) ); // ...and if closer was the widget then enable dragging it. if ( Object(_ckeditor_ckeditor5_widget_src_utils__WEBPACK_IMPORTED_MODULE_6__["isWidget"])( ancestor ) ) { return ancestor; } return null; } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/index.js": /*!*****************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/index.js ***! \*****************************************************************/ /*! exports provided: Clipboard, ClipboardPipeline, DragDrop, PastePlainText */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var _clipboard__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./clipboard */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboard.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Clipboard", function() { return _clipboard__WEBPACK_IMPORTED_MODULE_0__["default"]; }); /* harmony import */ var _clipboardpipeline__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./clipboardpipeline */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ClipboardPipeline", function() { return _clipboardpipeline__WEBPACK_IMPORTED_MODULE_1__["default"]; }); /* harmony import */ var _dragdrop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./dragdrop */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdrop.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DragDrop", function() { return _dragdrop__WEBPACK_IMPORTED_MODULE_2__["default"]; }); /* harmony import */ var _pasteplaintext__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./pasteplaintext */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/pasteplaintext.js"); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PastePlainText", function() { return _pasteplaintext__WEBPACK_IMPORTED_MODULE_3__["default"]; }); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module clipboard */ /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/pasteplaintext.js": /*!**************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/pasteplaintext.js ***! \**************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return PastePlainText; }); /* harmony import */ var _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core/src/plugin */ "./node_modules/@ckeditor/ckeditor5-core/src/plugin.js"); /* harmony import */ var _clipboardobserver__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./clipboardobserver */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.js"); /* harmony import */ var _clipboardpipeline__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./clipboardpipeline */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module clipboard/pasteplaintext */ /** * The plugin detects the user's intention to paste plain text. * * For example, it detects the Ctrl/Cmd + Shift + V keystroke. * * @extends module:core/plugin~Plugin */ class PastePlainText extends _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @inheritDoc */ static get pluginName() { return 'PastePlainText'; } /** * @inheritDoc */ static get requires() { return [ _clipboardpipeline__WEBPACK_IMPORTED_MODULE_2__["default"] ]; } /** * @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__WEBPACK_IMPORTED_MODULE_1__["default"] ); this.listenTo( viewDocument, 'keydown', ( evt, data ) => { shiftPressed = data.shiftKey; } ); editor.plugins.get( _clipboardpipeline__WEBPACK_IMPORTED_MODULE_2__["default"] ).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. // // @param {module:engine/view/documentfragment~DocumentFragment} documentFragment // @param {module:engine/model/schema~Schema} schema // @returns {Boolean} function isPlainTextFragment( documentFragment, schema ) { if ( documentFragment.childCount > 1 ) { return false; } const child = documentFragment.getChild( 0 ); if ( schema.isObject( child ) ) { return false; } return [ ...child.getAttributeKeys() ].length == 0; } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/normalizeclipboarddata.js": /*!****************************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/normalizeclipboarddata.js ***! \****************************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return normalizeClipboardData; }); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. 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). * * @param {String} data The HTML data to normalize. * @returns {String} Normalized HTML. */ function normalizeClipboardData( data ) { return data .replace( /(\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; } ); } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/plaintexttohtml.js": /*!*********************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/plaintexttohtml.js ***! \*********************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return plainTextToHtml; }); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. 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 {String} text The plain text to convert. * @returns {String} HTML generated from the plain text. */ function plainTextToHtml( text ) { text = text // Encode <>. .replace( //g, '>' ) // Creates a paragraph for each double line break. .replace( /\r?\n\r?\n/g, '

' ) // Creates a line break for each single line break. .replace( /\r?\n/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( '

' ) || text.includes( '
' ) ) { // If we created paragraphs above, add the trailing ones. text = `

${ text }

`; } // TODO: // * What about '\nfoo' vs ' foo'? return text; } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/viewtoplaintext.js": /*!*********************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/viewtoplaintext.js ***! \*********************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return viewToPlainText; }); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module clipboard/utils/viewtoplaintext */ // 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 `
  • `) so it is better to separate them by only one "\n". const smallPaddingElements = [ 'figcaption', 'li' ]; /** * Converts {@link module:engine/view/item~Item view item} and all of its children to plain text. * * @param {module:engine/view/item~Item} viewItem View item to convert. * @returns {String} Plain text representation of `viewItem`. */ function viewToPlainText( viewItem ) { let text = ''; if ( viewItem.is( '$text' ) || viewItem.is( '$textProxy' ) ) { // If item is `Text` or `TextProxy` simple take its text data. text = viewItem.data; } else if ( viewItem.is( 'element', 'img' ) && viewItem.hasAttribute( 'alt' ) ) { // Special case for images - use alt attribute if it is provided. text = viewItem.getAttribute( 'alt' ); } else if ( viewItem.is( 'element', 'br' ) ) { // A soft break should be converted into a single line break (#8045). text = '\n'; } else { // Other elements are document fragments, attribute elements or container elements. // They don't have their own text value, so convert their children. let prev = null; for ( const child of viewItem.getChildren() ) { const childText = viewToPlainText( child ); // Separate container element children with one or more new-line characters. if ( prev && ( prev.is( 'containerElement' ) || child.is( 'containerElement' ) ) ) { if ( smallPaddingElements.includes( prev.name ) || smallPaddingElements.includes( child.name ) ) { text += '\n'; } else { text += '\n\n'; } } text += childText; prev = child; } } return text; } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-clipboard/theme/clipboard.css": /*!************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-clipboard/theme/clipboard.css ***! \************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var api = __webpack_require__(/*! ../../../style-loader/dist/runtime/injectStylesIntoStyleTag.js */ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js"); var content = __webpack_require__(/*! !../../../postcss-loader/src??ref--5-1!./clipboard.css */ "./node_modules/postcss-loader/src/index.js?!./node_modules/@ckeditor/ckeditor5-clipboard/theme/clipboard.css"); content = content.__esModule ? content.default : content; if (typeof content === 'string') { content = [[module.i, content, '']]; } var options = {"injectType":"singletonStyleTag","attributes":{"data-cke":true}}; options.insert = "head"; options.singleton = true; var update = api(content, options); module.exports = content.locals || {}; /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-core/src/command.js": /*!**************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-core/src/command.js ***! \**************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Command; }); /* harmony import */ var _ckeditor_ckeditor5_utils_src_observablemixin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/observablemixin */ "./node_modules/@ckeditor/ckeditor5-utils/src/observablemixin.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_mix__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/mix */ "./node_modules/@ckeditor/ckeditor5-utils/src/mix.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module core/command */ /** * The base class for CKEditor commands. * * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other * commands) to make changes in the model. Commands are available in every part of code that has access to * the {@link module:core/editor/editor~Editor editor} instance. * * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}. * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}. * * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode. * * @mixes module:utils/observablemixin~ObservableMixin */ class Command { /** * Creates a new `Command` instance. * * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used. */ constructor( editor ) { /** * The editor on which this command will be used. * * @readonly * @member {module:core/editor/editor~Editor} */ this.editor = editor; /** * The value of the command. A concrete command class should define what it represents for it. * * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text. * And the value of the `'link'` command may be an object with links details. * * It is possible for a command to have no value (e.g. for stateless actions such as `'uploadImage'`). * * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method. * * @observable * @readonly * @member #value */ this.set( 'value', undefined ); /** * Flag indicating whether a command is enabled or disabled. * A disabled command will do nothing when executed. * * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method. * * It is possible to disable a command from "outside". For instance, in your integration you may want to disable * a certain set of commands for the time being. To do that, you can use the fact that `isEnabled` is observable * and it fires the `set:isEnabled` event every time anyone tries to modify its value: * * function disableCommand( cmd ) { * cmd.on( 'set:isEnabled', forceDisable, { priority: 'highest' } ); * * cmd.isEnabled = false; * * // Make it possible to enable the command again. * return () => { * cmd.off( 'set:isEnabled', forceDisable ); * cmd.refresh(); * }; * * function forceDisable( evt ) { * evt.return = false; * evt.stop(); * } * } * * // Usage: * * // Disabling the command. * const enableBold = disableCommand( editor.commands.get( 'bold' ) ); * * // Enabling the command again. * enableBold(); * * @observable * @readonly * @member {Boolean} #isEnabled */ this.set( 'isEnabled', false ); /** * Holds identifiers for {@link #forceDisabled} mechanism. * * @type {Set.} * @private */ this._disableStack = new Set(); this.decorate( 'execute' ); // By default every command is refreshed when changes are applied to the model. this.listenTo( this.editor.model.document, 'change', () => { this.refresh(); } ); this.on( 'execute', evt => { if ( !this.isEnabled ) { evt.stop(); } }, { priority: 'high' } ); // By default commands are disabled when the editor is in read-only mode. this.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => { if ( value ) { this.forceDisabled( 'readOnlyMode' ); } else { this.clearForceDisabled( 'readOnlyMode' ); } } ); } /** * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties * in this method. * * This method is automatically called when * {@link module:engine/model/document~Document#event:change any changes are applied to the document}. */ refresh() { this.isEnabled = true; } /** * Disables the command. * * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command. * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}. * * Disabling and enabling a command: * * command.isEnabled; // -> true * command.forceDisabled( 'MyFeature' ); * command.isEnabled; // -> false * command.clearForceDisabled( 'MyFeature' ); * command.isEnabled; // -> true * * Command disabled by multiple features: * * command.forceDisabled( 'MyFeature' ); * command.forceDisabled( 'OtherFeature' ); * command.clearForceDisabled( 'MyFeature' ); * command.isEnabled; // -> false * command.clearForceDisabled( 'OtherFeature' ); * command.isEnabled; // -> true * * Multiple disabling with the same identifier is redundant: * * command.forceDisabled( 'MyFeature' ); * command.forceDisabled( 'MyFeature' ); * command.clearForceDisabled( 'MyFeature' ); * command.isEnabled; // -> true * * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands, * so the command might be still disabled after {@link #clearForceDisabled} was used. * * @param {String} id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command. */ forceDisabled( id ) { this._disableStack.add( id ); if ( this._disableStack.size == 1 ) { this.on( 'set:isEnabled', forceDisable, { priority: 'highest' } ); this.isEnabled = false; } } /** * Clears forced disable previously set through {@link #forceDisabled}. See {@link #forceDisabled}. * * @param {String} id Unique identifier, equal to the one passed in {@link #forceDisabled} call. */ clearForceDisabled( id ) { this._disableStack.delete( id ); if ( this._disableStack.size == 0 ) { this.off( 'set:isEnabled', forceDisable ); this.refresh(); } } /** * Executes the command. * * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`} * to the command. * * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`). * This behavior is implemented by a high priority listener to the {@link #event:execute} event. * * In order to see how to disable a command from "outside" see the {@link #isEnabled} documentation. * * This method may return a value, which would be forwarded all the way down to the * {@link module:core/editor/editor~Editor#execute `editor.execute()`}. * * @fires execute */ execute() {} /** * Destroys the command. */ destroy() { this.stopListening(); } /** * Event fired by the {@link #execute} method. The command action is a listener to this event so it's * possible to change/cancel the behavior of the command by listening to this event. * * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples. * * **Note:** This event is fired even if command is disabled. However, it is automatically blocked * by a high priority listener in order to prevent command execution. * * @event execute */ } Object(_ckeditor_ckeditor5_utils_src_mix__WEBPACK_IMPORTED_MODULE_1__["default"])( Command, _ckeditor_ckeditor5_utils_src_observablemixin__WEBPACK_IMPORTED_MODULE_0__["default"] ); // Helper function that forces command to be disabled. function forceDisable( evt ) { evt.return = false; evt.stop(); } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-core/src/commandcollection.js": /*!************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-core/src/commandcollection.js ***! \************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CommandCollection; }); /* harmony import */ var _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/ckeditorerror */ "./node_modules/@ckeditor/ckeditor5-utils/src/ckeditorerror.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module core/commandcollection */ /** * Collection of commands. Its instance is available in {@link module:core/editor/editor~Editor#commands `editor.commands`}. */ class CommandCollection { /** * Creates collection instance. */ constructor() { /** * Command map. * * @private * @member {Map} */ this._commands = new Map(); } /** * Registers a new command. * * @param {String} commandName The name of the command. * @param {module:core/command~Command} command */ add( commandName, command ) { this._commands.set( commandName, command ); } /** * Retrieves a command from the collection. * * @param {String} commandName The name of the command. * @returns {module:core/command~Command} */ get( commandName ) { return this._commands.get( commandName ); } /** * Executes a command. * * @param {String} commandName The name of the command. * @param {*} [...commandParams] Command parameters. * @returns {*} The value returned by the {@link module:core/command~Command#execute `command.execute()`}. */ execute( commandName, ...args ) { const command = this.get( commandName ); if ( !command ) { /** * Command does not exist. * * @error commandcollection-command-not-found * @param {String} commandName Name of the command. */ throw new _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_0__["default"]( 'commandcollection-command-not-found', this, { commandName } ); } return command.execute( ...args ); } /** * Returns iterator of command names. * * @returns {Iterable.} */ * names() { yield* this._commands.keys(); } /** * Returns iterator of command instances. * * @returns {Iterable.} */ * commands() { yield* this._commands.values(); } /** * Iterable interface. * * Returns `[ commandName, commandInstance ]` pairs. * * @returns {Iterable.} */ [ Symbol.iterator ]() { return this._commands[ Symbol.iterator ](); } /** * Destroys all collection commands. */ destroy() { for ( const command of this.commands() ) { command.destroy(); } } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-core/src/context.js": /*!**************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-core/src/context.js ***! \**************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Context; }); /* harmony import */ var _ckeditor_ckeditor5_utils_src_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/config */ "./node_modules/@ckeditor/ckeditor5-utils/src/config.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_collection__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/collection */ "./node_modules/@ckeditor/ckeditor5-utils/src/collection.js"); /* harmony import */ var _plugincollection__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./plugincollection */ "./node_modules/@ckeditor/ckeditor5-core/src/plugincollection.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_locale__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/locale */ "./node_modules/@ckeditor/ckeditor5-utils/src/locale.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/ckeditorerror */ "./node_modules/@ckeditor/ckeditor5-utils/src/ckeditorerror.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module core/context */ /** * Provides a common, higher-level environment for solutions that use multiple {@link module:core/editor/editor~Editor editors} * or plugins that work outside the editor. Use it instead of {@link module:core/editor/editor~Editor.create `Editor.create()`} * in advanced application integrations. * * All configuration options passed to a context will be used as default options for editor instances initialized in that context. * * {@link module:core/contextplugin~ContextPlugin Context plugins} passed to a context instance will be shared among all * editor instances initialized in this context. These will be the same plugin instances for all the editors. * * **Note:** The context can only be initialized with {@link module:core/contextplugin~ContextPlugin context plugins} * (e.g. [comments](https://ckeditor.com/collaboration/comments/)). Regular {@link module:core/plugin~Plugin plugins} require an * editor instance to work and cannot be added to a context. * * **Note:** You can add a context plugin to an editor instance, though. * * If you are using multiple editor instances on one page and use any context plugins, create a context to share the configuration and * plugins among these editors. Some plugins will use the information about all existing editors to better integrate between them. * * If you are using plugins that do not require an editor to work (e.g. [comments](https://ckeditor.com/collaboration/comments/)), * enable and configure them using the context. * * If you are using only a single editor on each page, use {@link module:core/editor/editor~Editor.create `Editor.create()`} instead. * In such case, a context instance will be created by the editor instance in a transparent way. * * See {@link module:core/context~Context.create `Context.create()`} for usage examples. */ class Context { /** * Creates a context instance with a given configuration. * * Usually not to be used directly. See the static {@link module:core/context~Context.create `create()`} method. * * @param {Object} [config={}] The context configuration. */ constructor( config ) { /** * Stores all the configurations specific to this context instance. * * @readonly * @type {module:utils/config~Config} */ this.config = new _ckeditor_ckeditor5_utils_src_config__WEBPACK_IMPORTED_MODULE_0__["default"]( config, this.constructor.defaultConfig ); const availablePlugins = this.constructor.builtinPlugins; this.config.define( 'plugins', availablePlugins ); /** * The plugins loaded and in use by this context instance. * * @readonly * @type {module:core/plugincollection~PluginCollection} */ this.plugins = new _plugincollection__WEBPACK_IMPORTED_MODULE_2__["default"]( this, availablePlugins ); const languageConfig = this.config.get( 'language' ) || {}; /** * @readonly * @type {module:utils/locale~Locale} */ this.locale = new _ckeditor_ckeditor5_utils_src_locale__WEBPACK_IMPORTED_MODULE_3__["default"]( { uiLanguage: typeof languageConfig === 'string' ? languageConfig : languageConfig.ui, contentLanguage: this.config.get( 'language.content' ) } ); /** * Shorthand for {@link module:utils/locale~Locale#t}. * * @see module:utils/locale~Locale#t * @method #t */ this.t = this.locale.t; /** * A list of editors that this context instance is injected to. * * @readonly * @type {module:utils/collection~Collection} */ this.editors = new _ckeditor_ckeditor5_utils_src_collection__WEBPACK_IMPORTED_MODULE_1__["default"](); /** * Reference to the editor which created the context. * Null when the context was created outside of the editor. * * It is used to destroy the context when removing the editor that has created the context. * * @private * @type {module:core/editor/editor~Editor|null} */ this._contextOwner = null; } /** * Loads and initializes plugins specified in the configuration. * * @returns {Promise.} A promise which resolves * once the initialization is completed, providing an array of loaded plugins. */ initPlugins() { const plugins = this.config.get( 'plugins' ) || []; const substitutePlugins = this.config.get( 'substitutePlugins' ) || []; // Plugins for substitution should be checked as well. for ( const Plugin of plugins.concat( substitutePlugins ) ) { if ( typeof Plugin != 'function' ) { /** * Only a constructor function is allowed as a {@link module:core/contextplugin~ContextPlugin context plugin}. * * @error context-initplugins-constructor-only */ throw new _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_4__["default"]( 'context-initplugins-constructor-only', null, { Plugin } ); } if ( Plugin.isContextPlugin !== true ) { /** * Only a plugin marked as a {@link module:core/contextplugin~ContextPlugin.isContextPlugin context plugin} * is allowed to be used with a context. * * @error context-initplugins-invalid-plugin */ throw new _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_4__["default"]( 'context-initplugins-invalid-plugin', null, { Plugin } ); } } return this.plugins.init( plugins, [], substitutePlugins ); } /** * Destroys the context instance and all editors used with the context, * releasing all resources used by the context. * * @returns {Promise} A promise that resolves once the context instance is fully destroyed. */ destroy() { return Promise.all( Array.from( this.editors, editor => editor.destroy() ) ) .then( () => this.plugins.destroy() ); } /** * Adds a reference to the editor which is used with this context. * * When the given editor has created the context, the reference to this editor will be stored * as a {@link ~Context#_contextOwner}. * * This method should only be used by the editor. * * @protected * @param {module:core/editor/editor~Editor} editor * @param {Boolean} isContextOwner Stores the given editor as a context owner. */ _addEditor( editor, isContextOwner ) { if ( this._contextOwner ) { /** * Cannot add multiple editors to the context which is created by the editor. * * @error context-addeditor-private-context */ throw new _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_4__["default"]( 'context-addeditor-private-context' ); } this.editors.add( editor ); if ( isContextOwner ) { this._contextOwner = editor; } } /** * Removes a reference to the editor which was used with this context. * When the context was created by the given editor, the context will be destroyed. * * This method should only be used by the editor. * * @protected * @param {module:core/editor/editor~Editor} editor * @return {Promise} A promise that resolves once the editor is removed from the context or when the context was destroyed. */ _removeEditor( editor ) { if ( this.editors.has( editor ) ) { this.editors.remove( editor ); } if ( this._contextOwner === editor ) { return this.destroy(); } return Promise.resolve(); } /** * Returns the context configuration which will be copied to the editors created using this context. * * The configuration returned by this method has the plugins configuration removed — plugins are shared with all editors * through another mechanism. * * This method should only be used by the editor. * * @protected * @returns {Object} Configuration as a plain object. */ _getEditorConfig() { const result = {}; for ( const name of this.config.names() ) { if ( ![ 'plugins', 'removePlugins', 'extraPlugins' ].includes( name ) ) { result[ name ] = this.config.get( name ); } } return result; } /** * Creates and initializes a new context instance. * * const commonConfig = { ... }; // Configuration for all the plugins and editors. * const editorPlugins = [ ... ]; // Regular plugins here. * * Context * .create( { * // Only context plugins here. * plugins: [ ... ], * * // Configure the language for all the editors (it cannot be overwritten). * language: { ... }, * * // Configuration for context plugins. * comments: { ... }, * ... * * // Default configuration for editor plugins. * toolbar: { ... }, * image: { ... }, * ... * } ) * .then( context => { * const promises = []; * * promises.push( ClassicEditor.create( * document.getElementById( 'editor1' ), * { * editorPlugins, * context * } * ) ); * * promises.push( ClassicEditor.create( * document.getElementById( 'editor2' ), * { * editorPlugins, * context, * toolbar: { ... } // You can overwrite the configuration of the context. * } * ) ); * * return Promise.all( promises ); * } ); * * @param {Object} [config] The context configuration. * @returns {Promise} A promise resolved once the context is ready. The promise resolves with the created context instance. */ static create( config ) { return new Promise( resolve => { const context = new this( config ); resolve( context.initPlugins().then( () => context ) ); } ); } } /** * An array of plugins built into the `Context` class. * * It is used in CKEditor 5 builds featuring `Context` to provide a list of context plugins which are later automatically initialized * during the context initialization. * * They will be automatically initialized by `Context` unless `config.plugins` is passed. * * // Build some context plugins into the Context class first. * Context.builtinPlugins = [ FooPlugin, BarPlugin ]; * * // Normally, you need to define config.plugins, but since Context.builtinPlugins was * // defined, now you can call create() without any configuration. * Context * .create() * .then( context => { * context.plugins.get( FooPlugin ); // -> An instance of the Foo plugin. * context.plugins.get( BarPlugin ); // -> An instance of the Bar plugin. * } ); * * See also {@link module:core/context~Context.defaultConfig `Context.defaultConfig`} * and {@link module:core/editor/editor~Editor.builtinPlugins `Editor.builtinPlugins`}. * * @static * @member {Array.} module:core/context~Context.builtinPlugins */ /** * The default configuration which is built into the `Context` class. * * It is used in CKEditor 5 builds featuring `Context` to provide the default configuration options which are later used during the * context initialization. * * Context.defaultConfig = { * foo: 1, * bar: 2 * }; * * Context * .create() * .then( context => { * context.config.get( 'foo' ); // -> 1 * context.config.get( 'bar' ); // -> 2 * } ); * * // The default options can be overridden by the configuration passed to create(). * Context * .create( { bar: 3 } ) * .then( context => { * context.config.get( 'foo' ); // -> 1 * context.config.get( 'bar' ); // -> 3 * } ); * * See also {@link module:core/context~Context.builtinPlugins `Context.builtinPlugins`} * and {@link module:core/editor/editor~Editor.defaultConfig `Editor.defaultConfig`}. * * @static * @member {Object} module:core/context~Context.defaultConfig */ /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-core/src/contextplugin.js": /*!********************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-core/src/contextplugin.js ***! \********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ContextPlugin; }); /* harmony import */ var _ckeditor_ckeditor5_utils_src_observablemixin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/observablemixin */ "./node_modules/@ckeditor/ckeditor5-utils/src/observablemixin.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_mix__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/mix */ "./node_modules/@ckeditor/ckeditor5-utils/src/mix.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module core/contextplugin */ /** * The base class for {@link module:core/context~Context} plugin classes. * * A context plugin can either be initialized for an {@link module:core/editor/editor~Editor editor} or for * a {@link module:core/context~Context context}. In other words, it can either * work within one editor instance or with one or more editor instances that use a single context. * It is the context plugin's role to implement handling for both modes. * * There are a few rules for interaction between the editor plugins and context plugins: * * * A context plugin can require another context plugin. * * An {@link module:core/plugin~Plugin editor plugin} can require a context plugin. * * A context plugin MUST NOT require an {@link module:core/plugin~Plugin editor plugin}. * * @implements module:core/plugin~PluginInterface * @mixes module:utils/observablemixin~ObservableMixin */ class ContextPlugin { /** * Creates a new plugin instance. * * @param {module:core/context~Context|module:core/editor/editor~Editor} context */ constructor( context ) { /** * The context instance. * * @readonly * @type {module:core/context~Context|module:core/editor/editor~Editor} */ this.context = context; } /** * @inheritDoc */ destroy() { this.stopListening(); } /** * @inheritDoc */ static get isContextPlugin() { return true; } } Object(_ckeditor_ckeditor5_utils_src_mix__WEBPACK_IMPORTED_MODULE_1__["default"])( ContextPlugin, _ckeditor_ckeditor5_utils_src_observablemixin__WEBPACK_IMPORTED_MODULE_0__["default"] ); /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-core/src/editingkeystrokehandler.js": /*!******************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-core/src/editingkeystrokehandler.js ***! \******************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return EditingKeystrokeHandler; }); /* harmony import */ var _ckeditor_ckeditor5_utils_src_keystrokehandler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/keystrokehandler */ "./node_modules/@ckeditor/ckeditor5-utils/src/keystrokehandler.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module core/editingkeystrokehandler */ /** * A keystroke handler for editor editing. Its instance is available * in {@link module:core/editor/editor~Editor#keystrokes} so plugins * can register their keystrokes. * * E.g. an undo plugin would do this: * * editor.keystrokes.set( 'Ctrl+Z', 'undo' ); * editor.keystrokes.set( 'Ctrl+Shift+Z', 'redo' ); * editor.keystrokes.set( 'Ctrl+Y', 'redo' ); * * @extends module:utils/keystrokehandler~KeystrokeHandler */ class EditingKeystrokeHandler extends _ckeditor_ckeditor5_utils_src_keystrokehandler__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * Creates an instance of the keystroke handler. * * @param {module:core/editor/editor~Editor} editor */ constructor( editor ) { super(); /** * The editor instance. * * @readonly * @member {module:core/editor/editor~Editor} */ this.editor = editor; } /** * Registers a handler for the specified keystroke. * * The handler can be specified as a command name or a callback. * * @param {String|Array.} keystroke Keystroke defined in a format accepted by * the {@link module:utils/keyboard~parseKeystroke} function. * @param {Function|String} callback If a string is passed, then the keystroke will * {@link module:core/editor/editor~Editor#execute execute a command}. * If a function, then it will be called with the * {@link module:engine/view/observer/keyobserver~KeyEventData key event data} object and * a `cancel()` helper to both `preventDefault()` and `stopPropagation()` of the event. * @param {Object} [options={}] Additional options. * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of the keystroke * callback. The higher the priority value the sooner the callback will be executed. Keystrokes having the same priority * are called in the order they were added. */ set( keystroke, callback, options = {} ) { if ( typeof callback == 'string' ) { const commandName = callback; callback = ( evtData, cancel ) => { this.editor.execute( commandName ); cancel(); }; } super.set( keystroke, callback, options ); } } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor5-core/src/editor/editor.js": /*!********************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-core/src/editor/editor.js ***! \********************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Editor; }); /* harmony import */ var _context__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../context */ "./node_modules/@ckeditor/ckeditor5-core/src/context.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/config */ "./node_modules/@ckeditor/ckeditor5-utils/src/config.js"); /* harmony import */ var _ckeditor_ckeditor5_engine_src_controller_editingcontroller__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @ckeditor/ckeditor5-engine/src/controller/editingcontroller */ "./node_modules/@ckeditor/ckeditor5-engine/src/controller/editingcontroller.js"); /* harmony import */ var _plugincollection__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../plugincollection */ "./node_modules/@ckeditor/ckeditor5-core/src/plugincollection.js"); /* harmony import */ var _commandcollection__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../commandcollection */ "./node_modules/@ckeditor/ckeditor5-core/src/commandcollection.js"); /* harmony import */ var _ckeditor_ckeditor5_engine_src_controller_datacontroller__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @ckeditor/ckeditor5-engine/src/controller/datacontroller */ "./node_modules/@ckeditor/ckeditor5-engine/src/controller/datacontroller.js"); /* harmony import */ var _ckeditor_ckeditor5_engine_src_conversion_conversion__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @ckeditor/ckeditor5-engine/src/conversion/conversion */ "./node_modules/@ckeditor/ckeditor5-engine/src/conversion/conversion.js"); /* harmony import */ var _ckeditor_ckeditor5_engine_src_model_model__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @ckeditor/ckeditor5-engine/src/model/model */ "./node_modules/@ckeditor/ckeditor5-engine/src/model/model.js"); /* harmony import */ var _editingkeystrokehandler__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../editingkeystrokehandler */ "./node_modules/@ckeditor/ckeditor5-core/src/editingkeystrokehandler.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_observablemixin__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/observablemixin */ "./node_modules/@ckeditor/ckeditor5-utils/src/observablemixin.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_mix__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/mix */ "./node_modules/@ckeditor/ckeditor5-utils/src/mix.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/ckeditorerror */ "./node_modules/@ckeditor/ckeditor5-utils/src/ckeditorerror.js"); /* harmony import */ var _ckeditor_ckeditor5_engine_src_view_stylesmap__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @ckeditor/ckeditor5-engine/src/view/stylesmap */ "./node_modules/@ckeditor/ckeditor5-engine/src/view/stylesmap.js"); /** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module core/editor/editor */ /** * The class representing a basic, generic editor. * * Check out the list of its subclasses to learn about specific editor implementations. * * All editor implementations (like {@link module:editor-classic/classiceditor~ClassicEditor} or * {@link module:editor-inline/inlineeditor~InlineEditor}) should extend this class. They can add their * own methods and properties. * * When you are implementing a plugin, this editor represents the API * which your plugin can expect to get when using its {@link module:core/plugin~Plugin#editor} property. * * This API should be sufficient in order to implement the "editing" part of your feature * (schema definition, conversion, commands, keystrokes, etc.). * It does not define the editor UI, which is available only if * the specific editor implements also the {@link module:core/editor/editorwithui~EditorWithUI} interface * (as most editor implementations do). * * @abstract * @mixes module:utils/observablemixin~ObservableMixin */ class Editor { /** * Creates a new instance of the editor class. * * Usually, not to be used directly. See the static {@link module:core/editor/editor~Editor.create `create()`} method. * * @param {Object} [config={}] The editor configuration. */ constructor( config = {} ) { /** * The editor context. * When it is not provided through the configuration, the editor creates it. * * @protected * @type {module:core/context~Context} */ this._context = config.context || new _context__WEBPACK_IMPORTED_MODULE_0__["default"]( { language: config.language } ); this._context._addEditor( this, !config.context ); // Clone the plugins to make sure that the plugin array will not be shared // between editors and make the watchdog feature work correctly. const availablePlugins = Array.from( this.constructor.builtinPlugins || [] ); /** * Stores all configurations specific to this editor instance. * * editor.config.get( 'image.toolbar' ); * // -> [ 'imageStyle:full', 'imageStyle:side', '|', 'imageTextAlternative' ] * * @readonly * @member {module:utils/config~Config} */ this.config = new _ckeditor_ckeditor5_utils_src_config__WEBPACK_IMPORTED_MODULE_1__["default"]( config, this.constructor.defaultConfig ); this.config.define( 'plugins', availablePlugins ); this.config.define( this._context._getEditorConfig() ); /** * The plugins loaded and in use by this editor instance. * * editor.plugins.get( 'ClipboardPipeline' ); // -> An instance of the clipboard pipeline plugin. * * @readonly * @member {module:core/plugincollection~PluginCollection} */ this.plugins = new _plugincollection__WEBPACK_IMPORTED_MODULE_3__["default"]( this, availablePlugins, this._context.plugins ); /** * The locale instance. * * @readonly * @type {module:utils/locale~Locale} */ this.locale = this._context.locale; /** * Shorthand for {@link module:utils/locale~Locale#t}. * * @see module:utils/locale~Locale#t * @method #t */ this.t = this.locale.t; /** * Commands registered to the editor. * * Use the shorthand {@link #execute `editor.execute()`} method to execute commands: * * // Execute the bold command: * editor.execute( 'bold' ); * * // Check the state of the bold command: * editor.commands.get( 'bold' ).value; * * @readonly * @member {module:core/commandcollection~CommandCollection} */ this.commands = new _commandcollection__WEBPACK_IMPORTED_MODULE_4__["default"](); /** * Indicates the editor life-cycle state. * * The editor is in one of the following states: * * * `initializing` – During the editor initialization (before * {@link module:core/editor/editor~Editor.create `Editor.create()`}) finished its job. * * `ready` – After the promise returned by the {@link module:core/editor/editor~Editor.create `Editor.create()`} * method is resolved. * * `destroyed` – Once the {@link #destroy `editor.destroy()`} method was called. * * @observable * @member {'initializing'|'ready'|'destroyed'} #state */ this.set( 'state', 'initializing' ); this.once( 'ready', () => ( this.state = 'ready' ), { priority: 'high' } ); this.once( 'destroy', () => ( this.state = 'destroyed' ), { priority: 'high' } ); /** * Defines whether this editor is in read-only mode. * * In read-only mode the editor {@link #commands commands} are disabled so it is not possible * to modify the document by using them. Also, the editable element(s) become non-editable. * * In order to make the editor read-only, you can set this value directly: * * editor.isReadOnly = true; * * @observable * @member {Boolean} #isReadOnly */ this.set( 'isReadOnly', false ); /** * The editor's model. * * The central point of the editor's abstract data model. * * @readonly * @member {module:engine/model/model~Model} */ this.model = new _ckeditor_ckeditor5_engine_src_model_model__WEBPACK_IMPORTED_MODULE_7__["default"](); const stylesProcessor = new _ckeditor_ckeditor5_engine_src_view_stylesmap__WEBPACK_IMPORTED_MODULE_12__["StylesProcessor"](); /** * The {@link module:engine/controller/datacontroller~DataController data controller}. * Used e.g. for setting and retrieving the editor data. * * @readonly * @member {module:engine/controller/datacontroller~DataController} */ this.data = new _ckeditor_ckeditor5_engine_src_controller_datacontroller__WEBPACK_IMPORTED_MODULE_5__["default"]( this.model, stylesProcessor ); /** * The {@link module:engine/controller/editingcontroller~EditingController editing controller}. * Controls user input and rendering the content for editing. * * @readonly * @member {module:engine/controller/editingcontroller~EditingController} */ this.editing = new _ckeditor_ckeditor5_engine_src_controller_editingcontroller__WEBPACK_IMPORTED_MODULE_2__["default"]( this.model, stylesProcessor ); this.editing.view.document.bind( 'isReadOnly' ).to( this ); /** * Conversion manager through which you can register model-to-view and view-to-model converters. * * See the {@link module:engine/conversion/conversion~Conversion} documentation to learn how to add converters. * * @readonly * @member {module:engine/conversion/conversion~Conversion} */ this.conversion = new _ckeditor_ckeditor5_engine_src_conversion_conversion__WEBPACK_IMPORTED_MODULE_6__["default"]( [ this.editing.downcastDispatcher, this.data.downcastDispatcher ], this.data.upcastDispatcher ); this.conversion.addAlias( 'dataDowncast', this.data.downcastDispatcher ); this.conversion.addAlias( 'editingDowncast', this.editing.downcastDispatcher ); /** * An instance of the {@link module:core/editingkeystrokehandler~EditingKeystrokeHandler}. * * It allows setting simple keystrokes: * * // Execute the bold command on Ctrl+E: * editor.keystrokes.set( 'Ctrl+E', 'bold' ); * * // Execute your own callback: * editor.keystrokes.set( 'Ctrl+E', ( data, cancel ) => { * console.log( data.keyCode ); * * // Prevent the default (native) action and stop the underlying keydown event * // so no other editor feature will interfere. * cancel(); * } ); * * Note: Certain typing-oriented keystrokes (like Backspace or Enter) are handled * by a low-level mechanism and trying to listen to them via the keystroke handler will not work reliably. * To handle these specific keystrokes, see the events fired by the * {@link module:engine/view/document~Document editing view document} (`editor.editing.view.document`). * * @readonly * @member {module:core/editingkeystrokehandler~EditingKeystrokeHandler} */ this.keystrokes = new _editingkeystrokehandler__WEBPACK_IMPORTED_MODULE_8__["default"]( this ); this.keystrokes.listenTo( this.editing.view.document ); } /** * Loads and initializes plugins specified in the configuration. * * @returns {Promise.} A promise which resolves * once the initialization is completed, providing an array of loaded plugins. */ initPlugins() { const config = this.config; const plugins = config.get( 'plugins' ); const removePlugins = config.get( 'removePlugins' ) || []; const extraPlugins = config.get( 'extraPlugins' ) || []; const substitutePlugins = config.get( 'substitutePlugins' ) || []; return this.plugins.init( plugins.concat( extraPlugins ), removePlugins, substitutePlugins ); } /** * Destroys the editor instance, releasing all resources used by it. * * **Note** The editor cannot be destroyed during the initialization phase so if it is called * while the editor {@link #state is being initialized}, it will wait for the editor initialization before destroying it. * * @fires destroy * @returns {Promise} A promise that resolves once the editor instance is fully destroyed. */ destroy() { let readyPromise = Promise.resolve(); if ( this.state == 'initializing' ) { readyPromise = new Promise( resolve => this.once( 'ready', resolve ) ); } return readyPromise .then( () => { this.fire( 'destroy' ); this.stopListening(); this.commands.destroy(); } ) .then( () => this.plugins.destroy() ) .then( () => { this.model.destroy(); this.data.destroy(); this.editing.destroy(); this.keystrokes.destroy(); } ) // Remove the editor from the context. // When the context was created by this editor, the context will be destroyed. .then( () => this._context._removeEditor( this ) ); } /** * Executes the specified command with given parameters. * * Shorthand for: * * editor.commands.get( commandName ).execute( ... ); * * @param {String} commandName The name of the command to execute. * @param {*} [...commandParams] Command parameters. * @returns {*} The value returned by the {@link module:core/commandcollection~CommandCollection#execute `commands.execute()`}. */ execute( ...args ) { try { return this.commands.execute( ...args ); } catch ( err ) { // @if CK_DEBUG // throw err; /* istanbul ignore next */ _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_11__["default"].rethrowUnexpectedError( err, this ); } } /** * Focuses the editor. * * **Note** To explicitly focus the editing area of the editor, use the * {@link module:engine/view/view~View#focus `editor.editing.view.focus()`} method of the editing view. * * Check out the {@glink framework/guides/deep-dive/ui/focus-tracking#focus-in-the-editor-ui Focus in the editor UI} section * of the {@glink framework/guides/deep-dive/ui/focus-tracking Deep dive into focus tracking} guide to learn more. */ focus() { this.editing.view.focus(); } /** * Creates and initializes a new editor instance. * * This is an abstract method. Every editor type needs to implement its own initialization logic. * * See the `create()` methods of the existing editor types to learn how to use them: * * * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`} * * {@link module:editor-balloon/ballooneditor~BalloonEditor.create `BalloonEditor.create()`} * * {@link module:editor-decoupled/decouplededitor~DecoupledEditor.create `DecoupledEditor.create()`} * * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`} * * @abstract * @method module:core/editor/editor~Editor.create */ } Object(_ckeditor_ckeditor5_utils_src_mix__WEBPACK_IMPORTED_MODULE_10__["default"])( Editor, _ckeditor_ckeditor5_utils_src_observablemixin__WEBPACK_IMPORTED_MODULE_9__["default"] ); /** * Fired when the {@link module:engine/controller/datacontroller~DataController#event:ready data} and all additional * editor components are ready. * * Note: This event is most useful for plugin developers. When integrating the editor with your website or * application, you do not have to listen to `editor#ready` because when the promise returned by the static * {@link module:core/editor/editor~Editor.create `Editor.create()`} event is resolved, the editor is already ready. * In fact, since the first moment when the editor instance is available to you is inside `then()`'s callback, * you cannot even add a listener to the `editor#ready` event. * * See also the {@link #state `editor.state`} property. * * @event ready */ /** * Fired when this editor instance is destroyed. The editor at this point is not usable and this event should be used to * perform the clean-up in any plugin. * * * See also the {@link #state `editor.state`} property. * * @event destroy */ /** * This error is thrown when trying to pass a `