Skip to content

Add early click handling for WUBox and improve pre-commit hook#288

Merged
superdav42 merged 1 commit intomainfrom
feature/wubox-early-click-handling
Dec 9, 2025
Merged

Add early click handling for WUBox and improve pre-commit hook#288
superdav42 merged 1 commit intomainfrom
feature/wubox-early-click-handling

Conversation

@superdav42
Copy link
Collaborator

@superdav42 superdav42 commented Dec 7, 2025

Add Early Click Handling for WUBox and Improve Pre-Commit Hook

🎯 Overview

This PR includes two important improvements:

  1. WUBox early click handling - Prevents lost clicks on slow connections
  2. Enhanced pre-commit hook - Automatic PHPCBF fixing with better UX

🖱️ WUBox Early Click Handling

The Problem

Users clicking on .wubox elements before the script fully loads would experience:

  • ❌ Click being ignored
  • ❌ No visual feedback
  • ❌ Need to click again after page loads
  • ❌ Poor user experience on slow connections or heavy pages

The Solution

Implemented a two-phase early click capture system:

Phase 1: Inline Script (Before wubox.js loads)

File: inc/class-scripts.php

Added an inline script that runs immediately before wubox.js loads:

window.__wuboxEarlyClicks = [];
window.__wuboxEarlyClickHandler = function(e) {
    if (window.__wuboxReady) return;
    var t = e.target.closest('.wubox');
    if (!t) return;
    e.preventDefault();
    e.stopPropagation();
    t.style.cursor = 'wait';
    window.__wuboxEarlyClicks.push(t);
};
document.addEventListener('click', window.__wuboxEarlyClickHandler, true);

What it does:

  1. 🎣 Captures clicks on .wubox elements immediately
  2. 🛑 Prevents default action and event propagation
  3. Shows 'wait' cursor for instant visual feedback
  4. 📝 Queues clicked elements for later processing

Phase 2: Processing Queue (When wubox.js loads)

File: assets/js/wubox.js

When wubox.js loads and DOMContentLoaded fires:

window.__wuboxReady = true;

// Remove early click listener
if (window.__wuboxEarlyClickHandler) {
    document.removeEventListener('click', window.__wuboxEarlyClickHandler, true);
    delete window.__wuboxEarlyClickHandler;
}

// Process queued clicks
if (window.__wuboxEarlyClicks && window.__wuboxEarlyClicks.length > 0) {
    const uniqueClicks = [...new Set(window.__wuboxEarlyClicks)];
    uniqueClicks.forEach((target) => {
        const caption = target.title || target.name || '';
        const url = target.href || target.alt;
        const imageGroup = target.rel || false;
        target.style.cursor = '';
        window.wubox.show(caption, url, imageGroup);
    });
    window.__wuboxEarlyClicks = [];
}

What it does:

  1. Marks wubox as ready
  2. 🧹 Removes the early click listener (cleanup)
  3. 🔍 Deduplicates queued clicks
  4. Processes each unique click through wubox.show()
  5. 🎨 Restores cursor to normal

Benefits

No more lost clicks on slow connections
Immediate visual feedback with wait cursor
Automatic queue processing when ready
Prevents duplicate processing of same element
Clean cleanup of event listeners
Better user experience overall

Use Case

Perfect for:

  • 🌐 Slow network connections
  • 📱 Mobile devices
  • ⚡ Heavy pages with lots of scripts
  • 🎨 Image galleries with many thumbnails
  • 📊 Admin pages with complex UI

🔧 Pre-Commit Hook Improvements

File: .githooks/pre-commit

Enhanced auto-fixing capabilities for better developer experience

Before This Change:

  1. PHPCS finds errors ❌
  2. Shows error messages 📝
  3. Commit fails ⛔
  4. Developer manually runs PHPCBF 🔧
  5. Developer manually stages fixes 📤
  6. Developer tries commit again 🔄

After This Change:

  1. PHPCS finds errors ❌
  2. Automatically runs PHPCBF 🤖
  3. Re-stages fixed files
  4. Re-validates after fixes 🔍
  5. Only fails if errors still remain ⚠️
  6. Shows clear success/failure messages 📊

New Features

1. Auto-Fix Attempt

if [ $HAS_PHPCS_ERRORS -ne 0 ]; then
    echo "PHPCS found errors. Running PHPCBF to auto-fix..."
    vendor/bin/phpcbf "$FILE"
}

2. Smart Re-Staging

if vendor/bin/phpcs --colors "$FILE" 2>&1; then
    echo "✓ Auto-fixed: $FILE"
    git add "$FILE"  # Automatically stage the fixed file
