Compare commits

..

19 commits

Author SHA1 Message Date
Daniel
f1c91863b9
🔖 Release v3.3.2
Some checks failed
Release Docker Image / build (push) Has been cancelled
Signed-off-by: Daniel <845765@qq.com>
2025-09-09 18:15:27 +08:00
Daniel
8a9e746891
🎨 Clean code
Signed-off-by: Daniel <845765@qq.com>
2025-09-09 18:11:49 +08:00
Jeffrey Chen
517f5c8453
🎨 Hide the separator line in the top bar plugin menu in publish service (#15809) 2025-09-09 18:08:21 +08:00
Vanessa
88431279bf 🎨 https://github.com/siyuan-note/siyuan/issues/15806 2025-09-09 17:32:35 +08:00
Vanessa
dc656d83a2 🎨 https://github.com/siyuan-note/siyuan/issues/15806 2025-09-09 16:43:39 +08:00
Vanessa
b69fd04137 🎨 https://github.com/siyuan-note/siyuan/issues/15806 2025-09-09 10:18:44 +08:00
Vanessa
ff909fa149 🎨 https://github.com/siyuan-note/siyuan/issues/15805 2025-09-09 10:02:51 +08:00
Vanessa
bfe50d9009 🚨 2025-09-09 09:29:00 +08:00
Daniel
93422c134d
🎨 Add field disabledInPublish to the code snippet to indicate whether it is disabled in the publish service https://github.com/siyuan-note/siyuan/issues/15806
Signed-off-by: Daniel <845765@qq.com>
2025-09-09 09:18:12 +08:00
Daniel
2f70ef43a1
🎨 Clean code
Signed-off-by: Daniel <845765@qq.com>
2025-09-09 09:07:23 +08:00
Daniel
5f6ddb4655
📝 Update changelogs
Signed-off-by: Daniel <845765@qq.com>
2025-09-08 19:41:02 +08:00
Daniel
39c4b3325e
🧑‍💻 Improve kernel API appendBlock, insertBlock and prependBlock https://github.com/siyuan-note/siyuan/issues/15798
Signed-off-by: Daniel <845765@qq.com>
2025-09-08 19:24:41 +08:00
Vanessa
393c53941a
🎨 https://github.com/siyuan-note/siyuan/issues/15801
Signed-off-by: Daniel <845765@qq.com>
2025-09-08 17:39:03 +08:00
Daniel
a4f03191fa
🎨 https://github.com/siyuan-note/siyuan/issues/15777 2025-09-08 10:58:58 +08:00
Vanessa
de9e648e9e 🎨 https://github.com/siyuan-note/siyuan/issues/15782 2025-09-08 10:52:40 +08:00
Vanessa
c1f14a33d9 🎨 https://github.com/siyuan-note/siyuan/pull/15731 2025-09-08 10:06:52 +08:00
Jeffrey Chen
adca241ed5
🎨 Improve slash menu (#15731)
fix https://github.com/siyuan-note/siyuan/issues/12518
2025-09-08 09:57:36 +08:00
Vanessa
006da6bc90 🎨 https://github.com/siyuan-note/siyuan/issues/15782 2025-09-08 09:48:36 +08:00
Vanessa
490234caab 🚨 2025-09-08 09:44:52 +08:00
26 changed files with 310 additions and 101 deletions

View file

@ -9,7 +9,7 @@
<Identity Name="89C2A984.SiYuan"
ProcessorArchitecture="x64"
Publisher="CN=087C656E-C1D9-42D8-8807-CED45A74FC0F"
Version="3.3.1.0"/>
Version="3.3.2.0"/>
<Properties>
<DisplayName>SiYuan</DisplayName>
<PublisherDisplayName>云南链滴科技有限公司</PublisherDisplayName>

View file

@ -21,7 +21,7 @@ Below are the detailed changes in this version.
* [Database cells support vertical dragging to fill values](https://github.com/siyuan-note/siyuan/issues/12907)
* [Improve document tree movement and its animation](https://github.com/siyuan-note/siyuan/issues/12914)
* [Improve S3/WebDAV data sync config](https://github.com/siyuan-note/siyuan/issues/12923)
* [The Publishing service no longer support export](https://github.com/siyuan-note/siyuan/issues/12928)
* [The Publish service no longer support export](https://github.com/siyuan-note/siyuan/issues/12928)
* [Display document title in data history preview area](https://github.com/siyuan-note/siyuan/issues/12948)
* [Improve parsing `<img>` when importing markdown](https://github.com/siyuan-note/siyuan/issues/12956)
* [Improve parsing of YAML Front Matter when importing Markdown](https://github.com/siyuan-note/siyuan/issues/12962)

View file

@ -0,0 +1,48 @@
## Overview
This version improves some details.
## Changelogs
Below are the detailed changes in this version.
### Enhancement
* [Copy/Cut folded heading changed to copy/cut `Headings and Bottom Blocks` and support multiple headings copy/cut](https://github.com/siyuan-note/siyuan/issues/8019)
* [Improve database field editing menu](https://github.com/siyuan-note/siyuan/issues/15185)
* [Database rollup field filtering rules support "Any", "All", and "None"](https://github.com/siyuan-note/siyuan/issues/15609)
* [Improve flashcards](https://github.com/siyuan-note/siyuan/issues/15699)
* [If the new data created in the database is in a collapsed group, the edit box will not pop up](https://github.com/siyuan-note/siyuan/issues/15728)
* [Select Copy in the code block to copy only the plain text](https://github.com/siyuan-note/siyuan/issues/15733)
* [Use the default sorting when the search content in the code block language prompt is empty](https://github.com/siyuan-note/siyuan/issues/15737)
* [Improve database rollup field filtering](https://github.com/siyuan-note/siyuan/issues/15740)
* [Improve database date field filtering](https://github.com/siyuan-note/siyuan/issues/15744)
* [Disable editing when adding options to the database](https://github.com/siyuan-note/siyuan/issues/15751)
* [After dragging database entries across groups, groups in other views need to be updated](https://github.com/siyuan-note/siyuan/issues/15755)
* [Browser clipping extension supports clipping page to the database](https://github.com/siyuan-note/siyuan/issues/15758)
* [Hide the bottom gesture navigation bar on Android](https://github.com/siyuan-note/siyuan/issues/15763)
* [Improve database group view performance](https://github.com/siyuan-note/siyuan/issues/15764)
* [Dragging multiple files into the editor will cause them to be opened by the default program](https://github.com/siyuan-note/siyuan/pull/15773)
* [Improve HTML table clipping](https://github.com/siyuan-note/siyuan/issues/15781)
* [Automatically create a new document when clicking on a notebook without documents](https://github.com/siyuan-note/siyuan/issues/15782)
* [Add field `disabledInPublish` to the code snippet to indicate whether it is disabled in the publish service](https://github.com/siyuan-note/siyuan/issues/15806)
### Bugfix
* [PDF files with too long file names cannot generate annotated images](https://github.com/siyuan-note/siyuan/issues/15739)
* [The video block network address is incorrect](https://github.com/siyuan-note/siyuan/issues/15741)
* [The database date field cannot paste the time of 0 o'clock](https://github.com/siyuan-note/siyuan/issues/15742)
* [Read-only mode cannot be set in preview mode](https://github.com/siyuan-note/siyuan/issues/15756)
* [Exception when inserting batch files into the editor](https://github.com/siyuan-note/siyuan/issues/15768)
* [When using certain input methods, punctuation characters are inserted twice after pasting a link at the end of a block](https://github.com/siyuan-note/siyuan/issues/15801)
### Development
* [Add field `disabledInPublish` to the marketplace plugin package metadata to indicate whether it is disabled in the publish service](https://github.com/siyuan-note/siyuan/issues/11730)
* [Add plugin function `expandDocTree`](https://github.com/siyuan-note/siyuan/issues/15639)
* [Improve kernel API `appendBlock`, `insertBlock` and `prependBlock`](https://github.com/siyuan-note/siyuan/issues/15798)
## Download
* [B3log](https://b3log.org/siyuan/en/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -0,0 +1,48 @@
## 概述
該版本改進了一些細節。
## 變更記錄
以下是此版本中的詳細變更。
### 改進功能
* [折疊標題的複製/剪切改為複製/剪切 `標題及其下方塊`,並支援多標題複製/剪切](https://github.com/siyuan-note/siyuan/issues/8019)
* [改進資料庫欄位編輯選單](https://github.com/siyuan-note/siyuan/issues/15185)
* [資料庫匯總欄位篩選規則支援「任一」、「所有」和「沒有」](https://github.com/siyuan-note/siyuan/issues/15609)
* [改良閃卡](https://github.com/siyuan-note/siyuan/issues/15699)
* [資料庫中新建資料如果在折疊分組內,不再彈出編輯框](https://github.com/siyuan-note/siyuan/issues/15728)
* [程式碼區塊選擇複製時僅複製純文字](https://github.com/siyuan-note/siyuan/issues/15733)
* [程式碼區塊語言提示搜尋內容為空時使用預設排序](https://github.com/siyuan-note/siyuan/issues/15737)
* [改進資料庫匯總欄位篩選](https://github.com/siyuan-note/siyuan/issues/15740)
* [改進資料庫日期欄位篩選](https://github.com/siyuan-note/siyuan/issues/15744)
* [資料庫新增選項時禁止編輯](https://github.com/siyuan-note/siyuan/issues/15751)
* [資料庫條目跨分組拖曳後,同步更新其他檢視中的分組](https://github.com/siyuan-note/siyuan/issues/15755)
* [瀏覽器剪藏擴充功能支援剪藏頁面到資料庫](https://github.com/siyuan-note/siyuan/issues/15758)
* [Android 隱藏底部手勢導覽列](https://github.com/siyuan-note/siyuan/issues/15763)
* [提升資料庫分組檢視效能](https://github.com/siyuan-note/siyuan/issues/15764)
* [拖入多個檔案到編輯器不再被預設程式開啟](https://github.com/siyuan-note/siyuan/pull/15773)
* [改進 HTML 表格剪藏](https://github.com/siyuan-note/siyuan/issues/15781)
* [點選無文件的筆記本時自動新建文件](https://github.com/siyuan-note/siyuan/issues/15782)
* [程式碼片段新增欄位 `disabledInPublish`,用於識別發佈服務中是否已停用](https://github.com/siyuan-note/siyuan/issues/15806)
### 修復缺陷
* [PDF 檔名過長無法產生標註圖片](https://github.com/siyuan-note/siyuan/issues/15739)
* [影片區塊網路網址不正確](https://github.com/siyuan-note/siyuan/issues/15741)
* [資料庫日期欄位無法貼上 0 點時間](https://github.com/siyuan-note/siyuan/issues/15742)
* [預覽模式下無法設定唯讀模式](https://github.com/siyuan-note/siyuan/issues/15756)
* [批次插入檔案到編輯器時異常](https://github.com/siyuan-note/siyuan/issues/15768)
* [部分輸入法在區塊末尾貼上連結後標點符號重複插入](https://github.com/siyuan-note/siyuan/issues/15801)
### 開發者
* [集市插件包元資料新增欄位 `disabledInPublish`,用於識別發布服務中是否已停用](https://github.com/siyuan-note/siyuan/issues/11730)
* [新增外掛程式 `expandDocTree`](https://github.com/siyuan-note/siyuan/issues/15639)
* [改進內核 API `appendBlock`、`insertBlock` 和 `prependBlock`](https://github.com/siyuan-note/siyuan/issues/15798)
## 下載
* [B3log](https://b3log.org/siyuan/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -0,0 +1,48 @@
## 概述
该版本改进了一些细节。
## 变更记录
以下是此版本中的详细变更。
### 改进功能
* [折叠标题的复制/剪切改为复制/剪切 `标题及其下方块`,并支持多标题复制/剪切](https://github.com/siyuan-note/siyuan/issues/8019)
* [改进数据库字段编辑菜单](https://github.com/siyuan-note/siyuan/issues/15185)
* [数据库汇总字段筛选规则支持“任一”、“所有”和“没有”](https://github.com/siyuan-note/siyuan/issues/15609)
* [改进闪卡](https://github.com/siyuan-note/siyuan/issues/15699)
* [数据库中新建数据如果在折叠分组内,不再弹出编辑框](https://github.com/siyuan-note/siyuan/issues/15728)
* [代码块选择复制时仅复制纯文本](https://github.com/siyuan-note/siyuan/issues/15733)
* [代码块语言提示搜索内容为空时使用默认排序](https://github.com/siyuan-note/siyuan/issues/15737)
* [改进数据库汇总字段筛选](https://github.com/siyuan-note/siyuan/issues/15740)
* [改进数据库日期字段筛选](https://github.com/siyuan-note/siyuan/issues/15744)
* [数据库添加选项时禁止编辑](https://github.com/siyuan-note/siyuan/issues/15751)
* [数据库条目跨分组拖动后,同步更新其他视图中的分组](https://github.com/siyuan-note/siyuan/issues/15755)
* [浏览器剪藏扩展支持剪藏页面到数据库](https://github.com/siyuan-note/siyuan/issues/15758)
* [Android 隐藏底部手势导航栏](https://github.com/siyuan-note/siyuan/issues/15763)
* [提升数据库分组视图性能](https://github.com/siyuan-note/siyuan/issues/15764)
* [拖入多个文件到编辑器不再被默认程序打开](https://github.com/siyuan-note/siyuan/pull/15773)
* [改进 HTML 表格剪藏](https://github.com/siyuan-note/siyuan/issues/15781)
* [点击无文档的笔记本时自动新建文档](https://github.com/siyuan-note/siyuan/issues/15782)
* [代码片段新增字段 `disabledInPublish`,用于标识发布服务中是否禁用](https://github.com/siyuan-note/siyuan/issues/15806)
### 修复缺陷
* [PDF 文件名过长无法生成标注图片](https://github.com/siyuan-note/siyuan/issues/15739)
* [视频块网络地址不正确](https://github.com/siyuan-note/siyuan/issues/15741)
* [数据库日期字段无法粘贴 0 点时间](https://github.com/siyuan-note/siyuan/issues/15742)
* [预览模式下无法设置只读模式](https://github.com/siyuan-note/siyuan/issues/15756)
* [批量插入文件到编辑器时异常](https://github.com/siyuan-note/siyuan/issues/15768)
* [部分输入法在块末尾粘贴链接后标点符号重复插入](https://github.com/siyuan-note/siyuan/issues/15801)
### 开发者
* [集市插件包元数据新增字段 `disabledInPublish`,用于标识发布服务中是否禁用](https://github.com/siyuan-note/siyuan/issues/11730)
* [新增插件函数 `expandDocTree`](https://github.com/siyuan-note/siyuan/issues/15639)
* [改进内核 API `appendBlock`、`insertBlock` 和 `prependBlock`](https://github.com/siyuan-note/siyuan/issues/15798)
## 下载
* [B3log](https://b3log.org/siyuan/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -102,7 +102,7 @@
},
{
"Type": "NodeText",
"Data": " to enter the publishing service settings panel."
"Data": " to enter the publish service settings panel."
}
]
}
@ -252,7 +252,7 @@
"Children": [
{
"Type": "NodeText",
"Data": "If access control is required for the publishing service:"
"Data": "If access control is required for the publish service:"
}
]
},
@ -333,7 +333,7 @@
"Children": [
{
"Type": "NodeText",
"Data": "When enabled, the publishing service will use the "
"Data": "When enabled, the publish service will use the "
},
{
"Type": "NodeTextMark",
@ -482,7 +482,7 @@
"Children": [
{
"Type": "NodeText",
"Data": "After enabling the publishing service, visitors can browse the content of the entire workspace."
"Data": "After enabling the publish service, visitors can browse the content of the entire workspace."
}
]
}

View file

@ -1,6 +1,6 @@
{
"name": "SiYuan",
"version": "3.3.1",
"version": "3.3.2",
"description": "Refactor your thinking",
"homepage": "https://b3log.org/siyuan",
"main": "./electron/main.js",

View file

@ -6,7 +6,6 @@ import {processSync} from "../dialog/processSystem";
import {getCloudURL} from "./util/about";
import {openByMobile} from "../protyle/util/compatibility";
import {confirmDialog} from "../dialog/confirmDialog";
import {isKernelInMobile} from "../util/functions";
const renderProvider = (provider: number) => {
if (provider === 0) {

View file

@ -62,33 +62,31 @@ export const openSnippets = () => {
<div class="fn__flex-1" style="overflow:auto;padding: 16px 24px">
<div>
<div class="fn__flex">
<div class="fn__flex-1"></div>
<div class="b3-form__icon">
<div class="b3-form__icon fn__flex-1">
<svg class="b3-form__icon-icon"><use xlink:href="#iconSearch"></use></svg>
<input data-type="css" data-action="search" type="text" placeholder="${window.siyuan.languages.search}" class="b3-text-field b3-form__icon-input">
<input data-type="css" data-action="search" type="text" placeholder="${window.siyuan.languages.search}" class="b3-text-field b3-form__icon-input fn__block">
</div>
<div class="fn__space"></div>
<span aria-label="${window.siyuan.languages.addAttr} CSS" id="addCodeSnippetCSS" class="b3-tooltips b3-tooltips__sw block__icon block__icon--show">
<svg><use xlink:href="#iconAdd"></use></svg>
</span>
<div class="fn__space"></div>
<input data-action="toggleCSS" class="b3-switch b3-switch--side fn__flex-center" type="checkbox"${window.siyuan.config.snippet.enabledCSS ? " checked" : ""}>
<input data-action="toggleCSS" class="b3-switch fn__flex-center" type="checkbox"${window.siyuan.config.snippet.enabledCSS ? " checked" : ""}>
</div>
${cssHTML}
</div>
<div class="fn__none">
<div class="fn__flex">
<div class="fn__flex-1"></div>
<div class="b3-form__icon">
<div class="b3-form__icon fn__flex-1">
<svg class="b3-form__icon-icon"><use xlink:href="#iconSearch"></use></svg>
<input data-type="js" data-action="search" type="text" placeholder="${window.siyuan.languages.search}" class="b3-text-field b3-form__icon-input">
<input data-type="js" data-action="search" type="text" placeholder="${window.siyuan.languages.search}" class="b3-text-field b3-form__icon-input fn__block">
</div>
<div class="fn__space"></div>
<span aria-label="${window.siyuan.languages.addAttr} JS" id="addCodeSnippetJS" class="b3-tooltips b3-tooltips__sw block__icon block__icon--show">
<svg><use xlink:href="#iconAdd"></use></svg>
</span>
<div class="fn__space"></div>
<input data-action="toggleJS" class="b3-switch b3-switch--side fn__flex-center" type="checkbox"${window.siyuan.config.snippet.enabledJS ? " checked" : ""}>
<input data-action="toggleJS" class="b3-switch fn__flex-center" type="checkbox"${window.siyuan.config.snippet.enabledJS ? " checked" : ""}>
</div>
${jsHTML}
</div>
@ -120,7 +118,8 @@ export const openSnippets = () => {
type: target.id === "addCodeSnippetCSS" ? "css" : "js",
name: "",
content: "",
enabled: false
enabled: false,
disabledInPublish: false,
}));
event.stopPropagation();
event.preventDefault();
@ -195,13 +194,19 @@ const genSnippet = (options: ISnippet) => {
<div class="fn__hr--b"></div>
<div class="fn__flex">
<input type="text" class="fn__size200 b3-text-field" placeholder="${window.siyuan.languages.title}">
<div class="fn__space"></div>
<label class="fn__flex${window.siyuan.config.publish.enable ? "" : " fn__none"}">
<input data-type="disabledInPublish" type="checkbox" class="b3-switch fn__flex-center" ${options.disabledInPublish ? "" : " checked"}>
<div class="fn__space"></div>
<span class="fn__flex-center">${window.siyuan.languages.publishService}</span>
</label>
<div class="fn__flex-1"></div>
<div class="fn__space"></div>
<span aria-label="${window.siyuan.languages.remove}" data-action="remove" class="b3-tooltips b3-tooltips__sw block__icon block__icon--show">
<svg><use xlink:href="#iconTrashcan"></use></svg>
</span>
<div class="fn__space"></div>
<input data-type="snippet" class="b3-switch b3-switch--side fn__flex-center" type="checkbox"${options.enabled ? " checked" : ""}>
<input data-type="snippet" class="b3-switch fn__flex-center" type="checkbox"${options.enabled ? " checked" : ""}>
</div>
<div class="fn__hr"></div>
<textarea class="fn__block b3-text-field" placeholder="${window.siyuan.languages.codeSnippet}" style="resize: vertical;font-family:var(--b3-font-family-code)" spellcheck="false"></textarea>
@ -229,11 +234,12 @@ const setSnippet = (dialog: Dialog, oldSnippets: ISnippet[], removeIds: string[]
const snippets: ISnippet[] = [];
dialog.element.querySelectorAll("[data-id]").forEach((item) => {
snippets.push({
disabledInPublish: !(item.querySelector('.b3-switch[data-type="disabledInPublish"]') as HTMLInputElement).checked,
id: item.getAttribute("data-id"),
name: item.querySelector("input").value,
type: item.getAttribute("data-type"),
content: item.querySelector("textarea").value,
enabled: (item.querySelector(".b3-switch") as HTMLInputElement).checked
enabled: (item.querySelector('.b3-switch[data-type="snippet"]') as HTMLInputElement).checked
});
});
if (objEquals(oldSnippets, snippets) &&

View file

@ -1153,7 +1153,13 @@ data-type="navigation-root" data-path="/">
path: liElement.getAttribute("data-path"),
}, response => {
if (response.data.path === "/" && response.data.files.length === 0) {
showMessage(window.siyuan.languages.emptyContent);
newFile({
app: this.app,
notebookId,
currentPath: "/",
useSavePath: false,
listDocTree: true,
});
return;
}
this.onLsHTML(response.data);

View file

@ -4,7 +4,6 @@ import {Model} from "../../layout/Model";
import {Constants} from "../../constants";
import {getDisplayName, pathPosix, setNoteBook} from "../../util/pathName";
import {initFileMenu, initNavigationMenu, sortMenu} from "../../menus/navigation";
import {showMessage} from "../../dialog/message";
import {fetchPost, fetchSyncPost} from "../../util/fetch";
import {genUUID} from "../../util/genID";
import {openMobileFileById} from "../editor";
@ -649,7 +648,13 @@ export class MobileFiles extends Model {
path: liElement.getAttribute("data-path"),
}, response => {
if (response.data.path === "/" && response.data.files.length === 0) {
showMessage(window.siyuan.languages.emptyContent);
newFile({
app: this.app,
notebookId,
currentPath: "/",
useSavePath: false,
listDocTree: true,
});
return;
}
this.onLsHTML(response.data);

View file

@ -18,7 +18,7 @@ export const openTopBarMenu = (app: App, target?: Element) => {
openSetting(app).element.querySelector('.b3-tab-bar [data-name="bazaar"]').dispatchEvent(new CustomEvent("click"));
}
});
menu.addSeparator({id: "separator_1"}, isHuawei() || window.siyuan.config.readonly);
menu.addSeparator({id: "separator_1", ignore: isHuawei() || window.siyuan.config.readonly});
/// #endif
let hasPlugin = false;
app.plugins.forEach((plugin) => {

View file

@ -6,7 +6,7 @@ import {
focusByWbr,
getEditorRange,
getSelectionOffset,
getSelectionPosition, setLastNodeRange
getSelectionPosition,
} from "../util/selection";
import {genHintItemHTML, hintEmbed, hintRef, hintSlash} from "./extend";
import {getSavePath, newFile} from "../../util/newFile";
@ -559,16 +559,12 @@ ${genHintItemHTML(item)}
}, response => {
// https://github.com/siyuan-note/siyuan/issues/10133
protyle.toolbar.range = range;
protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
const refElement = protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
type: "id",
color: `${response.data}${Constants.ZWSP}${refIsS ? "s" : "d"}${Constants.ZWSP}${(refIsS ? fileNames[0] : realFileName).substring(0, window.siyuan.config.editor.blockRefDynamicAnchorTextMaxLen)}`
});
if (protyle.toolbar.range.endContainer.nodeType === 1 &&
protyle.toolbar.range.endContainer.childNodes[protyle.toolbar.range.endOffset]) {
const refElement = hasPreviousSibling(protyle.toolbar.range.endContainer.childNodes[protyle.toolbar.range.endOffset]) as HTMLElement;
if (refElement && refElement.nodeType === 1 && refElement.getAttribute("data-type") === "block-ref") {
setLastNodeRange(refElement as HTMLElement, protyle.toolbar.range, false);
}
if (refElement[0]) {
protyle.toolbar.range.setEnd(refElement[0].lastChild, refElement[0].lastChild.textContent.length);
}
protyle.toolbar.range.collapse(false);
});
@ -600,16 +596,12 @@ ${genHintItemHTML(item)}
tempElement.innerText = dynamicTexts[1];
}
}
protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
const refElement = protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
type: "id",
color: `${tempElement.getAttribute("data-id")}${Constants.ZWSP}${tempElement.getAttribute("data-subtype")}${Constants.ZWSP}${tempElement.textContent}`
});
if (protyle.toolbar.range.endContainer.nodeType === 1 &&
protyle.toolbar.range.endContainer.childNodes[protyle.toolbar.range.endOffset]) {
const refElement = hasPreviousSibling(protyle.toolbar.range.endContainer.childNodes[protyle.toolbar.range.endOffset]) as HTMLElement;
if (refElement && refElement.nodeType === 1 && refElement.getAttribute("data-type") === "block-ref") {
setLastNodeRange(refElement as HTMLElement, protyle.toolbar.range, false);
}
if (refElement[0]) {
protyle.toolbar.range.setEnd(refElement[0].lastChild, refElement[0].lastChild.textContent.length);
}
protyle.toolbar.range.collapse(false);
return;

View file

@ -386,10 +386,13 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
}
if (types.includes("block-ref")) {
protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
const refElement = protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
type: "id",
color: `${linkElement.dataset.id}${Constants.ZWSP}s${Constants.ZWSP}${range.toString()}`
});
if (refElement[0]) {
protyle.toolbar.range.selectNodeContents(refElement[0]);
}
return;
}
if (types.includes("a")) {
@ -508,11 +511,15 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
}
if (linkElement) {
const selectText = range.toString();
protyle.toolbar.setInlineMark(protyle, "a", "range", {
const aElements = protyle.toolbar.setInlineMark(protyle, "a", "range", {
type: "a",
color: `${linkElement.getAttribute("href")}${Constants.ZWSP}${selectText || linkElement.textContent}`
});
if (!selectText) {
if (aElements[0].lastChild) {
// https://github.com/siyuan-note/siyuan/issues/15801
range.setEnd(aElements[0].lastChild, aElements[0].lastChild.textContent.length);
}
range.collapse(false);
}
return;
@ -542,11 +549,14 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
if (range.toString() !== "") {
const firstLine = textPlain.split("\n")[0];
if (isDynamicRef(textPlain)) {
protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
const refElement = protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
type: "id",
// range 不能 escape否则 https://github.com/siyuan-note/siyuan/issues/8359
color: `${textPlain.substring(2, 22 + 2)}${Constants.ZWSP}s${Constants.ZWSP}${range.toString()}`
});
if (refElement[0]) {
protyle.toolbar.range.selectNodeContents(refElement[0]);
}
return;
} else if (isFileAnnotation(firstLine)) {
protyle.toolbar.setInlineMark(protyle, "file-annotation-ref", "range", {

View file

@ -66,7 +66,7 @@ import {openGlobalSearch} from "../../search/util";
import {popSearch} from "../../mobile/menu/search";
/// #endif
import {BlockPanel} from "../../block/Panel";
import {copyPlainText, isInIOS, isMac, isOnlyMeta, readClipboard, encodeBase64, writeText} from "../util/compatibility";
import {copyPlainText, isInIOS, isMac, isOnlyMeta, readClipboard, encodeBase64} from "../util/compatibility";
import {MenuItem} from "../../menus/Menu";
import {fetchPost, fetchSyncPost} from "../../util/fetch";
import {onGet} from "../util/onGet";

View file

@ -12,7 +12,7 @@ import {
import {transaction, turnsIntoOneTransaction, turnsIntoTransaction, updateTransaction} from "./transaction";
import {cancelSB, genEmptyElement} from "../../block/util";
import {listOutdent, updateListOrder} from "./list";
import {setFold, zoomOut} from "../../menus/protyle";
import {zoomOut} from "../../menus/protyle";
import {preventScroll} from "../scroll/preventScroll";
import {hideElements} from "../ui/hideElements";
import {Constants} from "../../constants";

View file

@ -64,7 +64,7 @@ declare namespace Config {
*/
openHelp: boolean;
/**
* Publishing service
* Publish service
*
*/
publish: IPublish;
@ -1078,29 +1078,29 @@ declare namespace Config {
export type TLogLevel = "off" | "trace" | "debug" | "info" | "warn" | "error" | "fatal";
/**
* Publishing service
* Publish service
*/
export interface IPublish {
/**
* Whether to open the publishing service
* Whether to open the publish service
*/
enable: boolean;
/**
* The basic authentication settings of publishing service
* The basic authentication settings of publish service
*/
auth: IPublishAuth;
/**
* Port on which the publishing service listens
* Port on which the publish service listens
*/
port: number;
}
/**
* Publishing service authentication settings
* Publish service authentication settings
*/
export interface IPublishAuth {
/**
* Whether to enable basic authentication for publishing services
* Whether to enable basic authentication for publish services
*/
enable: boolean;
/**

View file

@ -369,6 +369,7 @@ interface ISnippet {
type: string;
enabled: boolean;
content: string;
disabledInPublish: boolean;
}
interface IInbox {

View file

@ -249,10 +249,13 @@ export const newFileBySelect = (protyle: IProtyle, selectText: string, nodeEleme
}, (idResponse) => {
const refText = newFileName.substring(0, window.siyuan.config.editor.blockRefDynamicAnchorTextMaxLen);
if (idResponse.data && idResponse.data.length > 0) {
protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
const refElement = protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
type: "id",
color: `${idResponse.data[0]}${Constants.ZWSP}d${Constants.ZWSP}${refText}`
});
if (refElement[0]) {
protyle.toolbar.range.selectNodeContents(refElement[0]);
}
} else {
fetchPost("/api/filetree/createDocWithMd", {
notebook: targetNotebookId,
@ -260,10 +263,13 @@ export const newFileBySelect = (protyle: IProtyle, selectText: string, nodeEleme
parentID: protyle.notebookId === targetNotebookId ? protyle.block.rootID : "",
markdown: ""
}, response => {
protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
const refElement = protyle.toolbar.setInlineMark(protyle, "block-ref", "range", {
type: "id",
color: `${response.data}${Constants.ZWSP}d${Constants.ZWSP}${refText}`
});
if (refElement[0]) {
protyle.toolbar.range.selectNodeContents(refElement[0]);
}
});
}
hideElements(["toolbar"], protyle);

View file

@ -1,5 +1,5 @@
const isNormalItem = (currentHintElement: HTMLElement, className: string) => {
return !currentHintElement.classList.contains(className) || currentHintElement.getBoundingClientRect().height === 0;
export const isAbnormalItem = (currentHintElement: HTMLElement, className: string) => {
return !currentHintElement || !currentHintElement.classList.contains(className) || currentHintElement.getBoundingClientRect().height === 0;
};
export const upDownHint = (listElement: Element, event: KeyboardEvent, classActiveName = "b3-list-item--focus", defaultElement?: Element) => {
@ -19,13 +19,13 @@ export const upDownHint = (listElement: Element, event: KeyboardEvent, classActi
currentHintElement.classList.remove(classActiveName);
currentHintElement = currentHintElement.nextElementSibling as HTMLElement;
while (currentHintElement && isNormalItem(currentHintElement, className)) {
while (isAbnormalItem(currentHintElement, className)) {
currentHintElement = currentHintElement.nextElementSibling as HTMLElement;
}
if (!currentHintElement) {
currentHintElement = listElement.children[0] as HTMLElement;
while (currentHintElement && isNormalItem(currentHintElement, className)) {
while (isAbnormalItem(currentHintElement, className)) {
currentHintElement = currentHintElement.nextElementSibling as HTMLElement;
}
}
@ -44,7 +44,7 @@ export const upDownHint = (listElement: Element, event: KeyboardEvent, classActi
currentHintElement.classList.remove(classActiveName);
currentHintElement = currentHintElement.previousElementSibling as HTMLElement;
while (currentHintElement && isNormalItem(currentHintElement, className)) {
while (isAbnormalItem(currentHintElement, className)) {
currentHintElement = currentHintElement.previousElementSibling as HTMLElement;
}
@ -70,7 +70,7 @@ export const upDownHint = (listElement: Element, event: KeyboardEvent, classActi
event.stopPropagation();
currentHintElement.classList.remove(classActiveName);
currentHintElement = listElement.children[0] as HTMLElement;
while (currentHintElement && isNormalItem(currentHintElement, className)) {
while (isAbnormalItem(currentHintElement, className)) {
currentHintElement = currentHintElement.nextElementSibling as HTMLElement;
}
if (!currentHintElement) {
@ -84,7 +84,7 @@ export const upDownHint = (listElement: Element, event: KeyboardEvent, classActi
event.stopPropagation();
currentHintElement.classList.remove(classActiveName);
currentHintElement = listElement.children[listElement.children.length - 1] as HTMLElement;
while (currentHintElement && isNormalItem(currentHintElement, className)) {
while (isAbnormalItem(currentHintElement, className)) {
currentHintElement = currentHintElement.previousElementSibling as HTMLElement;
}
if (!currentHintElement) {

View file

@ -55,11 +55,20 @@ func getSnippet(c *gin.Context) {
return
}
isPublish := model.IsReadOnlyRole(model.GetGinContextRole(c))
var snippets []*conf.Snippet
for _, s := range confSnippets {
if ("all" == typ || s.Type == typ) && (2 == enabledArg || s.Enabled == enabled) {
snippets = append(snippets, s)
if isPublish && s.DisabledInPublish {
continue
}
if "all" != typ && s.Type != typ {
continue
}
if 2 != enabledArg && s.Enabled != enabled {
continue
}
snippets = append(snippets, s)
}
if "" != keyword {
@ -101,6 +110,9 @@ func setSnippet(c *gin.Context) {
Content: m["content"].(string),
Enabled: m["enabled"].(bool),
}
if nil != m["disabledInPublish"] {
snippet.DisabledInPublish = m["disabledInPublish"].(bool)
}
if "" == snippet.ID {
snippet.ID = ast.NewNodeID()
}

View file

@ -29,9 +29,10 @@ func NewSnpt() *Snpt {
}
type Snippet struct {
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"` // js/css
Enabled bool `json:"enabled"`
Content string `json:"content"`
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"` // js/css
Enabled bool `json:"enabled"`
DisabledInPublish bool `json:"disabledInPublish"`
Content string `json:"content"`
}

View file

@ -187,7 +187,7 @@ func SearchDocsByKeyword(keyword string, flashcard bool) (ret []map[string]strin
}
}
rootBlocks = sql.QueryRootBlockByCondition(condition)
rootBlocks = sql.QueryRootBlockByCondition(condition, Conf.Search.Limit)
} else {
for _, box := range boxes {
if flashcard {

View file

@ -587,20 +587,20 @@ func (tx *Transaction) doPrependInsert(operation *Operation) (ret *TxErr) {
if nil == insertedNode {
return &TxErr{code: TxErrCodeBlockNotFound, msg: "invalid data tree", id: block.ID}
}
var remains []*ast.Node
for remain := insertedNode.Next; nil != remain; remain = remain.Next {
if ast.NodeKramdownBlockIAL != remain.Type {
if "" == remain.ID {
remain.ID = ast.NewNodeID()
remain.SetIALAttr("id", remain.ID)
}
remains = append(remains, remain)
}
}
if "" == insertedNode.ID {
insertedNode.ID = ast.NewNodeID()
insertedNode.SetIALAttr("id", insertedNode.ID)
}
var toInserts []*ast.Node
for toInsert := insertedNode; nil != toInsert; toInsert = toInsert.Next {
if ast.NodeKramdownBlockIAL != toInsert.Type {
if "" == toInsert.ID {
toInsert.ID = ast.NewNodeID()
toInsert.SetIALAttr("id", toInsert.ID)
}
toInserts = append(toInserts, toInsert)
}
}
node := treenode.GetNodeInTree(tree, operation.ParentID)
if nil == node {
@ -608,31 +608,45 @@ func (tx *Transaction) doPrependInsert(operation *Operation) (ret *TxErr) {
return &TxErr{code: TxErrCodeBlockNotFound, id: operation.ParentID}
}
isContainer := node.IsContainerBlock()
for i := len(remains) - 1; 0 <= i; i-- {
remain := remains[i]
slices.Reverse(toInserts)
for _, toInsert := range toInserts {
if isContainer {
if ast.NodeListItem == node.Type && 3 == node.ListData.Typ {
node.FirstChild.InsertAfter(remain)
if ast.NodeList == node.Type {
// 列表下只能挂列表项,所以这里需要分情况处理
if ast.NodeList == toInsert.Type {
var childLis []*ast.Node
for childLi := toInsert.FirstChild; nil != childLi; childLi = childLi.Next {
childLis = append(childLis, childLi)
}
for i := len(childLis) - 1; -1 < i; i-- {
node.PrependChild(childLis[i])
}
} else {
newLiID := ast.NewNodeID()
newLi := &ast.Node{ID: newLiID, Type: ast.NodeListItem, ListData: &ast.ListData{Typ: node.ListData.Typ}}
newLi.SetIALAttr("id", newLiID)
node.PrependChild(newLi)
newLi.AppendChild(toInsert)
}
} else if ast.NodeSuperBlock == node.Type {
node.FirstChild.Next.InsertAfter(remain)
layout := node.ChildByType(ast.NodeSuperBlockLayoutMarker)
if nil != layout {
layout.InsertAfter(toInsert)
} else {
node.FirstChild.InsertAfter(toInsert)
}
} else {
node.PrependChild(remain)
node.PrependChild(toInsert)
}
} else {
node.InsertAfter(remain)
node.InsertAfter(toInsert)
}
createdUpdated(toInsert)
tx.nodes[toInsert.ID] = toInsert
}
if isContainer {
if ast.NodeListItem == node.Type && 3 == node.ListData.Typ {
node.FirstChild.InsertAfter(insertedNode)
} else if ast.NodeSuperBlock == node.Type {
node.FirstChild.Next.InsertAfter(insertedNode)
} else {
node.PrependChild(insertedNode)
}
} else {
node.InsertAfter(insertedNode)
}
createdUpdated(insertedNode)
tx.nodes[insertedNode.ID] = insertedNode
if err = tx.writeTree(tree); err != nil {
@ -695,9 +709,14 @@ func (tx *Transaction) doAppendInsert(operation *Operation) (ret *TxErr) {
if !isContainer {
slices.Reverse(toInserts)
}
var lastChildBelowHeading *ast.Node
if ast.NodeHeading == node.Type {
if children := treenode.HeadingChildren(node); 0 < len(children) {
lastChildBelowHeading = children[len(children)-1]
}
}
for i := 0; i < len(toInserts); i++ {
toInsert := toInserts[i]
for _, toInsert := range toInserts {
if isContainer {
if ast.NodeList == node.Type {
// 列表下只能挂列表项,所以这里需要分情况处理 https://github.com/siyuan-note/siyuan/issues/9955
@ -722,7 +741,15 @@ func (tx *Transaction) doAppendInsert(operation *Operation) (ret *TxErr) {
node.AppendChild(toInsert)
}
} else {
node.InsertAfter(toInsert)
if ast.NodeHeading == node.Type {
if nil != lastChildBelowHeading {
lastChildBelowHeading.InsertAfter(toInsert)
} else {
node.InsertAfter(toInsert)
}
} else {
node.InsertAfter(toInsert)
}
}
createdUpdated(toInsert)

View file

@ -69,8 +69,8 @@ func queryBlockHashes(rootID string) (ret map[string]string) {
return
}
func QueryRootBlockByCondition(condition string) (ret []*Block) {
sqlStmt := "SELECT *, length(hpath) - length(replace(hpath, '/', '')) AS lv FROM blocks WHERE type = 'd' AND " + condition + " ORDER BY box DESC,lv ASC LIMIT 128"
func QueryRootBlockByCondition(condition string, limit int) (ret []*Block) {
sqlStmt := "SELECT *, length(hpath) - length(replace(hpath, '/', '')) AS lv FROM blocks WHERE type = 'd' AND " + condition + " ORDER BY box DESC,lv ASC LIMIT " + strconv.Itoa(limit)
rows, err := query(sqlStmt)
if err != nil {
logging.LogErrorf("sql query [%s] failed: %s", sqlStmt, err)

View file

@ -45,7 +45,7 @@ import (
var Mode = "prod"
const (
Ver = "3.3.1"
Ver = "3.3.2"
IsInsider = false
// env vars as fallback for commandline parameters