antigravity-rtl-patcher 2.2.0 → 2.2.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antigravity-rtl-patcher",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "Smart RTL and Persian/Arabic typography patcher for Antigravity",
5
5
  "main": "src/patcher.js",
6
6
  "bin": {
@@ -6,12 +6,8 @@
6
6
  * MARKER: __AGY_RTL_INJECTED__
7
7
  */
8
8
  (function _agyRtlPreloadInit() {
9
- // Only run in renderer context
10
9
  if (typeof document === 'undefined') {
11
- // We're in the preload context before DOM exists.
12
- // Schedule injection for when the page actually loads.
13
10
  const { webFrame } = require('electron');
14
-
15
11
  webFrame.executeJavaScript(`(${_agyRtlRendererMain.toString()})();`);
16
12
  return;
17
13
  }
@@ -21,38 +17,20 @@
21
17
  function _agyRtlRendererMain() {
22
18
  'use strict';
23
19
 
24
- // Prevent double injection
25
20
  if (window.__AGY_RTL_LOADED__) return;
26
21
  window.__AGY_RTL_LOADED__ = true;
27
22
 
28
- // ─── Configuration ───────────────────────────────────────
23
+ // ─── Config ──────────────────────────────────────────────
29
24
  var STORAGE_KEY = 'agy-rtl-enabled';
30
25
  var PANEL_ID = 'agy-rtl-panel';
31
26
  var TOGGLE_BTN_ID = 'agy-rtl-toggle-btn';
32
27
  var STATUS_ICON_ID = 'agy-rtl-status-icon';
33
28
  var GITHUB_URL = 'https://github.com/VaFa1726/antigravity-rtl-patcher';
29
+ var PROCESSED_ATTR = 'data-agy-rtl';
34
30
 
35
- // RTL detection
36
31
  var RTL_REGEX = /[\u0591-\u07FF\u200F\u202B\u202E\uFB1D-\uFDFD\uFE70-\uFEFC]/;
37
32
  var RTL_CHAR_REGEX = /[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]/g;
38
33
  var MIN_RTL_RATIO = 0.3;
39
- var PROCESSED_ATTR = 'data-agy-rtl';
40
-
41
- var TARGET_SELECTORS = [
42
- 'p', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'td', 'th',
43
- '.chat-response-content p', '.chat-response-content li',
44
- '.chat-response-content h1', '.chat-response-content h2',
45
- '.chat-response-content h3', '.chat-response-content h4',
46
- '.chat-response-content blockquote',
47
- '.markdown-body p', '.markdown-body li',
48
- '.markdown-body h1', '.markdown-body h2',
49
- '.markdown-body h3', '.markdown-body blockquote',
50
- '.rendered-markdown p', '.rendered-markdown li',
51
- '.rendered-markdown h1', '.rendered-markdown h2',
52
- '.rendered-markdown h3', '.rendered-markdown blockquote',
53
- '.monaco-hover-content p', '.suggest-details p',
54
- '.notification-toast-container p',
55
- ].join(', ');
56
34
 
57
35
  // ─── State ───────────────────────────────────────────────
58
36
  var isEnabled = getStoredState();
@@ -60,52 +38,219 @@ function _agyRtlRendererMain() {
60
38
  var panelVisible = false;
61
39
 
62
40
  // ─── CSS ─────────────────────────────────────────────────
63
- var CSS = [
64
- '@import url("https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;700&display=swap");',
65
- '[data-agy-rtl="true"]{font-family:"Vazirmatn",system-ui,-apple-system,"Segoe UI",sans-serif!important;line-height:1.85!important;word-spacing:.02em}',
66
- '[data-agy-rtl="true"] code,[data-agy-rtl="true"] pre,[data-agy-rtl="true"] .monaco-tokenized-source{direction:ltr!important;text-align:left!important;unicode-bidi:isolate!important;font-family:"Cascadia Code","Fira Code","JetBrains Mono",Consolas,monospace!important;display:inline-block}',
67
- '[data-agy-rtl="true"] code{margin:0 3px;padding:1px 5px;border-radius:3px}',
68
- '[data-agy-rtl="true"] li{list-style-position:inside}',
69
- // Status icon
70
- '.agy-rtl-status-icon{position:fixed;bottom:0;right:60px;z-index:99999;display:flex;align-items:center;justify-content:center;width:32px;height:22px;cursor:pointer;color:#ccc;opacity:.85;transition:opacity .2s,color .2s,background .15s;border-radius:3px 3px 0 0;user-select:none;-webkit-user-select:none;background:rgba(0,0,0,.25)}',
71
- '.agy-rtl-status-icon:hover{opacity:1;color:#fff;background:rgba(255,255,255,.12)}',
72
- '.agy-rtl-status-dot{position:absolute;top:2px;right:2px;width:6px;height:6px;border-radius:50%;background:#666;transition:background .3s,box-shadow .3s}',
73
- '.agy-rtl-status-dot.active{background:#4caf50;box-shadow:0 0 4px rgba(76,175,80,.6)}',
74
- // Panel
75
- '.agy-rtl-panel{position:fixed;z-index:100000;min-width:260px;max-width:300px;background:#252526;border:1px solid #454545;border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.45),0 2px 8px rgba(0,0,0,.2);padding:16px;opacity:0;visibility:hidden;transform:translateY(8px) scale(.96);transition:opacity .2s,transform .2s,visibility .2s;font-family:-apple-system,"Segoe UI",system-ui,sans-serif;font-size:13px;color:#ccc}',
76
- '.agy-rtl-panel.visible{opacity:1;visibility:visible;transform:translateY(0) scale(1)}',
77
- '.agy-rtl-panel-header{margin-bottom:14px;padding-bottom:10px;border-bottom:1px solid #3a3a3a}',
78
- '.agy-rtl-panel-title{font-size:14px;font-weight:600;color:#e0e0e0;letter-spacing:-.01em}',
79
- '.agy-rtl-panel-row{display:flex;align-items:center;justify-content:space-between;padding:6px 0}',
80
- '.agy-rtl-panel-label{font-size:13px;color:#ccc}',
81
- '.agy-rtl-panel-sep{height:1px;background:#3a3a3a;margin:8px 0}',
82
- // Toggle switch
83
- '.agy-rtl-switch{position:relative;display:inline-block;width:40px;height:22px;cursor:pointer;flex-shrink:0}',
84
- '.agy-rtl-switch input{opacity:0;width:0;height:0;position:absolute}',
85
- '.agy-rtl-slider{position:absolute;inset:0;background:#555;border-radius:22px;transition:background .25s,box-shadow .25s}',
86
- '.agy-rtl-slider::before{content:"";position:absolute;width:16px;height:16px;left:3px;bottom:3px;background:#fff;border-radius:50%;transition:transform .25s;box-shadow:0 1px 3px rgba(0,0,0,.3)}',
87
- '.agy-rtl-switch input:checked+.agy-rtl-slider{background:#4b9cf5;box-shadow:0 0 8px rgba(75,156,245,.3)}',
88
- '.agy-rtl-switch input:checked+.agy-rtl-slider::before{transform:translateX(18px)}',
89
- // GitHub link
90
- '.agy-rtl-panel-gh{justify-content:center;padding-top:4px}',
91
- '.agy-rtl-gh-link{display:inline-flex;align-items:center;gap:6px;color:#9cdcfe;text-decoration:none;font-size:12px;opacity:.8;transition:opacity .2s}',
92
- '.agy-rtl-gh-link:hover{opacity:1;text-decoration:underline}',
93
- ].join('\n');
41
+ var CSS = `
42
+ @import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;700&display=swap');
43
+
44
+ /* === Global RTL Mode === */
45
+ html.agy-rtl-active {
46
+ direction: rtl !important;
47
+ }
48
+ html.agy-rtl-active body {
49
+ direction: rtl !important;
50
+ text-align: right !important;
51
+ }
52
+
53
+ /* Keep code and technical elements LTR */
54
+ html.agy-rtl-active code,
55
+ html.agy-rtl-active pre,
56
+ html.agy-rtl-active .monaco-editor,
57
+ html.agy-rtl-active .monaco-tokenized-source,
58
+ html.agy-rtl-active [class*="CodeMirror"],
59
+ html.agy-rtl-active input[type="text"],
60
+ html.agy-rtl-active input[type="url"],
61
+ html.agy-rtl-active input[type="email"],
62
+ html.agy-rtl-active textarea.inputarea,
63
+ html.agy-rtl-active .terminal,
64
+ html.agy-rtl-active .xterm {
65
+ direction: ltr !important;
66
+ text-align: left !important;
67
+ unicode-bidi: isolate !important;
68
+ }
69
+
70
+ /* Font for RTL text */
71
+ html.agy-rtl-active [${PROCESSED_ATTR}="true"] {
72
+ font-family: 'Vazirmatn', system-ui, -apple-system, 'Segoe UI', sans-serif !important;
73
+ line-height: 1.85 !important;
74
+ word-spacing: 0.02em;
75
+ }
76
+
77
+ /* Preserve code inside RTL blocks */
78
+ [${PROCESSED_ATTR}="true"] code,
79
+ [${PROCESSED_ATTR}="true"] pre {
80
+ direction: ltr !important;
81
+ text-align: left !important;
82
+ unicode-bidi: isolate !important;
83
+ font-family: 'Cascadia Code', 'Fira Code', 'JetBrains Mono', Consolas, monospace !important;
84
+ display: inline-block;
85
+ }
86
+ [${PROCESSED_ATTR}="true"] code {
87
+ margin: 0 3px;
88
+ padding: 1px 5px;
89
+ border-radius: 3px;
90
+ }
91
+ [${PROCESSED_ATTR}="true"] li {
92
+ list-style-position: inside;
93
+ }
94
+
95
+ /* === Status Bar Icon === */
96
+ .agy-rtl-status-icon {
97
+ position: fixed;
98
+ bottom: 2px;
99
+ right: 70px;
100
+ z-index: 99999;
101
+ display: flex;
102
+ align-items: center;
103
+ justify-content: center;
104
+ gap: 4px;
105
+ height: 20px;
106
+ padding: 0 8px;
107
+ cursor: pointer;
108
+ border-radius: 3px;
109
+ user-select: none;
110
+ -webkit-user-select: none;
111
+ transition: background .15s, opacity .15s;
112
+ opacity: .75;
113
+ font-family: -apple-system, 'Segoe UI', system-ui, sans-serif;
114
+ font-size: 11px;
115
+ font-weight: 500;
116
+ letter-spacing: .02em;
117
+ color: #999;
118
+ background: transparent;
119
+ }
120
+ .agy-rtl-status-icon:hover {
121
+ opacity: 1;
122
+ background: rgba(255,255,255,.08);
123
+ color: #ddd;
124
+ }
125
+ .agy-rtl-status-icon.active {
126
+ color: #6cb6ff;
127
+ opacity: .9;
128
+ }
129
+ .agy-rtl-status-icon.active:hover {
130
+ opacity: 1;
131
+ color: #8ecaff;
132
+ }
133
+ .agy-rtl-status-icon svg {
134
+ flex-shrink: 0;
135
+ }
136
+
137
+ /* === Panel === */
138
+ .agy-rtl-panel {
139
+ position: fixed;
140
+ z-index: 100000;
141
+ width: 280px;
142
+ background: #1e1e1e;
143
+ border: 1px solid #383838;
144
+ border-radius: 10px;
145
+ box-shadow: 0 12px 40px rgba(0,0,0,.5), 0 0 0 1px rgba(255,255,255,.04);
146
+ padding: 0;
147
+ opacity: 0;
148
+ visibility: hidden;
149
+ transform: translateY(6px);
150
+ transition: opacity .18s ease, transform .18s ease, visibility .18s ease;
151
+ font-family: -apple-system, 'Segoe UI', system-ui, sans-serif;
152
+ font-size: 13px;
153
+ color: #ccc;
154
+ overflow: hidden;
155
+ }
156
+ .agy-rtl-panel.visible {
157
+ opacity: 1;
158
+ visibility: visible;
159
+ transform: translateY(0);
160
+ }
161
+ .agy-rtl-panel-header {
162
+ padding: 14px 16px 12px;
163
+ background: rgba(255,255,255,.03);
164
+ border-bottom: 1px solid #2a2a2a;
165
+ }
166
+ .agy-rtl-panel-title {
167
+ font-size: 13px;
168
+ font-weight: 600;
169
+ color: #e0e0e0;
170
+ }
171
+ .agy-rtl-panel-body {
172
+ padding: 8px 16px 12px;
173
+ }
174
+ .agy-rtl-panel-row {
175
+ display: flex;
176
+ align-items: center;
177
+ justify-content: space-between;
178
+ padding: 8px 0;
179
+ }
180
+ .agy-rtl-panel-label {
181
+ font-size: 13px;
182
+ color: #b0b0b0;
183
+ }
184
+ .agy-rtl-panel-sep {
185
+ height: 1px;
186
+ background: #2a2a2a;
187
+ margin: 4px 0;
188
+ }
189
+
190
+ /* Toggle */
191
+ .agy-rtl-switch {
192
+ position: relative;
193
+ display: inline-block;
194
+ width: 36px;
195
+ height: 20px;
196
+ cursor: pointer;
197
+ flex-shrink: 0;
198
+ }
199
+ .agy-rtl-switch input { opacity: 0; width: 0; height: 0; position: absolute; }
200
+ .agy-rtl-slider {
201
+ position: absolute;
202
+ inset: 0;
203
+ background: #444;
204
+ border-radius: 20px;
205
+ transition: background .2s;
206
+ }
207
+ .agy-rtl-slider::before {
208
+ content: '';
209
+ position: absolute;
210
+ width: 14px;
211
+ height: 14px;
212
+ left: 3px;
213
+ bottom: 3px;
214
+ background: #fff;
215
+ border-radius: 50%;
216
+ transition: transform .2s;
217
+ box-shadow: 0 1px 2px rgba(0,0,0,.3);
218
+ }
219
+ .agy-rtl-switch input:checked + .agy-rtl-slider {
220
+ background: #4b9cf5;
221
+ }
222
+ .agy-rtl-switch input:checked + .agy-rtl-slider::before {
223
+ transform: translateX(16px);
224
+ }
225
+
226
+ /* Footer */
227
+ .agy-rtl-panel-footer {
228
+ padding: 8px 16px;
229
+ background: rgba(255,255,255,.02);
230
+ border-top: 1px solid #2a2a2a;
231
+ text-align: center;
232
+ }
233
+ .agy-rtl-gh-link {
234
+ display: inline-flex;
235
+ align-items: center;
236
+ gap: 5px;
237
+ color: #6c7986;
238
+ text-decoration: none;
239
+ font-size: 11px;
240
+ transition: color .15s;
241
+ }
242
+ .agy-rtl-gh-link:hover { color: #9cdcfe; }
243
+ `;
94
244
 
95
245
  // ─── Helpers ─────────────────────────────────────────────
96
246
 
97
247
  function getStoredState() {
98
- try {
99
- var s = localStorage.getItem(STORAGE_KEY);
100
- return s === null ? true : s === 'true';
101
- } catch (e) { return true; }
248
+ try { var s = localStorage.getItem(STORAGE_KEY); return s === null ? true : s === 'true'; }
249
+ catch (e) { return true; }
102
250
  }
103
-
104
251
  function setStoredState(v) {
105
- try { localStorage.setItem(STORAGE_KEY, v ? 'true' : 'false'); }
106
- catch (e) { /* ignore */ }
252
+ try { localStorage.setItem(STORAGE_KEY, v ? 'true' : 'false'); } catch (e) {}
107
253
  }
108
-
109
254
  function isRTL(text) {
110
255
  if (!text || text.trim().length === 0) return false;
111
256
  if (!RTL_REGEX.test(text)) return false;
@@ -114,32 +259,28 @@ function _agyRtlRendererMain() {
114
259
  var alpha = text.replace(/[\s\d\W]/g, '').length;
115
260
  return alpha > 0 && (m.length / alpha) >= MIN_RTL_RATIO;
116
261
  }
117
-
118
262
  function applyRTL(el) {
119
263
  if (el.getAttribute(PROCESSED_ATTR)) return;
120
264
  if (isRTL(el.textContent || '')) {
121
265
  el.setAttribute(PROCESSED_ATTR, 'true');
122
- el.style.direction = 'rtl';
123
- el.style.textAlign = 'start';
124
266
  el.style.unicodeBidi = 'plaintext';
125
267
  }
126
268
  }
127
-
128
269
  function removeRTL(el) {
129
270
  if (el.getAttribute(PROCESSED_ATTR)) {
130
271
  el.removeAttribute(PROCESSED_ATTR);
131
- el.style.direction = '';
132
- el.style.textAlign = '';
133
272
  el.style.unicodeBidi = '';
134
273
  }
135
274
  }
136
275
 
276
+ // Target all text-bearing elements
277
+ var SELECTORS = 'p,li,h1,h2,h3,h4,h5,h6,blockquote,td,th,span,div,a,label,button,[class*="title"],[class*="label"],[class*="name"],[class*="text"],[class*="message"],[class*="content"],[class*="description"]';
278
+
137
279
  function scanElement(root) {
138
280
  if (!root || root.nodeType !== 1) return;
139
- try { if (root.matches && root.matches(TARGET_SELECTORS)) applyRTL(root); } catch (e) {}
140
- try { root.querySelectorAll(TARGET_SELECTORS).forEach(applyRTL); } catch (e) {}
281
+ try { if (root.matches && root.matches(SELECTORS)) applyRTL(root); } catch (e) {}
282
+ try { root.querySelectorAll(SELECTORS).forEach(applyRTL); } catch (e) {}
141
283
  }
142
-
143
284
  function clearAllRTL() {
144
285
  try { document.querySelectorAll('[' + PROCESSED_ATTR + ']').forEach(removeRTL); } catch (e) {}
145
286
  }
@@ -148,6 +289,9 @@ function _agyRtlRendererMain() {
148
289
 
149
290
  function startObserver() {
150
291
  if (observer) return;
292
+ // Apply global RTL
293
+ document.documentElement.classList.add('agy-rtl-active');
294
+
151
295
  observer = new MutationObserver(function (muts) {
152
296
  if (!isEnabled) return;
153
297
  muts.forEach(function (m) {
@@ -161,6 +305,7 @@ function _agyRtlRendererMain() {
161
305
 
162
306
  function stopObserver() {
163
307
  if (observer) { observer.disconnect(); observer = null; }
308
+ document.documentElement.classList.remove('agy-rtl-active');
164
309
  clearAllRTL();
165
310
  }
166
311
 
@@ -168,10 +313,10 @@ function _agyRtlRendererMain() {
168
313
 
169
314
  function injectCSS() {
170
315
  if (document.getElementById('agy-rtl-styles')) return;
171
- var style = document.createElement('style');
172
- style.id = 'agy-rtl-styles';
173
- style.textContent = CSS;
174
- (document.head || document.documentElement).appendChild(style);
316
+ var s = document.createElement('style');
317
+ s.id = 'agy-rtl-styles';
318
+ s.textContent = CSS;
319
+ (document.head || document.documentElement).appendChild(s);
175
320
  }
176
321
 
177
322
  function createStatusIcon() {
@@ -179,36 +324,45 @@ function _agyRtlRendererMain() {
179
324
 
180
325
  var icon = document.createElement('div');
181
326
  icon.id = STATUS_ICON_ID;
182
- icon.className = 'agy-rtl-status-icon';
327
+ icon.className = 'agy-rtl-status-icon' + (isEnabled ? ' active' : '');
183
328
  icon.setAttribute('title', 'Antigravity Smart RTL');
184
329
 
330
+ // Globe + arrow SVG icon
185
331
  var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
186
- svg.setAttribute('width', '16');
187
- svg.setAttribute('height', '16');
332
+ svg.setAttribute('width', '14');
333
+ svg.setAttribute('height', '14');
188
334
  svg.setAttribute('viewBox', '0 0 24 24');
189
335
  svg.setAttribute('fill', 'none');
190
336
  svg.setAttribute('stroke', 'currentColor');
191
- svg.setAttribute('stroke-width', '2');
337
+ svg.setAttribute('stroke-width', '1.8');
192
338
  svg.setAttribute('stroke-linecap', 'round');
193
339
  svg.setAttribute('stroke-linejoin', 'round');
194
340
 
195
- var p1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
196
- p1.setAttribute('d', 'M16 4H9.5a3.5 3.5 0 1 0 0 7H12');
197
- svg.appendChild(p1);
198
- var l1 = document.createElementNS('http://www.w3.org/2000/svg', 'line');
199
- l1.setAttribute('x1', '12'); l1.setAttribute('y1', '4');
200
- l1.setAttribute('x2', '12'); l1.setAttribute('y2', '20');
201
- svg.appendChild(l1);
202
- var l2 = document.createElementNS('http://www.w3.org/2000/svg', 'line');
203
- l2.setAttribute('x1', '16'); l2.setAttribute('y1', '4');
204
- l2.setAttribute('x2', '16'); l2.setAttribute('y2', '20');
205
- svg.appendChild(l2);
341
+ // Globe circle
342
+ var circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
343
+ circle.setAttribute('cx', '12');
344
+ circle.setAttribute('cy', '12');
345
+ circle.setAttribute('r', '10');
346
+ svg.appendChild(circle);
347
+
348
+ // Globe horizontal line
349
+ var line1 = document.createElementNS('http://www.w3.org/2000/svg', 'line');
350
+ line1.setAttribute('x1', '2'); line1.setAttribute('y1', '12');
351
+ line1.setAttribute('x2', '22'); line1.setAttribute('y2', '12');
352
+ svg.appendChild(line1);
353
+
354
+ // Globe vertical ellipse
355
+ var ellipse = document.createElementNS('http://www.w3.org/2000/svg', 'path');
356
+ ellipse.setAttribute('d', 'M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z');
357
+ svg.appendChild(ellipse);
206
358
 
207
359
  icon.appendChild(svg);
208
360
 
209
- var dot = document.createElement('span');
210
- dot.className = 'agy-rtl-status-dot' + (isEnabled ? ' active' : '');
211
- icon.appendChild(dot);
361
+ // Label text
362
+ var lbl = document.createElement('span');
363
+ lbl.textContent = 'RTL';
364
+ lbl.style.cssText = 'direction:ltr!important;';
365
+ icon.appendChild(lbl);
212
366
 
213
367
  icon.addEventListener('click', function (e) { e.stopPropagation(); togglePanel(); });
214
368
  document.body.appendChild(icon);
@@ -220,6 +374,7 @@ function _agyRtlRendererMain() {
220
374
  var panel = document.createElement('div');
221
375
  panel.id = PANEL_ID;
222
376
  panel.className = 'agy-rtl-panel';
377
+ panel.style.cssText = 'direction:ltr!important;text-align:left!important;';
223
378
 
224
379
  // Header
225
380
  var header = document.createElement('div');
@@ -230,6 +385,10 @@ function _agyRtlRendererMain() {
230
385
  header.appendChild(title);
231
386
  panel.appendChild(header);
232
387
 
388
+ // Body
389
+ var body = document.createElement('div');
390
+ body.className = 'agy-rtl-panel-body';
391
+
233
392
  // Toggle row
234
393
  var row = document.createElement('div');
235
394
  row.className = 'agy-rtl-panel-row';
@@ -249,16 +408,12 @@ function _agyRtlRendererMain() {
249
408
  sw.appendChild(cb);
250
409
  sw.appendChild(slider);
251
410
  row.appendChild(sw);
252
- panel.appendChild(row);
253
-
254
- // Separator
255
- var sep = document.createElement('div');
256
- sep.className = 'agy-rtl-panel-sep';
257
- panel.appendChild(sep);
411
+ body.appendChild(row);
412
+ panel.appendChild(body);
258
413
 
259
- // GitHub link
260
- var ghRow = document.createElement('div');
261
- ghRow.className = 'agy-rtl-panel-row agy-rtl-panel-gh';
414
+ // Footer with GitHub
415
+ var footer = document.createElement('div');
416
+ footer.className = 'agy-rtl-panel-footer';
262
417
  var ghLink = document.createElement('a');
263
418
  ghLink.className = 'agy-rtl-gh-link';
264
419
  ghLink.href = GITHUB_URL;
@@ -266,20 +421,19 @@ function _agyRtlRendererMain() {
266
421
  ghLink.rel = 'noopener noreferrer';
267
422
 
268
423
  var ghSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
269
- ghSvg.setAttribute('width', '14');
270
- ghSvg.setAttribute('height', '14');
424
+ ghSvg.setAttribute('width', '12');
425
+ ghSvg.setAttribute('height', '12');
271
426
  ghSvg.setAttribute('viewBox', '0 0 16 16');
272
427
  ghSvg.setAttribute('fill', 'currentColor');
273
428
  var ghP = document.createElementNS('http://www.w3.org/2000/svg', 'path');
274
429
  ghP.setAttribute('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');
275
430
  ghSvg.appendChild(ghP);
276
431
  ghLink.appendChild(ghSvg);
277
-
278
432
  var ghText = document.createElement('span');
279
- ghText.textContent = ' Star on GitHub';
433
+ ghText.textContent = 'Star on GitHub';
280
434
  ghLink.appendChild(ghText);
281
- ghRow.appendChild(ghLink);
282
- panel.appendChild(ghRow);
435
+ footer.appendChild(ghLink);
436
+ panel.appendChild(footer);
283
437
 
284
438
  // Events
285
439
  cb.addEventListener('change', function () {
@@ -294,21 +448,22 @@ function _agyRtlRendererMain() {
294
448
  if (p && panelVisible && !p.contains(e.target) && !ic.contains(e.target)) hidePanel();
295
449
  });
296
450
 
451
+ document.addEventListener('keydown', function (e) {
452
+ if (e.key === 'Escape' && panelVisible) hidePanel();
453
+ });
454
+
297
455
  document.body.appendChild(panel);
298
456
  }
299
457
 
300
- function togglePanel() {
301
- panelVisible ? hidePanel() : showPanel();
302
- }
458
+ function togglePanel() { panelVisible ? hidePanel() : showPanel(); }
303
459
 
304
460
  function showPanel() {
305
461
  var panel = document.getElementById(PANEL_ID);
306
462
  if (!panel) { createPanel(); panel = document.getElementById(PANEL_ID); }
307
-
308
463
  var icon = document.getElementById(STATUS_ICON_ID);
309
464
  if (icon) {
310
465
  var r = icon.getBoundingClientRect();
311
- panel.style.bottom = (window.innerHeight - r.top + 8) + 'px';
466
+ panel.style.bottom = (window.innerHeight - r.top + 6) + 'px';
312
467
  panel.style.right = (window.innerWidth - r.right) + 'px';
313
468
  }
314
469
  panel.classList.add('visible');
@@ -322,10 +477,10 @@ function _agyRtlRendererMain() {
322
477
  }
323
478
 
324
479
  function updateState() {
325
- var dot = document.querySelector('.agy-rtl-status-dot');
326
- if (dot) {
327
- if (isEnabled) dot.classList.add('active');
328
- else dot.classList.remove('active');
480
+ var icon = document.getElementById(STATUS_ICON_ID);
481
+ if (icon) {
482
+ if (isEnabled) icon.classList.add('active');
483
+ else icon.classList.remove('active');
329
484
  }
330
485
  var cb = document.getElementById(TOGGLE_BTN_ID);
331
486
  if (cb) cb.checked = isEnabled;