knt-shared 1.10.6 → 1.10.7

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/index.esm.js CHANGED
@@ -2458,7 +2458,7 @@ const _hoisted_4$4 = {
2458
2458
  const _hoisted_5$4 = { class: "progress-bar" };
2459
2459
  const _hoisted_6$3 = { class: "controls-bottom" };
2460
2460
  const _hoisted_7$2 = { class: "controls-left" };
2461
- const _hoisted_8$1 = { class: "volume-slider-container" };
2461
+ const _hoisted_8$2 = { class: "volume-slider-container" };
2462
2462
  const _hoisted_9 = { class: "time-display" };
2463
2463
  const _hoisted_10 = { class: "controls-right" };
2464
2464
  const _hoisted_11 = { class: "control-button" };
@@ -2746,7 +2746,7 @@ const _sfc_main$h = /* @__PURE__ */ defineComponent({
2746
2746
  size: 20
2747
2747
  }))
2748
2748
  ]),
2749
- withDirectives(createElementVNode("div", _hoisted_8$1, [
2749
+ withDirectives(createElementVNode("div", _hoisted_8$2, [
2750
2750
  withDirectives(createElementVNode("input", {
2751
2751
  "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => volume.value = $event),
2752
2752
  type: "range",
@@ -2906,7 +2906,7 @@ const _hoisted_7$1 = {
2906
2906
  key: 1,
2907
2907
  class: "upload-tip sortable-tip"
2908
2908
  };
2909
- const _hoisted_8 = {
2909
+ const _hoisted_8$1 = {
2910
2910
  key: 5,
2911
2911
  class: "inline-video-preview"
2912
2912
  };
@@ -3632,7 +3632,7 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
3632
3632
  "file-name": previewFileName.value,
3633
3633
  "player-options": getProps.value.videoPlayerOptions
3634
3634
  }, null, 8, ["visible", "video-url", "file-name", "player-options"])) : createCommentVNode("", true),
3635
- getProps.value.videoPreviewMode === "inline" && previewVideoVisible.value ? (openBlock(), createElementBlock("div", _hoisted_8, [
3635
+ getProps.value.videoPreviewMode === "inline" && previewVideoVisible.value ? (openBlock(), createElementBlock("div", _hoisted_8$1, [
3636
3636
  createVNode(VideoPreview, {
3637
3637
  "video-url": previewVideoUrl.value,
3638
3638
  "player-options": getProps.value.videoPlayerOptions
@@ -10197,17 +10197,17 @@ function useDescription(props) {
10197
10197
  }
10198
10198
  ];
10199
10199
  }
10200
- const _hoisted_1$2 = { class: "basic-image" };
10201
- const _hoisted_2$1 = {
10200
+ const _hoisted_1$2 = {
10202
10201
  key: 0,
10203
10202
  class: "basic-image-empty"
10204
10203
  };
10205
- const _hoisted_3$1 = { class: "empty-text" };
10206
- const _hoisted_4 = {
10204
+ const _hoisted_2$1 = { class: "empty-text" };
10205
+ const _hoisted_3$1 = {
10207
10206
  key: 0,
10208
10207
  class: "basic-image-simple"
10209
10208
  };
10210
- const _hoisted_5 = { class: "image-wrapper" };
10209
+ const _hoisted_4 = { class: "image-wrapper" };
10210
+ const _hoisted_5 = ["src", "width", "height", "alt"];
10211
10211
  const _hoisted_6 = {
10212
10212
  key: 0,
10213
10213
  class: "image-count-badge"
@@ -10216,6 +10216,7 @@ const _hoisted_7 = {
10216
10216
  key: 0,
10217
10217
  style: { "display": "none" }
10218
10218
  };
10219
+ const _hoisted_8 = ["src", "width", "height", "alt"];
10219
10220
  const _sfc_main$4 = /* @__PURE__ */ defineComponent({
10220
10221
  ...{
10221
10222
  name: "BasicImage"
@@ -10243,21 +10244,45 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
10243
10244
  const getProps = computed(() => {
10244
10245
  return { ...props, ...innerPropsRef.value };
10245
10246
  });
10247
+ function isSafeImageUrl(url) {
10248
+ if (!url || typeof url !== "string") return false;
10249
+ const trimmed = url.trim();
10250
+ if (trimmed.startsWith("/") || trimmed.startsWith("./") || trimmed.startsWith("../")) {
10251
+ return true;
10252
+ }
10253
+ if (/^data:/i.test(trimmed)) {
10254
+ return /^data:image\/(?!svg\+xml)/i.test(trimmed);
10255
+ }
10256
+ try {
10257
+ const { protocol } = new URL(trimmed);
10258
+ return protocol === "http:" || protocol === "https:" || protocol === "blob:";
10259
+ } catch {
10260
+ return false;
10261
+ }
10262
+ }
10246
10263
  const normalizedImages = computed(() => {
10247
10264
  const images = getProps.value.images || [];
10248
10265
  if (!Array.isArray(images) || images.length === 0) {
10249
10266
  return [];
10250
10267
  }
10251
10268
  return images.map((item) => {
10252
- if (typeof item === "string") {
10253
- return { url: item };
10269
+ const normalized = typeof item === "string" ? { url: item } : item;
10270
+ if (!isSafeImageUrl(normalized.url)) {
10271
+ return { ...normalized, url: "" };
10254
10272
  }
10255
- return item;
10273
+ return normalized;
10256
10274
  });
10257
10275
  });
10276
+ const safeErrorImage = computed(() => {
10277
+ const url = getProps.value.errorImage;
10278
+ if (!url || !isSafeImageUrl(url)) return void 0;
10279
+ return url;
10280
+ });
10258
10281
  const gridStyle = computed(() => {
10282
+ const rawGap = getProps.value.gap ?? 8;
10283
+ const gap = Number.isFinite(rawGap) ? Math.max(0, rawGap) : 8;
10259
10284
  return {
10260
- gap: `${getProps.value.gap}px`
10285
+ gap: `${gap}px`
10261
10286
  };
10262
10287
  });
10263
10288
  const handleImageClick = (item, index) => {
@@ -10265,6 +10290,9 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
10265
10290
  return;
10266
10291
  }
10267
10292
  emit("click", item, index);
10293
+ if (getProps.value.preview) {
10294
+ emit("preview", item, index);
10295
+ }
10268
10296
  };
10269
10297
  const getImages = () => {
10270
10298
  return normalizedImages.value;
@@ -10284,41 +10312,52 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
10284
10312
  getProps: getPropsValue,
10285
10313
  setProps
10286
10314
  };
10287
- watch(
10288
- () => props,
10289
- () => {
10290
- },
10291
- { deep: true }
10292
- );
10293
10315
  onMounted(() => {
10294
10316
  emit("register", methods);
10295
10317
  });
10296
10318
  __expose(methods);
10297
10319
  return (_ctx, _cache) => {
10298
- return openBlock(), createElementBlock("div", _hoisted_1$2, [
10299
- normalizedImages.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_2$1, [
10320
+ return openBlock(), createElementBlock("div", {
10321
+ class: normalizeClass(["basic-image", { "basic-image--disabled": getProps.value.disabled }])
10322
+ }, [
10323
+ normalizedImages.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_1$2, [
10300
10324
  renderSlot(_ctx.$slots, "empty", {}, () => [
10301
- createElementVNode("span", _hoisted_3$1, toDisplayString(getProps.value.emptyText), 1)
10325
+ createElementVNode("span", _hoisted_2$1, toDisplayString(getProps.value.emptyText), 1)
10302
10326
  ], true)
10303
10327
  ])) : (openBlock(), createBlock(resolveDynamicComponent(getProps.value.preview ? unref(ImagePreviewGroup) : "div"), { key: 1 }, {
10304
10328
  default: withCtx(() => [
10305
- !getProps.value.showAll ? (openBlock(), createElementBlock("div", _hoisted_4, [
10306
- createElementVNode("div", _hoisted_5, [
10329
+ !getProps.value.showAll ? (openBlock(), createElementBlock("div", _hoisted_3$1, [
10330
+ createElementVNode("div", _hoisted_4, [
10307
10331
  createVNode(unref(Image$1), {
10308
10332
  src: normalizedImages.value[0].url,
10309
10333
  width: getProps.value.width,
10310
10334
  height: getProps.value.height,
10311
10335
  fit: getProps.value.fit,
10312
10336
  preview: getProps.value.preview,
10337
+ "show-loader": getProps.value.loading,
10313
10338
  alt: normalizedImages.value[0].name || "图片",
10314
10339
  onClick: _cache[0] || (_cache[0] = ($event) => handleImageClick(normalizedImages.value[0], 0))
10315
- }, null, 8, ["src", "width", "height", "fit", "preview", "alt"]),
10316
- normalizedImages.value.length > 1 ? (openBlock(), createElementBlock("div", _hoisted_6, " +" + toDisplayString(normalizedImages.value.length - 1), 1)) : createCommentVNode("", true)
10340
+ }, createSlots({ _: 2 }, [
10341
+ safeErrorImage.value ? {
10342
+ name: "error",
10343
+ fn: withCtx(() => [
10344
+ createElementVNode("img", {
10345
+ src: safeErrorImage.value,
10346
+ width: getProps.value.width,
10347
+ height: getProps.value.height,
10348
+ style: normalizeStyle({ display: "block", objectFit: getProps.value.fit }),
10349
+ alt: normalizedImages.value[0].name || "图片"
10350
+ }, null, 12, _hoisted_5)
10351
+ ]),
10352
+ key: "0"
10353
+ } : void 0
10354
+ ]), 1032, ["src", "width", "height", "fit", "preview", "show-loader", "alt"]),
10355
+ normalizedImages.value.length > (getProps.value.maxCount ?? 1) ? (openBlock(), createElementBlock("div", _hoisted_6, " +" + toDisplayString(normalizedImages.value.length - (getProps.value.maxCount ?? 1)), 1)) : createCommentVNode("", true)
10317
10356
  ]),
10318
- getProps.value.preview && normalizedImages.value.length > 1 ? (openBlock(), createElementBlock("div", _hoisted_7, [
10319
- (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedImages.value.slice(1), (item, index) => {
10357
+ getProps.value.preview && normalizedImages.value.length > (getProps.value.maxCount ?? 1) ? (openBlock(), createElementBlock("div", _hoisted_7, [
10358
+ (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedImages.value.slice(getProps.value.maxCount ?? 1), (item, index) => {
10320
10359
  return openBlock(), createBlock(unref(Image$1), {
10321
- key: index,
10360
+ key: `${item.url}-${index}`,
10322
10361
  src: item.url,
10323
10362
  alt: item.name || "图片"
10324
10363
  }, null, 8, ["src", "alt"]);
@@ -10331,7 +10370,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
10331
10370
  }, [
10332
10371
  (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedImages.value, (item, index) => {
10333
10372
  return openBlock(), createElementBlock("div", {
10334
- key: index,
10373
+ key: `${item.url}-${index}`,
10335
10374
  class: "image-item"
10336
10375
  }, [
10337
10376
  createVNode(unref(Image$1), {
@@ -10340,33 +10379,46 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
10340
10379
  height: getProps.value.height,
10341
10380
  fit: getProps.value.fit,
10342
10381
  preview: getProps.value.preview,
10382
+ "show-loader": getProps.value.loading,
10343
10383
  alt: item.name || "图片",
10344
10384
  onClick: ($event) => handleImageClick(item, index)
10345
- }, null, 8, ["src", "width", "height", "fit", "preview", "alt", "onClick"])
10385
+ }, createSlots({ _: 2 }, [
10386
+ safeErrorImage.value ? {
10387
+ name: "error",
10388
+ fn: withCtx(() => [
10389
+ createElementVNode("img", {
10390
+ src: safeErrorImage.value,
10391
+ width: getProps.value.width,
10392
+ height: getProps.value.height,
10393
+ style: normalizeStyle({ display: "block", objectFit: getProps.value.fit }),
10394
+ alt: item.name || "图片"
10395
+ }, null, 12, _hoisted_8)
10396
+ ]),
10397
+ key: "0"
10398
+ } : void 0
10399
+ ]), 1032, ["src", "width", "height", "fit", "preview", "show-loader", "alt", "onClick"])
10346
10400
  ]);
10347
10401
  }), 128))
10348
10402
  ], 4))
10349
10403
  ]),
10350
10404
  _: 1
10351
10405
  }))
10352
- ]);
10406
+ ], 2);
10353
10407
  };
10354
10408
  }
10355
10409
  });
10356
- const BasicImage = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-04c54d5a"]]);
10410
+ const BasicImage = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-71d2eff3"]]);
10357
10411
  function useImage(options) {
10358
10412
  const imageRef = ref(null);
10359
10413
  const loadedRef = ref(false);
10360
10414
  const register = (instance) => {
10361
- if (unref(imageRef) && instance === unref(imageRef)) {
10415
+ if (instance === unref(imageRef)) {
10362
10416
  return;
10363
10417
  }
10364
10418
  imageRef.value = instance;
10365
10419
  loadedRef.value = true;
10366
10420
  if (options) {
10367
- nextTick(() => {
10368
- instance.setProps(options);
10369
- });
10421
+ instance.setProps(options);
10370
10422
  }
10371
10423
  };
10372
10424
  const getInstance = () => {