antigravity-rtl-patcher 2.3.1 → 2.3.2

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/bin/cli.js CHANGED
@@ -5,13 +5,13 @@ const chalk = require('chalk');
5
5
  const { patch, restore, status } = require('../src/patcher');
6
6
 
7
7
  const BANNER = `
8
- ${chalk.cyan('Antigravity Smart RTL Patcher')} ${chalk.gray('v2.3.1')}
8
+ ${chalk.cyan('Antigravity Smart RTL Patcher')} ${chalk.gray('v2.3.2')}
9
9
  `;
10
10
 
11
11
  program
12
12
  .name('agy-rtl')
13
13
  .description('RTL patcher for Antigravity')
14
- .version('2.3.1');
14
+ .version('2.3.2');
15
15
 
16
16
  program
17
17
  .command('patch')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antigravity-rtl-patcher",
3
- "version": "2.3.1",
3
+ "version": "2.3.2",
4
4
  "description": "Smart RTL and Persian/Arabic typography patcher for Antigravity",
5
5
  "main": "src/patcher.js",
6
6
  "bin": {
@@ -237,16 +237,42 @@ function _agyRtlRendererMain() {
237
237
  var alpha = text.replace(/[\s\d\W]/g, '').length;
238
238
  return alpha > 0 && (m.length / alpha) >= MIN_RTL_RATIO;
239
239
  }
240
+ var INLINE_TAGS = ['SPAN', 'A', 'STRONG', 'B', 'EM', 'I', 'CODE', 'MARK', 'LABEL', 'BR', 'KBD', 'S', 'STRIKE', 'U', 'SUB', 'SUP'];
241
+ var TEXT_BLOCKS = ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'BLOCKQUOTE', 'LI', 'TD', 'TH', 'BUTTON', 'TEXTAREA', 'INPUT'];
242
+
243
+ function isTextContainer(el) {
244
+ if (!el || el.nodeType !== 1) return false;
245
+ var tag = el.tagName.toUpperCase();
246
+ if (TEXT_BLOCKS.indexOf(tag) !== -1) return true;
247
+
248
+ // For DIVs and others, they are considered text containers ONLY if they
249
+ // don't contain any structural/block children (like SVG, IMG, DIV, P, UL).
250
+ // This prevents RTL-ing flex containers like sidebars.
251
+ var hasInlineOrText = false;
252
+ for (var i = 0; i < el.childNodes.length; i++) {
253
+ var child = el.childNodes[i];
254
+ if (child.nodeType === 3) {
255
+ if (child.nodeValue.trim().length > 0) hasInlineOrText = true;
256
+ } else if (child.nodeType === 1) {
257
+ if (INLINE_TAGS.indexOf(child.tagName.toUpperCase()) === -1) {
258
+ return false; // Found a block-level child, this is a structural container!
259
+ }
260
+ hasInlineOrText = true;
261
+ }
262
+ }
263
+ return hasInlineOrText;
264
+ }
265
+
240
266
  function applyRTL(el) {
241
267
  if (el.getAttribute(PROCESSED_ATTR)) return;
242
268
  // Skip the RTL panel/icon itself
243
269
  if (el.closest && (el.closest('#' + PANEL_ID) || el.closest('#' + STATUS_ICON_ID))) return;
244
- var directText = Array.from(el.childNodes)
245
- .filter(n => n.nodeType === Node.TEXT_NODE)
246
- .map(n => n.textContent)
247
- .join(' ');
248
- if (directText.trim().length > 0 && isRTL(directText)) {
249
- el.setAttribute(PROCESSED_ATTR, 'true');
270
+
271
+ if (isTextContainer(el)) {
272
+ var text = el.textContent || '';
273
+ if (text.trim().length > 0 && isRTL(text)) {
274
+ el.setAttribute(PROCESSED_ATTR, 'true');
275
+ }
250
276
  }
251
277
  }
252
278
  function removeRTL(el) {
@@ -256,12 +282,8 @@ function _agyRtlRendererMain() {
256
282
  }
257
283
  }
258
284
 
259
- // Wide selectors — catch all text-bearing elements
260
- var SELECTORS = [
261
- 'p', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
262
- 'blockquote', 'td', 'th', 'span', 'a', 'label',
263
- 'button',
264
- ].join(',');
285
+ // Broad selectors — we use isTextContainer to filter them safely
286
+ var SELECTORS = 'div, p, li, h1, h2, h3, h4, h5, h6, blockquote, td, th, span, a, label, button';
265
287
 
266
288
  function scanElement(root) {
267
289
  if (!root || root.nodeType !== 1) return;