fi

3. Clear Feedback

  • ✅ Green checkmarks for successfully fixed files
  • ❌ Red X for files that couldn't be auto-fixed
  • 📊 Summary of results

4. Re-Validation

After auto-fixing, re-runs PHPCS to check if all errors are resolved:

# Re-check if there are still errors after auto-fixing
HAS_PHPCS_ERRORS=0
for FILE in $STAGED_FILES; do
    vendor/bin/phpcs "$FILE" > /dev/null 2>&1 || HAS_PHPCS_ERRORS=1
done

Benefits

Fewer manual interventions needed
Faster commit workflow - no manual PHPCBF runs
Automatic compliance with coding standards
Better developer experience - less context switching
Clearer error reporting - know exactly what needs fixing


📁 Files Changed

WUBox Early Click Handling:

  1. inc/class-scripts.php - Added inline early click handler script
  2. assets/js/wubox.js - Added queue processing on DOMContentLoaded
  3. assets/js/wubox.min.js - Updated minified version

Pre-Commit Hook:

  1. .githooks/pre-commit - Enhanced with auto-fixing capabilities

Stats: +99 additions, -11 deletions


🎬 Demo Scenarios

Scenario 1: WUBox on Slow Connection

Before:

  1. User clicks image thumbnail
  2. Nothing happens (script not loaded yet)
  3. User clicks again
  4. Modal opens

After:

  1. User clicks image thumbnail
  2. Cursor changes to 'wait' ⏳
  3. Click is queued
  4. When script loads, modal opens automatically
  5. Cursor returns to normal

Scenario 2: Pre-Commit Hook

Before:

$ git commit -m "Fix bug"
Running PHPCS...
ERROR: Found 5 violations
Pre-commit checks failed!
$ vendor/bin/phpcbf file.php
$ git add file.php
$ git commit -m "Fix bug"

After:

$ git commit -m "Fix bug"
Running PHPCS...
ERROR: Found 5 violations
Running PHPCBF to auto-fix...
✓ Auto-fixed: file.php
All errors fixed automatically!
[main abc123] Fix bug

✨ Impact Summary

WUBox:

  • 🚀 Better performance on slow connections
  • 👆 No more lost clicks - every click counts
  • Visual feedback during loading
  • 🎯 Improved UX for all users

Pre-Commit Hook:

  • Faster workflow - automatic fixes
  • 🔧 Auto-compliance with coding standards
  • 📊 Clear feedback on what was fixed
  • 🎨 Better DX - fewer interruptions

🧪 Testing

Manual Testing - WUBox

  1. Throttle network to slow 3G
  2. Navigate to page with .wubox elements
  3. Click element immediately as page loads
  4. Verify cursor changes to 'wait'
  5. Verify modal opens when script loads

Manual Testing - Pre-Commit Hook

  1. Stage a PHP file with PHPCS violations
  2. Try to commit
  3. Verify PHPCBF runs automatically
  4. Verify file is re-staged
  5. Verify commit succeeds if all errors fixed

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced wubox lightbox component to properly handle clicks occurring before the script fully loads, ensuring user interactions are seamlessly queued and processed without loss.

✏️ Tip: You can customize this high-level summary in your review settings.

## WUBox Early Click Handling

### Problem
Users clicking on `.wubox` elements before the script fully loads would experience:
- Click being ignored
- No visual feedback
- Need to click again after page loads
- Poor user experience on slow connections

### Solution

Implemented a two-phase early click capture system:

#### Phase 1: Inline Script (inc/class-scripts.php)
Added an inline script that runs **before** wubox.js loads:

```javascript
window.__wuboxEarlyClicks = [];
window.__wuboxEarlyClickHandler = function(e) {
    if (window.__wuboxReady) return;
    var t = e.target.closest('.wubox');
    if (!t) return;
    e.preventDefault();
    e.stopPropagation();
    t.style.cursor = 'wait';
    window.__wuboxEarlyClicks.push(t);
};
document.addEventListener('click', window.__wuboxEarlyClickHandler, true);
```

**What it does:**
- Captures clicks on `.wubox` elements immediately
- Prevents default action and propagation
- Shows 'wait' cursor for visual feedback
- Queues clicked elements for later processing

#### Phase 2: Processing Queue (assets/js/wubox.js)
When wubox.js loads and DOMContentLoaded fires:

