Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@ckeditor/ckeditor5-editor-balloon

Package Overview
Dependencies
Maintainers
1
Versions
764
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ckeditor/ckeditor5-editor-balloon - npm Package Compare versions

Comparing version 35.3.2 to 35.4.0

2

build/editor-balloon.js
/*!
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/(()=>{var t={704:(t,e,o)=>{t.exports=o(79)("./src/core.js")},492:(t,e,o)=>{t.exports=o(79)("./src/engine.js")},273:(t,e,o)=>{t.exports=o(79)("./src/ui.js")},209:(t,e,o)=>{t.exports=o(79)("./src/utils.js")},79:t=>{"use strict";t.exports=CKEditor5.dll}},e={};function o(i){var r=e[i];if(void 0!==r)return r.exports;var n=e[i]={exports:{}};return t[i](n,n.exports,o),n.exports}o.d=(t,e)=>{for(var i in e)o.o(e,i)&&!o.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},o.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),o.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var i={};(()=>{"use strict";o.r(i),o.d(i,{BalloonEditor:()=>C});var t=o(704),e=o(273),r=o(209);const n=function(t){return null!=t&&"object"==typeof t};const s="object"==typeof global&&global&&global.Object===Object&&global;var c="object"==typeof self&&self&&self.Object===Object&&self;const a=(s||c||Function("return this")()).Symbol;var l=Object.prototype,d=l.hasOwnProperty,u=l.toString,h=a?a.toStringTag:void 0;const g=function(t){var e=d.call(t,h),o=t[h];try{t[h]=void 0;var i=!0}catch(t){}var r=u.call(t);return i&&(e?t[h]=o:delete t[h]),r};var p=Object.prototype.toString;const b=function(t){return p.call(t)};var f=a?a.toStringTag:void 0;const m=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":f&&f in Object(t)?g(t):b(t)};const v=function(t,e){return function(o){return t(e(o))}}(Object.getPrototypeOf,Object);var y=Function.prototype,w=Object.prototype,j=y.toString,E=w.hasOwnProperty,O=j.call(Object);const x=function(t){if(!n(t)||"[object Object]"!=m(t))return!1;var e=v(t);if(null===e)return!0;var o=E.call(e,"constructor")&&e.constructor;return"function"==typeof o&&o instanceof o&&j.call(o)==O};const S=function(t){return n(t)&&1===t.nodeType&&!x(t)};var P=o(492);class T extends t.EditorUI{constructor(t,e){super(t),this.view=e}get element(){return this.view.editable.element}init(){const t=this.editor,e=this.view,o=t.editing.view,i=e.editable,r=o.document.getRoot();i.name=r.rootName,e.render();const n=i.element;this.setEditableElement(i.name,n),i.bind("isFocused").to(this.focusTracker),o.attachDomRoot(n),this._initPlaceholder(),this.fire("ready")}destroy(){super.destroy();const t=this.view;this.editor.editing.view.detachDomRoot(t.editable.name),t.destroy()}_initPlaceholder(){const t=this.editor,e=t.editing.view,o=e.document.getRoot(),i=t.sourceElement,r=t.config.get("placeholder")||i&&"textarea"===i.tagName.toLowerCase()&&i.getAttribute("placeholder");r&&(0,P.enablePlaceholder)({view:e,element:o,text:r,isDirectHost:!1,keepOnFocus:!0})}}class D extends e.EditorUIView{constructor(t,o,i){super(t);const r=t.t;this.editable=new e.InlineEditableUIView(t,o,i,{label:t=>r("Rich Text Editor. Editing area: %0",t.name)})}render(){super.render(),this.registerChild(this.editable)}}class C extends t.Editor{constructor(o,i={}){if(!S(o)&&void 0!==i.initialData)throw new r.CKEditorError("editor-create-initial-data",null);super(i),void 0===this.config.get("initialData")&&this.config.set("initialData",function(t){return S(t)?(0,r.getDataFromElement)(t):t}(o)),S(o)&&(this.sourceElement=o,(0,t.secureSourceElement)(this));const n=this.config.get("plugins");n.push(e.BalloonToolbar),this.config.set("plugins",n),this.config.define("balloonToolbar",this.config.get("toolbar")),this.model.document.createRoot();const s=new D(this.locale,this.editing.view,this.sourceElement);this.ui=new T(this,s),(0,t.attachToForm)(this)}destroy(){const t=this.getData();return this.ui.destroy(),super.destroy().then((()=>{this.sourceElement&&this.updateSourceElement(t)}))}static create(t,e={}){return new Promise((o=>{if(S(t)&&"TEXTAREA"===t.tagName)throw new r.CKEditorError("editor-wrong-element",null);const i=new this(t,e);o(i.initPlugins().then((()=>i.ui.init())).then((()=>i.data.init(i.config.get("initialData")))).then((()=>i.fire("ready"))).then((()=>i)))}))}}(0,r.mix)(C,t.DataApiMixin),(0,r.mix)(C,t.ElementApiMixin)})(),(window.CKEditor5=window.CKEditor5||{}).editorBalloon=i})();
*/(()=>{var t={704:(t,e,o)=>{t.exports=o(79)("./src/core.js")},492:(t,e,o)=>{t.exports=o(79)("./src/engine.js")},273:(t,e,o)=>{t.exports=o(79)("./src/ui.js")},209:(t,e,o)=>{t.exports=o(79)("./src/utils.js")},79:t=>{"use strict";t.exports=CKEditor5.dll}},e={};function o(i){var r=e[i];if(void 0!==r)return r.exports;var n=e[i]={exports:{}};return t[i](n,n.exports,o),n.exports}o.d=(t,e)=>{for(var i in e)o.o(e,i)&&!o.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},o.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),o.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var i={};(()=>{"use strict";o.r(i),o.d(i,{BalloonEditor:()=>C});var t=o(704),e=o(273),r=o(209),n=o(492);class s extends t.EditorUI{constructor(t,e){super(t),this.view=e}get element(){return this.view.editable.element}init(){const t=this.editor,e=this.view,o=t.editing.view,i=e.editable,r=o.document.getRoot();i.name=r.rootName,e.render();const n=i.element;this.setEditableElement(i.name,n),i.bind("isFocused").to(this.focusTracker),o.attachDomRoot(n),this._initPlaceholder(),this.fire("ready")}destroy(){super.destroy();const t=this.view;this.editor.editing.view.detachDomRoot(t.editable.name),t.destroy()}_initPlaceholder(){const t=this.editor,e=t.editing.view,o=e.document.getRoot(),i=t.sourceElement,r=t.config.get("placeholder")||i&&"textarea"===i.tagName.toLowerCase()&&i.getAttribute("placeholder");r&&(0,n.enablePlaceholder)({view:e,element:o,text:r,isDirectHost:!1,keepOnFocus:!0})}}class c extends e.EditorUIView{constructor(t,o,i){super(t);const r=t.t;this.editable=new e.InlineEditableUIView(t,o,i,{label:t=>r("Rich Text Editor. Editing area: %0",t.name)})}render(){super.render(),this.registerChild(this.editable)}}const a=function(t){return null!=t&&"object"==typeof t};const l="object"==typeof global&&global&&global.Object===Object&&global;var d="object"==typeof self&&self&&self.Object===Object&&self;const u=(l||d||Function("return this")()).Symbol;var h=Object.prototype,g=h.hasOwnProperty,p=h.toString,b=u?u.toStringTag:void 0;const f=function(t){var e=g.call(t,b),o=t[b];try{t[b]=void 0;var i=!0}catch(t){}var r=p.call(t);return i&&(e?t[b]=o:delete t[b]),r};var m=Object.prototype.toString;const v=function(t){return m.call(t)};var y=u?u.toStringTag:void 0;const w=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":y&&y in Object(t)?f(t):v(t)};const j=function(t,e){return function(o){return t(e(o))}}(Object.getPrototypeOf,Object);var E=Function.prototype,O=Object.prototype,x=E.toString,S=O.hasOwnProperty,P=x.call(Object);const T=function(t){if(!a(t)||"[object Object]"!=w(t))return!1;var e=j(t);if(null===e)return!0;var o=S.call(e,"constructor")&&e.constructor;return"function"==typeof o&&o instanceof o&&x.call(o)==P};const D=function(t){return a(t)&&1===t.nodeType&&!T(t)};class C extends((0,t.DataApiMixin)((0,t.ElementApiMixin)(t.Editor))){constructor(o,i={}){if(!R(o)&&void 0!==i.initialData)throw new r.CKEditorError("editor-create-initial-data",null);super(i),void 0===this.config.get("initialData")&&this.config.set("initialData",function(t){return R(t)?(0,r.getDataFromElement)(t):t}(o)),R(o)&&(this.sourceElement=o,(0,t.secureSourceElement)(this));const n=this.config.get("plugins");n.push(e.BalloonToolbar),this.config.set("plugins",n),this.config.define("balloonToolbar",this.config.get("toolbar")),this.model.document.createRoot();const a=new c(this.locale,this.editing.view,this.sourceElement);this.ui=new s(this,a),(0,t.attachToForm)(this)}destroy(){const t=this.getData();return this.ui.destroy(),super.destroy().then((()=>{this.sourceElement&&this.updateSourceElement(t)}))}static create(t,e={}){return new Promise((o=>{if(R(t)&&"TEXTAREA"===t.tagName)throw new r.CKEditorError("editor-wrong-element",null);const i=new this(t,e);o(i.initPlugins().then((()=>i.ui.init())).then((()=>i.data.init(i.config.get("initialData")))).then((()=>i.fire("ready"))).then((()=>i)))}))}}function R(t){return D(t)}})(),(window.CKEditor5=window.CKEditor5||{}).editorBalloon=i})();
{
"name": "@ckeditor/ckeditor5-editor-balloon",
"version": "35.3.2",
"version": "35.4.0",
"description": "Balloon editor implementation for CKEditor 5.",

@@ -14,19 +14,20 @@ "keywords": [

"dependencies": {
"ckeditor5": "^35.3.2",
"ckeditor5": "^35.4.0",
"lodash-es": "^4.17.15"
},
"devDependencies": {
"@ckeditor/ckeditor5-basic-styles": "^35.3.2",
"@ckeditor/ckeditor5-core": "^35.3.2",
"@ckeditor/ckeditor5-basic-styles": "^35.4.0",
"@ckeditor/ckeditor5-core": "^35.4.0",
"@ckeditor/ckeditor5-dev-utils": "^31.0.0",
"@ckeditor/ckeditor5-engine": "^35.3.2",
"@ckeditor/ckeditor5-enter": "^35.3.2",
"@ckeditor/ckeditor5-heading": "^35.3.2",
"@ckeditor/ckeditor5-image": "^35.3.2",
"@ckeditor/ckeditor5-paragraph": "^35.3.2",
"@ckeditor/ckeditor5-theme-lark": "^35.3.2",
"@ckeditor/ckeditor5-typing": "^35.3.2",
"@ckeditor/ckeditor5-ui": "^35.3.2",
"@ckeditor/ckeditor5-undo": "^35.3.2",
"@ckeditor/ckeditor5-utils": "^35.3.2",
"@ckeditor/ckeditor5-engine": "^35.4.0",
"@ckeditor/ckeditor5-enter": "^35.4.0",
"@ckeditor/ckeditor5-heading": "^35.4.0",
"@ckeditor/ckeditor5-image": "^35.4.0",
"@ckeditor/ckeditor5-paragraph": "^35.4.0",
"@ckeditor/ckeditor5-theme-lark": "^35.4.0",
"@ckeditor/ckeditor5-typing": "^35.4.0",
"@ckeditor/ckeditor5-ui": "^35.4.0",
"@ckeditor/ckeditor5-undo": "^35.4.0",
"@ckeditor/ckeditor5-utils": "^35.4.0",
"typescript": "^4.8.4",
"webpack": "^5.58.1",

@@ -50,3 +51,4 @@ "webpack-cli": "^4.9.0"

"lang",
"src",
"src/**/*.js",
"src/**/*.d.ts",
"theme",

@@ -58,4 +60,6 @@ "build",

"scripts": {
"dll:build": "webpack"
"dll:build": "webpack",
"build": "tsc -p ./tsconfig.release.json",
"postversion": "npm run build"
}
}

@@ -5,16 +5,11 @@ /**

*/
/**
* @module editor-balloon/ballooneditor
*/
import { Editor, DataApiMixin, ElementApiMixin, attachToForm, secureSourceElement } from 'ckeditor5/src/core';
import { BalloonToolbar } from 'ckeditor5/src/ui';
import { CKEditorError, getDataFromElement, mix } from 'ckeditor5/src/utils';
import { isElement } from 'lodash-es';
import { CKEditorError, getDataFromElement } from 'ckeditor5/src/utils';
import BalloonEditorUI from './ballooneditorui';
import BalloonEditorUIView from './ballooneditoruiview';
import { isElement as _isElement } from 'lodash-es';
/**

@@ -43,195 +38,175 @@ * The {@glink installation/getting-started/predefined-builds#balloon-editor balloon editor}

* {@link module:editor-balloon/ballooneditor~BalloonEditor.create `BalloonEditor.create()`}.
*
* @mixes module:core/editor/utils/dataapimixin~DataApiMixin
* @mixes module:core/editor/utils/elementapimixin~ElementApiMixin
* @implements module:core/editor/editorwithui~EditorWithUI
* @extends module:core/editor/editor~Editor
*/
export default class BalloonEditor extends Editor {
/**
* Creates an instance of the balloon editor.
*
* **Note:** do not use the constructor to create editor instances. Use the static
* {@link module:editor-balloon/ballooneditor~BalloonEditor.create `BalloonEditor.create()`} method instead.
*
* @protected
* @param {HTMLElement|String} sourceElementOrData The DOM element that will be the source for the created editor
* (on which the editor will be initialized) or initial data for the editor. For more information see
* {@link module:editor-balloon/ballooneditor~BalloonEditor.create `BalloonEditor.create()`}.
* @param {module:core/editor/editorconfig~EditorConfig} [config] The editor configuration.
*/
constructor( sourceElementOrData, config = {} ) {
// If both `config.initialData` is set and initial data is passed as the constructor parameter, then throw.
if ( !isElement( sourceElementOrData ) && config.initialData !== undefined ) {
// Documented in core/editor/editorconfig.jsdoc.
// eslint-disable-next-line ckeditor5-rules/ckeditor-error-message
throw new CKEditorError( 'editor-create-initial-data', null );
}
super( config );
if ( this.config.get( 'initialData' ) === undefined ) {
this.config.set( 'initialData', getInitialData( sourceElementOrData ) );
}
if ( isElement( sourceElementOrData ) ) {
this.sourceElement = sourceElementOrData;
secureSourceElement( this );
}
const plugins = this.config.get( 'plugins' );
plugins.push( BalloonToolbar );
this.config.set( 'plugins', plugins );
this.config.define( 'balloonToolbar', this.config.get( 'toolbar' ) );
this.model.document.createRoot();
const view = new BalloonEditorUIView( this.locale, this.editing.view, this.sourceElement );
this.ui = new BalloonEditorUI( this, view );
attachToForm( this );
}
/**
* Destroys the editor instance, releasing all resources used by it.
*
* Updates the original editor element with the data if the
* {@link module:core/editor/editorconfig~EditorConfig#updateSourceElementOnDestroy `updateSourceElementOnDestroy`}
* configuration option is set to `true`.
*
* @returns {Promise}
*/
destroy() {
// Cache the data, then destroy.
// It's safe to assume that the model->view conversion will not work after super.destroy().
const data = this.getData();
this.ui.destroy();
return super.destroy()
.then( () => {
if ( this.sourceElement ) {
this.updateSourceElement( data );
}
} );
}
/**
* Creates a new balloon editor instance.
*
* There are three general ways how the editor can be initialized.
*
* # Using an existing DOM element (and loading data from it)
*
* You can initialize the editor using an existing DOM element:
*
* BalloonEditor
* .create( document.querySelector( '#editor' ) )
* .then( editor => {
* console.log( 'Editor was initialized', editor );
* } )
* .catch( err => {
* console.error( err.stack );
* } );
*
* The element's content will be used as the editor data and the element will become the editable element.
*
* # Creating a detached editor
*
* Alternatively, you can initialize the editor by passing the initial data directly as a string.
* In this case, the editor will render an element that must be inserted into the DOM for the editor to work properly:
*
* BalloonEditor
* .create( '<p>Hello world!</p>' )
* .then( editor => {
* console.log( 'Editor was initialized', editor );
*
* // Initial data was provided so the editor UI element needs to be added manually to the DOM.
* document.body.appendChild( editor.ui.element );
* } )
* .catch( err => {
* console.error( err.stack );
* } );
*
* This lets you dynamically append the editor to your web page whenever it is convenient for you. You may use this method if your
* web page content is generated on the client side and the DOM structure is not ready at the moment when you initialize the editor.
*
* # Using an existing DOM element (and data provided in `config.initialData`)
*
* You can also mix these two ways by providing a DOM element to be used and passing the initial data through the configuration:
*
* BalloonEditor
* .create( document.querySelector( '#editor' ), {
* initialData: '<h2>Initial data</h2><p>Foo bar.</p>'
* } )
* .then( editor => {
* console.log( 'Editor was initialized', editor );
* } )
* .catch( err => {
* console.error( err.stack );
* } );
*
* This method can be used to initialize the editor on an existing element with the specified content in case if your integration
* makes it difficult to set the content of the source element.
*
* Note that an error will be thrown if you pass the initial data both as the first parameter and also in the configuration.
*
* # Configuring the editor
*
* See the {@link module:core/editor/editorconfig~EditorConfig editor configuration documentation} to learn more about
* customizing plugins, toolbar and more.
*
* # Using the editor from source
*
* The code samples listed in the previous sections of this documentation assume that you are using an
* {@glink installation/getting-started/predefined-builds editor build} (for example – `@ckeditor/ckeditor5-build-balloon`).
*
* If you want to use the balloon editor from source (`@ckeditor/ckeditor5-editor-balloon/src/ballooneditor`),
* you need to define the list of
* {@link module:core/editor/editorconfig~EditorConfig#plugins plugins to be initialized} and
* {@link module:core/editor/editorconfig~EditorConfig#toolbar toolbar items}. Read more about using the editor from
* source in the {@glink installation/advanced/alternative-setups/integrating-from-source dedicated guide}.
*
* @param {HTMLElement|String} sourceElementOrData The DOM element that will be the source for the created editor
* or the editor's initial data.
*
* If a DOM element is passed, its content will be automatically loaded to the editor upon initialization.
* The editor data will be set back to the original element once the editor is destroyed only if the
* {@link module:core/editor/editorconfig~EditorConfig#updateSourceElementOnDestroy updateSourceElementOnDestroy}
* option is set to `true`.
*
* If the initial data is passed, a detached editor will be created. In this case you need to insert it into the DOM manually.
* It is available under the {@link module:editor-balloon/ballooneditorui~BalloonEditorUI#element `editor.ui.element`} property.
*
* @param {module:core/editor/editorconfig~EditorConfig} [config] The editor configuration.
* @returns {Promise} A promise resolved once the editor is ready. The promise resolves with the created editor instance.
*/
static create( sourceElementOrData, config = {} ) {
return new Promise( resolve => {
if ( isElement( sourceElementOrData ) && sourceElementOrData.tagName === 'TEXTAREA' ) {
// Documented in core/editor/editor.js
// eslint-disable-next-line ckeditor5-rules/ckeditor-error-message
throw new CKEditorError( 'editor-wrong-element', null );
}
const editor = new this( sourceElementOrData, config );
resolve(
editor.initPlugins()
.then( () => editor.ui.init() )
.then( () => editor.data.init( editor.config.get( 'initialData' ) ) )
.then( () => editor.fire( 'ready' ) )
.then( () => editor )
);
} );
}
export default class BalloonEditor extends DataApiMixin(ElementApiMixin(Editor)) {
/**
* Creates an instance of the balloon editor.
*
* **Note:** do not use the constructor to create editor instances. Use the static
* {@link module:editor-balloon/ballooneditor~BalloonEditor.create `BalloonEditor.create()`} method instead.
*
* @param sourceElementOrData The DOM element that will be the source for the created editor
* (on which the editor will be initialized) or initial data for the editor. For more information see
* {@link module:editor-balloon/ballooneditor~BalloonEditor.create `BalloonEditor.create()`}.
* @param config The editor configuration.
*/
constructor(sourceElementOrData, config = {}) {
// If both `config.initialData` is set and initial data is passed as the constructor parameter, then throw.
if (!isElement(sourceElementOrData) && config.initialData !== undefined) {
// Documented in core/editor/editorconfig.jsdoc.
// eslint-disable-next-line ckeditor5-rules/ckeditor-error-message
throw new CKEditorError('editor-create-initial-data', null);
}
super(config);
if (this.config.get('initialData') === undefined) {
this.config.set('initialData', getInitialData(sourceElementOrData));
}
if (isElement(sourceElementOrData)) {
this.sourceElement = sourceElementOrData;
secureSourceElement(this);
}
const plugins = this.config.get('plugins');
plugins.push(BalloonToolbar);
this.config.set('plugins', plugins);
this.config.define('balloonToolbar', this.config.get('toolbar'));
this.model.document.createRoot();
const view = new BalloonEditorUIView(this.locale, this.editing.view, this.sourceElement);
this.ui = new BalloonEditorUI(this, view);
attachToForm(this);
}
/**
* Destroys the editor instance, releasing all resources used by it.
*
* Updates the original editor element with the data if the
* {@link module:core/editor/editorconfig~EditorConfig#updateSourceElementOnDestroy `updateSourceElementOnDestroy`}
* configuration option is set to `true`.
*/
destroy() {
// Cache the data, then destroy.
// It's safe to assume that the model->view conversion will not work after super.destroy().
const data = this.getData();
this.ui.destroy();
return super.destroy()
.then(() => {
if (this.sourceElement) {
this.updateSourceElement(data);
}
});
}
/**
* Creates a new balloon editor instance.
*
* There are three general ways how the editor can be initialized.
*
* # Using an existing DOM element (and loading data from it)
*
* You can initialize the editor using an existing DOM element:
*
* ```ts
* BalloonEditor
* .create( document.querySelector( '#editor' ) )
* .then( editor => {
* console.log( 'Editor was initialized', editor );
* } )
* .catch( err => {
* console.error( err.stack );
* } );
* ```
*
* The element's content will be used as the editor data and the element will become the editable element.
*
* # Creating a detached editor
*
* Alternatively, you can initialize the editor by passing the initial data directly as a string.
* In this case, the editor will render an element that must be inserted into the DOM for the editor to work properly:
*
* ```ts
* BalloonEditor
* .create( '<p>Hello world!</p>' )
* .then( editor => {
* console.log( 'Editor was initialized', editor );
*
* // Initial data was provided so the editor UI element needs to be added manually to the DOM.
* document.body.appendChild( editor.ui.element );
* } )
* .catch( err => {
* console.error( err.stack );
* } );
* ```
*
* This lets you dynamically append the editor to your web page whenever it is convenient for you. You may use this method if your
* web page content is generated on the client side and the DOM structure is not ready at the moment when you initialize the editor.
*
* # Using an existing DOM element (and data provided in `config.initialData`)
*
* You can also mix these two ways by providing a DOM element to be used and passing the initial data through the configuration:
*
* ```ts
* BalloonEditor
* .create( document.querySelector( '#editor' ), {
* initialData: '<h2>Initial data</h2><p>Foo bar.</p>'
* } )
* .then( editor => {
* console.log( 'Editor was initialized', editor );
* } )
* .catch( err => {
* console.error( err.stack );
* } );
* ```
*
* This method can be used to initialize the editor on an existing element with the specified content in case if your integration
* makes it difficult to set the content of the source element.
*
* Note that an error will be thrown if you pass the initial data both as the first parameter and also in the configuration.
*
* # Configuring the editor
*
* See the {@link module:core/editor/editorconfig~EditorConfig editor configuration documentation} to learn more about
* customizing plugins, toolbar and more.
*
* # Using the editor from source
*
* The code samples listed in the previous sections of this documentation assume that you are using an
* {@glink installation/getting-started/predefined-builds editor build} (for example – `@ckeditor/ckeditor5-build-balloon`).
*
* If you want to use the balloon editor from source (`@ckeditor/ckeditor5-editor-balloon/src/ballooneditor`),
* you need to define the list of
* {@link module:core/editor/editorconfig~EditorConfig#plugins plugins to be initialized} and
* {@link module:core/editor/editorconfig~EditorConfig#toolbar toolbar items}. Read more about using the editor from
* source in the {@glink installation/advanced/alternative-setups/integrating-from-source dedicated guide}.
*
* @param sourceElementOrData The DOM element that will be the source for the created editor
* or the editor's initial data.
*
* If a DOM element is passed, its content will be automatically loaded to the editor upon initialization.
* The editor data will be set back to the original element once the editor is destroyed only if the
* {@link module:core/editor/editorconfig~EditorConfig#updateSourceElementOnDestroy updateSourceElementOnDestroy}
* option is set to `true`.
*
* If the initial data is passed, a detached editor will be created. In this case you need to insert it into the DOM manually.
* It is available under the {@link module:editor-balloon/ballooneditorui~BalloonEditorUI#element `editor.ui.element`} property.
*
* @param config The editor configuration.
* @returns A promise resolved once the editor is ready. The promise resolves with the created editor instance.
*/
static create(sourceElementOrData, config = {}) {
return new Promise(resolve => {
if (isElement(sourceElementOrData) && sourceElementOrData.tagName === 'TEXTAREA') {
// Documented in core/editor/editor.js
// eslint-disable-next-line ckeditor5-rules/ckeditor-error-message
throw new CKEditorError('editor-wrong-element', null);
}
const editor = new this(sourceElementOrData, config);
resolve(editor.initPlugins()
.then(() => editor.ui.init())
.then(() => editor.data.init(editor.config.get('initialData')))
.then(() => editor.fire('ready'))
.then(() => editor));
});
}
}
mix( BalloonEditor, DataApiMixin );
mix( BalloonEditor, ElementApiMixin );
function getInitialData( sourceElementOrData ) {
return isElement( sourceElementOrData ) ? getDataFromElement( sourceElementOrData ) : sourceElementOrData;
function getInitialData(sourceElementOrData) {
return isElement(sourceElementOrData) ? getDataFromElement(sourceElementOrData) : sourceElementOrData;
}
function isElement(value) {
return _isElement(value);
}

@@ -5,119 +5,90 @@ /**

*/
/**
* @module editor-balloon/ballooneditorui
*/
import { EditorUI } from 'ckeditor5/src/core';
import { enablePlaceholder } from 'ckeditor5/src/engine';
/**
* The balloon editor UI class.
*
* @extends module:core/editor/editorui~EditorUI
*/
export default class BalloonEditorUI extends EditorUI {
/**
* Creates an instance of the balloon editor UI class.
*
* @param {module:core/editor/editor~Editor} editor The editor instance.
* @param {module:ui/editorui/editoruiview~EditorUIView} view The view of the UI.
*/
constructor( editor, view ) {
super( editor );
/**
* The main (top–most) view of the editor UI.
*
* @readonly
* @member {module:ui/editorui/editoruiview~EditorUIView} #view
*/
this.view = view;
}
/**
* @inheritDoc
*/
get element() {
return this.view.editable.element;
}
/**
* Initializes the UI.
*/
init() {
const editor = this.editor;
const view = this.view;
const editingView = editor.editing.view;
const editable = view.editable;
const editingRoot = editingView.document.getRoot();
// The editable UI and editing root should share the same name. Then name is used
// to recognize the particular editable, for instance in ARIA attributes.
editable.name = editingRoot.rootName;
view.render();
// The editable UI element in DOM is available for sure only after the editor UI view has been rendered.
// But it can be available earlier if a DOM element has been passed to BalloonEditor.create().
const editableElement = editable.element;
// Register the editable UI view in the editor. A single editor instance can aggregate multiple
// editable areas (roots) but the balloon editor has only one.
this.setEditableElement( editable.name, editableElement );
// Let the editable UI element respond to the changes in the global editor focus
// tracker. It has been added to the same tracker a few lines above but, in reality, there are
// many focusable areas in the editor, like balloons, toolbars or dropdowns and as long
// as they have focus, the editable should act like it is focused too (although technically
// it isn't), e.g. by setting the proper CSS class, visually announcing focus to the user.
// Doing otherwise will result in editable focus styles disappearing, once e.g. the
// toolbar gets focused.
editable.bind( 'isFocused' ).to( this.focusTracker );
// Bind the editable UI element to the editing view, making it an end– and entry–point
// of the editor's engine. This is where the engine meets the UI.
editingView.attachDomRoot( editableElement );
this._initPlaceholder();
this.fire( 'ready' );
}
/**
* @inheritDoc
*/
destroy() {
super.destroy();
const view = this.view;
const editingView = this.editor.editing.view;
editingView.detachDomRoot( view.editable.name );
view.destroy();
}
/**
* Enable the placeholder text on the editing root, if any was configured.
*
* @private
*/
_initPlaceholder() {
const editor = this.editor;
const editingView = editor.editing.view;
const editingRoot = editingView.document.getRoot();
const sourceElement = editor.sourceElement;
const placeholderText = editor.config.get( 'placeholder' ) ||
sourceElement && sourceElement.tagName.toLowerCase() === 'textarea' && sourceElement.getAttribute( 'placeholder' );
if ( placeholderText ) {
enablePlaceholder( {
view: editingView,
element: editingRoot,
text: placeholderText,
isDirectHost: false,
keepOnFocus: true
} );
}
}
/**
* Creates an instance of the balloon editor UI class.
*
* @param editor The editor instance.
* @param view The view of the UI.
*/
constructor(editor, view) {
super(editor);
this.view = view;
}
/**
* @inheritDoc
*/
get element() {
return this.view.editable.element;
}
/**
* Initializes the UI.
*/
init() {
const editor = this.editor;
const view = this.view;
const editingView = editor.editing.view;
const editable = view.editable;
const editingRoot = editingView.document.getRoot();
// The editable UI and editing root should share the same name. Then name is used
// to recognize the particular editable, for instance in ARIA attributes.
editable.name = editingRoot.rootName;
view.render();
// The editable UI element in DOM is available for sure only after the editor UI view has been rendered.
// But it can be available earlier if a DOM element has been passed to BalloonEditor.create().
const editableElement = editable.element;
// Register the editable UI view in the editor. A single editor instance can aggregate multiple
// editable areas (roots) but the balloon editor has only one.
this.setEditableElement(editable.name, editableElement);
// Let the editable UI element respond to the changes in the global editor focus
// tracker. It has been added to the same tracker a few lines above but, in reality, there are
// many focusable areas in the editor, like balloons, toolbars or dropdowns and as long
// as they have focus, the editable should act like it is focused too (although technically
// it isn't), e.g. by setting the proper CSS class, visually announcing focus to the user.
// Doing otherwise will result in editable focus styles disappearing, once e.g. the
// toolbar gets focused.
editable.bind('isFocused').to(this.focusTracker);
// Bind the editable UI element to the editing view, making it an end– and entry–point
// of the editor's engine. This is where the engine meets the UI.
editingView.attachDomRoot(editableElement);
this._initPlaceholder();
this.fire('ready');
}
/**
* @inheritDoc
*/
destroy() {
super.destroy();
const view = this.view;
const editingView = this.editor.editing.view;
editingView.detachDomRoot(view.editable.name);
view.destroy();
}
/**
* Enable the placeholder text on the editing root, if any was configured.
*/
_initPlaceholder() {
const editor = this.editor;
const editingView = editor.editing.view;
const editingRoot = editingView.document.getRoot();
const sourceElement = editor.sourceElement;
const placeholderText = editor.config.get('placeholder') ||
sourceElement && sourceElement.tagName.toLowerCase() === 'textarea' && sourceElement.getAttribute('placeholder');
if (placeholderText) {
enablePlaceholder({
view: editingView,
element: editingRoot,
text: placeholderText,
isDirectHost: false,
keepOnFocus: true
});
}
}
}

@@ -5,49 +5,34 @@ /**

*/
/**
* @module editor-balloon/ballooneditoruiview
*/
import { EditorUIView, InlineEditableUIView } from 'ckeditor5/src/ui';
/**
* Contextual editor UI view. Uses the {@link module:ui/editableui/inline/inlineeditableuiview~InlineEditableUIView}.
*
* @extends module:ui/editorui/editoruiview~EditorUIView
*/
export default class BalloonEditorUIView extends EditorUIView {
/**
* Creates an instance of the balloon editor UI view.
*
* @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance.
* @param {module:engine/view/view~View} editingView The editing view instance this view is related to.
* @param {HTMLElement} [editableElement] The editable element. If not specified, it will be automatically created by
* {@link module:ui/editableui/editableuiview~EditableUIView}. Otherwise, the given element will be used.
*/
constructor( locale, editingView, editableElement ) {
super( locale );
const t = locale.t;
/**
* The editable UI view.
*
* @readonly
* @member {module:ui/editableui/inline/inlineeditableuiview~InlineEditableUIView}
*/
this.editable = new InlineEditableUIView( locale, editingView, editableElement, {
label: editableView => {
return t( 'Rich Text Editor. Editing area: %0', editableView.name );
}
} );
}
/**
* @inheritDoc
*/
render() {
super.render();
this.registerChild( this.editable );
}
/**
* Creates an instance of the balloon editor UI view.
*
* @param locale The {@link module:core/editor/editor~Editor#locale} instance.
* @param editingView The editing view instance this view is related to.
* @param editableElement The editable element. If not specified, it will be automatically created by
* {@link module:ui/editableui/editableuiview~EditableUIView}. Otherwise, the given element will be used.
*/
constructor(locale, editingView, editableElement) {
super(locale);
const t = locale.t;
this.editable = new InlineEditableUIView(locale, editingView, editableElement, {
label: editableView => {
return t('Rich Text Editor. Editing area: %0', editableView.name);
}
});
}
/**
* @inheritDoc
*/
render() {
super.render();
this.registerChild(this.editable);
}
}

@@ -5,7 +5,5 @@ /**

*/
/**
* @module editor-balloon
*/
export { default as BalloonEditor } from './ballooneditor';
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc