@ckeditor/ckeditor5-word-count 48.2.0 → 48.3.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/dist/augmentation.d.ts +17 -17
- package/dist/index-content.css +1 -0
- package/dist/index-editor.css +1 -0
- package/dist/index.css +0 -2
- package/dist/index.d.ts +9 -9
- package/dist/index.js +228 -250
- package/dist/index.js.map +1 -1
- package/dist/utils.d.ts +11 -11
- package/dist/wordcount.d.ts +141 -141
- package/dist/wordcountconfig.d.ts +87 -87
- package/package.json +5 -5
- package/dist/index.css.map +0 -1
package/dist/augmentation.d.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import type { WordCount, WordCountConfig } from
|
|
6
|
-
declare module
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
2
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
+
*/
|
|
5
|
+
import type { WordCount, WordCountConfig } from "./index.js";
|
|
6
|
+
declare module "@ckeditor/ckeditor5-core" {
|
|
7
|
+
interface EditorConfig {
|
|
8
|
+
/**
|
|
9
|
+
* The configuration of the word count feature.
|
|
10
|
+
* It is introduced by the {@link module:word-count/wordcount~WordCount} feature.
|
|
11
|
+
*
|
|
12
|
+
* Read more in {@link module:word-count/wordcountconfig~WordCountConfig}.
|
|
13
|
+
*/
|
|
14
|
+
wordCount?: WordCountConfig;
|
|
15
|
+
}
|
|
16
|
+
interface PluginsMap {
|
|
17
|
+
[WordCount.pluginName]: WordCount;
|
|
18
|
+
}
|
|
19
19
|
}
|
package/dist/index-content.css
CHANGED
package/dist/index-editor.css
CHANGED
package/dist/index.css
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
+
*/
|
|
5
5
|
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export { WordCount, type WordCountUpdateEvent } from
|
|
9
|
-
export type { WordCountConfig } from
|
|
10
|
-
export { modelElementToPlainText as _modelElementToPlainText } from
|
|
11
|
-
import
|
|
6
|
+
* @module word-count
|
|
7
|
+
*/
|
|
8
|
+
export { WordCount, type WordCountUpdateEvent } from "./wordcount.js";
|
|
9
|
+
export type { WordCountConfig } from "./wordcountconfig.js";
|
|
10
|
+
export { modelElementToPlainText as _modelElementToPlainText } from "./utils.js";
|
|
11
|
+
import "./augmentation.js";
|
package/dist/index.js
CHANGED
|
@@ -2,260 +2,238 @@
|
|
|
2
2
|
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
4
|
*/
|
|
5
|
-
import { Plugin } from
|
|
6
|
-
import { Template, View } from
|
|
7
|
-
import { env } from
|
|
8
|
-
import {
|
|
5
|
+
import { Plugin } from "@ckeditor/ckeditor5-core";
|
|
6
|
+
import { Template, View } from "@ckeditor/ckeditor5-ui";
|
|
7
|
+
import { env } from "@ckeditor/ckeditor5-utils";
|
|
8
|
+
import { isElement, throttle } from "es-toolkit/compat";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
text += childText;
|
|
34
|
-
prev = child;
|
|
35
|
-
}
|
|
36
|
-
return text;
|
|
11
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
12
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Returns a plain text representation of an element and its children.
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
18
|
+
* @returns Plain text representing the model's data.
|
|
19
|
+
*/
|
|
20
|
+
function modelElementToPlainText(item) {
|
|
21
|
+
if (item.is("$text") || item.is("$textProxy")) return item.data;
|
|
22
|
+
const element = item;
|
|
23
|
+
let text = "";
|
|
24
|
+
let prev = null;
|
|
25
|
+
for (const child of element.getChildren()) {
|
|
26
|
+
const childText = modelElementToPlainText(child);
|
|
27
|
+
if (prev && prev.is("element")) text += "\n";
|
|
28
|
+
text += childText;
|
|
29
|
+
prev = child;
|
|
30
|
+
}
|
|
31
|
+
return text;
|
|
37
32
|
}
|
|
38
33
|
|
|
39
34
|
/**
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
return detectedWords.length;
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Determines the number of words and characters in the current editor's model and assigns it to {@link #characters} and {@link #words}.
|
|
246
|
-
* It also fires the {@link #event:update}.
|
|
247
|
-
*
|
|
248
|
-
* @fires update
|
|
249
|
-
*/ _refreshStats() {
|
|
250
|
-
const txt = this._getText();
|
|
251
|
-
const words = this.words = this._getWords(txt);
|
|
252
|
-
const characters = this.characters = this._getCharacters(txt);
|
|
253
|
-
this.fire('update', {
|
|
254
|
-
words,
|
|
255
|
-
characters
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
}
|
|
35
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
36
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* The word count plugin.
|
|
40
|
+
*
|
|
41
|
+
* This plugin calculates all words and characters in all {@link module:engine/model/text~ModelText text nodes} available in the model.
|
|
42
|
+
* It also provides an HTML element that updates its state whenever the editor content is changed.
|
|
43
|
+
*
|
|
44
|
+
* The model's data is first converted to plain text using {@link module:word-count/utils~modelElementToPlainText}.
|
|
45
|
+
* The number of words and characters in your text are determined based on the created plain text. Please keep in mind
|
|
46
|
+
* that every block in the editor is separated with a newline character, which is included in the calculation.
|
|
47
|
+
*
|
|
48
|
+
* Here are some examples of how the word and character calculations are made:
|
|
49
|
+
*
|
|
50
|
+
* ```html
|
|
51
|
+
* <paragraph>foo</paragraph>
|
|
52
|
+
* <paragraph>bar</paragraph>
|
|
53
|
+
* // Words: 2, Characters: 7
|
|
54
|
+
*
|
|
55
|
+
* <paragraph><$text bold="true">foo</$text>bar</paragraph>
|
|
56
|
+
* // Words: 1, Characters: 6
|
|
57
|
+
*
|
|
58
|
+
* <paragraph>*&^%)</paragraph>
|
|
59
|
+
* // Words: 0, Characters: 5
|
|
60
|
+
*
|
|
61
|
+
* <paragraph>foo(bar)</paragraph>
|
|
62
|
+
* //Words: 1, Characters: 8
|
|
63
|
+
*
|
|
64
|
+
* <paragraph>12345</paragraph>
|
|
65
|
+
* // Words: 1, Characters: 5
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
var WordCount = class extends Plugin {
|
|
69
|
+
/**
|
|
70
|
+
* The configuration of this plugin.
|
|
71
|
+
*/
|
|
72
|
+
_config;
|
|
73
|
+
/**
|
|
74
|
+
* The reference to a {@link module:ui/view~View view object} that contains the self-updating HTML container.
|
|
75
|
+
*/
|
|
76
|
+
_outputView;
|
|
77
|
+
/**
|
|
78
|
+
* A regular expression used to recognize words in the editor's content.
|
|
79
|
+
*/
|
|
80
|
+
_wordsMatchRegExp;
|
|
81
|
+
/**
|
|
82
|
+
* @inheritDoc
|
|
83
|
+
*/
|
|
84
|
+
constructor(editor) {
|
|
85
|
+
super(editor);
|
|
86
|
+
this.set("characters", 0);
|
|
87
|
+
this.set("words", 0);
|
|
88
|
+
Object.defineProperties(this, {
|
|
89
|
+
characters: { get() {
|
|
90
|
+
return this.characters = this._getCharacters(this._getText());
|
|
91
|
+
} },
|
|
92
|
+
words: { get() {
|
|
93
|
+
return this.words = this._getWords(this._getText());
|
|
94
|
+
} }
|
|
95
|
+
});
|
|
96
|
+
this.set("_wordsLabel", void 0);
|
|
97
|
+
this.set("_charactersLabel", void 0);
|
|
98
|
+
this._config = editor.config.get("wordCount") || {};
|
|
99
|
+
this._outputView = void 0;
|
|
100
|
+
this._wordsMatchRegExp = env.features.isRegExpUnicodePropertySupported ? /* @__PURE__ */ new RegExp("([\\p{L}\\p{N}]+\\S?)+", "gu") : /([a-zA-Z0-9À-ž]+\S?)+/gu;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* @inheritDoc
|
|
104
|
+
*/
|
|
105
|
+
static get pluginName() {
|
|
106
|
+
return "WordCount";
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* @inheritDoc
|
|
110
|
+
* @internal
|
|
111
|
+
*/
|
|
112
|
+
static get licenseFeatureCode() {
|
|
113
|
+
return "WC";
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* @inheritDoc
|
|
117
|
+
*/
|
|
118
|
+
static get isOfficialPlugin() {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* @inheritDoc
|
|
123
|
+
*/
|
|
124
|
+
static get isPremiumPlugin() {
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* @inheritDoc
|
|
129
|
+
*/
|
|
130
|
+
init() {
|
|
131
|
+
this.editor.model.document.on("change:data", throttle(this._refreshStats.bind(this), 250));
|
|
132
|
+
if (typeof this._config.onUpdate == "function") this.on("update", (evt, data) => {
|
|
133
|
+
this._config.onUpdate(data);
|
|
134
|
+
});
|
|
135
|
+
if (isElement(this._config.container)) this._config.container.appendChild(this.wordCountContainer);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* @inheritDoc
|
|
139
|
+
*/
|
|
140
|
+
destroy() {
|
|
141
|
+
if (this._outputView) {
|
|
142
|
+
this._outputView.element.remove();
|
|
143
|
+
this._outputView.destroy();
|
|
144
|
+
}
|
|
145
|
+
super.destroy();
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Creates a self-updating HTML element. Repeated executions return the same element.
|
|
149
|
+
* The returned element has the following HTML structure:
|
|
150
|
+
*
|
|
151
|
+
* ```html
|
|
152
|
+
* <div class="ck ck-word-count">
|
|
153
|
+
* <div class="ck-word-count__words">Words: 4</div>
|
|
154
|
+
* <div class="ck-word-count__characters">Characters: 28</div>
|
|
155
|
+
* </div>
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
get wordCountContainer() {
|
|
159
|
+
const editor = this.editor;
|
|
160
|
+
const t = editor.t;
|
|
161
|
+
const displayWords = editor.config.get("wordCount.displayWords");
|
|
162
|
+
const displayCharacters = editor.config.get("wordCount.displayCharacters");
|
|
163
|
+
const bind = Template.bind(this, this);
|
|
164
|
+
const children = [];
|
|
165
|
+
if (!this._outputView) {
|
|
166
|
+
this._outputView = new View();
|
|
167
|
+
if (displayWords || displayWords === void 0) {
|
|
168
|
+
this.bind("_wordsLabel").to(this, "words", (words) => {
|
|
169
|
+
return t("Words: %0", words);
|
|
170
|
+
});
|
|
171
|
+
children.push({
|
|
172
|
+
tag: "div",
|
|
173
|
+
children: [{ text: [bind.to("_wordsLabel")] }],
|
|
174
|
+
attributes: { class: "ck-word-count__words" }
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
if (displayCharacters || displayCharacters === void 0) {
|
|
178
|
+
this.bind("_charactersLabel").to(this, "characters", (words) => {
|
|
179
|
+
return t("Characters: %0", words);
|
|
180
|
+
});
|
|
181
|
+
children.push({
|
|
182
|
+
tag: "div",
|
|
183
|
+
children: [{ text: [bind.to("_charactersLabel")] }],
|
|
184
|
+
attributes: { class: "ck-word-count__characters" }
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
this._outputView.setTemplate({
|
|
188
|
+
tag: "div",
|
|
189
|
+
attributes: { class: ["ck", "ck-word-count"] },
|
|
190
|
+
children
|
|
191
|
+
});
|
|
192
|
+
this._outputView.render();
|
|
193
|
+
}
|
|
194
|
+
return this._outputView.element;
|
|
195
|
+
}
|
|
196
|
+
_getText() {
|
|
197
|
+
let txt = "";
|
|
198
|
+
for (const root of this.editor.model.document.getRoots()) {
|
|
199
|
+
if (txt !== "") txt += "\n";
|
|
200
|
+
txt += modelElementToPlainText(root);
|
|
201
|
+
}
|
|
202
|
+
return txt;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Determines the number of characters in the current editor's model.
|
|
206
|
+
*/
|
|
207
|
+
_getCharacters(txt) {
|
|
208
|
+
return txt.replace(/\n/g, "").length;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Determines the number of words in the current editor's model.
|
|
212
|
+
*/
|
|
213
|
+
_getWords(txt) {
|
|
214
|
+
return (txt.match(this._wordsMatchRegExp) || []).length;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Determines the number of words and characters in the current editor's model and assigns it to {@link #characters} and {@link #words}.
|
|
218
|
+
* It also fires the {@link #event:update}.
|
|
219
|
+
*
|
|
220
|
+
* @fires update
|
|
221
|
+
*/
|
|
222
|
+
_refreshStats() {
|
|
223
|
+
const txt = this._getText();
|
|
224
|
+
const words = this.words = this._getWords(txt);
|
|
225
|
+
const characters = this.characters = this._getCharacters(txt);
|
|
226
|
+
this.fire("update", {
|
|
227
|
+
words,
|
|
228
|
+
characters
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
235
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
236
|
+
*/
|
|
259
237
|
|
|
260
238
|
export { WordCount, modelElementToPlainText as _modelElementToPlainText };
|
|
261
|
-
//# sourceMappingURL=index.js.map
|
|
239
|
+
//# sourceMappingURL=index.js.map
|