```javascript
window.__wuboxReady = true;

// Remove early click listener
if (window.__wuboxEarlyClickHandler) {
    document.removeEventListener('click', window.__wuboxEarlyClickHandler, true);
    delete window.__wuboxEarlyClickHandler;
}

// Process queued clicks
if (window.__wuboxEarlyClicks && window.__wuboxEarlyClicks.length > 0) {
    const uniqueClicks = [...new Set(window.__wuboxEarlyClicks)];
    uniqueClicks.forEach((target) => {
        const caption = target.title || target.name || '';
        const url = target.href || target.alt;
        const imageGroup = target.rel || false;
        target.style.cursor = '';
        window.wubox.show(caption, url, imageGroup);
    });
    window.__wuboxEarlyClicks = [];
}
```

**What it does:**
- Marks wubox as ready
- Removes the early click listener (no longer needed)
- Deduplicates queued clicks
- Processes each unique click through wubox.show()
- Restores cursor to normal

### Benefits
✅ No more lost clicks on slow connections
✅ Immediate visual feedback (wait cursor)
✅ Automatic queue processing when ready
✅ Prevents duplicate processing
✅ Clean cleanup of event listeners
✅ Better user experience

### Files Changed
1. **inc/class-scripts.php** - Added inline early click handler
2. **assets/js/wubox.js** - Added queue processing on DOMContentLoaded
3. **assets/js/wubox.min.js** - Minified version updated

---

## Pre-Commit Hook Improvements

### File: .githooks/pre-commit

**Enhanced auto-fixing capabilities:**

#### Before:
- PHPCS found errors
- Showed error messages
- Commit failed
- Manual fixing required

#### After:
- PHPCS finds errors
- **Automatically runs PHPCBF** to fix them
- **Re-stages fixed files**
- **Re-validates** after fixes
- Only fails if errors remain after auto-fix
- Shows clear success/failure messages

**New Features:**
1. **Auto-fix attempt**: Runs PHPCBF on files with PHPCS errors
2. **Smart re-staging**: Automatically stages files that were fixed
3. **Re-validation**: Checks if errors were resolved
4. **Clear feedback**: Shows which files were fixed vs. which still have issues
5. **Better UX**: Green checkmarks for fixed files, red X for unfixable errors

**Code Example:**
```bash
if [ $HAS_PHPCS_ERRORS -ne 0 ]; then
    echo "PHPCS found errors. Running PHPCBF to auto-fix..."

    for FILE in $PHPCS_FAILED_FILES; do
        vendor/bin/phpcbf "$FILE" || true

        if vendor/bin/phpcs --colors "$FILE" 2>&1; then
            echo "✓ Auto-fixed: $FILE"
            git add "$FILE"  # Re-stage the fixed file
        else
            echo "✗ Could not fully fix: $FILE"
        fi
    done
}
```

**Benefits:**
✅ Fewer manual interventions needed
✅ Faster commit workflow
✅ Automatic compliance with coding standards
✅ Better developer experience
✅ Clearer error reporting

---

## Impact Summary

### WUBox:
- 🚀 Better performance on slow connections
- 👆 No more lost clicks
- ⏳ Visual feedback during loading
- 🎯 Improved user experience

### Pre-Commit Hook:
- ⚡ Faster commit workflow
- 🔧 Automatic code standard fixes
- 📊 Clear feedback on what was fixed
- 🎨 Better developer experience

---

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 7, 2025

Walkthrough

Three files were modified to enhance developer tooling and improve wubox click handling. The pre-commit hook now tracks PHPCS failures, auto-fixes them with PHPCBF, re-scans fixed files, and narrows PHPStan analysis to staged files only. An early-click queueing system was added to handle clicks on wubox elements before the script fully loads.

Changes

Cohort / File(s) Summary
Pre-commit hook enhancements
.githooks/pre-commit
PHPCS flow now tracks failing files, invokes PHPCBF for auto-fixes, re-scans fixed files, and stages successful corrections. PHPStan scope narrowed to staged files in inc/ directory only. Enhanced user feedback for auto-fix results and remaining errors.
Early-click queueing system
inc/class-scripts.php, assets/js/wubox.js
Inline script in class-scripts.php initializes global handler to queue clicks on .wubox elements before script readiness, preventing default behavior and visual feedback. Main wubox.js processes queued clicks on DOMContentLoaded, deduplicates targets, and triggers show sequentially.

Sequence Diagram

