@univerjs/docs-hyper-link-ui 1.0.0-insiders.20260809-70eefdd → 1.0.0-rc.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.
Files changed (88) hide show
  1. package/LICENSE +176 -0
  2. package/README.md +0 -1
  3. package/lib/cjs/index.js +211 -97
  4. package/lib/cjs/locale/ar-SA.js +0 -2
  5. package/lib/cjs/locale/ca-ES.js +0 -2
  6. package/lib/cjs/locale/de-DE.js +0 -2
  7. package/lib/cjs/locale/en-US.js +0 -2
  8. package/lib/cjs/locale/es-ES.js +0 -2
  9. package/lib/cjs/locale/fa-IR.js +0 -2
  10. package/lib/cjs/locale/fr-FR.js +0 -2
  11. package/lib/cjs/locale/id-ID.js +0 -2
  12. package/lib/cjs/locale/it-IT.js +0 -2
  13. package/lib/cjs/locale/ja-JP.js +0 -2
  14. package/lib/cjs/locale/ko-KR.js +0 -2
  15. package/lib/cjs/locale/pl-PL.js +0 -2
  16. package/lib/cjs/locale/pt-BR.js +0 -2
  17. package/lib/cjs/locale/ru-RU.js +0 -2
  18. package/lib/cjs/locale/sk-SK.js +0 -2
  19. package/lib/cjs/locale/vi-VN.js +0 -2
  20. package/lib/cjs/locale/zh-CN.js +0 -2
  21. package/lib/cjs/locale/zh-HK.js +0 -2
  22. package/lib/cjs/locale/zh-TW.js +0 -2
  23. package/lib/es/index.js +216 -102
  24. package/lib/es/locale/ar-SA.js +0 -2
  25. package/lib/es/locale/ca-ES.js +0 -2
  26. package/lib/es/locale/de-DE.js +0 -2
  27. package/lib/es/locale/en-US.js +0 -2
  28. package/lib/es/locale/es-ES.js +0 -2
  29. package/lib/es/locale/fa-IR.js +0 -2
  30. package/lib/es/locale/fr-FR.js +0 -2
  31. package/lib/es/locale/id-ID.js +0 -2
  32. package/lib/es/locale/it-IT.js +0 -2
  33. package/lib/es/locale/ja-JP.js +0 -2
  34. package/lib/es/locale/ko-KR.js +0 -2
  35. package/lib/es/locale/pl-PL.js +0 -2
  36. package/lib/es/locale/pt-BR.js +0 -2
  37. package/lib/es/locale/ru-RU.js +0 -2
  38. package/lib/es/locale/sk-SK.js +0 -2
  39. package/lib/es/locale/vi-VN.js +0 -2
  40. package/lib/es/locale/zh-CN.js +0 -2
  41. package/lib/es/locale/zh-HK.js +0 -2
  42. package/lib/es/locale/zh-TW.js +0 -2
  43. package/lib/index.css +51 -4
  44. package/lib/index.js +216 -102
  45. package/lib/locale/ar-SA.js +0 -2
  46. package/lib/locale/ca-ES.js +0 -2
  47. package/lib/locale/de-DE.js +0 -2
  48. package/lib/locale/en-US.js +0 -2
  49. package/lib/locale/es-ES.js +0 -2
  50. package/lib/locale/fa-IR.js +0 -2
  51. package/lib/locale/fr-FR.js +0 -2
  52. package/lib/locale/id-ID.js +0 -2
  53. package/lib/locale/it-IT.js +0 -2
  54. package/lib/locale/ja-JP.js +0 -2
  55. package/lib/locale/ko-KR.js +0 -2
  56. package/lib/locale/pl-PL.js +0 -2
  57. package/lib/locale/pt-BR.js +0 -2
  58. package/lib/locale/ru-RU.js +0 -2
  59. package/lib/locale/sk-SK.js +0 -2
  60. package/lib/locale/vi-VN.js +0 -2
  61. package/lib/locale/zh-CN.js +0 -2
  62. package/lib/locale/zh-HK.js +0 -2
  63. package/lib/locale/zh-TW.js +0 -2
  64. package/lib/types/controllers/render-controllers/hyper-link-event.render-controller.d.ts +1 -0
  65. package/lib/types/controllers/render-controllers/render.controller.d.ts +1 -5
  66. package/lib/types/locale/en-US.d.ts +0 -2
  67. package/lib/types/services/hyper-link-popup.service.d.ts +26 -9
  68. package/lib/umd/index.js +1 -1
  69. package/lib/umd/locale/ar-SA.js +1 -1
  70. package/lib/umd/locale/ca-ES.js +1 -1
  71. package/lib/umd/locale/de-DE.js +1 -1
  72. package/lib/umd/locale/en-US.js +1 -1
  73. package/lib/umd/locale/es-ES.js +1 -1
  74. package/lib/umd/locale/fa-IR.js +1 -1
  75. package/lib/umd/locale/fr-FR.js +1 -1
  76. package/lib/umd/locale/id-ID.js +1 -1
  77. package/lib/umd/locale/it-IT.js +1 -1
  78. package/lib/umd/locale/ja-JP.js +1 -1
  79. package/lib/umd/locale/ko-KR.js +1 -1
  80. package/lib/umd/locale/pl-PL.js +1 -1
  81. package/lib/umd/locale/pt-BR.js +1 -1
  82. package/lib/umd/locale/ru-RU.js +1 -1
  83. package/lib/umd/locale/sk-SK.js +1 -1
  84. package/lib/umd/locale/vi-VN.js +1 -1
  85. package/lib/umd/locale/zh-CN.js +1 -1
  86. package/lib/umd/locale/zh-HK.js +1 -1
  87. package/lib/umd/locale/zh-TW.js +1 -1
  88. package/package.json +13 -12
