Skip to content

Commit 079ce78

Browse files
authored
超融合 request #32 from nekomoyi/feat/migrate-to-pywebview
强兼苹果!
2 parents b70d372 + 5a86c57 commit 079ce78

19 files changed

Lines changed: 511 additions & 94 deletions

‎librian/librian_util/文件.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import logging
3+
from pathlib import Path
34

45

56
def 補充擴展名(文件名, 擴展名表, 路徑='./'):
@@ -14,5 +15,4 @@ def 補充擴展名(文件名, 擴展名表, 路徑='./'):
1415
return 文件名
1516

1617
def 轉爲網址路徑(路徑):
17-
絕對路徑 = os.path.abspath(路徑)
18-
return f'file:///{絕對路徑}'
18+
return Path(路徑).resolve().as_uri()

‎librian/librian本體/librian.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ def ember(project, 編寫模式=False, 跳過標題畫面=False, 監聽模式=Fa
2323
from . import 監聽服務
2424
監聽服務.啓動服務(端口)
2525
app = 窗口.啓動app()
26-
app.MainLoop()
26+
app.運行()
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import platform
2+
from pathlib import Path
3+
from urllib.parse import parse_qsl, urlencode, urlsplit, urlunsplit
4+
5+
from .前端API import 山彥API
6+
7+
8+
橋腳本 = Path(__file__).parent / '前端/pywebview橋.js'
9+
10+
11+
class WebView窗口:
12+
def __init__(self, webview, url, icon, title, size, storage_path):
13+
self._webview = webview
14+
self._url = _本地網址(url)
15+
self._icon = str(icon) if icon else None
16+
self._title = title
17+
self._size = tuple(size)
18+
self._storage_path = str(storage_path) if storage_path else None
19+
self._api = None
20+
self._window = None
21+
22+
def 綁定(self, 山彥):
23+
self._api = 山彥API(山彥)
24+
25+
def 執行js(self, script):
26+
return self._window.evaluate_js(script)
27+
28+
def 切換全屏(self):
29+
return self._window.toggle_fullscreen()
30+
31+
def 運行(self):
32+
if self._api is None:
33+
raise RuntimeError('啓動窗口前必須綁定山彥')
34+
35+
width, height = self._窗口尺寸()
36+
self._window = self._webview.create_window(
37+
title=self._title,
38+
url=self._url,
39+
js_api=self._api,
40+
width=width,
41+
height=height,
42+
)
43+
self._window.events.loaded += self._注入橋
44+
self._webview.start(
45+
private_mode=False,
46+
storage_path=self._storage_path,
47+
icon=self._icon,
48+
)
49+
50+
def _窗口尺寸(self):
51+
if platform.system() != 'Darwin':
52+
return self._size
53+
54+
import AppKit
55+
56+
內容寬, 內容高 = self._size
57+
樣式 = (
58+
AppKit.NSWindowStyleMaskTitled
59+
| AppKit.NSWindowStyleMaskClosable
60+
| AppKit.NSWindowStyleMaskMiniaturizable
61+
| AppKit.NSWindowStyleMaskResizable
62+
)
63+
內容矩形 = AppKit.NSMakeRect(0, 0, 內容寬, 內容高)
64+
外框矩形 = AppKit.NSWindow.frameRectForContentRect_styleMask_(內容矩形, 樣式)
65+
return round(外框矩形.size.width), round(外框矩形.size.height)
66+
67+
def _注入橋(self):
68+
當前網址 = urlsplit(self._window.get_current_url())
69+
if dict(parse_qsl(當前網址.query)).get('_librian_exit') == '1':
70+
self._window.destroy()
71+
else:
72+
self._window.run_js(橋腳本.read_text(encoding='utf8'))
73+
74+
75+
def _本地網址(url):
76+
區段 = urlsplit(str(url))
77+
查詢 = parse_qsl(區段.query, keep_blank_values=True)
78+
查詢.append(('_librian_webview', '1'))
79+
return urlunsplit(區段._replace(query=urlencode(查詢)))
80+
81+
82+
def 創建窗口(url, icon, title, size, storage_path):
83+
import webview
84+
85+
return WebView窗口(webview, url, icon, title, size, storage_path)

‎librian/librian本體/前端/adv.html‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<meta charset='utf-8'/>
55
<link rel="stylesheet" href='./黑科技/font-awesome-4.7.0/css/font-awesome.css'/>
66
<script src='./虛擬核心.js'></script>
7+
<script src='./pywebview橋.js'></script>
78
<script src='./dist/bundle.js'></script>
89
</head>
910
<style id="style"></style>

‎librian/librian本體/前端/adv.ptml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ html:
44
meta charset='utf-8';
55
link rel="stylesheet" href='./黑科技/font-awesome-4.7.0/css/font-awesome.css';
66
script src='./虛擬核心.js':
7+
script src='./pywebview橋.js':
78
script src='./dist/bundle.js':
89

910
style#style:
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
(function () {
2+
'use strict';
3+
4+
if (new URLSearchParams(window.location.search).get('_librian_webview') !== '1') {
5+
return;
6+
}
7+
if (window.山彥 && window.山彥.傳輸 === 'promise') {
8+
return;
9+
}
10+
11+
var api就緒 = new Promise(function (resolve) {
12+
if (window.pywebview && window.pywebview.api) {
13+
resolve(window.pywebview.api);
14+
return;
15+
}
16+
window.addEventListener('pywebviewready', function () {
17+
resolve(window.pywebview.api);
18+
}, { once: true });
19+
});
20+
var 調用隊列 = Promise.resolve();
21+
function 導航(網址) {
22+
var 目標 = new URL(網址, window.location.href);
23+
目標.searchParams.set('_librian_webview', '1');
24+
window.location.href = 目標.href;
25+
}
26+
function 退出() {
27+
var 目標 = new URL(window.location.href);
28+
目標.searchParams.set('_librian_exit', '1');
29+
window.location.href = 目標.href;
30+
}
31+
async function 忽略錯誤(結果) {
32+
try {
33+
await 結果;
34+
} catch (錯誤) {}
35+
}
36+
var 完成操作 = {
37+
回標題: 導航,
38+
開始: 導航,
39+
讀檔畫面: 導航,
40+
從劇本開始: 導航
41+
};
42+
async function 執行調用(上一次調用, 方法, 參數) {
43+
await 上一次調用;
44+
var api = await api就緒;
45+
var 返回值 = await api[方法].apply(api, 參數);
46+
if (完成操作[方法]) {
47+
return 完成操作[方法](返回值);
48+
}
49+
return 返回值;
50+
}
51+
52+
window.山彥 = new Proxy({ 傳輸: 'promise', 退出: 退出 }, {
53+
get: function (目標, 方法) {
54+
if (方法 in 目標) {
55+
return 目標[方法];
56+
}
57+
return async function () {
58+
var 參數 = Array.prototype.slice.call(arguments);
59+
var 結果 = 執行調用(調用隊列, 方法, 參數);
60+
調用隊列 = 忽略錯誤(結果);
61+
return await 結果;
62+
};
63+
}
64+
});
65+
})();

‎librian/librian本體/前端/src/全局.coffee‎

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,19 @@ window.onload = ->
6363
handler: (val, oldVal) ->
6464
山彥.vue更新(val)
6565
deep: true
66-
山彥.vue連接初始化((x)->
67-
for a,b of x
68-
v[a]=b
69-
)
66+
await 初始化()
67+
演出.準備工作()
7068
if 入口=='讀檔'
71-
山彥.初始化 ->
72-
演出.準備工作()
73-
存檔讀檔.讀檔準備()
69+
await 存檔讀檔.讀檔準備()
7470
else
75-
山彥.初始化 ->
76-
演出.準備工作()
77-
演出.更新()
78-
71+
await 演出.更新()
72+
73+
初始化 = ->
74+
狀態 = await 山彥.初始化()
75+
if 狀態
76+
for 鍵, 值 of 狀態
77+
v[鍵] = 值
78+
7979

8080

8181
從虛擬核心提取資源 = (心)->
@@ -94,9 +94,9 @@ window.onload = ->
9494

9595
window.加載完成的初始化 = ->
9696
$('#加載畫面').fadeOut()
97-
山彥.初始化 ->
98-
演出.準備工作()
99-
演出.更新()
97+
await 初始化()
98+
演出.準備工作()
99+
await 演出.更新()
100100

101101
在線運行 = ->
102102
if typeof(虛擬核心) == "undefined"
@@ -117,12 +117,12 @@ window.加載完成的初始化 = ->
117117
this.n += 1
118118
更新: ->
119119
演出.改變演出狀態(虛擬核心.演出步[this.n])
120-
狀態回調: (步進, callback)->
120+
狀態回調: (步進)->
121121
if 步進
122122
this.步進()
123-
callback(虛擬核心.演出步[this.n])
124-
初始化: (callback)->
125-
callback()
123+
虛擬核心.演出步[this.n]
124+
初始化: ->
125+
return
126126
切換全屏: ->
127127
doc = window.document
128128
docEl = doc.documentElement

‎librian/librian本體/前端/src/存檔讀檔.coffee‎

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,19 @@ import 演出 from './演出.coffee'
66

77
export default 存檔讀檔 =
88
存檔準備: ->
9-
山彥.取檔 (檔表) ->
10-
v.存檔讀檔.檔表 = 檔表
11-
v.存檔讀檔.啓動功能 = '存檔'
12-
$('#總畫面').attr('存檔讀檔面板', 'on')
9+
檔表 = await 山彥.取檔()
10+
v.存檔讀檔.檔表 = 檔表
11+
v.存檔讀檔.啓動功能 = '存檔'
12+
$('#總畫面').attr('存檔讀檔面板', 'on')
1313
讀檔準備: ->
14-
山彥.取檔 (檔表) ->
15-
v.存檔讀檔.檔表 = 檔表
16-
v.存檔讀檔.啓動功能 = '讀檔'
17-
$('#總畫面').attr('存檔讀檔面板', 'on')
14+
檔表 = await 山彥.取檔()
15+
v.存檔讀檔.檔表 = 檔表
16+
v.存檔讀檔.啓動功能 = '讀檔'
17+
$('#總畫面').attr('存檔讀檔面板', 'on')
1818
存檔: (名字, 描述)->
1919
this.截圖轉換 160, 90, (截圖)->
20-
山彥.存檔(名字, 描述, 截圖)
21-
山彥.取檔 (檔表) ->
22-
v.存檔讀檔.檔表 = 檔表
20+
await 山彥.存檔(名字, 描述, 截圖)
21+
v.存檔讀檔.檔表 = await 山彥.取檔()
2322
讀檔: (名字)->
2423
山彥.讀檔(名字)
2524
$('#總畫面').attr('存檔讀檔面板', 'off')
@@ -39,4 +38,4 @@ export default 存檔讀檔 =
3938
context = canvas.getContext("2d")
4039
context.drawImage(t, 0, 0, 160, 90)
4140
base64 = canvas.toDataURL("image/webp")
42-
回調(base64)
41+
回調(base64)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#話語框
2+
height: 90%
3+
4+
#名字框背景, #話語框背景
5+
box-sizing: border-box
6+
border: 36px solid
7+
border-image: url('../素材/t0.png') 86 86 round
8+
background: rgba(128, 128, 128, 0.8)
9+
background-clip: padding-box
10+
11+
#名字
12+
padding: 22px 42px
13+
14+
#話語
15+
padding: 40px

‎librian/librian本體/前端/src/演出.coffee‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ export default 演出 =
4141
setTimeout(演出.縮放調整, 200)
4242

4343
更新: (瞬間化=false)->
44-
山彥.狀態回調 false, (狀態, 步進=false)->
45-
演出.改變演出狀態(狀態, 瞬間化)
44+
狀態 = await 山彥.狀態回調(false)
45+
演出.改變演出狀態(狀態, 瞬間化)
4646

4747
步進更新: (瞬間化=false)->
48-
山彥.狀態回調 true, (狀態)->
49-
演出.改變演出狀態(狀態, 瞬間化)
48+
狀態 = await 山彥.狀態回調(true)
49+
演出.改變演出狀態(狀態, 瞬間化)
5050

5151
翻譯: (s)->
5252
if not v.翻譯

0 commit comments

Comments
 (0)