diff --git a/.github/workflows/commit-built-file-changes.yml b/.github/workflows/commit-built-file-changes.yml index f7265274cf520..f93cd4bd662ec 100644 --- a/.github/workflows/commit-built-file-changes.yml +++ b/.github/workflows/commit-built-file-changes.yml @@ -123,7 +123,7 @@ jobs: rm -f private-key.pem - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 if: ${{ steps.artifact-check.outputs.exists == 'true' }} with: repository: ${{ github.event.workflow_run.head_repository.full_name }} diff --git a/.github/workflows/install-testing.yml b/.github/workflows/install-testing.yml index 6cd3b70ad7439..648ff0485be94 100644 --- a/.github/workflows/install-testing.yml +++ b/.github/workflows/install-testing.yml @@ -122,7 +122,7 @@ jobs: steps: - name: Set up PHP ${{ matrix.php }} - uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # v2.35.5 + uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0 with: php-version: '${{ matrix.php }}' coverage: none diff --git a/.github/workflows/phpstan-static-analysis.yml b/.github/workflows/phpstan-static-analysis.yml new file mode 100644 index 0000000000000..9bb12e40927e2 --- /dev/null +++ b/.github/workflows/phpstan-static-analysis.yml @@ -0,0 +1,97 @@ +name: PHPStan Static Analysis + +on: + # PHPStan testing was introduced in 7.0.0. + push: + branches: + - trunk + - '[7-9].[0-9]' + tags: + - '[7-9].[0-9]' + - '[7-9]+.[0-9].[0-9]+' + pull_request: + branches: + - trunk + - '[7-9].[0-9]' + paths: + # This workflow only scans PHP files. + - '**.php' + # These files configure Composer. Changes could affect the outcome. + - 'composer.*' + # These files configure PHPStan. Changes could affect the outcome. + - 'phpstan.neon.dist' + - 'tests/phpstan/base.neon' + - 'tests/phpstan/baseline.php' + # Confirm any changes to relevant workflow files. + - '.github/workflows/phpstan-static-analysis.yml' + - '.github/workflows/reusable-phpstan-static-analysis.yml' + workflow_dispatch: + +# Cancels all previous workflow runs for pull requests that have not completed. +concurrency: + # The concurrency group contains the workflow name and the branch name for pull requests + # or the commit hash for any other events. + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} + cancel-in-progress: true + +# Disable permissions for all available scopes by default. +# Any needed permissions should be configured at the job level. +permissions: {} + +jobs: + # Runs PHPStan Static Analysis. + phpstan: + name: PHP static analysis + uses: ./.github/workflows/reusable-phpstan-static-analysis.yml + permissions: + contents: read + if: ${{ github.repository == 'WordPress/wordpress-develop' || ( github.event_name == 'pull_request' && github.actor != 'dependabot[bot]' ) }} + + slack-notifications: + name: Slack Notifications + uses: ./.github/workflows/slack-notifications.yml + permissions: + actions: read + contents: read + needs: [ phpstan ] + if: ${{ github.repository == 'WordPress/wordpress-develop' && github.event_name != 'pull_request' && always() }} + with: + calling_status: ${{ contains( needs.*.result, 'cancelled' ) && 'cancelled' || contains( needs.*.result, 'failure' ) && 'failure' || 'success' }} + secrets: + SLACK_GHA_SUCCESS_WEBHOOK: ${{ secrets.SLACK_GHA_SUCCESS_WEBHOOK }} + SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} + SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} + SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + + failed-workflow: + name: Failed workflow tasks + runs-on: ubuntu-24.04 + permissions: + actions: write + needs: [ slack-notifications ] + if: | + always() && + github.repository == 'WordPress/wordpress-develop' && + github.event_name != 'pull_request' && + github.run_attempt < 2 && + ( + contains( needs.*.result, 'cancelled' ) || + contains( needs.*.result, 'failure' ) + ) + + steps: + - name: Dispatch workflow run + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + retries: 2 + retry-exempt-status-codes: 418 + script: | + github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'failed-workflow.yml', + ref: 'trunk', + inputs: { + run_id: `${context.runId}`, + } + }); diff --git a/.github/workflows/pull-request-comments.yml b/.github/workflows/pull-request-comments.yml index dc7e6e7c7a7e6..da30e2feb7f11 100644 --- a/.github/workflows/pull-request-comments.yml +++ b/.github/workflows/pull-request-comments.yml @@ -167,7 +167,6 @@ jobs: [WordPress Playground](https://developer.wordpress.org/playground/) is an experimental project that creates a full WordPress instance entirely within the browser. ### Some things to be aware of - - The Plugin and Theme Directories cannot be accessed within Playground. - All changes will be lost when closing a tab with a Playground instance. - All changes will be lost when refreshing the page. - A fresh instance is created each time the link below is clicked. diff --git a/.github/workflows/reusable-build-package.yml b/.github/workflows/reusable-build-package.yml index 8361c1c9e7a99..1679f1938df17 100644 --- a/.github/workflows/reusable-build-package.yml +++ b/.github/workflows/reusable-build-package.yml @@ -29,13 +29,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm @@ -53,7 +53,7 @@ jobs: run: zip -q -r develop.zip wordpress/. - name: Upload ZIP as a GitHub Actions artifact - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: wordpress-develop path: develop.zip diff --git a/.github/workflows/reusable-check-built-files.yml b/.github/workflows/reusable-check-built-files.yml index f9bcab80343ab..c1d05d821dec5 100644 --- a/.github/workflows/reusable-check-built-files.yml +++ b/.github/workflows/reusable-check-built-files.yml @@ -37,12 +37,12 @@ jobs: contents: read steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - name: Set up Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm @@ -103,7 +103,7 @@ jobs: # Uploads the diff file as an artifact. - name: Upload diff file as artifact - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: ${{ steps.built-file-check.outputs.uncommitted_changes == 'true' }} with: name: pr-built-file-changes diff --git a/.github/workflows/reusable-coding-standards-javascript.yml b/.github/workflows/reusable-coding-standards-javascript.yml index e9f41e82d4b3e..5ad9212e7e58d 100644 --- a/.github/workflows/reusable-coding-standards-javascript.yml +++ b/.github/workflows/reusable-coding-standards-javascript.yml @@ -34,13 +34,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm diff --git a/.github/workflows/reusable-coding-standards-php.yml b/.github/workflows/reusable-coding-standards-php.yml index db343aa5b819c..59aacd51d1d44 100644 --- a/.github/workflows/reusable-coding-standards-php.yml +++ b/.github/workflows/reusable-coding-standards-php.yml @@ -46,13 +46,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} persist-credentials: false - name: Set up PHP - uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # v2.35.5 + uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0 with: php-version: ${{ inputs.php-version }} coverage: none @@ -65,7 +65,7 @@ jobs: run: echo "date=$(/bin/date -u --date='last Mon' "+%F")" >> "$GITHUB_OUTPUT" - name: Cache PHPCS scan cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | .cache/phpcs-src.json diff --git a/.github/workflows/reusable-end-to-end-tests.yml b/.github/workflows/reusable-end-to-end-tests.yml index 620949d7a6717..4c8f2214890ec 100644 --- a/.github/workflows/reusable-end-to-end-tests.yml +++ b/.github/workflows/reusable-end-to-end-tests.yml @@ -76,13 +76,13 @@ jobs: echo "PHP_FPM_GID=$(id -g)" >> "$GITHUB_ENV" - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm @@ -100,7 +100,7 @@ jobs: - name: Install Playwright browsers if: ${{ inputs.install-playwright }} - run: npx playwright install --with-deps + run: npx playwright install --with-deps chromium - name: Build WordPress run: npm run build @@ -145,7 +145,7 @@ jobs: run: npm run test:e2e - name: Archive debug artifacts (screenshots, HTML snapshots) - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() with: name: failures-artifacts${{ inputs.LOCAL_SCRIPT_DEBUG && '-SCRIPT_DEBUG' || '' }}-${{ github.run_id }} diff --git a/.github/workflows/reusable-javascript-tests.yml b/.github/workflows/reusable-javascript-tests.yml index 0fa37c589b2f7..0b6d28e44a93b 100644 --- a/.github/workflows/reusable-javascript-tests.yml +++ b/.github/workflows/reusable-javascript-tests.yml @@ -35,13 +35,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm diff --git a/.github/workflows/reusable-performance-report-v2.yml b/.github/workflows/reusable-performance-report-v2.yml index bc0174d083aa0..8ce3287d70c10 100644 --- a/.github/workflows/reusable-performance-report-v2.yml +++ b/.github/workflows/reusable-performance-report-v2.yml @@ -55,20 +55,20 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} fetch-depth: ${{ github.event_name == 'workflow_dispatch' && '2' || '1' }} persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm - name: Download artifacts - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: pattern: performance-${{ inputs.multisite && 'multisite' || 'single' }}-${{ inputs.memcached && 'memcached' || 'default' }}-* path: artifacts diff --git a/.github/workflows/reusable-performance-test-v2.yml b/.github/workflows/reusable-performance-test-v2.yml index d900c95844cab..cd9e27b38e74f 100644 --- a/.github/workflows/reusable-performance-test-v2.yml +++ b/.github/workflows/reusable-performance-test-v2.yml @@ -115,14 +115,14 @@ jobs: echo "PHP_FPM_GID=$(id -g)" >> "$GITHUB_ENV" - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} fetch-depth: ${{ github.event_name == 'workflow_dispatch' && '2' || '1' }} persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm @@ -227,9 +227,6 @@ jobs: - name: Deactivate WordPress Importer plugin run: npm run env:cli -- plugin deactivate wordpress-importer --path="/var/www/${LOCAL_DIR}" - - name: Update permalink structure - run: npm run env:cli -- rewrite structure '/%year%/%monthnum%/%postname%/' --path="/var/www/${LOCAL_DIR}" - - name: Install additional languages run: | npm run env:cli -- language core install de_DE --path="/var/www/${LOCAL_DIR}" @@ -258,7 +255,7 @@ jobs: TEST_RESULTS_PREFIX: ${{ inputs.subject != 'current' && inputs.subject || '' }} - name: Archive artifacts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() with: name: performance-${{ inputs.multisite && 'multisite' || 'single' }}-${{ inputs.memcached && 'memcached' || 'default' }}-${{ inputs.subject }} diff --git a/.github/workflows/reusable-performance.yml b/.github/workflows/reusable-performance.yml index 37941678978ab..b2c851659ab4c 100644 --- a/.github/workflows/reusable-performance.yml +++ b/.github/workflows/reusable-performance.yml @@ -127,7 +127,7 @@ jobs: echo "PHP_FPM_GID=$(id -g)" >> "$GITHUB_ENV" - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} fetch-depth: ${{ github.event_name == 'workflow_dispatch' && '2' || '1' }} @@ -139,7 +139,7 @@ jobs: run: echo "TARGET_SHA=$(git rev-parse HEAD^1)" >> "$GITHUB_ENV" - name: Set up Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm @@ -203,9 +203,6 @@ jobs: - name: Deactivate WordPress Importer plugin run: npm run env:cli -- plugin deactivate wordpress-importer --path="/var/www/${LOCAL_DIR}" - - name: Update permalink structure - run: npm run env:cli -- rewrite structure '/%year%/%monthnum%/%postname%/' --path="/var/www/${LOCAL_DIR}" - - name: Install additional languages run: | npm run env:cli -- language core install de_DE --path="/var/www/${LOCAL_DIR}" @@ -312,7 +309,7 @@ jobs: run: npm run test:performance - name: Archive artifacts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() with: name: performance-artifacts${{ inputs.multisite && '-multisite' || '' }}${{ inputs.memcached && '-memcached' || '' }}-${{ github.run_id }} diff --git a/.github/workflows/reusable-php-compatibility.yml b/.github/workflows/reusable-php-compatibility.yml index bbb688f040e74..9bec4260c184a 100644 --- a/.github/workflows/reusable-php-compatibility.yml +++ b/.github/workflows/reusable-php-compatibility.yml @@ -40,13 +40,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} persist-credentials: false - name: Set up PHP - uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # v2.35.5 + uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0 with: php-version: ${{ inputs.php-version }} coverage: none @@ -63,7 +63,7 @@ jobs: run: echo "date=$(/bin/date -u --date='last Mon' "+%F")" >> "$GITHUB_OUTPUT" - name: Cache PHP compatibility scan cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: .cache/phpcompat.json key: ${{ runner.os }}-date-${{ steps.get-date.outputs.date }}-php-${{ inputs.php-version }}-phpcompat-cache-${{ hashFiles('**/composer.json', 'phpcompat.xml.dist') }} diff --git a/.github/workflows/reusable-phpstan-static-analysis.yml b/.github/workflows/reusable-phpstan-static-analysis.yml new file mode 100644 index 0000000000000..879c3e5657bc4 --- /dev/null +++ b/.github/workflows/reusable-phpstan-static-analysis.yml @@ -0,0 +1,109 @@ +## +# A reusable workflow that runs PHP Static Analysis tests. +## +name: PHP Static Analysis + +on: + workflow_call: + inputs: + php-version: + description: 'The PHP version to use.' + required: false + type: 'string' + default: 'latest' + +# Disable permissions for all available scopes by default. +# Any needed permissions should be configured at the job level. +permissions: {} + +jobs: + # Runs PHP static analysis tests. + # + # Violations are reported inline with annotations. + # + # Performs the following steps: + # - Checks out the repository. + # - Sets up PHP. + # - Logs debug information. + # - Installs Composer dependencies. + # - Configures caching for PHP static analysis scans. + # - Make Composer packages available globally. + # - Runs PHPStan static analysis (with Pull Request annotations). + # - Saves the PHPStan result cache. + # - Ensures version-controlled files are not modified or deleted. + phpstan: + name: Run PHP static analysis + runs-on: ubuntu-24.04 + permissions: + contents: read + timeout-minutes: 20 + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} + persist-credentials: false + + - name: Set up Node.js + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version-file: '.nvmrc' + cache: npm + + - name: Set up PHP + uses: shivammathur/setup-php@20529878ed81ef8e78ddf08b480401e6101a850f # v2.35.3 + with: + php-version: ${{ inputs.php-version }} + coverage: none + tools: cs2pr + + # This date is used to ensure that the Composer cache is cleared at least once every week. + # http://man7.org/linux/man-pages/man1/date.1.html + - name: "Get last Monday's date" + id: get-date + run: echo "date=$(/bin/date -u --date='last Mon' "+%F")" >> "$GITHUB_OUTPUT" + + - name: General debug information + run: | + npm --version + node --version + composer --version + + # Since Composer dependencies are installed using `composer update` and no lock file is in version control, + # passing a custom cache suffix ensures that the cache is flushed at least once per week. + - name: Install Composer dependencies + uses: ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520 # v3.1.1 + with: + custom-cache-suffix: ${{ steps.get-date.outputs.date }} + + - name: Make Composer packages available globally + run: echo "${PWD}/vendor/bin" >> "$GITHUB_PATH" + + - name: Install npm dependencies + run: npm ci --ignore-scripts + + - name: Build WordPress + run: npm run build:dev + + - name: Cache PHP Static Analysis scan cache + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: .cache # This is defined in the base.neon file. + key: "phpstan-result-cache-${{ github.run_id }}" + restore-keys: | + phpstan-result-cache- + + - name: Run PHP static analysis tests + id: phpstan + run: composer run phpstan -- -vvv --error-format=checkstyle | cs2pr --errors-as-warnings --graceful-warnings + + - name: "Save result cache" + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + if: ${{ !cancelled() }} + with: + path: .cache + key: "phpstan-result-cache-${{ github.run_id }}" + + - name: Ensure version-controlled files are not modified or deleted + run: git diff --exit-code diff --git a/.github/workflows/reusable-phpunit-tests-v1.yml b/.github/workflows/reusable-phpunit-tests-v1.yml index 787e5f521b8b3..50891ef74e6cd 100644 --- a/.github/workflows/reusable-phpunit-tests-v1.yml +++ b/.github/workflows/reusable-phpunit-tests-v1.yml @@ -97,13 +97,13 @@ jobs: echo "PHP_FPM_GID=$(id -g)" >> "$GITHUB_ENV" - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm @@ -121,7 +121,7 @@ jobs: - name: Cache Composer dependencies if: ${{ env.COMPOSER_INSTALL == true }} - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 env: cache-name: cache-composer-dependencies with: diff --git a/.github/workflows/reusable-phpunit-tests-v2.yml b/.github/workflows/reusable-phpunit-tests-v2.yml index 092d09227131b..523db98096d1d 100644 --- a/.github/workflows/reusable-phpunit-tests-v2.yml +++ b/.github/workflows/reusable-phpunit-tests-v2.yml @@ -99,13 +99,13 @@ jobs: echo "PHP_FPM_GID=$(id -g)" >> "$GITHUB_ENV" - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} persist-credentials: false - name: Install Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm @@ -118,7 +118,7 @@ jobs: run: echo "composer_dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT" - name: Cache Composer dependencies - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 env: cache-name: cache-composer-dependencies with: diff --git a/.github/workflows/reusable-phpunit-tests-v3.yml b/.github/workflows/reusable-phpunit-tests-v3.yml index 34fffdfad4f99..45198c20f5e52 100644 --- a/.github/workflows/reusable-phpunit-tests-v3.yml +++ b/.github/workflows/reusable-phpunit-tests-v3.yml @@ -131,13 +131,13 @@ jobs: echo "PHP_FPM_GID=$(id -g)" >> "$GITHUB_ENV" - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm @@ -150,7 +150,7 @@ jobs: # dependency versions are installed and cached. ## - name: Set up PHP - uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # v2.35.5 + uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0 with: php-version: '${{ inputs.php }}' coverage: none @@ -237,7 +237,7 @@ jobs: - name: Upload test coverage report to Codecov if: ${{ inputs.coverage-report }} - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 with: token: ${{ secrets.CODECOV_TOKEN }} files: wp-code-coverage${{ inputs.multisite && '-multisite' || '-single' }}-${{ github.sha }}.xml @@ -246,7 +246,7 @@ jobs: - name: Upload HTML coverage report as artifact if: ${{ inputs.coverage-report }} - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: wp-code-coverage${{ inputs.multisite && '-multisite' || '-single' }}-${{ github.sha }} path: wp-code-coverage${{ inputs.multisite && '-multisite' || '-single' }}-${{ github.sha }} @@ -257,7 +257,7 @@ jobs: - name: Checkout the WordPress Test Reporter if: ${{ github.ref == 'refs/heads/trunk' && inputs.report }} - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: 'WordPress/phpunit-test-runner' path: 'test-runner' diff --git a/.github/workflows/reusable-support-json-reader-v1.yml b/.github/workflows/reusable-support-json-reader-v1.yml index c2f263a093ab9..be5693aac7297 100644 --- a/.github/workflows/reusable-support-json-reader-v1.yml +++ b/.github/workflows/reusable-support-json-reader-v1.yml @@ -49,7 +49,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: ${{ inputs.repository }} show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -86,7 +86,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: ${{ inputs.repository }} show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -129,7 +129,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: ${{ inputs.repository }} show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/reusable-test-core-build-process.yml b/.github/workflows/reusable-test-core-build-process.yml index d4cd2e4bce89a..4bec59e285c57 100644 --- a/.github/workflows/reusable-test-core-build-process.yml +++ b/.github/workflows/reusable-test-core-build-process.yml @@ -70,7 +70,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} persist-credentials: false @@ -91,7 +91,7 @@ jobs: custom-cache-suffix: ${{ steps.get-date.outputs.date }} - name: Set up Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm @@ -133,7 +133,7 @@ jobs: run: git diff --exit-code - name: Upload ZIP as a GitHub Actions artifact - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: ${{ inputs.save-build || inputs.prepare-playground }} with: name: wordpress-build-${{ github.event_name == 'pull_request' && github.event.number || github.sha }} @@ -151,7 +151,7 @@ jobs: # Uploads the PR number as an artifact for the Pull Request Commenting workflow to download and then # leave a comment detailing how to test the PR within WordPress Playground. - name: Upload PR number as artifact - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: ${{ inputs.prepare-playground && github.repository == 'WordPress/wordpress-develop' && github.event_name == 'pull_request' }} with: name: pr-number diff --git a/.github/workflows/reusable-test-gutenberg-build-process.yml b/.github/workflows/reusable-test-gutenberg-build-process.yml index a0e74d6d00bf5..c0fa87aa3ab20 100644 --- a/.github/workflows/reusable-test-gutenberg-build-process.yml +++ b/.github/workflows/reusable-test-gutenberg-build-process.yml @@ -49,13 +49,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} persist-credentials: false - name: Checkout Gutenberg plugin - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: 'WordPress/gutenberg' path: ${{ env.GUTENBERG_DIRECTORY }} @@ -63,7 +63,7 @@ jobs: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm diff --git a/.github/workflows/reusable-test-local-docker-environment-v1.yml b/.github/workflows/reusable-test-local-docker-environment-v1.yml index a9f2b448e4340..698956ff00346 100644 --- a/.github/workflows/reusable-test-local-docker-environment-v1.yml +++ b/.github/workflows/reusable-test-local-docker-environment-v1.yml @@ -86,13 +86,13 @@ jobs: echo "PHP_FPM_GID=$(id -g)" >> "$GITHUB_ENV" - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm @@ -105,7 +105,7 @@ jobs: # dependency versions are installed and cached. ## - name: Set up PHP - uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # v2.35.5 + uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0 with: php-version: '${{ inputs.php }}' coverage: none diff --git a/.github/workflows/reusable-upgrade-testing.yml b/.github/workflows/reusable-upgrade-testing.yml index aa1760daf6c40..f3659fab3ad26 100644 --- a/.github/workflows/reusable-upgrade-testing.yml +++ b/.github/workflows/reusable-upgrade-testing.yml @@ -78,7 +78,7 @@ jobs: steps: - name: Set up PHP ${{ inputs.php }} - uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # v2.35.5 + uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0 with: php-version: '${{ inputs.php }}' coverage: none @@ -114,7 +114,7 @@ jobs: - name: Download build artifact for the current branch if: ${{ inputs.new-version == 'develop' }} - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: wordpress-develop diff --git a/.github/workflows/reusable-workflow-lint.yml b/.github/workflows/reusable-workflow-lint.yml index 8a83830beb8fd..3a538a8a99690 100644 --- a/.github/workflows/reusable-workflow-lint.yml +++ b/.github/workflows/reusable-workflow-lint.yml @@ -21,7 +21,7 @@ jobs: timeout-minutes: 5 steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/test-and-zip-default-themes.yml b/.github/workflows/test-and-zip-default-themes.yml index c560a7b0dd21f..5af965af0907a 100644 --- a/.github/workflows/test-and-zip-default-themes.yml +++ b/.github/workflows/test-and-zip-default-themes.yml @@ -93,7 +93,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event_name == 'workflow_dispatch' && inputs.branch || github.ref }} show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -137,14 +137,14 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event_name == 'workflow_dispatch' && inputs.branch || github.ref }} show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm @@ -176,7 +176,7 @@ jobs: # Uploads the diff file as an artifact. - name: Upload diff file as artifact - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: ${{ steps.built-file-check.outputs.uncommitted_changes == 'true' }} with: name: pr-built-file-changes @@ -221,7 +221,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event_name == 'workflow_dispatch' && inputs.branch || github.ref }} show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -229,7 +229,7 @@ jobs: - name: Set up Node.js for themes needing minification if: matrix.theme == 'twentytwentytwo' || matrix.theme == 'twentytwentyfive' - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: '.nvmrc' cache: npm @@ -246,7 +246,7 @@ jobs: working-directory: src/wp-content/themes/${{ matrix.theme }} - name: Upload theme ZIP as an artifact - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: ${{ matrix.theme }} path: | diff --git a/.gitignore b/.gitignore index 3997df4c9d603..1cd9da16b3ed0 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ wp-tests-config.php /gutenberg /tests/phpunit/build /wp-cli.local.yml +/phpstan.neon /jsdoc /composer.lock /vendor @@ -37,6 +38,7 @@ wp-tests-config.php /src/wp-includes/css/*-rtl.css /src/wp-includes/blocks/* !/src/wp-includes/blocks/index.php +/src/wp-includes/icons /src/wp-includes/build /src/wp-includes/theme.json /packagehash.txt diff --git a/Gruntfile.js b/Gruntfile.js index 9363a26a746a6..81da2faae228f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -107,6 +107,7 @@ module.exports = function(grunt) { 'concat', 'copy', 'cssmin', + 'imagemin', 'jshint', 'qunit', 'uglify', @@ -282,8 +283,6 @@ module.exports = function(grunt) { src: buildFiles.concat( [ '!wp-includes/assets/**', // Assets is extracted into separate copy tasks. '!js/**', // JavaScript is extracted into separate copy tasks. - '!wp-includes/certificates/cacert.pem*', // Exclude raw root certificate files that are combined into ca-bundle.crt. - '!wp-includes/certificates/legacy-1024bit.pem', '!.{svn,git}', // Exclude version control folders. '!wp-includes/version.php', // Exclude version.php. '!{wp-admin,wp-includes,wp-content/themes/twenty*,wp-content/plugins/akismet}/**/*.map', // The build doesn't need .map files. @@ -581,7 +580,7 @@ module.exports = function(grunt) { }, certificates: { src: 'vendor/composer/ca-bundle/res/cacert.pem', - dest: SOURCE_DIR + 'wp-includes/certificates/cacert.pem' + dest: SOURCE_DIR + 'wp-includes/certificates/ca-bundle.crt' } }, sass: { @@ -1005,16 +1004,6 @@ module.exports = function(grunt) { WORKING_DIR + 'wp-includes/js/wp-emoji.min.js' ], dest: WORKING_DIR + 'wp-includes/js/wp-emoji-release.min.js' - }, - certificates: { - options: { - separator: '\n\n' - }, - src: [ - SOURCE_DIR + 'wp-includes/certificates/legacy-1024bit.pem', - SOURCE_DIR + 'wp-includes/certificates/cacert.pem' - ], - dest: SOURCE_DIR + 'wp-includes/certificates/ca-bundle.crt' } }, patch:{ @@ -1571,6 +1560,7 @@ module.exports = function(grunt) { ] ); grunt.registerTask( 'precommit:php', [ + 'phpstan', 'phpunit' ] ); @@ -1823,13 +1813,12 @@ module.exports = function(grunt) { } ); grunt.registerTask( 'build:certificates', [ - 'concat:certificates' + 'copy:certificates' ] ); grunt.registerTask( 'certificates:upgrade', [ 'certificates:upgrade-package', - 'copy:certificates', - 'build:certificates' + 'copy:certificates' ] ); grunt.registerTask( 'build:files', [ @@ -2013,6 +2002,18 @@ module.exports = function(grunt) { grunt.registerTask( 'test', 'Runs all QUnit and PHPUnit tasks.', ['qunit:compiled', 'phpunit'] ); + grunt.registerTask( 'phpstan', 'Runs PHPStan on the entire codebase.', function() { + var done = this.async(); + + grunt.util.spawn( { + cmd: 'composer', + args: [ 'phpstan' ], + opts: { stdio: 'inherit' } + }, function( error ) { + done( ! error ); + } ); + } ); + grunt.registerTask( 'format:php', 'Runs the code formatter on changed files.', function() { var done = this.async(); var flags = this.flags; diff --git a/composer.json b/composer.json index 2c5b20f7879a9..17f53c2116f71 100644 --- a/composer.json +++ b/composer.json @@ -19,10 +19,11 @@ "ext-dom": "*" }, "require-dev": { - "composer/ca-bundle": "1.5.9", + "composer/ca-bundle": "1.5.10", "squizlabs/php_codesniffer": "3.13.5", "wp-coding-standards/wpcs": "~3.3.0", "phpcompatibility/phpcompatibility-wp": "~2.1.3", + "phpstan/phpstan": "2.1.39", "yoast/phpunit-polyfills": "^1.1.0" }, "config": { @@ -32,6 +33,7 @@ "lock": false }, "scripts": { + "phpstan": "@php ./vendor/bin/phpstan analyse --memory-limit=2G", "compat": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --standard=phpcompat.xml.dist --report=summary,source", "format": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf --report=summary,source", "lint": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --report=summary,source", diff --git a/package-lock.json b/package-lock.json index 87af6af9dd1c2..e72e76a6fdf66 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,12 +10,13 @@ "hasInstallScript": true, "license": "GPL-2.0-or-later", "dependencies": { - "backbone": "1.6.0", + "backbone": "1.6.1", "clipboard": "2.0.11", "codemirror": "5.65.20", "core-js-url-browser": "3.6.4", "csslint": "1.0.5", "element-closest": "3.0.2", + "espree": "9.6.1", "esprima": "4.0.1", "formdata-polyfill": "4.0.10", "hoverintent": "2.2.1", @@ -27,7 +28,7 @@ "jquery-hoverintent": "1.10.2", "json2php": "0.0.12", "jsonlint": "1.6.3", - "lodash": "4.17.21", + "lodash": "4.17.23", "masonry-layout": "4.2.2", "moment": "2.30.1", "objectFitPolyfill": "2.3.5", @@ -44,6 +45,7 @@ "@lodder/grunt-postcss": "^3.1.1", "@playwright/test": "1.56.1", "@pmmmwh/react-refresh-webpack-plugin": "0.6.1", + "@types/codemirror": "5.60.17", "@wordpress/e2e-test-utils-playwright": "1.33.2", "@wordpress/prettier-config": "4.33.1", "@wordpress/scripts": "30.26.2", @@ -5131,6 +5133,16 @@ "@types/node": "*" } }, + "node_modules/@types/codemirror": { + "version": "5.60.17", + "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.17.tgz", + "integrity": "sha512-AZq2FIsUHVMlp7VSe2hTfl5w4pcUkoFkM3zVsRKsn1ca8CXRDYvnin04+HP2REkwsxemuHqvDofdlhUWNpbwfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/tern": "*" + } + }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", @@ -5420,6 +5432,16 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "node_modules/@types/tern": { + "version": "0.23.9", + "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz", + "integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, "node_modules/@types/tough-cookie": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.3.tgz", @@ -7445,7 +7467,6 @@ "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -7468,7 +7489,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -8505,9 +8525,9 @@ } }, "node_modules/backbone": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.6.0.tgz", - "integrity": "sha512-13PUjmsgw/49EowNcQvfG4gmczz1ximTMhUktj0Jfrjth0MVaTxehpU+qYYX4MxnuIuhmvBLC6/ayxuAGnOhbA==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.6.1.tgz", + "integrity": "sha512-YQzWxOrIgL6BoFnZjThVN99smKYhyEXXFyJJ2lsF1wJLyo4t+QjmkLrH8/fN22FZ4ykF70Xq7PgTugJVR4zS9Q==", "dependencies": { "underscore": ">=1.8.3" } @@ -13285,7 +13305,6 @@ "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -13302,7 +13321,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -22306,9 +22324,10 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "license": "MIT" }, "node_modules/lodash-es": { "version": "4.17.21", diff --git a/package.json b/package.json index 9ff5ddd3dae97..745ec98ab6b58 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "url": "https://develop.svn.wordpress.org/trunk" }, "gutenberg": { - "ref": "7bf80ea84eb8b62eceb1bb3fe82e42163673ca79" + "ref": "23b566c72e9c4a36219ef5d6e62890f05551f6cb" }, "engines": { "node": ">=20.10.0", @@ -30,6 +30,7 @@ "@lodder/grunt-postcss": "^3.1.1", "@playwright/test": "1.56.1", "@pmmmwh/react-refresh-webpack-plugin": "0.6.1", + "@types/codemirror": "5.60.17", "@wordpress/e2e-test-utils-playwright": "1.33.2", "@wordpress/prettier-config": "4.33.1", "@wordpress/scripts": "30.26.2", @@ -73,12 +74,13 @@ "webpack": "5.98.0" }, "dependencies": { - "backbone": "1.6.0", + "backbone": "1.6.1", "clipboard": "2.0.11", "codemirror": "5.65.20", "core-js-url-browser": "3.6.4", "csslint": "1.0.5", "element-closest": "3.0.2", + "espree": "9.6.1", "esprima": "4.0.1", "formdata-polyfill": "4.0.10", "hoverintent": "2.2.1", @@ -90,7 +92,7 @@ "jquery-hoverintent": "1.10.2", "json2php": "0.0.12", "jsonlint": "1.6.3", - "lodash": "4.17.21", + "lodash": "4.17.23", "masonry-layout": "4.2.2", "moment": "2.30.1", "objectFitPolyfill": "2.3.5", @@ -128,6 +130,7 @@ "test:coverage": "npm run test:php -- --coverage-html ./coverage/html/ --coverage-php ./coverage/php/report.php --coverage-text=./coverage/text/report.txt", "test:e2e": "wp-scripts test-playwright --config tests/e2e/playwright.config.js", "test:visual": "wp-scripts test-playwright --config tests/visual-regression/playwright.config.js", + "typecheck:php": "node ./tools/local-env/scripts/docker.js run --rm php composer phpstan", "gutenberg:checkout": "node tools/gutenberg/checkout-gutenberg.js", "gutenberg:build": "node tools/gutenberg/build-gutenberg.js", "gutenberg:copy": "node tools/gutenberg/copy-gutenberg-build.js", @@ -136,4 +139,4 @@ "sync-gutenberg-packages": "grunt sync-gutenberg-packages", "postsync-gutenberg-packages": "grunt wp-packages:sync-stable-blocks && grunt build --dev && grunt build" } -} +} \ No newline at end of file diff --git a/phpcs.xml.dist b/phpcs.xml.dist index a8387b3604c9b..a9d0cd5fb2bca 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -42,6 +42,9 @@ ^build/* + + /gutenberg/* + /node_modules/* /vendor/* @@ -73,6 +76,7 @@ /src/wp-includes/js/* /src/wp-includes/PHPMailer/* /src/wp-includes/Requests/* + /src/wp-includes/php-ai-client/* /src/wp-includes/SimplePie/* /src/wp-includes/sodium_compat/* /src/wp-includes/Text/* @@ -81,6 +85,9 @@ /tests/phpunit/build* /tests/phpunit/data/* + + /tests/phpstan/* + /tools/* diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000000000..e74e6ec1a441b --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,36 @@ +# PHPStan configuration for WordPress Core. +# +# To overload this configuration, copy this file to phpstan.neon and adjust as needed. +# +# https://phpstan.org/config-reference + +includes: + # The base configuration file for using PHPStan with the WordPress core codebase. + - tests/phpstan/base.neon + + # The baseline file includes preexisting errors in the codebase that should be ignored. + # https://phpstan.org/user-guide/baseline + - tests/phpstan/baseline.php + +parameters: + # https://phpstan.org/user-guide/rule-levels + level: 0 + reportUnmatchedIgnoredErrors: true + + ignoreErrors: + # Level 0: + - # Inner functions aren't supported by PHPStan. + message: '#Function wxr_[a-z_]+ not found#' + path: src/wp-admin/includes/export.php + - + identifier: function.inner + path: src/wp-admin/includes/export.php + count: 13 + - + identifier: function.inner + path: src/wp-admin/includes/file.php + count: 1 + - + identifier: function.inner + path: src/wp-includes/canonical.php + count: 1 diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 4b5b0d3ded110..4b6c149867c7d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -47,6 +47,7 @@ src/wp-includes/IXR src/wp-includes/PHPMailer src/wp-includes/Requests + src/wp-includes/php-ai-client src/wp-includes/SimplePie src/wp-includes/sodium_compat src/wp-includes/Text diff --git a/src/js/_enqueues/admin/site-health.js b/src/js/_enqueues/admin/site-health.js index 416295df69b17..57d5c9cbcf289 100644 --- a/src/js/_enqueues/admin/site-health.js +++ b/src/js/_enqueues/admin/site-health.js @@ -44,6 +44,10 @@ jQuery( function( $ ) { $( '.health-check-accordion' ).on( 'click', '.health-check-accordion-trigger', function() { var isExpanded = ( 'true' === $( this ).attr( 'aria-expanded' ) ); + if ( $( this ).prop( 'id' ) ) { + window.location.hash = $( this ).prop( 'id' ); + } + if ( isExpanded ) { $( this ).attr( 'aria-expanded', 'false' ); $( '#' + $( this ).attr( 'aria-controls' ) ).attr( 'hidden', true ); @@ -53,6 +57,20 @@ jQuery( function( $ ) { } } ); + /* global setTimeout */ + wp.domReady( function() { + // Get hash from query string and open the related accordion. + var hash = window.location.hash; + + if ( hash ) { + var requestedPanel = $( hash ); + + if ( requestedPanel.is( '.health-check-accordion-trigger' ) ) { + requestedPanel.trigger( 'click' ); + } + } + } ); + // Site Health test handling. $( '.site-health-view-passed' ).on( 'click', function() { diff --git a/src/js/_enqueues/vendor/codemirror/javascript-lint.js b/src/js/_enqueues/vendor/codemirror/javascript-lint.js new file mode 100644 index 0000000000000..3f98ad523346c --- /dev/null +++ b/src/js/_enqueues/vendor/codemirror/javascript-lint.js @@ -0,0 +1,121 @@ +/** + * CodeMirror JavaScript linter. + * + * @since 7.0.0 + */ + +import CodeMirror from 'codemirror'; + +/** + * CodeMirror Lint Error. + * + * @see https://codemirror.net/5/doc/manual.html#addon_lint + * + * @typedef {Object} CodeMirrorLintError + * @property {string} message - Error message. + * @property {'error'} severity - Severity. + * @property {CodeMirror.Position} from - From position. + * @property {CodeMirror.Position} to - To position. + */ + +/** + * JSHint options supported by Espree. + * + * @see https://jshint.com/docs/options/ + * @see https://www.npmjs.com/package/espree#options + * + * @typedef {Object} SupportedJSHintOptions + * @property {number} [esversion] - "This option is used to specify the ECMAScript version to which the code must adhere." + * @property {boolean} [es5] - "This option enables syntax first defined in the ECMAScript 5.1 specification. This includes allowing reserved keywords as object properties." + * @property {boolean} [es3] - "This option tells JSHint that your code needs to adhere to ECMAScript 3 specification. Use this option if you need your program to be executable in older browsersβ€”such as Internet Explorer 6/7/8/9β€”and other legacy JavaScript environments." + * @property {boolean} [module] - "This option informs JSHint that the input code describes an ECMAScript 6 module. All module code is interpreted as strict mode code." + * @property {'implied'} [strict] - "This option requires the code to run in ECMAScript 5's strict mode." + */ + +/** + * Validates JavaScript. + * + * @since 7.0.0 + * + * @param {string} text - Source. + * @param {SupportedJSHintOptions} options - Linting options. + * @returns {Promise} + */ +async function validator( text, options ) { + const errors = /** @type {CodeMirrorLintError[]} */ []; + try { + const espree = await import( /* webpackIgnore: true */ 'espree' ); + espree.parse( text, { + ...getEspreeOptions( options ), + loc: true, + } ); + } catch ( error ) { + if ( + // This is an `EnhancedSyntaxError` in Espree: . + error instanceof SyntaxError && + typeof error.lineNumber === 'number' && + typeof error.column === 'number' + ) { + const line = error.lineNumber - 1; + errors.push( { + message: error.message, + severity: 'error', + from: CodeMirror.Pos( line, error.column - 1 ), + to: CodeMirror.Pos( line, error.column ), + } ); + } else { + console.warn( '[CodeMirror] Unable to lint JavaScript:', error ); // jshint ignore:line + } + } + + return errors; +} + +CodeMirror.registerHelper( 'lint', 'javascript', validator ); + +/** + * Gets the options for Espree from the supported JSHint options. + * + * @since 7.0.0 + * + * @param {SupportedJSHintOptions} options - Linting options for JSHint. + * @return {{ + * ecmaVersion?: number|'latest', + * ecmaFeatures?: { + * impliedStrict?: true + * } + * }} + */ +function getEspreeOptions( options ) { + const ecmaFeatures = {}; + if ( options.strict === 'implied' ) { + ecmaFeatures.impliedStrict = true; + } + + return { + ecmaVersion: getEcmaVersion( options ), + sourceType: options.module ? 'module' : 'script', + ecmaFeatures, + }; +} + +/** + * Gets the ECMAScript version. + * + * @since 7.0.0 + * + * @param {SupportedJSHintOptions} options - Options. + * @return {number|'latest'} ECMAScript version. + */ +function getEcmaVersion( options ) { + if ( typeof options.esversion === 'number' ) { + return options.esversion; + } + if ( options.es5 ) { + return 5; + } + if ( options.es3 ) { + return 3; + } + return 'latest'; +} diff --git a/src/js/_enqueues/wp/media/editor.js b/src/js/_enqueues/wp/media/editor.js index 02c993fd4bbef..1097bca966fdb 100644 --- a/src/js/_enqueues/wp/media/editor.js +++ b/src/js/_enqueues/wp/media/editor.js @@ -703,15 +703,19 @@ * Update the featured image id when the 'remove' link is clicked. */ init: function() { - $('#postimagediv').on( 'click', '#set-post-thumbnail', function( event ) { - event.preventDefault(); - // Stop propagation to prevent thickbox from activating. - event.stopPropagation(); - - wp.media.featuredImage.frame().open(); - }).on( 'click', '#remove-post-thumbnail', function() { - wp.media.featuredImage.remove(); - return false; + $('#postimagediv').on( 'click keyup keydown', '#set-post-thumbnail', function( event ) { + if ( ( event.type === 'keyup' && event.key === ' ' ) || ( event.type === 'keydown' && event.key === 'Enter' ) || event.type === 'click' ) { + event.preventDefault(); + // Stop propagation to prevent thickbox from activating. + event.stopPropagation(); + + wp.media.featuredImage.frame().open(); + } + }).on( 'click keyup keydown', '#remove-post-thumbnail', function( event ) { + if ( ( event.type === 'keyup' && event.key === ' ' ) || ( event.type === 'keydown' && event.key === 'Enter' ) || event.type === 'click' ) { + wp.media.featuredImage.remove(); + return false; + } }); } }; diff --git a/src/js/_enqueues/wp/widgets/custom-html.js b/src/js/_enqueues/wp/widgets/custom-html.js index 3987eb4180e8d..d0be23eeb37af 100644 --- a/src/js/_enqueues/wp/widgets/custom-html.js +++ b/src/js/_enqueues/wp/widgets/custom-html.js @@ -333,7 +333,7 @@ wp.customHtmlWidgets = ( function( $ ) { * This ensures that the textarea is visible and the editor can be initialized. */ renderWhenAnimationDone = function() { - if ( ! ( wp.customize ? widgetContainer.parent().hasClass( 'expanded' ) : widgetContainer.hasClass( 'open' ) ) ) { // Core merge: The wp.customize condition can be eliminated with this change being in core: https://github.com/xwp/wordpress-develop/pull/247/commits/5322387d + if ( ! ( wp.customize ? widgetContainer.parent().hasClass( 'expanded' ) : widgetContainer.hasClass( 'open' ) ) ) { // Core merge: The wp.customize condition can be eliminated with this change being in core: https://core.trac.wordpress.org/changeset/41260 setTimeout( renderWhenAnimationDone, animatedCheckDelay ); } else { widgetControl.initializeEditor(); diff --git a/src/js/media/views/media-frame.js b/src/js/media/views/media-frame.js index aca0bf5ef8333..1140bf2795ff4 100644 --- a/src/js/media/views/media-frame.js +++ b/src/js/media/views/media-frame.js @@ -101,7 +101,7 @@ MediaFrame = Frame.extend(/** @lends wp.media.view.MediaFrame.prototype */{ tabPanelEl = this.$el.find( '.media-frame-tab-panel' ), ariaLabelledby; - tabPanelEl.removeAttr( 'role aria-labelledby tabindex' ); + tabPanelEl.removeAttr( 'role aria-labelledby' ); if ( this.state().get( 'menu' ) && this.menuView && this.menuView.isVisible ) { ariaLabelledby = 'menu-item-' + stateId; @@ -111,7 +111,6 @@ MediaFrame = Frame.extend(/** @lends wp.media.view.MediaFrame.prototype */{ .attr( { role: 'tabpanel', 'aria-labelledby': ariaLabelledby, - tabIndex: '0' } ); } }, @@ -127,7 +126,7 @@ MediaFrame = Frame.extend(/** @lends wp.media.view.MediaFrame.prototype */{ var tabPanelEl = this.$el.find( '.media-frame-content' ), ariaLabelledby; - tabPanelEl.removeAttr( 'role aria-labelledby tabindex' ); + tabPanelEl.removeAttr( 'role aria-labelledby' ); // Set the tab panel attributes only if the tabs are visible. if ( this.state().get( 'router' ) && this.routerView && this.routerView.isVisible && this.content._mode ) { @@ -137,7 +136,6 @@ MediaFrame = Frame.extend(/** @lends wp.media.view.MediaFrame.prototype */{ .attr( { role: 'tabpanel', 'aria-labelledby': ariaLabelledby, - tabIndex: '0' } ); } }, diff --git a/src/wp-activate.php b/src/wp-activate.php index 103df0364e973..f1eb579e61b19 100644 --- a/src/wp-activate.php +++ b/src/wp-activate.php @@ -101,12 +101,13 @@ function do_activate_header() { function wpmu_activate_stylesheet() { ?> .button.active { - border-color: variables.$button-color; + border-color: var(--wp-admin-theme-color); + background: rgba(var(--wp-admin-theme-color--rgb), 0.04); } .wp-ui-primary { @@ -215,28 +223,34 @@ textarea:focus { /* List tables */ -@if variables.$low-contrast-theme == "true" { - .wrap .page-title-action:hover { - color: variables.$menu-text; - background-color: variables.$menu-background; - } -} @else { - .wrap .page-title-action, - .wrap .page-title-action:active { - border: 1px solid variables.$highlight-color; - color: variables.$highlight-color; - } - .wrap .page-title-action:hover { - color: color.adjust(variables.$highlight-color, $lightness: -10%); - border-color: color.adjust(variables.$highlight-color, $lightness: -10%); - } +// .page-title-action uses secondary button styling +.wrap .page-title-action { + background: transparent; + border: 1px solid var(--wp-admin-theme-color); + border-radius: tokens.$radius-s; + color: var(--wp-admin-theme-color); +} - .wrap .page-title-action:focus { - border-color: color.adjust(variables.$highlight-color, $lightness: 10%); - color: color.adjust(variables.$highlight-color, $lightness: -20%); - box-shadow: 0 0 0 1px color.adjust(variables.$highlight-color, $lightness: 10%); - } +.wrap .page-title-action:hover { + background: rgba(var(--wp-admin-theme-color--rgb), 0.04); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); +} + +.wrap .page-title-action:focus { + background: transparent; + border-color: var(--wp-admin-theme-color); + color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color); + outline: 1px solid transparent; +} + +.wrap .page-title-action:active { + background: rgba(var(--wp-admin-theme-color--rgb), 0.08); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); + box-shadow: none; } .view-switch a.current:before { diff --git a/src/wp-admin/css/colors/_mixins.scss b/src/wp-admin/css/colors/_mixins.scss index d33cf3bb2d854..9575f1f2d623b 100644 --- a/src/wp-admin/css/colors/_mixins.scss +++ b/src/wp-admin/css/colors/_mixins.scss @@ -1,39 +1,132 @@ @use 'sass:color'; +@use 'tokens'; /* - * Button mixin- creates a button effect with correct - * highlights/shadows, based on a base color. + * Button mixin - creates a primary button effect. + * Uses CSS custom properties for theme color support across color schemes. */ -@mixin button( $button-color, $button-text-color: #fff ) { - background: $button-color; - border-color: $button-color; +@mixin button( $button-text-color: #fff ) { + background: var(--wp-admin-theme-color); + border-color: transparent; + border-radius: tokens.$radius-s; color: $button-text-color; - &:hover, - &:focus { - background: color.adjust($button-color, $lightness: 3%); - border-color: color.adjust($button-color, $lightness: -3%); + &:hover { + background: var(--wp-admin-theme-color-darker-10); + border-color: transparent; color: $button-text-color; } &:focus { + background: var(--wp-admin-theme-color); + border-color: transparent; + color: $button-text-color; + /* Gutenberg-style focus ring: outer theme color + inset white for contrast */ box-shadow: - 0 0 0 1px #fff, - 0 0 0 3px $button-color; + 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color), + inset 0 0 0 1px tokens.$white; + /* Visible in Windows High Contrast mode */ + outline: 1px solid transparent; } &:active { - background: color.adjust($button-color, $lightness: -5%); - border-color: color.adjust($button-color, $lightness: -5%); + background: var(--wp-admin-theme-color-darker-20); + border-color: transparent; color: $button-text-color; } + &:disabled, + &.disabled { + background: tokens.$gray-100; + border-color: transparent; + color: tokens.$gray-600; + cursor: not-allowed; + } + &.active, &.active:focus, &.active:hover { - background: $button-color; + background: var(--wp-admin-theme-color-darker-10); color: $button-text-color; - border-color: color.adjust($button-color, $lightness: -15%); - box-shadow: inset 0 2px 5px -3px color.adjust($button-color, $lightness: -50%); + border-color: transparent; + box-shadow: none; + } +} + +/* + * Secondary button mixin - outlined style with theme color. + * Matches Gutenberg's .is-secondary button variant. + */ +@mixin button-secondary() { + background: transparent; + border: 1px solid var(--wp-admin-theme-color); + border-radius: tokens.$radius-s; + color: var(--wp-admin-theme-color); + + &:hover { + background: rgba(var(--wp-admin-theme-color--rgb), 0.04); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); + } + + &:focus { + background: transparent; + border-color: var(--wp-admin-theme-color); + color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color); + outline: 1px solid transparent; + } + + &:active { + background: rgba(var(--wp-admin-theme-color--rgb), 0.08); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); + box-shadow: none; + } + + &:disabled, + &.disabled { + background: transparent; + border-color: tokens.$gray-300; + color: tokens.$gray-600; + cursor: not-allowed; + } +} + +/* + * Tertiary button mixin - transparent background, gray text. + */ +@mixin button-tertiary() { + background: transparent; + border: 1px solid tokens.$gray-600; + border-radius: tokens.$radius-s; + color: tokens.$gray-900; + + &:hover { + background: rgba(0, 0, 0, 0.05); + border-color: tokens.$gray-700; + color: tokens.$gray-900; + } + + &:focus { + background: transparent; + border-color: var(--wp-admin-theme-color); + color: tokens.$gray-900; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color); + outline: 1px solid transparent; + } + + &:active { + background: rgba(0, 0, 0, 0.1); + border-color: tokens.$gray-700; + color: tokens.$gray-900; + } + + &:disabled, + &.disabled { + background: transparent; + border-color: tokens.$gray-400; + color: tokens.$gray-600; + cursor: not-allowed; } } diff --git a/src/wp-admin/css/colors/_tokens.scss b/src/wp-admin/css/colors/_tokens.scss new file mode 100644 index 0000000000000..785f1f47f5076 --- /dev/null +++ b/src/wp-admin/css/colors/_tokens.scss @@ -0,0 +1,212 @@ +// ========================================================================== +// WordPress Design System Tokens +// ========================================================================== +// +// These tokens are derived from the WordPress Design System in Figma: +// https://www.figma.com/design/804HN2REV2iap2ytjRQ055/WordPress-Design-System +// +// IMPORTANT: Do NOT expose these as CSS custom properties. +// Use these Sass variables to compile to static CSS values. +// The only CSS custom properties available are those in wp-base-styles: +// - --wp-admin-theme-color +// - --wp-admin-theme-color--rgb +// - --wp-admin-theme-color-darker-10 +// - --wp-admin-theme-color-darker-20 +// - --wp-admin-border-width-focus +// +// ========================================================================== + + +// -------------------------------------------------------------------------- +// Grid Units (Spacing) +// -------------------------------------------------------------------------- +// Based on 4px base unit. Use for padding, margin, and gap values. + +$grid-unit-05: 4px; // Scales/grid unit 05 +$grid-unit-10: 8px; // Scales/grid unit 10 +$grid-unit-15: 12px; // Scales/grid unit 15 +$grid-unit-20: 16px; // Scales/grid unit 20 +$grid-unit-30: 24px; // Scales/grid unit 30 +$grid-unit-40: 32px; // Scales/grid unit 40 +$grid-unit-50: 40px; // Scales/grid unit 50 +$grid-unit-60: 48px; // Scales/grid unit 60 +$grid-unit-70: 56px; // Scales/grid unit 70 + + +// -------------------------------------------------------------------------- +// Border Radius +// -------------------------------------------------------------------------- + +$radius-xs: 1px; // radius-xs +$radius-s: 2px; // radius-s - Buttons, inputs +$radius-m: 4px; // radius-m - Focus rings +$radius-l: 8px; // radius-l - Cards, dashboard widgets +$radius-30: 12px; // Radius 30 +$radius-full: 9999px; // radius-full - Pills, avatars, circles + + +// -------------------------------------------------------------------------- +// Gray Scale +// -------------------------------------------------------------------------- +// Neutral colors for backgrounds, borders, and text. + +$gray-100: #f0f0f0; // Scales/Grays/gray-100 - Page background, disabled inputs +$gray-200: #e0e0e0; // Scales/Grays/gray-200 +$gray-300: #dddddd; // Scales/Grays/gray-300 +$gray-400: #cccccc; // Scales/Grays/gray-400 - Disabled borders +$gray-600: #949494; // Scales/Grays/gray-600 - Input borders, disabled text +$gray-700: #757575; // Scales/Grays/gray-700 +$gray-800: #2f2f2f; // Scales/Grays/gray-800 +$gray-900: #1e1e1e; // Scales/Grays/gray-900 - Primary text + +$white: #ffffff; // Scales/Black & White/white + + +// -------------------------------------------------------------------------- +// Theme Colors (Static reference values) +// -------------------------------------------------------------------------- +// For actual theme color usage, use var(--wp-admin-theme-color) instead. +// These are provided for reference and for contexts where CSS vars aren't available. + +$theme-reference: #3858e9; // Scales/Theme/theme (modern scheme) +$theme-darker-10-reference: #2145e6; // Scales/Theme/theme-darker-10 +$theme-darker-20-reference: #183ad6; // Scales/Theme/theme-darker-20 +$theme-alpha-04: rgba(56, 88, 233, 0.04); // Scales/Theme/theme-alpha-04 (4% opacity) +$theme-alpha-08: rgba(56, 88, 233, 0.08); // Scales/Theme/theme-alpha-08 (8% opacity) + +$brand-9: #4465db; // Scales/brand-9 - Focus ring color (static, not theme-dependent) + + +// -------------------------------------------------------------------------- +// Semantic Colors +// -------------------------------------------------------------------------- +// Use these for notices, alerts, and status indicators. +// These are intentionally NOT theme-dependent for consistency. + +$alert-yellow: #f0b849; // Scales/Yellow/alert-yellow - Warnings +$alert-green: #4ab866; // Scales/Green/alert-green - Success +$alert-red: #cc1818; // Scales/Red/alert-red - Errors +$alert-blue: #3858e9; // Info notices (matches modern theme) + +// Background tints for notices +$alert-yellow-bg: #fef8ee; // Warning notice background +$alert-green-bg: #eff9f1; // Success notice background +$alert-red-bg: #fcf0f0; // Error notice background + +$synced-color: #7a00df; // Scales/Purple/--wp-block-synced-color + + +// -------------------------------------------------------------------------- +// Text Colors +// -------------------------------------------------------------------------- + +$text-primary: $gray-900; // Primary text color +$text-secondary: $gray-700; // Secondary text +$text-tertiary: #5d5d5d; // Alias/text/text-tertiary - Placeholder, hints +$text-disabled: $gray-600; // Disabled text + + +// -------------------------------------------------------------------------- +// Component Tokens +// -------------------------------------------------------------------------- + +// Inputs +$input-bg: $white; // Alias/bg/bg-input +$input-border-color: $gray-600; // Default input border +$input-border-color-disabled: $gray-400; +$input-bg-disabled: $gray-100; +$input-border-width-default: 1px; // Input/Default +$input-border-width-focus: 1.5px; // Input/Focus +$field-spacing-horizontal: 8px; // Alias/field-spacing-horizontal + +// Checkboxes and Radios +$checkbox-size: 16px; // Alias/checkbox +$radio-size: 16px; // Alias/radio + +// Toggles +$toggle-width: 32px; // Alias/toggle-width +$toggle-height: 16px; // Alias/toggle-height + +// Buttons +// Note: Gutenberg is transitioning to 40px as the default button size. +// The "compact" size (32px) is available for space-constrained contexts. +$button-height-default: 40px; // Default button height (next-default-40px) +$button-height-compact: 32px; // Compact button height +$button-height-small: 24px; // Small button height + +// Cards and Surfaces +$card-bg: $white; +$card-border-color: rgba(0, 0, 0, 0.1); +$card-border-width: 1px; +$card-border-radius: $radius-l; // 8px for dashboard widgets +$card-border-radius-metabox: 0; // 0 for post editor metaboxes +$card-divider-color: rgba(0, 0, 0, 0.1); + +// Card Padding Sizes +$card-padding-xs: $grid-unit-10; // 8px - xSmall cards +$card-padding-sm: $grid-unit-20; // 16px - Small cards (metaboxes, dashboard widgets) +$card-padding-md-h: $grid-unit-30; // 24px - Medium cards horizontal +$card-padding-md-v: $grid-unit-20; // 16px - Medium cards vertical +$card-padding-lg-h: $grid-unit-40; // 32px - Large cards horizontal +$card-padding-lg-v: $grid-unit-30; // 24px - Large cards vertical + +// Page Layout +$page-padding-large: 48px; // Alias/page-large +$page-padding-small: 24px; // Alias/page-small + + +// -------------------------------------------------------------------------- +// Typography Scale +// -------------------------------------------------------------------------- + +// Font Sizes +$font-size-xs: 11px; // xs - Small labels, button small +$font-size-s: 12px; // s - Body small +$font-size-m: 13px; // m - Base body text, buttons +$font-size-l: 15px; // l - Body large, heading large +$font-size-xl: 20px; // xl - Heading XL + +// Line Heights +$line-height-xs: 16px; // xs +$line-height-s: 20px; // s - Most UI elements +$line-height-m: 24px; // m - Body large + +// Font Weights +$font-weight-regular: 400; // Regular - Body text +$font-weight-medium: 500; // Medium - Headings, buttons + + +// -------------------------------------------------------------------------- +// Elevation (Box Shadows) +// -------------------------------------------------------------------------- + +$elevation-xs: + 0 4px 4px rgba(0, 0, 0, 0.01), + 0 3px 3px rgba(0, 0, 0, 0.02), + 0 1px 2px rgba(0, 0, 0, 0.02), + 0 1px 1px rgba(0, 0, 0, 0.03); + +$elevation-s: + 0 8px 8px rgba(0, 0, 0, 0.02), + 0 1px 2px rgba(0, 0, 0, 0.05); + +$elevation-m: + 0 16px 16px rgba(0, 0, 0, 0.02), + 0 4px 5px rgba(0, 0, 0, 0.03), + 0 2px 3px rgba(0, 0, 0, 0.05); + +$elevation-l: + 0 50px 43px rgba(0, 0, 0, 0.02), + 0 30px 36px rgba(0, 0, 0, 0.04), + 0 15px 27px rgba(0, 0, 0, 0.07), + 0 5px 15px rgba(0, 0, 0, 0.08); + + +// -------------------------------------------------------------------------- +// Layout +// -------------------------------------------------------------------------- + +$modal-width-small: 384px; // Layout/Modal small +$modal-width-medium: 512px; // Layout/Modal medium +$modal-width-large: 840px; // Layout/Modal large + diff --git a/src/wp-admin/css/colors/_variables.scss b/src/wp-admin/css/colors/_variables.scss index 8a073f830e4b6..d37c2b1392f00 100644 --- a/src/wp-admin/css/colors/_variables.scss +++ b/src/wp-admin/css/colors/_variables.scss @@ -1,5 +1,8 @@ @use "sass:color"; +// Import design system tokens +@use "tokens" as *; + // assign default value to all undefined variables $scheme-name: "default" !default; @@ -15,7 +18,7 @@ $notification-color: #d54e21 !default; // global -$body-background: #f1f1f1 !default; +$body-background: $gray-100 !default; $link: #0073aa !default; $link-focus: color.adjust($link, $lightness: 10%) !default; diff --git a/src/wp-admin/css/common.css b/src/wp-admin/css/common.css index 70c110d351d0e..c80af03e11032 100644 --- a/src/wp-admin/css/common.css +++ b/src/wp-admin/css/common.css @@ -129,7 +129,9 @@ padding: 0; position: absolute; width: 1px; - word-wrap: normal !important; /* many screen reader and browser combinations announce broken words as they would appear visually */ + /* Many screen reader and browser combinations announce broken words as they would appear visually. */ + word-wrap: normal !important; + word-break: normal !important; } .button .screen-reader-text { @@ -153,8 +155,8 @@ font-weight: 600; padding: 15px 23px 14px; /* Background and color set to prevent false positives in automated accessibility tests. */ - background: #f0f0f1; - color: #2271b1; + background: #ffffff; + color: var(--wp-admin-theme-color, #3858e9); z-index: 100000; line-height: normal; } @@ -162,8 +164,8 @@ .screen-reader-shortcut:focus { top: -25px; /* Overrides a:focus in the admin. See ticket #56789. */ - color: #2271b1; - box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6); + color: var(--wp-admin-theme-color, #3858e9); + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); text-decoration: none; /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; @@ -278,7 +280,8 @@ a:focus .media-icon img, a:focus .plugin-icon, .wp-person a:focus .gravatar { color: #043959; - box-shadow: 0 0 0 2px #2271b1; + border-radius: 2px; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -632,14 +635,14 @@ code { top: -3px; margin-left: 4px; border: 1px solid #2271b1; - border-radius: 3px; - background: #f6f7f7; + border-radius: 2px; + background: transparent; font-size: 13px; - font-weight: 400; - line-height: 2.15384615; + font-weight: 500; + min-height: 32px; + line-height: 2.30769231; /* 30px for 32px height */ color: #2271b1; /* use the standard color used for buttons */ - padding: 0 10px; - min-height: 30px; + padding: 0 12px; -webkit-appearance: none; } @@ -650,7 +653,6 @@ code { .wrap .add-new-h2:hover, /* deprecated */ .wrap .page-title-action:hover { - background: #f0f0f1; border-color: #0a4b78; color: #0a4b78; } @@ -806,14 +808,14 @@ img.emoji { #bulk-titles .ntdelbutton:before, .notice-dismiss:before { background: none; - color: #787c82; + color: #1e1e1e; content: "\f153"; content: "\f153" / ''; display: block; - font: normal 16px/20px dashicons; - height: 20px; + font: normal 20px/24px dashicons; + height: 24px; text-align: center; - width: 20px; + width: 24px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } @@ -825,7 +827,7 @@ img.emoji { .tagchecklist .ntdelbutton .remove-tag-icon:before { margin-left: 2px; border-radius: 50%; - color: #2271b1; + color: var(--wp-admin-theme-color, #3858e9); /* vertically center the icon cross browsers */ line-height: 1.28; } @@ -842,7 +844,7 @@ img.emoji { } .tagchecklist .ntdelbutton:focus .remove-tag-icon:before { - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -931,10 +933,12 @@ a#remove-post-thumbnail:hover, clear: both; border-top: 1px solid #dcdcde; background: #f6f7f7; + display: flex; + align-items: center; + justify-content: space-between; } #delete-action { - float: left; line-height: 2.30769231; /* 30px */ } @@ -951,7 +955,7 @@ a#remove-post-thumbnail:hover, #publishing-action { text-align: right; - float: right; + margin-left: auto; line-height: 1.9; } @@ -1109,8 +1113,28 @@ th.action-links { margin: 0; } -/* Use flexbox only on the plugins install page. The `filter-links` and search form children will become flex items. */ -.plugin-install-php .wp-filter { +.wp-filter .search-form input[type="search"] { + min-height: 32px; + line-height: 2.14285714; /* 30px for 32px height with 14px font */ + padding: 0 8px; +} + +.wp-filter .search-form select, +.wp-filter .filter-items select { + min-height: 32px; + line-height: 2.14285714; /* 30px for 32px height with 14px font */ + padding: 0 24px 0 8px; +} + +.wp-filter .button { + min-height: 32px; + line-height: 2.30769231; /* 30px for 32px height with 13px font */ + padding: 0 12px; +} + +/* Use flexbox only on the plugins install page and upload page. The `filter-links` and search form children will become flex items. */ +.plugin-install-php .wp-filter, +.upload-php .wp-filter { display: flex; flex-wrap: wrap; justify-content: space-between; @@ -1421,11 +1445,11 @@ th.action-links { div.updated, div.error { background: #fff; - border: 1px solid #c3c4c7; - border-left-width: 4px; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); + border: none; + border-left: 4px solid #c3c4c7; + box-shadow: none; margin: 5px 15px 2px; - padding: 1px 12px; + padding: 8px 12px; } div[class="update-message"] { /* back-compat for pre-4.6 */ @@ -1438,15 +1462,31 @@ div.updated p, div.error p, .form-table td .notice p { margin: 0.5em 0; - padding: 2px; + padding: 0; + font-size: 13px; + line-height: 1.54; + color: #1e1e1e; } -.error a { +.notice a, +.error a, +.updated a { + color: var(--wp-admin-theme-color-darker-10); text-decoration: underline; } -.updated a { - padding-bottom: 2px; +.notice a:hover, +.error a:hover, +.updated a:hover { + color: var(--wp-admin-theme-color-darker-20); +} + +.notice a:focus, +.error a:focus, +.updated a:focus { + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + outline: 2px solid transparent; + border-radius: 2px; } .notice-alt { @@ -1464,66 +1504,82 @@ div.error p, } .wp-core-ui .notice.is-dismissible { - padding-right: 38px; + padding-right: 48px; position: relative; } .notice-dismiss { position: absolute; - top: 0; - right: 1px; + top: 12px; + right: 12px; border: none; margin: 0; - padding: 9px; + padding: 0; background: none; - color: #787c82; + color: #1e1e1e; cursor: pointer; + width: 24px; + height: 24px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 2px; } .notice-dismiss:hover:before, -.notice-dismiss:active:before, -.notice-dismiss:focus:before { - color: #d63638; +.notice-dismiss:active:before { + color: #1e1e1e; + opacity: 0.7; } .notice-dismiss:focus { - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } +.notice-dismiss:focus:before { + color: #1e1e1e; +} + .notice-success, div.updated { - border-left-color: #00a32a; + border-left-color: #4ab866; + background-color: #eff9f1; } -.notice-success.notice-alt { - background-color: #edfaef; +.notice-success.notice-alt, +div.updated.notice-alt { + background-color: #eff9f1; } .notice-warning { - border-left-color: #dba617; + border-left-color: #f0b849; + background-color: #fef8ee; } .notice-warning.notice-alt { - background-color: #fcf9e8; + background-color: #fef8ee; } .notice-error, div.error { - border-left-color: #d63638; + border-left-color: #cc1818; + background-color: #fcf0f0; } -.notice-error.notice-alt { - background-color: #fcf0f1; +.notice-error.notice-alt, +div.error.notice-alt { + background-color: #fcf0f0; } .notice-info { - border-left-color: #72aee6; + border-left-color: #3858e9; + background-color: #fff; } .notice-info.notice-alt { - background-color: #f0f6fc; + background-color: #fff; } #plugin-information-footer .update-now:not(.button-disabled):before { @@ -1716,7 +1772,9 @@ p.auto-update-status { .button.installing:before, .button.activated-message:before, .button.activating-message:before { - margin: 3px 5px 0 -2px; + margin: 0 5px 0 -2px; + line-height: 1.9; /* 38px (20px * 1.9) - matches button */ + vertical-align: top; } #plugin-information-footer .button { @@ -1734,11 +1792,13 @@ p.auto-update-status { #plugin-information-footer .button.updated-message:before, #plugin-information-footer .button.activated-message:before, #plugin-information-footer .button.activating-message:before { - margin: 9px 5px 0 -2px; + margin: 0 5px 0 -2px; + line-height: 1.9; /* 38px (20px * 1.9) - matches button */ + vertical-align: top; } #plugin-information-footer .button.update-now.updating-message:before { - margin: -3px 5px 0 -2px; + margin: 0 5px 0 -2px; } .button-primary.updating-message:before, @@ -1816,12 +1876,13 @@ p.auto-update-status { border: 1px solid #c3c4c7; border-top: none; height: auto; + min-height: 32px; /* Compact size for header buttons */ margin-bottom: 0; - padding: 3px 6px 3px 16px; + padding: 0 6px 0 16px; background: #fff; border-radius: 0 0 4px 4px; color: #646970; - line-height: 1.7; + line-height: 2.30769231; /* 30px - matches compact button */ box-shadow: 0 0 0 transparent; transition: box-shadow 0.1s linear; } @@ -1833,8 +1894,8 @@ p.auto-update-status { } #screen-meta-links .show-settings:focus { - border-color: #2271b1; - box-shadow: 0 0 0 1px #2271b1; + border-color: var(--wp-admin-theme-color, #3858e9); + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -1847,12 +1908,10 @@ p.auto-update-status { right: 0; content: "\f140"; content: "\f140" / ''; - font: normal 20px/1 dashicons; + font: normal 20px/1.5 dashicons; /* line-height 1.5 = 30px to match compact button */ display: inline-block; padding: 0 5px 0 0; - bottom: 2px; - position: relative; - vertical-align: bottom; + vertical-align: top; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-decoration: none; @@ -2453,7 +2512,7 @@ h1.nav-tab-wrapper, /* Back-compat for pre-4.4 */ .accordion-section-title button.accordion-trigger:focus, .nav-menus-php .metabox-holder .accordion-section-title button.accordion-trigger:focus { - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); outline: 2px solid transparent; } @@ -3275,7 +3334,7 @@ img { .postbox .handle-order-higher:focus, .postbox .handle-order-lower:focus, .postbox .handlediv:focus { - box-shadow: inset 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color); border-radius: 50%; /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; @@ -3386,7 +3445,7 @@ img { /* Reset default focus style. */ box-shadow: none; /* Use an inset outline instead, so it's visible also over the current file item. */ - outline: 2px solid #2271b1; + outline: 2px solid var(--wp-admin-theme-color, #3858e9); outline-offset: -2px; } @@ -3622,7 +3681,7 @@ img { } .widget-top .widget-action:focus .toggle-indicator:before { - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } diff --git a/src/wp-admin/css/customize-controls.css b/src/wp-admin/css/customize-controls.css index 60a6d0a3e7009..bb22b99559ac6 100644 --- a/src/wp-admin/css/customize-controls.css +++ b/src/wp-admin/css/customize-controls.css @@ -70,7 +70,7 @@ body { #customize-save-button-wrapper { float: right; - margin-top: 9px; + margin-top: 3px; /* Vertically center 40px button in 45px header */ } body:not(.ready) #customize-save-button-wrapper .save { @@ -185,7 +185,7 @@ body.trashing #publish-settings { } #customize-header-actions .spinner { - margin-top: 13px; + margin-top: 13px; /* Vertically center 20px spinner in 45px header */ margin-right: 4px; } @@ -272,8 +272,10 @@ body.trashing #publish-settings { .preview-link-wrapper .customize-copy-preview-link.preview-control-element.button { margin: 0; position: absolute; - bottom: 9px; + top: 50%; + transform: translateY(-50%) !important; right: 0; + background: #fff !important; } .preview-link-wrapper { @@ -283,10 +285,10 @@ body.trashing #publish-settings { .customize-copy-preview-link:before, .customize-copy-preview-link:after { content: ""; - height: 28px; + height: 40px; position: absolute; background: #fff; - top: -1px; + top: 0; } .customize-copy-preview-link:before { @@ -1136,6 +1138,12 @@ p.customize-section-description { position: static; } +#available-menu-items .new-content-item-wrapper > label, +.customize-control-dropdown-pages .new-content-item-wrapper > label { + margin-bottom: 4px; + display: block; +} + #available-menu-items .accordion-section-content .new-content-item, .customize-control-dropdown-pages .new-content-item { display: flex; @@ -1158,14 +1166,25 @@ p.customize-section-description { #available-menu-items .new-content-item .create-item-input, .customize-control-dropdown-pages .new-content-item .create-item-input { flex-grow: 10; + width: 100%; +} + +#available-menu-items .new-content-item .create-item-input { + min-height: 32px; + line-height: 2.15384615; /* 28px for 32px min-height with 13px font */ } #available-menu-items .new-content-item .add-content, .customize-control-dropdown-pages .new-content-item .add-content { - margin: 2px 0 2px 6px; + margin: 0 0 0 6px; flex-grow: 1; } +#available-menu-items .new-content-item .add-content { + min-height: 32px; + line-height: 2.30769231; /* 30px for 32px min-height with 13px font */ +} + .customize-control-dropdown-pages .new-content-item .create-item-input.invalid { border: 1px solid #d63638; } @@ -1448,17 +1467,16 @@ p.customize-section-description { .customize-control .attachment-media-view .upload-button { width: 100%; - padding: 9px 0; + text-align: center; } .customize-control .attachment-media-view .upload-button.control-focus { width: auto; - padding: 0 10px; } .customize-control.customize-control-header .actions .upload-button.button.new { width: 100%; - padding: 9px 0; + text-align: center; } .customize-control .attachment-media-view .thumbnail, @@ -1596,7 +1614,7 @@ p.customize-section-description { } .customize-control-header button.random .dice { - margin-top: 4px; + margin-top: 0; } .customize-control-header .placeholder:hover .dice, @@ -1637,7 +1655,7 @@ p.customize-section-description { } .customize-control-header .choice:focus { - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -1796,7 +1814,7 @@ p.customize-section-description { position: absolute; right: 10px; top: 50%; - margin-top: -14px; + margin-top: -20px; /* Half of 40px button height for vertical centering */ font-weight: 400; } @@ -2199,12 +2217,13 @@ p.customize-section-description { } .themes-filter-bar .wp-filter-search { - line-height: 1.8; - padding: 6px 10px 6px 30px; + line-height: 2.14285714; /* 30px for 32px compact input */ + padding: 0 10px 0 30px; max-width: 100%; width: 40%; min-width: 300px; height: 32px; + min-height: 32px; /* Override global 40px min-height for compact bar */ margin: 1px 0; top: 0; left: 0; @@ -2676,6 +2695,11 @@ body.adding-widget .add-new-widget:before, border-right: 1px solid #dcdcde; } +#available-widgets .accordion-section-title, +#available-menu-items .accordion-section-title { + z-index: 2; +} + #available-widgets .customize-section-title, #available-menu-items .customize-section-title { border: 0; @@ -2686,7 +2710,9 @@ body.adding-widget .add-new-widget:before, padding: 0; position: absolute; width: 1px; + /* Many screen reader and browser combinations announce broken words as they would appear visually. */ word-wrap: normal !important; + word-break: normal !important; } #available-widgets .customize-section-title button, @@ -2725,7 +2751,7 @@ body.adding-widget .add-new-widget:before, #available-widgets-filter input, #available-menu-items-search input { width: 100%; - min-height: 32px; + min-height: 40px; margin: 1px 0; padding: 0 30px; } @@ -2739,7 +2765,7 @@ body.adding-widget .add-new-widget:before, #available-widgets-filter .search-icon { display: block; position: absolute; - bottom: 15px; /* 13 container padding +1 input margin +1 input border */ + bottom: 19px; /* 13 container padding +1 input margin +1 input border +4 centering in 40px input */ left: 16px; width: 30px; height: 30px; @@ -2751,7 +2777,7 @@ body.adding-widget .add-new-widget:before, #available-widgets-filter .clear-results, #available-menu-items-search .accordion-section-title .clear-results { position: absolute; - top: 36px; /* 13 container padding +1 input margin +1 input border */ + top: 40px; /* 13 container padding +1 input margin +1 input border +4 centering in 40px input */ right: 16px; width: 30px; height: 30px; @@ -2794,7 +2820,8 @@ body.adding-widget .add-new-widget:before, #available-widgets-filter .clear-results:focus, #available-menu-items-search .clear-results:focus { - box-shadow: 0 0 0 2px #2271b1; + border-radius: 2px; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -2920,10 +2947,6 @@ body.adding-widget .add-new-widget:before, bottom: 16px; } - .preview-link-wrapper .customize-copy-preview-link.preview-control-element.button { - bottom: 10px; - } - .media-widget-control .media-widget-buttons .button.edit-media, .media-widget-control .media-widget-buttons .button.change-media, .media-widget-control .media-widget-buttons .button.select-media { @@ -3019,7 +3042,7 @@ body.adding-widget .add-new-widget:before, } .customize-control .attachment-media-view .upload-button { - padding: 5px 0; + text-align: center; } #customize-control-changeset_status .customize-inside-control-row { @@ -3089,7 +3112,7 @@ body.adding-widget .add-new-widget:before, } #available-menu-items-search .clear-results { - top: 36px; + top: 40px; right: 16px; } diff --git a/src/wp-admin/css/customize-nav-menus.css b/src/wp-admin/css/customize-nav-menus.css index 3bf0193f02eea..cabab59f49ca2 100644 --- a/src/wp-admin/css/customize-nav-menus.css +++ b/src/wp-admin/css/customize-nav-menus.css @@ -688,7 +688,7 @@ #available-menu-items-search .spinner { position: absolute; - bottom: 20px; /* 13 container padding +1 input margin +6 ( ( 32 input height - 20 spinner height ) / 2 ) */ + bottom: 24px; /* 13 container padding +1 input margin +10 ( ( 40 input height - 20 spinner height ) / 2 ) */ right: 21px; margin: 0 !important; } @@ -697,7 +697,7 @@ #available-menu-items #available-menu-items-search .accordion-section-content { position: absolute; left: 0; - top: 75px; /* below title div / search input */ + top: 83px; /* below title div / search input (75 + 8 for 40px input) */ bottom: 0; /* 100% height that still triggers lazy load */ max-height: none; width: 100%; @@ -860,6 +860,10 @@ li.assigned-to-menu-location .add-new-menu-item { } .customize-control-nav_menu .customize-control-nav_menu-buttons { + display: flex; + flex-direction: row-reverse; + align-items: center; + gap: 8px; margin-top: 12px; } @@ -874,7 +878,7 @@ li.assigned-to-menu-location .add-new-menu-item { .menu-delete:focus, .menu-item-bar .item-delete:focus:before, #available-menu-items .item-add:focus:before { - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -882,12 +886,12 @@ li.assigned-to-menu-location .add-new-menu-item { @media screen and (max-width: 782px) { #available-menu-items #available-menu-items-search .accordion-section-content { - top: 63px; + top: 71px; /* 63 + 8 for 40px input */ } } @media screen and (max-width: 640px) { #available-menu-items #available-menu-items-search .accordion-section-content { - top: 146px; + top: 154px; /* 146 + 8 for 40px input */ } } diff --git a/src/wp-admin/css/dashboard.css b/src/wp-admin/css/dashboard.css index 64aa30dbedeac..8196e6e10b49f 100644 --- a/src/wp-admin/css/dashboard.css +++ b/src/wp-admin/css/dashboard.css @@ -40,7 +40,15 @@ #dashboard-widgets-wrap { overflow: hidden; - margin: 0 -8px; + margin: 0 -4px; +} + +#dashboard-widgets .postbox { + border-radius: 8px; +} + +#dashboard-widgets .postbox-header .hndle { + padding: 12px 16px; } #dashboard-widgets .postbox .inside { @@ -50,20 +58,32 @@ #dashboard-widgets .meta-box-sortables { display: flow-root; /* avoid margin collapsing between parent and first/last child elements */ /* Required min-height to make the jQuery UI Sortable drop zone work. */ - min-height: 100px; - margin: 0 8px 20px; + min-height: 0; + margin-right: 8px; + padding: 4px; +} + +#dashboard-widgets .meta-box-sortables:not(:empty) { + margin-bottom: 16px; } #dashboard-widgets .postbox-container .empty-container { - outline: 3px dashed #c3c4c7; + outline: 2px dashed rgb(0, 0, 0, 0.15); + outline-offset: -2px; + border-radius: 8px; height: 250px; } -/* Only highlight drop zones when dragging and only in the 2 columns layout. */ +/* Only highlight drop zones when dragging. */ .is-dragging-metaboxes #dashboard-widgets .meta-box-sortables { - outline: 3px dashed #646970; - /* Prevent margin on the child from collapsing with margin on the parent. */ - display: flow-root; + border-radius: 8px; + background: rgb(var(--wp-admin-theme-color--rgb), 0.04); + min-height: 100px; +} + +.is-dragging-metaboxes #dashboard-widgets .postbox-container .empty-container { + outline: 2px dashed rgb(0, 0, 0, 0.15); + background: rgb(0, 0, 0, 0.01); } #dashboard-widgets .postbox-container .empty-container:after { @@ -121,6 +141,8 @@ overflow: auto; margin: 16px 0; background-color: #151515; + border: 1px solid rgb(0, 0, 0, 0.1); + border-radius: 8px; font-size: 14px; line-height: 1.3; clear: both; @@ -197,10 +219,12 @@ } .welcome-panel .welcome-panel-close { + display: flex; + align-items: center; position: absolute; top: 10px; right: 10px; - padding: 10px 15px 10px 24px; + padding: 10px 15px; font-size: 13px; line-height: 1.23076923; /* Chrome rounding, needs to be 16px equivalent */ text-decoration: none; @@ -208,9 +232,6 @@ } .welcome-panel .welcome-panel-close:before { - position: absolute; - top: 8px; - left: 0; transition: all .1s ease-in-out; content: '\f335'; font-size: 24px; @@ -259,11 +280,11 @@ clear: both; display: grid; z-index: 1; - padding: 48px; + padding: 24px; grid-template-columns: repeat(3, 1fr); gap: 32px; align-self: flex-end; - background: #fff; + background: #ffffff; } [class*="welcome-panel-icon"] { @@ -699,14 +720,6 @@ body #dashboard-widgets .postbox form .submit { margin-bottom: 10px; } -#dashboard_right_now .inside { - padding: 0; -} - -#dashboard_right_now .main { - padding: 0 12px 11px; -} - #dashboard_right_now .main p { margin: 0; } @@ -807,7 +820,7 @@ body #dashboard-widgets .postbox form .submit { min-height: 90px; max-height: 1300px; margin: 0 0 8px; - padding: 6px 7px; + padding: 8px 12px; resize: none; } @@ -892,7 +905,7 @@ body #dashboard-widgets .postbox form .submit { #dashboard_activity .inside { margin: 0; - padding-bottom: 0; + padding: 0 12px; } #dashboard_activity .no-activity { @@ -1240,10 +1253,6 @@ a.rsswidget { margin: 12px 0; } -#dashboard_php_nag .button .dashicons-external { - line-height: 25px; -} - .bigger-bolder-text { font-weight: 600; font-size: 14px; @@ -1298,10 +1307,11 @@ a.rsswidget { #dashboard-widgets #postbox-container-3 .empty-container, #dashboard-widgets #postbox-container-4 .empty-container { - outline: none; + border: none; height: 0; min-height: 0; margin-bottom: 0; + display: none; } #dashboard-widgets #postbox-container-3 .empty-container:after, @@ -1314,7 +1324,7 @@ a.rsswidget { } #wpbody #dashboard-widgets .metabox-holder.columns-1 .postbox-container .empty-container { - outline: none; + border: none; height: 0; min-height: 0; margin-bottom: 0; @@ -1352,10 +1362,11 @@ a.rsswidget { } #dashboard-widgets #postbox-container-4 .empty-container { - outline: none; + border: none; height: 0; min-height: 0; margin-bottom: 0; + display: none; } #dashboard-widgets #postbox-container-4 .empty-container:after { diff --git a/src/wp-admin/css/edit.css b/src/wp-admin/css/edit.css index 7e4110a8c569e..66214eec112a2 100644 --- a/src/wp-admin/css/edit.css +++ b/src/wp-admin/css/edit.css @@ -5,6 +5,7 @@ #poststuff #post-body { padding: 0; + margin: 0 -4px; } #poststuff .postbox-container { @@ -75,10 +76,16 @@ pointer-events: none; } +#titlewrap .skiplink { + background: #fff; + line-height: 2.30769231; /* 30px for 32px min-height */ + min-height: 32px; + right: 4px; +} + #titlewrap .skiplink:focus { clip: inherit; clip-path: inherit; - right: 4px; top: 4px; width: auto; } @@ -167,11 +174,14 @@ body.post-type-wp_navigation .inline-edit-status { /* Post Screen */ +.metabox-holder .postbox-container .meta-box-sortables { + padding: 4px; +} + /* Only highlight drop zones when dragging and only in the 2 columns layout. */ .is-dragging-metaboxes .metabox-holder .postbox-container .meta-box-sortables { - outline: 3px dashed #646970; - /* Prevent margin on the child from collapsing with margin on the parent. */ - display: flow-root; + border-radius: 8px; + background: rgb(var(--wp-admin-theme-color--rgb), 0.04); /* * This min-height is meant to limit jumpiness while dragging. It's equivalent * to the minimum height of the sortable-placeholder which is given by the height @@ -325,8 +335,9 @@ form#tags-filter { } #post-body .tagsdiv #newtag { - margin-right: 5px; - width: 16em; + margin-right: 0; + flex: 1; + min-width: 0; } #side-sortables input#post_password { @@ -334,7 +345,8 @@ form#tags-filter { } #side-sortables .tagsdiv #newtag { - width: 68%; + flex: 1; + min-width: 0; } #post-status-info { @@ -1055,10 +1067,6 @@ form#tags-filter { #edit-slug-box { padding: 0; } - - #titlewrap .skiplink:focus { - top: 5px; - } } @media only screen and (max-width: 1004px) { @@ -1323,7 +1331,7 @@ div.tabs-panel-inactive { } div.tabs-panel-active:focus { - box-shadow: inset 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -1423,6 +1431,9 @@ p.description code, #poststuff .tagsdiv .ajaxtag { margin-top: 1em; + display: flex; + gap: 8px; + align-items: center; } #poststuff .tagsdiv .howto { @@ -1434,7 +1445,8 @@ p.description code, } .tagsdiv .newtag { - width: 180px; + flex: 1; + min-width: 0; } .tagsdiv .the-tags { @@ -1770,7 +1782,8 @@ table.links-table { } .is-dragging-metaboxes.post-type-attachment #post-body .meta-box-sortables { - outline: none; + border: none; + background: transparent; min-height: 0; margin-bottom: 0; } @@ -1927,9 +1940,10 @@ table.links-table { /* Tags Metabox */ .tagsdiv .newtag { - width: 100%; + flex: 1; + min-width: 0; height: auto; - margin-bottom: 15px; + margin-bottom: 0; } .tagchecklist { diff --git a/src/wp-admin/css/forms.css b/src/wp-admin/css/forms.css index 719be1aad9ba1..cc4a8e482ca42 100644 --- a/src/wp-admin/css/forms.css +++ b/src/wp-admin/css/forms.css @@ -16,7 +16,7 @@ input { textarea { overflow: auto; - padding: 2px 6px; + padding: 8px 12px; /* inherits font size 14px */ line-height: 1.42857143; /* 20px */ resize: vertical; @@ -28,7 +28,7 @@ select { } textarea.code { - padding: 4px 6px 1px; + padding: 8px 12px; } input[type="text"], @@ -48,10 +48,10 @@ input[type="week"], select, textarea { box-shadow: 0 0 0 transparent; - border-radius: 4px; - border: 1px solid #8c8f94; + border-radius: 2px; + border: 1px solid #949494; background-color: #fff; - color: #2c3338; + color: #1e1e1e; } input[type="text"], @@ -67,11 +67,17 @@ input[type="tel"], input[type="time"], input[type="url"], input[type="week"] { - padding: 0 8px; + padding: 0 12px; /* inherits font size 14px */ - line-height: 2; /* 28px */ - /* Only necessary for IE11 */ - min-height: 30px; + line-height: 2.71428571; /* 38px for 40px min-height */ + min-height: 40px; +} + +select { + padding: 0 24px 0 12px; + /* inherits font size 14px */ + line-height: 2.71428571; /* 38px for 40px min-height */ + min-height: 40px; } ::-webkit-datetime-edit { @@ -93,17 +99,26 @@ input[type="tel"]:focus, input[type="time"]:focus, input[type="url"]:focus, input[type="week"]:focus, -input[type="checkbox"]:focus, -input[type="radio"]:focus, select:focus, textarea:focus { - border-color: #2271b1; - box-shadow: 0 0 0 1px #2271b1; + border-color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color); + /* Only visible in Windows High Contrast mode */ + outline: 2px solid transparent; +} + +/* Checkbox and radio use outset focus style */ +input[type="checkbox"]:focus, +input[type="radio"]:focus { + border-color: #1e1e1e; + box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--wp-admin-theme-color); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } /* rtl:ignore */ +.ltr, +input[type="password"], input[type="email"], input[type="url"] { direction: ltr; @@ -111,10 +126,10 @@ input[type="url"] { input[type="checkbox"], input[type="radio"] { - border: 1px solid #8c8f94; - border-radius: 4px; + border: 1px solid #1e1e1e; + border-radius: 2px; background: #fff; - color: #50575e; + color: #1e1e1e; clear: none; cursor: pointer; display: inline-block; @@ -128,12 +143,12 @@ input[type="radio"] { width: 1rem; min-width: 1rem; -webkit-appearance: none; - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: none; transition: .05s border-color ease-in-out; } input[type="radio"]:checked + label:before { - color: #8c8f94; + color: #949494; } .wp-core-ui input[type="reset"]:hover, @@ -174,20 +189,30 @@ input[type="radio"]:checked::before { input[type="checkbox"]:checked::before { /* Use the "Yes" SVG Dashicon */ - content: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M14.83%204.89l1.34.94-5.81%208.38H9.02L5.78%209.67l1.34-1.25%202.57%202.4z%27%20fill%3D%27%233582c4%27%2F%3E%3C%2Fsvg%3E"); - content: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M14.83%204.89l1.34.94-5.81%208.38H9.02L5.78%209.67l1.34-1.25%202.57%202.4z%27%20fill%3D%27%233582c4%27%2F%3E%3C%2Fsvg%3E") / ''; + content: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M14.83%204.89l1.34.94-5.81%208.38H9.02L5.78%209.67l1.34-1.25%202.57%202.4z%27%20fill%3D%27%23ffffff%27%2F%3E%3C%2Fsvg%3E"); + content: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M14.83%204.89l1.34.94-5.81%208.38H9.02L5.78%209.67l1.34-1.25%202.57%202.4z%27%20fill%3D%27%23ffffff%27%2F%3E%3C%2Fsvg%3E") / ''; margin: -0.1875rem 0 0 -0.25rem; height: 1.3125rem; width: 1.3125rem; } +input[type="checkbox"]:checked { + background: var(--wp-admin-theme-color); + border-color: var(--wp-admin-theme-color); +} + +input[type="radio"]:checked { + background: var(--wp-admin-theme-color); + border-color: var(--wp-admin-theme-color); +} + input[type="radio"]:checked::before { content: ""; border-radius: 50%; width: 0.5rem; /* 8px */ height: 0.5rem; /* 8px */ margin: 0.1875rem; /* 3px */ - background-color: #3582c4; + background-color: #fff; /* 16px not sure if still necessary, comes from the MP6 redesign in r26072 */ line-height: 1.14285714; } @@ -222,15 +247,15 @@ input.readonly, input[readonly], textarea.readonly, textarea[readonly] { - background-color: #f0f0f1; + background-color: #f0f0f0; } ::-webkit-input-placeholder { - color: #646970; + color: #757575; } ::-moz-placeholder { - color: #646970; + color: #757575; } .form-invalid .form-required, @@ -276,10 +301,10 @@ select:disabled, select.disabled, textarea:disabled, textarea.disabled { - background: rgba(255, 255, 255, 0.5); - border-color: rgba(220, 220, 222, 0.75); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.04); - color: rgba(44, 51, 56, 0.5); + background: #f0f0f0; + border-color: #cccccc; + box-shadow: none; + color: #949494; } input[type="file"]:disabled, @@ -314,34 +339,35 @@ input[type="radio"].disabled:checked:before { /* Select styles are based on the default button in buttons.css */ .wp-core-ui select { font-size: 14px; - line-height: 2; /* 28px */ - color: #2c3338; - border-color: #8c8f94; + line-height: 2.71428571; /* 38px for 40px min-height */ + color: #1e1e1e; + border-color: #949494; box-shadow: none; - border-radius: 3px; - padding: 0 24px 0 8px; - min-height: 30px; + border-radius: 2px; + padding: 0 24px 0 12px; + min-height: 40px; max-width: 25rem; -webkit-appearance: none; /* The SVG is arrow-down-alt2 from Dashicons. */ - background: #fff url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E') no-repeat right 5px top 55%; + background: #fff url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%231e1e1e%22%2F%3E%3C%2Fsvg%3E') no-repeat right 8px top 55%; background-size: 16px 16px; cursor: pointer; vertical-align: middle; } .wp-core-ui select:hover { - color: #2271b1; + color: #1e1e1e; + border-color: #1e1e1e; } .wp-core-ui select:focus { - border-color: #2271b1; - color: #0a4b78; - box-shadow: 0 0 0 1px #2271b1; + border-color: var(--wp-admin-theme-color); + color: #1e1e1e; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color); } .wp-core-ui select:active { - border-color: #8c8f94; + border-color: #949494; box-shadow: none; } @@ -376,7 +402,7 @@ input[type="radio"].disabled:checked:before { } .wp-core-ui select:hover::-ms-value { - color: #2271b1; + color: #1e1e1e; } .wp-core-ui select:focus::-ms-value { @@ -471,7 +497,7 @@ textarea.large-text { input.small-text { width: 50px; - padding: 0 6px; + padding: 0 8px; } label input.small-text { @@ -480,7 +506,7 @@ label input.small-text { input[type="number"].small-text { width: 65px; - padding-right: 0; + padding-right: 4px; } input.tiny-text { @@ -496,6 +522,9 @@ input[type="number"].tiny-text { #doaction2, #post-query-submit { margin: 0 8px 0 0; + min-height: 32px; + line-height: 2.30769231; /* 30px for 32px height with 13px font */ + padding: 0 12px; } /* @since 5.7.0 secondary bulk action controls require JS. */ @@ -512,20 +541,28 @@ input[type="number"].tiny-text { float: left; margin-right: 6px; max-width: 12.5rem; + min-height: 32px; + line-height: 2.14285714; /* 30px for 32px height with 14px font */ + padding: 0 24px 0 8px; +} + +.tablenav .actions .button { + min-height: 32px; + line-height: 2.30769231; /* 30px for 32px height with 13px font */ + padding: 0 12px; } #timezone_string option { margin-left: 1em; } -.wp-hide-pw > .dashicons, -.wp-cancel-pw > .dashicons { - position: relative; - top: 3px; +.wp-core-ui .button.wp-hide-pw > .dashicons, +.wp-core-ui .button.wp-cancel-pw > .dashicons { width: 1.25rem; height: 1.25rem; - top: 0.25rem; font-size: 20px; + line-height: 1; + vertical-align: middle; } .wp-cancel-pw .dashicons-no { @@ -560,11 +597,6 @@ fieldset label, height: min-content; } -.wp-pwd button.pwd-toggle .dashicons { - position: relative; - top: 0.25rem; -} - .wp-pwd { margin-top: 1em; position: relative; @@ -603,9 +635,9 @@ fieldset label, .mailserver-pass-wrap .button.wp-hide-pw:focus { background: transparent; - border-color: #3582c4; - border-radius: 4px; - box-shadow: 0 0 0 1px #3582c4; + border-color: var(--wp-admin-theme-color); + border-radius: 2px; + box-shadow: 0 0 0 0.5px var(--wp-admin-theme-color); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -621,9 +653,10 @@ fieldset label, } #pass-strength-result { - background-color: #f0f0f1; - border: 1px solid #dcdcde; - color: #1d2327; + background-color: #f0f0f0; + border: 1px solid #cccccc; + border-radius: 2px; + color: #1e1e1e; margin: -1px 1px 5px; padding: 3px 5px; text-align: center; @@ -682,7 +715,7 @@ fieldset label, #pass1:focus, #pass1-text:focus { - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 0.5px var(--wp-admin-theme-color); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -699,7 +732,7 @@ fieldset label, .wp-pwd [type="password"] { margin-bottom: 0; /* Same height as the buttons */ - min-height: 30px; + min-height: 40px; } /* Hide the Edge "reveal password" native button */ @@ -734,7 +767,7 @@ fieldset label, .profile-php .wp-pwd .caps-warning { padding: 3px 5px; top: -4px; - border-radius: 4px; + border-radius: 2px; } .wp-pwd .caps-icon { @@ -761,16 +794,32 @@ p.search-box { margin: 11px 0; } +p.search-box input[type="search"], +p.search-box input[type="text"] { + min-height: 32px; + line-height: 2.14285714; /* 30px for 32px height with 14px font */ + padding: 0 8px; +} + +p.search-box .button { + min-height: 32px; + line-height: 2.30769231; /* 30px for 32px height with 13px font */ + padding: 0 12px; +} + .network-admin.themes-php p.search-box { clear: left; } -.tablenav .search-plugins input[name="s"], -.tagsdiv .newtag { +.tablenav .search-plugins input[name="s"] { float: left; margin: 0 4px 0 0; } +.tagsdiv .newtag { + margin: 0; +} + .js.plugins-php .search-box .wp-filter-search { margin: 0; width: 280px; @@ -819,7 +868,7 @@ ul#add-to-blog-users { /* Colors for the tags autocomplete. */ .wp-tags-autocomplete .ui-state-focus, .wp-tags-autocomplete [aria-selected="true"] { - background-color: #2271b1; + background-color: var(--wp-admin-theme-color); color: #fff; /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; @@ -1047,12 +1096,12 @@ table.form-table td .updated p { .card { position: relative; margin-top: 20px; - padding: 0.7em 2em 1em; + padding: 16px 24px; min-width: 255px; max-width: 520px; - border: 1px solid #c3c4c7; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); - background: #fff; + border: 1px solid rgb(0, 0, 0, 0.1); + border-radius: 8px; + background: #ffffff; box-sizing: border-box; } @@ -1175,6 +1224,8 @@ table.form-table td .updated p { .options-general-php input.small-text { width: 56px; margin: -2px 0; + min-height: 24px; + line-height: 1.71428571; /* 24px for 14px font size */ } .options-general-php .spinner { @@ -1366,7 +1417,7 @@ table.form-table td .updated p { } .request-filesystem-credentials-dialog .ftp-password em { - color: #8c8f94; + color: #757575; } .request-filesystem-credentials-dialog label { @@ -1531,9 +1582,9 @@ table.form-table td .updated p { input[type="url"], input[type="week"] { -webkit-appearance: none; - padding: 3px 10px; - /* Only necessary for IE11 */ + padding: 0 12px; min-height: 40px; + line-height: 2.5; /* 40px for 16px font */ } ::-webkit-datetime-edit { @@ -1585,8 +1636,8 @@ table.form-table td .updated p { .wp-admin .form-table select { min-height: 40px; font-size: 16px; - line-height: 1.625; /* 26px */ - padding: 5px 24px 5px 8px; + line-height: 2.5; /* 40px for 16px font */ + padding: 0 24px 0 12px; } .wp-admin .button-cancel { diff --git a/src/wp-admin/css/install.css b/src/wp-admin/css/install.css index 2fdd96c1091a9..104941e556616 100644 --- a/src/wp-admin/css/install.css +++ b/src/wp-admin/css/install.css @@ -26,7 +26,8 @@ a:active { a:focus { color: #043959; - box-shadow: 0 0 0 2px #2271b1; + border-radius: 2px; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -356,7 +357,9 @@ body.language-chooser { padding: 0; position: absolute; width: 1px; + /* Many screen reader and browser combinations announce broken words as they would appear visually. */ word-wrap: normal !important; + word-break: normal !important; } .spinner { diff --git a/src/wp-admin/css/list-tables.css b/src/wp-admin/css/list-tables.css index 80e652003a33c..bd548e9e71053 100644 --- a/src/wp-admin/css/list-tables.css +++ b/src/wp-admin/css/list-tables.css @@ -538,7 +538,7 @@ th.sorted.desc:hover .sorting-indicator.asc:before { } .wp-list-table .toggle-row:focus:before { - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -653,7 +653,8 @@ th.sorted a { th.sortable a:focus, th.sorted a:focus { - box-shadow: inset 0 0 0 2px #2271b1; + border-radius: 2px; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -668,6 +669,9 @@ th.sorted a span { margin: 0 2px 0 0; font-size: 13px; text-align: center; + min-height: 32px; + line-height: 2.30769231; /* 30px for 32px height with 13px font */ + padding: 0 8px; } .tablenav .total-pages { @@ -680,9 +684,8 @@ th.sorted a span { .tablenav { clear: both; - height: 30px; + height: 32px; margin: 6px 0 4px; - padding-top: 5px; vertical-align: middle; } @@ -704,12 +707,12 @@ th.sorted a span { .tablenav .tablenav-pages .tablenav-pages-navspan { display: inline-block; vertical-align: baseline; - min-width: 30px; - min-height: 30px; + min-width: 32px; + min-height: 32px; margin: 0; padding: 0 4px; font-size: 16px; - line-height: 1.625; /* 26px */ + line-height: 1.875; /* 30px for 32px height */ text-align: center; } @@ -1421,11 +1424,11 @@ ul.cat-checklist input[name="post_category[]"]:indeterminate::before { content: "\f463"; content: "\f463" / ''; display: inline-block; - font: normal 20px/1 dashicons; - margin: -3px 5px 0 -2px; + font: normal 16px/1.875 dashicons; /* line-height 1.875 = 30px to match button */ + margin: 0 5px 0 -2px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - vertical-align: middle; + vertical-align: top; } .plugin-card .updating-message:before { @@ -1449,6 +1452,14 @@ ul.cat-checklist input[name="post_category[]"]:indeterminate::before { content: "\f147" / ''; } +.plugin-card .updated-message:before, +.plugin-card .updating-message:before { + line-height: 1; + position: relative; + top: -2px; + vertical-align: middle; +} + .plugin-install-php #the-list { display: flex; flex-wrap: wrap; @@ -1487,9 +1498,11 @@ ul.cat-checklist input[name="post_category[]"]:indeterminate::before { margin: 0 8px 16px; width: 48.5%; width: calc( 50% - 8px ); - background-color: #fff; - border: 1px solid #dcdcde; + background-color: #ffffff; + border: 1px solid rgb(0, 0, 0, 0.1); + border-radius: 8px; box-sizing: border-box; + overflow: hidden; } .plugin-card:nth-child(odd) { @@ -1553,7 +1566,7 @@ ul.cat-checklist input[name="post_category[]"]:indeterminate::before { .plugin-card-top { position: relative; - padding: 20px 20px 10px; + padding: 16px; min-height: 135px; } @@ -1562,6 +1575,13 @@ div.action-links, margin: 0; /* Override existing margins */ } +/* Use compact size for space-constrained plugin cards */ +.plugin-action-buttons li .button { + min-height: 32px; + line-height: 2.30769231; /* 30px for 32px min-height */ + padding: 0 12px; +} + .plugin-card h3 { margin: 0 12px 12px 0; font-size: 18px; @@ -1668,9 +1688,9 @@ div.action-links, .plugin-card-bottom { clear: both; - padding: 12px 20px; + padding: 16px; background-color: #f6f7f7; - border-top: 1px solid #dcdcde; + border-top: 1px solid rgb(0, 0, 0, 0.1); overflow: hidden; } diff --git a/src/wp-admin/css/login.css b/src/wp-admin/css/login.css index bd14b6db22a8e..ca49a0128c1ba 100644 --- a/src/wp-admin/css/login.css +++ b/src/wp-admin/css/login.css @@ -15,7 +15,7 @@ body { } a { - color: #2271b1; + color: var(--wp-admin-theme-color-darker-10); transition-property: border, background, color; transition-duration: .05s; transition-timing-function: ease-in-out; @@ -27,12 +27,12 @@ a { a:hover, a:active { - color: #135e96; + color: var(--wp-admin-theme-color-darker-20); } a:focus { color: #043959; - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -44,22 +44,32 @@ p { .login .message, .login .notice, .login .success { - border-left: 4px solid #72aee6; - padding: 12px; + border-left: 4px solid #3858e9; + padding: 8px 12px; + margin-top: 0; margin-left: 0; margin-bottom: 20px; background-color: #fff; - box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); word-wrap: break-word; } +.login .message p, +.login .notice p, +.login .success p { + font-size: 13px; + line-height: 1.54; + margin: 0.5em 0; +} + .login .success { - border-left-color: #00a32a; + border-left-color: #4ab866; + background-color: #eff9f1; } /* Match border color from common.css */ .login .notice-error { - border-left-color: #d63638; + border-left-color: #cc1818; + background-color: #fcf0f0; } .login .login-error-list { @@ -89,6 +99,7 @@ p { margin-bottom: 15px; } +/* rtl:ignore */ .login .button.wp-hide-pw { background: transparent; border: 1px solid transparent; @@ -112,8 +123,8 @@ p { .login .button.wp-hide-pw:focus { background: transparent; - border-color: #3582c4; - box-shadow: 0 0 0 1px #3582c4; + border-color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 1px var(--wp-admin-theme-color); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -127,7 +138,6 @@ p { .login .button.wp-hide-pw .dashicons { width: 1.25rem; height: 1.25rem; - top: 0.25rem; } .login .wp-pwd { @@ -355,16 +365,11 @@ p { font-family: Consolas, Monaco, monospace; } +/* rtl:ignore */ .js.login input.password-input { padding-right: 2.5rem; } -.login form .input, -.login input[type="text"], -.login form input[type="checkbox"] { - background: #fff; -} - .js.login-action-resetpass input[type="text"], .js.login-action-resetpass input[type="password"], .js.login-action-rp input[type="text"], @@ -413,7 +418,9 @@ body.interim-login { padding: 0; position: absolute; width: 1px; - word-wrap: normal !important; /* many screen reader and browser combinations announce broken words as they would appear visually */ + /* Many screen reader and browser combinations announce broken words as they would appear visually. */ + word-wrap: normal !important; + word-break: normal !important; } /* Hide the Edge "reveal password" native button */ diff --git a/src/wp-admin/css/media.css b/src/wp-admin/css/media.css index 786a35262a212..1929b10c1ce7e 100644 --- a/src/wp-admin/css/media.css +++ b/src/wp-admin/css/media.css @@ -341,11 +341,11 @@ #find-posts-close:hover, #find-posts-close:focus { - color: #135e96; + color: var(--wp-admin-theme-color-darker-20, #183ad6); } #find-posts-close:focus { - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; outline-offset: -2px; @@ -524,7 +524,7 @@ border color while dragging a file over the uploader drop area */ .media-frame.mode-grid .attachment:focus, .media-frame.mode-grid .selected.attachment:focus, .media-frame.mode-grid .attachment.details:focus { - box-shadow: inset 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; outline-offset: -6px; @@ -539,7 +539,7 @@ border color while dragging a file over the uploader drop area */ .media-frame.mode-grid .attachment.details { box-shadow: inset 0 0 0 3px #f0f0f1, - inset 0 0 0 7px #4f94d4; + inset 0 0 0 7px var(--wp-admin-theme-color, #3858e9); } .media-frame.mode-grid.mode-select .attachment .thumbnail { @@ -557,6 +557,21 @@ border color while dragging a file over the uploader drop area */ .media-frame.mode-grid .media-toolbar select { margin: 0 10px 0 0; + min-height: 32px; + line-height: 2.14285714; /* 30px for 32px height with 14px font */ + padding: 0 24px 0 8px; +} + +.media-frame.mode-grid .media-toolbar input[type="search"] { + min-height: 32px; + line-height: 2.14285714; /* 30px for 32px height with 14px font */ + padding: 0 8px; +} + +.media-frame.mode-grid .media-toolbar .button { + min-height: 32px; + line-height: 2.30769231; /* 30px for 32px height with 13px font */ + padding: 0 12px; } .media-frame.mode-grid.mode-edit .media-toolbar-secondary > .select-mode-toggle-button { @@ -762,6 +777,12 @@ border color while dragging a file over the uploader drop area */ text-align: center; } +.edit-attachment-frame .button { + min-height: 32px; + line-height: 2.30769231; /* 30px for 32px height with 13px font */ + padding: 0 12px; +} + .edit-attachment-frame .wp-media-wrapper { margin-bottom: 12px; } diff --git a/src/wp-admin/css/nav-menus.css b/src/wp-admin/css/nav-menus.css index 0c02cde9a4997..472abb10617bf 100644 --- a/src/wp-admin/css/nav-menus.css +++ b/src/wp-admin/css/nav-menus.css @@ -221,7 +221,6 @@ input.bulk-select-switcher:focus + .bulk-select-button-label { .menu-settings-group { margin: 0 0 10px; - overflow: hidden; padding-left: 20%; } @@ -428,7 +427,6 @@ input.bulk-select-switcher:focus + .bulk-select-button-label { /* Button Secondary Actions */ .list-controls { float: left; - margin-top: 5px; } .add-to-menu { @@ -756,7 +754,7 @@ body.menu-max-depth-11 { min-width: 1280px !important; } } .nav-menus-php .item-edit:focus:before { - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -867,12 +865,17 @@ body.menu-max-depth-11 { min-width: 1280px !important; } } #nav-menus-frame, -.button-controls, #menu-item-url-wrap, #menu-item-name-wrap { display: block; } +.button-controls { + display: flex; + align-items: center; + justify-content: space-between; +} + /* =Media Queries -------------------------------------------------------------- */ diff --git a/src/wp-admin/css/revisions.css b/src/wp-admin/css/revisions.css index e25438d85e549..4cb824c8574c2 100644 --- a/src/wp-admin/css/revisions.css +++ b/src/wp-admin/css/revisions.css @@ -482,7 +482,7 @@ div.revisions-controls > .wp-slider > .ui-slider-handle { .wp-slider .ui-slider-handle.ui-state-focus { background: #f0f0f1; border-color: #8c8f94; - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } diff --git a/src/wp-admin/css/themes.css b/src/wp-admin/css/themes.css index 3b8eb28ea57b0..41754ad235edf 100644 --- a/src/wp-admin/css/themes.css +++ b/src/wp-admin/css/themes.css @@ -64,9 +64,11 @@ body.js .theme-browser.search-loading { margin: 0 4% 4% 0; position: relative; width: 30.6%; - border: 1px solid #dcdcde; - box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.1); + background: #ffffff; + border: 1px solid rgb(0, 0, 0, 0.1); + border-radius: 8px; box-sizing: border-box; + overflow: hidden; } .theme-browser .theme:nth-child(3n) { @@ -83,13 +85,12 @@ body.js .theme-browser.search-loading { font-weight: 600; height: 18px; margin: 0; - padding: 15px; - box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1); + padding: 16px 15px; + border-top: 1px solid rgb(0, 0, 0, 0.1); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; - background: #fff; - background: rgba(255, 255, 255, 0.65); + background: #ffffff; } /* Activate and Customize buttons, shown on hover and focus */ @@ -112,9 +113,36 @@ body.js .theme-browser.search-loading { margin-right: 3px; } +/* Use compact size for space-constrained theme cards */ +.theme-browser .theme .theme-actions .button.updated-message, +.theme-browser .theme .theme-actions .button.updating-message, .theme-browser .theme .theme-actions .button { float: none; margin-left: 3px; + min-height: 32px; + line-height: 2.30769231; /* 30px for 32px min-height */ + padding: 0 12px; +} + +.theme-browser .theme .theme-actions .button.updated-message::before, +.theme-browser .theme .theme-actions .button.updating-message::before { + line-height: 1; + vertical-align: text-bottom; + position: relative; + top: 2px; +} + +/* Secondary buttons need white background for visibility on semi-transparent overlay */ +.theme-browser .theme .theme-actions .button:not(.button-primary) { + background: #fff; +} + +.theme-browser .theme .theme-actions .button:not(.button-primary):hover { + background: #f0f0f0; +} + +.theme-browser .theme .theme-actions .button:not(.button-primary):focus { + background: #fff; } /** @@ -180,12 +208,12 @@ body.js .theme-browser.search-loading { } .theme-browser .theme .more-details:focus { - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); } .theme-browser .theme.focus { - border-color: #2271b1; - box-shadow: 0 0 0 1px #2271b1; + border-color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -211,7 +239,7 @@ body.js .theme-browser.search-loading { .theme-browser .theme.active .theme-name { background: #1d2327; color: #fff; - padding-right: 110px; + padding-right: 115px; font-weight: 300; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5); } @@ -240,7 +268,7 @@ body.js .theme-browser.search-loading { top: 50%; transform: translateY(-50%); right: 0; - padding: 9px 15px; + padding: 9px 12px; box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1); } @@ -248,6 +276,19 @@ body.js .theme-browser.search-loading { margin-right: 0; } +/* Active theme secondary buttons need white background for visibility on dark overlay */ +.theme-browser .theme.active .theme-actions .button:not(.button-primary) { + background: #fff; +} + +.theme-browser .theme.active .theme-actions .button:not(.button-primary):hover { + background: #f0f0f0; +} + +.theme-browser .theme.active .theme-actions .button:not(.button-primary):focus { + background: #fff; +} + .theme-browser .theme .theme-author { background: #1d2327; color: #f0f0f1; @@ -271,8 +312,9 @@ body.js .theme-browser.search-loading { * Add new theme */ .theme-browser .theme.add-new-theme { + background: transparent; border: none; - box-shadow: none; + overflow: visible; } .theme-browser .theme.add-new-theme a { @@ -348,8 +390,8 @@ body.js .theme-browser.search-loading { .theme-browser .theme.add-new-theme .theme-name { background: none; + border: none; text-align: center; - box-shadow: none; font-weight: 400; position: relative; top: 0; @@ -1101,7 +1143,7 @@ body.folded .theme-browser ~ .theme-overlay .theme-wrap { padding: 30px 128px 30px 30px; } -.upload-plugin .wp-upload-form input[type=submit], +.upload-plugin .wp-upload-form input[type=submit], .upload-theme .wp-upload-form input[type=submit] { position: absolute; right: 30px; @@ -1356,10 +1398,6 @@ div#custom-background-image img { transform: rotate( 45deg ); } -.background-position-control .button-group .dashicons { - margin-top: 9px; -} - .background-position-control .button-group + .button-group { margin-top: -1px; } @@ -1475,7 +1513,7 @@ body.full-overlay-active { } .wp-full-overlay-sidebar .wp-full-overlay-header a.back { - margin-top: 9px; + margin-top: 3px; /* Vertically center 40px button in 45px header */ } .wp-full-overlay-sidebar .wp-full-overlay-footer { @@ -1620,7 +1658,7 @@ body.full-overlay-active { .wp-full-overlay .collapse-sidebar:hover .collapse-sidebar-arrow, .wp-full-overlay .collapse-sidebar:focus .collapse-sidebar-arrow { - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -1923,7 +1961,7 @@ body.full-overlay-active { .theme-install-overlay .wp-full-overlay-header .button { float: right; - margin: 8px 10px 0 0; + margin: 3px 10px 0 0; /* Vertically center 40px button in 45px header */ } .theme-install-overlay .wp-full-overlay-sidebar { @@ -2028,7 +2066,7 @@ body.full-overlay-active { width: 100%; } - .upload-plugin .wp-upload-form input[type=file], + .upload-plugin .wp-upload-form input[type=file], .upload-theme .wp-upload-form input[type=file] { padding: 30px 30px 80px; width: 100%; diff --git a/src/wp-admin/css/widgets.css b/src/wp-admin/css/widgets.css index 96ddd922792ed..99039d3c7c66a 100644 --- a/src/wp-admin/css/widgets.css +++ b/src/wp-admin/css/widgets.css @@ -336,7 +336,7 @@ } .sidebar-name .handlediv:focus .toggle-indicator:before { - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -582,6 +582,12 @@ div#widgets-right .closed .widgets-sortables { padding: 0 15px; } +.widget-control-actions { + display: flex; + align-items: center; + justify-content: space-between; +} + .editwidget .widget-control-actions { margin-top: 20px; } @@ -724,7 +730,7 @@ div#widgets-right .widget-top:hover, } .widgets-chooser .widgets-chooser-selected .widgets-chooser-button { - background: #2271b1; + background: var(--wp-admin-theme-color, #3858e9); color: #fff; } diff --git a/src/wp-admin/customize.php b/src/wp-admin/customize.php index 1f1a9d38b1a9e..2065e55ffb3ce 100644 --- a/src/wp-admin/customize.php +++ b/src/wp-admin/customize.php @@ -148,7 +148,7 @@ } $body_class .= ' locale-' . sanitize_html_class( strtolower( str_replace( '_', '-', get_user_locale() ) ) ); $admin_color = get_user_option( 'admin_color' ); -$body_class .= ' admin-color-' . sanitize_html_class( is_string( $admin_color ) ? $admin_color : '', 'fresh' ); +$body_class .= ' admin-color-' . sanitize_html_class( is_string( $admin_color ) ? $admin_color : '', 'modern' ); if ( wp_use_widgets_block_editor() ) { $body_class .= ' wp-embed-responsive'; diff --git a/src/wp-admin/edit-comments.php b/src/wp-admin/edit-comments.php index 29ec964924a4d..46cf66d393985 100644 --- a/src/wp-admin/edit-comments.php +++ b/src/wp-admin/edit-comments.php @@ -319,13 +319,13 @@ || isset( $_REQUEST['unspammed'] ) || isset( $_REQUEST['same'] ) ) { - $approved = isset( $_REQUEST['approved'] ) ? (int) $_REQUEST['approved'] : 0; - $deleted = isset( $_REQUEST['deleted'] ) ? (int) $_REQUEST['deleted'] : 0; - $trashed = isset( $_REQUEST['trashed'] ) ? (int) $_REQUEST['trashed'] : 0; - $untrashed = isset( $_REQUEST['untrashed'] ) ? (int) $_REQUEST['untrashed'] : 0; - $spammed = isset( $_REQUEST['spammed'] ) ? (int) $_REQUEST['spammed'] : 0; - $unspammed = isset( $_REQUEST['unspammed'] ) ? (int) $_REQUEST['unspammed'] : 0; - $same = isset( $_REQUEST['same'] ) ? (int) $_REQUEST['same'] : 0; + $approved = (int) ( $_REQUEST['approved'] ?? 0 ); + $deleted = (int) ( $_REQUEST['deleted'] ?? 0 ); + $trashed = (int) ( $_REQUEST['trashed'] ?? 0 ); + $untrashed = (int) ( $_REQUEST['untrashed'] ?? 0 ); + $spammed = (int) ( $_REQUEST['spammed'] ?? 0 ); + $unspammed = (int) ( $_REQUEST['unspammed'] ?? 0 ); + $same = (int) ( $_REQUEST['same'] ?? 0 ); if ( $approved > 0 || $deleted > 0 || $trashed > 0 || $untrashed > 0 || $spammed > 0 || $unspammed > 0 || $same > 0 ) { if ( $approved > 0 ) { diff --git a/src/wp-admin/edit-form-blocks.php b/src/wp-admin/edit-form-blocks.php index d0f2000fdce17..2237fc69ce293 100644 --- a/src/wp-admin/edit-form-blocks.php +++ b/src/wp-admin/edit-form-blocks.php @@ -92,6 +92,12 @@ static function ( $classes ) { 'description', 'gmt_offset', 'home', + 'image_sizes', + 'image_size_threshold', + 'image_output_formats', + 'jpeg_interlaced', + 'png_interlaced', + 'gif_interlaced', 'name', 'site_icon', 'site_icon_url', diff --git a/src/wp-admin/edit-form-comment.php b/src/wp-admin/edit-form-comment.php index cb6ab78e8f968..e0bbc9f657a73 100644 --- a/src/wp-admin/edit-form-comment.php +++ b/src/wp-admin/edit-form-comment.php @@ -62,7 +62,7 @@ - + diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php index e79642dc0b46e..f52f5f5c1d80f 100644 --- a/src/wp-admin/includes/ajax-actions.php +++ b/src/wp-admin/includes/ajax-actions.php @@ -1241,7 +1241,7 @@ function wp_ajax_get_tagcloud() { * * @since 3.1.0 * - * @global int $post_id + * @global int $post_id Post ID. * * @param string $action Action to perform. */ @@ -2353,9 +2353,9 @@ function wp_ajax_widgets_order() { * * @since 3.1.0 * - * @global array $wp_registered_widgets - * @global array $wp_registered_widget_controls - * @global array $wp_registered_widget_updates + * @global array $wp_registered_widgets Registered widgets. + * @global array $wp_registered_widget_controls Registered widget controls. + * @global array $wp_registered_widget_updates Registered widget updates. */ function wp_ajax_save_widget() { global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates; @@ -2462,7 +2462,7 @@ function wp_ajax_save_widget() { * * @since 3.9.0 * - * @global WP_Customize_Manager $wp_customize + * @global WP_Customize_Manager $wp_customize Customizer manager object. */ function wp_ajax_update_widget() { global $wp_customize; @@ -3588,7 +3588,7 @@ function wp_ajax_get_revision_diffs() { * * @since 3.8.0 * - * @global array $_wp_admin_css_colors + * @global array $_wp_admin_css_colors Registered admin CSS color schemes. */ function wp_ajax_save_user_color_scheme() { global $_wp_admin_css_colors; @@ -3617,8 +3617,8 @@ function wp_ajax_save_user_color_scheme() { * * @since 3.9.0 * - * @global array $themes_allowedtags - * @global array $theme_field_defaults + * @global array $themes_allowedtags Allowed HTML tags for theme descriptions. + * @global array $theme_field_defaults Default theme fields. */ function wp_ajax_query_themes() { global $themes_allowedtags, $theme_field_defaults; @@ -3750,8 +3750,8 @@ function wp_ajax_query_themes() { * * @global WP_Post $post Global post object. * @global WP_Embed $wp_embed WordPress Embed object. - * @global WP_Scripts $wp_scripts - * @global int $content_width + * @global WP_Scripts $wp_scripts Script dependencies object. + * @global int $content_width Shared post content width. */ function wp_ajax_parse_embed() { global $post, $wp_embed, $content_width; @@ -3891,7 +3891,7 @@ function wp_ajax_parse_embed() { * @since 4.0.0 * * @global WP_Post $post Global post object. - * @global WP_Scripts $wp_scripts + * @global WP_Scripts $wp_scripts Script dependencies object. */ function wp_ajax_parse_media_shortcode() { global $post, $wp_scripts; diff --git a/src/wp-admin/includes/class-core-upgrader.php b/src/wp-admin/includes/class-core-upgrader.php index 184376654295e..8a712a4afbc76 100644 --- a/src/wp-admin/includes/class-core-upgrader.php +++ b/src/wp-admin/includes/class-core-upgrader.php @@ -48,7 +48,7 @@ public function upgrade_strings() { * @since 2.8.0 * * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. - * @global callable $_wp_filesystem_direct_method + * @global callable $_wp_filesystem_direct_method Filesystem direct method callback. * * @param object $current Response object for whether WordPress is current. * @param array $args { diff --git a/src/wp-admin/includes/class-custom-image-header.php b/src/wp-admin/includes/class-custom-image-header.php index f95f9bc95dfe5..eb65605728062 100644 --- a/src/wp-admin/includes/class-custom-image-header.php +++ b/src/wp-admin/includes/class-custom-image-header.php @@ -268,7 +268,7 @@ public function take_action() { * * @since 3.0.0 * - * @global array $_wp_default_headers + * @global array $_wp_default_headers Default headers registered for themes. */ public function process_default_headers() { global $_wp_default_headers; diff --git a/src/wp-admin/includes/class-theme-upgrader.php b/src/wp-admin/includes/class-theme-upgrader.php index 47062d3fd60dc..9a963d433cf7e 100644 --- a/src/wp-admin/includes/class-theme-upgrader.php +++ b/src/wp-admin/includes/class-theme-upgrader.php @@ -746,7 +746,7 @@ public function current_after( $response, $theme ) { * * @since 2.8.0 * - * @global WP_Filesystem_Base $wp_filesystem Subclass + * @global WP_Filesystem_Base $wp_filesystem Filesystem subclass. * * @param bool $removed * @param string $local_destination diff --git a/src/wp-admin/includes/class-walker-nav-menu-checklist.php b/src/wp-admin/includes/class-walker-nav-menu-checklist.php index 099d2500762bb..b4e4f1a48049a 100644 --- a/src/wp-admin/includes/class-walker-nav-menu-checklist.php +++ b/src/wp-admin/includes/class-walker-nav-menu-checklist.php @@ -64,8 +64,8 @@ public function end_lvl( &$output, $depth = 0, $args = null ) { * @since 5.9.0 Renamed `$item` to `$data_object` and `$id` to `$current_object_id` * to match parent class for PHP 8 named parameter support. * - * @global int $_nav_menu_placeholder - * @global int|string $nav_menu_selected_id + * @global int $_nav_menu_placeholder A placeholder for the nav menu item ID. + * @global int|string $nav_menu_selected_id The ID of the selected nav menu. * * @param string $output Used to append additional content (passed by reference). * @param WP_Post $data_object Menu item data object. diff --git a/src/wp-admin/includes/class-walker-nav-menu-edit.php b/src/wp-admin/includes/class-walker-nav-menu-edit.php index 66ea47bb1fd0e..44a57c0c99f26 100644 --- a/src/wp-admin/includes/class-walker-nav-menu-edit.php +++ b/src/wp-admin/includes/class-walker-nav-menu-edit.php @@ -49,7 +49,7 @@ public function end_lvl( &$output, $depth = 0, $args = null ) {} * @since 5.9.0 Renamed `$item` to `$data_object` and `$id` to `$current_object_id` * to match parent class for PHP 8 named parameter support. * - * @global int $_wp_nav_menu_max_depth + * @global int $_wp_nav_menu_max_depth The maximum depth of the nav menu. * * @param string $output Used to append additional content (passed by reference). * @param WP_Post $data_object Menu item data object. diff --git a/src/wp-admin/includes/class-wp-comments-list-table.php b/src/wp-admin/includes/class-wp-comments-list-table.php index 78d6215376569..1feaeb3283bcd 100644 --- a/src/wp-admin/includes/class-wp-comments-list-table.php +++ b/src/wp-admin/includes/class-wp-comments-list-table.php @@ -31,7 +31,7 @@ class WP_Comments_List_Table extends WP_List_Table { * * @see WP_List_Table::__construct() for more information on default arguments. * - * @global int $post_id + * @global int $post_id The ID of the post to show comments for. * * @param array $args An associative array of arguments. */ @@ -224,8 +224,7 @@ public function get_per_page( $comment_status = 'all' ) { /** * Displays a message when no comments are found. - * - * @global string $comment_status + * @global string $comment_status The current comment status filter. */ public function no_items() { global $comment_status; @@ -242,9 +241,9 @@ public function no_items() { /** * Returns an array of comment status links. * - * @global int $post_id - * @global string $comment_status - * @global string $comment_type + * @global int $post_id The ID of the post to show comments for. + * @global string $comment_status The current comment status. + * @global string $comment_type The current comment type. * * @return array Comment status HTML links keyed by view. */ @@ -412,8 +411,8 @@ protected function get_bulk_actions() { /** * Displays extra controls between bulk actions and pagination. * - * @global string $comment_status - * @global string $comment_type + * @global string $comment_status Current comment status. + * @global string $comment_type Current comment type. * * @param string $which The location of the extra table nav markup: Either 'top' or 'bottom'. */ @@ -485,7 +484,7 @@ public function current_action() { /** * Gets the list of columns. * - * @global int $post_id + * @global int $post_id The ID of the post comments are being shown for. * * @return string[] Array of column titles keyed by their column name. */ @@ -1011,7 +1010,7 @@ public function column_comment( $comment ) { /** * Outputs the author column. * - * @global string $comment_status + * @global string $comment_status The current comment status. * * @param WP_Comment $comment The comment object. */ diff --git a/src/wp-admin/includes/class-wp-debug-data.php b/src/wp-admin/includes/class-wp-debug-data.php index aa0f3eb10ce45..f2399b30550c9 100644 --- a/src/wp-admin/includes/class-wp-debug-data.php +++ b/src/wp-admin/includes/class-wp-debug-data.php @@ -373,8 +373,8 @@ private static function get_wp_server(): array { ); $fields['httpd_software'] = array( 'label' => __( 'Web server' ), - 'value' => $_SERVER['SERVER_SOFTWARE'] ?? __( 'Unable to determine what web server software is used' ), - 'debug' => $_SERVER['SERVER_SOFTWARE'] ?? 'unknown', + 'value' => ! empty( $_SERVER['SERVER_SOFTWARE'] ) ? wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) : __( 'Unable to determine what web server software is used' ), + 'debug' => ! empty( $_SERVER['SERVER_SOFTWARE'] ) ? wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) : 'unknown', ); $fields['php_version'] = array( 'label' => __( 'PHP version' ), @@ -471,6 +471,83 @@ private static function get_wp_server(): array { 'debug' => $imagick_loaded, ); + // Opcode Cache. + if ( function_exists( 'opcache_get_status' ) ) { + $opcache_status = @opcache_get_status( false ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- Warning emitted in failure case. + + if ( false === $opcache_status ) { + $fields['opcode_cache'] = array( + 'label' => __( 'Opcode cache' ), + 'value' => __( 'Disabled by configuration' ), + 'debug' => 'not available', + ); + } else { + $fields['opcode_cache'] = array( + 'label' => __( 'Opcode cache' ), + 'value' => $opcache_status['opcache_enabled'] ? __( 'Enabled' ) : __( 'Disabled' ), + 'debug' => $opcache_status['opcache_enabled'], + ); + + if ( true === $opcache_status['opcache_enabled'] ) { + $fields['opcode_cache_memory_usage'] = array( + 'label' => __( 'Opcode cache memory usage' ), + 'value' => sprintf( + /* translators: 1: Used memory, 2: Total memory */ + __( '%1$s of %2$s' ), + size_format( $opcache_status['memory_usage']['used_memory'] ), + size_format( $opcache_status['memory_usage']['free_memory'] + $opcache_status['memory_usage']['used_memory'] ) + ), + 'debug' => sprintf( + '%s of %s', + $opcache_status['memory_usage']['used_memory'], + $opcache_status['memory_usage']['free_memory'] + $opcache_status['memory_usage']['used_memory'] + ), + ); + + if ( 0 !== $opcache_status['interned_strings_usage']['buffer_size'] ) { + $fields['opcode_cache_interned_strings_usage'] = array( + 'label' => __( 'Opcode cache interned strings usage' ), + 'value' => sprintf( + /* translators: 1: Percentage used, 2: Total memory, 3: Free memory */ + __( '%1$s%% of %2$s (%3$s free)' ), + number_format_i18n( ( $opcache_status['interned_strings_usage']['used_memory'] / $opcache_status['interned_strings_usage']['buffer_size'] ) * 100, 2 ), + size_format( $opcache_status['interned_strings_usage']['buffer_size'] ), + size_format( $opcache_status['interned_strings_usage']['free_memory'] ) + ), + 'debug' => sprintf( + '%s%% of %s (%s free)', + round( ( $opcache_status['interned_strings_usage']['used_memory'] / $opcache_status['interned_strings_usage']['buffer_size'] ) * 100, 2 ), + $opcache_status['interned_strings_usage']['buffer_size'], + $opcache_status['interned_strings_usage']['free_memory'] + ), + ); + } + + $fields['opcode_cache_hit_rate'] = array( + 'label' => __( 'Opcode cache hit rate' ), + 'value' => sprintf( + /* translators: %s: Hit rate percentage */ + __( '%s%%' ), + number_format_i18n( $opcache_status['opcache_statistics']['opcache_hit_rate'], 2 ) + ), + 'debug' => round( $opcache_status['opcache_statistics']['opcache_hit_rate'], 2 ), + ); + + $fields['opcode_cache_full'] = array( + 'label' => __( 'Is the Opcode cache full?' ), + 'value' => $opcache_status['cache_full'] ? __( 'Yes' ) : __( 'No' ), + 'debug' => $opcache_status['cache_full'], + ); + } + } + } else { + $fields['opcode_cache'] = array( + 'label' => __( 'Opcode cache' ), + 'value' => __( 'Disabled' ), + 'debug' => 'not available', + ); + } + // Pretty permalinks. $pretty_permalinks_supported = got_url_rewrite(); @@ -545,7 +622,7 @@ private static function get_wp_server(): array { ); $fields['server-time'] = array( 'label' => __( 'Current Server time' ), - 'value' => wp_date( 'c', $_SERVER['REQUEST_TIME'] ), + 'value' => isset( $_SERVER['REQUEST_TIME'] ) ? wp_date( 'c', (int) $_SERVER['REQUEST_TIME'] ) : __( 'Unable to determine server time' ), ); return array( @@ -1055,7 +1132,7 @@ private static function get_wp_plugins_raw_data(): array { * * @since 6.7.0 * - * @global array $_wp_theme_features + * @global array $_wp_theme_features The theme features for the active theme. * * @return array The active theme debug data. */ diff --git a/src/wp-admin/includes/class-wp-filesystem-direct.php b/src/wp-admin/includes/class-wp-filesystem-direct.php index ed22a821a14b0..a4b197c15229f 100644 --- a/src/wp-admin/includes/class-wp-filesystem-direct.php +++ b/src/wp-admin/includes/class-wp-filesystem-direct.php @@ -170,6 +170,22 @@ public function chmod( $file, $mode = false, $recursive = false ) { } if ( ! $recursive || ! $this->is_dir( $file ) ) { + $current_mode = fileperms( $file ) & 0777 | 0644; + + /* + * fileperms() populates the stat cache, so have to clear it + * to maintain parity with the previous behavior. + */ + clearstatcache( true, $file ); + + /* + * Avoid calling chmod() if the requested mode is already set, + * to prevent throwing a warning when we aren't the owner. + */ + if ( $current_mode === $mode ) { + return true; + } + return chmod( $file, $mode ); } diff --git a/src/wp-admin/includes/class-wp-filesystem-ssh2.php b/src/wp-admin/includes/class-wp-filesystem-ssh2.php index 9e0cb885b0bcc..9146045025942 100644 --- a/src/wp-admin/includes/class-wp-filesystem-ssh2.php +++ b/src/wp-admin/includes/class-wp-filesystem-ssh2.php @@ -670,9 +670,11 @@ public function size( $file ) { * Default 0. * @param int $atime Optional. Access time to set for file. * Default 0. + * @return false Always returns false because not implemented. */ public function touch( $file, $time = 0, $atime = 0 ) { // Not implemented. + return false; } /** diff --git a/src/wp-admin/includes/class-wp-importer.php b/src/wp-admin/includes/class-wp-importer.php index ef680f5d62d8c..085a5adc0e71a 100644 --- a/src/wp-admin/includes/class-wp-importer.php +++ b/src/wp-admin/includes/class-wp-importer.php @@ -279,7 +279,7 @@ public function min_whitespace( $text ) { * @since 3.0.0 * * @global wpdb $wpdb WordPress database abstraction object. - * @global int[] $wp_actions + * @global int[] $wp_actions Stores the number of times each action was triggered. */ public function stop_the_insanity() { global $wpdb, $wp_actions; diff --git a/src/wp-admin/includes/class-wp-links-list-table.php b/src/wp-admin/includes/class-wp-links-list-table.php index 744193e0ec4ae..309a00801adba 100644 --- a/src/wp-admin/includes/class-wp-links-list-table.php +++ b/src/wp-admin/includes/class-wp-links-list-table.php @@ -42,10 +42,10 @@ public function ajax_user_can() { } /** - * @global int $cat_id - * @global string $s - * @global string $orderby - * @global string $order + * @global int $cat_id Link category ID. + * @global string $s Search string. + * @global string $orderby The field to order the links by. + * @global string $order The direction to order the links. */ public function prepare_items() { global $cat_id, $s, $orderby, $order; @@ -77,12 +77,15 @@ public function prepare_items() { } /** + * Displays the message for no items. */ public function no_items() { _e( 'No links found.' ); } /** + * Gets the list of bulk actions. + * * @return array */ protected function get_bulk_actions() { @@ -93,8 +96,8 @@ protected function get_bulk_actions() { } /** - * @global int $cat_id - * @param string $which + * @global int $cat_id Link category ID. + * @param string $which The location: 'top' or 'bottom'. */ protected function extra_tablenav( $which ) { global $cat_id; @@ -142,6 +145,8 @@ public function get_columns() { } /** + * Gets the list of sortable columns. + * * @return array */ protected function get_sortable_columns() { @@ -224,7 +229,7 @@ public function column_url( $link ) { * * @since 4.3.0 * - * @global int $cat_id + * @global int $cat_id Link category ID. * * @param object $link The current link object. */ diff --git a/src/wp-admin/includes/class-wp-list-table.php b/src/wp-admin/includes/class-wp-list-table.php index e31e89a36fb5a..0795da27535c6 100644 --- a/src/wp-admin/includes/class-wp-list-table.php +++ b/src/wp-admin/includes/class-wp-list-table.php @@ -1692,7 +1692,7 @@ protected function display_tablenav( $which ) { * * @since 3.1.0 * - * @param string $which + * @param string $which The location: 'top' or 'bottom'. */ protected function extra_tablenav( $which ) {} diff --git a/src/wp-admin/includes/class-wp-media-list-table.php b/src/wp-admin/includes/class-wp-media-list-table.php index 5e26ebb9e118b..4a257804ff01c 100644 --- a/src/wp-admin/includes/class-wp-media-list-table.php +++ b/src/wp-admin/includes/class-wp-media-list-table.php @@ -23,8 +23,20 @@ class WP_Media_List_Table extends WP_List_Table { */ protected $comment_pending_count = array(); + /** + * Whether the list table is for detached media. + * + * @since 3.1.0 + * @var bool + */ private $detached; + /** + * Whether the list table is for trash. + * + * @since 3.1.0 + * @var bool + */ private $is_trash; /** @@ -53,6 +65,10 @@ public function __construct( $args = array() ) { } /** + * Checks if the current user has permissions to upload files. + * + * @since 3.1.0 + * * @return bool Whether the user can upload files. */ public function ajax_user_can() { @@ -60,10 +76,14 @@ public function ajax_user_can() { } /** + * Prepares the list of items for displaying. + * + * @since 3.1.0 + * * @global string $mode List table view mode. * @global WP_Query $wp_query WordPress Query object. - * @global array $post_mime_types - * @global array $avail_post_mime_types + * @global array $post_mime_types An array of post mime types. + * @global array $avail_post_mime_types An array of available post mime types. */ public function prepare_items() { global $mode, $wp_query, $post_mime_types, $avail_post_mime_types; @@ -117,8 +137,12 @@ public function prepare_items() { } /** - * @global array $post_mime_types - * @global array $avail_post_mime_types + * Gets an array of links for the available views on this table. + * + * @since 3.1.0 + * + * @global array $post_mime_types An array of post mime types. + * @global array $avail_post_mime_types An array of available post mime types. * @return array An array of links for the available views. */ protected function get_views() { @@ -198,7 +222,11 @@ protected function get_bulk_actions() { } /** - * @param string $which + * Displays extra controls between bulk actions and pagination. + * + * @since 3.1.0 + * + * @param string $which The location of the extra table nav: 'top' or 'bottom'. */ protected function extra_tablenav( $which ) { if ( 'bar' !== $which ) { @@ -253,6 +281,9 @@ public function has_items() { } /** + * Displays a message when no media items are found. + * + * @since 3.1.0 */ public function no_items() { if ( $this->is_trash ) { @@ -459,10 +490,8 @@ public function column_title( $post ) { if ( current_user_can( 'edit_post', $post->ID ) && ! $this->is_trash ) { $link_start = sprintf( - '', + '', get_edit_post_link( $post->ID ), - /* translators: %s: Attachment title. */ - esc_attr( sprintf( __( '“%s” (Edit)' ), $title ) ) ); $link_end = ''; } @@ -762,8 +791,12 @@ protected function get_default_primary_column_name() { } /** - * @param WP_Post $post - * @param string $att_title + * Gets the row actions for a media item. + * + * @since 3.1.0 + * + * @param WP_Post $post The current WP_Post object. + * @param string $att_title The attachment title. * @return array An array of row actions. */ private function _get_row_actions( $post, $att_title ) { diff --git a/src/wp-admin/includes/class-wp-ms-sites-list-table.php b/src/wp-admin/includes/class-wp-ms-sites-list-table.php index 9214927bee9f8..f4a937962ed19 100644 --- a/src/wp-admin/includes/class-wp-ms-sites-list-table.php +++ b/src/wp-admin/includes/class-wp-ms-sites-list-table.php @@ -50,7 +50,11 @@ public function __construct( $args = array() ) { } /** - * @return bool + * Checks if the current user has permissions to manage sites. + * + * @since 3.1.0 + * + * @return bool Whether the user can manage sites. */ public function ajax_user_can() { return current_user_can( 'manage_sites' ); @@ -62,7 +66,7 @@ public function ajax_user_can() { * @since 3.1.0 * * @global string $mode List table view mode. - * @global string $s + * @global string $s Search string. * @global wpdb $wpdb WordPress database abstraction object. */ public function prepare_items() { @@ -206,6 +210,9 @@ public function prepare_items() { } /** + * Displays a message when no sites are found. + * + * @since 3.1.0 */ public function no_items() { _e( 'No sites found.' ); @@ -286,7 +293,11 @@ protected function get_views() { } /** - * @return array + * Gets an associative array of bulk actions for this table. + * + * @since 3.1.0 + * + * @return array An associative array of bulk actions. */ protected function get_bulk_actions() { $actions = array(); @@ -300,6 +311,10 @@ protected function get_bulk_actions() { } /** + * Displays the pagination. + * + * @since 3.1.0 + * * @global string $mode List table view mode. * * @param string $which The location of the pagination nav markup: Either 'top' or 'bottom'. @@ -359,6 +374,10 @@ protected function extra_tablenav( $which ) { } /** + * Gets an array of column titles keyed by their column name. + * + * @since 3.1.0 + * * @return string[] Array of column titles keyed by their column name. */ public function get_columns() { @@ -386,7 +405,11 @@ public function get_columns() { } /** - * @return array + * Gets an array of sortable columns. + * + * @since 3.1.0 + * + * @return array An array of sortable columns. */ protected function get_sortable_columns() { @@ -640,7 +663,7 @@ public function display_rows() { * * @since 5.3.0 * - * @param array $site + * @param array $site An array of site data. */ protected function site_states( $site ) { $site_states = array(); diff --git a/src/wp-admin/includes/class-wp-ms-themes-list-table.php b/src/wp-admin/includes/class-wp-ms-themes-list-table.php index 37caa4b361dbf..6a1fbdfb8dfd2 100644 --- a/src/wp-admin/includes/class-wp-ms-themes-list-table.php +++ b/src/wp-admin/includes/class-wp-ms-themes-list-table.php @@ -37,8 +37,8 @@ class WP_MS_Themes_List_Table extends WP_List_Table { * * @see WP_List_Table::__construct() for more information on default arguments. * - * @global string $status - * @global int $page + * @global string $status The current theme status. + * @global int $page The current page number. * * @param array $args An associative array of arguments. */ @@ -70,7 +70,9 @@ public function __construct( $args = array() ) { } /** - * @return array + * Gets the list of CSS classes for the table tag. + * + * @return string[] The list of CSS classes. */ protected function get_table_classes() { // @todo Remove and add CSS for .themes. @@ -78,7 +80,9 @@ protected function get_table_classes() { } /** - * @return bool + * Checks if the current user has permissions to perform AJAX actions. + * + * @return bool True if the current user has permissions, false otherwise. */ public function ajax_user_can() { if ( $this->is_site_themes ) { @@ -89,12 +93,14 @@ public function ajax_user_can() { } /** - * @global string $status - * @global array $totals - * @global int $page - * @global string $orderby - * @global string $order - * @global string $s + * Prepares the themes list for display. + * + * @global string $status The current theme status. + * @global array $totals An array of theme counts for each status. + * @global int $page The current page number. + * @global string $orderby The column to order the themes list by. + * @global string $order The order of the themes list (ASC or DESC). + * @global string $s The search string. */ public function prepare_items() { global $status, $totals, $page, $orderby, $order, $s; @@ -261,8 +267,10 @@ public function prepare_items() { } /** - * @param WP_Theme $theme - * @return bool + * Filters a theme by the search term. + * + * @param WP_Theme $theme The WP_Theme object to check. + * @return bool True if the theme matches the search term, false otherwise. */ public function _search_callback( $theme ) { static $term = null; @@ -290,11 +298,14 @@ public function _search_callback( $theme ) { // Not used by any core columns. /** - * @global string $orderby - * @global string $order - * @param array $theme_a - * @param array $theme_b - * @return int + * Compares the order of two themes by a specific field. + * + * @global string $orderby The column to order the themes list by. + * @global string $order The order of the themes list (ASC or DESC). + * + * @param WP_Theme $theme_a The first theme to compare. + * @param WP_Theme $theme_b The second theme to compare. + * @return int 0 if equal, -1 if the first is less than the second, 1 if more. */ public function _order_callback( $theme_a, $theme_b ) { global $orderby, $order; @@ -308,6 +319,7 @@ public function _order_callback( $theme_a, $theme_b ) { } /** + * Displays the message when there are no items to list. */ public function no_items() { if ( $this->has_items ) { @@ -318,7 +330,9 @@ public function no_items() { } /** - * @return string[] Array of column titles keyed by their column name. + * Gets the list of columns for the list table. + * + * @return array Array of column titles keyed by their column name. */ public function get_columns() { $columns = array( @@ -335,7 +349,9 @@ public function get_columns() { } /** - * @return array + * Gets the list of sortable columns for the list table. + * + * @return array> An array of sortable columns. */ protected function get_sortable_columns() { return array( @@ -355,9 +371,12 @@ protected function get_primary_column_name() { } /** - * @global array $totals - * @global string $status - * @return array + * Gets the list of views (statuses) for the list table. + * + * @global array $totals An array of theme counts for each status. + * @global string $status The current theme status. + * + * @return array The list of views. */ protected function get_views() { global $totals, $status; @@ -451,9 +470,11 @@ protected function get_views() { } /** - * @global string $status + * Gets the list of bulk actions for the list table. + * + * @global string $status The current theme status. * - * @return array + * @return array The list of bulk actions. */ protected function get_bulk_actions() { global $status; @@ -532,9 +553,9 @@ public function column_cb( $item ) { * * @since 4.3.0 * - * @global string $status - * @global int $page - * @global string $s + * @global string $status The current theme status. + * @global int $page The current page number. + * @global string $s The search string. * * @param WP_Theme $theme The current WP_Theme object. */ @@ -689,8 +710,8 @@ public function column_name( $theme ) { * * @since 4.3.0 * - * @global string $status - * @global array $totals + * @global string $status The current theme status. + * @global array $totals An array of theme counts for each status. * * @param WP_Theme $theme The current WP_Theme object. */ @@ -777,8 +798,8 @@ public function column_description( $theme ) { * * @since 5.5.0 * - * @global string $status - * @global int $page + * @global string $status The current theme status. + * @global int $page The current page number. * * @param WP_Theme $theme The current WP_Theme object. */ @@ -979,10 +1000,12 @@ public function single_row_columns( $item ) { } /** - * @global string $status - * @global array $totals + * Handles the output for a single table row. + * + * @global string $status The current theme status. + * @global array $totals An array of theme counts for each status. * - * @param WP_Theme $theme + * @param WP_Theme $theme The current WP_Theme object. */ public function single_row( $theme ) { global $status, $totals; diff --git a/src/wp-admin/includes/class-wp-plugins-list-table.php b/src/wp-admin/includes/class-wp-plugins-list-table.php index 0c468763a39f1..c4866076f984d 100644 --- a/src/wp-admin/includes/class-wp-plugins-list-table.php +++ b/src/wp-admin/includes/class-wp-plugins-list-table.php @@ -46,11 +46,9 @@ public function __construct( $args = array() ) { ) ); - $allowed_statuses = array( 'active', 'inactive', 'recently_activated', 'upgrade', 'mustuse', 'dropins', 'search', 'paused', 'auto-update-enabled', 'auto-update-disabled' ); - $status = 'all'; - if ( isset( $_REQUEST['plugin_status'] ) && in_array( $_REQUEST['plugin_status'], $allowed_statuses, true ) ) { - $status = $_REQUEST['plugin_status']; + if ( isset( $_REQUEST['plugin_status'] ) ) { + $status = sanitize_key( $_REQUEST['plugin_status'] ); } if ( isset( $_REQUEST['s'] ) ) { @@ -584,6 +582,25 @@ protected function get_views() { $count ); break; + default: + /** + * Filters the status text of default switch case in the plugins list table. + * + * @since 7.0.0 + * + * @param string $text Plugins list status text. Default empty string. + * @param int $count Count of the number of plugins. + * @param string $type The status slug being filtered. + */ + $text = apply_filters( 'plugins_list_status_text', '', $count, $type ); + if ( empty( $text ) || ! is_string( $text ) ) { + $text = $type; + } + $text = esc_html( $text ) . ' ' . sprintf( + '(%s)', + number_format_i18n( $count ) + ); + break; } if ( 'search' !== $type ) { diff --git a/src/wp-admin/includes/class-wp-posts-list-table.php b/src/wp-admin/includes/class-wp-posts-list-table.php index d2d6eda2cba6f..f9c08ad5c73ee 100644 --- a/src/wp-admin/includes/class-wp-posts-list-table.php +++ b/src/wp-admin/includes/class-wp-posts-list-table.php @@ -1138,10 +1138,8 @@ public function column_title( $post ) { if ( $can_edit_post && 'trash' !== $post->post_status ) { printf( - '%s%s', + '%s%s', get_edit_post_link( $post->ID ), - /* translators: %s: Post title. */ - esc_attr( sprintf( __( '“%s” (Edit)' ), $title ) ), $pad, $title ); @@ -1781,7 +1779,7 @@ public function inline_edit() {
diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index dd537296a8655..44c04175abaf2 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1882,6 +1882,42 @@ public function get_test_available_updates_disk_space() { return $result; } + /** + * Tests if registration is open to everyone and the default role is privileged. + * + * @since 7.0.0 + * + * @return array The test results. + */ + public function get_test_insecure_registration() { + $users_can_register = get_option( 'users_can_register' ); + $default_role = get_option( 'default_role' ); + + $result = array( + 'label' => __( 'Open Registration with privileged default role' ), + 'status' => 'good', + 'badge' => array( + 'label' => __( 'Security' ), + 'color' => 'blue', + ), + 'description' => '

' . __( 'The combination of open registration setting and the default user role may lead to security issues.' ) . '

', + 'actions' => '', + 'test' => 'insecure_registration', + ); + + if ( $users_can_register && in_array( $default_role, array( 'editor', 'administrator' ), true ) ) { + $result['description'] = __( 'Registration is open to anyone, and the default role is set to a privileged role.' ); + $result['status'] = 'critical'; + $result['actions'] = sprintf( + '

%s

', + esc_url( admin_url( 'options-general.php' ) ), + __( 'Change these settings' ) + ); + } + + return $result; + } + /** * Tests if plugin and theme temporary backup directories are writable or can be created. * @@ -2755,6 +2791,52 @@ public function get_test_search_engine_visibility() { return $result; } + /** + * Tests if opcode cache is enabled and available. + * + * @since 7.0.0 + * + * @return array> The test result. + */ + public function get_test_opcode_cache(): array { + $opcode_cache_enabled = false; + if ( function_exists( 'opcache_get_status' ) ) { + $status = @opcache_get_status( false ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- Warning emitted in failure case. + if ( $status && true === $status['opcache_enabled'] ) { + $opcode_cache_enabled = true; + } + } + + $result = array( + 'label' => __( 'Opcode cache is enabled' ), + 'status' => 'good', + 'badge' => array( + 'label' => __( 'Performance' ), + 'color' => 'blue', + ), + 'description' => sprintf( + '

%s

', + __( 'Opcode cache improves PHP performance by storing precompiled script bytecode in memory, reducing the need for PHP to load and parse scripts on each request.' ) + ), + 'actions' => sprintf( + '

%s %s

', + esc_url( 'https://www.php.net/manual/en/book.opcache.php' ), + __( 'Learn more about OPcache.' ), + /* translators: Hidden accessibility text. */ + __( '(opens in a new tab)' ) + ), + 'test' => 'opcode_cache', + ); + + if ( ! $opcode_cache_enabled ) { + $result['status'] = 'recommended'; + $result['label'] = __( 'Opcode cache is not enabled' ); + $result['description'] .= '

' . __( 'Enabling this cache can significantly improve the performance of your site.' ) . '

'; + } + + return $result; + } + /** * Returns a set of tests that belong to the site status page. * @@ -2843,10 +2925,18 @@ public static function get_tests() { 'label' => __( 'Autoloaded options' ), 'test' => 'autoloaded_options', ), + 'insecure_registration' => array( + 'label' => __( 'Open Registration with privileged default role' ), + 'test' => 'insecure_registration', + ), 'search_engine_visibility' => array( 'label' => __( 'Search Engine Visibility' ), 'test' => 'search_engine_visibility', ), + 'opcode_cache' => array( + 'label' => __( 'Opcode cache' ), + 'test' => 'opcode_cache', + ), ), 'async' => array( 'dotorg_communication' => array( @@ -3378,22 +3468,21 @@ public function is_development_environment() { } /** - * Returns a list of headers and its verification callback to verify if page cache is enabled or not. - * - * Note: key is header name and value could be callable function to verify header value. - * Empty value mean existence of header detect page cache is enabled. + * Returns a mapping from response headers to an optional callback to verify if page cache is enabled or not. * * @since 6.1.0 * - * @return array List of client caching headers and their (optional) verification callbacks. + * @return array Mapping of page caching headers and their (optional) verification callbacks. + * A null value means a simple existence check is used for the header. */ - public function get_page_cache_headers() { + public function get_page_cache_headers(): array { $cache_hit_callback = static function ( $header_value ) { - return str_contains( strtolower( $header_value ), 'hit' ); + return 1 === preg_match( '/(^| |,)HIT(,| |$)/i', $header_value ); }; $cache_headers = array( + // Standard HTTP caching headers. 'cache-control' => static function ( $header_value ) { return (bool) preg_match( '/max-age=[1-9]/', $header_value ); }, @@ -3403,36 +3492,107 @@ public function get_page_cache_headers() { 'age' => static function ( $header_value ) { return is_numeric( $header_value ) && $header_value > 0; }, - 'last-modified' => '', - 'etag' => '', + 'last-modified' => null, + 'etag' => null, + 'via' => null, + + /** + * Custom caching headers. + * + * These do not seem to be actually used by any caching layers. There were first introduced in a Site Health + * test in the AMP plugin. They were copied into the Performance Lab plugin's Site Health test before they + * were merged into core. + * + * @link https://github.com/ampproject/amp-wp/pull/6849 + * @link https://github.com/WordPress/performance/pull/263 + * @link https://core.trac.wordpress.org/changeset/54043 + */ 'x-cache-enabled' => static function ( $header_value ) { - return 'true' === strtolower( $header_value ); + return ( 'true' === strtolower( $header_value ) ); }, 'x-cache-disabled' => static function ( $header_value ) { return ( 'on' !== strtolower( $header_value ) ); }, - 'x-srcache-store-status' => $cache_hit_callback, - 'x-srcache-fetch-status' => $cache_hit_callback, - // Generic caching proxies (Nginx, Varnish, etc.) - 'x-cache' => $cache_hit_callback, - 'x-cache-status' => $cache_hit_callback, - 'x-litespeed-cache' => $cache_hit_callback, - 'x-proxy-cache' => $cache_hit_callback, - 'via' => '', + /** + * CloudFlare. + * + * @link https://developers.cloudflare.com/cache/concepts/cache-responses/ + */ + 'cf-cache-status' => $cache_hit_callback, + + /** + * Fastly. + * + * @link https://www.fastly.com/documentation/reference/http/http-headers/X-Cache/ + */ + 'x-cache' => $cache_hit_callback, - // Cloudflare - 'cf-cache-status' => $cache_hit_callback, + /** + * LightSpeed. + * + * @link https://docs.litespeedtech.com/lscache/devguide/controls/#x-litespeed-cache + */ + 'x-litespeed-cache' => $cache_hit_callback, + + /** + * OpenResty srcache-nginx-module. + * + * The `x-srcache-store-status` header indicates if the response was stored in the cache. + * Valid values include `STORE` and `BYPASS`. + * + * The `x-srcache-fetch-status` header indicates if the response was fetched from the cache. + * Valid values include `HIT`, `MISS`, and `BYPASS`. + * + * @link https://github.com/openresty/srcache-nginx-module + */ + 'x-srcache-store-status' => static function ( $header_value ) { + return 'store' === strtolower( $header_value ); + }, + 'x-srcache-fetch-status' => $cache_hit_callback, + + /** + * Nginx. + * + * @link https://blog.nginx.org/blog/nginx-caching-guide + * @link https://www.inmotionhosting.com/support/website/nginx-cache-management/ + */ + 'x-cache-status' => $cache_hit_callback, + 'x-proxy-cache' => $cache_hit_callback, + + /** + * Varnish Cache. + * + * A header with a single number indicates it was not cached. If there are two numbers (or more), then this + * indicates the response was cached. + * + * @link https://vinyl-cache.org/docs/2.1/faq/http.html + * @link https://www.fastly.com/documentation/reference/http/http-headers/X-Varnish/ + * @link https://www.linuxjournal.com/content/speed-your-web-site-varnish + */ + 'x-varnish' => static function ( $header_value ) { + return 1 === preg_match( '/^\d+ \d+/', $header_value ); + }, ); /** * Filters the list of cache headers supported by core. * + * This list indicates how each of the specified headers will be checked to indicate if a page cache is enabled + * or not. WordPress checks for each of the headers in the returned array. If the callback is provided, it will + * be passed the value for the corresponding header and return a boolean value indicating if the header suggests + * that a cache is active. If the value is `null` for the header, then WordPress will assume that a cache is + * active if the header is present, regardless of its value. + * * @since 6.1.0 * - * @param array $cache_headers Array of supported cache headers. + * @param array $cache_headers Mapping from cache-related HTTP headers to whether they + * indicate if a page cache is enabled for the site. `null` + * indicates caching in the presence of the header; a callback is + * provided the header’s value and should return `true` if it + * implies that a cache is active. */ - return apply_filters( 'site_status_page_cache_supported_cache_headers', $cache_headers ); + return (array) apply_filters( 'site_status_page_cache_supported_cache_headers', $cache_headers ); } /** diff --git a/src/wp-admin/includes/class-wp-terms-list-table.php b/src/wp-admin/includes/class-wp-terms-list-table.php index 7537a499974d5..75e37e45d5c4f 100644 --- a/src/wp-admin/includes/class-wp-terms-list-table.php +++ b/src/wp-admin/includes/class-wp-terms-list-table.php @@ -413,10 +413,8 @@ public function column_name( $tag ) { $edit_link ); $name = sprintf( - '%s', + '%s', esc_url( $edit_link ), - /* translators: %s: Taxonomy term name. */ - esc_attr( sprintf( __( '“%s” (Edit)' ), $tag->name ) ), $name ); } diff --git a/src/wp-admin/includes/dashboard.php b/src/wp-admin/includes/dashboard.php index bba47a1c3442d..214b6c22c686a 100644 --- a/src/wp-admin/includes/dashboard.php +++ b/src/wp-admin/includes/dashboard.php @@ -2129,7 +2129,7 @@ function wp_welcome_panel() {

- +

diff --git a/src/wp-admin/includes/file.php b/src/wp-admin/includes/file.php index 610125b252ec0..99dc03c6cd656 100644 --- a/src/wp-admin/includes/file.php +++ b/src/wp-admin/includes/file.php @@ -202,6 +202,7 @@ function wp_get_plugin_file_editable_extensions( $plugin ) { 'inc', 'include', 'js', + 'mjs', 'json', 'jsx', 'less', @@ -261,6 +262,7 @@ function wp_get_theme_file_editable_extensions( $theme ) { 'inc', 'include', 'js', + 'mjs', 'json', 'jsx', 'less', @@ -2185,7 +2187,7 @@ function WP_Filesystem( $args = false, $context = false, $allow_relaxed_file_own $abstraction_file = apply_filters( 'filesystem_method_file', ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php', $method ); if ( ! file_exists( $abstraction_file ) ) { - return; + return null; } require_once $abstraction_file; diff --git a/src/wp-admin/includes/media.php b/src/wp-admin/includes/media.php index 9b70dc96cda94..1d45224f5b7e4 100644 --- a/src/wp-admin/includes/media.php +++ b/src/wp-admin/includes/media.php @@ -611,7 +611,7 @@ function wp_iframe( $content_func, ...$args ) { ?> - class="wp-core-ui no-js"> + class="wp-core-ui no-js "> @@ -3362,7 +3362,7 @@ function attachment_submitbox_metadata() {
- + diff --git a/src/wp-admin/includes/meta-boxes.php b/src/wp-admin/includes/meta-boxes.php index 506b38b3b9af0..1de3e600b667d 100644 --- a/src/wp-admin/includes/meta-boxes.php +++ b/src/wp-admin/includes/meta-boxes.php @@ -215,7 +215,7 @@ function post_submit_meta_box( $post, $args = array() ) { />
-
+
/>
diff --git a/src/wp-admin/includes/misc.php b/src/wp-admin/includes/misc.php index d3a93a17b48e2..f60e1aedf037a 100644 --- a/src/wp-admin/includes/misc.php +++ b/src/wp-admin/includes/misc.php @@ -1004,14 +1004,14 @@ function admin_color_scheme_picker( $user_id ) { ksort( $_wp_admin_css_colors ); - if ( isset( $_wp_admin_css_colors['fresh'] ) ) { - // Set Default ('fresh') and Light should go first. + if ( isset( $_wp_admin_css_colors['modern'] ) ) { + // Set Modern (new default), Classic ('fresh'), and Light first. $_wp_admin_css_colors = array_filter( array_merge( array( + 'modern' => '', 'fresh' => '', 'light' => '', - 'modern' => '', ), $_wp_admin_css_colors ) @@ -1021,7 +1021,7 @@ function admin_color_scheme_picker( $user_id ) { $current_color = get_user_option( 'admin_color', $user_id ); if ( empty( $current_color ) || ! isset( $_wp_admin_css_colors[ $current_color ] ) ) { - $current_color = 'fresh'; + $current_color = 'modern'; } ?>
@@ -1067,13 +1067,13 @@ function wp_color_scheme_settings() { // It's possible to have a color scheme set that is no longer registered. if ( empty( $_wp_admin_css_colors[ $color_scheme ] ) ) { - $color_scheme = 'fresh'; + $color_scheme = 'modern'; } if ( ! empty( $_wp_admin_css_colors[ $color_scheme ]->icon_colors ) ) { $icon_colors = $_wp_admin_css_colors[ $color_scheme ]->icon_colors; - } elseif ( ! empty( $_wp_admin_css_colors['fresh']->icon_colors ) ) { - $icon_colors = $_wp_admin_css_colors['fresh']->icon_colors; + } elseif ( ! empty( $_wp_admin_css_colors['modern']->icon_colors ) ) { + $icon_colors = $_wp_admin_css_colors['modern']->icon_colors; } else { // Fall back to the default set of icon colors if the default scheme is missing. $icon_colors = array( diff --git a/src/wp-admin/includes/plugin.php b/src/wp-admin/includes/plugin.php index 460874ca52181..fae10f1a679a4 100644 --- a/src/wp-admin/includes/plugin.php +++ b/src/wp-admin/includes/plugin.php @@ -926,7 +926,7 @@ function delete_plugins( $plugins, $deprecated = '' ) { require_once ABSPATH . 'wp-admin/admin-footer.php'; exit; } - return; + return null; } if ( ! WP_Filesystem( $credentials ) ) { @@ -941,7 +941,7 @@ function delete_plugins( $plugins, $deprecated = '' ) { require_once ABSPATH . 'wp-admin/admin-footer.php'; exit; } - return; + return null; } if ( ! is_object( $wp_filesystem ) ) { diff --git a/src/wp-admin/includes/post.php b/src/wp-admin/includes/post.php index eb0029a556169..de5aa4fb7d0fa 100644 --- a/src/wp-admin/includes/post.php +++ b/src/wp-admin/includes/post.php @@ -1644,7 +1644,7 @@ function _wp_post_thumbnail_html( $thumbnail_id = null, $post = null ) { $post = get_post( $post ); $post_type_object = get_post_type_object( $post->post_type ); - $set_thumbnail_link = '

%s

'; + $set_thumbnail_link = '

%s

'; $upload_iframe_src = get_upload_iframe_src( 'image', $post->ID ); $content = sprintf( @@ -1683,7 +1683,7 @@ function _wp_post_thumbnail_html( $thumbnail_id = null, $post = null ) { $thumbnail_html ); $content .= '

' . __( 'Click the image to edit or update' ) . '

'; - $content .= '

' . esc_html( $post_type_object->labels->remove_featured_image ) . '

'; + $content .= '

' . esc_html( $post_type_object->labels->remove_featured_image ) . '

'; } } diff --git a/src/wp-admin/includes/schema.php b/src/wp-admin/includes/schema.php index 7c762991b03bf..7a95f65ad80cc 100644 --- a/src/wp-admin/includes/schema.php +++ b/src/wp-admin/includes/schema.php @@ -409,160 +409,163 @@ function populate_options( array $options = array() ) { } $defaults = array( - 'siteurl' => $guessurl, - 'home' => $guessurl, - 'blogname' => __( 'My Site' ), - 'blogdescription' => '', - 'users_can_register' => 0, - 'admin_email' => 'you@example.com', + 'siteurl' => $guessurl, + 'home' => $guessurl, + 'blogname' => __( 'My Site' ), + 'blogdescription' => '', + 'users_can_register' => 0, + 'admin_email' => 'you@example.com', /* translators: Default start of the week. 0 = Sunday, 1 = Monday. */ - 'start_of_week' => _x( '1', 'start of week' ), - 'use_balanceTags' => 0, - 'use_smilies' => 1, - 'require_name_email' => 1, - 'comments_notify' => 1, - 'posts_per_rss' => 10, - 'rss_use_excerpt' => 0, - 'mailserver_url' => 'mail.example.com', - 'mailserver_login' => 'login@example.com', - 'mailserver_pass' => '', - 'mailserver_port' => 110, - 'default_category' => 1, - 'default_comment_status' => 'open', - 'default_ping_status' => 'open', - 'default_pingback_flag' => 1, - 'posts_per_page' => 10, + 'start_of_week' => _x( '1', 'start of week' ), + 'use_balanceTags' => 0, + 'use_smilies' => 1, + 'require_name_email' => 1, + 'comments_notify' => 1, + 'posts_per_rss' => 10, + 'rss_use_excerpt' => 0, + 'mailserver_url' => 'mail.example.com', + 'mailserver_login' => 'login@example.com', + 'mailserver_pass' => '', + 'mailserver_port' => 110, + 'default_category' => 1, + 'default_comment_status' => 'open', + 'default_ping_status' => 'open', + 'default_pingback_flag' => 1, + 'posts_per_page' => 10, /* translators: Default date format, see https://www.php.net/manual/datetime.format.php */ - 'date_format' => __( 'F j, Y' ), + 'date_format' => __( 'F j, Y' ), /* translators: Default time format, see https://www.php.net/manual/datetime.format.php */ - 'time_format' => __( 'g:i a' ), + 'time_format' => __( 'g:i a' ), /* translators: Links last updated date format, see https://www.php.net/manual/datetime.format.php */ - 'links_updated_date_format' => __( 'F j, Y g:i a' ), - 'comment_moderation' => 0, - 'moderation_notify' => 1, - 'permalink_structure' => '', - 'rewrite_rules' => '', - 'hack_file' => 0, - 'blog_charset' => 'UTF-8', - 'moderation_keys' => '', - 'active_plugins' => array(), - 'category_base' => '', - 'ping_sites' => 'https://rpc.pingomatic.com/', - 'comment_max_links' => 2, - 'gmt_offset' => $gmt_offset, + 'links_updated_date_format' => __( 'F j, Y g:i a' ), + 'comment_moderation' => 0, + 'moderation_notify' => 1, + 'permalink_structure' => '', + 'rewrite_rules' => '', + 'hack_file' => 0, + 'blog_charset' => 'UTF-8', + 'moderation_keys' => '', + 'active_plugins' => array(), + 'category_base' => '', + 'ping_sites' => 'https://rpc.pingomatic.com/', + 'comment_max_links' => 2, + 'gmt_offset' => $gmt_offset, // 1.5.0 - 'default_email_category' => 1, - 'recently_edited' => '', - 'template' => $template, - 'stylesheet' => $stylesheet, - 'comment_registration' => 0, - 'html_type' => 'text/html', + 'default_email_category' => 1, + 'recently_edited' => '', + 'template' => $template, + 'stylesheet' => $stylesheet, + 'comment_registration' => 0, + 'html_type' => 'text/html', // 1.5.1 - 'use_trackback' => 0, + 'use_trackback' => 0, // 2.0.0 - 'default_role' => 'subscriber', - 'db_version' => $wp_db_version, + 'default_role' => 'subscriber', + 'db_version' => $wp_db_version, // 2.0.1 - 'uploads_use_yearmonth_folders' => 1, - 'upload_path' => '', + 'uploads_use_yearmonth_folders' => 1, + 'upload_path' => '', // 2.1.0 - 'blog_public' => '1', - 'default_link_category' => 2, - 'show_on_front' => 'posts', + 'blog_public' => '1', + 'default_link_category' => 2, + 'show_on_front' => 'posts', // 2.2.0 - 'tag_base' => '', + 'tag_base' => '', // 2.5.0 - 'show_avatars' => '1', - 'avatar_rating' => 'G', - 'upload_url_path' => '', - 'thumbnail_size_w' => 150, - 'thumbnail_size_h' => 150, - 'thumbnail_crop' => 1, - 'medium_size_w' => 300, - 'medium_size_h' => 300, + 'show_avatars' => '1', + 'avatar_rating' => 'G', + 'upload_url_path' => '', + 'thumbnail_size_w' => 150, + 'thumbnail_size_h' => 150, + 'thumbnail_crop' => 1, + 'medium_size_w' => 300, + 'medium_size_h' => 300, // 2.6.0 - 'avatar_default' => 'mystery', + 'avatar_default' => 'mystery', // 2.7.0 - 'large_size_w' => 1024, - 'large_size_h' => 1024, - 'image_default_link_type' => 'none', - 'image_default_size' => '', - 'image_default_align' => '', - 'close_comments_for_old_posts' => 0, - 'close_comments_days_old' => 14, - 'thread_comments' => 1, - 'thread_comments_depth' => 5, - 'page_comments' => 0, - 'comments_per_page' => 50, - 'default_comments_page' => 'newest', - 'comment_order' => 'asc', - 'sticky_posts' => array(), - 'widget_categories' => array(), - 'widget_text' => array(), - 'widget_rss' => array(), - 'uninstall_plugins' => array(), + 'large_size_w' => 1024, + 'large_size_h' => 1024, + 'image_default_link_type' => 'none', + 'image_default_size' => '', + 'image_default_align' => '', + 'close_comments_for_old_posts' => 0, + 'close_comments_days_old' => 14, + 'thread_comments' => 1, + 'thread_comments_depth' => 5, + 'page_comments' => 0, + 'comments_per_page' => 50, + 'default_comments_page' => 'newest', + 'comment_order' => 'asc', + 'sticky_posts' => array(), + 'widget_categories' => array(), + 'widget_text' => array(), + 'widget_rss' => array(), + 'uninstall_plugins' => array(), // 2.8.0 - 'timezone_string' => $timezone_string, + 'timezone_string' => $timezone_string, // 3.0.0 - 'page_for_posts' => 0, - 'page_on_front' => 0, + 'page_for_posts' => 0, + 'page_on_front' => 0, // 3.1.0 - 'default_post_format' => 0, + 'default_post_format' => 0, // 3.5.0 - 'link_manager_enabled' => 0, + 'link_manager_enabled' => 0, // 4.3.0 - 'finished_splitting_shared_terms' => 1, - 'site_icon' => 0, + 'finished_splitting_shared_terms' => 1, + 'site_icon' => 0, // 4.4.0 - 'medium_large_size_w' => 768, - 'medium_large_size_h' => 0, + 'medium_large_size_w' => 768, + 'medium_large_size_h' => 0, // 4.9.6 - 'wp_page_for_privacy_policy' => 0, + 'wp_page_for_privacy_policy' => 0, // 4.9.8 - 'show_comments_cookies_opt_in' => 1, + 'show_comments_cookies_opt_in' => 1, // 5.3.0 - 'admin_email_lifespan' => ( time() + 6 * MONTH_IN_SECONDS ), + 'admin_email_lifespan' => ( time() + 6 * MONTH_IN_SECONDS ), // 5.5.0 - 'disallowed_keys' => '', - 'comment_previously_approved' => 1, - 'auto_plugin_theme_update_emails' => array(), + 'disallowed_keys' => '', + 'comment_previously_approved' => 1, + 'auto_plugin_theme_update_emails' => array(), // 5.6.0 - 'auto_update_core_dev' => 'enabled', - 'auto_update_core_minor' => 'enabled', + 'auto_update_core_dev' => 'enabled', + 'auto_update_core_minor' => 'enabled', /* * Default to enabled for new installs. * See https://core.trac.wordpress.org/ticket/51742. */ - 'auto_update_core_major' => 'enabled', + 'auto_update_core_major' => 'enabled', // 5.8.0 - 'wp_force_deactivated_plugins' => array(), + 'wp_force_deactivated_plugins' => array(), // 6.4.0 - 'wp_attachment_pages_enabled' => 0, + 'wp_attachment_pages_enabled' => 0, // 6.9.0 - 'wp_notes_notify' => 1, + 'wp_notes_notify' => 1, + + // 7.0.0 + 'wp_enable_real_time_collaboration' => 0, ); // 3.3.0 @@ -588,7 +591,7 @@ function populate_options( array $options = array() ) { ); $keys = "'" . implode( "', '", array_keys( $options ) ) . "'"; - $existing_options = $wpdb->get_col( "SELECT option_name FROM $wpdb->options WHERE option_name in ( $keys )" ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + $existing_options = $wpdb->get_col( "SELECT option_name FROM $wpdb->options WHERE option_name in ( $keys )" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared $insert = ''; diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php index b50ebc8c76678..6680bca89691a 100644 --- a/src/wp-admin/includes/template.php +++ b/src/wp-admin/includes/template.php @@ -493,7 +493,7 @@ function wp_comment_reply( $position = 1, $checkbox = false, $mode = 'single', $
- +
@@ -967,13 +967,18 @@ function parent_dropdown( $default_page = 0, $parent_page = 0, $level = 0, $post * Prints out option HTML elements for role selectors. * * @since 2.1.0 + * @since 7.0.0 Added $editable_roles parameter. * - * @param string $selected Slug for the role that should be already selected. + * @param string $selected Slug for the role that should be already selected. + * @param array $editable_roles Array of roles to include in the dropdown. Defaults to all + * roles the current user is allowed to edit. */ -function wp_dropdown_roles( $selected = '' ) { +function wp_dropdown_roles( $selected = '', $editable_roles = null ) { $r = ''; - $editable_roles = array_reverse( get_editable_roles() ); + if ( null === $editable_roles ) { + $editable_roles = array_reverse( get_editable_roles() ); + } foreach ( $editable_roles as $role => $details ) { $name = translate_user_role( $details['name'] ); @@ -2172,6 +2177,7 @@ function tb_close(){var win=window.dialogArguments||opener||parent||top;win.tb_r do_action( 'admin_head' ); $admin_body_class .= ' locale-' . sanitize_html_class( strtolower( str_replace( '_', '-', get_user_locale() ) ) ); + $admin_body_class .= ' admin-color-' . sanitize_html_class( get_user_option( 'admin_color' ), 'modern' ); if ( is_rtl() ) { $admin_body_class .= ' rtl'; diff --git a/src/wp-admin/includes/theme.php b/src/wp-admin/includes/theme.php index 8fa5d06a16a3b..ef5793b7dd118 100644 --- a/src/wp-admin/includes/theme.php +++ b/src/wp-admin/includes/theme.php @@ -40,7 +40,7 @@ function delete_theme( $stylesheet, $redirect = '' ) { require_once ABSPATH . 'wp-admin/admin-footer.php'; exit; } - return; + return null; } if ( ! WP_Filesystem( $credentials ) ) { @@ -55,7 +55,7 @@ function delete_theme( $stylesheet, $redirect = '' ) { require_once ABSPATH . 'wp-admin/admin-footer.php'; exit; } - return; + return null; } if ( ! is_object( $wp_filesystem ) ) { diff --git a/src/wp-admin/includes/update-core.php b/src/wp-admin/includes/update-core.php index 2f8045e8d193f..47cbc9e16fb64 100644 --- a/src/wp-admin/includes/update-core.php +++ b/src/wp-admin/includes/update-core.php @@ -840,10 +840,6 @@ 'wp-includes/js/dist/fields.min.js', 'wp-includes/js/dist/fields.js', // 6.9 - 'wp-includes/blocks/post-author/editor.css', - 'wp-includes/blocks/post-author/editor.min.css', - 'wp-includes/blocks/post-author/editor-rtl.css', - 'wp-includes/blocks/post-author/editor-rtl.min.css', 'wp-includes/SimplePie/src/Decode', 'wp-includes/SimplePie/src/Core.php', ); diff --git a/src/wp-admin/includes/upgrade.php b/src/wp-admin/includes/upgrade.php index 04b7016b83bc9..6adb0521ff295 100644 --- a/src/wp-admin/includes/upgrade.php +++ b/src/wp-admin/includes/upgrade.php @@ -886,6 +886,10 @@ function upgrade_all() { upgrade_682(); } + if ( $wp_current_db_version < 61644 ) { + upgrade_700(); + } + maybe_disable_link_manager(); maybe_disable_automattic_widgets(); @@ -2481,6 +2485,31 @@ function ( $url ) { } } +/** + * Executes changes made in WordPress 7.0. + * + * @ignore + * @since 7.0.0 + * + * @global int $wp_current_db_version The old (current) database version. + * @global wpdb $wpdb WordPress database abstraction object. + */ +function upgrade_700() { + global $wp_current_db_version, $wpdb; + + // Migrate users with 'fresh' admin color to 'modern'. + if ( $wp_current_db_version < 61644 ) { + $wpdb->update( + $wpdb->usermeta, + array( 'meta_value' => 'modern' ), + array( + 'meta_key' => 'admin_color', + 'meta_value' => 'fresh', + ) + ); + } +} + /** * Executes network-level upgrade routines. * diff --git a/src/wp-admin/includes/user.php b/src/wp-admin/includes/user.php index 6181a8457f1b8..1181dcb9fd4e6 100644 --- a/src/wp-admin/includes/user.php +++ b/src/wp-admin/includes/user.php @@ -134,7 +134,7 @@ function edit_user( $user_id = 0 ) { if ( $update ) { $user->rich_editing = isset( $_POST['rich_editing'] ) && 'false' === $_POST['rich_editing'] ? 'false' : 'true'; $user->syntax_highlighting = isset( $_POST['syntax_highlighting'] ) && 'false' === $_POST['syntax_highlighting'] ? 'false' : 'true'; - $user->admin_color = isset( $_POST['admin_color'] ) ? sanitize_text_field( $_POST['admin_color'] ) : 'fresh'; + $user->admin_color = isset( $_POST['admin_color'] ) ? sanitize_text_field( $_POST['admin_color'] ) : 'modern'; $user->show_admin_bar_front = isset( $_POST['admin_bar_front'] ) ? 'true' : 'false'; } diff --git a/src/wp-admin/includes/widgets.php b/src/wp-admin/includes/widgets.php index d4a370a1a37f5..e751602866b0d 100644 --- a/src/wp-admin/includes/widgets.php +++ b/src/wp-admin/includes/widgets.php @@ -303,7 +303,6 @@ function wp_widget_control( $sidebar_args ) { 'widget-' . esc_attr( $id_format ) . '-savewidget' ) ); ?>
-
diff --git a/src/wp-admin/install.php b/src/wp-admin/install.php index 7fcacab9bd6c9..b655af53f0cb6 100644 --- a/src/wp-admin/install.php +++ b/src/wp-admin/install.php @@ -15,7 +15,7 @@ Error: PHP is not running - +

Error: PHP is not running

WordPress requires that your web server is running PHP. Your server does not have PHP installed, or PHP is turned off.

@@ -72,7 +72,7 @@ function display_header( $body_classes = '' ) { <?php _e( 'WordPress › Installation' ); ?> - + - + ' . __( 'The menu management box at the top of the screen is used to control which menu is opened in the editor below.' ) . '

'; $menu_management .= '
  • ' . __( 'To edit an existing menu, choose a menu from the dropdown and click Select' ) . '
  • '; $menu_management .= '
  • ' . __( 'If you have not yet created any menus, click the ’create a new menu’ link to get started' ) . '
'; - $menu_management .= '

' . __( 'You can assign theme locations to individual menus by selecting the desired settings at the bottom of the menu editor. To assign menus to all theme locations at once, visit the Manage Locations tab at the top of the screen.' ) . '

'; + $menu_management .= '

' . __( 'You can assign individual menus to the theme’s menu locations by selecting the desired settings at the bottom of the menu editor. To assign menus to all theme menu locations at once, visit the Manage Locations tab at the top of the screen.' ) . '

'; get_current_screen()->add_help_tab( array( @@ -757,9 +757,9 @@ function wp_nav_menu_max_depth( $classes ) { ); else : // Locations tab. $locations_overview = '

' . __( 'This screen is used for globally assigning menus to locations defined by your theme.' ) . '

'; - $locations_overview .= '
  • ' . __( 'To assign menus to one or more theme locations, select a menu from each location’s dropdown. When you are finished, click Save Changes' ) . '
  • '; - $locations_overview .= '
  • ' . __( 'To edit a menu currently assigned to a theme location, click the adjacent ’Edit’ link' ) . '
  • '; - $locations_overview .= '
  • ' . __( 'To add a new menu instead of assigning an existing one, click the ’Use new menu’ link. Your new menu will be automatically assigned to that theme location' ) . '
'; + $locations_overview .= '
  • ' . __( 'To assign menus to one or more theme menu locations, select a menu from each location’s dropdown. When you are finished, click Save Changes' ) . '
  • '; + $locations_overview .= '
  • ' . __( 'To edit a menu currently assigned to a theme menu location, click the adjacent ’Edit’ link' ) . '
  • '; + $locations_overview .= '
  • ' . __( 'To add a new menu instead of assigning an existing one, click the ’Use new menu’ link. Your new menu will be automatically assigned to that location in the theme.' ) . '
'; get_current_screen()->add_help_tab( array( @@ -853,7 +853,7 @@ function wp_nav_menu_max_depth( $classes ) { - + @@ -1197,30 +1197,46 @@ function wp_nav_menu_max_depth( $classes ) { - + - + diff --git a/src/wp-admin/network/site-settings.php b/src/wp-admin/network/site-settings.php index 0d4b317d8ec33..8b1248f6b13b2 100644 --- a/src/wp-admin/network/site-settings.php +++ b/src/wp-admin/network/site-settings.php @@ -150,6 +150,25 @@ } } + $ltr_fields = array( + 'siteurl', + 'home', + 'admin_email', + 'new_admin_email', + 'mailserver_url', + 'mailserver_login', + 'mailserver_pass', + 'ping_sites', + 'permalink_structure', + 'category_base', + 'tag_base', + 'upload_path', + 'upload_url_path', + ); + if ( in_array( $option->option_name, $ltr_fields, true ) ) { + $class .= ' ltr'; + } + if ( str_contains( $option->option_value, "\n" ) ) { ?> diff --git a/src/wp-admin/network/site-users.php b/src/wp-admin/network/site-users.php index 070a8472e473d..6e32b5e8dd40d 100644 --- a/src/wp-admin/network/site-users.php +++ b/src/wp-admin/network/site-users.php @@ -376,11 +376,11 @@ - + - + diff --git a/src/wp-admin/network/users.php b/src/wp-admin/network/users.php index 7ddd5f40a662b..29238cd887034 100644 --- a/src/wp-admin/network/users.php +++ b/src/wp-admin/network/users.php @@ -86,16 +86,27 @@ /* translators: %s: User login. */ __( 'Warning! User cannot be modified. The user %s is a network administrator.' ), esc_html( $user->user_login ) - ) + ), + 403 ); } $userfunction = 'all_spam'; - $blogs = get_blogs_of_user( $user_id, true ); - foreach ( (array) $blogs as $details ) { - if ( ! is_main_site( $details->userblog_id ) ) { // Main site is not a spam! - update_blog_status( $details->userblog_id, 'spam', '1' ); + /** + * Filters whether to propagate the blog status when a user is marked as spam. + * + * @since 7.0.0 + * + * @param bool $propagate Whether to propagate the blog status. Default false. + * @param int $user_id User ID. + */ + if ( apply_filters( 'propagate_network_user_spam_to_blogs', false, $user_id ) ) { + foreach ( get_blogs_of_user( $user_id, true ) as $details ) { + // Assuming the main site is not a spam. + if ( ! is_main_site( $details->userblog_id ) ) { + update_blog_status( $details->userblog_id, 'spam', '1' ); + } } } @@ -108,11 +119,28 @@ case 'notspam': $user = get_userdata( $user_id ); + if ( is_super_admin( $user->ID ) ) { + wp_die( + sprintf( + /* translators: %s: User login. */ + __( 'Warning! User cannot be modified. The user %s is a network administrator.' ), + esc_html( $user->user_login ) + ), + 403 + ); + } + $userfunction = 'all_notspam'; $blogs = get_blogs_of_user( $user_id, true ); - foreach ( (array) $blogs as $details ) { - update_blog_status( $details->userblog_id, 'spam', '0' ); + /** This filter is documented in wp-admin/network/users.php */ + if ( apply_filters( 'propagate_network_user_spam_to_blogs', false, $user_id ) ) { + foreach ( get_blogs_of_user( $user_id, true ) as $details ) { + if ( ! is_main_site( $details->userblog_id ) && get_current_network_id() === $details->site_id ) { + // Assuming main site is never a spam and part of the current network. + update_blog_status( $details->userblog_id, 'spam', '0' ); + } + } } $user_data = $user->to_array(); diff --git a/src/wp-admin/options-general.php b/src/wp-admin/options-general.php index 214899d5a11a6..ac9b01a5966c6 100644 --- a/src/wp-admin/options-general.php +++ b/src/wp-admin/options-general.php @@ -304,7 +304,28 @@ class="" diff --git a/src/wp-admin/options-writing.php b/src/wp-admin/options-writing.php index 6f85b54679327..e9031cec59f1e 100644 --- a/src/wp-admin/options-writing.php +++ b/src/wp-admin/options-writing.php @@ -109,6 +109,13 @@ + + + + diff --git a/src/wp-admin/options.php b/src/wp-admin/options.php index 8db5cf50f2ec9..a3e2f77cad1d9 100644 --- a/src/wp-admin/options.php +++ b/src/wp-admin/options.php @@ -153,6 +153,7 @@ 'default_email_category', 'default_link_category', 'default_post_format', + 'wp_enable_real_time_collaboration', ), ); $allowed_options['misc'] = array(); diff --git a/src/wp-admin/press-this.php b/src/wp-admin/press-this.php index c91df1c96b84b..45021964364a3 100644 --- a/src/wp-admin/press-this.php +++ b/src/wp-admin/press-this.php @@ -22,8 +22,8 @@ function wp_load_press_this() { 403 ); } elseif ( is_plugin_active( $plugin_file ) ) { - include WP_PLUGIN_DIR . '/press-this/class-wp-press-this-plugin.php'; - $wp_press_this = new WP_Press_This_Plugin(); + include WP_PLUGIN_DIR . '/press-this/class-wp-press-this-plugin.php'; // @phpstan-ignore include.fileNotFound + $wp_press_this = new WP_Press_This_Plugin(); // @phpstan-ignore class.notFound $wp_press_this->html(); } elseif ( current_user_can( 'activate_plugins' ) ) { if ( file_exists( WP_PLUGIN_DIR . '/' . $plugin_file ) ) { diff --git a/src/wp-admin/setup-config.php b/src/wp-admin/setup-config.php index d2fa4ae8ea7ee..f9cbc08ced0dc 100644 --- a/src/wp-admin/setup-config.php +++ b/src/wp-admin/setup-config.php @@ -94,6 +94,7 @@ function setup_config_display_header( $body_classes = array() ) { $body_classes = (array) $body_classes; $body_classes[] = 'wp-core-ui'; + $body_classes[] = 'admin-color-modern'; $dir_attr = ''; if ( is_rtl() ) { $body_classes[] = 'rtl'; diff --git a/src/wp-admin/site-editor.php b/src/wp-admin/site-editor.php index 1c8e8b525459b..9a8268c3392d7 100644 --- a/src/wp-admin/site-editor.php +++ b/src/wp-admin/site-editor.php @@ -218,6 +218,12 @@ static function ( $classes ) { 'description', 'gmt_offset', 'home', + 'image_sizes', + 'image_size_threshold', + 'image_output_formats', + 'jpeg_interlaced', + 'png_interlaced', + 'gif_interlaced', 'name', 'site_icon', 'site_icon_url', diff --git a/src/wp-admin/site-health-info.php b/src/wp-admin/site-health-info.php index bfdd77df01553..faffb21636827 100644 --- a/src/wp-admin/site-health-info.php +++ b/src/wp-admin/site-health-info.php @@ -73,7 +73,7 @@ ?>

-

- + ID ) ) : ?> @@ -692,7 +692,7 @@
- +
- + @@ -600,7 +600,7 @@
- +
-
+
@@ -353,14 +353,13 @@
-
+
-
diff --git a/src/wp-content/themes/twentyfourteen/inc/featured-content.php b/src/wp-content/themes/twentyfourteen/inc/featured-content.php index b98ab983919df..3193aa8b93549 100644 --- a/src/wp-content/themes/twentyfourteen/inc/featured-content.php +++ b/src/wp-content/themes/twentyfourteen/inc/featured-content.php @@ -212,7 +212,7 @@ public static function delete_transient() { * @since Twenty Fourteen 1.0 * * @param WP_Query $query WP_Query object. - * @return WP_Query Possibly-modified WP_Query. + * @return void */ public static function pre_get_posts( $query ) { diff --git a/src/wp-content/themes/twentynineteen/inc/template-tags.php b/src/wp-content/themes/twentynineteen/inc/template-tags.php index 44e180785cb56..63e9f78e1b505 100644 --- a/src/wp-content/themes/twentynineteen/inc/template-tags.php +++ b/src/wp-content/themes/twentynineteen/inc/template-tags.php @@ -92,7 +92,7 @@ function twentynineteen_entry_footer() { /* translators: Hidden accessibility text. */ __( 'Posted in', 'twentynineteen' ), $categories_list - ); // WPCS: XSS OK. + ); } $tags_list = get_the_tag_list( '', wp_get_list_item_separator() ); @@ -104,7 +104,7 @@ function twentynineteen_entry_footer() { /* translators: Hidden accessibility text. */ __( 'Tags:', 'twentynineteen' ), $tags_list - ); // WPCS: XSS OK. + ); } } diff --git a/src/wp-content/themes/twentynineteen/sass/modules/_accessibility.scss b/src/wp-content/themes/twentynineteen/sass/modules/_accessibility.scss index 5db512eb6ceca..d9fde5499eaab 100644 --- a/src/wp-content/themes/twentynineteen/sass/modules/_accessibility.scss +++ b/src/wp-content/themes/twentynineteen/sass/modules/_accessibility.scss @@ -8,7 +8,9 @@ padding: 0; position: absolute !important; width: 1px; - word-wrap: normal !important; /* Many screen reader and browser combinations announce broken words as they would appear visually. */ + /* Many screen reader and browser combinations announce broken words as they would appear visually. */ + word-wrap: normal !important; + word-break: normal !important; &:focus { background-color: $color__background-screen; diff --git a/src/wp-content/themes/twentynineteen/style-rtl.css b/src/wp-content/themes/twentynineteen/style-rtl.css index 6bd0b155bf296..ae969d6e88e84 100644 --- a/src/wp-content/themes/twentynineteen/style-rtl.css +++ b/src/wp-content/themes/twentynineteen/style-rtl.css @@ -3627,8 +3627,9 @@ body.page .main-navigation { padding: 0; position: absolute !important; width: 1px; - word-wrap: normal !important; /* Many screen reader and browser combinations announce broken words as they would appear visually. */ + word-wrap: normal !important; + word-break: normal !important; } .screen-reader-text:focus { diff --git a/src/wp-content/themes/twentynineteen/style.css b/src/wp-content/themes/twentynineteen/style.css index cff39c5de37ab..1dafa52fd6be7 100644 --- a/src/wp-content/themes/twentynineteen/style.css +++ b/src/wp-content/themes/twentynineteen/style.css @@ -3627,8 +3627,9 @@ body.page .main-navigation { padding: 0; position: absolute !important; width: 1px; - word-wrap: normal !important; /* Many screen reader and browser combinations announce broken words as they would appear visually. */ + word-wrap: normal !important; + word-break: normal !important; } .screen-reader-text:focus { diff --git a/src/wp-content/themes/twentyseventeen/style.css b/src/wp-content/themes/twentyseventeen/style.css index 15a25aa01d4dc..1c507a9955c53 100644 --- a/src/wp-content/themes/twentyseventeen/style.css +++ b/src/wp-content/themes/twentyseventeen/style.css @@ -311,7 +311,9 @@ template { overflow: hidden; position: absolute !important; width: 1px; - word-wrap: normal !important; /* Many screen reader and browser combinations announce broken words as they would appear visually. */ + /* Many screen reader and browser combinations announce broken words as they would appear visually. */ + word-wrap: normal !important; + word-break: normal !important; } .screen-reader-text:focus { diff --git a/src/wp-content/themes/twentysixteen/style.css b/src/wp-content/themes/twentysixteen/style.css index e6b238c36db97..1fa05165775be 100644 --- a/src/wp-content/themes/twentysixteen/style.css +++ b/src/wp-content/themes/twentysixteen/style.css @@ -1289,8 +1289,9 @@ a:active { overflow: hidden; position: absolute !important; width: 1px; - /* many screen reader and browser combinations announce broken words as they would appear visually */ + /* Many screen reader and browser combinations announce broken words as they would appear visually. */ word-wrap: normal !important; + word-break: normal !important; } /* must have higher specificity than alternative color schemes inline styles */ diff --git a/src/wp-content/themes/twentytwenty/assets/css/editor-style-block-rtl.css b/src/wp-content/themes/twentytwenty/assets/css/editor-style-block-rtl.css index c2bfa33d639b3..875acb214d842 100644 --- a/src/wp-content/themes/twentytwenty/assets/css/editor-style-block-rtl.css +++ b/src/wp-content/themes/twentytwenty/assets/css/editor-style-block-rtl.css @@ -885,7 +885,7 @@ hr.wp-block-separator.is-style-dots::before { font-size: 16px; font-weight: 500; margin-top: 12px; - text-transform: none; + text-transform: inherit; } .editor-styles-wrapper .wp-block-pullquote.has-text-color cite, diff --git a/src/wp-content/themes/twentytwenty/assets/css/editor-style-block.css b/src/wp-content/themes/twentytwenty/assets/css/editor-style-block.css index 222019e9a9cc7..987d85daa3d72 100644 --- a/src/wp-content/themes/twentytwenty/assets/css/editor-style-block.css +++ b/src/wp-content/themes/twentytwenty/assets/css/editor-style-block.css @@ -889,7 +889,7 @@ hr.wp-block-separator.is-style-dots::before { font-size: 16px; font-weight: 500; margin-top: 12px; - text-transform: none; + text-transform: inherit; } .editor-styles-wrapper .wp-block-pullquote.has-text-color cite, diff --git a/src/wp-content/themes/twentytwenty/classes/class-twentytwenty-svg-icons.php b/src/wp-content/themes/twentytwenty/classes/class-twentytwenty-svg-icons.php index a87bf84db244c..946045e982347 100644 --- a/src/wp-content/themes/twentytwenty/classes/class-twentytwenty-svg-icons.php +++ b/src/wp-content/themes/twentytwenty/classes/class-twentytwenty-svg-icons.php @@ -327,7 +327,6 @@ public static function get_social_link_svg( $uri ) { 'whatsapp' => ' ', - // phpcs:disable WordPress.WP.CapitalPDangit.Misspelled 'wordpress' => '', 'yelp' => '', diff --git a/src/wp-content/themes/twentytwenty/classes/class-twentytwenty-walker-comment.php b/src/wp-content/themes/twentytwenty/classes/class-twentytwenty-walker-comment.php index eb2ec8efe55a6..8012677ce8e76 100644 --- a/src/wp-content/themes/twentytwenty/classes/class-twentytwenty-walker-comment.php +++ b/src/wp-content/themes/twentytwenty/classes/class-twentytwenty-walker-comment.php @@ -37,7 +37,7 @@ protected function html5_comment( $comment, $depth, $args ) { $tag = ( 'div' === $args['style'] ) ? 'div' : 'li'; ?> - < id="comment-" has_children ? 'parent' : '', $comment ); ?>> + < id="comment-" has_children ? 'parent' : '', $comment ); ?>>