antigravity-rtl-patcher 3.0.2 → 3.0.5
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.
- package/package.json +1 -1
- package/payload/Vazirmatn-Variable.woff2 +0 -0
- package/payload/utils-inject.js +309 -96
package/package.json
CHANGED
|
Binary file
|
package/payload/utils-inject.js
CHANGED
|
@@ -13,9 +13,7 @@ win.webContents.on('console-message', (event, ...args) => {
|
|
|
13
13
|
const configData = message.substring(16);
|
|
14
14
|
const configPath = require('path').join(require('os').homedir(), '.antigravity-rtl.json');
|
|
15
15
|
require('fs').writeFileSync(configPath, configData, 'utf8');
|
|
16
|
-
} catch (err) {
|
|
17
|
-
console.error('[RTL] Config save failed:', err);
|
|
18
|
-
}
|
|
16
|
+
} catch (err) {}
|
|
19
17
|
}
|
|
20
18
|
});
|
|
21
19
|
|
|
@@ -38,52 +36,276 @@ win.webContents.on('dom-ready', () => {
|
|
|
38
36
|
window.__RTL_LOADED__ = true;
|
|
39
37
|
|
|
40
38
|
let rtlEnabled = ${rtlConfig.enabled};
|
|
39
|
+
let panelVisible = false;
|
|
40
|
+
|
|
41
|
+
// RTL Detection Function
|
|
42
|
+
function isRTLText(text) {
|
|
43
|
+
if (!text || typeof text !== 'string') return false;
|
|
44
|
+
const rtlChars = /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/;
|
|
45
|
+
const cleanText = text.trim();
|
|
46
|
+
if (cleanText.length === 0) return false;
|
|
47
|
+
|
|
48
|
+
// Check first non-whitespace character
|
|
49
|
+
for (let char of cleanText) {
|
|
50
|
+
if (char.trim()) {
|
|
51
|
+
return rtlChars.test(char);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Apply RTL to text elements dynamically
|
|
58
|
+
function applyRTLToContent() {
|
|
59
|
+
if (!rtlEnabled) return;
|
|
60
|
+
|
|
61
|
+
// Target message containers and paragraphs
|
|
62
|
+
const textElements = document.querySelectorAll('p, h1, h2, h3, h4, h5, h6, li, blockquote, td, th');
|
|
63
|
+
|
|
64
|
+
textElements.forEach(el => {
|
|
65
|
+
// Skip if already processed or is UI element
|
|
66
|
+
if (el.classList.contains('rtl-ui') || el.classList.contains('rtl-processed')) return;
|
|
67
|
+
|
|
68
|
+
// Skip code blocks
|
|
69
|
+
if (el.closest('pre, code')) return;
|
|
70
|
+
|
|
71
|
+
const text = el.textContent;
|
|
72
|
+
if (isRTLText(text)) {
|
|
73
|
+
el.setAttribute('dir', 'rtl');
|
|
74
|
+
el.classList.add('rtl-processed');
|
|
75
|
+
} else if (el.hasAttribute('dir') && el.getAttribute('dir') === 'rtl') {
|
|
76
|
+
el.removeAttribute('dir');
|
|
77
|
+
el.classList.remove('rtl-processed');
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Observe DOM changes
|
|
83
|
+
const observer = new MutationObserver((mutations) => {
|
|
84
|
+
if (rtlEnabled) {
|
|
85
|
+
applyRTLToContent();
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Start observing after a short delay
|
|
90
|
+
setTimeout(() => {
|
|
91
|
+
observer.observe(document.body, {
|
|
92
|
+
childList: true,
|
|
93
|
+
subtree: true,
|
|
94
|
+
characterData: true
|
|
95
|
+
});
|
|
96
|
+
applyRTLToContent();
|
|
97
|
+
}, 500);
|
|
41
98
|
|
|
42
99
|
const CSS = \`
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
100
|
+
/* Vazirmatn Font */
|
|
101
|
+
@font-face {
|
|
102
|
+
font-family: 'Vazirmatn';
|
|
103
|
+
src: url('./Vazirmatn-Variable.woff2') format('woff2');
|
|
104
|
+
font-weight: 100 900;
|
|
105
|
+
font-display: swap;
|
|
46
106
|
}
|
|
47
107
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
108
|
+
/* Apply Vazirmatn to all text when RTL is active */
|
|
109
|
+
body.rtl-active {
|
|
110
|
+
font-family: 'Vazirmatn', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif !important;
|
|
51
111
|
}
|
|
52
112
|
|
|
53
|
-
|
|
113
|
+
/* RTL Styles - Only for message content */
|
|
114
|
+
body.rtl-active [dir="rtl"] {
|
|
115
|
+
direction: rtl !important;
|
|
116
|
+
text-align: right !important;
|
|
54
117
|
unicode-bidi: isolate !important;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* Keep paragraphs and headings with proper bidi */
|
|
121
|
+
body.rtl-active p,
|
|
122
|
+
body.rtl-active h1, body.rtl-active h2, body.rtl-active h3,
|
|
123
|
+
body.rtl-active h4, body.rtl-active h5, body.rtl-active h6 {
|
|
124
|
+
unicode-bidi: plaintext !important;
|
|
125
|
+
text-align: start !important;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* Lists in RTL context */
|
|
129
|
+
body.rtl-active [dir="rtl"] ul,
|
|
130
|
+
body.rtl-active [dir="rtl"] ol {
|
|
131
|
+
padding-left: 0 !important;
|
|
132
|
+
padding-right: 2rem !important;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* Code blocks always LTR */
|
|
136
|
+
body.rtl-active pre,
|
|
137
|
+
body.rtl-active code,
|
|
138
|
+
body.rtl-active pre *,
|
|
139
|
+
body.rtl-active code * {
|
|
55
140
|
direction: ltr !important;
|
|
56
141
|
text-align: left !important;
|
|
142
|
+
unicode-bidi: isolate !important;
|
|
143
|
+
font-family: 'Courier New', Consolas, Monaco, monospace !important;
|
|
57
144
|
}
|
|
58
145
|
|
|
59
|
-
|
|
146
|
+
/* Panel Container */
|
|
147
|
+
#rtl-trigger {
|
|
60
148
|
position: fixed;
|
|
61
149
|
bottom: 20px;
|
|
62
150
|
right: 20px;
|
|
63
|
-
z-index:
|
|
151
|
+
z-index: 999998;
|
|
64
152
|
width: 50px;
|
|
65
153
|
height: 50px;
|
|
66
154
|
border-radius: 50%;
|
|
67
|
-
background:
|
|
68
|
-
border:
|
|
155
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
156
|
+
border: none;
|
|
69
157
|
color: white;
|
|
70
158
|
cursor: pointer;
|
|
71
159
|
display: flex;
|
|
72
160
|
align-items: center;
|
|
73
161
|
justify-content: center;
|
|
74
162
|
font-size: 24px;
|
|
75
|
-
transition: all 0.3s;
|
|
76
|
-
box-shadow: 0
|
|
163
|
+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
164
|
+
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
#rtl-trigger:hover {
|
|
168
|
+
transform: scale(1.1) rotate(180deg);
|
|
169
|
+
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
#rtl-trigger.active {
|
|
173
|
+
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
|
174
|
+
box-shadow: 0 4px 12px rgba(245, 87, 108, 0.4);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
#rtl-panel {
|
|
178
|
+
position: fixed;
|
|
179
|
+
bottom: 80px;
|
|
180
|
+
right: 20px;
|
|
181
|
+
z-index: 999999;
|
|
182
|
+
width: 300px;
|
|
183
|
+
background: rgba(255, 255, 255, 0.95);
|
|
184
|
+
backdrop-filter: blur(10px);
|
|
185
|
+
border-radius: 16px;
|
|
186
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
|
187
|
+
opacity: 0;
|
|
188
|
+
transform: translateY(20px) scale(0.9);
|
|
189
|
+
pointer-events: none;
|
|
190
|
+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
191
|
+
overflow: hidden;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
#rtl-panel.visible {
|
|
195
|
+
opacity: 1;
|
|
196
|
+
transform: translateY(0) scale(1);
|
|
197
|
+
pointer-events: auto;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
@media (prefers-color-scheme: dark) {
|
|
201
|
+
#rtl-panel {
|
|
202
|
+
background: rgba(30, 30, 40, 0.95);
|
|
203
|
+
color: #e0e0e0;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.rtl-panel-header {
|
|
208
|
+
padding: 20px;
|
|
209
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
210
|
+
color: white;
|
|
211
|
+
text-align: center;
|
|
212
|
+
font-weight: 600;
|
|
213
|
+
font-size: 16px;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.rtl-panel-body {
|
|
217
|
+
padding: 24px;
|
|
77
218
|
}
|
|
78
219
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
220
|
+
.rtl-row {
|
|
221
|
+
display: flex;
|
|
222
|
+
align-items: center;
|
|
223
|
+
justify-content: space-between;
|
|
224
|
+
margin-bottom: 16px;
|
|
82
225
|
}
|
|
83
226
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
227
|
+
.rtl-label {
|
|
228
|
+
font-size: 14px;
|
|
229
|
+
font-weight: 500;
|
|
230
|
+
color: #333;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
@media (prefers-color-scheme: dark) {
|
|
234
|
+
.rtl-label {
|
|
235
|
+
color: #e0e0e0;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/* Toggle Switch */
|
|
240
|
+
.rtl-switch {
|
|
241
|
+
position: relative;
|
|
242
|
+
width: 52px;
|
|
243
|
+
height: 28px;
|
|
244
|
+
background: #ddd;
|
|
245
|
+
border-radius: 14px;
|
|
246
|
+
cursor: pointer;
|
|
247
|
+
transition: background 0.3s;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.rtl-switch.active {
|
|
251
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.rtl-switch::after {
|
|
255
|
+
content: '';
|
|
256
|
+
position: absolute;
|
|
257
|
+
width: 22px;
|
|
258
|
+
height: 22px;
|
|
259
|
+
background: white;
|
|
260
|
+
border-radius: 50%;
|
|
261
|
+
top: 3px;
|
|
262
|
+
left: 3px;
|
|
263
|
+
transition: transform 0.3s;
|
|
264
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.rtl-switch.active::after {
|
|
268
|
+
transform: translateX(24px);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.rtl-panel-footer {
|
|
272
|
+
padding: 16px 24px;
|
|
273
|
+
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
|
274
|
+
display: flex;
|
|
275
|
+
justify-content: center;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
@media (prefers-color-scheme: dark) {
|
|
279
|
+
.rtl-panel-footer {
|
|
280
|
+
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.rtl-github-btn {
|
|
285
|
+
display: flex;
|
|
286
|
+
align-items: center;
|
|
287
|
+
gap: 8px;
|
|
288
|
+
padding: 10px 20px;
|
|
289
|
+
background: #24292e;
|
|
290
|
+
color: white;
|
|
291
|
+
border: none;
|
|
292
|
+
border-radius: 8px;
|
|
293
|
+
cursor: pointer;
|
|
294
|
+
font-size: 13px;
|
|
295
|
+
font-weight: 500;
|
|
296
|
+
text-decoration: none;
|
|
297
|
+
transition: all 0.2s;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.rtl-github-btn:hover {
|
|
301
|
+
background: #1a1f23;
|
|
302
|
+
transform: translateY(-2px);
|
|
303
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.rtl-github-icon {
|
|
307
|
+
width: 18px;
|
|
308
|
+
height: 18px;
|
|
87
309
|
}
|
|
88
310
|
\`;
|
|
89
311
|
|
|
@@ -92,96 +314,87 @@ win.webContents.on('dom-ready', () => {
|
|
|
92
314
|
styleEl.textContent = CSS;
|
|
93
315
|
document.head.appendChild(styleEl);
|
|
94
316
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (cleaned.length === 0) return false;
|
|
99
|
-
|
|
100
|
-
const firstChar = cleaned.match(/[A-Za-z\\u0600-\\u06FF\\u0750-\\u077F\\u08A0-\\u08FF\\uFB50-\\uFDFF\\uFE70-\\uFEFF]/);
|
|
101
|
-
if (!firstChar) return false;
|
|
102
|
-
|
|
103
|
-
return /[\\u0600-\\u06FF\\u0750-\\u077F\\u08A0-\\u08FF\\uFB50-\\uFDFF\\uFE70-\\uFEFF]/.test(firstChar[0]);
|
|
317
|
+
// Apply RTL class if enabled
|
|
318
|
+
if (rtlEnabled) {
|
|
319
|
+
document.body.classList.add('rtl-active');
|
|
104
320
|
}
|
|
105
321
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if (cleaned.length > 0) {
|
|
114
|
-
const dir = detectRTL(cleaned) ? 'rtl' : 'ltr';
|
|
115
|
-
if (el.getAttribute('dir') !== dir) {
|
|
116
|
-
el.setAttribute('dir', dir);
|
|
117
|
-
}
|
|
118
|
-
} else {
|
|
119
|
-
if (el.hasAttribute('dir')) el.removeAttribute('dir');
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
document.querySelectorAll('.prose > *, [data-testid="chat-message"] > *, .markdown-body > *, .leading-relaxed > *').forEach(el => {
|
|
124
|
-
if (el.tagName === 'PRE' || el.tagName === 'CODE') return;
|
|
125
|
-
|
|
126
|
-
const text = el.textContent.replace(/[\\u200B-\\u200F\\uFEFF]/g, '').trim();
|
|
127
|
-
if (text) {
|
|
128
|
-
const dir = detectRTL(text) ? 'rtl' : 'ltr';
|
|
129
|
-
if (el.getAttribute('dir') !== dir) {
|
|
130
|
-
el.setAttribute('dir', dir);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
}
|
|
322
|
+
// Create UI
|
|
323
|
+
const trigger = document.createElement('button');
|
|
324
|
+
trigger.id = 'rtl-trigger';
|
|
325
|
+
trigger.className = rtlEnabled ? 'active rtl-ui' : 'rtl-ui';
|
|
326
|
+
trigger.innerHTML = '⇄';
|
|
327
|
+
trigger.title = 'RTL Settings';
|
|
135
328
|
|
|
136
|
-
document.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
329
|
+
const panel = document.createElement('div');
|
|
330
|
+
panel.id = 'rtl-panel';
|
|
331
|
+
panel.className = 'rtl-ui';
|
|
332
|
+
panel.innerHTML = \`
|
|
333
|
+
<div class="rtl-panel-header rtl-ui">
|
|
334
|
+
Antigravity Smart RTL
|
|
335
|
+
</div>
|
|
336
|
+
<div class="rtl-panel-body rtl-ui">
|
|
337
|
+
<div class="rtl-row rtl-ui">
|
|
338
|
+
<span class="rtl-label rtl-ui">RTL Mode</span>
|
|
339
|
+
<div class="rtl-switch \${rtlEnabled ? 'active' : ''} rtl-ui" id="rtl-toggle"></div>
|
|
340
|
+
</div>
|
|
341
|
+
</div>
|
|
342
|
+
<div class="rtl-panel-footer rtl-ui">
|
|
343
|
+
<a href="https://github.com/VaFa1726/antigravity-rtl-patcher" target="_blank" class="rtl-github-btn rtl-ui">
|
|
344
|
+
<svg class="rtl-github-icon rtl-ui" viewBox="0 0 16 16" fill="currentColor">
|
|
345
|
+
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/>
|
|
346
|
+
</svg>
|
|
347
|
+
Star on GitHub
|
|
348
|
+
</a>
|
|
349
|
+
</div>
|
|
350
|
+
\`;
|
|
140
351
|
|
|
141
|
-
document.
|
|
142
|
-
|
|
143
|
-
e.preventDefault();
|
|
144
|
-
toggleRTL();
|
|
145
|
-
}
|
|
146
|
-
}, { capture: true });
|
|
352
|
+
document.body.appendChild(trigger);
|
|
353
|
+
document.body.appendChild(panel);
|
|
147
354
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
355
|
+
// Event handlers
|
|
356
|
+
trigger.addEventListener('click', (e) => {
|
|
357
|
+
e.stopPropagation();
|
|
358
|
+
panelVisible = !panelVisible;
|
|
359
|
+
panel.classList.toggle('visible', panelVisible);
|
|
360
|
+
});
|
|
153
361
|
|
|
154
|
-
|
|
362
|
+
document.addEventListener('click', (e) => {
|
|
363
|
+
if (!e.target.classList.contains('rtl-ui')) {
|
|
364
|
+
panelVisible = false;
|
|
365
|
+
panel.classList.remove('visible');
|
|
366
|
+
}
|
|
367
|
+
});
|
|
155
368
|
|
|
156
|
-
|
|
369
|
+
document.getElementById('rtl-toggle').addEventListener('click', () => {
|
|
157
370
|
rtlEnabled = !rtlEnabled;
|
|
158
371
|
|
|
372
|
+
const toggle = document.getElementById('rtl-toggle');
|
|
373
|
+
toggle.classList.toggle('active', rtlEnabled);
|
|
374
|
+
trigger.classList.toggle('active', rtlEnabled);
|
|
375
|
+
|
|
159
376
|
if (rtlEnabled) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
document.head.appendChild(styleEl);
|
|
163
|
-
}
|
|
164
|
-
updateDirections();
|
|
377
|
+
document.body.classList.add('rtl-active');
|
|
378
|
+
applyRTLToContent();
|
|
165
379
|
} else {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (!el.closest('#rtl-toggle-btn')) {
|
|
172
|
-
el.removeAttribute('dir');
|
|
173
|
-
}
|
|
380
|
+
document.body.classList.remove('rtl-active');
|
|
381
|
+
// Remove all dir attributes when disabled
|
|
382
|
+
document.querySelectorAll('[dir="rtl"].rtl-processed').forEach(el => {
|
|
383
|
+
el.removeAttribute('dir');
|
|
384
|
+
el.classList.remove('rtl-processed');
|
|
174
385
|
});
|
|
175
386
|
}
|
|
176
387
|
|
|
177
388
|
console.log('RTL_CONFIG_SAVE:' + JSON.stringify({ enabled: rtlEnabled }));
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
document.body.appendChild(btn);
|
|
389
|
+
});
|
|
181
390
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
391
|
+
// Keyboard shortcut
|
|
392
|
+
document.addEventListener('keydown', (e) => {
|
|
393
|
+
if (e.altKey && e.code === 'KeyR') {
|
|
394
|
+
e.preventDefault();
|
|
395
|
+
document.getElementById('rtl-toggle').click();
|
|
396
|
+
}
|
|
397
|
+
});
|
|
185
398
|
})();
|
|
186
399
|
`).catch(err => console.error('[RTL] Injection failed:', err));
|
|
187
400
|
|