@@ -4,11 +4,9 @@ const locale = { "docs-hyper-link-ui": {
4
4
  edit: {
5
5
  confirm: "Подтвердить",
6
6
  cancel: "Отменить",
7
- title: "Ссылка",
8
7
  address: "Ссылка",
9
8
  label: "Текст",
10
9
  labelError: "Введите текст ссылки",
11
- placeholder: "Пожалуйста, введите ссылку",
12
10
  addressError: "Пожалуйста, введите корректную ссылку"
13
11
  },
14
12
  info: {
@@ -4,9 +4,7 @@ const locale = { "docs-hyper-link-ui": {
4
4
  edit: {
5
5
  confirm: "Potvrdiť",
6
6
  cancel: "Zrušiť",
7
- title: "Odkaz",
8
7
  address: "Odkaz",
9
- placeholder: "Zadajte URL odkazu",
10
8
  addressError: "URL je neplatná!",
11
9
  label: "Popisok",
12
10
  labelError: "Zadajte popis odkazu"
@@ -4,11 +4,9 @@ const locale = { "docs-hyper-link-ui": {
4
4
  edit: {
5
5
  confirm: "Xác nhận",
6
6
  cancel: "Hủy",
7
- title: "Liên kết",
8
7
  address: "Liên kết",
9
8
  label: "Nhãn",
10
9
  labelError: "Vui lòng nhập nhãn liên kết",
11
- placeholder: "Vui lòng nhập liên kết hợp lệ",
12
10
  addressError: "Vui lòng nhập liên kết hợp lệ"
13
11
  },
14
12
  info: {
@@ -4,11 +4,9 @@ const locale = { "docs-hyper-link-ui": {
4
4
  edit: {
5
5
  confirm: "确认",
6
6
  cancel: "取消",
7
- title: "链接",
8
7
  address: "链接",
9
8
  label: "文本",
10
9
  labelError: "请输入链接文本",
11
- placeholder: "请输入合法的链接",
12
10
  addressError: "请输入合法的链接"
13
11
  },
14
12
  info: {
@@ -4,11 +4,9 @@ const locale = { "docs-hyper-link-ui": {
4
4
  edit: {
5
5
  confirm: "確認",
6
6
  cancel: "取消",
7
- title: "連結",
8
7
  address: "連結",
9
8
  label: "文字",
10
9
  labelError: "請輸入連結文字",
11
- placeholder: "請輸入合法的連結",
12
10
  addressError: "請輸入合法的連結"
13
11
  },
14
12
  info: {
@@ -4,11 +4,9 @@ const locale = { "docs-hyper-link-ui": {
4
4
  edit: {
5
5
  confirm: "確認",
6
6
  cancel: "取消",
7
- title: "連結",
8
7
  address: "連結",
9
8
  label: "文字",
10
9
  labelError: "請輸入連結文字",
11
- placeholder: "請輸入合法的連結",
12
10
  addressError: "請輸入合法的連結"
13
11
  },
14
12
  info: {
package/lib/es/index.js CHANGED
@@ -1,19 +1,20 @@
1
- import { DocCanvasPopManagerService, DocEventManagerService, DocRenderController, EMPTY_PARAGRAPH_MENU_ID, FLOAT_TOOLBAR_MENU_POSITION, INSERT_BELLOW_MENU_ID, UniverDocsUIPlugin, whenDocAndEditorFocused } from "@univerjs/docs-ui";
1
+ import { DocCanvasPopManagerService, DocEventManagerService, EMPTY_PARAGRAPH_MENU_ID, FLOAT_TOOLBAR_MENU_POSITION, INSERT_BELLOW_MENU_ID, UniverDocsUIPlugin, whenDocAndEditorFocused } from "@univerjs/docs-ui";
2
2
  import { ComponentManager, ContextMenuGroup, ContextMenuPosition, IMenuManagerService, IMessageService, IShortcutService, IconManager, KeyCode, MenuItemType, MetaKeys, RibbonInsertGroup, getMenuHiddenObservable, useDependency, useObservable } from "@univerjs/ui";
3
- import { BuildTextUtils, CommandType, CustomRangeType, DOCS_NORMAL_EDITOR_UNIT_ID_KEY, DependentOn, Disposable, ICommandService, IConfigService, IUniverInstanceService, Inject, Injector, LocaleService, Plugin, Tools, UniverInstanceType, generateRandomId, getBodySlice, isSafeUrl, merge } from "@univerjs/core";
4
- import { DOC_INTERCEPTOR_POINT, DocInterceptorService, DocSelectionManagerService, DocSkeletonManagerService, SetTextSelectionsOperation, UniverDocsPlugin, addCustomRangeBySelectionFactory, deleteCustomRangeFactory, replaceSelectionFactory } from "@univerjs/docs";
5
- import { BehaviorSubject, Observable, debounceTime, distinctUntilChanged, pairwise } from "rxjs";
3
+ import { BuildTextUtils, CommandType, CustomRangeType, DOCS_NORMAL_EDITOR_UNIT_ID_KEY, DependentOn, Disposable, DocumentDataModel, ICommandService, IConfigService, IPermissionService, IUniverInstanceService, Inject, Injector, LocaleService, Plugin, Tools, UniverInstanceType, generateRandomId, getBodySlice, isSafeUrl, merge } from "@univerjs/core";
4
+ import { DOC_INTERCEPTOR_POINT, DocInterceptorService, DocSelectionManagerService, DocSkeletonManagerService, SetTextSelectionsOperation, UniverDocsPlugin, addCustomRangeBySelectionFactory, canEditDocumentTargets, deleteCustomRangeFactory, getDocumentEntityParentPermissionObjectIds, getDocumentEntityPermissionObjectId, getDocumentPermissionValue, replaceSelectionFactory } from "@univerjs/docs";
5
+ import { IRenderManagerService, UniverRenderEnginePlugin } from "@univerjs/engine-render";
6
+ import { BehaviorSubject, Observable, debounceTime } from "rxjs";
6
7
  import { Button, FormLayout, Input, MessageType, Tooltip, borderClassName, clsx } from "@univerjs/design";
7
8
  import { useEffect, useState } from "react";
8
- import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { DocHyperLinkCommandId, UniverDocsHyperLinkPlugin } from "@univerjs/docs-hyper-link";
10
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
11
  import { CopyIcon, LinkIcon, UnlinkIcon, WriteIcon } from "@univerjs/icons";
10
- import { UniverDocsHyperLinkPlugin } from "@univerjs/docs-hyper-link";
11
- import { IRenderManagerService, UniverRenderEnginePlugin } from "@univerjs/engine-render";
12
+ import { UnitAction } from "@univerjs/protocol";
12
13
 
13
14
  //#region src/commands/commands/add-link.command.ts
14
15
  const AddDocHyperLinkCommand = {
15
16
  type: CommandType.COMMAND,
16
- id: "docs.command.add-hyper-link",
17
+ id: DocHyperLinkCommandId.Add,
17
18
  async handler(accessor, params) {
18
19
  if (!params) return false;
19
20
  const { payload, unitId, selections } = params;
@@ -33,7 +34,7 @@ const AddDocHyperLinkCommand = {
33
34
  //#endregion
34
35
  //#region src/commands/commands/update-link.command.ts
35
36
  const UpdateDocHyperLinkCommand = {
36
- id: "docs.command.update-hyper-link",
37
+ id: DocHyperLinkCommandId.Update,
37
38
  type: CommandType.COMMAND,
38
39
  handler(accessor, params) {
39
40
  var _doc$getSelfOrHeaderF, _getBodySlice$textRun;
@@ -170,7 +171,7 @@ const DocHyperLinkEdit = () => {
170
171
  };
171
172
  if (!doc) return;
172
173
  return /* @__PURE__ */ jsxs("div", {
173
- className: clsx("univer-box-border univer-w-[328px] univer-rounded-xl univer-bg-white univer-px-6 univer-py-5 univer-shadow dark:!univer-bg-gray-900", borderClassName),
174
+ className: clsx("univer-box-border univer-w-[328px] univer-rounded-xl univer-bg-gray-0 univer-px-6 univer-py-5 univer-shadow dark:!univer-bg-gray-900", borderClassName),
174
175
  children: [/* @__PURE__ */ jsxs("div", { children: [editing ? /* @__PURE__ */ jsx(FormLayout, {
175
176
  label: localeService.t("docs-hyper-link-ui.edit.label"),
176
177
  error: showError && isBlankInput(label) ? localeService.t("docs-hyper-link-ui.edit.labelError") : "",
@@ -213,7 +214,7 @@ DocHyperLinkEdit.componentKey = "docs-hyper-link-edit";
213
214
  //#region src/commands/commands/delete-link.command.ts
214
215
  const DeleteDocHyperLinkCommand = {
215
216
  type: CommandType.COMMAND,
216
- id: "docs.command.delete-hyper-link",
217
+ id: DocHyperLinkCommandId.Delete,
217
218
  async handler(accessor, params) {
218
219
  if (!params) return false;
219
220
  const { unitId, linkId, segmentId } = params;
@@ -238,15 +239,24 @@ const DocLinkPopup = () => {
238
239
  const localeService = useDependency(LocaleService);
239
240
  const currentPopup = useObservable(hyperLinkService.showingLink$);
240
241
  const univerInstanceService = useDependency(IUniverInstanceService);
242
+ const permissionService = useDependency(IPermissionService);
241
243
  if (!currentPopup) return null;
242
244
  const { unitId, linkId, segmentId, startIndex, endIndex } = currentPopup;
243
245
  const doc = univerInstanceService.getUnit(unitId, UniverInstanceType.UNIVER_DOC);
244
- const body = doc === null || doc === void 0 || (_doc$getSelfOrHeaderF = doc.getSelfOrHeaderFooterModel(segmentId)) === null || _doc$getSelfOrHeaderF === void 0 ? void 0 : _doc$getSelfOrHeaderF.getBody();
246
+ const body = doc instanceof DocumentDataModel ? (_doc$getSelfOrHeaderF = doc.getSelfOrHeaderFooterModel(segmentId)) === null || _doc$getSelfOrHeaderF === void 0 ? void 0 : _doc$getSelfOrHeaderF.getBody() : void 0;
245
247
  const link = body === null || body === void 0 || (_body$customRanges = body.customRanges) === null || _body$customRanges === void 0 ? void 0 : _body$customRanges.find((range) => range.rangeId === linkId && range.rangeType === CustomRangeType.HYPERLINK && range.startIndex === startIndex && range.endIndex === endIndex);
246
248
  if (!link) return null;
247
249
  const url = (_link$properties = link.properties) === null || _link$properties === void 0 ? void 0 : _link$properties.url;
250
+ const canEdit = hyperLinkService.canEditLink(unitId, currentPopup);
251
+ const canCopy = getDocumentPermissionValue(permissionService, unitId, unitId, UnitAction.Copy);
248
252
  return /* @__PURE__ */ jsxs("div", {
249
- className: clsx("univer-box-border univer-flex univer-max-w-80 univer-items-center univer-justify-between univer-overflow-hidden univer-rounded-lg univer-bg-white univer-p-3 univer-shadow dark:!univer-bg-gray-900", borderClassName),
253
+ className: clsx("univer-box-border univer-flex univer-max-w-80 univer-items-center univer-justify-between univer-overflow-hidden univer-rounded-lg univer-bg-gray-0 univer-p-3 univer-shadow dark:!univer-bg-gray-900", borderClassName),
254
+ onPointerEnter: () => {
255
+ hyperLinkService.cancelScheduledHideInfoPopup();
256
+ },
257
+ onPointerLeave: () => {
258
+ hyperLinkService.scheduleHideInfoPopup();
259
+ },
250
260
  onClick: () => {
251
261
  hyperLinkService.hideInfoPopup();
252
262
  },
@@ -254,7 +264,7 @@ const DocLinkPopup = () => {
254
264
  className: "univer-flex univer-h-6 univer-flex-1 univer-cursor-pointer univer-items-center univer-truncate univer-text-sm univer-leading-5 univer-text-primary-500",
255
265
  onClick: () => window.open(url, void 0, "noopener noreferrer"),
256
266
  children: [/* @__PURE__ */ jsx("div", {
257
- className: "univer-mr-2 univer-flex univer-size-5 univer-flex-[0_0_auto] univer-items-center univer-justify-center univer-text-base univer-text-gray-900 dark:!univer-text-white",
267
+ className: "univer-mr-2 univer-flex univer-size-5 univer-flex-[0_0_auto] univer-items-center univer-justify-center univer-text-base univer-text-gray-900 dark:!univer-text-gray-0",
258
268
  children: /* @__PURE__ */ jsx(LinkIcon, {})
259
269
  }), /* @__PURE__ */ jsx(Tooltip, {
260
270
  showIfEllipsis: true,
@@ -266,49 +276,50 @@ const DocLinkPopup = () => {
266
276
  })]
267
277
  }), /* @__PURE__ */ jsxs("div", {
268
278
  className: "univer-flex univer-h-6 univer-flex-[0_0_auto] univer-items-center univer-justify-center",
269
- children: [
270
- /* @__PURE__ */ jsx("div", {
271
- className: "univer-ml-2 univer-flex univer-size-6 univer-cursor-pointer univer-items-center univer-justify-center univer-rounded univer-text-base",
272
- onClick: () => {
273
- navigator.clipboard.writeText(url);
274
- messageService.show({
275
- content: localeService.t("docs-hyper-link-ui.info.coped"),
276
- type: MessageType.Info
277
- });
278
- },
279
- children: /* @__PURE__ */ jsx(Tooltip, {
280
- placement: "bottom",
281
- title: localeService.t("docs-hyper-link-ui.info.copy"),
282
- children: /* @__PURE__ */ jsx(CopyIcon, {})
283
- })
284
- }),
285
- /* @__PURE__ */ jsx("div", {
286
- className: "univer-ml-2 univer-flex univer-size-6 univer-cursor-pointer univer-items-center univer-justify-center univer-rounded univer-text-base",
287
- onClick: () => {
288
- commandService.executeCommand(ShowDocHyperLinkEditPopupOperation.id, { link: currentPopup });
289
- },
290
- children: /* @__PURE__ */ jsx(Tooltip, {
291
- placement: "bottom",
292
- title: localeService.t("docs-hyper-link-ui.info.edit"),
293
- children: /* @__PURE__ */ jsx(WriteIcon, {})
294
- })
295
- }),
296
- /* @__PURE__ */ jsx("div", {
297
- className: "univer-ml-2 univer-flex univer-size-6 univer-cursor-pointer univer-items-center univer-justify-center univer-rounded univer-text-base",
298
- onClick: () => {
299
- commandService.executeCommand(DeleteDocHyperLinkCommand.id, {
300
- unitId,
301
- linkId: link.rangeId,
302
- segmentId
303
- });
304
- },
305
- children: /* @__PURE__ */ jsx(Tooltip, {
306
- placement: "bottom",
307
- title: localeService.t("docs-hyper-link-ui.info.cancel"),
308
- children: /* @__PURE__ */ jsx(UnlinkIcon, {})
309
- })
279
+ children: [/* @__PURE__ */ jsx(Button, {
280
+ type: "button",
281
+ variant: "text",
282
+ size: "small",
283
+ "aria-label": localeService.t("docs-hyper-link-ui.info.copy"),
284
+ className: "univer-ml-2 !univer-flex univer-size-6 !univer-rounded !univer-border-0 !univer-bg-transparent !univer-p-0 !univer-text-base !univer-font-normal hover:!univer-bg-transparent active:!univer-bg-transparent disabled:!univer-pointer-events-auto disabled:!univer-opacity-40",
285
+ disabled: !canCopy,
286
+ onClick: () => {
287
+ navigator.clipboard.writeText(url);
288
+ messageService.show({
289
+ content: localeService.t("docs-hyper-link-ui.info.coped"),
290
+ type: MessageType.Info
291
+ });
292
+ },
293
+ children: /* @__PURE__ */ jsx(Tooltip, {
294
+ placement: "bottom",
295
+ title: localeService.t("docs-hyper-link-ui.info.copy"),
296
+ children: /* @__PURE__ */ jsx(CopyIcon, {})
297
+ })
298
+ }), canEdit && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
299
+ className: "univer-ml-2 univer-flex univer-size-6 univer-cursor-pointer univer-items-center univer-justify-center univer-rounded univer-text-base",
300
+ onClick: () => {
301
+ commandService.executeCommand(ShowDocHyperLinkEditPopupOperation.id, { link: currentPopup });
302
+ },
303
+ children: /* @__PURE__ */ jsx(Tooltip, {
304
+ placement: "bottom",
305
+ title: localeService.t("docs-hyper-link-ui.info.edit"),
306
+ children: /* @__PURE__ */ jsx(WriteIcon, {})
310
307
  })
311
- ]
308
+ }), /* @__PURE__ */ jsx("div", {
309
+ className: "univer-ml-2 univer-flex univer-size-6 univer-cursor-pointer univer-items-center univer-justify-center univer-rounded univer-text-base",
310
+ onClick: () => {
311
+ commandService.executeCommand(DeleteDocHyperLinkCommand.id, {
312
+ unitId,
313
+ linkId: link.rangeId,
314
+ segmentId
315
+ });
316
+ },
317
+ children: /* @__PURE__ */ jsx(Tooltip, {
318
+ placement: "bottom",
319
+ title: localeService.t("docs-hyper-link-ui.info.cancel"),
320
+ children: /* @__PURE__ */ jsx(UnlinkIcon, {})
321
+ })
322
+ })] })]
312
323
  })]
313
324
  });
314
325
  };
@@ -375,22 +386,66 @@ function __decorate(decorators, target, key, desc) {
375
386
 
376
387
  //#endregion
377
388
  //#region src/services/hyper-link-popup.service.ts
389
+ /**
390
+ * Copyright 2023-present DreamNum Co., Ltd.
391
+ *
392
+ * Licensed under the Apache License, Version 2.0 (the "License");
393
+ * you may not use this file except in compliance with the License.
394
+ * You may obtain a copy of the License at
395
+ *
396
+ * http://www.apache.org/licenses/LICENSE-2.0
397
+ *
398
+ * Unless required by applicable law or agreed to in writing, software
399
+ * distributed under the License is distributed on an "AS IS" BASIS,
400
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
401
+ * See the License for the specific language governing permissions and
402
+ * limitations under the License.
403
+ */
404
+ const INFO_POPUP_HIDE_DELAY = 150;
405
+ function isSameLinkInfo(current, next) {
406
+ return (current === null || current === void 0 ? void 0 : current.linkId) === next.linkId && current.unitId === next.unitId && (current.segmentId ?? "") === (next.segmentId ?? "") && current.segmentPage === next.segmentPage && current.startIndex === next.startIndex && current.endIndex === next.endIndex;
407
+ }
378
408
  let DocHyperLinkPopupService = class DocHyperLinkPopupService extends Disposable {
379
- constructor(_docCanvasPopupManagerService, _textSelectionManagerService, _univerInstanceService) {
409
+ constructor(_docCanvasPopupManagerService, _textSelectionManagerService, _univerInstanceService, _permissionService, _renderManagerService) {
380
410
  super();
381
411
  this._docCanvasPopupManagerService = _docCanvasPopupManagerService;
382
412
  this._textSelectionManagerService = _textSelectionManagerService;
383
413
  this._univerInstanceService = _univerInstanceService;
414
+ this._permissionService = _permissionService;
415
+ this._renderManagerService = _renderManagerService;
384
416
  _defineProperty(this, "_editingLink$", new BehaviorSubject(null));
385
417
  _defineProperty(this, "_showingLink$", new BehaviorSubject(null));
386
418
  _defineProperty(this, "editingLink$", this._editingLink$.asObservable());
387
419
  _defineProperty(this, "showingLink$", this._showingLink$.asObservable());
388
420
  _defineProperty(this, "_editPopup", null);
421
+ _defineProperty(this, "_editPopupUnitId", null);
389
422
  _defineProperty(this, "_infoPopup", null);
423
+ _defineProperty(this, "_infoPopupPinned", false);
424
+ _defineProperty(this, "_infoPopupHideTimer", null);
425
+ _defineProperty(this, "_infoPopupSuppressed", false);
426
+ _defineProperty(this, "_infoPopupSuppressionTimer", null);
390
427
  this.disposeWithMe(() => {
428
+ this.cancelScheduledHideInfoPopup();
429
+ if (this._infoPopupSuppressionTimer !== null) clearTimeout(this._infoPopupSuppressionTimer);
391
430
  this._editingLink$.complete();
392
431
  this._showingLink$.complete();
393
432
  });
433
+ this.disposeWithMe(this._permissionService.permissionPointUpdate$.subscribe(() => {
434
+ const editing = this.editing;
435
+ if (editing && !this.canEditLink(editing.unitId, editing)) this.hideEditPopup();
436
+ const showing = this.showing;
437
+ if (showing) this._showingLink$.next({ ...showing });
438
+ }));
439
+ this.disposeWithMe(this._renderManagerService.disposed$.subscribe((unitId) => {
440
+ var _this$showing;
441
+ if (this._editPopupUnitId === unitId) this.hideEditPopup();
442
+ if (((_this$showing = this.showing) === null || _this$showing === void 0 ? void 0 : _this$showing.unitId) === unitId) this.hideInfoPopup();
443
+ }));
444
+ }
445
+ dispose() {
446
+ this.hideEditPopup();
447
+ this.hideInfoPopup();
448
+ super.dispose();
394
449
  }
395
450
  get editing() {
396
451
  return this._editingLink$.value;
@@ -398,8 +453,16 @@ let DocHyperLinkPopupService = class DocHyperLinkPopupService extends Disposable
398
453
  get showing() {
399
454
  return this._showingLink$.value;
400
455
  }
456
+ get infoPopupPinned() {
457
+ return this._infoPopupPinned;
458
+ }
401
459
  showEditPopup(unitId, linkInfo) {
402
- if (this._editPopup) this._editPopup.dispose();
460
+ if (!this.canEditLink(unitId, linkInfo)) return null;
461
+ if (this._editPopup) {
462
+ this._editPopup.dispose();
463
+ this._editPopup = null;
464
+ this._editPopupUnitId = null;
465
+ }
403
466
  this._editingLink$.next(linkInfo);
404
467
  const textRanges = this._textSelectionManagerService.getTextRanges({
405
468
  unitId,
@@ -423,8 +486,10 @@ let DocHyperLinkPopupService = class DocHyperLinkPopupService extends Disposable
423
486
  if (activeRange) {
424
487
  this._editPopup = this._docCanvasPopupManagerService.attachPopupToRange(activeRange, {
425
488
  componentKey: DocHyperLinkEdit.componentKey,
426
- direction: "bottom"
489
+ direction: "bottom",
490
+ offset: [0, 10]
427
491
  }, unitId);
492
+ this._editPopupUnitId = unitId;
428
493
  return this._editPopup;
429
494
  }
430
495
  return null;
@@ -433,13 +498,23 @@ let DocHyperLinkPopupService = class DocHyperLinkPopupService extends Disposable
433
498
  var _this$_editPopup;
434
499
  this._editingLink$.next(null);
435
500
  (_this$_editPopup = this._editPopup) === null || _this$_editPopup === void 0 || _this$_editPopup.dispose();
501
+ this._editPopup = null;
502
+ this._editPopupUnitId = null;
436
503
  }
437
- showInfoPopup(info) {
438
- var _this$showing, _this$showing2, _this$showing3, _this$showing4, _this$showing5, _this$showing6;
504
+ showInfoPopup(info, options) {
505
+ this.cancelScheduledHideInfoPopup();
506
+ if (this._infoPopupSuppressed) return;
439
507
  const { linkId, unitId, segmentId, segmentPage, startIndex, endIndex } = info;
440
- if (((_this$showing = this.showing) === null || _this$showing === void 0 ? void 0 : _this$showing.linkId) === linkId && ((_this$showing2 = this.showing) === null || _this$showing2 === void 0 ? void 0 : _this$showing2.unitId) === unitId && ((_this$showing3 = this.showing) === null || _this$showing3 === void 0 ? void 0 : _this$showing3.segmentId) === segmentId && ((_this$showing4 = this.showing) === null || _this$showing4 === void 0 ? void 0 : _this$showing4.segmentPage) === segmentPage && ((_this$showing5 = this.showing) === null || _this$showing5 === void 0 ? void 0 : _this$showing5.startIndex) === startIndex && ((_this$showing6 = this.showing) === null || _this$showing6 === void 0 ? void 0 : _this$showing6.endIndex) === endIndex) return;
441
- if (this._infoPopup) this._infoPopup.dispose();
442
- if (!this._univerInstanceService.getUnit(unitId, UniverInstanceType.UNIVER_DOC)) return;
508
+ if (isSameLinkInfo(this.showing, info)) {
509
+ if (options === null || options === void 0 ? void 0 : options.pinned) this._infoPopupPinned = true;
510
+ return;
511
+ }
512
+ if (this._infoPopup) {
513
+ this._infoPopup.dispose();
514
+ this._infoPopup = null;
515
+ }
516
+ if (!(this._univerInstanceService.getUnit(unitId, UniverInstanceType.UNIVER_DOC) instanceof DocumentDataModel)) return;
517
+ this._infoPopupPinned = (options === null || options === void 0 ? void 0 : options.pinned) ?? false;
443
518
  this._showingLink$.next({
444
519
  unitId,
445
520
  linkId,
@@ -458,6 +533,7 @@ let DocHyperLinkPopupService = class DocHyperLinkPopupService extends Disposable
458
533
  componentKey: DocLinkPopup.componentKey,
459
534
  direction: "top-center",
460
535
  multipleDirection: "top",
536
+ offset: [0, 10],
461
537
  onClickOutside: () => {
462
538
  this.hideInfoPopup();
463
539
  }
@@ -466,14 +542,49 @@ let DocHyperLinkPopupService = class DocHyperLinkPopupService extends Disposable
466
542
  }
467
543
  hideInfoPopup() {
468
544
  var _this$_infoPopup;
545
+ this.cancelScheduledHideInfoPopup();
546
+ this._infoPopupPinned = false;
469
547
  this._showingLink$.next(null);
470
548
  (_this$_infoPopup = this._infoPopup) === null || _this$_infoPopup === void 0 || _this$_infoPopup.dispose();
549
+ this._infoPopup = null;
550
+ }
551
+ scheduleHideInfoPopup() {
552
+ if (this._infoPopupPinned || !this.showing) return;
553
+ this.cancelScheduledHideInfoPopup();
554
+ this._infoPopupHideTimer = setTimeout(() => {
555
+ this._infoPopupHideTimer = null;
556
+ if (!this._infoPopupPinned) this.hideInfoPopup();
557
+ }, INFO_POPUP_HIDE_DELAY);
558
+ }
559
+ cancelScheduledHideInfoPopup() {
560
+ if (this._infoPopupHideTimer !== null) {
561
+ clearTimeout(this._infoPopupHideTimer);
562
+ this._infoPopupHideTimer = null;
563
+ }
564
+ }
565
+ hideInfoPopupOnPointerDown() {
566
+ this._infoPopupSuppressed = true;
567
+ if (this._infoPopupSuppressionTimer !== null) clearTimeout(this._infoPopupSuppressionTimer);
568
+ this.hideInfoPopup();
569
+ this._infoPopupSuppressionTimer = setTimeout(() => {
570
+ this._infoPopupSuppressed = false;
571
+ this._infoPopupSuppressionTimer = null;
572
+ }, 0);
573
+ }
574
+ canEditLink(unitId, linkInfo) {
575
+ const document = this._univerInstanceService.getUnit(unitId, UniverInstanceType.UNIVER_DOC);
576
+ if (!(document instanceof DocumentDataModel)) return false;
577
+ if (!linkInfo) return canEditDocumentTargets(this._permissionService, unitId, []);
578
+ const segmentId = linkInfo.segmentId ?? "";
579
+ return canEditDocumentTargets(this._permissionService, unitId, [...getDocumentEntityParentPermissionObjectIds(document, segmentId, "custom-range", linkInfo.linkId), getDocumentEntityPermissionObjectId(segmentId, "custom-range", linkInfo.linkId)]);
471
580
  }
472
581
  };
473
582
  DocHyperLinkPopupService = __decorate([
474
583
  __decorateParam(0, Inject(DocCanvasPopManagerService)),
475
584
  __decorateParam(1, Inject(DocSelectionManagerService)),
476
- __decorateParam(2, IUniverInstanceService)
585
+ __decorateParam(2, IUniverInstanceService),
586
+ __decorateParam(3, IPermissionService),
587
+ __decorateParam(4, IRenderManagerService)
477
588
  ], DocHyperLinkPopupService);
478
589
 
479
590
  //#endregion
@@ -498,7 +609,7 @@ const ShowDocHyperLinkEditPopupOperation = {
498
609
  const hyperLinkService = accessor.get(DocHyperLinkPopupService);
499
610
  const unitId = (linkInfo === null || linkInfo === void 0 ? void 0 : linkInfo.unitId) || ((_univerInstanceServic = univerInstanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_DOC)) === null || _univerInstanceServic === void 0 ? void 0 : _univerInstanceServic.getUnitId());
500
611
  if (!unitId) return false;
501
- hyperLinkService.showEditPopup(unitId, linkInfo);
612
+ hyperLinkService.showEditPopup(unitId, linkInfo ?? null);
502
613
  return true;
503
614
  }
504
615
  };
@@ -588,7 +699,7 @@ const menuSchema = {
588
699
  //#endregion
589
700
  //#region package.json
590
701
  var name = "@univerjs/docs-hyper-link-ui";
591
- var version = "1.0.0-insiders.20260809-70eefdd";
702
+ var version = "1.0.0-rc.0";
592
703
 
593
704
  //#endregion
594
705
  //#region src/config/config.ts
@@ -648,25 +759,23 @@ let DocHyperLinkSelectionController = class DocHyperLinkSelectionController exte
648
759
  const { unitId, ranges, segmentId } = commandInfo.params;
649
760
  const doc = this._univerInstanceService.getUnit(unitId, UniverInstanceType.UNIVER_DOC);
650
761
  const primary = ranges[0];
651
- if (primary && doc) {
762
+ if ((primary === null || primary === void 0 ? void 0 : primary.collapsed) && doc) {
652
763
  var _doc$getSelfOrHeaderF;
653
- const { startOffset, endOffset, collapsed, segmentPage } = primary;
764
+ const { startOffset, endOffset, segmentPage } = primary;
654
765
  const customRanges = (_doc$getSelfOrHeaderF = doc.getSelfOrHeaderFooterModel(segmentId)) === null || _doc$getSelfOrHeaderF === void 0 || (_doc$getSelfOrHeaderF = _doc$getSelfOrHeaderF.getBody()) === null || _doc$getSelfOrHeaderF === void 0 ? void 0 : _doc$getSelfOrHeaderF.customRanges;
655
- if (collapsed) {
656
- const index = (customRanges === null || customRanges === void 0 ? void 0 : customRanges.findIndex((value) => value.startIndex < startOffset && value.endIndex > endOffset - 1)) ?? -1;
657
- if (index > -1) {
658
- const customRange = customRanges[index];
659
- this._docHyperLinkService.showInfoPopup({
660
- unitId,
661
- linkId: customRange.rangeId,
662
- segmentId,
663
- segmentPage,
664
- startIndex: customRange.startIndex,
665
- endIndex: customRange.endIndex
666
- });
667
- return;
668
- }
669
- } else if (customRanges === null || customRanges === void 0 ? void 0 : customRanges.find((value) => value.startIndex <= startOffset && value.endIndex >= endOffset - 1)) return;
766
+ const showing = this._docHyperLinkService.showing;
767
+ const customRange = ((showing === null || showing === void 0 ? void 0 : showing.unitId) === unitId && (showing.segmentId ?? "") === segmentId && showing.segmentPage === segmentPage && showing.endIndex === endOffset - 1 ? customRanges === null || customRanges === void 0 ? void 0 : customRanges.find((value) => value.rangeId === showing.linkId && value.rangeType === CustomRangeType.HYPERLINK && value.startIndex <= startOffset && value.endIndex === endOffset - 1) : void 0) ?? (customRanges === null || customRanges === void 0 ? void 0 : customRanges.find((value) => value.rangeType === CustomRangeType.HYPERLINK && value.startIndex <= startOffset && value.endIndex > endOffset - 1));
768
+ if (customRange) {
769
+ this._docHyperLinkService.showInfoPopup({
770
+ unitId,
771
+ linkId: customRange.rangeId,
772
+ segmentId,
773
+ segmentPage,
774
+ startIndex: customRange.startIndex,
775
+ endIndex: customRange.endIndex
776
+ });
777
+ return;
778
+ }
670
779
  }
671
780
  this._docHyperLinkService.hideInfoPopup();
672
781
  this._docHyperLinkService.hideEditPopup();
@@ -695,11 +804,18 @@ let DocHyperLinkEventRenderController = class DocHyperLinkEventRenderController
695
804
  this._docSkeletonManagerService = _docSkeletonManagerService;
696
805
  this._docSelectionManagerService = _docSelectionManagerService;
697
806
  if (this._context.unitId === DOCS_NORMAL_EDITOR_UNIT_ID_KEY) return;
807
+ this._initPointerDown();
698
808
  this._initHover();
699
809
  this._initClick();
700
810
  }
701
811
  _hideInfoPopup() {
702
- if (this._hyperLinkPopupService.showing) this._commandService.executeCommand(ToggleDocHyperLinkInfoPopupOperation.id);
812
+ if (this._hyperLinkPopupService.infoPopupPinned) return;
813
+ if (this._hyperLinkPopupService.showing) this._hyperLinkPopupService.scheduleHideInfoPopup();
814
+ }
815
+ _initPointerDown() {
816
+ this.disposeWithMe(this._docEventManagerService.pointerDownCustomRanges$.subscribe((ranges) => {
817
+ if (!ranges.some((range) => range.range.rangeType === CustomRangeType.HYPERLINK)) this._hyperLinkPopupService.hideInfoPopupOnPointerDown();
818
+ }));
703
819
  }
704
820
  _initHover() {
705
821
  this.disposeWithMe(this._docEventManagerService.hoverCustomRanges$.subscribe((ranges) => {
@@ -726,7 +842,19 @@ let DocHyperLinkEventRenderController = class DocHyperLinkEventRenderController
726
842
  _initClick() {
727
843
  this.disposeWithMe(this._docEventManagerService.clickCustomRanges$.subscribe((range) => {
728
844
  const link = range.range;
729
- if (link) this._commandService.executeCommand(ClickDocHyperLinkOperation.id, {
845
+ if (link.rangeType !== CustomRangeType.HYPERLINK) return;
846
+ if (!range.ctrlKey && !range.metaKey) {
847
+ this._hyperLinkPopupService.showInfoPopup({
848
+ unitId: this._context.unitId,
849
+ linkId: link.rangeId,
850
+ segmentId: range.segmentId,
851
+ segmentPage: range.segmentPageIndex,
852
+ startIndex: link.startIndex,
853
+ endIndex: link.endIndex
854
+ }, { pinned: true });
855
+ return;
856
+ }
857
+ this._commandService.executeCommand(ClickDocHyperLinkOperation.id, {
730
858
  unitId: this._context.unitId,
731
859
  linkId: link.rangeId,
732
860
  segmentId: range.segmentId
@@ -745,14 +873,11 @@ DocHyperLinkEventRenderController = __decorate([
745
873
  //#endregion
746
874
  //#region src/controllers/render-controllers/render.controller.ts
747
875
  let DocHyperLinkRenderController = class DocHyperLinkRenderController extends Disposable {
748
- constructor(_context, _docInterceptorService, _hyperLinkService, _docRenderController) {
876
+ constructor(_context, _docInterceptorService, _hyperLinkService) {
749
877
  super();
750
- this._context = _context;
751
878
  this._docInterceptorService = _docInterceptorService;
752
879
  this._hyperLinkService = _hyperLinkService;
753
- this._docRenderController = _docRenderController;
754
880
  this._init();
755
- this._initReRender();
756
881
  }
757
882
  _init() {
758
883
  this._docInterceptorService.intercept(DOC_INTERCEPTOR_POINT.CUSTOM_RANGE, { handler: (data, pos, next) => {
@@ -771,19 +896,8 @@ let DocHyperLinkRenderController = class DocHyperLinkRenderController extends Di
771
896
  });
772
897
  } });
773
898
  }
774
- _initReRender() {
775
- this.disposeWithMe(this._hyperLinkService.showingLink$.pipe(distinctUntilChanged((prev, aft) => (prev === null || prev === void 0 ? void 0 : prev.linkId) === (aft === null || aft === void 0 ? void 0 : aft.linkId) && (prev === null || prev === void 0 ? void 0 : prev.unitId) === (aft === null || aft === void 0 ? void 0 : aft.unitId) && (prev === null || prev === void 0 ? void 0 : prev.startIndex) === (aft === null || aft === void 0 ? void 0 : aft.startIndex)), pairwise()).subscribe(([preLink, link]) => {
776
- if (link) {
777
- if (link.unitId === this._context.unitId) this._docRenderController.reRender(link.unitId);
778
- } else if (preLink && preLink.unitId === this._context.unitId) this._docRenderController.reRender(preLink.unitId);
779
- }));
780
- }
781
899
  };
782
- DocHyperLinkRenderController = __decorate([
783
- __decorateParam(1, Inject(DocInterceptorService)),
784
- __decorateParam(2, Inject(DocHyperLinkPopupService)),
785
- __decorateParam(3, Inject(DocRenderController))
786
- ], DocHyperLinkRenderController);
900
+ DocHyperLinkRenderController = __decorate([__decorateParam(1, Inject(DocInterceptorService)), __decorateParam(2, Inject(DocHyperLinkPopupService))], DocHyperLinkRenderController);
787
901
 
788
902
  //#endregion
789
903
  //#region src/controllers/ui.controller.ts
@@ -3,9 +3,7 @@ const locale = { "docs-hyper-link-ui": {
3
3
  edit: {
4
4
  confirm: "تأكيد",
5
5
  cancel: "إلغاء",
6
- title: "ارتباط",
7
6
  address: "ارتباط",
8
- placeholder: "يُرجى إدخال عنوان URL للارتباط",
9
7
  addressError: "عنوان URL غير قانوني!",
10
8
  label: "تسمية",
11
9
  labelError: "يُرجى إدخال تسمية الارتباط"
@@ -3,9 +3,7 @@ const locale = { "docs-hyper-link-ui": {
3
3
  edit: {
4
4
  confirm: "Confirma",
5
5
  cancel: "Cancel·la",
6
- title: "Enllaç",
7
6
  address: "Enllaç",
8
- placeholder: "Si us plau, introdueix una URL",
9
7
  addressError: "La URL no és vàlida!",
10
8
  label: "Etiqueta",
11
9
  labelError: "Si us plau, introdueix l'etiqueta de l'enllaç"
@@ -3,9 +3,7 @@ const locale = { "docs-hyper-link-ui": {
3
3
  edit: {
4
4
  confirm: "Bestätigen",
5
5
  cancel: "Abbrechen",
6
- title: "Link",
7
6
  address: "Link",
8
- placeholder: "Bitte eine Link-URL eingeben",
9
7
  addressError: "URL ist ungültig!",
10
8
  label: "Bezeichnung",
11
9
  labelError: "Bitte die Bezeichnung des Links eingeben"
@@ -18,9 +18,7 @@ const locale = { "docs-hyper-link-ui": {
18
18
  edit: {
19
19
  confirm: "Confirm",
20
20
  cancel: "Cancel",
21
- title: "Link",
22
21
  address: "Link",
23
- placeholder: "Please input a link url",
24
22
  addressError: "Url is illegal!",
25
23
  label: "Label",
26
24
  labelError: "Please input label of link"
@@ -3,9 +3,7 @@ const locale = { "docs-hyper-link-ui": {
3
3
  edit: {
4
4
  confirm: "Confirmar",
5
5
  cancel: "Cancelar",
6
- title: "Enlace",
7
6
  address: "Enlace",
8
- placeholder: "Por favor, introduce una URL",
9
7
  addressError: "¡La URL no es válida!",
10
8
  label: "Etiqueta",
11
9
  labelError: "Por favor, introduce la etiqueta del enlace"
@@ -3,9 +3,7 @@ const locale = { "docs-hyper-link-ui": {
3
3
  edit: {
4
4
  confirm: "تایید",
5
5
  cancel: "انصراف",
6
- title: "لینک",
7
6
  address: "لینک",
8
- placeholder: "لطفا یک آدرس لینک وارد کنید",
9
7
  addressError: "آدرس غیرمجاز است!",
10
8
  label: "برچسب",
11
9
  labelError: "لطفا برچسب لینک را وارد کنید"