/*! * @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 link":"Edit link","Editor toolbar":"Editor toolbar","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","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 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","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",Previous:"Previous",Purple:"Purple",Red:"Red",Redo:"Redo","Remove color":"Remove color","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","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/ckeditor-cloud-services-core/src/token/token.js": /*!********************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor-cloud-services-core/src/token/token.js ***! \********************************************************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var _ckeditor_ckeditor5_utils_src_mix__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/mix */ "./node_modules/@ckeditor/ckeditor5-utils/src/mix.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_observablemixin__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/observablemixin */ "./node_modules/@ckeditor/ckeditor5-utils/src/observablemixin.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/ckeditorerror */ "./node_modules/@ckeditor/ckeditor5-utils/src/ckeditorerror.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module cloud-services-core/token */ /* globals XMLHttpRequest, setTimeout, clearTimeout, atob */ const DEFAULT_OPTIONS = { autoRefresh: true }; const DEFAULT_TOKEN_REFRESH_TIMEOUT_TIME = 3600000; /** * Class representing the token used for communication with CKEditor Cloud Services. * Value of the token is retrieving from the specified URL and is refreshed every 1 hour by default. * * @mixes ObservableMixin */ class Token { /** * Creates `Token` instance. * Method `init` should be called after using the constructor or use `create` method instead. * * @param {String|Function} tokenUrlOrRefreshToken Endpoint address to download the token or a callback that provides the token. If the * value is a function it has to match the {@link module:cloud-services-core/token~refreshToken} interface. * @param {Object} options * @param {String} [options.initValue] Initial value of the token. * @param {Boolean} [options.autoRefresh=true] Specifies whether to start the refresh automatically. */ constructor( tokenUrlOrRefreshToken, options = DEFAULT_OPTIONS ) { if ( !tokenUrlOrRefreshToken ) { /** * A `tokenUrl` must be provided as the first constructor argument. * * @error token-missing-token-url */ throw new _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_2__["default"]( 'token-missing-token-url', this ); } if ( options.initValue ) { this._validateTokenValue( options.initValue ); } /** * Value of the token. * The value of the token is null if `initValue` is not provided or `init` method was not called. * `create` method creates token with initialized value from url. * * @name value * @member {String} #value * @observable * @readonly */ this.set( 'value', options.initValue ); /** * Base refreshing function. * * @private * @member {String|Function} #_refresh */ if ( typeof tokenUrlOrRefreshToken === 'function' ) { this._refresh = tokenUrlOrRefreshToken; } else { this._refresh = () => defaultRefreshToken( tokenUrlOrRefreshToken ); } /** * @type {Object} * @private */ this._options = Object.assign( {}, DEFAULT_OPTIONS, options ); } /** * Initializes the token. * * @returns {Promise.} */ init() { return new Promise( ( resolve, reject ) => { if ( !this.value ) { this.refreshToken() .then( resolve ) .catch( reject ); return; } if ( this._options.autoRefresh ) { this._registerRefreshTokenTimeout(); } resolve( this ); } ); } /** * Refresh token method. Useful in a method form as it can be override in tests. * @returns {Promise.} */ refreshToken() { return this._refresh() .then( value => { this._validateTokenValue( value ); this.set( 'value', value ); if ( this._options.autoRefresh ) { this._registerRefreshTokenTimeout(); } } ) .then( () => this ); } /** * Destroys token instance. Stops refreshing. */ destroy() { clearTimeout( this._tokenRefreshTimeout ); } /** * Checks whether the provided token follows the JSON Web Tokens (JWT) format. * * @protected * @param {String} tokenValue The token to validate. */ _validateTokenValue( tokenValue ) { // The token must be a string. const isString = typeof tokenValue === 'string'; // The token must be a plain string without quotes (""). const isPlainString = !/^".*"$/.test( tokenValue ); // JWT token contains 3 parts: header, payload, and signature. // Each part is separated by a dot. const isJWTFormat = isString && tokenValue.split( '.' ).length === 3; if ( !( isPlainString && isJWTFormat ) ) { /** * The provided token must follow the [JSON Web Tokens](https://jwt.io/introduction/) format. * * @error token-not-in-jwt-format */ throw new _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_2__["default"]( 'token-not-in-jwt-format', this ); } } /** * Registers a refresh token timeout for the time taken from token. * * @protected */ _registerRefreshTokenTimeout() { const tokenRefreshTimeoutTime = this._getTokenRefreshTimeoutTime(); clearTimeout( this._tokenRefreshTimeout ); this._tokenRefreshTimeout = setTimeout( () => { this.refreshToken(); }, tokenRefreshTimeoutTime ); } /** * Returns token refresh timeout time calculated from expire time in the token payload. * * If the token parse fails or the token payload doesn't contain, the default DEFAULT_TOKEN_REFRESH_TIMEOUT_TIME is returned. * * @protected * @returns {Number} */ _getTokenRefreshTimeoutTime() { try { const [ , binaryTokenPayload ] = this.value.split( '.' ); const { exp: tokenExpireTime } = JSON.parse( atob( binaryTokenPayload ) ); if ( !tokenExpireTime ) { return DEFAULT_TOKEN_REFRESH_TIMEOUT_TIME; } const tokenRefreshTimeoutTime = Math.floor( ( ( tokenExpireTime * 1000 ) - Date.now() ) / 2 ); return tokenRefreshTimeoutTime; } catch ( err ) { return DEFAULT_TOKEN_REFRESH_TIMEOUT_TIME; } } /** * Creates a initialized {@link module:cloud-services-core/token~Token} instance. * * @param {String|Function} tokenUrlOrRefreshToken Endpoint address to download the token or a callback that provides the token. If the * value is a function it has to match the {@link module:cloud-services-core/token~refreshToken} interface. * @param {Object} options * @param {String} [options.initValue] Initial value of the token. * @param {Boolean} [options.autoRefresh=true] Specifies whether to start the refresh automatically. * @returns {Promise.} */ static create( tokenUrlOrRefreshToken, options = DEFAULT_OPTIONS ) { const token = new Token( tokenUrlOrRefreshToken, options ); return token.init(); } } Object(_ckeditor_ckeditor5_utils_src_mix__WEBPACK_IMPORTED_MODULE_0__["default"])( Token, _ckeditor_ckeditor5_utils_src_observablemixin__WEBPACK_IMPORTED_MODULE_1__["default"] ); /** * This function is called in a defined interval by the {@link ~Token} class. It also can be invoked manually. * It should return a promise, which resolves with the new token value. * If any error occurs it should return a rejected promise with an error message. * * @function refreshToken * @returns {Promise.} */ /** * @private * @param {String} tokenUrl */ function defaultRefreshToken( tokenUrl ) { return new Promise( ( resolve, reject ) => { const xhr = new XMLHttpRequest(); xhr.open( 'GET', tokenUrl ); xhr.addEventListener( 'load', () => { const statusCode = xhr.status; const xhrResponse = xhr.response; if ( statusCode < 200 || statusCode > 299 ) { /** * Cannot download new token from the provided url. * * @error token-cannot-download-new-token */ return reject( new _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_2__["default"]( 'token-cannot-download-new-token', null ) ); } return resolve( xhrResponse ); } ); xhr.addEventListener( 'error', () => reject( new Error( 'Network Error' ) ) ); xhr.addEventListener( 'abort', () => reject( new Error( 'Abort' ) ) ); xhr.send(); } ); } /* harmony default export */ __webpack_exports__["default"] = (Token); /***/ }), /***/ "./node_modules/@ckeditor/ckeditor-cloud-services-core/src/uploadgateway/fileuploader.js": /*!***********************************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor-cloud-services-core/src/uploadgateway/fileuploader.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 FileUploader; }); /* harmony import */ var _ckeditor_ckeditor5_utils_src_mix__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/mix */ "./node_modules/@ckeditor/ckeditor5-utils/src/mix.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_emittermixin__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/emittermixin */ "./node_modules/@ckeditor/ckeditor5-utils/src/emittermixin.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/ckeditorerror */ "./node_modules/@ckeditor/ckeditor5-utils/src/ckeditorerror.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module cloud-services-core/uploadgateway/fileuploader */ /* globals XMLHttpRequest, FormData, Blob, atob */ const BASE64_HEADER_REG_EXP = /^data:(\S*?);base64,/; /** * FileUploader class used to upload single file. */ class FileUploader { /** * Creates `FileUploader` instance. * * @param {Blob|String} fileOrData A blob object or a data string encoded with Base64. * @param {module:cloud-services-core/token~Token} token Token used for authentication. * @param {String} apiAddress API address. */ constructor( fileOrData, token, apiAddress ) { if ( !fileOrData ) { /** * File must be provided as the first argument. * * @error fileuploader-missing-file */ throw new _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_2__["default"]( 'fileuploader-missing-file', null ); } if ( !token ) { /** * Token must be provided as the second argument. * * @error fileuploader-missing-token */ throw new _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_2__["default"]( 'fileuploader-missing-token', null ); } if ( !apiAddress ) { /** * Api address must be provided as the third argument. * * @error fileuploader-missing-api-address */ throw new _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_2__["default"]( 'fileuploader-missing-api-address', null ); } /** * A file that is being uploaded. * * @type {Blob} */ this.file = _isBase64( fileOrData ) ? _base64ToBlob( fileOrData ) : fileOrData; /** * CKEditor Cloud Services access token. * * @type {module:cloud-services-core/token~Token} * @private */ this._token = token; /** * CKEditor Cloud Services API address. * * @type {String} * @private */ this._apiAddress = apiAddress; } /** * Registers callback on `progress` event. * * @chainable * @param {Function} callback * @returns {module:cloud-services-core/uploadgateway/fileuploader~FileUploader} */ onProgress( callback ) { this.on( 'progress', ( event, data ) => callback( data ) ); return this; } /** * Registers callback on `error` event. Event is called once when error occurs. * * @chainable * @param {Function} callback * @returns {module:cloud-services-core/uploadgateway/fileuploader~FileUploader} */ onError( callback ) { this.once( 'error', ( event, data ) => callback( data ) ); return this; } /** * Aborts upload process. */ abort() { this.xhr.abort(); } /** * Sends XHR request to API. * * @chainable * @returns {Promise.} */ send() { this._prepareRequest(); this._attachXHRListeners(); return this._sendRequest(); } /** * Prepares XHR request. * * @private */ _prepareRequest() { const xhr = new XMLHttpRequest(); xhr.open( 'POST', this._apiAddress ); xhr.setRequestHeader( 'Authorization', this._token.value ); xhr.responseType = 'json'; this.xhr = xhr; } /** * Attaches listeners to the XHR. * * @private */ _attachXHRListeners() { const that = this; const xhr = this.xhr; xhr.addEventListener( 'error', onError( 'Network Error' ) ); xhr.addEventListener( 'abort', onError( 'Abort' ) ); /* istanbul ignore else */ if ( xhr.upload ) { xhr.upload.addEventListener( 'progress', event => { if ( event.lengthComputable ) { this.fire( 'progress', { total: event.total, uploaded: event.loaded } ); } } ); } xhr.addEventListener( 'load', () => { const statusCode = xhr.status; const xhrResponse = xhr.response; if ( statusCode < 200 || statusCode > 299 ) { return this.fire( 'error', xhrResponse.message || xhrResponse.error ); } } ); function onError( message ) { return () => that.fire( 'error', message ); } } /** * Sends XHR request. * * @private */ _sendRequest() { const formData = new FormData(); const xhr = this.xhr; formData.append( 'file', this.file ); return new Promise( ( resolve, reject ) => { xhr.addEventListener( 'load', () => { const statusCode = xhr.status; const xhrResponse = xhr.response; if ( statusCode < 200 || statusCode > 299 ) { if ( xhrResponse.message ) { /** * Uploading file failed. * * @error fileuploader-uploading-data-failed */ return reject( new _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_2__["default"]( 'fileuploader-uploading-data-failed', this, { message: xhrResponse.message } ) ); } return reject( xhrResponse.error ); } return resolve( xhrResponse ); } ); xhr.addEventListener( 'error', () => reject( new Error( 'Network Error' ) ) ); xhr.addEventListener( 'abort', () => reject( new Error( 'Abort' ) ) ); xhr.send( formData ); } ); } /** * Fired when error occurs. * * @event error * @param {String} error Error message */ /** * Fired on upload progress. * * @event progress * @param {Object} status Total and uploaded status */ } Object(_ckeditor_ckeditor5_utils_src_mix__WEBPACK_IMPORTED_MODULE_0__["default"])( FileUploader, _ckeditor_ckeditor5_utils_src_emittermixin__WEBPACK_IMPORTED_MODULE_1__["default"] ); /** * Transforms Base64 string data into file. * * @param {String} base64 String data. * @param {Number} [sliceSize=512] * @returns {Blob} * @private */ function _base64ToBlob( base64, sliceSize = 512 ) { try { const contentType = base64.match( BASE64_HEADER_REG_EXP )[ 1 ]; const base64Data = atob( base64.replace( BASE64_HEADER_REG_EXP, '' ) ); const byteArrays = []; for ( let offset = 0; offset < base64Data.length; offset += sliceSize ) { const slice = base64Data.slice( offset, offset + sliceSize ); const byteNumbers = new Array( slice.length ); for ( let i = 0; i < slice.length; i++ ) { byteNumbers[ i ] = slice.charCodeAt( i ); } byteArrays.push( new Uint8Array( byteNumbers ) ); } return new Blob( byteArrays, { type: contentType } ); } catch ( error ) { /** * Problem with decoding Base64 image data. * * @error fileuploader-decoding-image-data-error */ throw new _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_2__["default"]( 'fileuploader-decoding-image-data-error', null ); } } /** * Checks that string is Base64. * * @param {String} string * @returns {Boolean} * @private */ function _isBase64( string ) { if ( typeof string !== 'string' ) { return false; } const match = string.match( BASE64_HEADER_REG_EXP ); return !!( match && match.length ); } /***/ }), /***/ "./node_modules/@ckeditor/ckeditor-cloud-services-core/src/uploadgateway/uploadgateway.js": /*!************************************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor-cloud-services-core/src/uploadgateway/uploadgateway.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 UploadGateway; }); /* harmony import */ var _fileuploader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./fileuploader */ "./node_modules/@ckeditor/ckeditor-cloud-services-core/src/uploadgateway/fileuploader.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/ckeditorerror */ "./node_modules/@ckeditor/ckeditor5-utils/src/ckeditorerror.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module cloud-services-core/uploadgateway/uploadgateway */ /** * UploadGateway abstracts file uploads to CKEditor Cloud Services. */ class UploadGateway { /** * Creates `UploadGateway` instance. * * @param {module:cloud-services-core/token~Token} token Token used for authentication. * @param {String} apiAddress API address. */ constructor( token, apiAddress ) { if ( !token ) { /** * Token must be provided. * * @error uploadgateway-missing-token */ throw new _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_1__["default"]( 'uploadgateway-missing-token', null ); } if ( !apiAddress ) { /** * Api address must be provided. * * @error uploadgateway-missing-api-address */ throw new _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_1__["default"]( 'uploadgateway-missing-api-address', null ); } /** * CKEditor Cloud Services access token. * * @type {module:cloud-services-core/token~Token} * @private */ this._token = token; /** * CKEditor Cloud Services API address. * * @type {String} * @private */ this._apiAddress = apiAddress; } /** * Creates a {@link module:cloud-services-core/uploadgateway/fileuploader~FileUploader} instance that wraps * file upload process. The file is being sent at a time when the * {@link module:cloud-services-core/uploadgateway/fileuploader~FileUploader#send} method is called. * * const token = await Token.create( 'https://token-endpoint' ); * new UploadGateway( token, 'https://example.org' ) * .upload( 'FILE' ) * .onProgress( ( data ) => console.log( data ) ) * .send() * .then( ( response ) => console.log( response ) ); * * @param {Blob|String} fileOrData A blob object or a data string encoded with Base64. * @returns {module:cloud-services-core/uploadgateway/fileuploader~FileUploader} Returns `FileUploader` instance. */ upload( fileOrData ) { return new _fileuploader__WEBPACK_IMPORTED_MODULE_0__["default"]( fileOrData, this._token, this._apiAddress ); } } /***/ }), /***/ "./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 _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_upload_src_filerepository__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-upload/src/filerepository */ "./node_modules/@ckeditor/ckeditor5-upload/src/filerepository.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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @inheritDoc */ static get requires() { return [ _ckeditor_ckeditor5_upload_src_filerepository__WEBPACK_IMPORTED_MODULE_1__["default"] ]; } /** * @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( _ckeditor_ckeditor5_upload_src_filerepository__WEBPACK_IMPORTED_MODULE_1__["default"] ).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-2020, 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 _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 _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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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( ... ); * * 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 _ckeditor_ckeditor5_core_src_command__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core/src/command */ "./node_modules/@ckeditor/ckeditor5-core/src/command.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_first__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/first */ "./node_modules/@ckeditor/ckeditor5-utils/src/first.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils */ "./node_modules/@ckeditor/ckeditor5-alignment/src/utils.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module alignment/alignmentcommand */ const ALIGNMENT = 'alignment'; /** * The alignment command plugin. * * @extends module:core/command~Command */ class AlignmentCommand extends _ckeditor_ckeditor5_core_src_command__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @inheritDoc */ refresh() { const editor = this.editor; const locale = editor.locale; const firstBlock = Object(_ckeditor_ckeditor5_utils_src_first__WEBPACK_IMPORTED_MODULE_1__["default"])( 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 _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 _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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @inheritDoc */ static get pluginName() { return 'AlignmentEditing'; } /** * @inheritDoc */ constructor( editor ) { super( editor ); editor.config.define( 'alignment', { options: [ ..._utils__WEBPACK_IMPORTED_MODULE_2__["supportedOptions"] ] } ); } /** * @inheritDoc */ init() { const editor = this.editor; const locale = editor.locale; const schema = editor.model.schema; // Filter out unsupported options. const enabledOptions = editor.config.get( 'alignment.options' ).filter( _utils__WEBPACK_IMPORTED_MODULE_2__["isSupported"] ); // Allow alignment attribute on all blocks. schema.extend( '$block', { allowAttributes: 'alignment' } ); editor.model.schema.setAttributeProperties( 'alignment', { isFormatting: true } ); const definition = _buildDefinition( enabledOptions.filter( option => !Object(_utils__WEBPACK_IMPORTED_MODULE_2__["isDefault"])( option, locale ) ) ); editor.conversion.attributeToAttribute( definition ); editor.commands.add( 'alignment', new _alignmentcommand__WEBPACK_IMPORTED_MODULE_1__["default"]( editor ) ); } } // Utility function responsible for building converter definition. // @private function _buildDefinition( options ) { const definition = { model: { key: 'alignment', values: options.slice() }, view: {} }; for ( const option of options ) { definition.view[ option ] = { key: 'style', value: { 'text-align': option } }; } return definition; } /***/ }), /***/ "./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 _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_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-ui/src/button/buttonview */ "./node_modules/@ckeditor/ckeditor5-ui/src/button/buttonview.js"); /* harmony import */ var _ckeditor_ckeditor5_ui_src_dropdown_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @ckeditor/ckeditor5-ui/src/dropdown/utils */ "./node_modules/@ckeditor/ckeditor5-ui/src/dropdown/utils.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils */ "./node_modules/@ckeditor/ckeditor5-alignment/src/utils.js"); /* harmony import */ var _ckeditor_ckeditor5_core_theme_icons_align_left_svg__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @ckeditor/ckeditor5-core/theme/icons/align-left.svg */ "./node_modules/@ckeditor/ckeditor5-core/theme/icons/align-left.svg"); /* harmony import */ var _ckeditor_ckeditor5_core_theme_icons_align_right_svg__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @ckeditor/ckeditor5-core/theme/icons/align-right.svg */ "./node_modules/@ckeditor/ckeditor5-core/theme/icons/align-right.svg"); /* harmony import */ var _ckeditor_ckeditor5_core_theme_icons_align_center_svg__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @ckeditor/ckeditor5-core/theme/icons/align-center.svg */ "./node_modules/@ckeditor/ckeditor5-core/theme/icons/align-center.svg"); /* harmony import */ var _ckeditor_ckeditor5_core_theme_icons_align_justify_svg__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @ckeditor/ckeditor5-core/theme/icons/align-justify.svg */ "./node_modules/@ckeditor/ckeditor5-core/theme/icons/align-justify.svg"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module alignment/alignmentui */ const icons = new Map( [ [ 'left', _ckeditor_ckeditor5_core_theme_icons_align_left_svg__WEBPACK_IMPORTED_MODULE_4__["default"] ], [ 'right', _ckeditor_ckeditor5_core_theme_icons_align_right_svg__WEBPACK_IMPORTED_MODULE_5__["default"] ], [ 'center', _ckeditor_ckeditor5_core_theme_icons_align_center_svg__WEBPACK_IMPORTED_MODULE_6__["default"] ], [ 'justify', _ckeditor_ckeditor5_core_theme_icons_align_justify_svg__WEBPACK_IMPORTED_MODULE_7__["default"] ] ] ); /** * 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * 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 = editor.config.get( 'alignment.options' ); options .filter( _utils__WEBPACK_IMPORTED_MODULE_3__["isSupported"] ) .forEach( option => this._addButton( option ) ); componentFactory.add( 'alignment', locale => { const dropdownView = Object(_ckeditor_ckeditor5_ui_src_dropdown_utils__WEBPACK_IMPORTED_MODULE_2__["createDropdown"])( locale ); // Add existing alignment buttons to dropdown's toolbar. const buttons = options.map( option => componentFactory.create( `alignment:${ option }` ) ); Object(_ckeditor_ckeditor5_ui_src_dropdown_utils__WEBPACK_IMPORTED_MODULE_2__["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' ? _ckeditor_ckeditor5_core_theme_icons_align_right_svg__WEBPACK_IMPORTED_MODULE_5__["default"] : _ckeditor_ckeditor5_core_theme_icons_align_left_svg__WEBPACK_IMPORTED_MODULE_4__["default"]; // 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 _ckeditor_ckeditor5_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__["default"]( locale ); buttonView.set( { label: this.localizedOptionTitles[ option ], icon: icons.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 */ /***/ (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; }); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module 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'; } } /***/ }), /***/ "./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 _blockautoformatediting__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./blockautoformatediting */ "./node_modules/@ckeditor/ckeditor5-autoformat/src/blockautoformatediting.js"); /* harmony import */ var _inlineautoformatediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./inlineautoformatediting */ "./node_modules/@ckeditor/ckeditor5-autoformat/src/inlineautoformatediting.js"); /* harmony import */ var _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @ckeditor/ckeditor5-core/src/plugin */ "./node_modules/@ckeditor/ckeditor5-core/src/plugin.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module autoformat/autoformat */ /** * 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_2__["default"] { /** * @inheritDoc */ static get pluginName() { return 'Autoformat'; } /** * @inheritDoc */ afterInit() { this._addListAutoformats(); this._addBasicStylesAutoformats(); this._addHeadingAutoformats(); this._addBlockQuoteAutoformats(); this._addCodeBlockAutoformats(); } /** * Adds autoformatting related to the {@link module:list/list~List}. * * When typed: * - `* ` or `- ` – A paragraph will be changed to a bulleted list. * - `1. ` or `1) ` – A paragraph will be changed to a numbered list ("1" can be any digit or a list of digits). * * @private */ _addListAutoformats() { const commands = this.editor.commands; if ( commands.get( 'bulletedList' ) ) { Object(_blockautoformatediting__WEBPACK_IMPORTED_MODULE_0__["default"])( this.editor, this, /^[*-]\s$/, 'bulletedList' ); } if ( commands.get( 'numberedList' ) ) { Object(_blockautoformatediting__WEBPACK_IMPORTED_MODULE_0__["default"])( this.editor, this, /^1[.|)]\s$/, 'numberedList' ); } } /** * Adds autoformatting related to the {@link module:basic-styles/bold~Bold}, * {@link module:basic-styles/italic~Italic}, {@link module:basic-styles/code~Code} * and {@link module:basic-styles/strikethrough~Strikethrough} * * When typed: * - `**foobar**` – `**` characters are removed and `foobar` is set to bold, * - `__foobar__` – `__` characters are removed and `foobar` is set to bold, * - `*foobar*` – `*` characters are removed and `foobar` is set to italic, * - `_foobar_` – `_` characters are removed and `foobar` is set to italic, * - ``` `foobar` – ``` ` ``` characters are removed and `foobar` is set to code, * - `~~foobar~~` – `~~` characters are removed and `foobar` is set to strikethrough. * * @private */ _addBasicStylesAutoformats() { const commands = this.editor.commands; if ( commands.get( 'bold' ) ) { const boldCallback = getCallbackFunctionForInlineAutoformat( this.editor, 'bold' ); Object(_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_1__["default"])( this.editor, this, /(\*\*)([^*]+)(\*\*)$/g, boldCallback ); Object(_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_1__["default"])( this.editor, this, /(__)([^_]+)(__)$/g, boldCallback ); } if ( commands.get( 'italic' ) ) { const italicCallback = getCallbackFunctionForInlineAutoformat( this.editor, 'italic' ); // The italic autoformatter cannot be triggered by the bold markers, so we need to check the // text before the pattern (e.g. `(?:^|[^\*])`). Object(_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_1__["default"])( this.editor, this, /(?:^|[^*])(\*)([^*_]+)(\*)$/g, italicCallback ); Object(_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_1__["default"])( this.editor, this, /(?:^|[^_])(_)([^_]+)(_)$/g, italicCallback ); } if ( commands.get( 'code' ) ) { const codeCallback = getCallbackFunctionForInlineAutoformat( this.editor, 'code' ); Object(_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_1__["default"])( this.editor, this, /(`)([^`]+)(`)$/g, codeCallback ); } if ( commands.get( 'strikethrough' ) ) { const strikethroughCallback = getCallbackFunctionForInlineAutoformat( this.editor, 'strikethrough' ); Object(_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_1__["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_0__["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_0__["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_0__["default"])( this.editor, this, /^```$/, 'codeBlock' ); } } } // Helper function for getting `inlineAutoformatEditing` callbacks that checks if command is enabled. // // @param {module:core/editor/editor~Editor} editor // @param {String} attributeKey // @returns {Function} function getCallbackFunctionForInlineAutoformat( editor, attributeKey ) { return ( writer, rangesToFormat ) => { const command = editor.commands.get( attributeKey ); if ( !command.isEnabled ) { return false; } const validRanges = editor.model.schema.getValidRanges( rangesToFormat, attributeKey ); for ( const range of validRanges ) { writer.setAttribute( attributeKey, true, range ); } // After applying attribute to the text, remove given attribute from the selection. // This way user is able to type a text without attribute used by auto formatter. writer.removeSelectionAttribute( attributeKey ); }; } /***/ }), /***/ "./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 _ckeditor_ckeditor5_engine_src_model_liverange__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-engine/src/model/liverange */ "./node_modules/@ckeditor/ckeditor5-engine/src/model/liverange.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_first__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/first */ "./node_modules/@ckeditor/ckeditor5-utils/src/first.js"); /** * @license Copyright (c) 2003-2020, 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(_ckeditor_ckeditor5_utils_src_first__WEBPACK_IMPORTED_MODULE_1__["default"])( 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; } // 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 _ckeditor_ckeditor5_engine_src_model_liverange__WEBPACK_IMPORTED_MODULE_0__["default"]( start, end ); const wasChanged = callback( { match } ); // Remove matched text. if ( wasChanged !== false ) { writer.remove( range ); } 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-2020, 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 _ckeditor_ckeditor5_core_src_command__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core/src/command */ "./node_modules/@ckeditor/ckeditor5-core/src/command.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module 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 _ckeditor_ckeditor5_core_src_command__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _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 _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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _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 _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _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_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-ui/src/button/buttonview */ "./node_modules/@ckeditor/ckeditor5-ui/src/button/buttonview.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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _ckeditor_ckeditor5_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__["default"]( 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 _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 _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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _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 _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _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_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-ui/src/button/buttonview */ "./node_modules/@ckeditor/ckeditor5-ui/src/button/buttonview.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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _ckeditor_ckeditor5_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__["default"]( 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 _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 _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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _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 _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _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_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-ui/src/button/buttonview */ "./node_modules/@ckeditor/ckeditor5-ui/src/button/buttonview.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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _ckeditor_ckeditor5_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__["default"]( 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 _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 _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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _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 _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _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_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-ui/src/button/buttonview */ "./node_modules/@ckeditor/ckeditor5-ui/src/button/buttonview.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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _ckeditor_ckeditor5_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__["default"]( 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 _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 _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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _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 _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _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_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-ui/src/button/buttonview */ "./node_modules/@ckeditor/ckeditor5-ui/src/button/buttonview.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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _ckeditor_ckeditor5_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__["default"]( 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 _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 _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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _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 _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _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_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-ui/src/button/buttonview */ "./node_modules/@ckeditor/ckeditor5-ui/src/button/buttonview.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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _ckeditor_ckeditor5_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__["default"]( 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 _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 _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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _ckeditor_ckeditor5_core_src_command__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core/src/command */ "./node_modules/@ckeditor/ckeditor5-core/src/command.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_first__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/first */ "./node_modules/@ckeditor/ckeditor5-utils/src/first.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module block-quote/blockquotecommand */ /** * The block quote command plugin. * * @extends module:core/command~Command */ class BlockQuoteCommand extends _ckeditor_ckeditor5_core_src_command__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * 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(_ckeditor_ckeditor5_utils_src_first__WEBPACK_IMPORTED_MODULE_1__["default"])( 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(_ckeditor_ckeditor5_utils_src_first__WEBPACK_IMPORTED_MODULE_1__["default"])( 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 _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 _blockquotecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./blockquotecommand */ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquotecommand.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module block-quote/blockquoteediting */ /** * The block quote editing. * * Introduces the `'blockQuote'` command and the `'blockQuote'` model element. * * @extends module:core/plugin~Plugin */ class BlockQuoteEditing extends _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @inheritDoc */ static get pluginName() { return 'BlockQuoteEditing'; } /** * @inheritDoc */ init() { const editor = this.editor; const schema = editor.model.schema; editor.commands.add( 'blockQuote', new _blockquotecommand__WEBPACK_IMPORTED_MODULE_1__["default"]( editor ) ); schema.register( 'blockQuote', { allowWhere: '$block', allowContentOf: '$root' } ); // Disallow blockQuote in blockQuote. schema.addChildCheck( ( ctx, childDef ) => { if ( ctx.endsWith( 'blockQuote' ) && childDef.name == 'blockQuote' ) { return false; } } ); 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 - most likely inside another blockQuote. Unwrap it // so the content inside is not lost. writer.unwrap( element ); return true; } else if ( element.is( 'element' ) ) { // Just added an element. Check its children to see if there are no nested blockQuotes somewhere inside. 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; } ); } /** * @inheritDoc */ afterInit() { const editor = this.editor; const command = 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 listener is added in afterInit in order to register it after list's feature listener. // We can't use a priority for this, because 'low' is already used by the enter feature, unless // we'd use numeric priority in this case. this.listenTo( this.editor.editing.view.document, 'enter', ( evt, data ) => { const doc = this.editor.model.document; const positionParent = doc.selection.getLastPosition().parent; if ( doc.selection.isCollapsed && positionParent.isEmpty && command.value ) { this.editor.execute( 'blockQuote' ); this.editor.editing.view.scrollToTheSelection(); data.preventDefault(); evt.stop(); } } ); } } /***/ }), /***/ "./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 _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_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-ui/src/button/buttonview */ "./node_modules/@ckeditor/ckeditor5-ui/src/button/buttonview.js"); /* harmony import */ var _ckeditor_ckeditor5_core_theme_icons_quote_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @ckeditor/ckeditor5-core/theme/icons/quote.svg */ "./node_modules/@ckeditor/ckeditor5-core/theme/icons/quote.svg"); /* harmony import */ var _theme_blockquote_css__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../theme/blockquote.css */ "./node_modules/@ckeditor/ckeditor5-block-quote/theme/blockquote.css"); /* harmony import */ var _theme_blockquote_css__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_theme_blockquote_css__WEBPACK_IMPORTED_MODULE_3__); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module block-quote/blockquoteui */ /** * The block quote UI plugin. * * It introduces the `'blockQuote'` button. * * @extends module:core/plugin~Plugin */ class BlockQuoteUI extends _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _ckeditor_ckeditor5_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__["default"]( locale ); buttonView.set( { label: t( 'Block quote' ), icon: _ckeditor_ckeditor5_core_theme_icons_quote_svg__WEBPACK_IMPORTED_MODULE_2__["default"], 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 _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 _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"); /* harmony import */ var _ckeditor_ckeditor5_adapter_ckfinder_src_uploadadapter__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter */ "./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @inheritDoc */ static get pluginName() { return 'CKFinder'; } /** * @inheritDoc */ static get requires() { return [ _ckfinderediting__WEBPACK_IMPORTED_MODULE_2__["default"], _ckfinderui__WEBPACK_IMPORTED_MODULE_1__["default"], _ckeditor_ckeditor5_adapter_ckfinder_src_uploadadapter__WEBPACK_IMPORTED_MODULE_3__["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 _ckeditor_ckeditor5_core_src_command__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core/src/command */ "./node_modules/@ckeditor/ckeditor5-core/src/command.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/ckeditorerror */ "./node_modules/@ckeditor/ckeditor5-utils/src/ckeditorerror.js"); /** * @license Copyright (c) 2003-2020, 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/imageinsertcommand~ImageInsertCommand 'imageInsert'} 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 _ckeditor_ckeditor5_core_src_command__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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( 'imageInsert' ); 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 _ckeditor_ckeditor5_utils_src_ckeditorerror__WEBPACK_IMPORTED_MODULE_1__["default"]( '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( 'imageInsert' ); // 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( 'imageInsert', { 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 _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_image_src_image_imageediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-image/src/image/imageediting */ "./node_modules/@ckeditor/ckeditor5-image/src/image/imageediting.js"); /* harmony import */ var _ckeditor_ckeditor5_link_src_linkediting__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @ckeditor/ckeditor5-link/src/linkediting */ "./node_modules/@ckeditor/ckeditor5-link/src/linkediting.js"); /* harmony import */ var _ckeditor_ckeditor5_ui_src_notification_notification__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @ckeditor/ckeditor5-ui/src/notification/notification */ "./node_modules/@ckeditor/ckeditor5-ui/src/notification/notification.js"); /* harmony import */ var _ckfindercommand__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ckfindercommand */ "./node_modules/@ckeditor/ckeditor5-ckfinder/src/ckfindercommand.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module ckfinder/ckfinderediting */ /** * The CKFinder editing feature. It introduces the {@link module:ckfinder/ckfindercommand~CKFinderCommand CKFinder command}. * * @extends module:core/plugin~Plugin */ class CKFinderEditing extends _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @inheritDoc */ static get pluginName() { return 'CKFinderEditing'; } /** * @inheritDoc */ static get requires() { return [ _ckeditor_ckeditor5_ui_src_notification_notification__WEBPACK_IMPORTED_MODULE_3__["default"], _ckeditor_ckeditor5_image_src_image_imageediting__WEBPACK_IMPORTED_MODULE_1__["default"], _ckeditor_ckeditor5_link_src_linkediting__WEBPACK_IMPORTED_MODULE_2__["default"] ]; } /** * @inheritDoc */ init() { const editor = this.editor; editor.commands.add( 'ckfinder', new _ckfindercommand__WEBPACK_IMPORTED_MODULE_4__["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 _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_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-ui/src/button/buttonview */ "./node_modules/@ckeditor/ckeditor5-ui/src/button/buttonview.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-2020, 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 _ckeditor_ckeditor5_core_src_plugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @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 _ckeditor_ckeditor5_ui_src_button_buttonview__WEBPACK_IMPORTED_MODULE_1__["default"]( 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 _pasteplaintext__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./pasteplaintext */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/pasteplaintext.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"); /* harmony import */ var _ckeditor_ckeditor5_engine_src_dataprocessor_htmldataprocessor__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor */ "./node_modules/@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor.js"); /* harmony import */ var _ckeditor_ckeditor5_utils_src_eventinfo__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils/src/eventinfo */ "./node_modules/@ckeditor/ckeditor5-utils/src/eventinfo.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module clipboard/clipboard */ /** * The clipboard feature. It is responsible for intercepting the `paste` and `drop` events and * passing the pasted content through the clipboard pipeline in order to insert it into the editor's content. * It also handles the `cut` and `copy` events to fill the native clipboard with serialized editor's data. * * Read more about the clipboard integration in {@glink framework/guides/deep-dive/clipboard "Clipboard" deep dive} guide. * * @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 [ _pasteplaintext__WEBPACK_IMPORTED_MODULE_1__["default"] ]; } /** * @inheritDoc */ init() { const editor = this.editor; const modelDocument = editor.model.document; const view = editor.editing.view; const viewDocument = view.document; /** * Data processor used to convert pasted HTML to a view structure. * * @private * @member {module:engine/dataprocessor/htmldataprocessor~HtmlDataProcessor} #_htmlDataProcessor */ this._htmlDataProcessor = new _ckeditor_ckeditor5_engine_src_dataprocessor_htmldataprocessor__WEBPACK_IMPORTED_MODULE_6__["default"]( viewDocument ); view.addObserver( _clipboardobserver__WEBPACK_IMPORTED_MODULE_2__["default"] ); // The clipboard paste pipeline. // Pasting and dropping is disabled when editor is read-only. // 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 = ''; 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._htmlDataProcessor.toView( content ); const eventInfo = new _ckeditor_ckeditor5_utils_src_eventinfo__WEBPACK_IMPORTED_MODULE_7__["default"]( this, 'inputTransformation' ); this.fire( eventInfo, { content, dataTransfer, asPlainText: data.asPlainText } ); // 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 ) { evt.stop(); } view.scrollToTheSelection(); }, { priority: 'low' } ); this.listenTo( this, 'inputTransformation', ( evt, data ) => { if ( !data.content.isEmpty ) { const dataController = this.editor.data; const model = this.editor.model; // Convert the pasted content to a model document fragment. // Conversion is contextual, but in this case we need an "all allowed" context and for that // we use the $clipboardHolder item. const modelFragment = dataController.toModel( data.content, '$clipboardHolder' ); if ( modelFragment.childCount == 0 ) { return; } // Plain text can be determined based on event flag (#7799) or auto detection (#1006). If detected // preserve selection attributes on pasted items. if ( data.asPlainText || isPlainTextFragment( modelFragment ) ) { // Consider only formatting attributes. const textAttributes = new Map( Array.from( modelDocument.selection.getAttributes() ).filter( keyValuePair => editor.model.schema.getAttributeProperties( keyValuePair[ 0 ] ).isFormatting ) ); model.change( writer => { const range = writer.createRangeIn( modelFragment ); for ( const item of range.getItems() ) { if ( item.is( '$text' ) || item.is( '$textProxy' ) ) { writer.setAttributes( textAttributes, item ); } } } ); } model.insertContent( modelFragment ); evt.stop(); } }, { priority: 'low' } ); // The clipboard copy/cut pipeline. 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 read-only. // 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._htmlDataProcessor.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 a `content` and `dataTransfer` objects. 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 needs access to a raw clipboard data. * * It is a part of the {@glink framework/guides/deep-dive/clipboard#input-pipeline "clipboard input pipeline"}. * * @see module:clipboard/clipboardobserver~ClipboardObserver * @see module:clipboard/clipboard~Clipboard * @event module:clipboard/clipboard~Clipboard#event:inputTransformation * @param {Object} data Event data. * @param {module:engine/view/documentfragment~DocumentFragment} data.content Event data. Content to be inserted into the editor. * It can be modified by the event listeners. Read more about the clipboard pipelines in * {@glink framework/guides/deep-dive/clipboard "Clipboard" deep dive}. * @param {module:clipboard/datatransfer~DataTransfer} data.dataTransfer Data transfer instance. * @param {Boolean} data.asPlainText If set to `true` content is pasted as plain text. */ /** * Fired on {@link module:engine/view/document~Document#event:copy} and {@link module:engine/view/document~Document#event:cut} * with a copy of 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/clipboard~Clipboard * @event module:engine/view/document~Document#event:clipboardOutput * @param {module:clipboard/clipboard~ClipboardOutputEventData} data Event data. */ /** * The value of the {@link module:engine/view/document~Document#event:clipboardOutput} event. * * @class module:clipboard/clipboard~ClipboardOutputEventData */ /** * Data transfer instance. * * @readonly * @member {module:clipboard/datatransfer~DataTransfer} module:clipboard/clipboard~ClipboardOutputEventData#dataTransfer */ /** * Content to be put into the clipboard. It can be modified by the event listeners. * Read more about the clipboard pipelines in {@glink framework/guides/deep-dive/clipboard "Clipboard" deep dive}. * * @member {module:engine/view/documentfragment~DocumentFragment} module:clipboard/clipboard~ClipboardOutputEventData#content */ /** * Whether the event was triggered by copy or cut operation. * * @member {'copy'|'cut'} module:clipboard/clipboard~ClipboardOutputEventData#method */ // Returns true if specified `documentFragment` represents a plain text. // // @param {module:engine/view/documentfragment~DocumentFragment} documentFragment // @returns {Boolean} function isPlainTextFragment( documentFragment ) { if ( documentFragment.childCount > 1 ) { return false; } const child = documentFragment.getChild( 0 ); return [ ...child.getAttributeKeys() ].length == 0; } /***/ }), /***/ "./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-2020, 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:dragover} * * {@link module:engine/view/document~Document#event:drop} * * {@link module:engine/view/document~Document#event:paste} * * {@link module:engine/view/document~Document#event:copy} * * {@link module:engine/view/document~Document#event:cut} * * Note that this observer is not available by default (it is not added by the engine). * To make it available it needs to be added to {@link module:engine/view/document~Document} by * the {@link module:engine/view/view~View#addObserver `View#addObserver()`} method. You can also 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' ]; this.listenTo( viewDocument, 'paste', handleInput, { priority: 'low' } ); this.listenTo( viewDocument, 'drop', handleInput, { priority: 'low' } ); function handleInput( evt, data ) { data.preventDefault(); const targetRanges = data.dropRange ? [ data.dropRange ] : Array.from( viewDocument.selection.getRanges() ); const eventInfo = new _ckeditor_ckeditor5_utils_src_eventinfo__WEBPACK_IMPORTED_MODULE_1__["default"]( viewDocument, 'clipboardInput' ); viewDocument.fire( eventInfo, { dataTransfer: data.dataTransfer, targetRanges } ); // 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' ) { 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 ); } else { return view.document.selection.getFirstRange(); } } /** * Fired as a continuation of {@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"}. * * Fired with a `dataTransfer` which comes from the clipboard and which content should be processed * and inserted into the editor. * * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver} * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method. * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually. * * @see module:clipboard/clipboardobserver~ClipboardObserver * @see module:clipboard/clipboard~Clipboard * @event module:engine/view/document~Document#event:clipboardInput * @param {Object} data Event data. * @param {module:clipboard/datatransfer~DataTransfer} data.dataTransfer Data transfer instance. * @param {Array.} data.targetRanges Ranges which are the target of the operation * (usually – into which the content should be inserted). * If clipboard input was triggered by a paste operation, then these are the selection ranges. If by a drop operation, * then it's the drop position (which can be different than the selection at the moment of drop). */ /** * Fired when user drags content over one of the editables. * * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}. * * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver} * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method. * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually. * * @see module:engine/view/document~Document#event:clipboardInput * @event module:engine/view/document~Document#event:dragover * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data. */ /** * Fired when user dropped content into one of the editables. * * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}. * * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver} * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method. * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually. * * @see module:engine/view/document~Document#event:clipboardInput * @event module:engine/view/document~Document#event:drop * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data. * @param {module:engine/view/range~Range} dropRange The position into which the content is dropped. */ /** * Fired when user pasted content into one of the editables. * * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}. * * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver} * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method. * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually. * * @see module:engine/view/document~Document#event:clipboardInput * @event module:engine/view/document~Document#event:paste * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data. */ /** * Fired when user copied content from one of the editables. * * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}. * * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver} * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method. * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually. * * @see module:clipboard/clipboardobserver~ClipboardObserver * @event module:engine/view/document~Document#event:copy * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data. */ /** * Fired when user cut content from one of the editables. * * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}. * * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver} * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method. * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually. * * @see module:clipboard/clipboardobserver~ClipboardObserver * @event module:engine/view/document~Document#event:cut * @param {module:clipboard/clipboardobserver~ClipboardEventData} data 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 clipboard data use `dataTransfer` property. * * @class module:clipboard/clipboardobserver~ClipboardEventData * @extends module:engine/view/observer/domeventdata~DomEventData */ /** * Data transfer instance. * * @readonly * @member {module:clipboard/datatransfer~DataTransfer} module:clipboard/clipboardobserver~ClipboardEventData#dataTransfer */ /***/ }), /***/ "./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-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module clipboard/datatransfer */ /** * 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 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 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 ); } } 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 have empty DataTransfer.files, but let get files through the items interface. return items .filter( item => item.kind === 'file' ) .map( item => item.getAsFile() ); } /***/ }), /***/ "./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"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module clipboard/clipboard */ /** * The plugin detects user intentions for pasting plain text. * * For example, it detects ctrl/cmd + shift + ctrl/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 */ init() { const view = this.editor.editing.view; const viewDocument = view.document; let shiftPressed = false; view.addObserver( _clipboardobserver__WEBPACK_IMPORTED_MODULE_1__["default"] ); this.listenTo( viewDocument, 'keydown', ( evt, data ) => { shiftPressed = data.shiftKey; } ); this.listenTo( viewDocument, 'clipboardInput', ( evt, data ) => { if ( shiftPressed ) { data.asPlainText = true; } }, { priority: 'high' } ); } } /***/ }), /***/ "./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-2020, 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-2020, 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-2020, 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-cloud-services/src/cloudservices.js": /*!******************************************************************************!*\ !*** ./node_modules/@ckeditor/ckeditor5-cloud-services/src/cloudservices.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 CloudServices; }); /* harmony import */ var _ckeditor_ckeditor5_core_src_contextplugin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core/src/contextplugin */ "./node_modules/@ckeditor/ckeditor5-core/src/contextplugin.js"); /* harmony import */ var _ckeditor_ckeditor_cloud_services_core_src_token_token__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor-cloud-services-core/src/token/token */ "./node_modules/@ckeditor/ckeditor-cloud-services-core/src/token/token.js"); /** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module cloud-services/cloudservices */ /** * Plugin introducing integration between CKEditor 5 and CKEditor Cloud Services . * * It initializes the token provider based on * the {@link module:cloud-services/cloudservices~CloudServicesConfig `config.cloudService`}. * * @extends module:core/plugin~Plugin */ class CloudServices extends _ckeditor_ckeditor5_core_src_contextplugin__WEBPACK_IMPORTED_MODULE_0__["default"] { /** * @inheritdoc */ static get pluginName() { return 'CloudServices'; } /** * @inheritDoc */ init() { const config = this.context.config; const options = config.get( 'cloudServices' ) || {}; for ( const optionName in options ) { this[ optionName ] = options[ optionName ]; } /** * The authentication token URL for CKEditor Cloud Services or a callback to the token value promise. See the * {@link module:cloud-services/cloudservices~CloudServicesConfig#tokenUrl} for more details. * * @readonly * @member {String|Function|undefined} #tokenUrl */ /** * The URL to which the files should be uploaded. * * @readonly * @member {String} #uploadUrl */ /** * Other plugins use this token for the authorization process. It handles token requesting and refreshing. * Its value is `null` when {@link module:cloud-services/cloudservices~CloudServicesConfig#tokenUrl} is not provided. * * @readonly * @member {Object|null} #token */ if ( !this.tokenUrl ) { this.token = null; return; } this.token = new CloudServices.Token( this.tokenUrl ); return this.token.init(); } /** * @inheritDoc */ destroy() { super.destroy(); if ( this.token ) { this.token.destroy(); } } } CloudServices.Token = _ckeditor_ckeditor_cloud_services_core_src_token_token__WEBPACK_IMPORTED_MODULE_1__["default"]; /** * The configuration of CKEditor Cloud Services. Introduced by the {@link module:cloud-services/cloudservices~CloudServices} plugin. * * Read more in {@link module:cloud-services/cloudservices~CloudServicesConfig}. * * @member {module:cloud-services/cloudservices~CloudServicesConfig} module:core/editor/editorconfig~EditorConfig#cloudServices */ /** * The configuration for all plugins using CKEditor Cloud Services. * * ClassicEditor * .create( document.querySelector( '#editor' ), { * cloudServices: { * tokenUrl: 'https://example.com/cs-token-endpoint', * uploadUrl: 'https://your-organization-id.cke-cs.com/easyimage/upload/' * } * } ) * .then( ... ) * .catch( ... ); * * See {@link module:core/editor/editorconfig~EditorConfig all editor options}. * * @interface CloudServicesConfig */ /** * A token URL or a token request function. * * As a string, it should be a URL to the security token endpoint in your application. The role of this endpoint is to securely authorize * the end users of your application to use [CKEditor Cloud Services](https://ckeditor.com/ckeditor-cloud-services) only * if they should have access e.g. to upload files with {@glink @cs guides/easy-image/quick-start Easy Image} or to use the * {@glink @cs guides/collaboration/quick-start Collaboration} service. * * ClassicEditor * .create( document.querySelector( '#editor' ), { * cloudServices: { * tokenUrl: 'https://example.com/cs-token-endpoint', * ... * } * } ) * .then( ... ) * .catch( ... ); * * As a function, it should provide a promise to the token value, so you can highly customize the token and provide your token URL endpoint. * By using this approach you can set your own headers for the request. * * ClassicEditor * .create( document.querySelector( '#editor' ), { * cloudServices: { * tokenUrl: () => new Promise( ( resolve, reject ) => { * const xhr = new XMLHttpRequest(); * * xhr.open( 'GET', 'https://example.com/cs-token-endpoint' ); * * xhr.addEventListener( 'load', () => { * const statusCode = xhr.status; * const xhrResponse = xhr.response; * * if ( statusCode < 200 || statusCode > 299 ) { * return reject( new Error( 'Cannot download new token!' ) ); * } * * return resolve( xhrResponse ); * } ); * * xhr.addEventListener( 'error', () => reject( new Error( 'Network Error' ) ) ); * xhr.addEventListener( 'abort', () => reject( new Error( 'Abort' ) ) ); * * xhr.setRequestHeader( customHeader, customValue ); * * xhr.send(); * } ), * ... * } * } ) * * You can find more information about token endpoints in the * {@glink @cs guides/easy-image/quick-start#create-token-endpoint Cloud Services - Quick start} * and {@glink @cs guides/security/token-endpoint Cloud Services - Token endpoint} documentation. * * Without a properly working token endpoint (token URL) CKEditor plugins will not be able to connect to CKEditor Cloud Services. * * @member {String|Function} module:cloud-services/cloudservices~CloudServicesConfig#tokenUrl */ /** * The endpoint URL for [CKEditor Cloud Services](https://ckeditor.com/ckeditor-cloud-services) uploads. * This option must be set for Easy Image to work correctly. * * The upload URL is unique for each customer and can be found in the * [CKEditor Ecosystem customer dashboard](https://dashboard.ckeditor.com) after subscribing to the Easy Image service. * To learn how to start using Easy Image, check the {@glink @cs guides/easy-image/quick-start Easy Image - Quick start} documentation. * * Note: Make sure to also set the {@link module:cloud-services/cloudservices~CloudServicesConfig#tokenUrl} configuration option. * * @member {String} module:cloud-services/cloudservices~CloudServicesConfig#uploadUrl */ /** * The URL for web socket communication, used by the `RealTimeCollaborativeEditing` plugin. Every customer (organization in the CKEditor * Ecosystem dashboard) has their own, unique URLs to communicate with CKEditor Cloud Services. The URL can be found in the * CKEditor Ecosystem customer dashboard. * * Note: Unlike most plugins, `RealTimeCollaborativeEditing` is not included in any CKEditor 5 build and needs to be installed manually. * Check [Collaboration overview](https://ckeditor.com/docs/ckeditor5/latest/features/collaboration/overview.html) for more details. * * @member {String} module:cloud-services/cloudservices~CloudServicesConfig#webSocketUrl */ /** * An optional parameter used for integration with CKEditor Cloud Services when uploading the editor build to cloud services. * * Whenever the editor build or the configuration changes, this parameter should be set to a new, unique value to differentiate * the new bundle (build + configuration) from the old ones. * * @member {String} module:cloud-services/cloudservices~CloudServicesConfig#bundleVersion */ /***/ }), /***/ "./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-2020, 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 `'imageUpload'`). * * 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-2020, 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-2020, 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' ) || []; for ( const Plugin of plugins ) { 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 ); } /** * 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-2020, 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-2020, 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-2020, 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( 'Clipboard' ); // -> An instance of the clipboard 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' ) || []; return this.plugins.init( plugins.concat( extraPlugins ), removePlugins ); } /** * 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 ); } } /** * 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 `