diff --git a/app/appearance/langs/ar_SA.json b/app/appearance/langs/ar_SA.json index fe6bd19b1..b11f04359 100644 --- a/app/appearance/langs/ar_SA.json +++ b/app/appearance/langs/ar_SA.json @@ -1583,6 +1583,7 @@ "250": "تم تحديد معدل الطلب بواسطة التخزين السحابي. الرجاء التحقق من الإعدادات وأذونات التخزين السحابية", "251": "‫مجموع الأصول غير المستخدمة [%d]، [%d] فقط منها مدرج هنا‬", "252": "\uD83D\uDEA8 قد يقوم Microsoft Defender بحذف النواة عن طريق الخطأ، وحذف البيانات وتقليل الأداء بشكل كبير. يُوصى بإضافة مسار التثبيت ومسار مساحة العمل الخاصة بـ SiYuan إلى قائمة الاستثناءات", - "253": "جارٍ ضغط الملف [%s]، يرجى الانتظار..." + "253": "جارٍ ضغط الملف [%s]، يرجى الانتظار...", + "254": "[Region ID] معرّف المنطقة غير صحيح، يرجى الرجوع إلى وثائق مزود خدمة S3 لتكوين معرّف المنطقة" } } diff --git a/app/appearance/langs/de_DE.json b/app/appearance/langs/de_DE.json index cec8addd2..38850a0b1 100644 --- a/app/appearance/langs/de_DE.json +++ b/app/appearance/langs/de_DE.json @@ -1583,6 +1583,7 @@ "250": "Die Anfrage wurde vom Cloud-Speicher begrenzt. Bitte überprüfen Sie die Einstellungen und die Berechtigungen für den Cloud-Speicher", "251": "Insgesamt ungenutzte Assets [%d], hier nur [%d] aufgeführt", "252": "\uD83D\uDEA8 Microsoft Defender kann fälschlicherweise den Kernel löschen, Daten löschen und die Leistung erheblich verringern. Es wird empfohlen, den SiYuan-Installationspfad und den Arbeitsbereichspfad zur Ausschlussliste hinzuzufügen", - "253": "Datei [%s] wird komprimiert, bitte warten..." + "253": "Datei [%s] wird komprimiert, bitte warten...", + "254": "[Region ID] Falsche Regions-ID, bitte konsultieren Sie die Dokumentation des S3-Dienstanbieters zur Konfiguration der Regions-ID" } } diff --git a/app/appearance/langs/en_US.json b/app/appearance/langs/en_US.json index 48b926c85..0fdd7effb 100644 --- a/app/appearance/langs/en_US.json +++ b/app/appearance/langs/en_US.json @@ -1583,6 +1583,7 @@ "250": "Request has been rate-limited by cloud storage. Please check the settings and cloud storage permissions", "251": "Total unused assets [%d], only [%d] listed here", "252": "\uD83D\uDEA8 Microsoft Defender may mistakenly delete the kernel, delete data, and significantly reduce performance. It is recommended to add the SiYuan installation path and workspace path to the exclusion list", - "253": "Compressing file [%s], please wait..." + "253": "Compressing file [%s], please wait...", + "254": "[Region ID] Incorrect Region ID, please refer to the S3 service provider's documentation to configure the Region ID" } } diff --git a/app/appearance/langs/es_ES.json b/app/appearance/langs/es_ES.json index 84dec9b3b..8a8bd14bc 100644 --- a/app/appearance/langs/es_ES.json +++ b/app/appearance/langs/es_ES.json @@ -1583,6 +1583,7 @@ "250": "La solicitud ha sido limitada por el almacenamiento en la nube. Por favor, verifique las configuraciones y permisos de almacenamiento en la nube", "251": "Total de activos no utilizados [%d], solo [%d] listados aquí", "252": "\uD83D\uDEA8 Microsoft Defender puede eliminar por error el núcleo, eliminar datos y reducir significativamente el rendimiento. Se recomienda agregar la ruta de instalación y el espacio de trabajo de SiYuan a la lista de exclusiones", - "253": "Comprimiendo el archivo [%s], por favor espere..." + "253": "Comprimiendo el archivo [%s], por favor espere...", + "254": "[Region ID] ID de región incorrecto, por favor consulte la documentación del proveedor de servicios S3 para configurar el ID de región" } } diff --git a/app/appearance/langs/fr_FR.json b/app/appearance/langs/fr_FR.json index c16a4eb27..0f6fcbcd2 100644 --- a/app/appearance/langs/fr_FR.json +++ b/app/appearance/langs/fr_FR.json @@ -1583,6 +1583,7 @@ "250": "La demande a été limitée par le stockage cloud. Veuillez vérifier les paramètres et les autorisations de stockage cloud", "251": "Total des actifs inutilisés [%d], seulement [%d] listés ici", "252": "\uD83D\uDEA8 Microsoft Defender peut supprimer par erreur le noyau, supprimer des données et réduire considérablement les performances. Il est recommandé d'ajouter le chemin d'installation et l'espace de travail de SiYuan à la liste des exclusions", - "253": "Compression du fichier [%s], veuillez patienter..." + "253": "Compression du fichier [%s], veuillez patienter...", + "254": "[Region ID] ID de région incorrect, veuillez consulter la documentation du fournisseur de services S3 pour configurer l'ID de région" } } diff --git a/app/appearance/langs/he_IL.json b/app/appearance/langs/he_IL.json index ff42f96bd..1dca2d611 100644 --- a/app/appearance/langs/he_IL.json +++ b/app/appearance/langs/he_IL.json @@ -1583,6 +1583,7 @@ "250": "הבקשה הוגבלה על ידי אחסון הענן. אנא בדוק את ההגדרות והרשאות האחסון בענן", "251": "סך כל הנכסים שלא נעשה בהם שימוש [%d], רק [%d] מופיעים כאן", "252": "\uD83D\uDEA8 Microsoft Defender עלול למחוק בטעות את הליבה, למחוק נתונים ולהפחית משמעותית את הביצועים. מומלץ להוסיף את נתיב ההתקנה ונתיב סביבת העבודה של SiYuan לרשימת החריגים", - "253": "דוחס את הקובץ [%s], אנא המתן..." + "253": "דוחס את הקובץ [%s], אנא המתן...", + "254": "[Region ID] מזהה האזור שגוי, אנא עיין בתיעוד ספק שירותי S3 כדי להגדיר את מזהה האזור" } } diff --git a/app/appearance/langs/it_IT.json b/app/appearance/langs/it_IT.json index 3ff032287..6a296e224 100644 --- a/app/appearance/langs/it_IT.json +++ b/app/appearance/langs/it_IT.json @@ -1583,6 +1583,7 @@ "250": "La richiesta è stata limitata dall'archiviazione cloud. Si prega di controllare attentamente le impostazioni e le autorizzazioni di archiviazione cloud", "251": "Totale risorse inutilizzate [%d], qui elencate solo [%d]", "252": "\uD83D\uDEA8 Microsoft Defender potrebbe eliminare erroneamente il kernel, eliminare i dati e ridurre significativamente le prestazioni. Si consiglia di aggiungere il percorso di installazione e lo spazio di lavoro di SiYuan all'elenco delle esclusioni", - "253": "Compressione del file [%s], attendere prego..." + "253": "Compressione del file [%s], attendere prego...", + "254": "[Region ID] ID regione non corretto, si prega di consultare la documentazione del fornitore di servizi S3 per configurare l'ID regione" } } diff --git a/app/appearance/langs/ja_JP.json b/app/appearance/langs/ja_JP.json index 67e8ac3ea..03971664c 100644 --- a/app/appearance/langs/ja_JP.json +++ b/app/appearance/langs/ja_JP.json @@ -1583,6 +1583,7 @@ "250": "リクエストがクラウドストレージによって制限されました。設定を一つずつ確認し、クラウドストレージの権限を確認してください", "251": "未使用のアセットの合計 [%d]、ここにリストされているのは [%d] のみ", "252": "\uD83D\uDEA8 Microsoft Defender は、カーネルを誤って削除したり、データを削除したり、パフォーマンスを大幅に低下させたりする可能性があります。SiYuan のインストールパスとワークスペースパスを除外リストに追加することをお勧めします", - "253": "ファイル [%s] を圧縮しています、お待ちください..." + "253": "ファイル [%s] を圧縮しています、お待ちください...", + "254": "[Region ID] リージョンIDが正しくありません。S3サービスプロバイダーのドキュメントを参照してリージョンIDを設定してください" } } diff --git a/app/appearance/langs/pl_PL.json b/app/appearance/langs/pl_PL.json index 40f1c8b0b..97e4efb46 100644 --- a/app/appearance/langs/pl_PL.json +++ b/app/appearance/langs/pl_PL.json @@ -1583,6 +1583,7 @@ "250": "Żądanie zostało ograniczone przez przechowywanie w chmurze. Proszę dokładnie sprawdzić ustawienia i uprawnienia do przechowywania w chmurze", "251": "Łączna liczba nieużywanych zasobów [%d], tutaj wymieniono tylko [%d]", "252": "\uD83D\uDEA8 Microsoft Defender może błędnie usunąć jądro, usunąć dane i znacznie obniżyć wydajność. Zaleca się dodanie ścieżki instalacji i przestrzeni roboczej SiYuan do listy wykluczeń", - "253": "Kompresja pliku [%s], proszę czekać..." + "253": "Kompresja pliku [%s], proszę czekać...", + "254": "[Region ID] Nieprawidłowy identyfikator regionu, proszę zapoznać się z dokumentacją dostawcy usług S3 w celu skonfigurowania identyfikatora regionu" } } diff --git a/app/appearance/langs/ru_RU.json b/app/appearance/langs/ru_RU.json index ba34b829e..21b8b771e 100644 --- a/app/appearance/langs/ru_RU.json +++ b/app/appearance/langs/ru_RU.json @@ -1583,6 +1583,7 @@ "250": "Запрос был ограничен облачным хранилищем. Пожалуйста, проверьте настройки и права доступа к облачному хранилищу", "251": "Всего неиспользованных активов [%d], здесь перечислены только [%d]", "252": "\uD83D\uDEA8 Microsoft Defender может ошибочно удалить ядро, удалить данные и значительно снизить производительность. Рекомендуется добавить путь установки и рабочее пространство SiYuan в список исключений", - "253": "Сжатие файла [%s], пожалуйста, подождите..." + "253": "Сжатие файла [%s], пожалуйста, подождите...", + "254": "[Region ID] Неправильный идентификатор региона, пожалуйста, обратитесь к документации поставщика услуг S3 для настройки идентификатора региона" } } diff --git a/app/appearance/langs/zh_CHT.json b/app/appearance/langs/zh_CHT.json index e8d646b3e..66187f439 100644 --- a/app/appearance/langs/zh_CHT.json +++ b/app/appearance/langs/zh_CHT.json @@ -1583,6 +1583,7 @@ "250": "請求已被雲端存儲限流,請仔細逐個核對配置項,並檢查雲端存儲相關權限配置", "251": "未引用資源一共 ${x} 個,這裡僅列出 ${y} 個", "252": "\uD83D\uDEA8 Microsoft Defender 可能會誤殺內核、誤刪數據和嚴重降低運行性能,建議將思源安裝路徑和工作空間路徑添加到排除列表", - "253": "正在壓縮文件 [%s],請稍等..." + "253": "正在壓縮文件 [%s],請稍等...", + "254": "[Region ID] 不正確,請參考 S3 服務提供商的文檔配置地域 ID" } } diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json index 8392a4dcb..a503f1460 100644 --- a/app/appearance/langs/zh_CN.json +++ b/app/appearance/langs/zh_CN.json @@ -1583,6 +1583,7 @@ "250": "请求已被云端存储限流,请仔细逐个核对配置项,并检查云端存储相关权限配置", "251": "未引用资源一共 [%d] 个,这里仅列出 [%d] 个", "252": "\uD83D\uDEA8 Microsoft Defender 可能会误杀内核、误删数据和严重降低运行性能,建议将思源安装路径和工作空间路径添加到排除列表", - "253": "正在压缩文件 [%s],请稍等..." + "253": "正在压缩文件 [%s],请稍等...", + "254": "[Region ID] 不正确,请参考 S3 服务提供商的文档配置地域 ID" } } diff --git a/app/src/mobile/util/MobileBackFoward.ts b/app/src/mobile/util/MobileBackFoward.ts index 07f481632..3d23e5357 100644 --- a/app/src/mobile/util/MobileBackFoward.ts +++ b/app/src/mobile/util/MobileBackFoward.ts @@ -153,9 +153,13 @@ export const goBack = () => { closePanel(); return; } - if (window.JSAndroid && window.siyuan.backStack.length < 1) { + if ((window.JSAndroid || window.JSHarmony) && window.siyuan.backStack.length < 1) { if (document.querySelector('#message [data-id="exitTip"]')) { - window.JSAndroid.returnDesktop(); + if (window.JSAndroid) { + window.JSAndroid.returnDesktop(); + } else if (window.JSHarmony) { + window.JSHarmony.returnDesktop(); + } } else { showMessage(window.siyuan.languages.returnDesktop, 3000, "info", "exitTip"); } diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index 139a6beda..b1b35b916 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -199,6 +199,7 @@ interface Window { writeClipboard(text: string): void writeHTMLClipboard(text: string, html: string): void readClipboard(): string + returnDesktop(): void } Protyle: import("../protyle/method").default diff --git a/kernel/model/blockial.go b/kernel/model/blockial.go index d5f3db007..603af84d5 100644 --- a/kernel/model/blockial.go +++ b/kernel/model/blockial.go @@ -232,7 +232,7 @@ func setNodeAttrs0(node *ast.Node, nameValues map[string]string) (oldAttrs map[s } for name, value := range nameValues { - value = util.RemoveInvalid(value) + value = util.RemoveInvalidRetainCtrl(value) value = strings.TrimSpace(value) value = strings.TrimSuffix(value, ",") if "" == value { diff --git a/kernel/model/blockinfo.go b/kernel/model/blockinfo.go index f0e291fea..dc0b1f48d 100644 --- a/kernel/model/blockinfo.go +++ b/kernel/model/blockinfo.go @@ -240,7 +240,7 @@ func GetBlockRefText(id string) string { func GetDOMText(dom string) (ret string) { luteEngine := NewLute() tree := luteEngine.BlockDOM2Tree(dom) - ret = renderBlockText(tree.Root.FirstChild, nil) + ret = renderBlockText(tree.Root.FirstChild, nil, true) return } @@ -265,7 +265,7 @@ func getNodeRefText(node *ast.Node) string { ret = util.EscapeHTML(ret) return ret } - return getNodeRefText0(node, Conf.Editor.BlockRefDynamicAnchorTextMaxLen) + return getNodeRefText0(node, Conf.Editor.BlockRefDynamicAnchorTextMaxLen, true) } func getNodeAvBlockText(node *ast.Node) (icon, content string) { @@ -279,7 +279,7 @@ func getNodeAvBlockText(node *ast.Node) (icon, content string) { name = util.EscapeHTML(name) content = name } else { - content = getNodeRefText0(node, 1024) + content = getNodeRefText0(node, 1024, false) } content = strings.TrimSpace(content) @@ -290,7 +290,7 @@ func getNodeAvBlockText(node *ast.Node) (icon, content string) { return } -func getNodeRefText0(node *ast.Node, maxLen int) string { +func getNodeRefText0(node *ast.Node, maxLen int, removeLineBreak bool) string { switch node.Type { case ast.NodeBlockQueryEmbed: return "Query Embed Block..." @@ -313,7 +313,7 @@ func getNodeRefText0(node *ast.Node, maxLen int) string { if ast.NodeDocument != node.Type && node.IsContainerBlock() { node = treenode.FirstLeafBlock(node) } - ret := renderBlockText(node, nil) + ret := renderBlockText(node, nil, removeLineBreak) if maxLen < utf8.RuneCountInString(ret) { ret = gulu.Str.SubStr(ret, maxLen) + "..." } @@ -481,9 +481,9 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string, isEmbedBlock bo } else { if "" == name { if ast.NodeListItem == parent.Type || ast.NodeList == parent.Type || ast.NodeSuperBlock == parent.Type || ast.NodeBlockquote == parent.Type { - name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes), maxNameLen) + name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes, true), maxNameLen) } else { - name = gulu.Str.SubStr(renderBlockText(parent, excludeTypes), maxNameLen) + name = gulu.Str.SubStr(renderBlockText(parent, excludeTypes, true), maxNameLen) } } if ast.NodeHeading == parent.Type { @@ -504,7 +504,7 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string, isEmbedBlock bo } if ast.NodeListItem == parent.Type { if "" == name { - name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes), maxNameLen) + name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes, true), maxNameLen) } } @@ -542,7 +542,7 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string, isEmbedBlock bo continue } - name = gulu.Str.SubStr(renderBlockText(b, excludeTypes), maxNameLen) + name = gulu.Str.SubStr(renderBlockText(b, excludeTypes, true), maxNameLen) name = util.EscapeHTML(name) ret = append([]*BlockPath{{ ID: b.ID, diff --git a/kernel/model/heading.go b/kernel/model/heading.go index 0da46a492..b9749d0f3 100644 --- a/kernel/model/heading.go +++ b/kernel/model/heading.go @@ -296,7 +296,7 @@ func Heading2Doc(srcHeadingID, targetBoxID, targetPath, previousPath string) (sr } box := Conf.Box(targetBoxID) - headingText := getNodeRefText0(headingNode, Conf.Editor.BlockRefDynamicAnchorTextMaxLen) + headingText := getNodeRefText0(headingNode, Conf.Editor.BlockRefDynamicAnchorTextMaxLen, true) if strings.Contains(headingText, "/") { headingText = strings.ReplaceAll(headingText, "/", "_") util.PushMsg(Conf.language(246), 7000) diff --git a/kernel/model/render.go b/kernel/model/render.go index 5fcace663..82d459e20 100644 --- a/kernel/model/render.go +++ b/kernel/model/render.go @@ -103,14 +103,16 @@ func renderOutline(heading *ast.Node, luteEngine *lute.Lute) (ret string) { return } -func renderBlockText(node *ast.Node, excludeTypes []string) (ret string) { +func renderBlockText(node *ast.Node, excludeTypes []string, removeLineBreak bool) (ret string) { if nil == node { return } ret = sql.NodeStaticContent(node, excludeTypes, false, false, false) ret = strings.TrimSpace(ret) - ret = strings.ReplaceAll(ret, "\n", "") + if removeLineBreak { + ret = strings.ReplaceAll(ret, "\n", "") + } ret = util.UnescapeHTML(ret) ret = util.EscapeHTML(ret) ret = strings.TrimSpace(ret) diff --git a/kernel/model/sync.go b/kernel/model/sync.go index d47dfade0..51522f380 100644 --- a/kernel/model/sync.go +++ b/kernel/model/sync.go @@ -648,6 +648,8 @@ func formatRepoErrorMsg(err error) string { msgLowerCase := strings.ToLower(msg) if strings.Contains(msgLowerCase, "permission denied") || strings.Contains(msg, "access is denied") { msg = Conf.Language(33) + } else if strings.Contains(msgLowerCase, "region was not a valid DNS name") { + msg = Conf.language(254) } else if strings.Contains(msgLowerCase, "device or resource busy") || strings.Contains(msg, "is being used by another") { msg = fmt.Sprintf(Conf.Language(85), err) } else if strings.Contains(msgLowerCase, "cipher: message authentication failed") { diff --git a/kernel/model/template.go b/kernel/model/template.go index 0388e1f8c..0f6596a1c 100644 --- a/kernel/model/template.go +++ b/kernel/model/template.go @@ -188,12 +188,16 @@ func DocSaveAsTemplate(id, name string, overwrite bool) (code int, err error) { return ast.WalkContinue } - // Code content in templates is not properly escaped https://github.com/siyuan-note/siyuan/issues/9649 + // Content in templates is not properly escaped + // https://github.com/siyuan-note/siyuan/issues/9649 + // https://github.com/siyuan-note/siyuan/issues/13701 switch n.Type { case ast.NodeCodeBlockCode: n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("""), []byte("\"")) case ast.NodeCodeSpanContent: n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("""), []byte("\"")) + case ast.NodeBlockQueryEmbedScript: + n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("""), []byte("\"")) case ast.NodeTextMark: if n.IsTextMarkType("code") { n.TextMarkTextContent = strings.ReplaceAll(n.TextMarkTextContent, """, "\"") diff --git a/kernel/util/rune.go b/kernel/util/rune.go index 3e385d5ae..c6b3593a0 100644 --- a/kernel/util/rune.go +++ b/kernel/util/rune.go @@ -20,6 +20,7 @@ import ( "os" "path/filepath" "regexp" + "strings" "unicode" "github.com/88250/gulu" @@ -69,6 +70,13 @@ func RemoveInvalid(text string) (ret string) { return } +func RemoveInvalidRetainCtrl(text string) (ret string) { + ret = strings.ReplaceAll(text, "\u00A0", " ") // NBSP 转换为普通空格 + ret = gulu.Str.RemoveZeroWidthCharacters(ret) + ret = gulu.Str.RemovePUA(ret) + return +} + var NativeEmojiChars = map[string]bool{} func InitEmojiChars() {