-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJsScripts.vb
More file actions
225 lines (203 loc) · 11 KB
/
Copy pathJsScripts.vb
File metadata and controls
225 lines (203 loc) · 11 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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
Imports System.IO
Imports System.Reflection
Imports System.Text
''' <summary>
''' Helper interno per il caricamento lazy delle risorse incorporate (JavaScript e CSS) da assembly.
''' </summary>
Friend Module EmbeddedScriptLoader
Private ReadOnly _resourceCache As New Dictionary(Of String, String)(StringComparer.OrdinalIgnoreCase)
Private ReadOnly _lockObj As New Object()
Public Function GetEmbeddedString(resourceFileName As String) As String
SyncLock _lockObj
Dim cached As String = Nothing
If _resourceCache.TryGetValue(resourceFileName, cached) Then
Return cached
End If
Dim asm = Assembly.GetExecutingAssembly()
Dim resourceName = asm.GetManifestResourceNames().FirstOrDefault(Function(n) n.EndsWith(resourceFileName, StringComparison.OrdinalIgnoreCase))
If resourceName Is Nothing Then
Debug.WriteLine($"[EmbeddedScriptLoader] Embedded resource '{resourceFileName}' not found.")
Return String.Empty
End If
Using stream = asm.GetManifestResourceStream(resourceName)
If stream Is Nothing Then Return String.Empty
Using reader As New StreamReader(stream, Encoding.UTF8)
cached = reader.ReadToEnd()
_resourceCache(resourceFileName) = cached
Return cached
End Using
End Using
End SyncLock
End Function
End Module
''' <summary>
''' Contiene gli script CSS e JavaScript per la personalizzazione dell'interfaccia Web di WhatsApp e Telegram
''' (angoli arrotondati, temi scuro/chiaro e sincronizzazione tema) caricati on-demand.
''' </summary>
Public Class ThemeJsScripts
Private Shared ReadOnly _lightModeJs As New Lazy(Of String)(Function()
Dim themeCss = EmbeddedScriptLoader.GetEmbeddedString("theme.css")
Return "var style = document.createElement(""style"");" & vbCrLf &
"style.innerHTML = `" & themeCss & " body{ background:#fff !important; } ._ap4q::after { background-color: #fff !important; } `;" & vbCrLf &
"var ref = document.querySelector(""script"");" & vbCrLf &
"ref.parentNode.insertBefore(style, ref);" & vbCrLf &
"document.getElementsByTagName(""body"")[0].classList = [""""];"
End Function)
Private Shared ReadOnly _darkModeJs As New Lazy(Of String)(Function()
Dim themeCss = EmbeddedScriptLoader.GetEmbeddedString("theme.css")
Return "var style = document.createElement(""style"");" & vbCrLf &
"style.innerHTML = `" & themeCss & " body{ background:#000 !important; } ._ap4q::after { background-color: #000 !important; } `;" & vbCrLf &
"var ref = document.querySelector(""script"");" & vbCrLf &
"ref.parentNode.insertBefore(style, ref);" & vbCrLf &
"document.getElementsByTagName(""body"")[0].classList = [""dark""];"
End Function)
Private Shared ReadOnly _telegramInitJs As New Lazy(Of String)(Function()
Dim telegramCss = EmbeddedScriptLoader.GetEmbeddedString("telegram.css")
Return "(function() {" & vbCrLf &
" var injectCss = function() {" & vbCrLf &
" try {" & vbCrLf &
" var styleId = 'hidachat-telegram-css';" & vbCrLf &
" if (!document.getElementById(styleId)) {" & vbCrLf &
" var style = document.createElement('style');" & vbCrLf &
" style.id = styleId;" & vbCrLf &
" style.textContent = `" & telegramCss & "`;" & vbCrLf &
" (document.head || document.documentElement).appendChild(style);" & vbCrLf &
" }" & vbCrLf &
" } catch(e) {}" & vbCrLf &
" };" & vbCrLf &
" injectCss();" & vbCrLf &
" if (document.readyState === 'loading') {" & vbCrLf &
" document.addEventListener('DOMContentLoaded', injectCss);" & vbCrLf &
" }" & vbCrLf &
"})();"
End Function)
Private Shared ReadOnly _telegramLightModeJs As New Lazy(Of String)(Function()
Dim telegramCss = EmbeddedScriptLoader.GetEmbeddedString("telegram.css")
Return "(function() {" & vbCrLf &
" try {" & vbCrLf &
" var styleId = 'hidachat-telegram-css';" & vbCrLf &
" if (!document.getElementById(styleId)) {" & vbCrLf &
" var style = document.createElement('style');" & vbCrLf &
" style.id = styleId;" & vbCrLf &
" style.textContent = `" & telegramCss & "`;" & vbCrLf &
" (document.head || document.documentElement).appendChild(style);" & vbCrLf &
" }" & vbCrLf &
" document.documentElement.classList.remove('night', 'theme-dark', 'dark');" & vbCrLf &
" if (document.body) { document.body.classList.remove('night', 'theme-dark', 'dark'); }" & vbCrLf &
" localStorage.setItem('tt-theme', 'day');" & vbCrLf &
" localStorage.setItem('theme', 'day');" & vbCrLf &
" } catch(e) {}" & vbCrLf &
" if (window.themeController && typeof window.themeController.setTheme === 'function') {" & vbCrLf &
" try { window.themeController.setTheme('day'); } catch(e) {}" & vbCrLf &
" }" & vbCrLf &
" if (window.appThemeController && typeof window.appThemeController.setTheme === 'function') {" & vbCrLf &
" try { window.appThemeController.setTheme('day'); } catch(e) {}" & vbCrLf &
" }" & vbCrLf &
"})();"
End Function)
Private Shared ReadOnly _telegramDarkModeJs As New Lazy(Of String)(Function()
Dim telegramCss = EmbeddedScriptLoader.GetEmbeddedString("telegram.css")
Return "(function() {" & vbCrLf &
" try {" & vbCrLf &
" var styleId = 'hidachat-telegram-css';" & vbCrLf &
" var existingStyle = document.getElementById(styleId);" & vbCrLf &
" if (!existingStyle) {" & vbCrLf &
" var style = document.createElement('style');" & vbCrLf &
" style.id = styleId;" & vbCrLf &
" style.textContent = `" & telegramCss & "`;" & vbCrLf &
" (document.head || document.documentElement).appendChild(style);" & vbCrLf &
" }" & vbCrLf &
" document.documentElement.classList.add('night');" & vbCrLf &
" if (document.body) { document.body.classList.add('night'); }" & vbCrLf &
" localStorage.setItem('tt-theme', 'night');" & vbCrLf &
" localStorage.setItem('theme', 'night');" & vbCrLf &
" } catch(e) {}" & vbCrLf &
" if (window.themeController && typeof window.themeController.setTheme === 'function') {" & vbCrLf &
" try { window.themeController.setTheme('night'); } catch(e) {}" & vbCrLf &
" }" & vbCrLf &
" if (window.appThemeController && typeof window.appThemeController.setTheme === 'function') {" & vbCrLf &
" try { window.appThemeController.setTheme('night'); } catch(e) {}" & vbCrLf &
" }" & vbCrLf &
"})();"
End Function)
''' <summary>Script per l'applicazione del tema Chiaro in WhatsApp Web.</summary>
Public Shared ReadOnly Property LightModeJS As String
Get
Return _lightModeJs.Value
End Get
End Property
''' <summary>Script per l'applicazione del tema Scuro in WhatsApp Web.</summary>
Public Shared ReadOnly Property DarkModeJS As String
Get
Return _darkModeJs.Value
End Get
End Property
''' <summary>Script per l'iniezione iniziale dei fogli di stile responsivi in Telegram Web.</summary>
Public Shared ReadOnly Property TelegramInitJS As String
Get
Return _telegramInitJs.Value
End Get
End Property
''' <summary>Script per l'applicazione del tema Chiaro in Telegram Web.</summary>
Public Shared ReadOnly Property TelegramLightModeJS As String
Get
Return _telegramLightModeJs.Value
End Get
End Property
''' <summary>Script per l'applicazione del tema Scuro in Telegram Web.</summary>
Public Shared ReadOnly Property TelegramDarkModeJS As String
Get
Return _telegramDarkModeJs.Value
End Get
End Property
End Class
''' <summary>
''' Contiene lo script JavaScript per l'override delle notifiche native del browser (ServiceWorkerRegistration e Notification),
''' reindirizzando le notifiche di WhatsApp verso la finestra host WPF via IPC (chrome.webview.postMessage).
''' </summary>
Public Class NotificationJsScripts
Private Shared ReadOnly _notificationJs As New Lazy(Of String)(Function()
Return EmbeddedScriptLoader.GetEmbeddedString("notification.js")
End Function)
''' <summary>Script per l'override delle notifiche.</summary>
Public Shared ReadOnly Property NotificationOverrideJS As String
Get
Return _notificationJs.Value
End Get
End Property
End Class
''' <summary>
''' Contiene gli script JavaScript necessari alla funzione di traduzione messaggi (pulsante hover, bolla di traduzione, scansione DOM).
''' </summary>
Public Class TranslationJsScripts
Private Shared ReadOnly _translationTemplate As New Lazy(Of String)(Function()
Return EmbeddedScriptLoader.GetEmbeddedString("translation.js")
End Function)
''' <summary>
''' Assembla ed inietta lo script JavaScript completo di traduzione configurato con la lingua e le opzioni attuali.
''' </summary>
Public Shared Function GetTranslationJS(
targetLangCode As String,
targetLangName As String,
tooltipLabel As String,
enableHover As Boolean,
enableFullPage As Boolean
) As String
Dim escapedTooltip = tooltipLabel.Replace("'", "\'")
Dim escapedName = targetLangName.Replace("'", "\'")
Dim hoverClassListCmd = If(enableHover,
"document.body.classList.remove('disable-hover-translation');",
"document.body.classList.add('disable-hover-translation');")
Dim fullPageInitCmd = If(enableFullPage,
"if (document.readyState === 'complete') { window.translatePage(); } else { window.addEventListener('load', () => window.translatePage()); }",
"")
Dim sb As New StringBuilder(_translationTemplate.Value)
sb.Replace("$$LANG_CODE$$", targetLangCode)
sb.Replace("$$LANG_NAME$$", escapedName)
sb.Replace("$$TOOLTIP$$", escapedTooltip)
sb.Replace("$$ENABLE_HOVER$$", enableHover.ToString().ToLowerInvariant())
sb.Replace("$$HOVER_CLASS_CMD$$", hoverClassListCmd)
sb.Replace("$$FULL_PAGE_INIT$$", fullPageInitCmd)
Return sb.ToString()
End Function
End Class