Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 11 additions & 100 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -1,107 +1,18 @@
#!/bin/bash

# Pre-commit hook for running phpcs and phpstan on changed files
# This hook runs PHPCS and PHPStan on staged PHP files
# Pre-commit hook for Ultimate Multisite
# Runs ESLint and Stylelint with auto-fix on staged files

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo "Running pre-commit checks..."

echo -e "${GREEN}Running pre-commit checks...${NC}"

# Get list of staged PHP files
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.php$' | grep -v '^vendor/' | grep -v '^tests/' || true)

if [ -z "$STAGED_FILES" ]; then
echo -e "${GREEN}No PHP files to check.${NC}"
exit 0
fi

echo -e "${YELLOW}Checking PHP files:${NC}"
echo "$STAGED_FILES"

# Check if composer dependencies are installed
if [ ! -f "vendor/bin/phpcs" ] || [ ! -f "vendor/bin/phpstan" ]; then
echo -e "${RED}Error: Please run 'composer install' to install development dependencies.${NC}"
exit 1
fi

# Run PHPCS on staged files
echo -e "${YELLOW}Running PHPCS...${NC}"
HAS_PHPCS_ERRORS=0
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"
HAS_PHPCS_ERRORS=1
fi
fi
done

# If PHPCS found errors, try to auto-fix them with PHPCBF
if [ $HAS_PHPCS_ERRORS -ne 0 ]; then
echo -e "${YELLOW}PHPCS found errors. Running PHPCBF to auto-fix...${NC}"

FIXED_FILES=""
for FILE in $PHPCS_FAILED_FILES; do
if [ -f "$FILE" ]; then
# Run phpcbf (it returns 1 if it made changes, 0 if no changes needed)
vendor/bin/phpcbf "$FILE" || true

# Re-run phpcs to check if the file is now clean
if vendor/bin/phpcs --colors "$FILE" 2>&1; then
echo -e "${GREEN}✓ Auto-fixed: $FILE${NC}"
FIXED_FILES="$FIXED_FILES $FILE"
# Stage the fixed file
git add "$FILE"
else
echo -e "${RED}✗ Could not fully fix: $FILE${NC}"
fi
fi
done

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

if [ $HAS_PHPCS_ERRORS -eq 0 ]; then
echo -e "${GREEN}All PHPCS errors have been auto-fixed!${NC}"
fi
# Check if lint-staged is available
if command -v npx &> /dev/null; then
echo "Running lint-staged..."
npx lint-staged
echo "Pre-commit checks passed!"
else
echo "Warning: npx not found. Skipping lint-staged."
echo "Run 'npm install' to set up the development environment."
fi

# Run PHPStan on staged files
echo -e "${YELLOW}Running PHPStan...${NC}"
HAS_PHPSTAN_ERRORS=0
PHPSTAN_FILES=""
for FILE in $STAGED_FILES; do
if [ -f "$FILE" ] && [[ "$FILE" =~ ^inc/ ]]; then
PHPSTAN_FILES="$PHPSTAN_FILES $FILE"
fi
done

if [ -n "$PHPSTAN_FILES" ]; then
vendor/bin/phpstan analyse --no-progress --error-format=table $PHPSTAN_FILES || HAS_PHPSTAN_ERRORS=1
fi

# Exit with error if any checks failed
if [ $HAS_PHPCS_ERRORS -ne 0 ] || [ $HAS_PHPSTAN_ERRORS -ne 0 ]; then
echo -e "${RED}Pre-commit checks failed!${NC}"
if [ $HAS_PHPCS_ERRORS -ne 0 ]; then
echo -e "${YELLOW}Some PHPCS errors could not be auto-fixed. Please fix them manually.${NC}"
echo -e "${YELLOW}Run 'vendor/bin/phpcs' to see remaining errors.${NC}"
fi
echo -e "${YELLOW}To bypass these checks, use: git commit --no-verify${NC}"
exit 1
fi

echo -e "${GREEN}All pre-commit checks passed!${NC}"
exit 0
197 changes: 197 additions & 0 deletions assets/css/password.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/**
* Password field styles.
*
* Styles for password visibility toggle, strength meter,
* and related password field components.
*
* @since 2.4.0
*/

