@ckeditor/ckeditor5-ui 43.3.1 → 44.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -7
- package/dist/badge/badge.d.ts +133 -0
- package/dist/dropdown/dropdownview.d.ts +6 -0
- package/dist/editorui/bodycollection.d.ts +47 -12
- package/dist/editorui/editorui.d.ts +5 -0
- package/dist/editorui/evaluationbadge.d.ts +37 -0
- package/dist/editorui/poweredby.d.ts +12 -49
- package/dist/index-editor.css +52 -3
- package/dist/index.css +62 -3
- package/dist/index.css.map +1 -1
- package/dist/index.js +351 -144
- package/dist/index.js.map +1 -1
- package/dist/menubar/menubarmenupanelview.d.ts +1 -1
- package/dist/menubar/menubarmenuview.d.ts +5 -0
- package/dist/menubar/utils.d.ts +1 -0
- package/package.json +4 -4
- package/src/badge/badge.d.ts +129 -0
- package/src/badge/badge.js +218 -0
- package/src/dialog/dialogview.js +6 -2
- package/src/dropdown/dropdownview.d.ts +6 -0
- package/src/dropdown/dropdownview.js +9 -1
- package/src/editorui/bodycollection.d.ts +47 -12
- package/src/editorui/bodycollection.js +50 -19
- package/src/editorui/editorui.d.ts +5 -0
- package/src/editorui/editorui.js +3 -0
- package/src/editorui/evaluationbadge.d.ts +33 -0
- package/src/editorui/evaluationbadge.js +99 -0
- package/src/editorui/poweredby.d.ts +12 -49
- package/src/editorui/poweredby.js +36 -194
- package/src/menubar/menubarmenupanelview.d.ts +1 -1
- package/src/menubar/menubarmenuview.d.ts +5 -0
- package/src/menubar/menubarmenuview.js +23 -1
- package/src/menubar/utils.d.ts +1 -0
- package/src/menubar/utils.js +2 -0
- package/theme/globals/_evaluationbadge.css +54 -0
- package/theme/globals/_poweredby.css +15 -3
- package/theme/globals/globals.css +1 -0
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
4
|
*/
|
|
5
|
-
import { Collection, CKEditorError, EmitterMixin, isNode, toArray, DomEmitterMixin, ObservableMixin, isIterable, uid, env, delay, getEnvKeystrokeText, isVisible, global, KeystrokeHandler, FocusTracker, Rect, toUnit, createElement, ResizeObserver, getBorderWidths, logWarning, getOptimalPosition, isText, isRange, priorities, first,
|
|
5
|
+
import { Collection, CKEditorError, EmitterMixin, isNode, toArray, DomEmitterMixin, ObservableMixin, isIterable, uid, env, delay, getEnvKeystrokeText, isVisible, global, KeystrokeHandler, FocusTracker, Rect, toUnit, createElement, ResizeObserver, getBorderWidths, logWarning, getOptimalPosition, isText, isRange, priorities, first, parseBase64EncodedObject, getAncestors } from '@ckeditor/ckeditor5-utils/dist/index.js';
|
|
6
6
|
import { cloneDeepWith, isObject, isElement, debounce, throttle, cloneDeep, extend, escapeRegExp, escape } from 'lodash-es';
|
|
7
7
|
import { icons, Plugin, ContextPlugin } from '@ckeditor/ckeditor5-core/dist/index.js';
|
|
8
8
|
import parse from 'color-parse';
|
|
@@ -3459,10 +3459,14 @@ const toPx$6 = /* #__PURE__ */ toUnit('px');
|
|
|
3459
3459
|
*/ render() {
|
|
3460
3460
|
super.render();
|
|
3461
3461
|
this.keystrokes.set('Esc', (data, cancel)=>{
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3462
|
+
// Do not react to the Esc key if the event has already been handled and defaultPrevented
|
|
3463
|
+
// by some logic of the dialog guest (child) view (https://github.com/ckeditor/ckeditor5/issues/17343).
|
|
3464
|
+
if (!data.defaultPrevented) {
|
|
3465
|
+
this.fire('close', {
|
|
3466
|
+
source: 'escKeyPress'
|
|
3467
|
+
});
|
|
3468
|
+
cancel();
|
|
3469
|
+
}
|
|
3466
3470
|
});
|
|
3467
3471
|
// Support for dragging the modal.
|
|
3468
3472
|
this.on('drag', (evt, { deltaX, deltaY })=>{
|
|
@@ -4481,28 +4485,62 @@ var accessibilityIcon = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/20
|
|
|
4481
4485
|
}
|
|
4482
4486
|
|
|
4483
4487
|
/**
|
|
4484
|
-
* This is a special {@link module:ui/viewcollection~ViewCollection} dedicated to elements that are detached
|
|
4485
|
-
*
|
|
4488
|
+
* This is a special {@link module:ui/viewcollection~ViewCollection} dedicated to elements that are detached from the DOM structure of
|
|
4489
|
+
* the editor, like floating panels, floating toolbars, dialogs, etc.
|
|
4486
4490
|
*
|
|
4487
|
-
* The body collection is available
|
|
4491
|
+
* The body collection is available under the {@link module:ui/editorui/editoruiview~EditorUIView#body `editor.ui.view.body`} property.
|
|
4488
4492
|
* Any plugin can add a {@link module:ui/view~View view} to this collection.
|
|
4489
|
-
* These views will render in a container placed directly in the `<body>` element.
|
|
4490
|
-
* The editor will detach and destroy this collection when the editor will be {@link module:core/editor/editor~Editor#destroy destroyed}.
|
|
4491
4493
|
*
|
|
4492
|
-
*
|
|
4494
|
+
* All views added to a body collection render in a dedicated DOM container (`<div class="ck ck-body ...">...</div>`). All body collection
|
|
4495
|
+
* containers render in a common shared (`<div class="ck-body-wrapper">...</div>`) in the DOM to limit the pollution of
|
|
4496
|
+
* the `<body>` element. The resulting DOM structure is as follows:
|
|
4497
|
+
*
|
|
4498
|
+
* ```html
|
|
4499
|
+
* <body>
|
|
4500
|
+
* <!-- Content of the webpage... -->
|
|
4501
|
+
*
|
|
4502
|
+
* <!-- The shared wrapper for all body collection containers. -->
|
|
4503
|
+
* <div class="ck-body-wrapper">
|
|
4504
|
+
* <!-- The container of the first body collection instance. -->
|
|
4505
|
+
* <div class="ck ck-body ...">
|
|
4506
|
+
* <!-- View elements belonging to the first body collection -->
|
|
4507
|
+
* </div>
|
|
4508
|
+
*
|
|
4509
|
+
* <!-- The container of the second body collection instance. -->
|
|
4510
|
+
* <div class="ck ck-body ...">...</div>
|
|
4511
|
+
*
|
|
4512
|
+
* <!-- More body collection containers for the rest of instances... -->
|
|
4513
|
+
* </div>
|
|
4514
|
+
* </body>
|
|
4515
|
+
* ```
|
|
4493
4516
|
*
|
|
4494
|
-
*
|
|
4495
|
-
*
|
|
4496
|
-
*
|
|
4497
|
-
*
|
|
4517
|
+
* By default, the {@link module:ui/editorui/editoruiview~EditorUIView `editor.ui.view`} manages the life cycle of the
|
|
4518
|
+
* {@link module:ui/editorui/editoruiview~EditorUIView#body `editor.ui.view.body`} collection, attaching and detaching it
|
|
4519
|
+
* when the editor gets created or {@link module:core/editor/editor~Editor#destroy destroyed}.
|
|
4520
|
+
*
|
|
4521
|
+
* # Custom body collection instances
|
|
4522
|
+
*
|
|
4523
|
+
* Even though most editor instances come with a built-in body collection
|
|
4524
|
+
* ({@link module:ui/editorui/editoruiview~EditorUIView#body `editor.ui.view.body`}), you can create your own instance of this
|
|
4525
|
+
* class if you need to control their life cycle.
|
|
4526
|
+
*
|
|
4527
|
+
* The life cycle of a custom body collection must be handled manually by the developer using the dedicated API:
|
|
4528
|
+
* * A body collection will render itself automatically in the DOM as soon as you call {@link ~BodyCollection#attachToDom}.
|
|
4529
|
+
* * Calling {@link ~BodyCollection#detachFromDom} will remove the collection from the DOM.
|
|
4530
|
+
*
|
|
4531
|
+
* **Note**: The shared collection wrapper (`<div class="ck-body-wrapper">...</div>`) gets automatically removed from DOM when the
|
|
4532
|
+
* last body collection is {@link ~BodyCollection#detachFromDom detached} and does not require any special handling.
|
|
4498
4533
|
*/ class BodyCollection extends ViewCollection {
|
|
4499
4534
|
/**
|
|
4500
4535
|
* The {@link module:core/editor/editor~Editor#locale editor's locale} instance.
|
|
4501
4536
|
* See the view {@link module:ui/view~View#locale locale} property.
|
|
4502
4537
|
*/ locale;
|
|
4503
4538
|
/**
|
|
4504
|
-
* The element holding elements of the body
|
|
4539
|
+
* The element holding elements of the body collection.
|
|
4505
4540
|
*/ _bodyCollectionContainer;
|
|
4541
|
+
/**
|
|
4542
|
+
* The wrapper element that holds all of the {@link #_bodyCollectionContainer} elements.
|
|
4543
|
+
*/ static _bodyWrapper;
|
|
4506
4544
|
/**
|
|
4507
4545
|
* Creates a new instance of the {@link module:ui/editorui/bodycollection~BodyCollection}.
|
|
4508
4546
|
*
|
|
@@ -4513,7 +4551,7 @@ var accessibilityIcon = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/20
|
|
|
4513
4551
|
this.locale = locale;
|
|
4514
4552
|
}
|
|
4515
4553
|
/**
|
|
4516
|
-
* The element holding elements of the body
|
|
4554
|
+
* The element holding elements of the body collection.
|
|
4517
4555
|
*/ get bodyCollectionContainer() {
|
|
4518
4556
|
return this._bodyCollectionContainer;
|
|
4519
4557
|
}
|
|
@@ -4535,14 +4573,14 @@ var accessibilityIcon = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/20
|
|
|
4535
4573
|
},
|
|
4536
4574
|
children: this
|
|
4537
4575
|
}).render();
|
|
4538
|
-
|
|
4539
|
-
if (!
|
|
4540
|
-
|
|
4576
|
+
// Create a shared wrapper if there were none or the previous one got disconnected from DOM.
|
|
4577
|
+
if (!BodyCollection._bodyWrapper || !BodyCollection._bodyWrapper.isConnected) {
|
|
4578
|
+
BodyCollection._bodyWrapper = createElement(document, 'div', {
|
|
4541
4579
|
class: 'ck-body-wrapper'
|
|
4542
4580
|
});
|
|
4543
|
-
document.body.appendChild(
|
|
4581
|
+
document.body.appendChild(BodyCollection._bodyWrapper);
|
|
4544
4582
|
}
|
|
4545
|
-
|
|
4583
|
+
BodyCollection._bodyWrapper.appendChild(this._bodyCollectionContainer);
|
|
4546
4584
|
}
|
|
4547
4585
|
/**
|
|
4548
4586
|
* Detaches the collection from the DOM structure. Use this method when you do not need to use the body collection
|
|
@@ -4552,9 +4590,9 @@ var accessibilityIcon = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/20
|
|
|
4552
4590
|
if (this._bodyCollectionContainer) {
|
|
4553
4591
|
this._bodyCollectionContainer.remove();
|
|
4554
4592
|
}
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4593
|
+
if (BodyCollection._bodyWrapper && !BodyCollection._bodyWrapper.childElementCount) {
|
|
4594
|
+
BodyCollection._bodyWrapper.remove();
|
|
4595
|
+
delete BodyCollection._bodyWrapper;
|
|
4558
4596
|
}
|
|
4559
4597
|
}
|
|
4560
4598
|
}
|
|
@@ -5948,7 +5986,7 @@ function getTextareaElementClone(element, value) {
|
|
|
5948
5986
|
fitInViewport: true,
|
|
5949
5987
|
positions: this._panelPositions
|
|
5950
5988
|
});
|
|
5951
|
-
this.panelView.position = optimalPanelPosition ? optimalPanelPosition.name : this.
|
|
5989
|
+
this.panelView.position = optimalPanelPosition ? optimalPanelPosition.name : this._defaultPanelPositionName;
|
|
5952
5990
|
} else {
|
|
5953
5991
|
this.panelView.position = this.panelPosition;
|
|
5954
5992
|
}
|
|
@@ -6018,6 +6056,13 @@ function getTextareaElementClone(element, value) {
|
|
|
6018
6056
|
];
|
|
6019
6057
|
}
|
|
6020
6058
|
}
|
|
6059
|
+
/**
|
|
6060
|
+
* Returns the default position of the dropdown panel based on the direction of the UI language.
|
|
6061
|
+
* It is used when the {@link #panelPosition} is set to `'auto'` and the panel has not found a
|
|
6062
|
+
* suitable position to fit into the viewport.
|
|
6063
|
+
*/ get _defaultPanelPositionName() {
|
|
6064
|
+
return this.locale.uiLanguageDirection === 'rtl' ? 'sw' : 'se';
|
|
6065
|
+
}
|
|
6021
6066
|
/**
|
|
6022
6067
|
* A set of positioning functions used by the dropdown view to determine
|
|
6023
6068
|
* the optimal position (i.e. fitting into the browser viewport) of its
|
|
@@ -11795,57 +11840,51 @@ function createMutationObserver(callback) {
|
|
|
11795
11840
|
};
|
|
11796
11841
|
}
|
|
11797
11842
|
|
|
11798
|
-
var poweredByIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"53\" height=\"10\" viewBox=\"0 0 53 10\"><path fill=\"#1C2331\" d=\"M31.724 1.492a15.139 15.139 0 0 0 .045 1.16 2.434 2.434 0 0 0-.687-.34 3.68 3.68 0 0 0-1.103-.166 2.332 2.332 0 0 0-1.14.255 1.549 1.549 0 0 0-.686.87c-.15.41-.225.98-.225 1.712 0 .939.148 1.659.444 2.161.297.503.792.754 1.487.754.452.015.9-.094 1.294-.316.296-.174.557-.4.771-.669l.14.852h1.282V.007h-1.623v1.485ZM31 6.496a1.77 1.77 0 0 1-.494.061.964.964 0 0 1-.521-.127.758.758 0 0 1-.296-.466 3.984 3.984 0 0 1-.093-.992 4.208 4.208 0 0 1 .098-1.052.753.753 0 0 1 .307-.477 1.08 1.08 0 0 1 .55-.122c.233-.004.466.026.69.089l.483.144v2.553c-.11.076-.213.143-.307.2a1.73 1.73 0 0 1-.417.189ZM35.68 0l-.702.004c-.322.002-.482.168-.48.497l.004.581c.002.33.164.493.486.49l.702-.004c.322-.002.481-.167.48-.496L36.165.49c-.002-.33-.164-.493-.486-.491ZM36.145 2.313l-1.612.01.034 5.482 1.613-.01-.035-5.482ZM39.623.79 37.989.8 38 2.306l-.946.056.006 1.009.949-.006.024 2.983c.003.476.143.844.419 1.106.275.26.658.39 1.148.387.132 0 .293-.01.483-.03.19-.02.38-.046.57-.08.163-.028.324-.068.482-.119l-.183-1.095-.702.004a.664.664 0 0 1-.456-.123.553.553 0 0 1-.14-.422l-.016-2.621 1.513-.01-.006-1.064-1.514.01-.01-1.503ZM46.226 2.388c-.41-.184-.956-.274-1.636-.27-.673.004-1.215.101-1.627.29-.402.179-.72.505-.888.91-.18.419-.268.979-.264 1.68.004.688.1 1.24.285 1.655.172.404.495.724.9.894.414.18.957.268 1.63.264.68-.004 1.224-.099 1.632-.284.4-.176.714-.501.878-.905.176-.418.263-.971.258-1.658-.004-.702-.097-1.261-.28-1.677a1.696 1.696 0 0 0-.888-.9Zm-.613 3.607a.77.77 0 0 1-.337.501 1.649 1.649 0 0 1-1.317.009.776.776 0 0 1-.343-.497 4.066 4.066 0 0 1-.105-1.02 4.136 4.136 0 0 1 .092-1.03.786.786 0 0 1 .337-.507 1.59 1.59 0 0 1 1.316-.008.79.79 0 0 1 .344.502c.078.337.113.683.105 1.03.012.343-.019.685-.092 1.02ZM52.114 2.07a2.67 2.67 0 0 0-1.128.278c-.39.191-.752.437-1.072.73l-.157-.846-1.273.008.036 5.572 1.623-.01-.024-3.78c.35-.124.646-.22.887-.286.26-.075.53-.114.8-.118l.45-.003.144-1.546-.286.001ZM22.083 7.426l-1.576-2.532a2.137 2.137 0 0 0-.172-.253 1.95 1.95 0 0 0-.304-.29.138.138 0 0 1 .042-.04 1.7 1.7 0 0 0 .328-.374l1.75-2.71c.01-.015.025-.028.024-.048-.01-.01-.021-.007-.031-.007L20.49 1.17a.078.078 0 0 0-.075.045l-.868 1.384c-.23.366-.46.732-.688 1.099a.108.108 0 0 1-.112.06c-.098-.005-.196-.001-.294-.002-.018 0-.038.006-.055-.007.002-.02.002-.039.005-.058a4.6 4.6 0 0 0 .046-.701V1.203c0-.02-.009-.032-.03-.03h-.033L16.93 1.17c-.084 0-.073-.01-.073.076v6.491c-.001.018.006.028.025.027h1.494c.083 0 .072.007.072-.071v-2.19c0-.055-.003-.11-.004-.166a3.366 3.366 0 0 0-.05-.417h.06c.104 0 .209.002.313-.002a.082.082 0 0 1 .084.05c.535.913 1.07 1.824 1.607 2.736a.104.104 0 0 0 .103.062c.554-.003 1.107-.002 1.66-.002l.069-.003-.019-.032-.188-.304ZM27.112 6.555c-.005-.08-.004-.08-.082-.08h-2.414c-.053 0-.106-.003-.159-.011a.279.279 0 0 1-.246-.209.558.558 0 0 1-.022-.15c0-.382 0-.762-.002-1.143 0-.032.007-.049.042-.044h2.504c.029.003.037-.012.034-.038V3.814c0-.089.013-.078-.076-.078h-2.44c-.07 0-.062.003-.062-.06v-.837c0-.047.004-.093.013-.14a.283.283 0 0 1 .241-.246.717.717 0 0 1 .146-.011h2.484c.024.002.035-.009.036-.033l.003-.038.03-.496c.01-.183.024-.365.034-.548.005-.085.003-.087-.082-.094-.218-.018-.437-.038-.655-.05a17.845 17.845 0 0 0-.657-.026 72.994 72.994 0 0 0-1.756-.016 1.7 1.7 0 0 0-.471.064 1.286 1.286 0 0 0-.817.655c-.099.196-.149.413-.145.633v3.875c0 .072.003.144.011.216a1.27 1.27 0 0 0 .711 1.029c.228.113.48.167.734.158.757-.005 1.515.002 2.272-.042.274-.016.548-.034.82-.053.03-.002.043-.008.04-.041-.008-.104-.012-.208-.019-.312a69.964 69.964 0 0 1-.05-.768ZM16.14 7.415l-.127-1.075c-.004-.03-.014-.04-.044-.037a13.125 13.125 0 0 1-.998.073c-.336.01-.672.02-1.008.016-.116-.001-.233-.014-.347-.039a.746.746 0 0 1-.45-.262c-.075-.1-.132-.211-.167-.33a3.324 3.324 0 0 1-.126-.773 9.113 9.113 0 0 1-.015-.749c0-.285.022-.57.065-.852.023-.158.066-.312.127-.46a.728.728 0 0 1 .518-.443 1.64 1.64 0 0 1 .397-.048c.628-.001 1.255.003 1.882.05.022.001.033-.006.036-.026l.003-.031.06-.55c.019-.177.036-.355.057-.532.004-.034-.005-.046-.04-.056a5.595 5.595 0 0 0-1.213-.21 10.783 10.783 0 0 0-.708-.02c-.24-.003-.48.01-.719.041a3.477 3.477 0 0 0-.625.14 1.912 1.912 0 0 0-.807.497c-.185.2-.33.433-.424.688a4.311 4.311 0 0 0-.24 1.096c-.031.286-.045.572-.042.86-.006.43.024.86.091 1.286.04.25.104.497.193.734.098.279.26.53.473.734.214.205.473.358.756.446.344.11.702.17 1.063.177a8.505 8.505 0 0 0 1.578-.083 6.11 6.11 0 0 0 .766-.18c.03-.008.047-.023.037-.057a.157.157 0 0 1-.003-.025Z\"/><path fill=\"#AFE229\" d=\"M6.016 6.69a1.592 1.592 0 0 0-.614.21c-.23.132-.422.32-.56.546-.044.072-.287.539-.287.539l-.836 1.528.009.006c.038.025.08.046.123.063.127.046.26.07.395.073.505.023 1.011-.007 1.517-.003.29.009.58.002.869-.022a.886.886 0 0 0 .395-.116.962.962 0 0 0 .312-.286c.056-.083.114-.163.164-.249.24-.408.48-.816.718-1.226.075-.128.148-.257.222-.386l.112-.192a1.07 1.07 0 0 0 .153-.518l-1.304.023s-1.258-.005-1.388.01Z\"/><path fill=\"#771BFF\" d=\"m2.848 9.044.76-1.39.184-.352c-.124-.067-.245-.14-.367-.21-.346-.204-.706-.384-1.045-.6a.984.984 0 0 1-.244-.207c-.108-.134-.136-.294-.144-.46-.021-.409-.002-.818-.009-1.227-.003-.195 0-.39.003-.585.004-.322.153-.553.427-.713l.833-.488c.22-.13.44-.257.662-.385.05-.029.105-.052.158-.077.272-.128.519-.047.76.085l.044.028c.123.06.242.125.358.196.318.178.635.357.952.537.095.056.187.117.275.184.194.144.254.35.266.578.016.284.007.569.006.853-.001.28.004.558 0 .838.592-.003 1.259 0 1.259 0l.723-.013c-.003-.292-.007-.584-.007-.876 0-.524.015-1.048-.016-1.571-.024-.42-.135-.8-.492-1.067a5.02 5.02 0 0 0-.506-.339A400.52 400.52 0 0 0 5.94.787C5.722.664 5.513.524 5.282.423 5.255.406 5.228.388 5.2.373 4.758.126 4.305-.026 3.807.21c-.097.046-.197.087-.29.14A699.896 699.896 0 0 0 .783 1.948c-.501.294-.773.717-.778 1.31-.004.36-.009.718-.001 1.077.016.754-.017 1.508.024 2.261.016.304.07.6.269.848.127.15.279.28.448.382.622.4 1.283.734 1.92 1.11l.183.109Z\"/></svg>\n";
|
|
11799
|
-
|
|
11800
|
-
const ICON_WIDTH = 53;
|
|
11801
|
-
const ICON_HEIGHT = 10;
|
|
11802
11843
|
// ⚠ Note, whenever changing the threshold, make sure to update the docs/support/managing-ckeditor-logo.md docs
|
|
11803
11844
|
// as this information is also mentioned there ⚠.
|
|
11804
11845
|
const NARROW_ROOT_HEIGHT_THRESHOLD = 50;
|
|
11805
11846
|
const NARROW_ROOT_WIDTH_THRESHOLD = 350;
|
|
11806
|
-
const DEFAULT_LABEL = 'Powered by';
|
|
11807
11847
|
/**
|
|
11808
|
-
* A helper that enables the
|
|
11809
|
-
*
|
|
11848
|
+
* A helper that enables the badge feature in the editor and renders a custom view next to the bottom of the editable element
|
|
11849
|
+
* (editor root, source editing area, etc.) when the editor is focused.
|
|
11810
11850
|
*
|
|
11811
11851
|
* @private
|
|
11812
|
-
*/ class
|
|
11852
|
+
*/ class Badge extends /* #__PURE__ */ DomEmitterMixin() {
|
|
11813
11853
|
/**
|
|
11814
11854
|
* Editor instance the helper was created for.
|
|
11815
11855
|
*/ editor;
|
|
11816
11856
|
/**
|
|
11817
|
-
* A reference to the balloon panel hosting and positioning the
|
|
11818
|
-
*/ _balloonView;
|
|
11857
|
+
* A reference to the balloon panel hosting and positioning the badge content.
|
|
11858
|
+
*/ _balloonView = null;
|
|
11819
11859
|
/**
|
|
11820
11860
|
* A throttled version of the {@link #_showBalloon} method meant for frequent use to avoid performance loss.
|
|
11821
|
-
*/ _showBalloonThrottled
|
|
11861
|
+
*/ _showBalloonThrottled = throttle(()=>this._showBalloon(), 50, {
|
|
11862
|
+
leading: true
|
|
11863
|
+
});
|
|
11822
11864
|
/**
|
|
11823
11865
|
* A reference to the last editable element (root, source editing area, etc.) focused by the user.
|
|
11824
11866
|
* Since the focus can move to other focusable elements in the UI, this reference allows positioning the balloon over the
|
|
11825
11867
|
* right element whether the user is typing or using the UI.
|
|
11826
|
-
*/ _lastFocusedEditableElement;
|
|
11868
|
+
*/ _lastFocusedEditableElement = null;
|
|
11869
|
+
/**
|
|
11870
|
+
* An additional CSS class added to the `BalloonView`.
|
|
11871
|
+
*/ _balloonClass;
|
|
11827
11872
|
/**
|
|
11828
|
-
* Creates a
|
|
11873
|
+
* Creates a badge for a given editor. The feature is initialized on Editor#ready
|
|
11829
11874
|
* event.
|
|
11830
|
-
|
|
11831
|
-
* @param editor
|
|
11832
|
-
*/ constructor(editor){
|
|
11875
|
+
*/ constructor(editor, options = {}){
|
|
11833
11876
|
super();
|
|
11834
11877
|
this.editor = editor;
|
|
11835
|
-
this.
|
|
11836
|
-
this.
|
|
11837
|
-
this._showBalloonThrottled = throttle(this._showBalloon.bind(this), 50, {
|
|
11838
|
-
leading: true
|
|
11839
|
-
});
|
|
11840
|
-
editor.on('ready', this._handleEditorReady.bind(this));
|
|
11878
|
+
this._balloonClass = options.balloonClass;
|
|
11879
|
+
editor.on('ready', ()=>this._handleEditorReady());
|
|
11841
11880
|
}
|
|
11842
11881
|
/**
|
|
11843
|
-
* Destroys the
|
|
11882
|
+
* Destroys the badge along with its view.
|
|
11844
11883
|
*/ destroy() {
|
|
11845
11884
|
const balloon = this._balloonView;
|
|
11846
11885
|
if (balloon) {
|
|
11847
11886
|
// Balloon gets destroyed by the body collection.
|
|
11848
|
-
// The
|
|
11887
|
+
// The badge view gets destroyed by the balloon.
|
|
11849
11888
|
balloon.unpin();
|
|
11850
11889
|
this._balloonView = null;
|
|
11851
11890
|
}
|
|
@@ -11853,14 +11892,13 @@ const DEFAULT_LABEL = 'Powered by';
|
|
|
11853
11892
|
this.stopListening();
|
|
11854
11893
|
}
|
|
11855
11894
|
/**
|
|
11856
|
-
* Enables
|
|
11895
|
+
* Enables badge label once the editor (ui) is ready.
|
|
11857
11896
|
*/ _handleEditorReady() {
|
|
11858
11897
|
const editor = this.editor;
|
|
11859
|
-
|
|
11860
|
-
/* istanbul ignore next -- @preserve */ if (!forceVisible && verifyLicense(editor.config.get('licenseKey')) === 'VALID') {
|
|
11898
|
+
if (!this._isEnabled()) {
|
|
11861
11899
|
return;
|
|
11862
11900
|
}
|
|
11863
|
-
// No view means no body collection to append the
|
|
11901
|
+
// No view means no body collection to append the badge balloon to.
|
|
11864
11902
|
if (!editor.ui.view) {
|
|
11865
11903
|
return;
|
|
11866
11904
|
}
|
|
@@ -11883,41 +11921,63 @@ const DEFAULT_LABEL = 'Powered by';
|
|
|
11883
11921
|
});
|
|
11884
11922
|
}
|
|
11885
11923
|
/**
|
|
11886
|
-
*
|
|
11887
|
-
|
|
11888
|
-
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
|
|
11892
|
-
|
|
11893
|
-
|
|
11894
|
-
balloon.set({
|
|
11895
|
-
class: 'ck-powered-by-balloon'
|
|
11896
|
-
});
|
|
11897
|
-
editor.ui.view.body.add(balloon);
|
|
11898
|
-
this._balloonView = balloon;
|
|
11924
|
+
* Returns normalized configuration for the badge.
|
|
11925
|
+
*/ _getNormalizedConfig() {
|
|
11926
|
+
return {
|
|
11927
|
+
side: this.editor.locale.contentLanguageDirection === 'ltr' ? 'right' : 'left',
|
|
11928
|
+
position: 'border',
|
|
11929
|
+
verticalOffset: 0,
|
|
11930
|
+
horizontalOffset: 5
|
|
11931
|
+
};
|
|
11899
11932
|
}
|
|
11900
11933
|
/**
|
|
11901
|
-
* Attempts to display the balloon with the
|
|
11934
|
+
* Attempts to display the balloon with the badge view.
|
|
11902
11935
|
*/ _showBalloon() {
|
|
11903
|
-
|
|
11936
|
+
const attachOptions = this._getBalloonAttachOptions();
|
|
11937
|
+
if (!attachOptions) {
|
|
11904
11938
|
return;
|
|
11905
11939
|
}
|
|
11906
|
-
|
|
11907
|
-
|
|
11908
|
-
if (!this._balloonView) {
|
|
11909
|
-
this._createBalloonView();
|
|
11910
|
-
}
|
|
11911
|
-
this._balloonView.pin(attachOptions);
|
|
11940
|
+
if (!this._balloonView) {
|
|
11941
|
+
this._balloonView = this._createBalloonView();
|
|
11912
11942
|
}
|
|
11943
|
+
this._balloonView.pin(attachOptions);
|
|
11913
11944
|
}
|
|
11914
11945
|
/**
|
|
11915
|
-
* Hides the
|
|
11946
|
+
* Hides the badge balloon if already visible.
|
|
11916
11947
|
*/ _hideBalloon() {
|
|
11917
11948
|
if (this._balloonView) {
|
|
11918
11949
|
this._balloonView.unpin();
|
|
11919
11950
|
}
|
|
11920
11951
|
}
|
|
11952
|
+
/**
|
|
11953
|
+
* Creates an instance of the {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView balloon panel}
|
|
11954
|
+
* with the badge view inside ready for positioning.
|
|
11955
|
+
*/ _createBalloonView() {
|
|
11956
|
+
const editor = this.editor;
|
|
11957
|
+
const balloon = new BalloonPanelView();
|
|
11958
|
+
const view = this._createBadgeContent();
|
|
11959
|
+
balloon.content.add(view);
|
|
11960
|
+
if (this._balloonClass) {
|
|
11961
|
+
balloon.class = this._balloonClass;
|
|
11962
|
+
}
|
|
11963
|
+
editor.ui.view.body.add(balloon);
|
|
11964
|
+
return balloon;
|
|
11965
|
+
}
|
|
11966
|
+
/**
|
|
11967
|
+
* Returns the options for attaching the balloon to the focused editable element.
|
|
11968
|
+
*/ _getBalloonAttachOptions() {
|
|
11969
|
+
if (!this._lastFocusedEditableElement) {
|
|
11970
|
+
return null;
|
|
11971
|
+
}
|
|
11972
|
+
const badgeConfig = this._getNormalizedConfig();
|
|
11973
|
+
const positioningFunction = badgeConfig.side === 'right' ? getLowerRightCornerPosition(this._lastFocusedEditableElement, badgeConfig) : getLowerLeftCornerPosition(this._lastFocusedEditableElement, badgeConfig);
|
|
11974
|
+
return {
|
|
11975
|
+
target: this._lastFocusedEditableElement,
|
|
11976
|
+
positions: [
|
|
11977
|
+
positioningFunction
|
|
11978
|
+
]
|
|
11979
|
+
};
|
|
11980
|
+
}
|
|
11921
11981
|
/**
|
|
11922
11982
|
* Updates the {@link #_lastFocusedEditableElement} based on the state of the global focus tracker.
|
|
11923
11983
|
*/ _updateLastFocusedEditableElement() {
|
|
@@ -11934,17 +11994,113 @@ const DEFAULT_LABEL = 'Powered by';
|
|
|
11934
11994
|
if (editableEditorElements.includes(focusedElement)) {
|
|
11935
11995
|
this._lastFocusedEditableElement = focusedElement;
|
|
11936
11996
|
} else {
|
|
11937
|
-
// If it's none of the editable element, then the focus is somewhere in the UI. Let's display
|
|
11997
|
+
// If it's none of the editable element, then the focus is somewhere in the UI. Let's display the badge
|
|
11938
11998
|
// over the first element then.
|
|
11939
11999
|
this._lastFocusedEditableElement = editableEditorElements[0];
|
|
11940
12000
|
}
|
|
11941
12001
|
}
|
|
11942
12002
|
}
|
|
12003
|
+
function getLowerRightCornerPosition(focusedEditableElement, config) {
|
|
12004
|
+
return getLowerCornerPosition(focusedEditableElement, config, (rootRect, balloonRect)=>{
|
|
12005
|
+
return rootRect.left + rootRect.width - balloonRect.width - config.horizontalOffset;
|
|
12006
|
+
});
|
|
12007
|
+
}
|
|
12008
|
+
function getLowerLeftCornerPosition(focusedEditableElement, config) {
|
|
12009
|
+
return getLowerCornerPosition(focusedEditableElement, config, (rootRect)=>rootRect.left + config.horizontalOffset);
|
|
12010
|
+
}
|
|
12011
|
+
function getLowerCornerPosition(focusedEditableElement, config, getBalloonLeft) {
|
|
12012
|
+
return (visibleEditableElementRect, balloonRect)=>{
|
|
12013
|
+
const editableElementRect = new Rect(focusedEditableElement);
|
|
12014
|
+
if (editableElementRect.width < NARROW_ROOT_WIDTH_THRESHOLD || editableElementRect.height < NARROW_ROOT_HEIGHT_THRESHOLD) {
|
|
12015
|
+
return null;
|
|
12016
|
+
}
|
|
12017
|
+
let balloonTop;
|
|
12018
|
+
if (config.position === 'inside') {
|
|
12019
|
+
balloonTop = editableElementRect.bottom - balloonRect.height;
|
|
12020
|
+
} else {
|
|
12021
|
+
balloonTop = editableElementRect.bottom - balloonRect.height / 2;
|
|
12022
|
+
}
|
|
12023
|
+
balloonTop -= config.verticalOffset;
|
|
12024
|
+
const balloonLeft = getBalloonLeft(editableElementRect, balloonRect);
|
|
12025
|
+
// Clone the editable element rect and place it where the balloon would be placed.
|
|
12026
|
+
// This will allow getVisible() to work from editable element's perspective (rect source).
|
|
12027
|
+
// and yield a result as if the balloon was on the same (scrollable) layer as the editable element.
|
|
12028
|
+
const newBalloonPositionRect = visibleEditableElementRect.clone().moveTo(balloonLeft, balloonTop).getIntersection(balloonRect.clone().moveTo(balloonLeft, balloonTop));
|
|
12029
|
+
const newBalloonPositionVisibleRect = newBalloonPositionRect.getVisible();
|
|
12030
|
+
if (!newBalloonPositionVisibleRect || newBalloonPositionVisibleRect.getArea() < balloonRect.getArea()) {
|
|
12031
|
+
return null;
|
|
12032
|
+
}
|
|
12033
|
+
return {
|
|
12034
|
+
top: balloonTop,
|
|
12035
|
+
left: balloonLeft,
|
|
12036
|
+
name: `position_${config.position}-side_${config.side}`,
|
|
12037
|
+
config: {
|
|
12038
|
+
withArrow: false
|
|
12039
|
+
}
|
|
12040
|
+
};
|
|
12041
|
+
};
|
|
12042
|
+
}
|
|
12043
|
+
|
|
12044
|
+
var poweredByIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"53\" height=\"10\" viewBox=\"0 0 53 10\"><path fill=\"#1C2331\" d=\"M31.724 1.492a15.139 15.139 0 0 0 .045 1.16 2.434 2.434 0 0 0-.687-.34 3.68 3.68 0 0 0-1.103-.166 2.332 2.332 0 0 0-1.14.255 1.549 1.549 0 0 0-.686.87c-.15.41-.225.98-.225 1.712 0 .939.148 1.659.444 2.161.297.503.792.754 1.487.754.452.015.9-.094 1.294-.316.296-.174.557-.4.771-.669l.14.852h1.282V.007h-1.623v1.485ZM31 6.496a1.77 1.77 0 0 1-.494.061.964.964 0 0 1-.521-.127.758.758 0 0 1-.296-.466 3.984 3.984 0 0 1-.093-.992 4.208 4.208 0 0 1 .098-1.052.753.753 0 0 1 .307-.477 1.08 1.08 0 0 1 .55-.122c.233-.004.466.026.69.089l.483.144v2.553c-.11.076-.213.143-.307.2a1.73 1.73 0 0 1-.417.189ZM35.68 0l-.702.004c-.322.002-.482.168-.48.497l.004.581c.002.33.164.493.486.49l.702-.004c.322-.002.481-.167.48-.496L36.165.49c-.002-.33-.164-.493-.486-.491ZM36.145 2.313l-1.612.01.034 5.482 1.613-.01-.035-5.482ZM39.623.79 37.989.8 38 2.306l-.946.056.006 1.009.949-.006.024 2.983c.003.476.143.844.419 1.106.275.26.658.39 1.148.387.132 0 .293-.01.483-.03.19-.02.38-.046.57-.08.163-.028.324-.068.482-.119l-.183-1.095-.702.004a.664.664 0 0 1-.456-.123.553.553 0 0 1-.14-.422l-.016-2.621 1.513-.01-.006-1.064-1.514.01-.01-1.503ZM46.226 2.388c-.41-.184-.956-.274-1.636-.27-.673.004-1.215.101-1.627.29-.402.179-.72.505-.888.91-.18.419-.268.979-.264 1.68.004.688.1 1.24.285 1.655.172.404.495.724.9.894.414.18.957.268 1.63.264.68-.004 1.224-.099 1.632-.284.4-.176.714-.501.878-.905.176-.418.263-.971.258-1.658-.004-.702-.097-1.261-.28-1.677a1.696 1.696 0 0 0-.888-.9Zm-.613 3.607a.77.77 0 0 1-.337.501 1.649 1.649 0 0 1-1.317.009.776.776 0 0 1-.343-.497 4.066 4.066 0 0 1-.105-1.02 4.136 4.136 0 0 1 .092-1.03.786.786 0 0 1 .337-.507 1.59 1.59 0 0 1 1.316-.008.79.79 0 0 1 .344.502c.078.337.113.683.105 1.03.012.343-.019.685-.092 1.02ZM52.114 2.07a2.67 2.67 0 0 0-1.128.278c-.39.191-.752.437-1.072.73l-.157-.846-1.273.008.036 5.572 1.623-.01-.024-3.78c.35-.124.646-.22.887-.286.26-.075.53-.114.8-.118l.45-.003.144-1.546-.286.001ZM22.083 7.426l-1.576-2.532a2.137 2.137 0 0 0-.172-.253 1.95 1.95 0 0 0-.304-.29.138.138 0 0 1 .042-.04 1.7 1.7 0 0 0 .328-.374l1.75-2.71c.01-.015.025-.028.024-.048-.01-.01-.021-.007-.031-.007L20.49 1.17a.078.078 0 0 0-.075.045l-.868 1.384c-.23.366-.46.732-.688 1.099a.108.108 0 0 1-.112.06c-.098-.005-.196-.001-.294-.002-.018 0-.038.006-.055-.007.002-.02.002-.039.005-.058a4.6 4.6 0 0 0 .046-.701V1.203c0-.02-.009-.032-.03-.03h-.033L16.93 1.17c-.084 0-.073-.01-.073.076v6.491c-.001.018.006.028.025.027h1.494c.083 0 .072.007.072-.071v-2.19c0-.055-.003-.11-.004-.166a3.366 3.366 0 0 0-.05-.417h.06c.104 0 .209.002.313-.002a.082.082 0 0 1 .084.05c.535.913 1.07 1.824 1.607 2.736a.104.104 0 0 0 .103.062c.554-.003 1.107-.002 1.66-.002l.069-.003-.019-.032-.188-.304ZM27.112 6.555c-.005-.08-.004-.08-.082-.08h-2.414c-.053 0-.106-.003-.159-.011a.279.279 0 0 1-.246-.209.558.558 0 0 1-.022-.15c0-.382 0-.762-.002-1.143 0-.032.007-.049.042-.044h2.504c.029.003.037-.012.034-.038V3.814c0-.089.013-.078-.076-.078h-2.44c-.07 0-.062.003-.062-.06v-.837c0-.047.004-.093.013-.14a.283.283 0 0 1 .241-.246.717.717 0 0 1 .146-.011h2.484c.024.002.035-.009.036-.033l.003-.038.03-.496c.01-.183.024-.365.034-.548.005-.085.003-.087-.082-.094-.218-.018-.437-.038-.655-.05a17.845 17.845 0 0 0-.657-.026 72.994 72.994 0 0 0-1.756-.016 1.7 1.7 0 0 0-.471.064 1.286 1.286 0 0 0-.817.655c-.099.196-.149.413-.145.633v3.875c0 .072.003.144.011.216a1.27 1.27 0 0 0 .711 1.029c.228.113.48.167.734.158.757-.005 1.515.002 2.272-.042.274-.016.548-.034.82-.053.03-.002.043-.008.04-.041-.008-.104-.012-.208-.019-.312a69.964 69.964 0 0 1-.05-.768ZM16.14 7.415l-.127-1.075c-.004-.03-.014-.04-.044-.037a13.125 13.125 0 0 1-.998.073c-.336.01-.672.02-1.008.016-.116-.001-.233-.014-.347-.039a.746.746 0 0 1-.45-.262c-.075-.1-.132-.211-.167-.33a3.324 3.324 0 0 1-.126-.773 9.113 9.113 0 0 1-.015-.749c0-.285.022-.57.065-.852.023-.158.066-.312.127-.46a.728.728 0 0 1 .518-.443 1.64 1.64 0 0 1 .397-.048c.628-.001 1.255.003 1.882.05.022.001.033-.006.036-.026l.003-.031.06-.55c.019-.177.036-.355.057-.532.004-.034-.005-.046-.04-.056a5.595 5.595 0 0 0-1.213-.21 10.783 10.783 0 0 0-.708-.02c-.24-.003-.48.01-.719.041a3.477 3.477 0 0 0-.625.14 1.912 1.912 0 0 0-.807.497c-.185.2-.33.433-.424.688a4.311 4.311 0 0 0-.24 1.096c-.031.286-.045.572-.042.86-.006.43.024.86.091 1.286.04.25.104.497.193.734.098.279.26.53.473.734.214.205.473.358.756.446.344.11.702.17 1.063.177a8.505 8.505 0 0 0 1.578-.083 6.11 6.11 0 0 0 .766-.18c.03-.008.047-.023.037-.057a.157.157 0 0 1-.003-.025Z\"/><path fill=\"#AFE229\" d=\"M6.016 6.69a1.592 1.592 0 0 0-.614.21c-.23.132-.422.32-.56.546-.044.072-.287.539-.287.539l-.836 1.528.009.006c.038.025.08.046.123.063.127.046.26.07.395.073.505.023 1.011-.007 1.517-.003.29.009.58.002.869-.022a.886.886 0 0 0 .395-.116.962.962 0 0 0 .312-.286c.056-.083.114-.163.164-.249.24-.408.48-.816.718-1.226.075-.128.148-.257.222-.386l.112-.192a1.07 1.07 0 0 0 .153-.518l-1.304.023s-1.258-.005-1.388.01Z\"/><path fill=\"#771BFF\" d=\"m2.848 9.044.76-1.39.184-.352c-.124-.067-.245-.14-.367-.21-.346-.204-.706-.384-1.045-.6a.984.984 0 0 1-.244-.207c-.108-.134-.136-.294-.144-.46-.021-.409-.002-.818-.009-1.227-.003-.195 0-.39.003-.585.004-.322.153-.553.427-.713l.833-.488c.22-.13.44-.257.662-.385.05-.029.105-.052.158-.077.272-.128.519-.047.76.085l.044.028c.123.06.242.125.358.196.318.178.635.357.952.537.095.056.187.117.275.184.194.144.254.35.266.578.016.284.007.569.006.853-.001.28.004.558 0 .838.592-.003 1.259 0 1.259 0l.723-.013c-.003-.292-.007-.584-.007-.876 0-.524.015-1.048-.016-1.571-.024-.42-.135-.8-.492-1.067a5.02 5.02 0 0 0-.506-.339A400.52 400.52 0 0 0 5.94.787C5.722.664 5.513.524 5.282.423 5.255.406 5.228.388 5.2.373 4.758.126 4.305-.026 3.807.21c-.097.046-.197.087-.29.14A699.896 699.896 0 0 0 .783 1.948c-.501.294-.773.717-.778 1.31-.004.36-.009.718-.001 1.077.016.754-.017 1.508.024 2.261.016.304.07.6.269.848.127.15.279.28.448.382.622.4 1.283.734 1.92 1.11l.183.109Z\"/></svg>\n";
|
|
12045
|
+
|
|
12046
|
+
const DEFAULT_LABEL = 'Powered by';
|
|
12047
|
+
/**
|
|
12048
|
+
* A helper that enables the "powered by" feature in the editor and renders a link to the project's
|
|
12049
|
+
* webpage next to the bottom of the editable element (editor root, source editing area, etc.) when the editor is focused.
|
|
12050
|
+
*
|
|
12051
|
+
* @private
|
|
12052
|
+
*/ class PoweredBy extends Badge {
|
|
12053
|
+
constructor(editor){
|
|
12054
|
+
super(editor, {
|
|
12055
|
+
balloonClass: 'ck-powered-by-balloon'
|
|
12056
|
+
});
|
|
12057
|
+
}
|
|
12058
|
+
/**
|
|
12059
|
+
* Enables "powered by" label.
|
|
12060
|
+
*/ _isEnabled() {
|
|
12061
|
+
const editor = this.editor;
|
|
12062
|
+
const forceVisible = editor.config.get('ui.poweredBy.forceVisible');
|
|
12063
|
+
if (forceVisible) {
|
|
12064
|
+
return true;
|
|
12065
|
+
}
|
|
12066
|
+
const licenseKey = editor.config.get('licenseKey');
|
|
12067
|
+
if (licenseKey == 'GPL') {
|
|
12068
|
+
return true;
|
|
12069
|
+
}
|
|
12070
|
+
const licenseContent = parseBase64EncodedObject(licenseKey.split('.')[1]);
|
|
12071
|
+
if (!licenseContent) {
|
|
12072
|
+
return true;
|
|
12073
|
+
}
|
|
12074
|
+
return !licenseContent.whiteLabel;
|
|
12075
|
+
}
|
|
12076
|
+
/**
|
|
12077
|
+
* Creates a "powered by" badge content.
|
|
12078
|
+
*/ _createBadgeContent() {
|
|
12079
|
+
return new PoweredByView(this.editor.locale, this._getNormalizedConfig().label);
|
|
12080
|
+
}
|
|
12081
|
+
/**
|
|
12082
|
+
* Returns the normalized configuration for the "powered by" badge.
|
|
12083
|
+
* It takes the user configuration into account and falls back to the default one.
|
|
12084
|
+
*/ _getNormalizedConfig() {
|
|
12085
|
+
const badgeConfig = super._getNormalizedConfig();
|
|
12086
|
+
const userConfig = this.editor.config.get('ui.poweredBy') || {};
|
|
12087
|
+
const position = userConfig.position || badgeConfig.position;
|
|
12088
|
+
const verticalOffset = position === 'inside' ? 5 : badgeConfig.verticalOffset;
|
|
12089
|
+
return {
|
|
12090
|
+
position,
|
|
12091
|
+
side: userConfig.side || badgeConfig.side,
|
|
12092
|
+
label: userConfig.label === undefined ? DEFAULT_LABEL : userConfig.label,
|
|
12093
|
+
verticalOffset: userConfig.verticalOffset !== undefined ? userConfig.verticalOffset : verticalOffset,
|
|
12094
|
+
horizontalOffset: userConfig.horizontalOffset !== undefined ? userConfig.horizontalOffset : badgeConfig.horizontalOffset,
|
|
12095
|
+
forceVisible: !!userConfig.forceVisible
|
|
12096
|
+
};
|
|
12097
|
+
}
|
|
12098
|
+
}
|
|
11943
12099
|
/**
|
|
11944
12100
|
* A view displaying a "powered by" label and project logo wrapped in a link.
|
|
11945
12101
|
*/ class PoweredByView extends View {
|
|
11946
12102
|
/**
|
|
11947
|
-
*
|
|
12103
|
+
* Creates an instance of the "powered by" view.
|
|
11948
12104
|
*
|
|
11949
12105
|
* @param locale The localization services instance.
|
|
11950
12106
|
* @param label The label text.
|
|
@@ -11956,14 +12112,6 @@ const DEFAULT_LABEL = 'Powered by';
|
|
|
11956
12112
|
content: poweredByIcon,
|
|
11957
12113
|
isColorInherited: false
|
|
11958
12114
|
});
|
|
11959
|
-
iconView.extendTemplate({
|
|
11960
|
-
attributes: {
|
|
11961
|
-
style: {
|
|
11962
|
-
width: ICON_WIDTH + 'px',
|
|
11963
|
-
height: ICON_HEIGHT + 'px'
|
|
11964
|
-
}
|
|
11965
|
-
}
|
|
11966
|
-
});
|
|
11967
12115
|
this.setTemplate({
|
|
11968
12116
|
tag: 'div',
|
|
11969
12117
|
attributes: {
|
|
@@ -12006,67 +12154,101 @@ const DEFAULT_LABEL = 'Powered by';
|
|
|
12006
12154
|
});
|
|
12007
12155
|
}
|
|
12008
12156
|
}
|
|
12009
|
-
|
|
12010
|
-
|
|
12011
|
-
|
|
12012
|
-
|
|
12013
|
-
|
|
12014
|
-
|
|
12015
|
-
|
|
12016
|
-
|
|
12157
|
+
|
|
12158
|
+
/**
|
|
12159
|
+
* A helper that enables the "evaluation badge" feature in the editor at the bottom of the editable element
|
|
12160
|
+
* (editor root, source editing area, etc.) when the editor is focused.
|
|
12161
|
+
*
|
|
12162
|
+
* @private
|
|
12163
|
+
*/ class EvaluationBadge extends Badge {
|
|
12164
|
+
licenseTypeMessage = {
|
|
12165
|
+
evaluation: 'For evaluation purposes only',
|
|
12166
|
+
trial: 'For evaluation purposes only',
|
|
12167
|
+
development: 'For development purposes only'
|
|
12017
12168
|
};
|
|
12018
|
-
|
|
12019
|
-
|
|
12020
|
-
|
|
12021
|
-
|
|
12022
|
-
}
|
|
12023
|
-
|
|
12024
|
-
|
|
12025
|
-
|
|
12026
|
-
|
|
12027
|
-
|
|
12028
|
-
|
|
12029
|
-
|
|
12030
|
-
|
|
12031
|
-
|
|
12032
|
-
|
|
12033
|
-
|
|
12034
|
-
|
|
12035
|
-
|
|
12036
|
-
|
|
12037
|
-
|
|
12038
|
-
|
|
12039
|
-
|
|
12040
|
-
|
|
12041
|
-
|
|
12042
|
-
|
|
12043
|
-
|
|
12044
|
-
const
|
|
12045
|
-
const
|
|
12046
|
-
if (!newBalloonPositionVisibleRect || newBalloonPositionVisibleRect.getArea() < balloonRect.getArea()) {
|
|
12047
|
-
return null;
|
|
12048
|
-
}
|
|
12169
|
+
constructor(editor){
|
|
12170
|
+
super(editor, {
|
|
12171
|
+
balloonClass: 'ck-evaluation-badge-balloon'
|
|
12172
|
+
});
|
|
12173
|
+
}
|
|
12174
|
+
/**
|
|
12175
|
+
* Enables "evaluation badge" label.
|
|
12176
|
+
*/ _isEnabled() {
|
|
12177
|
+
const editor = this.editor;
|
|
12178
|
+
const licenseKey = editor.config.get('licenseKey');
|
|
12179
|
+
const licenseType = getLicenseTypeFromLicenseKey(licenseKey);
|
|
12180
|
+
return Boolean(licenseType && this.licenseTypeMessage[licenseType]);
|
|
12181
|
+
}
|
|
12182
|
+
/**
|
|
12183
|
+
* Creates the content of the "evaluation badge".
|
|
12184
|
+
*/ _createBadgeContent() {
|
|
12185
|
+
const licenseKey = this.editor.config.get('licenseKey');
|
|
12186
|
+
const licenseType = getLicenseTypeFromLicenseKey(licenseKey);
|
|
12187
|
+
return new EvaluationBadgeView(this.editor.locale, this.licenseTypeMessage[licenseType]);
|
|
12188
|
+
}
|
|
12189
|
+
/**
|
|
12190
|
+
* Returns the normalized configuration for the "evaluation badge".
|
|
12191
|
+
* It takes 'ui.poweredBy' configuration into account to determine the badge position and side.
|
|
12192
|
+
*/ _getNormalizedConfig() {
|
|
12193
|
+
const badgeConfig = super._getNormalizedConfig();
|
|
12194
|
+
const userConfig = this.editor.config.get('ui.poweredBy') || {};
|
|
12195
|
+
const position = userConfig.position || badgeConfig.position;
|
|
12196
|
+
const poweredBySide = userConfig.side || badgeConfig.side;
|
|
12049
12197
|
return {
|
|
12050
|
-
|
|
12051
|
-
left:
|
|
12052
|
-
|
|
12053
|
-
|
|
12054
|
-
withArrow: false
|
|
12055
|
-
}
|
|
12198
|
+
position,
|
|
12199
|
+
side: poweredBySide === 'left' ? 'right' : 'left',
|
|
12200
|
+
verticalOffset: badgeConfig.verticalOffset,
|
|
12201
|
+
horizontalOffset: badgeConfig.horizontalOffset
|
|
12056
12202
|
};
|
|
12057
|
-
}
|
|
12203
|
+
}
|
|
12058
12204
|
}
|
|
12059
|
-
|
|
12060
|
-
|
|
12061
|
-
|
|
12062
|
-
|
|
12063
|
-
|
|
12064
|
-
|
|
12065
|
-
|
|
12066
|
-
|
|
12067
|
-
|
|
12068
|
-
|
|
12069
|
-
|
|
12205
|
+
/**
|
|
12206
|
+
* A view displaying the "evaluation badge".
|
|
12207
|
+
*/ class EvaluationBadgeView extends View {
|
|
12208
|
+
/**
|
|
12209
|
+
* Creates an instance of the "evaluation badge" view.
|
|
12210
|
+
*
|
|
12211
|
+
* @param locale The localization services instance.
|
|
12212
|
+
* @param label The label text.
|
|
12213
|
+
*/ constructor(locale, label){
|
|
12214
|
+
super(locale);
|
|
12215
|
+
this.setTemplate({
|
|
12216
|
+
tag: 'div',
|
|
12217
|
+
attributes: {
|
|
12218
|
+
class: [
|
|
12219
|
+
'ck',
|
|
12220
|
+
'ck-evaluation-badge'
|
|
12221
|
+
],
|
|
12222
|
+
'aria-hidden': true
|
|
12223
|
+
},
|
|
12224
|
+
children: [
|
|
12225
|
+
{
|
|
12226
|
+
tag: 'span',
|
|
12227
|
+
attributes: {
|
|
12228
|
+
class: [
|
|
12229
|
+
'ck',
|
|
12230
|
+
'ck-evaluation-badge__label'
|
|
12231
|
+
]
|
|
12232
|
+
},
|
|
12233
|
+
children: [
|
|
12234
|
+
label
|
|
12235
|
+
]
|
|
12236
|
+
}
|
|
12237
|
+
]
|
|
12238
|
+
});
|
|
12239
|
+
}
|
|
12240
|
+
}
|
|
12241
|
+
/**
|
|
12242
|
+
* Returns the license type based on the license key.
|
|
12243
|
+
*/ function getLicenseTypeFromLicenseKey(licenseKey) {
|
|
12244
|
+
if (licenseKey == 'GPL') {
|
|
12245
|
+
return 'GPL';
|
|
12246
|
+
}
|
|
12247
|
+
const licenseContent = parseBase64EncodedObject(licenseKey.split('.')[1]);
|
|
12248
|
+
if (!licenseContent) {
|
|
12249
|
+
return null;
|
|
12250
|
+
}
|
|
12251
|
+
return licenseContent.licenseType || 'production';
|
|
12070
12252
|
}
|
|
12071
12253
|
|
|
12072
12254
|
/**
|
|
@@ -12737,6 +12919,7 @@ const NESTED_PANEL_HORIZONTAL_OFFSET = 5;
|
|
|
12737
12919
|
* groupId: 'insertInline',
|
|
12738
12920
|
* items: [
|
|
12739
12921
|
* 'menuBar:link',
|
|
12922
|
+
* 'menuBar:bookmark',
|
|
12740
12923
|
* 'menuBar:comment',
|
|
12741
12924
|
* 'menuBar:insertMergeField'
|
|
12742
12925
|
* ]
|
|
@@ -12993,6 +13176,7 @@ const DefaultMenuBarItems = [
|
|
|
12993
13176
|
groupId: 'insertInline',
|
|
12994
13177
|
items: [
|
|
12995
13178
|
'menuBar:link',
|
|
13179
|
+
'menuBar:bookmark',
|
|
12996
13180
|
'menuBar:comment',
|
|
12997
13181
|
'menuBar:insertMergeField'
|
|
12998
13182
|
]
|
|
@@ -13610,6 +13794,9 @@ function isMenuDefinition(definition) {
|
|
|
13610
13794
|
/**
|
|
13611
13795
|
* A helper that enables the "powered by" feature in the editor and renders a link to the project's webpage.
|
|
13612
13796
|
*/ poweredBy;
|
|
13797
|
+
/**
|
|
13798
|
+
* A helper that enables the "evaluation badge" feature in the editor.
|
|
13799
|
+
*/ evaluationBadge;
|
|
13613
13800
|
/**
|
|
13614
13801
|
* A helper that manages the content of an `aria-live` regions used by editor features to announce status changes
|
|
13615
13802
|
* to screen readers.
|
|
@@ -13644,6 +13831,7 @@ function isMenuDefinition(definition) {
|
|
|
13644
13831
|
this.focusTracker = new FocusTracker();
|
|
13645
13832
|
this.tooltipManager = new TooltipManager(editor);
|
|
13646
13833
|
this.poweredBy = new PoweredBy(editor);
|
|
13834
|
+
this.evaluationBadge = new EvaluationBadge(editor);
|
|
13647
13835
|
this.ariaLiveAnnouncer = new AriaLiveAnnouncer(editor);
|
|
13648
13836
|
this.set('viewportOffset', this._readViewportOffsetFromConfig());
|
|
13649
13837
|
this.once('ready', ()=>{
|
|
@@ -13684,6 +13872,7 @@ function isMenuDefinition(definition) {
|
|
|
13684
13872
|
this.focusTracker.destroy();
|
|
13685
13873
|
this.tooltipManager.destroy(this.editor);
|
|
13686
13874
|
this.poweredBy.destroy();
|
|
13875
|
+
this.evaluationBadge.destroy();
|
|
13687
13876
|
// Clean–up the references to the CKEditor instance stored in the native editable DOM elements.
|
|
13688
13877
|
for (const domElement of this._editableElementsMap.values()){
|
|
13689
13878
|
domElement.ckeditorInstance = null;
|
|
@@ -17204,7 +17393,7 @@ const toPx = /* #__PURE__ */ toUnit('px');
|
|
|
17204
17393
|
fitInViewport: true,
|
|
17205
17394
|
positions: this._panelPositions
|
|
17206
17395
|
});
|
|
17207
|
-
this.panelView.position = optimalPanelPosition ? optimalPanelPosition.name : this.
|
|
17396
|
+
this.panelView.position = optimalPanelPosition ? optimalPanelPosition.name : this._defaultMenuPositionName;
|
|
17208
17397
|
});
|
|
17209
17398
|
}
|
|
17210
17399
|
/**
|
|
@@ -17251,6 +17440,24 @@ const toPx = /* #__PURE__ */ toUnit('px');
|
|
|
17251
17440
|
}
|
|
17252
17441
|
}
|
|
17253
17442
|
}
|
|
17443
|
+
/**
|
|
17444
|
+
* The default position of the panel when the menu is opened.
|
|
17445
|
+
* It is used when the optimal position cannot be calculated.
|
|
17446
|
+
*/ get _defaultMenuPositionName() {
|
|
17447
|
+
if (this.locale.uiLanguageDirection === 'ltr') {
|
|
17448
|
+
if (this.parentMenuView) {
|
|
17449
|
+
return 'es';
|
|
17450
|
+
} else {
|
|
17451
|
+
return 'se';
|
|
17452
|
+
}
|
|
17453
|
+
} else {
|
|
17454
|
+
if (this.parentMenuView) {
|
|
17455
|
+
return 'ws';
|
|
17456
|
+
} else {
|
|
17457
|
+
return 'sw';
|
|
17458
|
+
}
|
|
17459
|
+
}
|
|
17460
|
+
}
|
|
17254
17461
|
/**
|
|
17255
17462
|
* A function used to calculate the optimal position for the dropdown panel.
|
|
17256
17463
|
*
|