askclass-course-theme 0.16.2 → 0.17.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4ce64de0443f65b49f34b38d0533ff9e62ecf3000e3e75000dee8cece5120464
4
- data.tar.gz: 55381a81434be5e764ea82ffc0d89a64da0ac070b31387251e2a34e8d40810a8
3
+ metadata.gz: 886e39bbcdab94d388dfa9c55bcbfe41b1b1283f479c4db696d93883bf9c23df
4
+ data.tar.gz: 785bca91c47314ff9456392e3f5f32ccaee7b78eb07e0f046929ba4be96215d3
5
5
  SHA512:
6
- metadata.gz: b7dde1de1e3910395c4625721569ad72324bf233ffa77a00d4ffd6fddbf1bca212c5887b4c97924e6fbc303005a8a19030b9a0d85b1e837bfc9759e6fd8aa0f3
7
- data.tar.gz: cd0db138a8946959e5f402dc99fb7376abc56af4d3c8834f0b2e1fb5c4bfb5d7e2450b87254c77dad73f2de44b5780d4da32349152f51c37e0ffcb5d55e0bbaa
6
+ metadata.gz: 6571e10c3b28c25ac4e98153c5bf828ac3ae36ebf28beac7beac9b927ef948940b2c95970a9df227b1801a01183ea5cbe27477d503ff8a3bb42ea8808087c780
7
+ data.tar.gz: 7d45255fc7eb87db6331645d7ccf3f2636ea596f2cb11db03d893d35c85364f8812fcd0add0120dd14727843caa34029f0df0c2b690c2391aec2742f4282dba9
@@ -0,0 +1,7 @@
1
+ <div id="course-popup" class="course-popup">
2
+ <div class="card-tab {{ segment_data.theme }}">
3
+ <div class="top-bar">&nbsp;</div>
4
+ <div class="tab icon {{ symbols }}">close</div>
5
+ <div class="body"></div>
6
+ </div>
7
+ </div>
@@ -1,36 +1,28 @@
1
- {% assign words = include.text | split: " " %}
2
1
 
3
2
  <div class="bubble-container {{ include.side }}">
4
3
  <div class="talk-bubble {{ include.side }} tri-right {{ include.side }}-in border round">
5
4
  <div class="talktext">
6
- <div class="index">{{ include.index }}</div>
5
+ {%- if session_data.index %}
6
+ <div class="index">{{ include.index }}</div>
7
+ {%- endif %}
8
+
9
+ {% assign words = include.text | replace: '\', '<br/>' | split: " " %}
7
10
  {%- for raw in words %}
8
- {%- assign w = raw
9
- | replace: 'th', '<u>th</u>'
10
- | replace: 'Th', '<u>Th</u>'
11
- | replace: 'St', '<u>St</u>'
12
- | replace: 've', '<u>ve</u>'
13
- | replace: 'Ve', '<u>Ve</u>'
14
- | replace: 'dr', '<u>dr</u>'
15
- | replace: 'Dr', '<u>Dr</u>'
16
- %}
17
- {%- assign str = w | remove_first: '^' %}
18
- {%- if str == w %}
19
- {{ w }}
20
- {%- else -%}
21
- {%- assign word = str
22
- | remove_first: '.'
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 -%}
11
+ {%- if session_data.mode == 'learn-english' %}
12
+ {%- assign w = raw
13
+ | replace: 'th', '<u>th</u>'
14
+ | replace: 'Th', '<u>Th</u>'
15
+ | replace: 'St', '<u>St</u>'
16
+ | replace: 've', '<u>ve</u>'
17
+ | replace: 'Ve', '<u>Ve</u>'
18
+ | replace: 'dr', '<u>dr</u>'
19
+ | replace: 'Dr', '<u>Dr</u>'
20
+ %}
21
+ {%- else %}
22
+ {%- assign w = raw %}
23
+ {%- endif %}
24
+
25
+ {%- include session/hilight_word.html word=w %}
34
26
  {% endfor -%}
35
27
  </div>
36
28
  </div>
@@ -6,6 +6,14 @@
6
6
  {%- else -%}
7
7
  {%- assign side = 'left' -%}
8
8
  {%- endif -%}
9
- {% include session/bubble.html text=text side=side index=forloop.index %}
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>
@@ -4,6 +4,9 @@
4
4
  {%- if session_data.width != 'max' -%}
5
5
  {%- assign constraint = 'max-width' -%}
6
6
  {%- endif -%}
7
+ {%- if session_data.type == '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.type == '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/popup.scss ADDED
@@ -0,0 +1,25 @@
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: inherit;
24
+ }
25
+ }
@@ -3,5 +3,7 @@
3
3
 
4
4
  @use "init" as *;
5
5
  @use "base" as *;
6
+ @use "tab-main" as *;
6
7
  @use "article" as *;
7
8
  @use "bubbles" as *;
9
+ @use "popup" as *;
@@ -0,0 +1,70 @@
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
+ }
43
+
44
+ function initPopupClose() {
45
+ const popup = document.getElementById('course-popup');
46
+ if (!popup) return;
47
+
48
+ popup.querySelector('.tab')?.addEventListener('click', () => {
49
+ popup.classList.remove('show');
50
+ });
51
+
52
+ popup.addEventListener('click', (e) => {
53
+ if (e.target === popup) {
54
+ popup.classList.remove('show');
55
+ }
56
+ });
57
+
58
+ document.addEventListener('keydown', (e) => {
59
+ if (e.key === 'Escape' && popup.classList.contains('show')) {
60
+ popup.classList.remove('show');
61
+ }
62
+ });
63
+ }
64
+
65
+ document.addEventListener('click', handleWordClick, true);
66
+ if (document.readyState === 'loading') {
67
+ document.addEventListener('DOMContentLoaded', initPopupClose);
68
+ } else {
69
+ initPopupClose();
70
+ }
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.16.2
4
+ version: 0.17.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-16 00:00:00.000000000 Z
11
+ date: 2026-01-22 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
@@ -1,2 +0,0 @@
1
- {% assign word = include.word | replace: '<u>' | replace: '</u>' %}
2
- <a target="_blank" href="https://www.google.com/search?q=pronounce+{{ word }}">{{ include.word }}</a>{{ include.punct }}