@kungal/editor-core 0.17.0 → 0.19.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # @kungal/editor-core
2
2
 
3
+ ## 0.19.0
4
+
5
+ ## 0.18.0
6
+
7
+ ### Minor Changes
8
+
9
+ - 6545866: Toolbar image upload now shows an in-document "uploading…" placeholder.
10
+
11
+ Previously only paste/drop showed the in-flight placeholder (Milkdown's `upload`
12
+ plugin); the toolbar image button uploaded silently — the image just popped in
13
+ when the adapter resolved. Now the toolbar path uses the same placeholder UX
14
+ (ProseMirror's official upload-example pattern).
15
+
16
+ - **editor-core**: `startImageUpload(view, file, { uploadImage, notify, locale })`
17
+ - the `imageUploadPlaceholder` decoration plugin (exported from `/preset`;
18
+ wired by the preset when `uploadImage` is present). Inserts a
19
+ `.kun-editor__uploading` widget at the caret, uploads, then replaces it with the
20
+ image (or removes it + notifies on failure); not an undo step. The paste/drop
21
+ placeholder now uses the same `.kun-editor__uploading` class so both look
22
+ identical.
23
+ - **editor-vue**: `KunEditorToolbarApi` gains `uploadImage(file)`; both the
24
+ headless `EditorToolbar` and the `#toolbar` slot API route uploads through
25
+ `startImageUpload`.
26
+ - **editor-nuxt**: `<KunEditorToolbar>`'s image button uses it.
27
+ - **Headless kept**: the placeholder is a class + widget hook only; style it via
28
+ `.kun-editor__uploading` in the reference `kun-editor.css` (primary-colored).
29
+
30
+ Customizable: style the placeholder via `.kun-editor__uploading`; the text is
31
+ localized (zh/en). Verified in the docs production build: uploading via either
32
+ toolbar inserts the image; the unit tests confirm the placeholder shows during a
33
+ pending upload and is replaced on success / removed on failure.
34
+
3
35
  ## 0.17.0
4
36
 
5
37
  ### Minor Changes
@@ -19,13 +19,13 @@ var katex = require('katex');
19
19
  var remarkMath = require('remark-math');
20
20
  var codeBlock = require('@milkdown/kit/component/code-block');
21
21
  var commands$1 = require('@codemirror/commands');
22
- var view = require('@codemirror/view');
22
+ var view$1 = require('@codemirror/view');
23
23
  var languageData = require('@codemirror/language-data');
24
24
  var codemirror = require('codemirror');
25
25
  var language = require('@codemirror/language');
26
26
  var highlight = require('@lezer/highlight');
27
27
  var upload = require('@milkdown/kit/plugin/upload');
28
- var view$1 = require('@milkdown/kit/prose/view');
28
+ var view = require('@milkdown/kit/prose/view');
29
29
 
30
30
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
31
31
 
@@ -374,7 +374,7 @@ var colors = {
374
374
  content2: "var(--color-content2)",
375
375
  content3: "var(--color-content3)"};
376
376
  var kunCMTheme = () => {
377
- return view.EditorView.theme({
377
+ return view$1.EditorView.theme({
378
378
  "&": {
379
379
  backgroundColor: colors.backgroundAlpha,
380
380
  borderRadius: "0.75rem",
@@ -690,8 +690,8 @@ var applyCodeBlockConfig = (ctx, options = {}) => {
690
690
  ...prev,
691
691
  extensions: [
692
692
  kunCM(),
693
- view.EditorView.lineWrapping,
694
- view.keymap.of(commands$1.defaultKeymap.concat(commands$1.indentWithTab)),
693
+ view$1.EditorView.lineWrapping,
694
+ view$1.keymap.of(commands$1.defaultKeymap.concat(commands$1.indentWithTab)),
695
695
  codemirror.basicSetup,
696
696
  ...options.extensions ?? []
697
697
  ],
@@ -958,12 +958,15 @@ var createUploader = (uploadImage, options = {}) => {
958
958
  return nodes.filter((node) => node !== null);
959
959
  };
960
960
  };
961
+ var uploadingWidget = (locale) => {
962
+ const el = document.createElement("span");
963
+ el.className = "kun-editor__uploading";
964
+ el.textContent = uploadingLabel(locale);
965
+ return el;
966
+ };
961
967
  var createUploadWidgetFactory = (options = {}) => {
962
968
  return (pos, spec) => {
963
- const widgetDOM = document.createElement("span");
964
- widgetDOM.textContent = uploadingLabel(options.locale);
965
- widgetDOM.style.color = "var(--color-primary)";
966
- return view$1.Decoration.widget(pos, widgetDOM, spec);
969
+ return view.Decoration.widget(pos, uploadingWidget(options.locale), spec);
967
970
  };
968
971
  };
969
972
  var applyUploadConfig = (ctx, uploadImage, options = {}) => {
@@ -977,6 +980,76 @@ var uploadConfigPlugin = (uploadImage, options) => (ctx) => () => {
977
980
  applyUploadConfig(ctx, uploadImage, options);
978
981
  };
979
982
  var createUploadPlugin = (uploadImage, options = {}) => [...upload.upload, uploadConfigPlugin(uploadImage, options)];
983
+ var placeholderKey = new state.PluginKey("KUN_IMAGE_UPLOAD_PLACEHOLDER");
984
+ var imageUploadPlaceholder = utils.$prose(
985
+ () => new state.Plugin({
986
+ key: placeholderKey,
987
+ state: {
988
+ init: () => view.DecorationSet.empty,
989
+ apply(tr, set) {
990
+ let next = set.map(tr.mapping, tr.doc);
991
+ const meta = tr.getMeta(placeholderKey);
992
+ if (meta?.add) {
993
+ const deco = view.Decoration.widget(
994
+ meta.add.pos,
995
+ uploadingWidget(meta.add.locale),
996
+ { id: meta.add.id }
997
+ );
998
+ next = next.add(tr.doc, [deco]);
999
+ } else if (meta?.remove) {
1000
+ const { id } = meta.remove;
1001
+ next = next.remove(
1002
+ next.find(void 0, void 0, (spec) => spec.id === id)
1003
+ );
1004
+ }
1005
+ return next;
1006
+ }
1007
+ },
1008
+ props: {
1009
+ decorations: (state) => placeholderKey.getState(state)
1010
+ }
1011
+ })
1012
+ );
1013
+ var findPlaceholder = (view, id) => {
1014
+ const set = placeholderKey.getState(view.state);
1015
+ const found = set?.find(void 0, void 0, (spec) => spec.id === id);
1016
+ return found && found.length ? found[0].from : null;
1017
+ };
1018
+ var startImageUpload = async (view, file, options) => {
1019
+ if (!file.type.startsWith("image/")) {
1020
+ return;
1021
+ }
1022
+ const id = {};
1023
+ const tr = view.state.tr;
1024
+ if (!tr.selection.empty) {
1025
+ tr.deleteSelection();
1026
+ }
1027
+ tr.setMeta(placeholderKey, {
1028
+ add: { id, pos: tr.selection.from, locale: options.locale }
1029
+ });
1030
+ tr.setMeta("addToHistory", false);
1031
+ view.dispatch(tr);
1032
+ try {
1033
+ const src = await options.uploadImage(file);
1034
+ const pos = findPlaceholder(view, id);
1035
+ if (pos === null) {
1036
+ return;
1037
+ }
1038
+ const imageType = view.state.schema.nodes.image;
1039
+ const node = imageType?.createAndFill({ src, alt: file.name });
1040
+ if (!node) {
1041
+ return;
1042
+ }
1043
+ view.dispatch(
1044
+ view.state.tr.replaceWith(pos, pos, node).setMeta(placeholderKey, { remove: { id } })
1045
+ );
1046
+ } catch {
1047
+ view.dispatch(
1048
+ view.state.tr.setMeta(placeholderKey, { remove: { id } }).setMeta("addToHistory", false)
1049
+ );
1050
+ options.notify?.(uploadFailedLabel(options.locale), "error");
1051
+ }
1052
+ };
980
1053
  var SKIP_PARENTS = /* @__PURE__ */ new Set([
981
1054
  "code_block",
982
1055
  "bullet_list",
@@ -1021,8 +1094,8 @@ var createPlaceholderPlugin = (config = {}) => {
1021
1094
  return null;
1022
1095
  }
1023
1096
  const before = selection.$anchor.before();
1024
- return view$1.DecorationSet.create(state.doc, [
1025
- view$1.Decoration.node(before, before + node.nodeSize, {
1097
+ return view.DecorationSet.create(state.doc, [
1098
+ view.Decoration.node(before, before + node.nodeSize, {
1026
1099
  class: "kun-editor__placeholder",
1027
1100
  "data-placeholder": text
1028
1101
  })
@@ -1084,6 +1157,7 @@ var createKunEditorPlugins = (adapters = {}, features = {}, options = {}) => {
1084
1157
  notify: adapters.notify
1085
1158
  })
1086
1159
  );
1160
+ plugins.push(imageUploadPlaceholder);
1087
1161
  }
1088
1162
  plugins.push(createStopLinkPlugin());
1089
1163
  plugins.push(createHeadingPlugin());
@@ -1117,6 +1191,7 @@ exports.createUploadPlugin = createUploadPlugin;
1117
1191
  exports.createUploadWidgetFactory = createUploadWidgetFactory;
1118
1192
  exports.createUploader = createUploader;
1119
1193
  exports.editIcon = editIcon;
1194
+ exports.imageUploadPlaceholder = imageUploadPlaceholder;
1120
1195
  exports.insertKunSpoilerCommand = insertKunSpoilerCommand;
1121
1196
  exports.insertMentionCommand = insertMentionCommand;
1122
1197
  exports.insertQuoteCommand = insertQuoteCommand;
@@ -1142,6 +1217,7 @@ exports.searchIcon = searchIcon;
1142
1217
  exports.setHeadingCommand = setHeadingCommand;
1143
1218
  exports.spoilerAttr = spoilerAttr;
1144
1219
  exports.spoilerSchema = spoilerSchema;
1220
+ exports.startImageUpload = startImageUpload;
1145
1221
  exports.stopLinkCommand = stopLinkCommand;
1146
1222
  exports.toggleLatexCommand = toggleLatexCommand;
1147
1223
  exports.visibilityOffIcon = visibilityOffIcon;