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() {