sequenceDiagram
    participant User
    participant DOM as Document (early)
    participant InlineScript as Inline Script<br/>(class-scripts.php)
    participant WuboxJS as wubox.js
    participant Window as Window Globals

    Note over DOM,Window: Before wubox.js loads

    User->>DOM: Click .wubox element
    DOM->>InlineScript: Capture phase listener
    InlineScript->>InlineScript: preventDefault()<br/>stopPropagation()
    InlineScript->>InlineScript: Set cursor: wait
    InlineScript->>Window: Queue target in<br/>__wuboxEarlyClicks
    
    Note over DOM,Window: wubox.js loads

    WuboxJS->>Window: DOMContentLoaded fires
    WuboxJS->>Window: Mark wubox as ready
    WuboxJS->>Window: Remove early listener
    WuboxJS->>Window: Deduplicate queue
    loop For each queued target
        WuboxJS->>WuboxJS: Trigger show(target)
    end
    WuboxJS->>Window: Clear queue
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pre-commit hook changes: Review the PHPCS auto-fix loop logic, PHPCBF invocation per file, re-scan logic, and PHPStan scope narrowing to ensure proper error handling and file staging.
  • Early-click queueing system: Verify the cross-file interaction between the inline script initialization and wubox.js queue processing; confirm deduplication logic and event listener cleanup to prevent memory leaks or duplicate handler registrations.
  • Event handler scope: Ensure the capture-phase listener doesn't interfere with other document listeners or event handlers.

Poem

🐰 Early clicks? Don't fret, we've got your back,
Queued and waiting 'til the script's on track,
PHPCS fixes fly, PHPStan stays tight,
Pre-commit hooks running, automation's right!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately summarizes the two main changes: WUBox early click handling and pre-commit hook improvements, directly reflecting the core objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/wubox-early-click-handling

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
inc/class-scripts.php (1)

253-269: Consider adding a timeout fallback if wubox.js fails to load.

If the main wubox.js script fails to load (network error, blocked, etc.), the early click handler will remain attached indefinitely and clicked elements will be stuck with cursor: wait.

Consider adding a timeout to restore normal behavior:

 wp_add_inline_script(
     'wubox',
     "(function(){
         window.__wuboxEarlyClicks=[];
         window.__wuboxEarlyClickHandler=function(e){
             if(window.__wuboxReady)return;
             var t=e.target.closest('.wubox');
             if(!t)return;
             e.preventDefault();
             e.stopPropagation();
             t.style.cursor='wait';
             window.__wuboxEarlyClicks.push(t);
         };
         document.addEventListener('click',window.__wuboxEarlyClickHandler,true);
+        // Fallback: remove handler after 30s if wubox never loads
+        setTimeout(function(){
+            if(!window.__wuboxReady){
+                document.removeEventListener('click',window.__wuboxEarlyClickHandler,true);
+                window.__wuboxEarlyClicks.forEach(function(t){t.style.cursor='';});
+                window.__wuboxEarlyClicks=[];
+            }
+        },30000);
     })();",
     'before'
 );
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 165ab6e and 17620f2.

