askclass-course-theme 0.16.2 → 0.18.0
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/_includes/course.html +3 -1
- data/_includes/foot/popup.html +7 -0
- data/_includes/header.html +1 -1
- data/_includes/segment/index.html +2 -4
- data/_includes/session/bubble.html +20 -29
- data/_includes/session/conversation.html +9 -1
- data/_includes/session/hilight_word.html +23 -0
- data/_includes/word-click-handler.html +7 -0
- data/_layouts/session.html +9 -1
- data/_sass/_base.scss +4 -0
- data/_sass/_bubbles.scss +11 -10
- data/_sass/_bullets.scss +33 -0
- data/_sass/_tab-main.scss +4 -0
- data/_sass/popup.scss +29 -0
- data/assets/css/dialog.scss +2 -0
- data/assets/js/word-click-handler.js +74 -0
- metadata +7 -3
- data/_includes/session/say.html +0 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 774894d1fc1a67d7c731c3cd0d3563798198c89968ddf9620529004f3d31b17b
|
|
4
|
+
data.tar.gz: a16889d3dfde34bac5aeaaa375403f1f46efcbc827458d9ffb988118b8107722
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5c17878b86a406c61a94e490b23f7c26f9d1453d3f4e2e485a00f5951d56cfe42d30fbeb0619d00671368117b70e05e60c70ca145c1546c9704d7f595e707e7c
|
|
7
|
+
data.tar.gz: 0c42c8af64f481af2ebbf8e14174dc10ee8636621c6fcdbdff7a6b25c65ea5f1e6a1073c8816ca2a38d8d5d579c02d1e3c59246921ff49abcb700acc0142450b
|
data/_includes/course.html
CHANGED
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
{{ session.title }}
|
|
49
49
|
|
|
50
50
|
{%- if session.part -%}
|
|
51
|
-
<small>(
|
|
51
|
+
<small>({{ session.part }})</small>
|
|
52
52
|
{%- endif -%}
|
|
53
53
|
</div>
|
|
54
54
|
{%- endfor -%}
|
|
@@ -56,8 +56,10 @@
|
|
|
56
56
|
<div class="control">
|
|
57
57
|
<a class="button" href="/segment/{{ segment }}">
|
|
58
58
|
{{ info.title }}
|
|
59
|
+
{%- if info['rocket-icon'] != 'none' %}
|
|
59
60
|
<span data-date="{{ info.end }}"
|
|
60
61
|
class="middle-align rocket {{ symbols }}">rocket_launch</span>
|
|
62
|
+
{%- endif %}
|
|
61
63
|
</a>
|
|
62
64
|
</div>
|
|
63
65
|
</li>
|
data/_includes/header.html
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
{% include head/meta.html -%}
|
|
3
3
|
{%- include head/common.html -%}
|
|
4
4
|
{%- if page.collection == 'session' -%}
|
|
5
|
-
{%- if session_data.
|
|
5
|
+
{%- if session_data.dialog -%}
|
|
6
6
|
<link rel="stylesheet" href="{{ 'assets/css/dialog.css' | relative_url }}" />
|
|
7
7
|
{%- else -%}
|
|
8
8
|
<link rel="stylesheet" href="{{ 'assets/css/session.css' | relative_url }}" />
|
|
@@ -23,10 +23,8 @@
|
|
|
23
23
|
<span data-date="{{ session.due }}" class="{{ symbols }} alarm">alarm_on</span>
|
|
24
24
|
{{ session.due | date: '%b %e, %y' }}
|
|
25
25
|
</div>
|
|
26
|
-
{%- elsif session.type -%}
|
|
27
|
-
<div class="header">{{ session.header }}</div>
|
|
28
26
|
{%- else -%}
|
|
29
|
-
<div class="header"
|
|
27
|
+
<div class="header">{{ session.header | default: " " }}</div>
|
|
30
28
|
{%- endif -%}
|
|
31
29
|
|
|
32
30
|
<div class="body">
|
|
@@ -38,7 +36,7 @@
|
|
|
38
36
|
|
|
39
37
|
{%- if session.part -%}
|
|
40
38
|
<div class="item">
|
|
41
|
-
|
|
39
|
+
{{ session.part }}
|
|
42
40
|
</div>
|
|
43
41
|
{%- endif -%}
|
|
44
42
|
</div>
|
|
@@ -1,36 +1,27 @@
|
|
|
1
|
-
{% assign words = include.text | split: " " %}
|
|
2
|
-
|
|
3
1
|
<div class="bubble-container {{ include.side }}">
|
|
4
2
|
<div class="talk-bubble {{ include.side }} tri-right {{ include.side }}-in border round">
|
|
5
3
|
<div class="talktext">
|
|
6
|
-
|
|
4
|
+
{%- if session_data.index %}
|
|
5
|
+
<div class="index">{{ include.index }}</div>
|
|
6
|
+
{%- endif %}
|
|
7
|
+
|
|
8
|
+
{% assign words = include.text | replace: '\', '<br/>' | split: " " %}
|
|
7
9
|
{%- for raw in words %}
|
|
8
|
-
{%-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
{%-
|
|
19
|
-
{
|
|
20
|
-
{%-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
| remove_first: ','
|
|
24
|
-
| remove_first: '!'
|
|
25
|
-
| remove_first: '?'
|
|
26
|
-
%}
|
|
27
|
-
{%- if word == str %}
|
|
28
|
-
{%- include session/say.html word=word -%}
|
|
29
|
-
{%- else %}
|
|
30
|
-
{%- assign punct = str | slice: -1, 1 -%}
|
|
31
|
-
{%- include session/say.html word=word punct=punct -%}
|
|
32
|
-
{% endif -%}
|
|
33
|
-
{% endif -%}
|
|
10
|
+
{%- if session_data.mode == 'learn-english' %}
|
|
11
|
+
{%- assign w = raw
|
|
12
|
+
| replace: 'th', '<u>th</u>'
|
|
13
|
+
| replace: 'Th', '<u>Th</u>'
|
|
14
|
+
| replace: 'St', '<u>St</u>'
|
|
15
|
+
| replace: 've', '<u>ve</u>'
|
|
16
|
+
| replace: 'Ve', '<u>Ve</u>'
|
|
17
|
+
| replace: 'dr', '<u>dr</u>'
|
|
18
|
+
| replace: 'Dr', '<u>Dr</u>'
|
|
19
|
+
%}
|
|
20
|
+
{%- else %}
|
|
21
|
+
{%- assign w = raw %}
|
|
22
|
+
{%- endif %}
|
|
23
|
+
|
|
24
|
+
{%- include session/hilight_word.html word=w %}
|
|
34
25
|
{% endfor -%}
|
|
35
26
|
</div>
|
|
36
27
|
</div>
|
|
@@ -6,6 +6,14 @@
|
|
|
6
6
|
{%- else -%}
|
|
7
7
|
{%- assign side = 'left' -%}
|
|
8
8
|
{%- endif -%}
|
|
9
|
-
{
|
|
9
|
+
{%- if text.first -%}
|
|
10
|
+
{%- assign idx = forloop.index -%}
|
|
11
|
+
{%- for line in text -%}
|
|
12
|
+
{%- assign i = forloop.index | prepend: "." | prepend: idx -%}
|
|
13
|
+
{% include session/bubble.html text=line side=side index=i %}
|
|
14
|
+
{%- endfor -%}
|
|
15
|
+
{%- else -%}
|
|
16
|
+
{% include session/bubble.html text=text side=side index=forloop.index %}
|
|
17
|
+
{%- endif -%}
|
|
10
18
|
{%- endfor -%}
|
|
11
19
|
</section>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{% assign word = include.word | replace: '<u>' | replace: '</u>' %}
|
|
2
|
+
{%- assign str = word | remove_first: '^' %}
|
|
3
|
+
|
|
4
|
+
{%- if str == word %}
|
|
5
|
+
{{ word }}
|
|
6
|
+
{%- else -%}
|
|
7
|
+
{%- assign w = str
|
|
8
|
+
| remove_first: '.'
|
|
9
|
+
| remove_first: ','
|
|
10
|
+
| remove_first: ';'
|
|
11
|
+
| remove_first: '!'
|
|
12
|
+
| remove_first: '?'
|
|
13
|
+
%}
|
|
14
|
+
{%- if w == str %}
|
|
15
|
+
{%- assign punct = '' -%}
|
|
16
|
+
{%- else %}
|
|
17
|
+
{%- assign punct = str | slice: -1, 1 -%}
|
|
18
|
+
{% endif -%}
|
|
19
|
+
<a href="#"
|
|
20
|
+
data-word-click="wordClick"
|
|
21
|
+
data-arg-word="{{ w }}"
|
|
22
|
+
>{{ w }}</a>{{ punct }}
|
|
23
|
+
{% endif -%}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
function wordClick(_event, _link, args) {
|
|
3
|
+
console.info('Default "wordClick" function defined in _includes/word-click-handler.html\nReplace this file with your custom function');
|
|
4
|
+
console.log(`Word clicked: "${args.word}"`);
|
|
5
|
+
showPopup("Word", args.word);
|
|
6
|
+
}
|
|
7
|
+
</script>
|
data/_layouts/session.html
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
{%- if session_data.width != 'max' -%}
|
|
5
5
|
{%- assign constraint = 'max-width' -%}
|
|
6
6
|
{%- endif -%}
|
|
7
|
+
{%- if session_data.dialog -%}
|
|
8
|
+
{%- assign constraint = constraint | prepend: 'dialog ' -%}
|
|
9
|
+
{%- endif -%}
|
|
7
10
|
|
|
8
11
|
<!doctype html>
|
|
9
12
|
<html lang="en">
|
|
@@ -20,7 +23,7 @@
|
|
|
20
23
|
{%- include session/sounds.html audio=session_data.audio -%}
|
|
21
24
|
{{ content }}
|
|
22
25
|
{%- if page.dialogue -%}
|
|
23
|
-
{%- include session/conversation.html data=page.dialogue-%}
|
|
26
|
+
{%- include session/conversation.html data=page.dialogue -%}
|
|
24
27
|
{%- endif -%}
|
|
25
28
|
</article>
|
|
26
29
|
</section>
|
|
@@ -30,5 +33,10 @@
|
|
|
30
33
|
{%- include footer.html -%}
|
|
31
34
|
{%- include foot/mathjax.html -%}
|
|
32
35
|
<script async src="/assets/js/essential-audio-player.js"></script>
|
|
36
|
+
{%- if session_data.dialog -%}
|
|
37
|
+
<script async src="/assets/js/word-click-handler.js"></script>
|
|
38
|
+
{%- include word-click-handler.html -%}
|
|
39
|
+
{%- include foot/popup.html -%}
|
|
40
|
+
{%- endif -%}
|
|
33
41
|
</body>
|
|
34
42
|
</html>
|
data/_sass/_base.scss
CHANGED
data/_sass/_bubbles.scss
CHANGED
|
@@ -281,23 +281,24 @@ html {
|
|
|
281
281
|
font-size: calc(20px + (30 - 10) * ((100vw - 500px) / (1600 - 300)));
|
|
282
282
|
line-height: calc(30px + (12 - 0) * ((100vw - 500px) / (600 - 10)));
|
|
283
283
|
font-family: var(--font-tertiary);
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
284
|
+
.index {
|
|
285
|
+
position: absolute;
|
|
286
|
+
top: -14px;
|
|
287
|
+
display: flex;
|
|
288
|
+
width: 30px;
|
|
289
|
+
font-size: 20px;
|
|
290
|
+
line-height: 29px;
|
|
291
|
+
white-space: nowrap;
|
|
292
|
+
}
|
|
292
293
|
}
|
|
293
294
|
.left .talktext .index {
|
|
294
295
|
color: var(--color1);
|
|
295
|
-
left: -
|
|
296
|
+
left: -37px;
|
|
296
297
|
justify-content: flex-end;
|
|
297
298
|
}
|
|
298
299
|
.right .talktext .index {
|
|
299
300
|
color: var(--color2);
|
|
300
|
-
right: -
|
|
301
|
+
right: -37px;
|
|
301
302
|
justify-content: flex-begin;
|
|
302
303
|
}
|
|
303
304
|
u {
|
data/_sass/_bullets.scss
CHANGED
|
@@ -32,3 +32,36 @@ ul > li > ul > li {
|
|
|
32
32
|
list-style-type: initial;
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
+
|
|
36
|
+
details {
|
|
37
|
+
summary {
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
list-style: none;
|
|
40
|
+
&::-webkit-details-marker,
|
|
41
|
+
&::marker {
|
|
42
|
+
display: none;
|
|
43
|
+
}
|
|
44
|
+
&::before {
|
|
45
|
+
content: "\25B6\FE0E";
|
|
46
|
+
margin-right: 5px;
|
|
47
|
+
font-size: 0.9em;
|
|
48
|
+
color: var(--color-bullet);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
&[open] {
|
|
52
|
+
summary {
|
|
53
|
+
&::before {
|
|
54
|
+
content: "\25BC\FE0E";
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
details > *:not(summary) {
|
|
61
|
+
animation: fadeIn 0.3s ease-in;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@keyframes fadeIn {
|
|
65
|
+
from { opacity: 0; margin-top: -10px; }
|
|
66
|
+
to { opacity: 1; margin-top: 0; }
|
|
67
|
+
}
|
data/_sass/_tab-main.scss
CHANGED
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
font-family: var(--icon-name);
|
|
46
46
|
line-height: 0.7;
|
|
47
47
|
font-size: 37px;
|
|
48
|
+
cursor: pointer;
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -69,6 +70,9 @@
|
|
|
69
70
|
padding: 10px;
|
|
70
71
|
overflow: hidden;
|
|
71
72
|
text-align: left;
|
|
73
|
+
display: flex;
|
|
74
|
+
flex-direction: column;
|
|
75
|
+
justify-content: space-between;
|
|
72
76
|
&.limit-height {
|
|
73
77
|
max-height: var(--grid-body-height);
|
|
74
78
|
overflow-y: auto;
|
data/_sass/popup.scss
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
.course-popup {
|
|
2
|
+
position: fixed;
|
|
3
|
+
inset: 0;
|
|
4
|
+
background: rgba(0, 0, 0, 0.6);
|
|
5
|
+
display: flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
z-index: 9999;
|
|
9
|
+
opacity: 0;
|
|
10
|
+
visibility: hidden;
|
|
11
|
+
transition: all 0.2s ease;
|
|
12
|
+
|
|
13
|
+
&.show {
|
|
14
|
+
opacity: 1;
|
|
15
|
+
visibility: visible;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.card-tab {
|
|
19
|
+
max-width: 90%;
|
|
20
|
+
width: 480px;
|
|
21
|
+
max-height: 85vh;
|
|
22
|
+
position: relative;
|
|
23
|
+
height: initial;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.body {
|
|
27
|
+
overflow-y: auto;
|
|
28
|
+
}
|
|
29
|
+
}
|
data/assets/css/dialog.scss
CHANGED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
function handleWordClick(e) {
|
|
2
|
+
let link = e.target.closest('a[data-word-click]');
|
|
3
|
+
if (!link) return;
|
|
4
|
+
|
|
5
|
+
const fnName = link.dataset.wordClick;
|
|
6
|
+
if (!fnName) return;
|
|
7
|
+
|
|
8
|
+
const customFn = window[fnName];
|
|
9
|
+
if (typeof customFn !== 'function') {
|
|
10
|
+
console.warn(`Custom function not found: ${fnName}`);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
e.preventDefault();
|
|
15
|
+
e.stopPropagation();
|
|
16
|
+
|
|
17
|
+
const args = {};
|
|
18
|
+
for (const attr of link.attributes) {
|
|
19
|
+
if (attr.name.startsWith('data-arg-')) {
|
|
20
|
+
const key = attr.name.replace(/^data-arg-/, '');
|
|
21
|
+
args[key] = attr.value;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
customFn(e, link, args);
|
|
27
|
+
} catch (err) {
|
|
28
|
+
console.error(`Error in word click handler "${fnName}":`, err);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function showPopup(title, html) {
|
|
33
|
+
const popup = document.getElementById('course-popup');
|
|
34
|
+
if (!popup) return;
|
|
35
|
+
|
|
36
|
+
const header = popup.querySelector('.top-bar');
|
|
37
|
+
const body = popup.querySelector('.body');
|
|
38
|
+
if (header) header.textContent = title;
|
|
39
|
+
if (body) body.innerHTML = html;
|
|
40
|
+
|
|
41
|
+
popup.classList.add('show');
|
|
42
|
+
document.body.classList.add('no-scroll');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function close(popup) {
|
|
46
|
+
popup.classList.remove('show');
|
|
47
|
+
document.body.classList.remove('no-scroll');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function initPopupClose() {
|
|
51
|
+
const popup = document.getElementById('course-popup');
|
|
52
|
+
if (!popup) return;
|
|
53
|
+
|
|
54
|
+
popup.querySelector('.tab')?.addEventListener('click', () => close(popup));
|
|
55
|
+
|
|
56
|
+
popup.addEventListener('click', (e) => {
|
|
57
|
+
if (e.target === popup) {
|
|
58
|
+
close(popup);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
document.addEventListener('keydown', (e) => {
|
|
63
|
+
if (e.key === 'Escape' && popup.classList.contains('show')) {
|
|
64
|
+
close(popup);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
document.addEventListener('click', handleWordClick, true);
|
|
70
|
+
if (document.readyState === 'loading') {
|
|
71
|
+
document.addEventListener('DOMContentLoaded', initPopupClose);
|
|
72
|
+
} else {
|
|
73
|
+
initPopupClose();
|
|
74
|
+
}
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: askclass-course-theme
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.18.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- AskClass
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-01-
|
|
11
|
+
date: 2026-01-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: jekyll
|
|
@@ -37,6 +37,7 @@ files:
|
|
|
37
37
|
- _includes/course.html
|
|
38
38
|
- _includes/date_range.html
|
|
39
39
|
- _includes/foot/mathjax.html
|
|
40
|
+
- _includes/foot/popup.html
|
|
40
41
|
- _includes/foot/pwaupdate.html
|
|
41
42
|
- _includes/footer.html
|
|
42
43
|
- _includes/head/common.html
|
|
@@ -53,15 +54,16 @@ files:
|
|
|
53
54
|
- _includes/session/conversation.html
|
|
54
55
|
- _includes/session/googledrive.html
|
|
55
56
|
- _includes/session/header.html
|
|
57
|
+
- _includes/session/hilight_word.html
|
|
56
58
|
- _includes/session/images.html
|
|
57
59
|
- _includes/session/item.html
|
|
58
60
|
- _includes/session/next_prev.html
|
|
59
61
|
- _includes/session/paginator.html
|
|
60
62
|
- _includes/session/points.html
|
|
61
|
-
- _includes/session/say.html
|
|
62
63
|
- _includes/session/sounds.html
|
|
63
64
|
- _includes/session/videos.html
|
|
64
65
|
- _includes/session/youtube.html
|
|
66
|
+
- _includes/word-click-handler.html
|
|
65
67
|
- _layouts/default.html
|
|
66
68
|
- _layouts/segment.html
|
|
67
69
|
- _layouts/session.html
|
|
@@ -80,11 +82,13 @@ files:
|
|
|
80
82
|
- _sass/_table.scss
|
|
81
83
|
- _sass/_video.scss
|
|
82
84
|
- _sass/init.scss
|
|
85
|
+
- _sass/popup.scss
|
|
83
86
|
- assets/css/dialog.scss
|
|
84
87
|
- assets/css/segment.scss
|
|
85
88
|
- assets/css/session.scss
|
|
86
89
|
- assets/favicon.ico
|
|
87
90
|
- assets/js/essential-audio-player.js
|
|
91
|
+
- assets/js/word-click-handler.js
|
|
88
92
|
- assets/loading.svg
|
|
89
93
|
- assets/logo-144.png
|
|
90
94
|
- assets/logo-192.png
|
data/_includes/session/say.html
DELETED