cursorflow 2.7.5__py3-none-any.whl → 2.7.6__py3-none-any.whl
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.
- cursorflow/core/query_engine.py +85 -20
- {cursorflow-2.7.5.dist-info → cursorflow-2.7.6.dist-info}/METADATA +1 -1
- {cursorflow-2.7.5.dist-info → cursorflow-2.7.6.dist-info}/RECORD +7 -7
- {cursorflow-2.7.5.dist-info → cursorflow-2.7.6.dist-info}/WHEEL +0 -0
- {cursorflow-2.7.5.dist-info → cursorflow-2.7.6.dist-info}/entry_points.txt +0 -0
- {cursorflow-2.7.5.dist-info → cursorflow-2.7.6.dist-info}/licenses/LICENSE +0 -0
- {cursorflow-2.7.5.dist-info → cursorflow-2.7.6.dist-info}/top_level.txt +0 -0
cursorflow/core/query_engine.py
CHANGED
@@ -420,29 +420,90 @@ class QueryEngine:
|
|
420
420
|
|
421
421
|
# Phase 1: Enhanced DOM filtering
|
422
422
|
|
423
|
-
# Filter by selector (improved matching)
|
423
|
+
# Filter by selector (improved matching with correct field paths and priority)
|
424
424
|
if 'selector' in filters or 'select' in filters:
|
425
425
|
selector = filters.get('selector') or filters.get('select')
|
426
|
-
# Remove leading dot if present (e.g., ".class" -> "class")
|
427
|
-
selector_clean = selector.lstrip('.')
|
428
426
|
|
429
|
-
|
430
|
-
|
427
|
+
# Detect selector type
|
428
|
+
is_id_selector = selector.startswith('#')
|
429
|
+
is_class_selector = selector.startswith('.')
|
430
|
+
|
431
|
+
# Remove leading dot or hash if present (e.g., ".class" -> "class", "#id" -> "id")
|
432
|
+
selector_clean = selector.lstrip('.#')
|
433
|
+
|
434
|
+
# Determine if this looks like a simple tag name (no special characters)
|
435
|
+
is_simple_tag = selector.isalpha() and not is_id_selector and not is_class_selector
|
436
|
+
|
437
|
+
result_elements = []
|
438
|
+
for el in filtered_elements:
|
439
|
+
matched = False
|
440
|
+
|
441
|
+
# Priority 1: ID selector (#id) - only check ID field
|
442
|
+
if is_id_selector:
|
443
|
+
if selector_clean == el.get('id', ''):
|
444
|
+
result_elements.append(el)
|
445
|
+
continue
|
446
|
+
|
447
|
+
# Priority 2: Class selector (.class) - only check className
|
448
|
+
if is_class_selector:
|
449
|
+
if el.get('className'):
|
450
|
+
class_names = str(el.get('className')).split()
|
451
|
+
if selector_clean in class_names:
|
452
|
+
result_elements.append(el)
|
453
|
+
# Backward compatibility: Check classes array (old format)
|
454
|
+
elif selector_clean in el.get('classes', []):
|
455
|
+
result_elements.append(el)
|
456
|
+
continue
|
457
|
+
|
458
|
+
# Priority 3: For simple alphanumeric selectors, check tagName, ID, and className
|
459
|
+
# This handles ambiguous cases like "page" (could be tag or ID)
|
460
|
+
if is_simple_tag:
|
461
|
+
# Check tag name match (exact, case insensitive)
|
462
|
+
if selector.lower() == el.get('tagName', '').lower():
|
463
|
+
result_elements.append(el)
|
464
|
+
continue
|
465
|
+
|
466
|
+
# Check ID match (exact)
|
467
|
+
if selector_clean == el.get('id', ''):
|
468
|
+
result_elements.append(el)
|
469
|
+
continue
|
470
|
+
|
471
|
+
# Class name match (whole word match to avoid "a" matching "navbar")
|
472
|
+
if el.get('className'):
|
473
|
+
class_names = str(el.get('className')).split()
|
474
|
+
if selector_clean in class_names:
|
475
|
+
result_elements.append(el)
|
476
|
+
continue
|
477
|
+
|
478
|
+
# Backward compatibility: Check classes array (old format)
|
479
|
+
if selector_clean in el.get('classes', []):
|
480
|
+
result_elements.append(el)
|
481
|
+
|
482
|
+
# Don't fall through to selector string checks for simple tags
|
483
|
+
continue
|
484
|
+
|
485
|
+
# Priority 2: For complex selectors, check selector strings and attributes
|
431
486
|
if (
|
432
|
-
# Check
|
487
|
+
# Check selectors.unique_css (current format)
|
488
|
+
(selector in el.get('selectors', {}).get('unique_css', '')) or
|
489
|
+
# Check selectors.css (current format)
|
490
|
+
(selector in el.get('selectors', {}).get('css', '')) or
|
491
|
+
# Check selectors.xpath
|
492
|
+
(selector in el.get('selectors', {}).get('xpath', '')) or
|
493
|
+
# Check ID (exact match or contains for partial IDs)
|
494
|
+
(el.get('id') and selector_clean in str(el.get('id'))) or
|
495
|
+
# Check className (can be string or None)
|
496
|
+
(el.get('className') and selector_clean in str(el.get('className'))) or
|
497
|
+
# Backward compatibility: Check nested uniqueSelector (old format)
|
433
498
|
(selector in el.get('selectors', {}).get('uniqueSelector', '')) or
|
434
|
-
# Check top-level uniqueSelector (old format)
|
499
|
+
# Backward compatibility: Check top-level uniqueSelector (old format)
|
435
500
|
(selector in el.get('uniqueSelector', '')) or
|
436
|
-
# Check
|
437
|
-
(selector in el.get('tagName', '')) or
|
438
|
-
# Check ID
|
439
|
-
(selector == el.get('id', '')) or
|
440
|
-
# Check className string
|
441
|
-
(el.get('className') and selector_clean in el.get('className', '')) or
|
442
|
-
# Check classes array (old format)
|
501
|
+
# Backward compatibility: Check classes array (old format)
|
443
502
|
(selector_clean in el.get('classes', []))
|
444
|
-
)
|
445
|
-
|
503
|
+
):
|
504
|
+
result_elements.append(el)
|
505
|
+
|
506
|
+
filtered_elements = result_elements
|
446
507
|
|
447
508
|
# Filter by attributes
|
448
509
|
if 'with_attr' in filters:
|
@@ -460,18 +521,18 @@ class QueryEngine:
|
|
460
521
|
if el.get('accessibility', {}).get('role') == role
|
461
522
|
]
|
462
523
|
|
463
|
-
# Filter by visibility
|
524
|
+
# Filter by visibility (use correct nested path)
|
464
525
|
if 'visible' in filters and filters['visible']:
|
465
526
|
filtered_elements = [
|
466
527
|
el for el in filtered_elements
|
467
|
-
if el.get('visual_context', {}).get('
|
528
|
+
if el.get('visual_context', {}).get('visibility', {}).get('is_visible', False)
|
468
529
|
]
|
469
530
|
|
470
|
-
# Filter by interactivity
|
531
|
+
# Filter by interactivity (use correct nested path)
|
471
532
|
if 'interactive' in filters and filters['interactive']:
|
472
533
|
filtered_elements = [
|
473
534
|
el for el in filtered_elements
|
474
|
-
if el.get('accessibility', {}).get('
|
535
|
+
if el.get('accessibility', {}).get('is_interactive', False)
|
475
536
|
]
|
476
537
|
|
477
538
|
# Filter elements with errors (from console errors)
|
@@ -958,6 +1019,10 @@ class QueryEngine:
|
|
958
1019
|
elif format == "csv":
|
959
1020
|
return self._to_csv(data, data_type)
|
960
1021
|
|
1022
|
+
elif format == "dict" or format == "raw":
|
1023
|
+
# Return raw dictionary (useful for programmatic access)
|
1024
|
+
return data
|
1025
|
+
|
961
1026
|
else:
|
962
1027
|
return data
|
963
1028
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: cursorflow
|
3
|
-
Version: 2.7.
|
3
|
+
Version: 2.7.6
|
4
4
|
Summary: 🔥 Complete page intelligence for AI-driven development with Hot Reload Intelligence - captures DOM, network, console, performance, HMR events, and comprehensive page analysis
|
5
5
|
Author-email: GeekWarrior Development <rbush@cooltheory.com>
|
6
6
|
License-Expression: MIT
|
@@ -26,7 +26,7 @@ cursorflow/core/log_monitor.py,sha256=pONMu_JHEnT0T62OA5KRZ4nClzKgNpifPyrfN5w_RM
|
|
26
26
|
cursorflow/core/mockup_comparator.py,sha256=ttcXdueZz9dwcUGBQ2sft4i66zRdkZkFPu41s6JlEwU,63472
|
27
27
|
cursorflow/core/output_manager.py,sha256=PT73Awq4htYVwbBN3EadXGvuy3Wreip0Y35sCg7Pz5s,28013
|
28
28
|
cursorflow/core/persistent_session.py,sha256=FsEHj4wKkycmdp6PFRHv3g333Y74yqra0x_qhUTQpik,36075
|
29
|
-
cursorflow/core/query_engine.py,sha256=
|
29
|
+
cursorflow/core/query_engine.py,sha256=lhsF0rUc86jJBYZBjx8fz5N8_BxhQhoeGgpO4w3kf00,58233
|
30
30
|
cursorflow/core/report_generator.py,sha256=-vosfyrnfVyWDbAIMlMurl90xOXqBae8d6aLd9sEqiY,10113
|
31
31
|
cursorflow/core/trace_manager.py,sha256=Jj9ultZrL1atiZXfcRVI6ynCnnfqZM-X0_taxt-llJ0,7189
|
32
32
|
cursorflow/log_sources/local_file.py,sha256=GVnhsaifIdc41twXwbxRM9-fBeRDsknDpk5IEGulnhQ,8318
|
@@ -34,9 +34,9 @@ cursorflow/log_sources/ssh_remote.py,sha256=_Kwh0bhRpKgq-0c98oaX2hN6h9cT-wCHlqY5
|
|
34
34
|
cursorflow/rules/__init__.py,sha256=gPcA-IkhXj03sl7cvZV0wwo7CtEkcyuKs4y0F5oQbqE,458
|
35
35
|
cursorflow/rules/cursorflow-installation.mdc,sha256=D55pzzDPAVVbE3gAtKPUGoT-2fvB-FI2l6yrTdzUIEo,10208
|
36
36
|
cursorflow/rules/cursorflow-usage.mdc,sha256=OYsqF1OKeGP5Bl8yR5TJ92dDXH7C3yp-SKAs9aZfBAw,34744
|
37
|
-
cursorflow-2.7.
|
38
|
-
cursorflow-2.7.
|
39
|
-
cursorflow-2.7.
|
40
|
-
cursorflow-2.7.
|
41
|
-
cursorflow-2.7.
|
42
|
-
cursorflow-2.7.
|
37
|
+
cursorflow-2.7.6.dist-info/licenses/LICENSE,sha256=e4QbjAsj3bW-xgQOvQelr8sGLYDoqc48k6cKgCr_pBU,1080
|
38
|
+
cursorflow-2.7.6.dist-info/METADATA,sha256=0_8B5N3kBPoAiRTCoz2lIdFrSiMLzAjeBeGYi59GVCs,19844
|
39
|
+
cursorflow-2.7.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
40
|
+
cursorflow-2.7.6.dist-info/entry_points.txt,sha256=-Ed_n4Uff7wClEtWS-Py6xmQabecB9f0QAOjX0w7ljA,51
|
41
|
+
cursorflow-2.7.6.dist-info/top_level.txt,sha256=t1UZwRyZP4u-ng2CEcNHmk_ZT4ibQxoihB2IjTF7ovc,11
|
42
|
+
cursorflow-2.7.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|