Merge branch 'dev' into dev-av-style

This commit is contained in:
Jeffrey Chen 2024-11-27 00:27:41 +08:00 committed by GitHub
commit 0e8d1e12c0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
72 changed files with 551 additions and 196 deletions

View file

@ -1,5 +1,6 @@
{
"empty": "Leer",
"newRowInRelation": "Neue Zeile in ${x} erstellen <b class='ft__on-surface'>${y}</b>",
"keyContent": "Schlüsselinhalt",
"addDesc": "Beschreibung hinzufügen",
"dataRepoAutoPurgeIndexRetentionDays": "Daten-Snapshot-Aufbewahrungstage",

View file

@ -1,5 +1,6 @@
{
"empty": "Empty",
"newRowInRelation": "Create a new row in ${x} <b class='ft__on-surface'>${y}</b>",
"keyContent": "Key content",
"addDesc": "Add description",
"dataRepoAutoPurgeIndexRetentionDays": "Data snapshot retention days",

View file

@ -1,5 +1,6 @@
{
"empty": "Vacío",
"newRowInRelation": "Crear una nueva fila en ${x} <b class='ft__on-surface'>${y}</b>",
"keyContent": "Contenido de la clave",
"addDesc": "Agregar descripción",
"dataRepoAutoPurgeIndexRetentionDays": "Días de retención de instantáneas de datos",

View file

@ -1,4 +1,5 @@
{
"newRowInRelation": "Créer une nouvelle ligne dans ${x} <b class='ft__on-surface'>${y}</b>",
"keyContent": "Contenu de la clé",
"addDesc": "Ajouter une description",
"dataRepoAutoPurgeIndexRetentionDays": "Jours de rétention des instantanés de données",

View file

@ -1,5 +1,6 @@
{
"empty": "ריק",
"newRowInRelation": "צור שורה חדשה ב-${x} <b class='ft__on-surface'>${y}</b>",
"keyContent": "תוכן המפתח",
"addDesc": "הוסף תיאור",
"dataRepoAutoPurgeIndexRetentionDays": "ימי שמירת תמונות נתונים",

View file

@ -1,5 +1,6 @@
{
"empty": "Vuoto",
"newRowInRelation": "Crea una nuova riga in ${x} <b class='ft__on-surface'>${y}</b>",
"keyContent": "Contenuto della chiave",
"addDesc": "Aggiungi descrizione",
"dataRepoAutoPurgeIndexRetentionDays": "Giorni di conservazione degli snapshot dei dati",

View file

@ -1,5 +1,6 @@
{
"empty": "空白",
"newRowInRelation": "${x} に新しい行を作成 <b class='ft__on-surface'>${y}</b>",
"keyContent": "キーコンテンツ",
"addDesc": "説明を追加",
"dataRepoAutoPurgeIndexRetentionDays": "データスナップショットの保持日数",

View file

@ -1,5 +1,6 @@
{
"empty": "Pusty",
"newRowInRelation": "Utwórz nowy wiersz w ${x} <b class='ft__on-surface'>${y}</b>",
"keyContent": "Zawartość klucza",
"addDesc": "Dodaj opis",
"dataRepoAutoPurgeIndexRetentionDays": "Dni przechowywania migawek danych",

View file

@ -1,5 +1,6 @@
{
"empty": "Пусто",
"newRowInRelation": "Создать новую строку в ${x} <b class='ft__on-surface'>${y}</b>",
"keyContent": "Содержимое ключа",
"addDesc": "Добавить описание",
"dataRepoAutoPurgeIndexRetentionDays": "Срок хранения снимков данных",

View file

@ -1,5 +1,6 @@
{
"empty": "空白",
"newRowInRelation": "在 ${x} 中新建行 <b class='ft__on-surface'>${y}</b>",
"keyContent": "主鍵內容",
"addDesc": "添加描述",
"dataRepoAutoPurgeIndexRetentionDays": "數據快照保留天數",

View file

@ -1,5 +1,6 @@
{
"empty": "空白",
"newRowInRelation": "在 ${x} 中新建行 <b class='ft__on-surface'>${y}</b>",
"keyContent": "主键内容",
"addDesc": "添加描述",
"dataRepoAutoPurgeIndexRetentionDays": "数据快照保留天数",

View file

@ -200,7 +200,7 @@
}
/* https://github.com/siyuan-note/siyuan/issues/6440 */
.protyle-action--order:after {
.protyle-action--order::after {
mix-blend-mode: multiply;
}

View file

@ -199,7 +199,7 @@
}
/* https://github.com/siyuan-note/siyuan/issues/6440 */
.protyle-action--order:after {
.protyle-action--order::after {
mix-blend-mode: screen;
}

View file

@ -8,9 +8,55 @@
"title": "Please Start Here",
"title-img": "background-color:#556;background-image: linear-gradient(30deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(150deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(30deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(150deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(60deg, #99a 25%, transparent 25.5%, transparent 75%, #99a 75%, #99a),linear-gradient(60deg, #99a 25%, transparent 25.5%, transparent 75%, #99a 75%, #99a);background-size:80px 140px;background-position: 0 0, 0 0, 40px 70px, 40px 70px, 0 0, 40px 70px;",
"type": "doc",
"updated": "20241018102340"
"updated": "20241125224626"
},
"Children": [
{
"ID": "20241125224615-dwfqru1",
"Type": "NodeBlockquote",
"Properties": {
"id": "20241125224615-dwfqru1",
"updated": "20241125224626"
},
"Children": [
{
"Type": "NodeBlockquoteMarker",
"Data": "\u003e"
},
{
"ID": "20241125224615-z2fevdf",
"Type": "NodeParagraph",
"Properties": {
"id": "20241125224615-z2fevdf",
"updated": "20241125224626"
},
"Children": [
{
"Type": "NodeText",
"Data": "When you close SiYuan Notes, the User Guide will be automatically closed. You can click "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "Main Menu"
},
{
"Type": "NodeText",
"Data": " - "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "User Guide"
},
{
"Type": "NodeText",
"Data": " to view it again"
}
]
}
]
},
{
"ID": "20210528120135-bznvpp6",
"Type": "NodeSuperBlock",

View file

@ -8,9 +8,55 @@
"title": "请从这里开始",
"title-img": "background-color:#556;background-image: linear-gradient(30deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(150deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(30deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(150deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(60deg, #99a 25%, transparent 25.5%, transparent 75%, #99a 75%, #99a),linear-gradient(60deg, #99a 25%, transparent 25.5%, transparent 75%, #99a 75%, #99a);background-size:80px 140px;background-position: 0 0, 0 0, 40px 70px, 40px 70px, 0 0, 40px 70px;",
"type": "doc",
"updated": "20241018102134"
"updated": "20241125224159"
},
"Children": [
{
"ID": "20241125224159-8zf3bos",
"Type": "NodeBlockquote",
"Properties": {
"id": "20241125224159-8zf3bos",
"updated": "20241125224159"
},
"Children": [
{
"Type": "NodeBlockquoteMarker",
"Data": "\u003e"
},
{
"ID": "20241125224159-vcaj2bv",
"Type": "NodeParagraph",
"Properties": {
"id": "20241125224159-vcaj2bv",
"updated": "20241125224159"
},
"Children": [
{
"Type": "NodeText",
"Data": "关闭思源笔记时会自动关闭用户指南,可以点击 "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "主菜单"
},
{
"Type": "NodeText",
"Data": " - "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "用户指南"
},
{
"Type": "NodeText",
"Data": " 再次查看"
}
]
}
]
},
{
"ID": "20210528115012-vst5lwt",
"Type": "NodeSuperBlock",

View file

@ -8,9 +8,55 @@
"title": "請從這裡開始",
"title-img": "background-color:#556;background-image: linear-gradient(30deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(150deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(30deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(150deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(60deg, #99a 25%, transparent 25.5%, transparent 75%, #99a 75%, #99a),linear-gradient(60deg, #99a 25%, transparent 25.5%, transparent 75%, #99a 75%, #99a);background-size:80px 140px;background-position: 0 0, 0 0, 40px 70px, 40px 70px, 0 0, 40px 70px;",
"type": "doc",
"updated": "20241018105300"
"updated": "20241125224503"
},
"Children": [
{
"ID": "20241125224503-8vqkbc9",
"Type": "NodeBlockquote",
"Properties": {
"id": "20241125224503-8vqkbc9",
"updated": "20241125224503"
},
"Children": [
{
"Type": "NodeBlockquoteMarker",
"Data": "\u003e"
},
{
"ID": "20241125224503-fqq0875",
"Type": "NodeParagraph",
"Properties": {
"id": "20241125224503-fqq0875",
"updated": "20241125224503"
},
"Children": [
{
"Type": "NodeText",
"Data": "關閉思源筆記時會自動關閉用戶指南,可以點擊 "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "主菜單"
},
{
"Type": "NodeText",
"Data": " - "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "用戶指南"
},
{
"Type": "NodeText",
"Data": " ​再次查看"
}
]
}
]
},
{
"ID": "20211226115745-rorv31l",
"Type": "NodeSuperBlock",

View file

@ -9,9 +9,55 @@
"title": "スタートガイド",
"title-img": "background-color:#556;background-image: linear-gradient(30deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(150deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(30deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(150deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),linear-gradient(60deg, #99a 25%, transparent 25.5%, transparent 75%, #99a 75%, #99a),linear-gradient(60deg, #99a 25%, transparent 25.5%, transparent 75%, #99a 75%, #99a);background-size:80px 140px;background-position: 0 0, 0 0, 40px 70px, 40px 70px, 0 0, 40px 70px;",
"type": "doc",
"updated": "20241018102426"
"updated": "20241125225136"
},
"Children": [
{
"ID": "20241125224702-5a9o34q",
"Type": "NodeBlockquote",
"Properties": {
"id": "20241125224702-5a9o34q",
"updated": "20241125225136"
},
"Children": [
{
"Type": "NodeBlockquoteMarker",
"Data": "\u003e"
},
{
"ID": "20241125225100-s0akx3f",
"Type": "NodeParagraph",
"Properties": {
"id": "20241125225100-s0akx3f",
"updated": "20241125225136"
},
"Children": [
{
"Type": "NodeText",
"Data": "SiYuan を閉じると、ユーザーガイドは自動的に閉じられます。"
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "メインメニュー"
},
{
"Type": "NodeText",
"Data": " - "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "ユーザーガイド"
},
{
"Type": "NodeText",
"Data": " ​をクリックすると、再度表示できます"
}
]
}
]
},
{
"ID": "20240530101000-x3xk6o7",
"Type": "NodeSuperBlock",

View file

@ -329,8 +329,8 @@ html {
opacity: .38;
}
.dragover__top:after,
.dragover__bottom:after {
.dragover__top::after,
.dragover__bottom::after {
content: "";
width: var(--file-toggle-width);
height: 4px;
@ -341,7 +341,7 @@ html {
z-index: 1;
}
.dragover__top:after {
.dragover__top::after {
top: -3px;
bottom: auto;
}

View file

@ -29,7 +29,7 @@
background: var(--b3-border-color);
border-radius: var(--b3-border-radius);
&:after {
&::after {
content: " ";
border-radius: var(--b3-border-radius);
position: absolute;

View file

@ -1,5 +1,16 @@
.dragover {
background-color: var(--b3-theme-primary-lightest) !important;
&::after {
background-color: var(--b3-theme-primary-lightest);
position: absolute;
width: 100%;
height: 100%;
content: " ";
left: 0;
top: 0;
z-index: 3;
pointer-events: none;
}
// 需要 !important否则拖拽到闪卡无效果
&__top {

View file

@ -7,7 +7,7 @@
position: relative;
z-index: 1;
[data-node-id].li[fold="1"] > .protyle-action:after {
[data-node-id].li[fold="1"] > .protyle-action::after {
background-color: transparent;
border: 1px solid var(--b3-list-hover);
box-sizing: border-box;

View file

@ -2,7 +2,7 @@
overflow-y: hidden; // https://github.com/siyuan-note/siyuan/issues/6706
&__wnd--active .layout-tab-bar .item--focus {
&:after {
&::after {
background-color: var(--b3-theme-primary);
}
@ -111,11 +111,11 @@
position: relative;
z-index: 4; // 需大于 #sidebarContainer https://github.com/siyuan-note/siyuan/issues/11759
&:hover:after {
&:hover::after {
background-color: var(--b3-scroll-color);
}
&:after {
&::after {
content: "";
width: 100%;
height: .5px;
@ -133,7 +133,7 @@
margin: 0 -6px 0 0;
height: auto;
&:after {
&::after {
top: 0;
width: .5px;
left: 0;
@ -226,7 +226,7 @@
max-width: none;
flex: 1;
&.item--focus:after {
&.item--focus::after {
background-color: var(--b3-theme-primary);
}
}
@ -268,7 +268,7 @@
}
}
&--focus:after {
&--focus::after {
content: "";
width: 100%;
height: 3px;
@ -384,12 +384,12 @@
padding: 0;
.dock__item {
&[data-index="0"]:after {
&[data-index="0"]::after {
top: -32px;
bottom: auto;
}
&[data-index="1"]:after {
&[data-index="1"]::after {
bottom: 100%;
}
}

View file

@ -24,7 +24,7 @@
margin: 0 -6px 0 0;
height: auto;
&:after {
&::after {
width: .5px;
height: 100%;
}
@ -104,7 +104,7 @@
position: relative;
z-index: 2;
&:after {
&::after {
content: "";
display: block;
background-color: var(--b3-theme-surface-lighter);
@ -116,7 +116,7 @@
height: .5px;
}
&:hover:after {
&:hover::after {
background-color: var(--b3-scroll-color);
}
}

View file

@ -27,7 +27,7 @@
position: relative;
}
.b3-list__panel:before {
.b3-list__panel::before {
content: "";
height: 100%;
top: 0;

View file

@ -41,7 +41,7 @@
&--error .b3-snackbar__content {
padding-left: 47px;
&:after {
&::after {
content: "";
position: absolute;
left: 16px;

View file

@ -24,7 +24,7 @@
align-self: center;
}
&:after {
&::after {
width: 8px;
height: 8px;
border-radius: 50%;
@ -40,7 +40,7 @@
transition: left 80ms linear, background-color 80ms linear, width 80ms linear, height 80ms linear;
}
&:before {
&::before {
z-index: 2;
content: "";
left: 7px;
@ -59,28 +59,28 @@
background-color: var(--b3-switch-checked-background);
border-color: transparent;
&:after {
&::after {
background-color: var(--b3-switch-checked);
height: 12px;
width: 12px;
}
&:before,
&:after {
&::before,
&::after {
left: 17px;
}
&:hover:not(:disabled) {
&:after {
&::after {
background-color: var(--b3-switch-checked-hover);
}
&:before {
&::before {
background-color: var(--b3-switch-checked-hover2);
}
}
&:active:not(:disabled):after {
&:active:not(:disabled)::after {
height: 14px;
width: 14px;
}
@ -91,12 +91,12 @@
cursor: auto;
}
&:active:not(:disabled):after {
&:active:not(:disabled)::after {
height: 10px;
width: 10px;
}
&:hover:not(:disabled):before {
&:hover:not(:disabled)::before {
display: inline-block;
}
}

View file

@ -197,8 +197,8 @@
}
@media screen and (max-width: 520px) {
.b3-tooltips:before,
.b3-tooltips:after {
.b3-tooltips::before,
.b3-tooltips::after {
content: none;
}
}

View file

@ -123,7 +123,7 @@
blockquote,
.bq {
&:before {
&::before {
content: '';
background-color: var(--b3-theme-surface-lighter);
width: .25em;
@ -345,7 +345,7 @@
display: flex;
align-items: baseline; // https://ld246.com/article/1645933216334
&:before {
&::before {
content: "";
flex: 1;
}

View file

@ -234,7 +234,7 @@
cursor: ew-resize;
right: -6px;
&:after {
&::after {
content: "";
width: 1px;
height: 100%;
@ -244,7 +244,7 @@
left: 3px;
}
&:hover:after {
&:hover::after {
background-color: var(--b3-scroll-color);
}
}

View file

@ -390,7 +390,7 @@
padding: 0 4px 0 2px;
white-space: break-spaces;
&:empty:after {
&:empty::after {
content: attr(data-tip);
color: var(--b3-theme-on-surface-light);
cursor: text;
@ -420,11 +420,11 @@ table[contenteditable="true"] + .protyle-action__table {
cursor: col-resize;
z-index: 2;
&:hover:after {
&:hover::after {
background-color: var(--b3-theme-primary-light);
}
&:after {
&::after {
top: 0;
width: 2px;
left: 2px;

View file

@ -5,7 +5,7 @@
user-select: auto;
overflow-x: clip;
&--empty:empty:before {
&--empty:empty::before {
color: var(--b3-empty-color);
content: attr(placeholder);
}
@ -43,7 +43,7 @@
position: relative;
height: 26px;
&:after {
&::after {
position: absolute;
content: " ";
height: 1px;
@ -86,14 +86,14 @@
display: flex;
flex-direction: column;
&:before {
&::before {
content: "";
position: absolute;
border-left: .5px solid var(--b3-theme-background-light);
left: 17px;
}
&:hover:before {
&:hover::before {
border-left-color: var(--b3-scroll-color);
}
@ -111,11 +111,11 @@
}
&[fold="1"] {
&:before {
&::before {
content: none;
}
& > .protyle-action:after {
& > .protyle-action::after {
background-color: var(--b3-list-hover);
}
@ -147,7 +147,7 @@
padding-bottom: 0;
}
&:after {
&::after {
content: "";
position: absolute;
border-radius: 50%;
@ -163,7 +163,7 @@
position: relative;
}
&--order:after {
&--order::after {
border-radius: var(--b3-border-radius);
}
}
@ -177,11 +177,11 @@
display: flex;
flex-wrap: wrap;
justify-content: space-between;
column-gap: 1.5em;
& > div {
flex: 1;
flex: 1 0 10%;
box-sizing: border-box;
margin-right: 24px;
min-width: 1px;
&:nth-last-child(2),
@ -334,7 +334,7 @@
filter: brightness(.68);
}
&--drag > span:after {
&--drag > span::after {
content: "";
position: absolute;
top: 0;
@ -363,8 +363,8 @@
box-shadow: 0 0 1px 1px var(--b3-theme-on-background);
}
&:before,
&:after {
&::before,
&::after {
position: absolute;
width: 4px;
content: "";
@ -372,7 +372,7 @@
left: -4px;
}
&:after {
&::after {
left: 4px;
width: 8px
}
@ -409,7 +409,7 @@
}
&--drag {
.iframe-content:after {
.iframe-content::after {
content: "";
position: absolute;
top: 0;
@ -433,7 +433,7 @@
box-shadow: 0 0 1px 1px var(--b3-theme-on-surface);
box-sizing: border-box;
&:after {
&::after {
content: "";
background-color: var(--b3-theme-surface);
width: 32px;
@ -449,7 +449,7 @@
}
&:hover,
&:hover:after {
&:hover::after {
background-color: var(--b3-theme-background);
box-shadow: 0 0 1px 1px var(--b3-theme-on-background);
}
@ -459,17 +459,10 @@
&--select,
&--hl {
&:after {
background-color: var(--b3-theme-primary-lightest);
position: absolute;
width: 100%;
height: 100%;
content: " ";
left: 0;
top: 0;
@extend .dragover;
&::after {
border-radius: var(--b3-border-radius);
z-index: 3;
pointer-events: none;
}
}
@ -515,7 +508,7 @@
min-height: 26px !important;
}
div[fold="1"][data-type="NodeHeading"]:before {
div[fold="1"][data-type="NodeHeading"]::before {
content: "";
height: 16px !important;
width: 16px;
@ -600,7 +593,7 @@
cursor: pointer;
&:hover {
&:after {
&::after {
background-color: var(--b3-theme-background-light);
}

View file

@ -337,8 +337,8 @@ export class BlockPanel {
this.element.querySelector(".block__content").addEventListener("scroll", () => {
this.editors.forEach(item => {
hideElements(["gutter"], item.protyle)
})
})
hideElements(["gutter"], item.protyle);
});
});
}
}

View file

@ -54,6 +54,24 @@ export const keymap = {
<input data-key="plugin${Constants.ZWSP}${item.name}${Constants.ZWSP}${command.langKey}" data-value="${command.customHotkey}" data-default="${command.hotkey}" class="b3-text-field fn__none" value="${keyValue}" spellcheck="false">
</label>`;
});
item.updateProtyleToolbar([]).forEach(toolbarItem => {
if (typeof toolbarItem === "string" || Constants.INLINE_TYPE.concat("|").includes(toolbarItem.name) || !toolbarItem.hotkey) {
return
}
const dockKeymap = window.siyuan.config.keymap.plugin[item.name][toolbarItem.name];
const keyValue = updateHotkeyTip(dockKeymap.custom);
commandHTML += `<label class="b3-list-item b3-list-item--narrow b3-list-item--hide-action">
<span class="b3-list-item__text">${toolbarItem.tip||window.siyuan.languages[toolbarItem.lang]}</span>
<span data-type="reset" class="b3-list-item__action b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.reset}">
<svg><use xlink:href="#iconUndo"></use></svg>
</span>
<span data-type="clear" class="b3-list-item__action b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.remove}">
<svg><use xlink:href="#iconTrashcan"></use></svg>
</span>
<span data-type="update" class="config-keymap__key">${keyValue}</span>
<input data-key="plugin${Constants.ZWSP}${item.name}${Constants.ZWSP}${toolbarItem.name}" data-value="${dockKeymap.custom}" data-default="${dockKeymap.default}" class="b3-text-field fn__none" value="${keyValue}" spellcheck="false">
</label>`;
})
Object.keys(item.docks).forEach(key => {
const dockConfig = item.docks[key].config;
if (!dockConfig.hotkey) {

View file

@ -86,7 +86,7 @@ export const initConfigSearch = (element: HTMLElement, app: App) => {
getLang(["cloudStorage", "trafficStat", "sync", "backup", "cdn", "total", "sizeLimit", "cloudBackup",
"cloudBackupTip", "updatePath", "cloudSync", "upload", "download", "syncMode", "syncModeTip",
"generateConflictDoc", "generateConflictDocTip", "syncProvider", "syncProviderTip",
"syncMode1", "syncMode2", "reposTip", "openSyncTip1", "openSyncTip2", "cloudSyncDir", "config"]),
"syncMode1", "syncMode2", "reposTip", "openSyncTip1", "openSyncTip2", "cloudSyncDir", "cloudSyncDirTip", "config"]),
// 发布
getLang(["publishService", "publishServiceTip", "publishServicePort", "publishServicePortTip",
@ -100,7 +100,8 @@ export const initConfigSearch = (element: HTMLElement, app: App) => {
"systemLog", "importKey", "genKey", "genKeyByPW", "copyKey", "resetRepo", "systemLogTip", "export",
"downloadLatestVer", "safeQuit", "directConnection", "siyuanNote", "key", "password", "copied", "resetRepoTip",
"autoDownloadUpdatePkg", "autoDownloadUpdatePkgTip", "networkProxy", "keyPlaceholder", "initRepoKeyTip",
"googleAnalytics", "googleAnalyticsTip"]),
"googleAnalytics", "googleAnalyticsTip", "dataRepoPurge", "dataRepoPurgeTip", "dataRepoAutoPurgeIndexRetentionDays",
"dataRepoAutoPurgeRetentionIndexesDaily"]),
];
const inputElement = element.querySelector(".b3-form__icon input") as HTMLInputElement;
/// #if !BROWSER

View file

@ -44,7 +44,7 @@ export const showTooltip = (message: string, target: Element, tooltipClass?: str
left = parentRect.right + 8;
} else if (position?.endsWith("parentW")) {
// 数据库属性视图
top = parentRect.top + parseInt(position) || 8;
top = parentRect.top + (parseInt(position) || 8);
left = parentRect.left - messageElement.clientWidth;
}

View file

@ -737,7 +737,7 @@ export class Files extends Model {
}
private updateDocInfo(data: IWebSocketData) {
const liElement = this.element.querySelector(`li[data-node-id="${data.data.rootID}"]`)
const liElement = this.element.querySelector(`li[data-node-id="${data.data.rootID}"]`);
if (liElement) {
liElement.setAttribute("data-count", data.data.subFileCount);
liElement.querySelector(".ariaLabel")?.setAttribute("aria-label", this.genDocAriaLabel(data.data, escapeGreat));

View file

@ -172,9 +172,12 @@ export const openEditorTab = (app: App, ids: string[], notebookId?: string, path
};
export const copyPNGByLink = (link: string) => {
if (isInAndroid() || isInHarmony()) {
if (isInAndroid()) {
window.JSAndroid.writeImageClipboard(link);
return;
} else if (isInHarmony()) {
window.JSHarmony.writeImageClipboard(link);
return;
} else {
const canvas = document.createElement("canvas");
const tempElement = document.createElement("img");

View file

@ -34,7 +34,7 @@ class App {
public appId: string;
constructor() {
if (!window.webkit?.messageHandlers && !window.JSAndroid) {
if (!window.webkit?.messageHandlers && !window.JSAndroid && !window.JSHarmony) {
registerServiceWorker(`${Constants.SERVICE_WORKER_PATH}?v=${Constants.SIYUAN_VERSION}`);
}
addBaseURL();

View file

@ -15,6 +15,7 @@ import {hasClosestByAttribute} from "../protyle/util/hasClosest";
import {BlockPanel} from "../block/Panel";
import {Setting} from "./Setting";
import {clearOBG} from "../layout/dock/util";
import {Constants} from "../constants";
export class Plugin {
private app: App;
@ -75,6 +76,29 @@ export class Plugin {
value: options.name,
writable: false,
});
this.updateProtyleToolbar([]).forEach(toolbarItem => {
if (typeof toolbarItem === "string" || Constants.INLINE_TYPE.concat("|").includes(toolbarItem.name) || !toolbarItem.hotkey) {
return
}
if (!window.siyuan.config.keymap.plugin) {
window.siyuan.config.keymap.plugin = {};
}
if (!window.siyuan.config.keymap.plugin[options.name]) {
window.siyuan.config.keymap.plugin[options.name] = {
[toolbarItem.name]: {
default: toolbarItem.hotkey,
custom: toolbarItem.hotkey,
}
};
}
if (!window.siyuan.config.keymap.plugin[options.name][toolbarItem.name]) {
window.siyuan.config.keymap.plugin[options.name][toolbarItem.name] = {
default: toolbarItem.hotkey,
custom: toolbarItem.hotkey,
}
}
})
}
public onload() {

View file

@ -1653,8 +1653,10 @@ export class Gutter {
label: `${window.siyuan.languages.copy} ${window.siyuan.languages.headings1}`,
click() {
fetchPost("/api/block/getHeadingChildrenDOM", {id}, (response) => {
if (isInAndroid() || isInHarmony()) {
if (isInAndroid()) {
window.JSAndroid.writeHTMLClipboard(protyle.lute.BlockDOM2StdMd(response.data).trimEnd(), response.data + Constants.ZWSP);
} else if (isInHarmony()) {
window.JSHarmony.writeHTMLClipboard(protyle.lute.BlockDOM2StdMd(response.data).trimEnd(), response.data + Constants.ZWSP);
} else {
writeText(response.data + Constants.ZWSP);
}
@ -1667,8 +1669,10 @@ export class Gutter {
label: `${window.siyuan.languages.cut} ${window.siyuan.languages.headings1}`,
click() {
fetchPost("/api/block/getHeadingChildrenDOM", {id}, (response) => {
if (isInAndroid() || isInHarmony()) {
if (isInAndroid()) {
window.JSAndroid.writeHTMLClipboard(protyle.lute.BlockDOM2StdMd(response.data).trimEnd(), response.data + Constants.ZWSP);
} else if (isInHarmony()) {
window.JSHarmony.writeHTMLClipboard(protyle.lute.BlockDOM2StdMd(response.data).trimEnd(), response.data + Constants.ZWSP);
} else {
writeText(response.data + Constants.ZWSP);
}

View file

@ -8,6 +8,7 @@ import {updateCellsValue} from "./cell";
import {updateAttrViewCellAnimation} from "./action";
import {focusBlock} from "../../util/selection";
import {setPosition} from "../../../util/setPosition";
import * as dayjs from "dayjs";
const genSearchList = (element: Element, keyword: string, avId?: string, excludes = true, cb?: () => void) => {
fetchPost("/api/av/searchAttributeView", {
@ -213,6 +214,11 @@ const genSelectItemHTML = (type: "selected" | "empty" | "unselect", id?: string,
<svg class="b3-menu__action"><use xlink:href="#iconMin"></use></svg>`;
}
if (type === "empty") {
if (id) {
return `<button class="b3-menu__item" data-type="setRelationCell">
<span class="b3-menu__label">${window.siyuan.languages.newRowInRelation.replace('${x}', text).replace('${y}', id)}</span>
</button>`;
}
return `<button class="b3-menu__item">
<span class="b3-menu__label">${window.siyuan.languages.emptyContent}</span>
</button>`;
@ -234,8 +240,12 @@ const filterItem = (menuElement: Element, cellElement: HTMLElement, keyword: str
let html = "";
let selectHTML = "";
const hasIds: string[] = [];
let selectHasShowItem = false;
cellElement.querySelectorAll("span").forEach((item) => {
hasIds.push(item.dataset.id);
if (item.textContent.indexOf(keyword) > -1) {
selectHasShowItem = true;
}
selectHTML += `<button data-id="${item.dataset.id}" data-type="setRelationCell" class="b3-menu__item${item.textContent.indexOf(keyword) > -1 ? "" : " fn__none"}" draggable="true">${genSelectItemHTML("selected", item.dataset.id, !item.classList.contains("av__celltext--ref"), item.textContent || window.siyuan.languages.untitled)}</button>`;
});
cells.forEach((item) => {
@ -243,9 +253,9 @@ const filterItem = (menuElement: Element, cellElement: HTMLElement, keyword: str
html += genSelectItemHTML("unselect", item.block.id, item.isDetached, item.block.content || window.siyuan.languages.untitled);
}
});
menuElement.querySelector(".b3-menu__items").innerHTML = `${selectHTML || genSelectItemHTML("empty")}
menuElement.querySelector(".b3-menu__items").innerHTML = `${selectHTML}
<button class="b3-menu__separator"></button>
${html || genSelectItemHTML("empty")}`;
${html || genSelectItemHTML("empty", selectHasShowItem ? "" : keyword, undefined, menuElement.querySelector(".popover__block").outerHTML)}`;
menuElement.querySelector(".b3-menu__items .b3-menu__item:not(.fn__none)").classList.add("b3-menu__item--current");
});
};
@ -273,7 +283,7 @@ export const bindRelationEvent = (options: {
html += genSelectItemHTML("unselect", item.block.id, item.isDetached, item.block.content || window.siyuan.languages.untitled);
}
});
options.menuElement.querySelector(".b3-menu__items").innerHTML = `${selectHTML || genSelectItemHTML("empty")}
options.menuElement.querySelector(".b3-menu__items").innerHTML = `${selectHTML}
<button class="b3-menu__separator"></button>
${html || genSelectItemHTML("empty")}`;
const cellRect = options.cellElements[options.cellElements.length - 1].getBoundingClientRect();
@ -340,7 +350,7 @@ export const getRelationHTML = (data: IAV, cellElements?: HTMLElement[]) => {
};
export const setRelationCell = (protyle: IProtyle, nodeElement: HTMLElement, target: HTMLElement, cellElements: HTMLElement[]) => {
const menuElement = hasClosestByClassName(target, "b3-menu__items");
const menuElement = hasClosestByClassName(target, "b3-menu");
if (!menuElement) {
return;
}
@ -353,7 +363,7 @@ export const setRelationCell = (protyle: IProtyle, nodeElement: HTMLElement, tar
}
if (!nodeElement.contains(cellElements[0])) {
cellElements[0] = (nodeElement.querySelector(`.av__row[data-id="${rowElement.dataset.id}"] .av__cell[data-col-id="${cellElements[0].dataset.colId}"]`) ||
nodeElement.querySelector(`.fn__flex-1[data-col-id="${cellElements[0].dataset.colId}"]`) ) as HTMLElement;
nodeElement.querySelector(`.fn__flex-1[data-col-id="${cellElements[0].dataset.colId}"]`)) as HTMLElement;
}
const newValue: IAVCellRelationValue = {blockIDs: [], contents: []};
menuElement.querySelectorAll('[draggable="true"]').forEach(item => {
@ -380,13 +390,7 @@ export const setRelationCell = (protyle: IProtyle, nodeElement: HTMLElement, tar
newValue.contents.splice(removeIndex, 1);
separatorElement.after(target);
target.outerHTML = genSelectItemHTML("unselect", targetId, !target.querySelector(".popover__block"), target.querySelector(".b3-menu__label").textContent);
if (!separatorElement.previousElementSibling) {
separatorElement.insertAdjacentHTML("beforebegin", genSelectItemHTML("empty"));
}
} else {
if (!separatorElement.previousElementSibling.getAttribute("data-id")) {
separatorElement.previousElementSibling.remove();
}
} else if (targetId) {
newValue.blockIDs.push(targetId);
newValue.contents.push({
type: "block",
@ -401,6 +405,38 @@ export const setRelationCell = (protyle: IProtyle, nodeElement: HTMLElement, tar
if (!separatorElement.nextElementSibling) {
separatorElement.insertAdjacentHTML("afterend", genSelectItemHTML("empty"));
}
} else {
const blockID = target.querySelector(".popover__block").getAttribute("data-id");
const content = target.querySelector("b").textContent
const rowId = Lute.NewNodeID();
transaction(protyle, [{
action: "insertAttrViewBlock",
avID: menuElement.firstElementChild.getAttribute("data-av-id"),
srcs: [{
id: rowId,
isDetached: true,
content
}],
blockID,
}, {
action: "doUpdateUpdated",
id: blockID,
data: dayjs().format("YYYYMMDDHHmmss"),
}]);
newValue.blockIDs.push(rowId);
newValue.contents.push({
type: "block",
block: {
id: rowId,
content
},
isDetached: true
});
separatorElement.before(target);
target.outerHTML = `<button data-id="${rowId}" data-type="setRelationCell" class="b3-menu__item" draggable="true">${genSelectItemHTML("selected", rowId, true, content)}</button>`;
if (!separatorElement.nextElementSibling) {
separatorElement.insertAdjacentHTML("afterend", genSelectItemHTML("empty"));
}
}
menuElement.querySelector(".b3-menu__item--current")?.classList.remove("b3-menu__item--current");
menuElement.querySelector(".b3-menu__items .b3-menu__item:not(.fn__none)").classList.add("b3-menu__item--current");

View file

@ -18,7 +18,7 @@ export const flowchartRender = (element: Element, cdn = Constants.PROTYLE_CDN) =
if (flowchartElements.length === 0) {
return;
}
addScript(`${cdn}/js/flowchart.js/flowchart.min.js?v=0.0.0`, "protyleFlowchartScript").then(() => {
addScript(`${cdn}/js/flowchart.js/flowchart.min.js?v=1.18.0`, "protyleFlowchartScript").then(() => {
if (flowchartElements[0].firstElementChild.clientWidth === 0) {
const observer = new MutationObserver(() => {
initFlowchart(flowchartElements);

View file

@ -69,7 +69,14 @@ export class Toolbar {
/// #endif
this.toolbarHeight = 29;
protyle.app.plugins.forEach(item => {
options.toolbar = toolbarKeyToMenu(item.updateProtyleToolbar(options.toolbar));
const pluginToolbar = item.updateProtyleToolbar(options.toolbar)
pluginToolbar.forEach(toolbarItem => {
if (typeof toolbarItem === "string" || Constants.INLINE_TYPE.concat("|").includes(toolbarItem.name) || !toolbarItem.hotkey) {
return
}
toolbarItem.hotkey = window.siyuan.config.keymap.plugin[item.name][toolbarItem.name].custom;
})
options.toolbar = toolbarKeyToMenu(pluginToolbar);
});
options.toolbar.forEach((menuItem: IMenuItem) => {
const itemElement = this.genItem(protyle, menuItem);
@ -81,7 +88,14 @@ export class Toolbar {
this.element.innerHTML = "";
protyle.options.toolbar = toolbarKeyToMenu(Constants.PROTYLE_TOOLBAR);
protyle.app.plugins.forEach(item => {
protyle.options.toolbar = toolbarKeyToMenu(item.updateProtyleToolbar(protyle.options.toolbar));
const pluginToolbar = item.updateProtyleToolbar(protyle.options.toolbar)
pluginToolbar.forEach(toolbarItem => {
if (typeof toolbarItem === "string" || Constants.INLINE_TYPE.concat("|").includes(toolbarItem.name) || !toolbarItem.hotkey) {
return
}
toolbarItem.hotkey = window.siyuan.config.keymap.plugin[item.name][toolbarItem.name].custom;
})
protyle.options.toolbar = toolbarKeyToMenu(pluginToolbar);
});
protyle.options.toolbar.forEach((menuItem: IMenuItem) => {
const itemElement = this.genItem(protyle, menuItem);
@ -153,7 +167,7 @@ export class Toolbar {
this.toolbarHeight = this.element.clientHeight;
const y = rangePosition.top - this.toolbarHeight - 4;
this.element.setAttribute("data-inity", y + Constants.ZWSP + protyle.contentElement.scrollTop.toString());
setPosition(this.element, rangePosition.left - 52, Math.max(y, protyle.element.getBoundingClientRect().top));
setPosition(this.element, rangePosition.left - 52, Math.max(y, protyle.element.getBoundingClientRect().top + 30));
this.element.querySelectorAll(".protyle-toolbar__item--current").forEach(item => {
item.classList.remove("protyle-toolbar__item--current");
});
@ -291,7 +305,7 @@ export class Toolbar {
)) {
// 移除
if (type === "clear") {
toolbarElement.querySelectorAll('[data-type="em"],[data-type="u"],[data-type="s"],[data-type="mark"],[data-type="sup"],[data-type="sub"],[data-type="strong"]').forEach(item => {
toolbarElement.querySelectorAll('[data-type="strong"],[data-type="em"],[data-type="u"],[data-type="s"],[data-type="mark"],[data-type="sup"],[data-type="sub"],[data-type="kbd"],[data-type="mark"],[data-type="code"]').forEach(item => {
item.classList.remove("protyle-toolbar__item--current");
});
} else if (actionBtn) {

View file

@ -184,7 +184,7 @@ export const setPadding = (protyle: IProtyle) => {
if (window.siyuan.config.editor.displayBookmarkIcon) {
const editorAttrElement = document.getElementById("editorAttr");
if (editorAttrElement) {
editorAttrElement.innerHTML = `.protyle-wysiwyg--attr .b3-tooltips:after { max-width: ${protyle.wysiwyg.element.clientWidth - left - right}px; }`;
editorAttrElement.innerHTML = `.protyle-wysiwyg--attr .b3-tooltips::after { max-width: ${protyle.wysiwyg.element.clientWidth - left - right}px; }`;
}
}
const oldWidth = protyle.wysiwyg.element.getAttribute("data-realwidth");

View file

@ -21,16 +21,20 @@ export const openByMobile = (uri: string) => {
window.webkit.messageHandlers.openLink.postMessage("https://" + uri);
}
}
} else if (isInAndroid() || isInHarmony()) {
} else if (isInAndroid()) {
window.JSAndroid.openExternal(uri);
} else if (isInHarmony()) {
window.JSHarmony.openExternal(uri);
} else {
window.open(uri);
}
};
export const readText = () => {
if (isInAndroid() || isInHarmony()) {
if (isInAndroid()) {
return window.JSAndroid.readClipboard();
} else if (isInHarmony()) {
return window.JSHarmony.readClipboard();
}
return navigator.clipboard.readText();
};
@ -42,10 +46,14 @@ export const writeText = (text: string) => {
}
try {
// navigator.clipboard.writeText 抛出异常不进入 catch这里需要先处理移动端复制
if (isInAndroid() || isInHarmony()) {
if (isInAndroid()) {
window.JSAndroid.writeClipboard(text);
return;
}
if (isInHarmony()) {
window.JSHarmony.writeClipboard(text);
return;
}
if (isInIOS()) {
window.webkit.messageHandlers.setClipboard.postMessage(text);
return;
@ -54,8 +62,10 @@ export const writeText = (text: string) => {
} catch (e) {
if (isInIOS()) {
window.webkit.messageHandlers.setClipboard.postMessage(text);
} else if (isInAndroid() || isInHarmony()) {
} else if (isInAndroid()) {
window.JSAndroid.writeClipboard(text);
} else if (isInHarmony()) {
window.JSHarmony.writeClipboard(text);
} else {
const textElement = document.createElement("textarea");
textElement.value = text;
@ -137,8 +147,8 @@ export const isInIOS = () => {
};
export const isInHarmony = () => {
return window.siyuan.config.system.container === "harmony";
}
return window.siyuan.config.system.container === "harmony" && window.JSHarmony;
};
// MacWindows 快捷键展示
export const updateHotkeyTip = (hotkey: string) => {

View file

@ -452,9 +452,14 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
)) {
isHTML = false;
} else {
// 需注意 Edge 中的选不应识别为图片 https://github.com/siyuan-note/siyuan/issues/7021
// 需注意 Edge 中的选不应识别为图片 https://github.com/siyuan-note/siyuan/issues/7021
isHTML = true;
}
if (textPlain && "" !== textPlain.trim() && textHTML.startsWith("<span") && -1 < textHTML.indexOf("white-space: pre;")) {
// 豆包复制粘贴问题 https://github.com/siyuan-note/siyuan/issues/13265
isHTML = false;
}
}
if (isHTML) {
const tempElement = document.createElement("div");

View file

@ -4,7 +4,8 @@ import {
hasClosestByAttribute,
hasClosestByClassName,
hasClosestByMatchTag,
hasTopClosestByClassName, isInEmbedBlock,
hasTopClosestByClassName,
isInEmbedBlock,
} from "../util/hasClosest";
import {
focusBlock,
@ -12,7 +13,8 @@ import {
focusByWbr,
focusSideBlock,
getEditorRange,
getSelectionOffset, setFirstNodeRange,
getSelectionOffset,
setFirstNodeRange,
setLastNodeRange,
} from "../util/selection";
import {Constants} from "../../constants";
@ -23,7 +25,8 @@ import {
contentMenu,
enterBack,
fileAnnotationRefMenu,
imgMenu, inlineMathMenu,
imgMenu,
inlineMathMenu,
linkMenu,
refMenu,
setFold,
@ -62,7 +65,7 @@ import {openGlobalSearch} from "../../search/util";
import {popSearch} from "../../mobile/menu/search";
/// #endif
import {BlockPanel} from "../../block/Panel";
import {isInIOS, isOnlyMeta, readText} from "../util/compatibility";
import {isInIOS, isMac, isOnlyMeta, readText} from "../util/compatibility";
import {MenuItem} from "../../menus/Menu";
import {fetchPost} from "../../util/fetch";
import {onGet} from "../util/onGet";
@ -2005,14 +2008,6 @@ export class WYSIWYG {
// 输入法测试点 https://github.com/siyuan-note/siyuan/issues/3027
let isComposition = false; // for iPhone
this.element.addEventListener("compositionstart", (event) => {
// 搜狗输入法划选输入后无 data https://github.com/siyuan-note/siyuan/issues/4672
const range = getEditorRange(protyle.wysiwyg.element);
const nodeElement = hasClosestBlock(range.startContainer);
if (nodeElement && typeof protyle.wysiwyg.lastHTMLs[nodeElement.getAttribute("data-node-id")] === "undefined") {
range.insertNode(document.createElement("wbr"));
protyle.wysiwyg.lastHTMLs[nodeElement.getAttribute("data-node-id")] = nodeElement.outerHTML;
nodeElement.querySelector("wbr").remove();
}
isComposition = true;
event.stopPropagation();
});
@ -2085,22 +2080,26 @@ export class WYSIWYG {
this.element.addEventListener("keyup", (event) => {
const range = getEditorRange(this.element).cloneRange();
const nodeElement = hasClosestBlock(range.startContainer);
if (event.key !== "PageUp" && event.key !== "PageDown" && event.key !== "Home" && event.key !== "End" && event.key.indexOf("Arrow") === -1 &&
event.key !== "Alt" && event.key !== "Shift" && event.key !== "CapsLock" && event.key !== "Escape" && event.key !== "Meta" && !/^F\d{1,2}$/.test(event.key) &&
(!event.isComposing || (event.isComposing && range.toString() !== "")) // https://github.com/siyuan-note/siyuan/issues/4341
) {
if (event.key !== "PageUp" && event.key !== "PageDown" && event.key !== "Home" && event.key !== "End" &&
event.key.indexOf("Arrow") === -1 && event.key !== "Escape" && event.key !== "Shift" &&
event.key !== "Meta" && event.key !== "Alt" && event.key !== "Control" && event.key !== "CapsLock" &&
!event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey &&
!/^F\d{1,2}$/.test(event.key)) {
// 搜狗输入法不走 keydown需重新记录历史状态
if (range.toString() === "" && // windows 下回车新建块输入abc选中 bc ctrl+m 后光标错误
nodeElement && typeof protyle.wysiwyg.lastHTMLs[nodeElement.getAttribute("data-node-id")] === "undefined") {
if (!isMac() && nodeElement &&
(typeof protyle.wysiwyg.lastHTMLs[nodeElement.getAttribute("data-node-id")] === "undefined" || range.toString() !== "" || !this.preventKeyup)) {
range.insertNode(document.createElement("wbr"));
protyle.wysiwyg.lastHTMLs[nodeElement.getAttribute("data-node-id")] = nodeElement.outerHTML;
nodeElement.querySelector("wbr").remove();
}
this.preventKeyup = false;
return;
}
// 需放在 lastHTMLs 后,否则 https://github.com/siyuan-note/siyuan/issues/4388
if (this.preventKeyup) {
this.preventKeyup = false;
return;
}

View file

@ -298,6 +298,7 @@ const updateInput = (html: string, protyle: IProtyle, id: string) => {
data: protyle.wysiwyg.lastHTMLs[id],
action: "update"
});
protyle.wysiwyg.lastHTMLs[id] = item.outerHTML;
} else {
let firstElement;
if (index === 0) {

View file

@ -166,15 +166,17 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
// 有可能输入 shift+. ,因此需要使用 event.key 来进行判断
if (event.key !== "PageUp" && event.key !== "PageDown" && event.key !== "Home" && event.key !== "End" && event.key.indexOf("Arrow") === -1 &&
event.key !== "Escape" && event.key !== "Shift" && event.key !== "Meta" && event.key !== "Alt" && event.key !== "Control" && event.key !== "CapsLock" &&
!isNotEditBlock(nodeElement) &&
!/^F\d{1,2}$/.test(event.key) && typeof protyle.wysiwyg.lastHTMLs[nodeElement.getAttribute("data-node-id")] === "undefined") {
!isNotEditBlock(nodeElement) && !/^F\d{1,2}$/.test(event.key)) {
const cloneRange = range.cloneRange();
range.collapse(false);
range.insertNode(document.createElement("wbr"));
protyle.wysiwyg.lastHTMLs[nodeElement.getAttribute("data-node-id")] = nodeElement.outerHTML;
nodeElement.querySelector("wbr").remove();
// 光标位于引用结尾后 ctrl+b 偶尔会失效
range = cloneRange;
// 会导致 protyle.toolbar.range 和 range 不一致,先在有问题的地方重置一下 https://github.com/siyuan-note/siyuan/issues/10933
focusByRange(cloneRange);
protyle.toolbar.range = cloneRange;
protyle.wysiwyg.preventKeyup = true;
}
if (!window.siyuan.menus.menu.element.classList.contains("fn__none") &&

View file

@ -387,6 +387,8 @@ export const removeBlock = (protyle: IProtyle, blockElement: Element, range: Ran
// 需先移除 removeElement否则 side 会选中 removeElement
removeElement.remove();
focusBlock(previousLastElement, undefined, false);
// https://github.com/siyuan-note/siyuan/issues/13254
undoOperations.splice(0, 1);
} else {
const previousLastEditElement = getContenteditableElement(previousLastElement);
if (editableElement && (editableElement.textContent !== "" || editableElement.querySelector(".emoji"))) {

View file

@ -1121,7 +1121,6 @@ export const transaction = (protyle: IProtyle, doOperations: IOperation[], undoO
protyle.transactionTime - time < Constants.TIMEOUT_INPUT) {
needDebounce = true;
}
protyle.wysiwyg.lastHTMLs = {};
if (undoOperations) {
if (window.siyuan.config.fileTree.openFilesUseCurrentTab && protyle.model) {
protyle.model.headElement.classList.remove("item--unupdate");

View file

@ -178,6 +178,15 @@ interface Window {
readClipboard(): string
getBlockURL(): string
}
JSHarmony: {
openExternal(url: string): void
changeStatusBarColor(color: string, mode: number): void
writeClipboard(text: string): void
writeHTMLClipboard(text: string, html: string): void
writeImageClipboard(uri: string): void
readClipboard(): string
getBlockURL(): string
}
Protyle: import("../protyle/method").default

View file

@ -205,9 +205,9 @@ export const setInlineStyle = (set = true) => {
.b3-typography code:not(.hljs), .protyle-wysiwyg span[data-type~=code] { font-variant-ligatures: ${window.siyuan.config.editor.codeLigatures ? "normal" : "none"} }
.li > .protyle-action {height:${height + 8}px;line-height: ${height + 8}px}
.protyle-wysiwyg [data-node-id].li > .protyle-action ~ .h1, .protyle-wysiwyg [data-node-id].li > .protyle-action ~ .h2, .protyle-wysiwyg [data-node-id].li > .protyle-action ~ .h3, .protyle-wysiwyg [data-node-id].li > .protyle-action ~ .h4, .protyle-wysiwyg [data-node-id].li > .protyle-action ~ .h5, .protyle-wysiwyg [data-node-id].li > .protyle-action ~ .h6 {line-height:${height + 8}px;}
.protyle-wysiwyg [data-node-id].li > .protyle-action:after {height: ${window.siyuan.config.editor.fontSize}px;width: ${window.siyuan.config.editor.fontSize}px;margin:-${window.siyuan.config.editor.fontSize / 2}px 0 0 -${window.siyuan.config.editor.fontSize / 2}px}
.protyle-wysiwyg [data-node-id].li > .protyle-action::after {height: ${window.siyuan.config.editor.fontSize}px;width: ${window.siyuan.config.editor.fontSize}px;margin:-${window.siyuan.config.editor.fontSize / 2}px 0 0 -${window.siyuan.config.editor.fontSize / 2}px}
.protyle-wysiwyg [data-node-id].li > .protyle-action svg {height: ${Math.max(14, window.siyuan.config.editor.fontSize - 8)}px}
.protyle-wysiwyg [data-node-id].li:before {height: calc(100% - ${height + 8}px);top:${(height + 8)}px}
.protyle-wysiwyg [data-node-id].li::before {height: calc(100% - ${height + 8}px);top:${(height + 8)}px}
.protyle-wysiwyg [data-node-id] [spellcheck] {min-height:${height}px;}
.protyle-wysiwyg .p,
.protyle-wysiwyg .code-block .hljs,
@ -342,8 +342,10 @@ const updateMobileTheme = (OSTheme: string) => {
}
if (isInIOS()) {
window.webkit.messageHandlers.changeStatusBar.postMessage((backgroundColor || (mode === 0 ? "#fff" : "#1e1e1e")) + " " + mode);
} else if (isInAndroid() || isInHarmony()) {
} else if (isInAndroid()) {
window.JSAndroid.changeStatusBarColor(backgroundColor, mode);
} else if ( isInHarmony()) {
window.JSHarmony.changeStatusBarColor(backgroundColor, mode);
}
}, 500); // 移动端需要加载完才可以获取到颜色
}

View file

@ -1,5 +1,5 @@
import {hasClosestBlock, hasClosestByAttribute} from "../protyle/util/hasClosest";
import {getEditorRange} from "../protyle/util/selection";
import {focusByRange, getEditorRange} from "../protyle/util/selection";
export const bgFade = (element: Element) => {
element.classList.add("protyle-wysiwyg--hl");
@ -56,7 +56,8 @@ export const scrollCenter = (protyle: IProtyle, nodeElement?: Element, top = fal
(blockElement.querySelector(".av__row--header").getAttribute("style")?.indexOf("transform") > -1 || blockElement.querySelector(".av__row--footer").getAttribute("style")?.indexOf("transform") > -1)) {
return;
}
// 撤销时 br 插入删除会导致 rang 被修改 https://github.com/siyuan-note/siyuan/issues/12679
const cloneRange = range.cloneRange();
const br2Element = document.createElement("br");
range.insertNode(br2Element);
const editorElement = protyle.contentElement;
@ -71,6 +72,7 @@ export const scrollCenter = (protyle: IProtyle, nodeElement?: Element, top = fal
editorElement.scroll({top: scrollTop, behavior});
}
br2Element.remove();
focusByRange(cloneRange);
return;
}
}

View file

@ -416,7 +416,7 @@
const {ipcRenderer} = require('electron')
ipcRenderer.send('siyuan-quit', window.location.port)
} catch (e) {
if ((window.webkit && window.webkit.messageHandlers) || window.JSAndroid) {
if ((window.webkit && window.webkit.messageHandlers) || window.JSAndroid || window.JSHarmony) {
window.location.href = 'siyuan://api/system/exit'
} else {
window.location.reload()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -6,7 +6,7 @@ const INITIAL_CACHED_RESOURCES = [
"/stage/icon-large.png",
"/stage/icon.png",
"/stage/loading-pure.svg",
"/stage/build/fonts/JetBrainsMono-Regular.woff",
"/stage/build/fonts/JetBrainsMono-Regular.woff2",
"/stage/protyle/js/lute/lute.min.js",
"/stage/protyle/js/protyle-html.js"
];

View file

@ -76,10 +76,10 @@ module.exports = (env, argv) => {
],
},
{
test: /\.woff$/,
test: /\.woff2$/,
type: "asset/resource",
generator: {
filename: "../fonts/JetBrainsMono-Regular.woff",
filename: "../fonts/JetBrainsMono-Regular.woff2",
},
},
{

View file

@ -79,10 +79,10 @@ module.exports = (env, argv) => {
],
},
{
test: /\.woff$/,
test: /\.woff2$/,
type: "asset/resource",
generator: {
filename: "../fonts/JetBrainsMono-Regular.woff",
filename: "../fonts/JetBrainsMono-Regular.woff2",
},
},
{

View file

@ -72,10 +72,10 @@ module.exports = (env, argv) => {
],
},
{
test: /\.woff$/,
test: /\.woff2$/,
type: "asset/resource",
generator: {
filename: "../fonts/JetBrainsMono-Regular.woff",
filename: "../fonts/JetBrainsMono-Regular.woff2",
},
},
],

View file

@ -80,10 +80,10 @@ module.exports = (env, argv) => {
],
},
{
test: /\.woff$/,
test: /\.woff2$/,
type: "asset/resource",
generator: {
filename: "../fonts/JetBrainsMono-Regular.woff",
filename: "../fonts/JetBrainsMono-Regular.woff2",
},
},
{

View file

@ -10,7 +10,7 @@ require (
github.com/88250/epub v0.0.0-20230830085737-c19055cd1f48
github.com/88250/go-humanize v0.0.0-20240424102817-4f78fac47ea7
github.com/88250/gulu v1.2.3-0.20240612035750-c9cf5f7a4d02
github.com/88250/lute v1.7.7-0.20241123145043-7cfd2f597705
github.com/88250/lute v1.7.7-0.20241126013711-d6892e61b9f4
github.com/88250/pdfcpu v0.3.14-0.20230401044135-c7369a99720c
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1
github.com/ClarkThan/ahocorasick v0.0.0-20231011042242-30d1ef1347f4

View file

@ -14,8 +14,8 @@ github.com/88250/go-sqlite3 v1.14.13-0.20231214121541-e7f54c482950 h1:Pa5hMiBceT
github.com/88250/go-sqlite3 v1.14.13-0.20231214121541-e7f54c482950/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/88250/gulu v1.2.3-0.20240612035750-c9cf5f7a4d02 h1:3e5+yobj655pTeKOYMbJrnc1mE51ZkbXIxquTYZuYCY=
github.com/88250/gulu v1.2.3-0.20240612035750-c9cf5f7a4d02/go.mod h1:MUfzyfmbPrRDZLqxc7aPrVYveatTHRfoUa5TynPS0i8=
github.com/88250/lute v1.7.7-0.20241123145043-7cfd2f597705 h1:3MMyy7v8OaGG2UuaYZs7vtdBcOwZzS1ehnSL/sP5gZ8=
github.com/88250/lute v1.7.7-0.20241123145043-7cfd2f597705/go.mod h1:VDAzL8b+oCh+e3NAlmwwLzC53ten0rZlS8NboB7ljtk=
github.com/88250/lute v1.7.7-0.20241126013711-d6892e61b9f4 h1:H6+9W7fPUolYhg/2bGl6OKHya3qfYb1gpEkk196gJ3w=
github.com/88250/lute v1.7.7-0.20241126013711-d6892e61b9f4/go.mod h1:VDAzL8b+oCh+e3NAlmwwLzC53ten0rZlS8NboB7ljtk=
github.com/88250/pdfcpu v0.3.14-0.20230401044135-c7369a99720c h1:Dl/8S9iLyPMTElnWIBxmjaLiWrkI5P4a21ivwAn5pU0=
github.com/88250/pdfcpu v0.3.14-0.20230401044135-c7369a99720c/go.mod h1:S5YT38L/GCjVjmB4PB84PymA1qfopjEhfhTNQilLpv4=
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1 h1:48T899JQDwyyRu9yXHePYlPdHtpJfrJEUGBMH3SMBWY=

View file

@ -126,8 +126,8 @@ func SetTimezone(container, appDir, timezoneID string) {
}
//export DisableFeature
func DisableFeature(feature string) {
util.DisableFeature(feature)
func DisableFeature(feature *C.char) {
util.DisableFeature(C.GoString(feature))
}
func main() {}

View file

@ -249,7 +249,9 @@ func NetAssets2LocalAssets(rootID string, onlyImg bool, originalURL string) (err
func SearchAssetsByName(keyword string, exts []string) (ret []*cache.Asset) {
ret = []*cache.Asset{}
keywords := strings.Split(keyword, " ")
pathHitCount := map[string]int{}
count := 0
filterByExt := 0 < len(exts)
for _, asset := range cache.GetAssets() {
@ -269,16 +271,24 @@ func SearchAssetsByName(keyword string, exts []string) (ret []*cache.Asset) {
lowerHName := strings.ToLower(asset.HName)
lowerPath := strings.ToLower(asset.Path)
lowerKeyword := strings.ToLower(keyword)
hitName := strings.Contains(lowerHName, lowerKeyword)
hitPath := strings.Contains(lowerPath, lowerKeyword)
if !hitName && !hitPath {
continue
var hitNameCount, hitPathCount int
for _, k := range keywords {
lowerKeyword := strings.ToLower(k)
hitNameCount += strings.Count(lowerHName, lowerKeyword)
hitPathCount += strings.Count(lowerPath, lowerKeyword)
if 1 > hitNameCount && 1 > hitPathCount {
continue
}
}
if 1 > hitNameCount+hitPathCount {
continue
}
pathHitCount[asset.Path] += hitNameCount + hitPathCount
hName := asset.HName
if hitName {
_, hName = search.MarkText(asset.HName, keyword, 64, Conf.Search.CaseSensitive)
if 0 < hitNameCount {
_, hName = search.MarkText(asset.HName, strings.Join(keywords, search.TermSep), 64, Conf.Search.CaseSensitive)
}
ret = append(ret, &cache.Asset{
HName: hName,
@ -291,9 +301,15 @@ func SearchAssetsByName(keyword string, exts []string) (ret []*cache.Asset) {
}
}
sort.Slice(ret, func(i, j int) bool {
return ret[i].Updated > ret[j].Updated
})
if 0 < len(pathHitCount) {
sort.Slice(ret, func(i, j int) bool {
return pathHitCount[ret[i].Path] > pathHitCount[ret[j].Path]
})
} else {
sort.Slice(ret, func(i, j int) bool {
return ret[i].Updated > ret[j].Updated
})
}
return
}

View file

@ -614,11 +614,7 @@ func matchBacklinkKeyword(block *Block, keywords []string) bool {
for _, k := range keywords {
k = strings.ToLower(k)
content := block.Content
if block.IsContainerBlock() {
content = block.FContent
}
if strings.Contains(strings.ToLower(content), k) ||
if strings.Contains(strings.ToLower(block.Content), k) ||
strings.Contains(strings.ToLower(path.Base(block.HPath)), k) ||
strings.Contains(strings.ToLower(block.Name), k) ||
strings.Contains(strings.ToLower(block.Alias), k) ||

View file

@ -493,6 +493,7 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string, isEmbedBlock bo
}
name = strings.ReplaceAll(name, editor.Caret, "")
name = util.UnescapeHTML(name)
name = util.EscapeHTML(name)
if !isEmbedBlock && parent == node {

View file

@ -1944,6 +1944,8 @@ func exportMarkdownContent0(tree *parse.Tree, cloudAssetsBase string, assetsDest
})
}
currentDocDir := path.Dir(tree.HPath)
var unlinks []*ast.Node
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering {
@ -1979,11 +1981,17 @@ func exportMarkdownContent0(tree *parse.Tree, cloudAssetsBase string, assetsDest
var href string
bt := treenode.GetBlockTree(defID)
if nil != bt {
href += strings.TrimPrefix(bt.HPath, "/") + ".md"
href += bt.HPath + ".md"
if "d" != bt.Type {
href += "#" + defID
}
if tree.ID == bt.RootID {
href = "#" + defID
}
}
href = strings.TrimPrefix(href, currentDocDir)
href = util.FilterFilePath(href)
href = strings.TrimPrefix(href, "/")
blockRefLink := &ast.Node{Type: ast.NodeTextMark, TextMarkType: "a", TextMarkTextContent: linkText, TextMarkAHref: href}
blockRefLink.KramdownIAL = n.KramdownIAL
n.InsertBefore(blockRefLink)

View file

@ -695,6 +695,7 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
hPathsIDs := map[string]string{}
idPaths := map[string]string{}
moveIDs := map[string]string{}
if gulu.File.IsDir(localPath) { // 导入文件夹
// 收集所有资源文件
@ -793,6 +794,7 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
}
if "" != yfmRootID {
moveIDs[id] = yfmRootID
id = yfmRootID
}
if "" != yfmTitle {
@ -999,6 +1001,13 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
}
if 0 < len(importTrees) {
for id, newID := range moveIDs {
for _, importTree := range importTrees {
importTree.ID = strings.ReplaceAll(importTree.ID, id, newID)
importTree.Path = strings.ReplaceAll(importTree.Path, id, newID)
}
}
initSearchLinks()
convertWikiLinksAndTags()
buildBlockRefInText()
@ -1184,16 +1193,6 @@ func imgHtmlBlock2InlineImg(tree *parse.Tree) {
}
func reassignIDUpdated(tree *parse.Tree, rootID, updated string) {
var blockCount int
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering || "" == n.ID {
return ast.WalkContinue
}
blockCount++
return ast.WalkContinue
})
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering || "" == n.ID {
return ast.WalkContinue
@ -1207,8 +1206,10 @@ func reassignIDUpdated(tree *parse.Tree, rootID, updated string) {
n.SetIALAttr("id", n.ID)
if "" != updated {
n.SetIALAttr("updated", updated)
n.ID = updated + "-" + gulu.Rand.String(7)
n.SetIALAttr("id", n.ID)
if "" == rootID {
n.ID = updated + "-" + gulu.Rand.String(7)
n.SetIALAttr("id", n.ID)
}
} else {
n.SetIALAttr("updated", util.TimeFromID(n.ID))
}

View file

@ -18,13 +18,13 @@ package model
import (
"bytes"
"github.com/88250/lute/editor"
"regexp"
"strings"
"github.com/88250/gulu"
"github.com/88250/lute"
"github.com/88250/lute/ast"
"github.com/88250/lute/editor"
"github.com/88250/lute/html"
"github.com/88250/lute/parse"
"github.com/88250/lute/render"
@ -110,6 +110,7 @@ func renderBlockText(node *ast.Node, excludeTypes []string) (ret string) {
ret = sql.NodeStaticContent(node, excludeTypes, false, false, false)
ret = strings.TrimSpace(ret)
ret = strings.ReplaceAll(ret, "\n", "")
ret = util.UnescapeHTML(ret)
ret = util.EscapeHTML(ret)
ret = strings.TrimSpace(ret)
if "" == ret {

View file

@ -231,16 +231,16 @@ func FilterFilePath(p string) (ret string) {
}
func FilterFileName(name string) string {
name = strings.ReplaceAll(name, "\\", "")
name = strings.ReplaceAll(name, "/", "")
name = strings.ReplaceAll(name, ":", "")
name = strings.ReplaceAll(name, "*", "")
name = strings.ReplaceAll(name, "?", "")
name = strings.ReplaceAll(name, "\"", "")
name = strings.ReplaceAll(name, "'", "")
name = strings.ReplaceAll(name, "<", "")
name = strings.ReplaceAll(name, ">", "")
name = strings.ReplaceAll(name, "|", "")
name = strings.ReplaceAll(name, "\\", "_")
name = strings.ReplaceAll(name, "/", "_")
name = strings.ReplaceAll(name, ":", "_")
name = strings.ReplaceAll(name, "*", "_")
name = strings.ReplaceAll(name, "?", "_")
name = strings.ReplaceAll(name, "\"", "_")
name = strings.ReplaceAll(name, "'", "_")
name = strings.ReplaceAll(name, "<", "_")
name = strings.ReplaceAll(name, ">", "_")
name = strings.ReplaceAll(name, "|", "_")
name = strings.TrimSpace(name)
name = gulu.Str.RemoveInvisible(name) // Remove invisible characters from file names when uploading assets https://github.com/siyuan-note/siyuan/issues/11683
return name