/**
* CSS Custom Properties for password field theming.
*
* Uses a smart fallback cascade to automatically pick up theme colors from:
* - Elementor: --e-global-color-primary, --e-global-color-accent
* - Kadence Theme: --global-palette1, --global-palette2
* - Beaver Builder: --fl-global-primary-color
* - Block Themes (theme.json): --wp--preset--color--primary, --wp--preset--color--accent
* - WordPress Admin: --wp-admin-theme-color
*
* Themes can also override directly by setting --wu-password-icon-color.
*/
:root {
/*
* Internal intermediate variables to build the cascade.
* CSS doesn't support long fallback chains, so we build it in layers.
*/

/* Layer 1: WordPress core fallbacks */
--wu-pwd-fallback-wp: var(
--wp--preset--color--accent,
var(
--wp--preset--color--primary,
var(--wp-admin-theme-color, #2271b1)
)
);

/* Layer 2: Beaver Builder -> WordPress fallback */
--wu-pwd-fallback-bb: var(--fl-global-primary-color, var(--wu-pwd-fallback-wp));

/* Layer 3: Kadence -> Beaver Builder fallback */
--wu-pwd-fallback-kadence: var(--global-palette1, var(--wu-pwd-fallback-bb));

/* Layer 4: Elementor -> Kadence fallback (final cascade) */
--wu-pwd-fallback-final: var(
--e-global-color-accent,
var(
--e-global-color-primary,
var(--wu-pwd-fallback-kadence)
)
);

/*
* Primary icon color.
* Themes can override this directly, otherwise uses the cascade above.
*/
--wu-password-icon-color: var(--wu-pwd-fallback-final);

--wu-password-toggle-size: 20px;
--wu-password-strength-weak: #dc3232;
--wu-password-strength-medium: #f0b849;
--wu-password-strength-strong: #46b450;
}

/**
* Password field container.
*
* Ensures the toggle button can be absolutely positioned.
*/
.wu-password-field-container {
position: relative;
}

/**
* Password input with space for toggle.
*/
.wu-password-input {
padding-right: 40px !important;
}

/**
* Password visibility toggle button.
*
* Positioned absolutely within the input container,
* vertically centered.
*/
.wu-pwd-toggle {
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
padding: 4px;
background: transparent;
border: 0;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
box-shadow: none;
}

/**
* Toggle button icon styling.
*
* Uses theme primary color with hover effect.
*/
.wu-pwd-toggle .dashicons {
font-size: var(--wu-password-toggle-size);
width: var(--wu-password-toggle-size);
height: var(--wu-password-toggle-size);
transition: color 0.2s ease;
}

.wu-pwd-toggle:hover .dashicons,
.wu-pwd-toggle:focus .dashicons {
color: var(--wu-password-icon-color);
}

/**
* Active state when password is visible.
*/
.wu-pwd-toggle[data-toggle="1"] .dashicons {
color: var(--wu-password-icon-color);
}

/**
* Password strength meter container.
*/
.wu-password-strength-wrapper {
display: block;
margin-top: 8px;
}

/**
* Password strength result display.
*/
#pass-strength-result {
display: block;
padding: 8px 12px;
border-radius: 4px;
font-size: 13px;
text-align: center;
transition: background-color 0.2s ease, color 0.2s ease;
}

/**
* Strength meter states.
*
* Override default WordPress colors for consistency.
*/
#pass-strength-result.short,
#pass-strength-result.bad {
background-color: #fce4e4;
color: var(--wu-password-strength-weak);
}

#pass-strength-result.good {
background-color: #fff8e1;
color: #d88a00;
}

#pass-strength-result.strong {
background-color: #e8f5e9;
color: var(--wu-password-strength-strong);
}

#pass-strength-result.mismatch {
background-color: #fce4e4;
color: var(--wu-password-strength-weak);
}

/**
* Empty state for strength meter.
*/
#pass-strength-result.empty,
#pass-strength-result:empty {
background-color: transparent;
}

/**
* Focus visibility for accessibility.
*/
.wu-pwd-toggle:focus {
outline: 2px solid var(--wu-password-icon-color);
outline-offset: 2px;
border-radius: 2px;
}

.wu-pwd-toggle:focus:not(:focus-visible) {
outline: none;
}

.wu-pwd-toggle:focus-visible {
outline: 2px solid var(--wu-password-icon-color);
outline-offset: 2px;
border-radius: 2px;
}
13 changes: 13 additions & 0 deletions assets/css/password.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading