dsh-chat-link-actions 0.2.5 → 0.2.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.
Files changed (2) hide show
  1. package/client.js +65 -12
  2. package/package.json +1 -1
package/client.js CHANGED
@@ -477,6 +477,37 @@ window.__ModuleLoader__.load({
477
477
  "@keyframes dcla-in{from{opacity:0;transform:translateY(-2px);}to{opacity:1;transform:none;}}"
478
478
  ].join("");
479
479
 
480
+ /** 界面语言跟着宿主走:宿主把当前语言写在 <html lang> 上。 */ // ui-copy-ignore
481
+ var TEXT = {
482
+ zh: { // ui-copy-ignore
483
+ menu: "文件操作", // ui-copy-ignore
484
+ quote: "引用到对话", // ui-copy-ignore
485
+ reveal: "在文件管理器中查看", // ui-copy-ignore
486
+ copy: "复制路径", // ui-copy-ignore
487
+ copiedPath: "已复制路径", // ui-copy-ignore
488
+ copiedQuote: "已复制引用", // ui-copy-ignore
489
+ missing: "目标文件不存在", // ui-copy-ignore
490
+ managerFailed: "无法打开文件管理器" // ui-copy-ignore
491
+ },
492
+ en: { // ui-copy-ignore
493
+ menu: "File actions", // ui-copy-ignore
494
+ quote: "Quote in chat", // ui-copy-ignore
495
+ reveal: "Show in file manager", // ui-copy-ignore
496
+ copy: "Copy path", // ui-copy-ignore
497
+ copiedPath: "Path copied", // ui-copy-ignore
498
+ copiedQuote: "Reference copied", // ui-copy-ignore
499
+ missing: "File not found", // ui-copy-ignore
500
+ managerFailed: "Could not open the file manager" // ui-copy-ignore
501
+ }
502
+ };
503
+
504
+ function strings() {
505
+ var element = document.documentElement;
506
+ var lang = element === null ? "" : element.getAttribute("lang");
507
+ var tag = typeof lang === "string" && lang !== "" ? lang : (typeof navigator === "undefined" ? "" : navigator.language);
508
+ return /^zh/i.test(String(tag === null || tag === undefined ? "" : tag)) ? TEXT.zh : TEXT.en;
509
+ }
510
+
480
511
  function ensureStyle() {
481
512
  if (document.getElementById(STYLE_ID) !== null) return;
482
513
  var style = document.createElement("style");
@@ -546,12 +577,29 @@ window.__ModuleLoader__.load({
546
577
 
547
578
  function onKeyDown(event) {
548
579
  if (open === null) return;
580
+ var typing = editableField(event.target) === true || (open.restoreFocus !== null && editableField(open.restoreFocus) === true);
549
581
  if (event.key === "Escape") {
550
582
  event.preventDefault();
551
583
  event.stopPropagation();
552
584
  closeMenu(true);
553
585
  return;
554
586
  }
587
+ if (typing && event.key !== "ArrowDown" && event.key !== "ArrowUp") {
588
+ /* 用户已经在打字,就当放弃了菜单,别抢键。 */
589
+ closeMenu(false);
590
+ return;
591
+ }
592
+ if (event.key === "Tab") {
593
+ closeMenu(false);
594
+ return;
595
+ }
596
+ if (event.key === "Home" || event.key === "End") {
597
+ event.preventDefault();
598
+ event.stopPropagation();
599
+ open.index = event.key === "Home" ? 0 : open.items.length - 1;
600
+ paintActive();
601
+ return;
602
+ }
555
603
  if (event.key === "ArrowDown" || event.key === "ArrowUp") {
556
604
  event.preventDefault();
557
605
  event.stopPropagation();
@@ -593,13 +641,16 @@ window.__ModuleLoader__.load({
593
641
  for (var i = 0; i < open.buttons.length; i += 1) {
594
642
  open.buttons[i].setAttribute("data-active", i === open.index ? "true" : "false");
595
643
  }
644
+ var active = open.buttons[open.index];
645
+ if (active !== undefined) open.panel.setAttribute("aria-activedescendant", active.id);
596
646
  }
597
647
 
598
648
  function buildMenu(path, items) {
599
649
  var panel = document.createElement("div");
600
650
  panel.className = "dcla-menu";
601
651
  panel.setAttribute("role", "menu");
602
- panel.setAttribute("aria-label", "文件操作");
652
+ panel.setAttribute("aria-label", strings().menu);
653
+ panel.setAttribute("aria-activedescendant", "dcla-item-0");
603
654
 
604
655
  var caption = document.createElement("div");
605
656
  caption.className = "dcla-path";
@@ -616,7 +667,9 @@ window.__ModuleLoader__.load({
616
667
  var button = document.createElement("button");
617
668
  button.type = "button";
618
669
  button.className = "dcla-item";
670
+ button.id = "dcla-item-" + position;
619
671
  button.setAttribute("role", "menuitem");
672
+ button.setAttribute("tabindex", "-1");
620
673
  button.setAttribute("data-active", position === 0 ? "true" : "false");
621
674
 
622
675
  var glyph = document.createElement("span");
@@ -651,23 +704,23 @@ window.__ModuleLoader__.load({
651
704
  var settings = options === null || options === undefined ? {} : options;
652
705
 
653
706
  var items = [
654
- { id: "quote", label: "引用到对话", icon: "quote", run: function () {
707
+ { id: "quote", label: strings().quote, icon: "quote", run: function () {
655
708
  probePath(path, function (kind) {
656
709
  var directory = kind === "directory" ? true : kind === "file" ? false : settings.directory;
657
710
  if (directory === undefined && kind !== "file" && kind !== "directory") directory = guessDirectory(path);
658
711
  var inserted = quoteIntoComposer(path, directory);
659
712
  if (inserted) return;
660
713
  navigator.clipboard.writeText(referenceText(path)).then(function () {
661
- toast("已复制引用");
714
+ toast(strings().copiedQuote);
662
715
  }, function () {});
663
716
  });
664
717
  } },
665
- { id: "reveal", label: "在文件管理器中查看", icon: "reveal", run: function () {
718
+ { id: "reveal", label: strings().reveal, icon: "reveal", run: function () {
666
719
  reveal(path);
667
720
  } },
668
- { id: "copy", label: "复制路径", icon: "copy", run: function () {
721
+ { id: "copy", label: strings().copy, icon: "copy", run: function () {
669
722
  navigator.clipboard.writeText(path).then(function () {
670
- toast("已复制路径");
723
+ toast(strings().copiedPath);
671
724
  }, function () {});
672
725
  } }
673
726
  ];
@@ -837,7 +890,7 @@ window.__ModuleLoader__.load({
837
890
  function reveal(path) {
838
891
  probePath(path, function (kind) {
839
892
  if (kind === "missing") {
840
- toast("目标文件不存在");
893
+ toast(strings().missing);
841
894
  return;
842
895
  }
843
896
  revealViaRoute(path);
@@ -849,7 +902,7 @@ window.__ModuleLoader__.load({
849
902
  fetch("/chat-link-actions?action=reveal&path=" + encodeURIComponent(path), { method: "POST" }).then(function (response) {
850
903
  if (response.ok) return;
851
904
  if (response.status === 404) {
852
- toast("目标文件不存在");
905
+ toast(strings().missing);
853
906
  return;
854
907
  }
855
908
  revealRemote(path);
@@ -863,18 +916,18 @@ window.__ModuleLoader__.load({
863
916
  var remote = sessionRemote();
864
917
  var session = remote === null ? null : remote.session;
865
918
  if (session === null || session === undefined || typeof session.openWorkspacePath !== "function") {
866
- toast("无法打开文件管理器");
919
+ toast(strings().managerFailed);
867
920
  return;
868
921
  }
869
922
  try {
870
923
  session.openWorkspacePath({ path: path, action: "reveal" }).then(function (result) {
871
924
  if (result !== null && result !== undefined && result.ok === true) return;
872
- toast(isUnreachablePath(result === null || result === undefined ? null : result.error) ? "目标文件不存在" : "无法打开文件管理器");
925
+ toast(isUnreachablePath(result === null || result === undefined ? null : result.error) ? strings().missing : strings().managerFailed);
873
926
  }, function (error) {
874
- toast(isUnreachablePath(error) ? "目标文件不存在" : "无法打开文件管理器");
927
+ toast(isUnreachablePath(error) ? strings().missing : strings().managerFailed);
875
928
  });
876
929
  } catch (error) {
877
- toast("无法打开文件管理器");
930
+ toast(strings().managerFailed);
878
931
  }
879
932
  }
880
933
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-chat-link-actions",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "Right-click actions on file links in the DSH transcript: quote the path into the composer, or reveal the file in the OS file manager. Menus are drawn in the app's own style, never the system one.",
5
5
  "type": "module",
6
6
  "main": "index.js",