mirror of
https://github.com/purocean/yn.git
synced 2026-10-13 07:38:54 +08:00
Merge branch 'release/2.0.0-beta4.2'
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
# github: purocean
|
||||
custom: https://github.com/purocean/yn#%E6%8D%90%E8%B5%A0
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 157 KiB After Width: | Height: | Size: 210 KiB |
@@ -6,15 +6,16 @@
|
||||

|
||||
|
||||
## 特色
|
||||
+ 使用方便:使用 Monaco 编辑器(vscode 编辑器内核)编辑,添加了针对 Markdown 文件加入快捷键和补全规则
|
||||
+ 归档方便:图片文件保存在本地,无元数据文件或其他数据库,Markdown 文件可简单处理离线工作
|
||||
+ 拓展性强:可在文档中嵌入小工具、可运行的代码块、ECharts 图形、Plantuml 图形等
|
||||
+ 支持加密:用来保存账号等隐私文件,文件可单独设置密码
|
||||
+ **使用方便**:使用 Monaco 编辑器(vscode 编辑器内核)编辑,添加了针对 Markdown 文件加入快捷键和补全规则
|
||||
+ **兼容性强**:资源保存本地,Markdown 文件可简单处理离线工作;拓展功能尽量用 Markdown 原有的语法实现
|
||||
+ **高拓展性**:可在文档中嵌入小工具、可运行的代码块、ECharts 图形、Plantuml 图形、Drawio 图形等
|
||||
+ **支持加密**:用来保存账号等隐私文件,文件可单独设置密码
|
||||
|
||||
## 注意事项
|
||||
+ Yank Note 是一款**针对程序员**的 Markdown 编辑器,目标应用场景为在本机写文章,日志,笔记,小工具。
|
||||
+ Yank Note 为了更高的拓展性和方便性,牺牲了安全防护(命令执行,文件读写)。如果要用 Yank Note 打开外来 Markdown 文件,**请务必仔细甄别文件内容是值得信任的**。
|
||||
+ 为了更高的拓展性和方便性,Yank Note 牺牲了安全防护(命令执行,任意文件读写)。如果要用它打开外来 Markdown 文件,**请务必仔细甄别文件内容是值得信任的**。
|
||||
+ 如果要改造为对外的 Web 服务,本工具可能不太适合。或者请运行在可隔离控制的环境下。
|
||||
+ 加密文件的加密解密操作均在前端完成,请**务必保管好自己的密码**。一旦密码丢失,就只能暴力破解了。
|
||||
|
||||
## Yank-Note 2.0 开发计划
|
||||
[V2 项目看板](https://github.com/purocean/yn/projects/2)
|
||||
@@ -158,6 +159,11 @@ yarn run start
|
||||
## 更新日志
|
||||
[最新发布](https://github.com/purocean/yn/releases)
|
||||
|
||||
### [v2.0.0-beta4.2](https://github.com/purocean/yn/releases/tag/v2.0.0-beta4.2) 2019-08-09
|
||||
1. 修复文件方式引入 drawio 图形问题
|
||||
1. 支持直接在新窗口打开 drawio 图形
|
||||
1. 调整 drawio 图形样式
|
||||
|
||||
### [v2.0.0-beta4.1](https://github.com/purocean/yn/releases/tag/v2.0.0-beta4.1) 2019-08-09
|
||||
1. 修复 js 文件打包拷贝
|
||||
1. 修复在 Electron 中用新窗口打开 drawio 图形
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "yank.note.yang",
|
||||
"version": "2.0.0-beta4.1",
|
||||
"version": "2.0.0-beta4.2",
|
||||
"description": "Yank-Note",
|
||||
"main": "dist/app.js",
|
||||
"author": {
|
||||
|
||||
+3
-1
@@ -26,7 +26,9 @@ const createWindow = () => {
|
||||
webPreferences: {
|
||||
webSecurity: false,
|
||||
nodeIntegration: true
|
||||
}
|
||||
},
|
||||
minWidth: 700,
|
||||
minHeight: 500,
|
||||
})
|
||||
|
||||
win.maximize()
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
<div :style="{
|
||||
backgroundColor: `rgb(${220 - 220 * todoDoneCount / todoCount}, ${200 * todoDoneCount / todoCount}, 0)`,
|
||||
width: `${todoDoneCount * 100 / todoCount}%`
|
||||
}"> {{(todoDoneCount * 100 / todoCount).toFixed(2)}}% {{todoDoneCount}}/{{todoCount}} </div>
|
||||
}">
|
||||
<span style="padding-right: 3px;">{{(todoDoneCount * 100 / todoCount).toFixed(2)}}% {{todoDoneCount}}/{{todoCount}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else></div>
|
||||
<div class="convert">
|
||||
@@ -206,9 +208,10 @@ export default {
|
||||
|
||||
const nodes = this.$refs.view.querySelectorAll('.drawio[data-file]')
|
||||
for (const el of nodes) {
|
||||
const originPath = el.dataset.file
|
||||
let originPath = el.dataset.file
|
||||
if (originPath) {
|
||||
const filepath = originPath.startsWith('/') ? originPath : (file.dirname(this.filePath) + originPath.replace(/^.\//, ''))
|
||||
originPath = decodeURI(originPath)
|
||||
const filepath = originPath.startsWith('/') ? originPath : (file.dirname(this.filePath) + '/' + originPath.replace(/^.\//, ''))
|
||||
DrawioPlugin.load(el, this.fileRepo, filepath)
|
||||
} else {
|
||||
DrawioPlugin.load(el)
|
||||
@@ -388,6 +391,7 @@ export default {
|
||||
background: #303133;
|
||||
}
|
||||
|
||||
.markdown-body /deep/ div.drawio-wrapper,
|
||||
.markdown-body /deep/ input,
|
||||
.markdown-body /deep/ img
|
||||
{
|
||||
@@ -395,6 +399,7 @@ export default {
|
||||
filter: brightness(70%);
|
||||
}
|
||||
|
||||
.markdown-body /deep/ div.drawio-wrapper:hover,
|
||||
.markdown-body /deep/ img:hover
|
||||
{
|
||||
filter: none;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import File from '@/lib/file'
|
||||
import DrawioPlugin from '@/plugins/DrawioPlugin'
|
||||
|
||||
export default {
|
||||
name: 'tree-node',
|
||||
@@ -55,7 +56,11 @@ export default {
|
||||
if (item.name.endsWith('.md')) {
|
||||
this.$store.commit('app/setCurrentFile', item)
|
||||
} else {
|
||||
window.open(`api/attachment/${encodeURIComponent(item.name)}?repo=${item.repo}&path=${encodeURIComponent(item.path)}`)
|
||||
if (item.path.toLowerCase().endsWith('.drawio')) {
|
||||
DrawioPlugin.open(item)
|
||||
} else {
|
||||
window.open(`api/attachment/${encodeURIComponent(item.name)}?repo=${item.repo}&path=${encodeURIComponent(item.path)}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@ const Plugin = md => {
|
||||
iframe.dataset['content'] = content || ''
|
||||
|
||||
return `
|
||||
<div style="position: relative">
|
||||
<div class="drawio-wrapper" style="position: relative">
|
||||
${iframe.outerHTML}
|
||||
</div>
|
||||
`
|
||||
@@ -48,8 +48,7 @@ const Plugin = md => {
|
||||
}
|
||||
}
|
||||
|
||||
Plugin.load = async (el, repo, path) => {
|
||||
let content = el.dataset['content']
|
||||
const buildSrcdoc = async ({ repo, path, content }) => {
|
||||
if (!content) {
|
||||
content = (await file.read({ repo, path })).content
|
||||
}
|
||||
@@ -67,7 +66,7 @@ Plugin.load = async (el, repo, path) => {
|
||||
xml: content
|
||||
})
|
||||
|
||||
const srcdoc = `
|
||||
return `
|
||||
<style>
|
||||
::selection {
|
||||
background: #d3d3d3;
|
||||
@@ -102,53 +101,64 @@ Plugin.load = async (el, repo, path) => {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
${div.outerHTML}
|
||||
<script src="${location.origin}/viewer.min.js"></script>
|
||||
`
|
||||
}
|
||||
|
||||
const openInNewWindow = srcdoc => {
|
||||
const opener = window.open('about:blank')
|
||||
const frame = document.createElement('iframe')
|
||||
frame.width = '100%'
|
||||
frame.height = '100%'
|
||||
frame.frameBorder = '0'
|
||||
frame.srcdoc = srcdoc
|
||||
|
||||
const isElectron = !!(window && window.process && window.process.versions && window.process.versions['electron'])
|
||||
if (isElectron) {
|
||||
const json = JSON.stringify(frame.outerHTML)
|
||||
opener.eval(`
|
||||
document.body.style.height = '100vh'
|
||||
document.body.style.margin = '0'
|
||||
document.body.innerHTML = ${json}
|
||||
`)
|
||||
} else {
|
||||
opener.document.body.style.height = '100vh'
|
||||
opener.document.body.style.margin = '0'
|
||||
opener.document.body.appendChild(frame)
|
||||
}
|
||||
}
|
||||
|
||||
Plugin.load = async (el, repo, path) => {
|
||||
const content = el.dataset['content']
|
||||
|
||||
const srcdoc = await buildSrcdoc({ repo, path, content })
|
||||
|
||||
const resize = () => {
|
||||
el.contentDocument.body.style.height = 'auto'
|
||||
el.contentDocument.documentElement.style.height = 'auto'
|
||||
el.height = el.contentDocument.documentElement.scrollHeight + 'px'
|
||||
el.height = el.contentDocument.documentElement.offsetHeight + 'px'
|
||||
el.contentDocument.body.style.height = el.contentDocument.body.clientHeight + 'px'
|
||||
el.contentDocument.documentElement.style.height = '100%'
|
||||
appVm.$bus.emit('resize')
|
||||
window.appVm.$bus.emit('resize')
|
||||
}
|
||||
|
||||
const appVm = window.appVm
|
||||
el.onload = () => setTimeout(resize, 300)
|
||||
el.srcdoc = srcdoc
|
||||
|
||||
const button1 = document.createElement('button')
|
||||
button1.style.cssText = 'margin-left: 5px;font-size: 14px;background: #444444; border: 0; padding: 0 6px; color: #ccc; cursor: pointer; border-radius: 2px; transition: all .3s ease-in-out; line-height: 24px;'
|
||||
button1.style.cssText = 'margin-left: 5px;font-size: 14px;background: #cacaca; border: 0; padding: 0 6px; color: #2c2b2b; cursor: pointer; border-radius: 2px; transition: all .3s ease-in-out; line-height: 24px;'
|
||||
button1.innerText = '适应高度'
|
||||
button1.onclick = resize
|
||||
const button2 = document.createElement('button')
|
||||
button2.style.cssText = 'margin-left: 5px;font-size: 14px;background: #444444; border: 0; padding: 0 6px; color: #ccc; cursor: pointer; border-radius: 2px; transition: all .3s ease-in-out; line-height: 24px;'
|
||||
button2.style.cssText = 'margin-left: 5px;font-size: 14px;background: #cacaca; border: 0; padding: 0 6px; color: #2c2b2b; cursor: pointer; border-radius: 2px; transition: all .3s ease-in-out; line-height: 24px;'
|
||||
button2.innerText = '新窗口打开'
|
||||
button2.onclick = () => {
|
||||
const opener = window.open('about:blank')
|
||||
const frame = document.createElement('iframe')
|
||||
frame.width = '100%'
|
||||
frame.height = '100%'
|
||||
frame.frameBorder = '0'
|
||||
frame.srcdoc = srcdoc
|
||||
|
||||
const isElectron = !!(window && window.process && window.process.versions && window.process.versions['electron'])
|
||||
if (isElectron) {
|
||||
const json = JSON.stringify(frame.outerHTML)
|
||||
opener.eval(`
|
||||
document.body.style.height = '100vh'
|
||||
document.body.style.margin = '0'
|
||||
document.body.innerHTML = ${json}
|
||||
`)
|
||||
} else {
|
||||
opener.document.body.style.height = '100vh'
|
||||
opener.document.body.style.margin = '0'
|
||||
opener.document.body.appendChild(frame)
|
||||
}
|
||||
}
|
||||
button2.onclick = () => openInNewWindow(srcdoc)
|
||||
|
||||
const action = document.createElement('div')
|
||||
action.className = 'no-print'
|
||||
@@ -158,4 +168,9 @@ Plugin.load = async (el, repo, path) => {
|
||||
el.parentElement.appendChild(action)
|
||||
}
|
||||
|
||||
Plugin.open = async file => {
|
||||
const srcdoc = await buildSrcdoc(file)
|
||||
openInNewWindow(srcdoc)
|
||||
}
|
||||
|
||||
export default Plugin
|
||||
|
||||
Reference in New Issue
Block a user