Roselia-Blog 3.7 更新
3.7版本,对于浏览者来说,没有太多的亮点,因为几乎看不见什么显著的变化。 对于在上面写作的人来说,体验变好了。首先的变化是,图片上传功能的回归。说是回归的原因是,Roselia-Blog曾经neo版本就具有了上传图片的功能,后来在Roselia-Blog 2.0的升级中,取消了该功能 毕竟重写了。在这个版本中,终于想到去写一写这个功能了。
首先,最大的变化是弃用了SimpleMDE
,因为已经多年没有维护了,改为了API基本一致的EasyMDE
。该版本解决了在黑暗模式下,图标颜色无法变化的问题,因此,现在进入编辑页面,不会强制进入浅色模式了。
接下来是增加了图片上传的功能,主要分为三个channel,上传到本站,chevereto和sm.ms。在编辑文章的时候,可以选择相应的channel上传。这次更新取消了通常的上传选择和上传按钮,改为在编辑器中粘贴图片或者拖拽图片来上传,其中的图片将自动转为markdown格式。
在探究编辑器粘贴板的时候,我发现了粘贴板里面可以有多个不同类型的文件,首先必有的是type为text/plain
的,作为纯文本。我只需要拦截kind为file的,并且type以image开头的,将其读取之后,发送上传请求即可,最后在编辑器内改变或输入相应的文本即可。
有意思的点是,我发现了VSCode在粘贴文本的时候,会增加一些特殊的metadata,这应该是实现粘贴自动匹配语言的实现方法。
其样本如下:
{
"version": 1,
"isFromEmptySelection": false,
"multicursorText": null,
"mode": "typescript"
}
isFromEmptySelection
决定了该文本是不是啥都没选的情况下直接点复制而来的
multicursorText
为一个字符串的列表,表示了每一个不同的选择域选了哪些文本。
而mode
就是我们关心的,决定了语言。因此我们只要去读这个内容,看见了该信息,就自动粘贴为markdown的fenced code即可。
Roselia-Blog 3.8
在3.7发布不久后,3.8就发布了,并不是为了恶意刷版本号,而是因为3.8具有一个breaking change。主要的改动对用户不可见。即,token原本被作为参数传入,现在Roselia-Blog遵循规范,将其放在HTTP Header里面,作为Authentication header。
形如:Authentication: Bearer <token>
这样做的好处是:原本token作为参数,在get请求时有被记录的可能,造成泄漏。 现在,放在header里面,降低了这种可能性。
3.8.1
该版本的改动就是增加了动态预览的功能。在编辑界面时,将会看见类似r{{ icon('preview') }}这样的按钮。在点击后,会弹出新窗口,你可以将该窗口与编辑窗口并列,或者放到新的屏幕上。接下来,你在内容上的改动将实时体现在该窗口上。该功能的实现原理是实时监听localStorage
中草稿的变化。一旦监听到变化就重新渲染文章。编辑页面上只监听文章内容的变化,对于文章元信息的改变需要手动点保存草稿,或者等待编辑文章内容时的自动保存。
上述更新其实就是普通的细节更新,作为访客,自然无法发现区别。但是看似简单的东西有别样的内涵一直是Roselia-Blog的设计目标,现在,就是向这个目标迈向的一小步。
体验
如果你拥有Roselia-Blog的账户,而且你愿意尝试,点击按钮尝试新的编辑体验:r{{ (function (w) { var userData = w.JSON.parse(w.localStorage.getItem('loginData')) var upgrade = () => { if (!userData) { sendNotification({ message: 'Sorry, please login.', color: 'error' }) return; } userData.role = userData.role || 1 w.localStorage.setItem('loginData', (w.JSON.stringify(userData))) sendNotification({ message: 'Great! Redirecting you to editing page.', color: 'success' }) w.setTimeout(() => { w.location.href = '/blog/edit' }, 1000); }
var tryBtn = btn('Try', () => askForAccess('edit-experience', 'New Editing Experience', 'You are invited to try out the new editing experience.').then(upgrade)); var loginBtn = btn('Login', () => { w.sessionStorage.setItem('redirectURL', w.JSON.stringify(w.location.pathname.replace('/blog', ''))) w.location.href = '/blog/login' }, 'warning'); var successBtn = btn('Go Edit', () => { w.location.href = '/blog/edit' }, 'success') if (userData) return userData.role ? successBtn : tryBtn; return loginBtn;
})(''.constructor.constructor('return window')()) }}
r{{ changeExtraDisplaySettings({disableSideNavigation: true, blurMainImage: true}) }}