⛔ Files ignored due to path filters (1)
  • assets/js/wubox.min.js is excluded by !**/*.min.js
📒 Files selected for processing (3)
  • .githooks/pre-commit (2 hunks)
  • assets/js/wubox.js (2 hunks)
  • inc/class-scripts.php (1 hunks)
🔇 Additional comments (4)
assets/js/wubox.js (1)

447-472: LGTM on the early click processing logic.

The implementation correctly:

  • Marks wubox as ready to prevent further queuing
  • Removes the early click handler to clean up
  • Deduplicates queued elements by reference
  • Restores cursor and triggers the modal
inc/class-scripts.php (1)

249-269: Good implementation of early click capture.

The inline script correctly:

  • Uses an IIFE to avoid polluting the global scope unnecessarily
  • Attaches to the capture phase to intercept clicks before bubbling handlers
  • Uses closest('.wubox') for reliable element detection
  • Provides immediate visual feedback with cursor change
.githooks/pre-commit (2)

46-79: Good auto-fix workflow with re-staging.

The workflow correctly:

  • Attempts to auto-fix with PHPCBF
  • Verifies fixes by re-running PHPCS
  • Only stages files that are now clean
  • Provides clear feedback on what was fixed vs. what requires manual intervention

96-104: LGTM on error handling and user feedback.

The enhanced error messages provide clear guidance on:

  • Which checks failed
  • How to see remaining errors manually
  • How to bypass if needed

Comment on lines +36 to 44
PHPCS_FAILED_FILES=""
for FILE in $STAGED_FILES; do
if [ -f "$FILE" ]; then
vendor/bin/phpcs --colors "$FILE" || HAS_PHPCS_ERRORS=1
if ! vendor/bin/phpcs --colors "$FILE"; then
PHPCS_FAILED_FILES="$PHPCS_FAILED_FILES $FILE"
HAS_PHPCS_ERRORS=1
fi
fi
done
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Word splitting issue: filenames with spaces will break the loop.

The variable PHPCS_FAILED_FILES is built by string concatenation and later iterated with unquoted expansion. If any PHP filename contains spaces, it will be split incorrectly.

Consider using arrays instead:

 HAS_PHPCS_ERRORS=0
-PHPCS_FAILED_FILES=""
+PHPCS_FAILED_FILES=()
 for FILE in $STAGED_FILES; do
     if [ -f "$FILE" ]; then
         if ! vendor/bin/phpcs --colors "$FILE"; then
-            PHPCS_FAILED_FILES="$PHPCS_FAILED_FILES $FILE"
+            PHPCS_FAILED_FILES+=("$FILE")
             HAS_PHPCS_ERRORS=1
         fi
     fi
 done

And update the loop at line 51:

-    for FILE in $PHPCS_FAILED_FILES; do
+    for FILE in "${PHPCS_FAILED_FILES[@]}"; do
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
PHPCS_FAILED_FILES=""
for FILE in $STAGED_FILES; do
if [ -f "$FILE" ]; then
vendor/bin/phpcs --colors "$FILE" || HAS_PHPCS_ERRORS=1
if ! vendor/bin/phpcs --colors "$FILE"; then
PHPCS_FAILED_FILES="$PHPCS_FAILED_FILES $FILE"
HAS_PHPCS_ERRORS=1
fi
fi
done
PHPCS_FAILED_FILES=()
for FILE in $STAGED_FILES; do
if [ -f "$FILE" ]; then
if ! vendor/bin/phpcs --colors "$FILE"; then
PHPCS_FAILED_FILES+=("$FILE")
HAS_PHPCS_ERRORS=1
fi
fi
done
🤖 Prompt for AI Agents
.githooks/pre-commit around lines 36 to 44: the script builds PHPCS_FAILED_FILES
as a space-separated string which breaks on filenames with spaces; switch
PHPCS_FAILED_FILES to a bash array (initialize empty array), append failing
files with array syntax (e.g., PHPCS_FAILED_FILES+=("$FILE")), and later iterate
over the array using the proper indexed expansion (\"${PHPCS_FAILED_FILES[@]}\")
when processing at the later loop (around line 51).

Comment on lines +459 to +470
if (window.__wuboxEarlyClicks && window.__wuboxEarlyClicks.length > 0) {
// Remove duplicates - only keep unique elements
const uniqueClicks = [...new Set(window.__wuboxEarlyClicks)];

uniqueClicks.forEach((target) => {
const caption = target.title || target.name || '';
const url = target.href || target.alt;
const imageGroup = target.rel || false;
target.style.cursor = '';
window.wubox.show(caption, url, imageGroup);
});
window.__wuboxEarlyClicks = [];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Potential issue: Multiple modals may stack if multiple early clicks were captured.

If a user clicks multiple different .wubox elements before wubox loads, the forEach loop will call window.wubox.show() for each without waiting for the previous modal to close. This could result in stacked modals or visual glitches.

Consider processing only the first/last click, or ensuring previous modals are removed before showing the next:

     uniqueClicks.forEach((target) => {
       const caption = target.title || target.name || '';
       const url = target.href || target.alt;
       const imageGroup = target.rel || false;
-	  target.style.cursor = '';
+      target.style.cursor = '';
       window.wubox.show(caption, url, imageGroup);
     });

Alternatively, if only a single modal should be shown, consider processing only the last clicked element:

if (uniqueClicks.length > 0) {
  const target = uniqueClicks[uniqueClicks.length - 1];
  // restore cursors for all
  uniqueClicks.forEach(t => t.style.cursor = '');
  const caption = target.title || target.name || '';
  const url = target.href || target.alt;
  const imageGroup = target.rel || false;
  window.wubox.show(caption, url, imageGroup);
}
🤖 Prompt for AI Agents
In assets/js/wubox.js around lines 459 to 470, multiple early clicks are
iterated and window.wubox.show() is called for each, which can stack modals;
instead pick a single click to show (e.g., the last item), restore cursor styles
for all captured targets, then call window.wubox.show() only once for that
selected target and finally clear window.__wuboxEarlyClicks; if you prefer to
allow sequential shows, ensure you close any existing modal before calling show
(call window.wubox.close() if available) to prevent visual stacking.

@superdav42 superdav42 merged commit 6ad55ce into main Dec 9, 2025
10 checks passed
@superdav42 superdav42 deleted the feature/wubox-early-click-handling branch December 9, 2025 06:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant