-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfix_ggb.py
More file actions
130 lines (116 loc) · 5.93 KB
/
Copy pathfix_ggb.py
File metadata and controls
130 lines (116 loc) · 5.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""Fix appletOnLoad bug + improve UX in 6 GeoGebra pages."""
import re, os, sys
sys.stdout.reconfigure(encoding='utf-8')
BASE = r'C:\Users\DAVID\Desktop\פרויקטים\מתמטיקה לחרדים מוכן'
PAGES = [
'learn/meshulashim.html',
'topics/merubaot.html',
'topics/maagal.html',
'learn/geo_analytit.html',
'learn/funktziot.html',
'learn/mishvaa_ribuit.html',
]
# Spinner keyframe CSS to inject once per file
SPINNER_CSS = '''
<style id="ggb-spinner-css">
@keyframes ggb-spin{to{transform:rotate(360deg)}}
</style>'''
def make_load_fn(pid, appname, algebra):
safe_pid = pid.replace('-', '_')
return (
" function _load() {\n"
" if (_loaded) return; _loaded = true;\n"
" var ph = document.getElementById('ggb-ph-' + _id);\n"
" var cont = document.getElementById('ggb-cont-' + _id);\n"
"\n"
" /* loading UI */\n"
" var h = window.innerWidth < 640 ? 350 : 500;\n"
" cont.style.height = h + 'px';\n"
" ph.innerHTML =\n"
" '<div style=\"display:flex;flex-direction:column;align-items:center;'\n"
" + 'justify-content:center;min-height:220px;gap:16px;padding:28px;text-align:center\">'\n"
" + '<div style=\"width:34px;height:34px;border-radius:50%;border:3px solid #e0ddd8;'\n"
" + 'border-top-color:#2b3a32;animation:ggb-spin .85s linear infinite\"></div>'\n"
" + '<div style=\"font-size:.95rem;font-weight:700;color:#2b3a32\">'\n"
" + '\\u05D8\\u05D5\\u05E2\\u05DF \\u05DB\\u05DC\\u05D9 GeoGebra\\u2026</div>'\n"
" + '<div style=\"font-size:.78rem;color:#888;max-width:290px;line-height:1.6\">'\n"
" + '\\u05D4\\u05DB\\u05DC\\u05D9 \\u05E2\\u05E9\\u05D5\\u05D9 \\u05DC\\u05E7\\u05D7\\u05EA'\n"
" + ' 5\\u201315 \\u05E9\\u05E0\\u05D9\\u05D5\\u05EA \\u05DC\\u05D8\\u05E2\\u05D9\\u05E0\\u05D4.'\n"
" + ' \\u05D0\\u05E0\\u05D0 \\u05D4\\u05DE\\u05EA\\u05DF.</div>'\n"
" + '</div>';\n"
"\n"
" /* string callback — the only correct way with deployggb.js */\n"
" var cbName = '__ggbCb_" + safe_pid + "';\n"
" var _timer = setTimeout(function() {\n"
" ph.style.display = '';\n"
" ph.innerHTML =\n"
" '<div style=\"text-align:center;padding:28px\">'\n"
" + '<div style=\"font-size:1.8rem;margin-bottom:8px\">⚠️</div>'\n"
" + '<div style=\"font-weight:700;color:#c0392b;margin-bottom:6px\">'\n"
" + '\\u05D4\\u05D8\\u05E2\\u05D9\\u05E0\\u05D4 \\u05E0\\u05DB\\u05E9\\u05DC\\u05D4</div>'\n"
" + '<div style=\"font-size:.82rem;color:#666;margin-bottom:16px\">'\n"
" + '\\u05D1\\u05D3\\u05D5\\u05E7 \\u05D7\\u05D9\\u05D1\\u05D5\\u05E8'\n"
" + ' \\u05DC\\u05D0\\u05D9\\u05E0\\u05D8\\u05E8\\u05E0\\u05D8 \\u05D5\\u05E0\\u05E1\\u05D4 \\u05E9\\u05D5\\u05D1.</div>'\n"
" + '<button onclick=\"_loaded=false;ph.style.display=\\'\\';_load()\" '\n"
" + 'style=\"padding:8px 22px;border-radius:10px;border:2px solid #2b3a32;'\n"
" + 'background:#2b3a32;color:#fff;font-family:Heebo,sans-serif;'\n"
" + 'font-size:.9rem;font-weight:700;cursor:pointer\">'\n"
" + '\\uD83D\\uDD04 \\u05E0\\u05E1\\u05D4 \\u05E9\\u05D5\\u05D1</button>'\n"
" + '</div>';\n"
" }, 25000);\n"
"\n"
" window[cbName] = function(api) {\n"
" clearTimeout(_timer);\n"
" _api = api; /* api arg is reliable; window.ggbApplet is not */\n"
" ph.style.display = 'none';\n"
" cont.style.opacity = '0';\n"
" cont.style.transition = 'opacity .45s ease';\n"
" requestAnimationFrame(function() { cont.style.opacity = '1'; });\n"
" var rb = document.getElementById('ggb-reset-' + _id);\n"
" if (rb) rb.style.display = '';\n"
" delete window[cbName];\n"
" };\n"
"\n"
" new GGBApplet({\n"
" appName: '" + appname + "', language: 'he',\n"
" width: Math.max(cont.offsetWidth, 400), height: h,\n"
" showToolBar: true, showAlgebraInput: " + algebra + ", showMenuBar: false,\n"
" showResetIcon: false, enableRightClick: false, showZoomButtons: true,\n"
" enableFileFeatures: false,\n"
" appletOnLoad: cbName /* must be string name, not function ref */\n"
" }, true).inject('ggb-cont-' + _id);\n"
" }"
)
for rel in PAGES:
path = os.path.join(BASE, rel.replace('/', os.sep))
with open(path, encoding='utf-8') as f:
html = f.read()
# Extract key params
id_m = re.search(r"var _id = '([^']+)'", html)
app_m = re.search(r"appName: '([^']+)'", html)
alg_m = re.search(r'showAlgebraInput: (true|false)', html)
if not (id_m and app_m and alg_m):
print(f'SKIP (parse failed): {rel}')
continue
pid = id_m.group(1)
appname = app_m.group(1)
algebra = alg_m.group(1)
new_load = make_load_fn(pid, appname, algebra)
# Replace the old _load() function
pattern = r' function _load\(\) \{.+?\n \}(?=\n\n var _sec)'
new_html, n = re.subn(pattern, lambda m: new_load, html, flags=re.DOTALL)
if n == 0:
print(f'NO MATCH: {rel}')
continue
# Fix obs.disconnect() → obs.unobserve(entry)
new_html = new_html.replace(
'{ _load(); _obs.disconnect(); }',
'{ _load(); _obs.unobserve(e[0].target); }'
)
# Inject spinner CSS if not already present
if 'ggb-spin' not in new_html and '<head>' in new_html:
new_html = new_html.replace('</head>', SPINNER_CSS + '\n</head>', 1)
with open(path, 'w', encoding='utf-8') as f:
f.write(new_html)
print(f'FIXED: {rel} (id={pid}, app={appname}, alg={algebra}, replacements={n})')
print('Done.')