wani 0.1.10 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +7 -3
- data/assets/build.json +3 -3
- data/assets/index.html +4 -1
- data/assets/style.css +10 -1
- data/assets/time-expired.webp +0 -0
- data/assets/wani.wasm +2 -2
- data/lib/wani/browser/application.rb +22 -2
- data/lib/wani/browser/presentation_timer.rb +9 -0
- data/lib/wani/browser/renderer.rb +4 -1
- data/lib/wani/server/application.rb +1 -1
- data/lib/wani/version.rb +1 -1
- metadata +2 -2
- data/assets/time-expired.png +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 85ec1823b674eea078278bc07b3516fc1cca469f3b00a42a7d53d677cf76306d
|
|
4
|
+
data.tar.gz: 2c6fe20e5c8749718b51cb2cadc40706cc610b75002c2ff061f9650733cdcc40
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0fe3730449dc7263365ea27e2fb84447c382896bec358ae4926aead67af4eb5fbf96cc1e13d0a2f055174948dd69ad6babd6af49f13331eb7d9f3a3ed3cb2804
|
|
7
|
+
data.tar.gz: 128750706c4ad65b2945348703d19d09606e30a4c24c1738bf3fe2974ed84622872469e4e1061079fb9d073e818e094e5586c1c415d82ed7237fa3cfdcd1afb9
|
data/README.md
CHANGED
|
@@ -25,7 +25,7 @@ npm ci
|
|
|
25
25
|
bundle exec rake build:wasm
|
|
26
26
|
|
|
27
27
|
gem build wani.gemspec
|
|
28
|
-
gem install ./wani-0.1.
|
|
28
|
+
gem install ./wani-0.1.11.gem
|
|
29
29
|
|
|
30
30
|
wani new my-talk
|
|
31
31
|
cd my-talk
|
|
@@ -130,7 +130,10 @@ Ctrl+P でも印刷できます。
|
|
|
130
130
|
|
|
131
131
|
## 発表タイマー
|
|
132
132
|
|
|
133
|
-
|
|
133
|
+
hashなしのURLで開くと、最初のスライドに半透明の黒いベールと「スタート」ボタンを表示します。
|
|
134
|
+
待機中はページ移動と計測を止め、ボタンを押すとベールが消えてタイマーが始まります。Fキーで全画面にして待機できます。
|
|
135
|
+
`#slide=1` などのhash付きURLでは、読み込み完了から計測します。
|
|
136
|
+
既定では5分で時間切れ画面を表示します。
|
|
134
137
|
Front Matter の `time_limit` に分数を指定して変更できます(小数も可)。
|
|
135
138
|
`time_limit: 0` でタイマーを無効にします。
|
|
136
139
|
|
|
@@ -138,12 +141,13 @@ Front Matter の `time_limit` に分数を指定して変更できます(小
|
|
|
138
141
|
残り5秒は中央に数字を表示し、画面の短辺に対して20%・40%・60%・80%・100%と強調サイズを増やします。
|
|
139
142
|
各数字は0.8秒で通常サイズに戻ります。動きを減らす設定では拡大アニメーションを省略します。
|
|
140
143
|
時間切れになると、兎柄フードをくわえたワニ(さめ)の画像を表示します。
|
|
144
|
+
画像は軽量なWebP形式で配布し、発表開始前に読み込みとデコードを済ませて、時間切れの文字と同時に表示します。
|
|
141
145
|
左右キーまたは「スライドに戻る」ボタンで、時間切れ直前のスライドに戻れます。
|
|
142
146
|
戻った後は通常通りページを移動でき、時間切れ画面は再表示しません。
|
|
143
147
|
最終スライドの表示中はタイマーを一時停止し、カウントダウンも時間切れ画面も表示しません。
|
|
144
148
|
前のスライドに戻ると、停止前の残り時間から再開します。1ページだけの場合も停止します。
|
|
145
149
|
ページを再読み込みするとタイマーも最初から始まります。
|
|
146
|
-
|
|
150
|
+
開始待ち画面、タイマー、時間切れ画面はPDFには含めません。
|
|
147
151
|
|
|
148
152
|
## 同梱フォント
|
|
149
153
|
|
data/assets/build.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.1.
|
|
3
|
-
"source_sha256": "
|
|
2
|
+
"version": "0.1.11",
|
|
3
|
+
"source_sha256": "7fd82f57dedeab0d552457b69e4a32432bfce7316ce41c8618808d34c001e82e",
|
|
4
4
|
"loader_commit": "dc6b0ffd5800ed9bfc49268ed8021d456f10ddf8",
|
|
5
|
-
"wasm_sha256": "
|
|
5
|
+
"wasm_sha256": "777e59a959570126bfe466047c60b3e49ae72bb9a4b645c6564321cf9580ae08"
|
|
6
6
|
}
|
data/assets/index.html
CHANGED
|
@@ -24,10 +24,13 @@
|
|
|
24
24
|
<p id="status" role="status">Ruby を読み込んでいます…</p>
|
|
25
25
|
<aside id="warnings" role="status" hidden></aside>
|
|
26
26
|
<div id="viewport"><main id="stage" aria-label="スライド"></main></div>
|
|
27
|
+
<section id="start-overlay" role="dialog" aria-modal="true" aria-label="発表の開始" hidden>
|
|
28
|
+
<button id="start-presentation">スタート</button>
|
|
29
|
+
</section>
|
|
27
30
|
<output id="countdown" aria-live="off" aria-label="発表の残り時間" hidden></output>
|
|
28
31
|
<section id="time-expired" role="dialog" aria-modal="true" aria-labelledby="time-expired-title" hidden>
|
|
29
32
|
<h1 id="time-expired-title">時間切れです!</h1>
|
|
30
|
-
<
|
|
33
|
+
<img id="time-expired-image" class="time-expired-image" src="/assets/time-expired.webp" width="1086" height="724" alt="兎柄フードをくわえるワニ(さめ)">
|
|
31
34
|
<p>← または → キーで元のスライドに戻れます</p>
|
|
32
35
|
<button id="resume-slides">スライドに戻る</button>
|
|
33
36
|
</section>
|
data/assets/style.css
CHANGED
|
@@ -34,6 +34,10 @@ button:focus-visible, a:focus-visible { outline: 2px solid #557e64; outline-offs
|
|
|
34
34
|
.title { margin: 0 0 36px; white-space: nowrap; flex: 0 0 160px; font-weight: 700; line-height: 1.12; overflow: hidden; letter-spacing: -.025em; }
|
|
35
35
|
.body { flex: 1 1 0; min-height: 0; overflow: hidden; line-height: 1.3; }
|
|
36
36
|
.body p { margin: 0 0 .35em; }
|
|
37
|
+
.titleless .body { display: flex; flex-direction: column; justify-content: safe center; text-align: center; }
|
|
38
|
+
.titleless .body > * { flex-shrink: 0; }
|
|
39
|
+
.titleless .body > :last-child { margin-bottom: 0; }
|
|
40
|
+
.titleless .body img { margin-inline: auto; }
|
|
37
41
|
.body ul, .body ol { margin: .2em 0 .4em; padding-left: 1.35em; }
|
|
38
42
|
.body pre { margin: .3em 0; padding: .4em .55em; background: #f3f6f2; white-space: pre-wrap; tab-size: 2; }
|
|
39
43
|
.body code { font-family: ui-monospace, "IBM Plex Sans JP", monospace; font-size: .8em; }
|
|
@@ -89,7 +93,7 @@ button:focus-visible, a:focus-visible { outline: 2px solid #557e64; outline-offs
|
|
|
89
93
|
#time-expired { position: fixed; inset: 0; z-index: 30; display: flex; flex-direction: column; align-items: center; justify-content: center; background: white; color: #20352e; padding: 16px; overflow: auto; }
|
|
90
94
|
#time-expired[hidden], #countdown[hidden] { display: none; }
|
|
91
95
|
#time-expired h1 { margin: 0; font-size: clamp(24px, 4vw, 56px); }
|
|
92
|
-
.time-expired-image { width: min(90vw, calc(65vh *
|
|
96
|
+
.time-expired-image { width: min(90vw, calc(65vh * 1086 / 724)); aspect-ratio: 1086 / 724; height: auto; flex-shrink: 0; }
|
|
93
97
|
#time-expired p { margin: 8px 0; text-align: center; }
|
|
94
98
|
@media print { #countdown, #time-expired { display: none !important; } }
|
|
95
99
|
|
|
@@ -102,3 +106,8 @@ button:focus-visible, a:focus-visible { outline: 2px solid #557e64; outline-offs
|
|
|
102
106
|
.island-left { left: 0; }
|
|
103
107
|
.island-right { right: 0; }
|
|
104
108
|
.rabbit-position { z-index: 2; }
|
|
109
|
+
|
|
110
|
+
#start-overlay { position: fixed; inset: 0; z-index: 30; display: flex; align-items: center; justify-content: center; background: rgb(0 0 0 / 60%); }
|
|
111
|
+
#start-overlay[hidden] { display: none; }
|
|
112
|
+
#start-presentation { padding: 18px 48px; font-size: clamp(24px, 4vw, 40px); font-weight: 700; border-radius: 12px; }
|
|
113
|
+
@media print { #start-overlay { display: none !important; } }
|
|
Binary file
|
data/assets/wani.wasm
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: data/assets/wani.wasm
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 35169057 bytes
|
|
4
|
+
sha256: 777e59a959570126bfe466047c60b3e49ae72bb9a4b645c6564321cf9580ae08
|
|
@@ -26,11 +26,19 @@ module Wani
|
|
|
26
26
|
@layout.wait_assets(element("stage"))
|
|
27
27
|
@sections.each_with_index { |section, index| @layout.fit_slide(section, index + 1) }
|
|
28
28
|
prepare_pages(false)
|
|
29
|
+
prepare_timer_image
|
|
29
30
|
bind_events
|
|
31
|
+
@waiting_to_start = JS.global[:location][:hash].to_s.empty?
|
|
30
32
|
go(hash_index)
|
|
31
33
|
%w[previous next fullscreen speaker print print-notes].each { |id| element(id)[:disabled] = false }
|
|
32
34
|
update_buttons
|
|
33
|
-
|
|
35
|
+
if @waiting_to_start
|
|
36
|
+
element("start-overlay")[:hidden] = false
|
|
37
|
+
element("viewport")[:inert] = true
|
|
38
|
+
element("start-presentation").focus
|
|
39
|
+
else
|
|
40
|
+
start_timer
|
|
41
|
+
end
|
|
34
42
|
element("status")[:textContent] = "準備できました"
|
|
35
43
|
end
|
|
36
44
|
|
|
@@ -55,6 +63,15 @@ module Wani
|
|
|
55
63
|
end
|
|
56
64
|
|
|
57
65
|
def bind_events
|
|
66
|
+
element("start-presentation").addEventListener("click") do
|
|
67
|
+
next unless @waiting_to_start
|
|
68
|
+
@waiting_to_start = false
|
|
69
|
+
element("start-overlay")[:hidden] = true
|
|
70
|
+
element("viewport")[:inert] = false
|
|
71
|
+
element("start-presentation").blur
|
|
72
|
+
go(0)
|
|
73
|
+
start_timer
|
|
74
|
+
end
|
|
58
75
|
element("previous").addEventListener("click") { go(@index - 1) }
|
|
59
76
|
element("next").addEventListener("click") { go(@index + 1) }
|
|
60
77
|
element("fullscreen").addEventListener("click") { fullscreen }
|
|
@@ -65,6 +82,7 @@ module Wani
|
|
|
65
82
|
target = event[:target]
|
|
66
83
|
next if event[:ctrlKey] == JS::True || event[:altKey] == JS::True || event[:metaKey] == JS::True
|
|
67
84
|
next if %w[INPUT TEXTAREA SELECT].include?(target[:tagName].to_s) || target[:isContentEditable] == JS::True
|
|
85
|
+
next if @waiting_to_start && !%w[f F Escape n N].include?(event[:key].to_s)
|
|
68
86
|
handled = true
|
|
69
87
|
case event[:key].to_s
|
|
70
88
|
when "ArrowRight", " ", "PageDown" then go(@index + 1)
|
|
@@ -89,6 +107,8 @@ module Wani
|
|
|
89
107
|
end
|
|
90
108
|
|
|
91
109
|
def go(index)
|
|
110
|
+
return if @waiting_to_start && @active_number
|
|
111
|
+
|
|
92
112
|
if @time_expired
|
|
93
113
|
@time_expired = false
|
|
94
114
|
element("time-expired")[:hidden] = true
|
|
@@ -102,7 +122,7 @@ module Wani
|
|
|
102
122
|
@active_number = @index + 1
|
|
103
123
|
element("position")[:textContent] = "#{@index + 1} / #{@sections.length}"
|
|
104
124
|
desired = "#slide=#{@index + 1}"
|
|
105
|
-
JS.global[:history].replaceState(JS::Null, "", desired) unless JS.global[:location][:hash].to_s == desired
|
|
125
|
+
JS.global[:history].replaceState(JS::Null, "", desired) unless @waiting_to_start || JS.global[:location][:hash].to_s == desired
|
|
106
126
|
update_buttons
|
|
107
127
|
@layout.scale
|
|
108
128
|
sync_speaker
|
|
@@ -3,6 +3,15 @@ module Wani
|
|
|
3
3
|
class Application
|
|
4
4
|
private
|
|
5
5
|
|
|
6
|
+
# Decode the actual displayed image before enabling presentation controls.
|
|
7
|
+
def prepare_timer_image
|
|
8
|
+
return if @presentation.time_limit.zero?
|
|
9
|
+
|
|
10
|
+
element("time-expired-image").decode.await
|
|
11
|
+
rescue JS::Error
|
|
12
|
+
warn("時間切れの画像を読み込めませんでした")
|
|
13
|
+
end
|
|
14
|
+
|
|
6
15
|
def start_timer
|
|
7
16
|
return if @presentation.time_limit.zero?
|
|
8
17
|
|
|
@@ -13,7 +13,10 @@ module Wani
|
|
|
13
13
|
section.setAttribute("aria-label", "スライド #{slide.number}")
|
|
14
14
|
title = child(section, "h1", "title")
|
|
15
15
|
title[:textContent] = notes ? "ノート #{slide.number}" : slide.title
|
|
16
|
-
|
|
16
|
+
if title[:textContent].to_s.empty?
|
|
17
|
+
title[:style][:display] = "none"
|
|
18
|
+
section[:className] = "slide titleless"
|
|
19
|
+
end
|
|
17
20
|
body = child(section, "div", "body")
|
|
18
21
|
body[:innerHTML] = notes ? slide.notes_html : slide.html
|
|
19
22
|
resolve_links(body)
|
|
@@ -7,7 +7,7 @@ module Wani
|
|
|
7
7
|
module Server
|
|
8
8
|
# Only the selected Markdown, images below its directory and fixed gem assets are public.
|
|
9
9
|
class Application
|
|
10
|
-
ASSETS = %w[index.html style.css highlight.css rouge.LICENSE bootstrap.rb speaker.html rabbit.svg shark.svg time-expired.
|
|
10
|
+
ASSETS = %w[index.html style.css highlight.css rouge.LICENSE bootstrap.rb speaker.html rabbit.svg shark.svg time-expired.webp runtime.pr672.js wani.wasm runtime.LICENSE runtime.NOTICE build.json
|
|
11
11
|
fonts/IBMPlexSansJP-Regular.woff2 fonts/IBMPlexSansJP-Bold.woff2].freeze
|
|
12
12
|
TYPES = { ".html" => "text/html; charset=utf-8", ".css" => "text/css; charset=utf-8", ".rb" => "text/plain; charset=utf-8", ".js" => "text/javascript", ".wasm" => "application/wasm", ".md" => "text/plain; charset=utf-8", ".svg" => "image/svg+xml", ".png" => "image/png", ".jpg" => "image/jpeg", ".jpeg" => "image/jpeg", ".webp" => "image/webp", ".json" => "application/json", ".woff2" => "font/woff2" }.freeze
|
|
13
13
|
IMAGES = %w[.png .jpg .jpeg .webp .svg].freeze
|
data/lib/wani/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wani
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.11
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ledsun
|
|
@@ -100,7 +100,7 @@ files:
|
|
|
100
100
|
- assets/shark.svg
|
|
101
101
|
- assets/speaker.html
|
|
102
102
|
- assets/style.css
|
|
103
|
-
- assets/time-expired.
|
|
103
|
+
- assets/time-expired.webp
|
|
104
104
|
- assets/wani.wasm
|
|
105
105
|
- exe/wani
|
|
106
106
|
- lib/wani.rb
|
data/assets/time-expired.png
DELETED
|
Binary file
|