diff --git a/.env.example b/.env.example index 76a4744165505..6974d8554611a 100644 --- a/.env.example +++ b/.env.example @@ -46,12 +46,12 @@ LOCAL_DB_TYPE=mysql ## # The database version to use. # -# Defaults to 8.0 with the assumption that LOCAL_DB_TYPE is set to `mysql` above. +# Defaults to 9.7 with the assumption that LOCAL_DB_TYPE is set to `mysql` above. # # When using `mysql`, see https://hub.docker.com/_/mysql for valid versions. # When using `mariadb`, see https://hub.docker.com/_/mariadb for valid versions. ## -LOCAL_DB_VERSION=8.4 +LOCAL_DB_VERSION=9.7 # Whether or not to enable multisite. LOCAL_MULTISITE=false diff --git a/.github/workflows/commit-built-file-changes.yml b/.github/workflows/commit-built-file-changes.yml index f93cd4bd662ec..8648db58da602 100644 --- a/.github/workflows/commit-built-file-changes.yml +++ b/.github/workflows/commit-built-file-changes.yml @@ -40,7 +40,9 @@ jobs: if: ${{ github.repository == 'wordpress/wordpress-develop' }} timeout-minutes: 10 permissions: - contents: write + # The actual `git push` is authenticated via a dedicated GitHub App installation token + # generated below, so `GITHUB_TOKEN` only needs read access to the triggering workflow's artifacts. + actions: read # Required to list and download the artifact uploaded by the triggering workflow run. steps: - name: Download artifact uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 @@ -90,21 +92,18 @@ jobs: id: generate_token if: ${{ steps.artifact-check.outputs.exists == 'true' }} env: - GH_APP_ID: ${{ secrets.GH_PR_BUILT_FILES_APP_ID }} + GH_APP_ID: ${{ vars.GH_PR_BUILT_FILES_APP_ID }} GH_APP_PRIVATE_KEY: ${{ secrets.GH_PR_BUILT_FILES_PRIVATE_KEY }} run: | - echo "$GH_APP_PRIVATE_KEY" > private-key.pem - # Generate JWT JWT=$(python3 - <> "$GITHUB_ENV" - - rm -f private-key.pem + echo "access-token=$ACCESS_TOKEN" >> "$GITHUB_OUTPUT" - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -130,12 +127,13 @@ jobs: ref: ${{ github.event.workflow_run.head_branch }} path: 'pr-repo' show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - token: ${{ env.ACCESS_TOKEN }} + token: ${{ steps.generate_token.outputs.access-token }} + persist-credentials: true - name: Apply patch if: ${{ steps.artifact-check.outputs.exists == 'true' }} working-directory: 'pr-repo' - run: git apply ${{ github.workspace }}/changes.diff + run: git apply "$GITHUB_WORKSPACE/changes.diff" - name: Display changes to versioned files if: ${{ steps.artifact-check.outputs.exists == 'true' }} @@ -146,10 +144,10 @@ jobs: if: ${{ steps.artifact-check.outputs.exists == 'true' }} working-directory: 'pr-repo' env: - GH_APP_ID: ${{ secrets.GH_PR_BUILT_FILES_APP_ID }} + GH_APP_ID: ${{ vars.GH_PR_BUILT_FILES_APP_ID }} run: | git config user.name "wordpress-develop-pr-bot[bot]" - git config user.email ${{ env.GH_APP_ID }}+wordpress-develop-pr-bot[bot]@users.noreply.github.com + git config user.email "${GH_APP_ID}+wordpress-develop-pr-bot[bot]@users.noreply.github.com" - name: Stage changes if: ${{ steps.artifact-check.outputs.exists == 'true' }} diff --git a/.github/workflows/end-to-end-tests.yml b/.github/workflows/end-to-end-tests.yml index b397a2241947e..4375091546dd7 100644 --- a/.github/workflows/end-to-end-tests.yml +++ b/.github/workflows/end-to-end-tests.yml @@ -53,7 +53,7 @@ permissions: {} env: LOCAL_DIR: build - PUPPETEER_SKIP_DOWNLOAD: ${{ true }} + PUPPETEER_SKIP_DOWNLOAD: true jobs: # Runs the end-to-end test suite. diff --git a/.github/workflows/install-testing.yml b/.github/workflows/install-testing.yml index f15d6e4830268..440c2ee842149 100644 --- a/.github/workflows/install-testing.yml +++ b/.github/workflows/install-testing.yml @@ -49,7 +49,6 @@ jobs: uses: ./.github/workflows/reusable-support-json-reader-v1.yml permissions: contents: read - secrets: inherit if: ${{ github.repository == 'WordPress/wordpress-develop' }} with: wp-version: ${{ inputs.wp-version }} @@ -95,11 +94,12 @@ jobs: - db-version: '9.3' - db-version: '9.4' - db-version: '9.5' + - db-version: '9.6' # MySQL 9.0+ will not work on PHP 7.2 & 7.3. See https://core.trac.wordpress.org/ticket/61218. - php: '7.2' - db-version: '9.6' + db-version: '9.7' - php: '7.3' - db-version: '9.6' + db-version: '9.7' services: database: @@ -118,7 +118,7 @@ jobs: steps: - name: Set up PHP ${{ matrix.php }} - uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.37.0 + uses: shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc # 2.37.1 with: php-version: '${{ matrix.php }}' coverage: none diff --git a/.github/workflows/local-docker-environment.yml b/.github/workflows/local-docker-environment.yml index c9dbae312595a..b786cc2419c03 100644 --- a/.github/workflows/local-docker-environment.yml +++ b/.github/workflows/local-docker-environment.yml @@ -79,7 +79,6 @@ jobs: uses: ./.github/workflows/reusable-support-json-reader-v1.yml permissions: contents: read - secrets: inherit if: ${{ github.repository == 'WordPress/wordpress-develop' }} with: wp-version: ${{ github.event_name == 'pull_request' && github.base_ref || github.ref_name }} @@ -109,6 +108,7 @@ jobs: - db-version: '9.3' - db-version: '9.4' - db-version: '9.5' + - db-version: '9.6' # No PHP 8.5 + Memcached support yet. - php: '8.5' memcached: true diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index d9be2c8842ec4..87832b1c52ca2 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -37,7 +37,6 @@ on: - 'tests/performance/**' # Confirm any changes to relevant workflow files. - '.github/workflows/performance.yml' - - '.github/workflows/reusable-performance.yml' - '.github/workflows/reusable-performance-*.yml' workflow_dispatch: diff --git a/.github/workflows/phpunit-tests.yml b/.github/workflows/phpunit-tests.yml index de36d5a505187..f46b419656a44 100644 --- a/.github/workflows/phpunit-tests.yml +++ b/.github/workflows/phpunit-tests.yml @@ -66,7 +66,9 @@ jobs: uses: ./.github/workflows/reusable-phpunit-tests-v3.yml permissions: contents: read - secrets: inherit + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + WPT_REPORT_API_KEY: ${{ secrets.WPT_REPORT_API_KEY }} if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} strategy: fail-fast: false @@ -74,7 +76,7 @@ jobs: os: [ ubuntu-24.04 ] php: [ '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] db-type: [ 'mysql' ] - db-version: [ '5.7', '8.0', '8.4' ] + db-version: [ '5.7', '8.0', '8.4', '9.7' ] tests-domain: [ 'example.org' ] multisite: [ false, true ] memcached: [ false ] @@ -143,7 +145,9 @@ jobs: uses: ./.github/workflows/reusable-phpunit-tests-v3.yml permissions: contents: read - secrets: inherit + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + WPT_REPORT_API_KEY: ${{ secrets.WPT_REPORT_API_KEY }} if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} strategy: fail-fast: false @@ -177,7 +181,7 @@ jobs: multisite: ${{ matrix.multisite }} memcached: ${{ matrix.memcached }} phpunit-config: ${{ matrix.multisite && 'tests/phpunit/multisite.xml' || 'phpunit.xml.dist' }} - report: ${{ false }} + report: false # # Creates PHPUnit test jobs to test MariaDB and MySQL innovation releases. @@ -195,7 +199,9 @@ jobs: uses: ./.github/workflows/reusable-phpunit-tests-v3.yml permissions: contents: read - secrets: inherit + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + WPT_REPORT_API_KEY: ${{ secrets.WPT_REPORT_API_KEY }} if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} strategy: fail-fast: false @@ -203,15 +209,13 @@ jobs: os: [ ubuntu-24.04 ] php: [ '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] db-type: [ 'mysql', 'mariadb' ] - db-version: [ '9.6', '12.1' ] + db-version: [ '12.1' ] multisite: [ false, true ] memcached: [ false ] db-innovation: [ true ] exclude: # Exclude version combinations that don't exist. - - db-type: 'mariadb' - db-version: '9.6' - db-type: 'mysql' db-version: '12.1' with: @@ -223,7 +227,7 @@ jobs: multisite: ${{ matrix.multisite }} memcached: ${{ matrix.memcached }} phpunit-config: ${{ matrix.multisite && 'tests/phpunit/multisite.xml' || 'phpunit.xml.dist' }} - report: ${{ false }} + report: false # # Runs the HTML API test group. @@ -238,7 +242,9 @@ jobs: uses: ./.github/workflows/reusable-phpunit-tests-v3.yml permissions: contents: read - secrets: inherit + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + WPT_REPORT_API_KEY: ${{ secrets.WPT_REPORT_API_KEY }} if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} strategy: fail-fast: false @@ -267,20 +273,22 @@ jobs: uses: ./.github/workflows/reusable-phpunit-tests-v3.yml permissions: contents: read - secrets: inherit + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + WPT_REPORT_API_KEY: ${{ secrets.WPT_REPORT_API_KEY }} if: ${{ ! startsWith( github.repository, 'WordPress/' ) && github.event_name == 'pull_request' }} strategy: fail-fast: false matrix: php: [ '7.4', '8.4' ] - db-version: [ '8.4', '11.8' ] + db-version: [ '9.7', '11.8' ] db-type: [ 'mysql', 'mariadb' ] multisite: [ false ] include: # Include one multisite job for each database type. - php: '8.4' - db-version: '8.4' + db-version: '9.7' db-type: 'mysql' multisite: true - php: '8.4' @@ -289,13 +297,13 @@ jobs: multisite: true # Test with memcached. - php: '8.4' - db-version: '8.4' + db-version: '9.7' db-type: 'mysql' multisite: true memcached: true # Run specific test groups once. - php: '8.4' - db-version: '8.4' + db-version: '9.7' db-type: 'mysql' phpunit-test-groups: 'html-api-html5lib-tests' @@ -304,7 +312,7 @@ jobs: - db-type: 'mysql' db-version: '11.8' - db-type: 'mariadb' - db-version: '8.4' + db-version: '9.7' with: php: ${{ matrix.php }} diff --git a/.github/workflows/pull-request-comments.yml b/.github/workflows/pull-request-comments.yml index da30e2feb7f11..e0fdbc664b149 100644 --- a/.github/workflows/pull-request-comments.yml +++ b/.github/workflows/pull-request-comments.yml @@ -20,63 +20,6 @@ concurrency: permissions: {} jobs: - # Comments on a pull request when the author is a first time contributor. - post-welcome-message: - runs-on: ubuntu-24.04 - permissions: - issues: write - pull-requests: write - timeout-minutes: 5 - if: ${{ github.repository == 'WordPress/wordpress-develop' && github.event_name == 'pull_request_target' }} - steps: - - name: Post a welcome comment - uses: wow-actions/welcome@68019c2c271561f63162fea75bb7707ef8a02c85 # v1.3.1 - with: - FIRST_PR_REACTIONS: 'hooray' - FIRST_PR_COMMENT: > - Hi @{{ author }}! 👋 - - - Thank you for your contribution to WordPress! 💖 - - - It looks like this is your first pull request to `wordpress-develop`. Here are a few things to be aware of that may help you out! - - - **No one monitors this repository for new pull requests.** Pull requests **must** be attached to a Trac ticket to be considered for inclusion in WordPress Core. To attach a pull request to a Trac ticket, please include the ticket's full URL in your pull request description. - - - **Pull requests are never merged on GitHub.** The WordPress codebase continues to be managed through the SVN repository that this GitHub repository mirrors. Please feel free to open pull requests to work on any contribution you are making. - - - More information about how GitHub pull requests can be used to contribute to WordPress can be found in [the Core Handbook](https://make.wordpress.org/core/handbook/contribute/git/github-pull-requests-for-code-review/). - - - **Please include automated tests.** Including tests in your pull request is one way to help your patch be considered faster. To learn about WordPress' test suites, visit the [Automated Testing](https://make.wordpress.org/core/handbook/testing/automated-testing/) page in the handbook. - - - If you have not had a chance, please review the [Contribute with Code page](https://make.wordpress.org/core/handbook/contribute/) in the [WordPress Core Handbook](https://make.wordpress.org/core/handbook/). - - - The [Developer Hub](https://developer.wordpress.org/) also documents the various [coding standards](https://make.wordpress.org/core/handbook/best-practices/coding-standards/) that are followed: - - - [PHP Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/php/) - - - [CSS Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/css/) - - - [HTML Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/html/) - - - [JavaScript Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/javascript/) - - - [Accessibility Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/accessibility/) - - - [Inline Documentation Standards](https://developer.wordpress.org/coding-standards/inline-documentation-standards/) - - - Thank you, - - The WordPress Project - # Leaves a comment on a pull request with a link to test the changes in a WordPress Playground instance. playground-details: name: Comment on a pull request with Playground details diff --git a/.github/workflows/reusable-build-package.yml b/.github/workflows/reusable-build-package.yml index 320ec1c621335..dda138505e6f0 100644 --- a/.github/workflows/reusable-build-package.yml +++ b/.github/workflows/reusable-build-package.yml @@ -35,7 +35,7 @@ jobs: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 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 11d97639a30fc..033b2a46ac3e9 100644 --- a/.github/workflows/reusable-check-built-files.yml +++ b/.github/workflows/reusable-check-built-files.yml @@ -17,7 +17,6 @@ jobs: # Performs the following steps: # - Checks out the repository. # - Sets up Node.js. - # - Configures caching for Composer. # - Installs Composer dependencies. # - Logs general debug information about the runner. # - Installs npm dependencies. @@ -40,25 +39,20 @@ jobs: 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@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: '.nvmrc' cache: npm - # This date is used to ensure that the PHPCS 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" - # 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@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 + uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # 4.0.0 with: - custom-cache-suffix: ${{ steps.get-date.outputs.date }} + custom-cache-suffix: $(/bin/date -u --date='last Mon' "+%F") - name: Log debug information run: | @@ -103,7 +97,7 @@ jobs: # Uploads the diff file as an artifact. - name: Upload diff file as artifact - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: ${{ steps.built-file-check.outputs.uncommitted_changes == 'true' }} with: name: pr-built-file-changes diff --git a/.github/workflows/reusable-cleanup-pull-requests.yml b/.github/workflows/reusable-cleanup-pull-requests.yml index 9dae63cb213d3..cdce56001d16b 100644 --- a/.github/workflows/reusable-cleanup-pull-requests.yml +++ b/.github/workflows/reusable-cleanup-pull-requests.yml @@ -19,7 +19,7 @@ jobs: # - Parse fixed ticket numbers from the commit message. # - Parse the SVN revision from the commit message. # - Searches for pull requests referencing any fixed tickets. - # - Leaves a comment on each PR before closing. +# - Comments on pull requests referencing any fixed tickets before closing. close-prs: name: Find and close PRs runs-on: ubuntu-24.04 @@ -43,13 +43,17 @@ jobs: COMMIT_MESSAGE="$(echo "$COMMIT_MSG_RAW" | sed -n '$p')" echo "svn_revision_number=$(echo "$COMMIT_MESSAGE" | sed -n 's/.*git-svn-id: https:\/\/develop.svn.wordpress.org\/[^@]*@\([0-9]*\) .*/\1/p')" >> "$GITHUB_OUTPUT" - - name: Find pull requests - id: linked-prs + - name: Find, comment on, and close pull requests if: ${{ steps.trac-tickets.outputs.fixed_list != '' && steps.git-svn-id.outputs.svn_revision_number != '' }} uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + FIXED_LIST: ${{ steps.trac-tickets.outputs.fixed_list }} + SVN_REVISION_NUMBER: ${{ steps.git-svn-id.outputs.svn_revision_number }} with: script: | - const fixedList = "${{ steps.trac-tickets.outputs.fixed_list }}".split(' ').filter(Boolean); + const fixedList = process.env.FIXED_LIST.split(' ').filter(Boolean); + const svnRevisionNumber = process.env.SVN_REVISION_NUMBER; + const githubSha = process.env.GITHUB_SHA; let prNumbers = []; for (const ticket of fixedList) { @@ -86,19 +90,10 @@ jobs: prNumbers.push(...matchingPRs); } - return prNumbers; - - - name: Comment and close pull requests - if: ${{ steps.trac-tickets.outputs.fixed_list != '' && steps.git-svn-id.outputs.svn_revision_number != '' }} - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - with: - script: | - const prNumbers = ${{ steps.linked-prs.outputs.result }}; - const commentBody = `A commit was made that fixes the Trac ticket referenced in the description of this pull request. - SVN changeset: [${{ steps.git-svn-id.outputs.svn_revision_number }}](https://core.trac.wordpress.org/changeset/${{ steps.git-svn-id.outputs.svn_revision_number }}) - GitHub commit: https://github.com/WordPress/wordpress-develop/commit/${{ github.sha }} + SVN changeset: [${svnRevisionNumber}](https://core.trac.wordpress.org/changeset/${svnRevisionNumber}) + GitHub commit: https://github.com/WordPress/wordpress-develop/commit/${githubSha} This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.`; diff --git a/.github/workflows/reusable-coding-standards-javascript.yml b/.github/workflows/reusable-coding-standards-javascript.yml index 5c9a0c1ec0d03..eac5bbdc352f2 100644 --- a/.github/workflows/reusable-coding-standards-javascript.yml +++ b/.github/workflows/reusable-coding-standards-javascript.yml @@ -7,7 +7,7 @@ on: workflow_call: env: - PUPPETEER_SKIP_DOWNLOAD: ${{ true }} + PUPPETEER_SKIP_DOWNLOAD: true # Disable permissions for all available scopes by default. # Any needed permissions should be configured at the job level. @@ -40,7 +40,7 @@ jobs: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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 1213ccb6baa6f..fab8bffb31e11 100644 --- a/.github/workflows/reusable-coding-standards-php.yml +++ b/.github/workflows/reusable-coding-standards-php.yml @@ -29,6 +29,7 @@ jobs: # Performs the following steps: # - Checks out the repository. # - Sets up PHP. + # - Gets last Monday's date for use in cache keys. # - Configures caching for PHPCS scans. # - Installs Composer dependencies. # - Make Composer packages available globally. @@ -52,7 +53,7 @@ jobs: persist-credentials: false - name: Set up PHP - uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.37.0 + uses: shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc # 2.37.1 with: php-version: ${{ inputs.php-version }} coverage: none @@ -65,7 +66,7 @@ jobs: run: echo "date=$(/bin/date -u --date='last Mon' "+%F")" >> "$GITHUB_OUTPUT" - name: Cache PHPCS scan cache - uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: | .cache/phpcs-src.json @@ -75,7 +76,7 @@ jobs: # 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@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 + uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # 4.0.0 with: custom-cache-suffix: ${{ steps.get-date.outputs.date }} diff --git a/.github/workflows/reusable-end-to-end-tests.yml b/.github/workflows/reusable-end-to-end-tests.yml index 0b2ceec077602..87f90f1b53039 100644 --- a/.github/workflows/reusable-end-to-end-tests.yml +++ b/.github/workflows/reusable-end-to-end-tests.yml @@ -82,7 +82,7 @@ jobs: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: '.nvmrc' cache: npm @@ -145,7 +145,7 @@ jobs: run: npm run test:e2e - name: Archive debug artifacts (screenshots, HTML snapshots) - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 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 6bab6a5287665..3988ec9d6b055 100644 --- a/.github/workflows/reusable-javascript-tests.yml +++ b/.github/workflows/reusable-javascript-tests.yml @@ -41,7 +41,7 @@ jobs: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: '.nvmrc' cache: npm @@ -55,7 +55,7 @@ jobs: - name: Install npm Dependencies run: npm ci - # Older branches using outdated versions of Puppeteer fail on newer versions of the `ubuntu-24` image. + # Branches prior to 6.1 using outdated versions of Puppeteer fail on newer versions of the `ubuntu-24` image. # This disables AppArmor in order to work around those failures. # # See https://issues.chromium.org/issues/373753919 diff --git a/.github/workflows/reusable-javascript-type-checking-v1.yml b/.github/workflows/reusable-javascript-type-checking-v1.yml index 7eab9346f2147..9dabd01e27fa0 100644 --- a/.github/workflows/reusable-javascript-type-checking-v1.yml +++ b/.github/workflows/reusable-javascript-type-checking-v1.yml @@ -39,7 +39,7 @@ jobs: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: '.nvmrc' cache: npm @@ -53,7 +53,7 @@ jobs: run: npm ci --ignore-scripts - name: Cache TypeScript build info - uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: | *.tsbuildinfo @@ -65,7 +65,7 @@ jobs: run: npm run typecheck:js - name: "Save result cache" - uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 if: ${{ !cancelled() }} with: path: | diff --git a/.github/workflows/reusable-performance-report-v2.yml b/.github/workflows/reusable-performance-report-v2.yml index 1b158bb6813ae..33a83bd2e5c3d 100644 --- a/.github/workflows/reusable-performance-report-v2.yml +++ b/.github/workflows/reusable-performance-report-v2.yml @@ -62,7 +62,7 @@ jobs: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: '.nvmrc' cache: npm diff --git a/.github/workflows/reusable-performance-test-v2.yml b/.github/workflows/reusable-performance-test-v2.yml index f572060e26d63..c0279c37fe64b 100644 --- a/.github/workflows/reusable-performance-test-v2.yml +++ b/.github/workflows/reusable-performance-test-v2.yml @@ -19,7 +19,7 @@ on: description: 'The version being used for baseline measurements.' required: false type: 'string' - default: '6.7.0' + default: '7.0.0' TARGET_SHA: description: 'SHA hash of the target commit used for "before" measurements.' required: true @@ -49,7 +49,7 @@ on: required: false env: - PUPPETEER_SKIP_DOWNLOAD: ${{ true }} + PUPPETEER_SKIP_DOWNLOAD: true # Prevent wp-scripts from downloading extra Playwright browsers, # since Chromium will be installed in its dedicated step already. @@ -78,6 +78,7 @@ jobs: # - Configure environment variables. # - Checkout repository. # - Set up Node.js. + # - Set up PHP. # - Log debug information. # - Install npm dependencies. # - Install Playwright browsers. @@ -122,11 +123,19 @@ jobs: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: '.nvmrc' cache: npm + - name: Set up PHP + if: ${{ inputs.subject == 'base' }} + uses: shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc # 2.37.1 + with: + php-version: ${{ inputs.php-version }} + tools: wp-cli + coverage: none + - name: Log debug information run: | npm --version @@ -183,7 +192,7 @@ jobs: if: ${{ inputs.subject == 'base' }} run: | VERSION="${BASE_TAG%.0}" - npm run env:cli -- core download --version="$VERSION" --force --path="/var/www/${LOCAL_DIR}" + wp core download --version="$VERSION" --force --path="${LOCAL_DIR}" - name: Install object cache drop-in if: ${{ inputs.memcached }} @@ -255,7 +264,7 @@ jobs: TEST_RESULTS_PREFIX: ${{ inputs.subject != 'current' && inputs.subject || '' }} - name: Archive artifacts - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 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 deleted file mode 100644 index 923b472f609c6..0000000000000 --- a/.github/workflows/reusable-performance.yml +++ /dev/null @@ -1,357 +0,0 @@ -## -# A reusable workflow that runs the performance test suite. -## -name: Run performance Tests - -on: - workflow_call: - inputs: - LOCAL_DIR: - description: 'Where to run WordPress from.' - required: false - type: 'string' - default: 'build' - BASE_TAG: - description: 'The version being used for baseline measurements.' - required: false - type: 'string' - default: '6.7.0' - php-version: - description: 'The PHP version to use.' - required: false - type: 'string' - default: 'latest' - memcached: - description: 'Whether to enable memcached.' - required: false - type: 'boolean' - default: false - multisite: - description: 'Whether to use Multisite.' - required: false - type: 'boolean' - default: false - secrets: - CODEVITALS_PROJECT_TOKEN: - description: 'The authorization token for https://www.codevitals.run/project/wordpress.' - required: false - -env: - PUPPETEER_SKIP_DOWNLOAD: ${{ true }} - - # Prevent wp-scripts from downloading extra Playwright browsers, - # since Chromium will be installed in its dedicated step already. - PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: true - - # Performance testing should be performed in an environment reflecting a standard production environment. - LOCAL_WP_DEBUG: false - LOCAL_SCRIPT_DEBUG: false - LOCAL_SAVEQUERIES: false - LOCAL_WP_DEVELOPMENT_MODE: "''" - - # This workflow takes two sets of measurements — one for the current commit, - # and another against a consistent version that is used as a baseline measurement. - # This is done to isolate variance in measurements caused by the GitHub runners - # from differences caused by code changes between commits. The BASE_TAG value here - # represents the version being used for baseline measurements. It should only be - # changed if we want to normalize results against a different baseline. - BASE_TAG: ${{ inputs.BASE_TAG }} - LOCAL_DIR: ${{ inputs.LOCAL_DIR }} - TARGET_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref || '' }} - TARGET_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} - - LOCAL_PHP_MEMCACHED: ${{ inputs.memcached }} - LOCAL_PHP: ${{ inputs.php-version }}${{ 'latest' != inputs.php-version && '-fpm' || '' }} - LOCAL_MULTISITE: ${{ inputs.multisite }} - -# Disable permissions for all available scopes by default. -# Any needed permissions should be configured at the job level. -permissions: {} - -jobs: - # Performs the following steps: - # - Configure environment variables. - # - Checkout repository. - # - Determine the target SHA value (on `workflow_dispatch` only). - # - Set up Node.js. - # - Log debug information. - # - Install npm dependencies. - # - Install Playwright browsers. - # - Build WordPress. - # - Start Docker environment. - # - Install object cache drop-in. - # - Log running Docker containers. - # - Docker debug information. - # - Install WordPress. - # - Enable themes on Multisite. - # - Install WordPress Importer plugin. - # - Import mock data. - # - Deactivate WordPress Importer plugin. - # - Update permalink structure. - # - Install additional languages. - # - Disable external HTTP requests. - # - Disable cron. - # - List defined constants. - # - Install MU plugin. - # - Run performance tests (current commit). - # - Download previous build artifact (target branch or previous commit). - # - Download artifact. - # - Unzip the build. - # - Run any database upgrades. - # - Flush cache. - # - Delete expired transients. - # - Run performance tests (previous/target commit). - # - Set the environment to the baseline version. - # - Run any database upgrades. - # - Flush cache. - # - Delete expired transients. - # - Run baseline performance tests. - # - Archive artifacts. - # - Compare results. - # - Add workflow summary. - # - Set the base sha. - # - Set commit details. - # - Publish performance results. - # - Ensure version-controlled files are not modified or deleted. - performance: - name: ${{ inputs.multisite && 'Multisite' || 'Single site' }} / ${{ inputs.memcached && 'Memcached' || 'Default' }} - runs-on: ubuntu-24.04 - permissions: - contents: read - if: ${{ ! contains( github.event.before, '00000000' ) }} - - steps: - - name: Configure environment variables - run: | - echo "PHP_FPM_UID=$(id -u)" >> "$GITHUB_ENV" - echo "PHP_FPM_GID=$(id -g)" >> "$GITHUB_ENV" - - - name: Checkout repository - 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 - - # The `workflow_dispatch` event is the only one missing the needed SHA to target. - - name: Retrieve previous commit SHA (if necessary) - if: ${{ github.event_name == 'workflow_dispatch' }} - run: echo "TARGET_SHA=$(git rev-parse HEAD^1)" >> "$GITHUB_ENV" - - - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 - with: - node-version-file: '.nvmrc' - cache: npm - - - name: Log debug information - run: | - npm --version - node --version - curl --version - git --version - locale -a - - - name: Install npm dependencies - run: npm ci - - - name: Install Playwright browsers - run: npx playwright install --with-deps chromium - - - name: Build WordPress - run: npm run build - - - name: Start Docker environment - run: npm run env:start - - - name: Install object cache drop-in - if: ${{ inputs.memcached }} - run: cp src/wp-content/object-cache.php build/wp-content/object-cache.php - - - name: Log running Docker containers - run: docker ps -a - - - name: Docker debug information - run: | - docker -v - docker compose run --rm mysql mysql --version - docker compose run --rm php php --version - docker compose run --rm php php -m - docker compose run --rm php php -i - docker compose run --rm php locale -a - - - name: Install WordPress - run: npm run env:install - - - name: Enable themes on Multisite - if: ${{ inputs.multisite }} - run: | - npm run env:cli -- theme enable twentytwentyone --network --path="/var/www/${LOCAL_DIR}" - npm run env:cli -- theme enable twentytwentythree --network --path="/var/www/${LOCAL_DIR}" - npm run env:cli -- theme enable twentytwentyfour --network --path="/var/www/${LOCAL_DIR}" - npm run env:cli -- theme enable twentytwentyfive --network --path="/var/www/${LOCAL_DIR}" - - - name: Install WordPress Importer plugin - run: npm run env:cli -- plugin install wordpress-importer --activate --path="/var/www/${LOCAL_DIR}" - - - name: Import mock data - run: | - curl -O https://raw.githubusercontent.com/WordPress/theme-test-data/b9752e0533a5acbb876951a8cbb5bcc69a56474c/themeunittestdata.wordpress.xml - npm run env:cli -- import themeunittestdata.wordpress.xml --authors=create --path="/var/www/${LOCAL_DIR}" - rm themeunittestdata.wordpress.xml - - - name: Deactivate WordPress Importer plugin - run: npm run env:cli -- plugin deactivate wordpress-importer --path="/var/www/${LOCAL_DIR}" - - - name: Install additional languages - run: | - npm run env:cli -- language core install de_DE --path="/var/www/${LOCAL_DIR}" - npm run env:cli -- language plugin install de_DE --all --path="/var/www/${LOCAL_DIR}" - npm run env:cli -- language theme install de_DE --all --path="/var/www/${LOCAL_DIR}" - - # Prevent background update checks from impacting test stability. - - name: Disable external HTTP requests - run: npm run env:cli -- config set WP_HTTP_BLOCK_EXTERNAL true --raw --type=constant --path="/var/www/${LOCAL_DIR}" - - # Prevent background tasks from impacting test stability. - - name: Disable cron - run: npm run env:cli -- config set DISABLE_WP_CRON true --raw --type=constant --path="/var/www/${LOCAL_DIR}" - - - name: List defined constants - run: npm run env:cli -- config list --path="/var/www/${LOCAL_DIR}" - - - name: Install MU plugin - run: | - mkdir "./${LOCAL_DIR}/wp-content/mu-plugins" - cp ./tests/performance/wp-content/mu-plugins/server-timing.php "./${LOCAL_DIR}/wp-content/mu-plugins/server-timing.php" - - - name: Run performance tests (current commit) - run: npm run test:performance - - - name: Download previous build artifact (target branch or previous commit) - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - id: get-previous-build - with: - script: | - const artifacts = await github.rest.actions.listArtifactsForRepo({ - owner: context.repo.owner, - repo: context.repo.repo, - name: 'wordpress-build-' + process.env.TARGET_SHA, - }); - - const matchArtifact = artifacts.data.artifacts[0]; - - if ( ! matchArtifact ) { - core.setFailed( 'No artifact found!' ); - return false; - } - - const download = await github.rest.actions.downloadArtifact( { - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: matchArtifact.id, - archive_format: 'zip', - } ); - - const fs = require( 'fs' ); - fs.writeFileSync( process.env.GITHUB_WORKSPACE + '/before.zip', Buffer.from( download.data ) ) - - return true; - - - name: Unzip the build - if: ${{ steps.get-previous-build.outputs.result }} - run: | - unzip "${GITHUB_WORKSPACE}/before.zip" - unzip -o "${GITHUB_WORKSPACE}/wordpress.zip" - - - name: Run any database upgrades - if: ${{ steps.get-previous-build.outputs.result }} - run: npm run env:cli -- core update-db --path="/var/www/${LOCAL_DIR}" - - - name: Flush cache - if: ${{ steps.get-previous-build.outputs.result }} - run: npm run env:cli -- cache flush --path="/var/www/${LOCAL_DIR}" - - - name: Delete expired transients - if: ${{ steps.get-previous-build.outputs.result }} - run: npm run env:cli -- transient delete --expired --path="/var/www/${LOCAL_DIR}" - - - name: Run target performance tests (previous/target commit) - if: ${{ steps.get-previous-build.outputs.result }} - env: - TEST_RESULTS_PREFIX: before - run: npm run test:performance - - - name: Set the environment to the baseline version - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/trunk' }} - run: | - VERSION="${BASE_TAG}" - VERSION="${VERSION%.0}" - npm run env:cli -- core update --version="$VERSION" --force --path="/var/www/${LOCAL_DIR}" - npm run env:cli -- core version --path="/var/www/${LOCAL_DIR}" - - - name: Run any database upgrades - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/trunk' }} - run: npm run env:cli -- core update-db --path="/var/www/${LOCAL_DIR}" - - - name: Flush cache - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/trunk' }} - run: npm run env:cli -- cache flush --path="/var/www/${LOCAL_DIR}" - - - name: Delete expired transients - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/trunk' }} - run: npm run env:cli -- transient delete --expired --path="/var/www/${LOCAL_DIR}" - - - name: Run baseline performance tests - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/trunk' }} - env: - TEST_RESULTS_PREFIX: base - run: npm run test:performance - - - name: Archive artifacts - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 - if: always() - with: - name: performance-artifacts${{ inputs.multisite && '-multisite' || '' }}${{ inputs.memcached && '-memcached' || '' }}-${{ github.run_id }} - path: artifacts - if-no-files-found: ignore - include-hidden-files: true - - - name: Compare results - run: node ./tests/performance/compare-results.js "${RUNNER_TEMP}/summary.md" - - - name: Add workflow summary - run: cat "${RUNNER_TEMP}/summary.md" >> "$GITHUB_STEP_SUMMARY" - - - name: Set the base sha - # Only needed when publishing results. - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/trunk' && ! inputs.memcached && ! inputs.multisite }} - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - id: base-sha - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const baseRef = await github.rest.git.getRef({ - owner: context.repo.owner, - repo: context.repo.repo, - ref: 'tags/' + process.env.BASE_TAG, - }); - return baseRef.data.object.sha; - - - name: Publish performance results - # Only publish results on pushes to trunk. - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/trunk' && ! inputs.memcached && ! inputs.multisite }} - env: - BASE_SHA: ${{ steps.base-sha.outputs.result }} - CODEVITALS_PROJECT_TOKEN: ${{ secrets.CODEVITALS_PROJECT_TOKEN }} - HOST_NAME: "codevitals.run" - run: | - if [ -z "$CODEVITALS_PROJECT_TOKEN" ]; then - echo "Performance results could not be published. 'CODEVITALS_PROJECT_TOKEN' is not set" - exit 1 - fi - COMMITTED_AT="$(git show -s "$GITHUB_SHA" --format='%cI')" - node ./tests/performance/log-results.js "$CODEVITALS_PROJECT_TOKEN" trunk "$GITHUB_SHA" "$BASE_SHA" "$COMMITTED_AT" "$HOST_NAME" - - - name: Ensure version-controlled files are not modified or deleted - run: git diff --exit-code diff --git a/.github/workflows/reusable-php-compatibility.yml b/.github/workflows/reusable-php-compatibility.yml index fee371fbdf7a0..7756330282e6f 100644 --- a/.github/workflows/reusable-php-compatibility.yml +++ b/.github/workflows/reusable-php-compatibility.yml @@ -46,7 +46,7 @@ jobs: persist-credentials: false - name: Set up PHP - uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.37.0 + uses: shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc # 2.37.1 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@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 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') }} @@ -71,7 +71,7 @@ jobs: # 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@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 + uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # 4.0.0 with: custom-cache-suffix: ${{ steps.get-date.outputs.date }} diff --git a/.github/workflows/reusable-phpstan-static-analysis-v1.yml b/.github/workflows/reusable-phpstan-static-analysis-v1.yml index bbf1b78589a8c..c73c1e5e692fe 100644 --- a/.github/workflows/reusable-phpstan-static-analysis-v1.yml +++ b/.github/workflows/reusable-phpstan-static-analysis-v1.yml @@ -23,11 +23,14 @@ jobs: # # Performs the following steps: # - Checks out the repository. + # - Sets up Node.js. # - Sets up PHP. # - Logs debug information. # - Installs Composer dependencies. - # - Configures caching for PHP static analysis scans. # - Make Composer packages available globally. + # - Installs npm dependencies. + # - Builds WordPress. + # - Configures caching for PHPStan static analysis scans. # - Runs PHPStan static analysis (with Pull Request annotations). # - Saves the PHPStan result cache. # - Ensures version-controlled files are not modified or deleted. @@ -46,24 +49,18 @@ jobs: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: '.nvmrc' cache: npm - name: Set up PHP - uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.37.0 + uses: shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc # 2.37.1 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 @@ -73,9 +70,9 @@ jobs: # 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@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 + uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # 4.0.0 with: - custom-cache-suffix: ${{ steps.get-date.outputs.date }} + custom-cache-suffix: $(/bin/date -u --date='last Mon' "+%F") - name: Make Composer packages available globally run: echo "${PWD}/vendor/bin" >> "$GITHUB_PATH" @@ -87,7 +84,7 @@ jobs: run: npm run build:dev - name: Cache PHP Static Analysis scan cache - uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: .cache # This is defined in the base.neon file. key: "phpstan-result-cache-${{ github.run_id }}" @@ -99,7 +96,7 @@ jobs: run: composer run phpstan -- -vvv --error-format=checkstyle | cs2pr --errors-as-warnings --graceful-warnings - name: "Save result cache" - uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 if: ${{ !cancelled() }} with: path: .cache diff --git a/.github/workflows/reusable-phpunit-tests-v1.yml b/.github/workflows/reusable-phpunit-tests-v1.yml index bcb0451d7134b..2783b72a911b1 100644 --- a/.github/workflows/reusable-phpunit-tests-v1.yml +++ b/.github/workflows/reusable-phpunit-tests-v1.yml @@ -50,13 +50,13 @@ on: type: boolean default: false env: - COMPOSER_INSTALL: ${{ false }} + COMPOSER_INSTALL: false LOCAL_PHP: ${{ inputs.php }}-fpm LOCAL_PHPUNIT: ${{ inputs.phpunit && inputs.phpunit || inputs.php }}-fpm LOCAL_PHP_MEMCACHED: ${{ inputs.memcached }} PHPUNIT_CONFIG: ${{ inputs.phpunit-config }} PHPUNIT_SCRIPT: php - PUPPETEER_SKIP_DOWNLOAD: ${{ true }} + PUPPETEER_SKIP_DOWNLOAD: true SLOW_TESTS: 'external-http,media' # Disable permissions for all available scopes by default. @@ -103,7 +103,7 @@ jobs: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 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 4e7b6716ebef1..5e078b6ef0c2e 100644 --- a/.github/workflows/reusable-phpunit-tests-v2.yml +++ b/.github/workflows/reusable-phpunit-tests-v2.yml @@ -58,7 +58,7 @@ env: LOCAL_PHP: ${{ inputs.php }}-fpm LOCAL_PHP_MEMCACHED: ${{ inputs.memcached }} PHPUNIT_CONFIG: ${{ inputs.phpunit-config }} - PUPPETEER_SKIP_DOWNLOAD: ${{ true }} + PUPPETEER_SKIP_DOWNLOAD: true # Controls which npm script to use for running PHPUnit tests. Options ar `php` and `php-composer`. PHPUNIT_SCRIPT: php SLOW_TESTS: 'external-http,media' @@ -105,7 +105,7 @@ jobs: persist-credentials: false - name: Install Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 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 da0372f8538be..7e10a030953a4 100644 --- a/.github/workflows/reusable-phpunit-tests-v3.yml +++ b/.github/workflows/reusable-phpunit-tests-v3.yml @@ -82,14 +82,14 @@ on: env: LOCAL_PHP: ${{ inputs.php }}-fpm - LOCAL_PHP_XDEBUG: ${{ inputs.coverage-report || false }} - LOCAL_PHP_XDEBUG_MODE: ${{ inputs.coverage-report && 'coverage' || 'develop,debug' }} + LOCAL_PHP_XDEBUG: false + LOCAL_PHP_XDEBUG_MODE: 'develop,debug' LOCAL_DB_TYPE: ${{ inputs.db-type }} LOCAL_DB_VERSION: ${{ inputs.db-version }} LOCAL_PHP_MEMCACHED: ${{ inputs.memcached }} LOCAL_WP_TESTS_DOMAIN: ${{ inputs.tests-domain }} PHPUNIT_CONFIG: ${{ inputs.phpunit-config }} - PUPPETEER_SKIP_DOWNLOAD: ${{ true }} + PUPPETEER_SKIP_DOWNLOAD: true # Disable permissions for all available scopes by default. # Any needed permissions should be configured at the job level. @@ -113,7 +113,6 @@ jobs: # - Install WordPress within the Docker container. # - Run the PHPUnit tests. # - Upload the code coverage report to Codecov.io. - # - Upload the HTML code coverage report as an artifact. # - Ensures version-controlled files are not modified or deleted. # - Checks out the WordPress Test reporter repository. # - Submit the test results to the WordPress.org host test results. @@ -137,7 +136,7 @@ jobs: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: '.nvmrc' cache: npm @@ -150,7 +149,7 @@ jobs: # dependency versions are installed and cached. ## - name: Set up PHP - uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.37.0 + uses: shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc # 2.37.1 with: php-version: '${{ inputs.php }}' coverage: none @@ -158,7 +157,7 @@ jobs: # 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@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 + uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # 4.0.0 with: custom-cache-suffix: $(/bin/date -u --date='last Mon' "+%F") @@ -201,15 +200,45 @@ jobs: - name: Install WordPress run: npm run env:install + # Installs PCOV as the code coverage driver for the PHPUnit run below. + # + # The INI directives tune PCOV for WordPress's codebase: + # - `pcov.enabled` keeps the Zend hooks active (this is the default, but + # stated explicitly for clarity). + # - `pcov.directory` restricts instrumentation to `src/`, so PCOV does not + # record hits for `vendor/`, `tests/`, or WordPress test fixtures that + # PHPUnit would discard at report time anyway. + # - `pcov.initial.files` pre-sizes the internal file tracking array for + # the thousands of files under `src/`, avoiding reallocation churn + # during test warmup. The default of 64 is far too low here. + - name: Install PCOV coverage driver + if: ${{ inputs.coverage-report }} + run: | + docker compose exec -T -u 0 php sh -c ' + pecl install --force pcov-1.0.12 && + docker-php-ext-enable pcov && + { + echo "pcov.enabled=1" + echo "pcov.directory=/var/www/src" + echo "pcov.initial.files=10000" + } >> /usr/local/etc/php/conf.d/docker-php-ext-pcov.ini && + php -m | grep -i pcov + ' + + - name: Run external HTTP tests + if: ${{ ! inputs.multisite && ! inputs.phpunit-test-groups && ! inputs.coverage-report }} + continue-on-error: ${{ inputs.allow-errors }} + run: node ./tools/local-env/scripts/docker.js run php ./vendor/bin/phpunit --verbose -c "${PHPUNIT_CONFIG}" --group external-http + - name: Run PHPUnit tests${{ inputs.phpunit-test-groups && format( ' ({0} groups)', inputs.phpunit-test-groups ) || '' }}${{ inputs.coverage-report && ' with coverage report' || '' }} continue-on-error: ${{ inputs.allow-errors }} run: | - node ./tools/local-env/scripts/docker.js run \ + node ./tools/local-env/scripts/docker.js ${{ inputs.coverage-report && 'exec' || 'run' }} \ php ./vendor/bin/phpunit \ --verbose \ -c "${PHPUNIT_CONFIG}" \ ${{ inputs.phpunit-test-groups && '--group "${TEST_GROUPS}"' || '' }} \ - ${{ inputs.coverage-report && '--coverage-clover "wp-code-coverage-${MULTISITE_FLAG}-${GITHUB_SHA}.xml" --coverage-html "wp-code-coverage-${MULTISITE_FLAG}-${GITHUB_SHA}"' || '' }} + ${{ inputs.coverage-report && '--coverage-clover "wp-code-coverage-${MULTISITE_FLAG}-${GITHUB_SHA}.xml"' || '' }} env: TEST_GROUPS: ${{ inputs.phpunit-test-groups }} MULTISITE_FLAG: ${{ inputs.multisite && 'multisite' || 'single' }} @@ -224,11 +253,6 @@ jobs: continue-on-error: ${{ inputs.allow-errors }} run: node ./tools/local-env/scripts/docker.js run php ./vendor/bin/phpunit --verbose -c "${PHPUNIT_CONFIG}" --group ms-files - - name: Run external HTTP tests - if: ${{ ! inputs.multisite && ! inputs.phpunit-test-groups && ! inputs.coverage-report }} - continue-on-error: ${{ inputs.allow-errors }} - run: node ./tools/local-env/scripts/docker.js run php ./vendor/bin/phpunit --verbose -c "${PHPUNIT_CONFIG}" --group external-http - # __fakegroup__ is excluded to force PHPUnit to ignore the settings in phpunit.xml.dist. - name: Run (Xdebug) tests if: ${{ ! inputs.phpunit-test-groups && ! inputs.coverage-report }} @@ -237,21 +261,13 @@ jobs: - name: Upload test coverage report to Codecov if: ${{ inputs.coverage-report }} - uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5.5.3 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: token: ${{ secrets.CODECOV_TOKEN }} files: wp-code-coverage${{ inputs.multisite && '-multisite' || '-single' }}-${{ github.sha }}.xml flags: ${{ inputs.multisite && 'multisite' || 'single' }},php fail_ci_if_error: true - - name: Upload HTML coverage report as artifact - if: ${{ inputs.coverage-report }} - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 - with: - name: wp-code-coverage${{ inputs.multisite && '-multisite' || '-single' }}-${{ github.sha }} - path: wp-code-coverage${{ inputs.multisite && '-multisite' || '-single' }}-${{ github.sha }} - overwrite: true - - name: Ensure version-controlled files are not modified or deleted run: git diff --exit-code diff --git a/.github/workflows/reusable-test-core-build-process.yml b/.github/workflows/reusable-test-core-build-process.yml index fbb6a08b15820..1566d1583a807 100644 --- a/.github/workflows/reusable-test-core-build-process.yml +++ b/.github/workflows/reusable-test-core-build-process.yml @@ -38,7 +38,7 @@ on: default: false env: - PUPPETEER_SKIP_DOWNLOAD: ${{ true }} + PUPPETEER_SKIP_DOWNLOAD: true NODE_OPTIONS: --max-old-space-size=4096 # Disable permissions for all available scopes by default. @@ -86,12 +86,12 @@ jobs: # passing a custom cache suffix ensures that the cache is flushed at least once per week. - name: Install Composer dependencies if: ${{ inputs.test-certificates }} - uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 + uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # 4.0.0 with: custom-cache-suffix: ${{ steps.get-date.outputs.date }} - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 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@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 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 6fff07a842bf2..4a780d08ee07f 100644 --- a/.github/workflows/reusable-test-gutenberg-build-process.yml +++ b/.github/workflows/reusable-test-gutenberg-build-process.yml @@ -19,7 +19,7 @@ on: env: GUTENBERG_DIRECTORY: ${{ inputs.directory == 'build' && 'build' || 'src' }}/wp-content/plugins/gutenberg - PUPPETEER_SKIP_DOWNLOAD: ${{ true }} + PUPPETEER_SKIP_DOWNLOAD: true NODE_OPTIONS: '--max-old-space-size=8192' # Disable permissions for all available scopes by default. @@ -63,7 +63,7 @@ jobs: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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 9aa0fb124a22e..8f1a556afa2b4 100644 --- a/.github/workflows/reusable-test-local-docker-environment-v1.yml +++ b/.github/workflows/reusable-test-local-docker-environment-v1.yml @@ -45,7 +45,7 @@ env: LOCAL_DB_VERSION: ${{ inputs.db-version }} LOCAL_PHP_MEMCACHED: ${{ inputs.memcached }} LOCAL_WP_TESTS_DOMAIN: ${{ inputs.tests-domain }} - PUPPETEER_SKIP_DOWNLOAD: ${{ true }} + PUPPETEER_SKIP_DOWNLOAD: true # Disable permissions for all available scopes by default. # Any needed permissions should be configured at the job level. @@ -92,7 +92,7 @@ jobs: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@accd6127cb78bee3e8082180cb391013d204ef9f # v2.37.0 + uses: shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc # 2.37.1 with: php-version: '${{ inputs.php }}' coverage: none @@ -113,7 +113,7 @@ jobs: # 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@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0 + uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # 4.0.0 with: custom-cache-suffix: $(/bin/date -u --date='last Mon' "+%F") diff --git a/.github/workflows/reusable-upgrade-testing.yml b/.github/workflows/reusable-upgrade-testing.yml index 60d5523a9e3b6..47ad8723f808b 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@accd6127cb78bee3e8082180cb391013d204ef9f # v2.37.0 + uses: shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc # 2.37.1 with: php-version: '${{ inputs.php }}' coverage: none diff --git a/.github/workflows/reusable-workflow-lint.yml b/.github/workflows/reusable-workflow-lint.yml index 3a538a8a99690..127a392a2dd28 100644 --- a/.github/workflows/reusable-workflow-lint.yml +++ b/.github/workflows/reusable-workflow-lint.yml @@ -7,12 +7,10 @@ permissions: {} jobs: # Runs the actionlint GitHub Action workflow file linter. # + # See https://github.com/rhysd/actionlint. + # # This helps guard against common mistakes including strong type checking for expressions (${{ }}), security checks, # `run:` script checking, glob syntax validation, and more. - # - # Performs the following steps: - # - Checks out the repository. - # - Runs actionlint. actionlint: name: Run actionlint runs-on: ubuntu-24.04 @@ -26,9 +24,46 @@ jobs: persist-credentials: false show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - # actionlint is static checker for GitHub Actions workflow files. - # See https://github.com/rhysd/actionlint. - name: Run actionlint - uses: docker://rhysd/actionlint@sha256:887a259a5a534f3c4f36cb02dca341673c6089431057242cdc931e9f133147e9 # v1.7.7 + uses: docker://rhysd/actionlint@sha256:5457037ba91acd225478edac3d4b32e45cf6c10291e0dabbfd2491c63129afe1 # v1.7.11 with: args: "-color -verbose" + + # Runs the Zizmor GitHub Action workflow file linter. + # + # See https://github.com/zizmorcore/zizmor + # + # This helps guard against supply chain attacks, unpinned dependencies, excessive permissions, + # dangerous triggers, credential leaks, and sophisticated security vulnerabilities. + # + # Performs the following steps: + # - Checks out the repository. + # - Installs and configures uv. + # - Runs a zizmor scan. + # - Uploads the SARIF file to GitHub. + zizmor: + name: Zizmor + runs-on: ubuntu-24.04 + permissions: + security-events: write + actions: read + contents: read + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Install the latest version of uv + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + + - name: Run zizmor + run: uvx zizmor@1.24.1 --persona=regular --format=sarif --strict-collection . > results.sarif + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 + with: + sarif_file: results.sarif + category: zizmor diff --git a/.github/workflows/slack-notifications.yml b/.github/workflows/slack-notifications.yml index 3d0dd7c680558..bf9dca7dbf362 100644 --- a/.github/workflows/slack-notifications.yml +++ b/.github/workflows/slack-notifications.yml @@ -171,7 +171,7 @@ jobs: steps: - name: Post failure notifications to Slack - uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1 + uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 with: webhook-type: webhook-trigger webhook: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} @@ -188,7 +188,7 @@ jobs: steps: - name: Post failure notifications to Slack - uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1 + uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 with: webhook-type: webhook-trigger webhook: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} @@ -205,7 +205,7 @@ jobs: steps: - name: Post success notifications to Slack - uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1 + uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 with: webhook-type: webhook-trigger webhook: ${{ secrets.SLACK_GHA_SUCCESS_WEBHOOK }} @@ -222,7 +222,7 @@ jobs: steps: - name: Post cancelled notifications to Slack - uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1 + uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 with: webhook-type: webhook-trigger webhook: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} diff --git a/.github/workflows/test-and-zip-default-themes.yml b/.github/workflows/test-and-zip-default-themes.yml index 6ea0f7f206809..1a44a8ff12e3a 100644 --- a/.github/workflows/test-and-zip-default-themes.yml +++ b/.github/workflows/test-and-zip-default-themes.yml @@ -144,7 +144,7 @@ jobs: persist-credentials: false - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: ${{ steps.built-file-check.outputs.uncommitted_changes == 'true' }} with: name: pr-built-file-changes @@ -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@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ matrix.theme }} path: | diff --git a/.github/workflows/test-coverage.yml b/.github/workflows/test-coverage.yml index deb190eba9e9b..e1c3dd3be2f59 100644 --- a/.github/workflows/test-coverage.yml +++ b/.github/workflows/test-coverage.yml @@ -38,10 +38,8 @@ concurrency: permissions: {} env: - LOCAL_PHP_XDEBUG: true - LOCAL_PHP_XDEBUG_MODE: 'coverage' - LOCAL_PHP_MEMCACHED: ${{ false }} - PUPPETEER_SKIP_DOWNLOAD: ${{ true }} + LOCAL_PHP_MEMCACHED: false + PUPPETEER_SKIP_DOWNLOAD: true jobs: # diff --git a/.github/workflows/test-old-branches.yml b/.github/workflows/test-old-branches.yml index 74f9c2d43d54c..ae651290d9cd8 100644 --- a/.github/workflows/test-old-branches.yml +++ b/.github/workflows/test-old-branches.yml @@ -7,7 +7,7 @@ on: - trunk paths: - '.github/workflows/test-old-branches.yml' - - '.github/workflows/reusable-phpunit-tests-v[1-2].yml' + - '.github/workflows/reusable-phpunit-tests-v[1-3].yml' # Run twice a month on the 1st and 15th at 00:00 UTC. schedule: - cron: '0 0 1 * *' diff --git a/.github/workflows/upgrade-develop-testing.yml b/.github/workflows/upgrade-develop-testing.yml index 7dfe96271f459..6d4abe304ecfb 100644 --- a/.github/workflows/upgrade-develop-testing.yml +++ b/.github/workflows/upgrade-develop-testing.yml @@ -75,7 +75,7 @@ jobs: db-type: [ 'mysql' ] db-version: [ '5.7', '8.4' ] # WordPress 5.3 is the oldest version that supports PHP 7.4. - wp: [ '5.3', '6.8', '6.9', '7.0-RC2' ] + wp: [ '5.3', '6.9', '7.0' ] multisite: [ false, true ] with: os: ${{ matrix.os }} @@ -101,7 +101,7 @@ jobs: php: [ '7.4', '8.4' ] db-type: [ 'mysql' ] db-version: [ '8.4' ] - wp: [ '6.8', '6.9', '7.0-RC2' ] + wp: [ '6.9', '7.0' ] multisite: [ false, true ] with: os: ${{ matrix.os }} diff --git a/.github/workflows/upgrade-testing.yml b/.github/workflows/upgrade-testing.yml index b8953bad20def..8a74e5ae614c5 100644 --- a/.github/workflows/upgrade-testing.yml +++ b/.github/workflows/upgrade-testing.yml @@ -70,8 +70,8 @@ jobs: os: [ 'ubuntu-24.04' ] php: [ '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] db-type: [ 'mysql' ] - db-version: [ '5.7', '8.0', '8.4', '9.6' ] - wp: [ '6.8', '6.9', '7.0-RC2' ] + db-version: [ '5.7', '8.0', '8.4', '9.7' ] + wp: [ '6.9', '7.0' ] multisite: [ false, true ] with: os: ${{ matrix.os }} @@ -179,7 +179,7 @@ jobs: os: [ 'ubuntu-24.04' ] php: [ '7.4' ] db-type: [ 'mysql' ] - db-version: [ '5.7', '8.0', '8.4', '9.6' ] + db-version: [ '5.7', '8.0', '8.4', '9.7' ] wp: [ '4.7' ] multisite: [ false, true ] with: diff --git a/.version-support-mysql.json b/.version-support-mysql.json index 6e81f2eff0f09..7ab8aa38df392 100644 --- a/.version-support-mysql.json +++ b/.version-support-mysql.json @@ -1,12 +1,6 @@ { "7-1": [ - "9.6", - "9.5", - "9.4", - "9.3", - "9.2", - "9.1", - "9.0", + "9.7", "8.4", "8.0", "5.7", diff --git a/Gruntfile.js b/Gruntfile.js index 5f9109fac3cb0..ab56358b8f60d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -41,18 +41,43 @@ module.exports = function(grunt) { 'wp-admin/css/colors/**/*.css', ], - // Built js files, in /src or /build. + // Built JavaScript files that do not belong to a more specific group. jsFiles = [ 'wp-admin/js/', - 'wp-includes/js/', + 'wp-includes/js/*', + /* + * This directory has shared responsibility and is managed through + * gutenbergUnversionedFiles, webpackFiles, and copy:vendor-js. + */ + '!wp-includes/js/dist', + 'wp-includes/js/dist/vendor/*.js', + // Managed by the Gutenberg-related tasks. + '!wp-includes/js/dist/vendor/react-jsx-runtime*', ], - // All files copied from the Gutenberg repository excluded from version control. - gutenbergFiles = [ - 'wp-includes/js/dist', - 'wp-includes/css/dist', - // Old location kept temporarily to ensure they are cleaned up. - 'wp-includes/icons', + // Files sourced from the Gutenberg repository built asset that are ignored by version control. + gutenbergUnversionedFiles = [ + SOURCE_DIR + 'wp-includes/blocks/*/*.css', + SOURCE_DIR + 'wp-includes/css/dist', + SOURCE_DIR + 'wp-includes/js/dist/*.js', + SOURCE_DIR + 'wp-includes/js/dist/script-modules', + SOURCE_DIR + 'wp-includes/js/dist/vendor/react-jsx-runtime*', + ], + + // Files sourced from the Gutenberg repository built asset that are managed through version control. + gutenbergVersionedFiles = [ + // Block assets (block.json, top-level PHP, nested PHP helpers). + SOURCE_DIR + 'wp-includes/blocks/*', + '!' + SOURCE_DIR + 'wp-includes/blocks/index.php', + SOURCE_DIR + 'wp-includes/images/icon-library', + SOURCE_DIR + 'wp-includes/theme.json', + SOURCE_DIR + 'wp-includes/theme-i18n.json', + // Routes and pages. + SOURCE_DIR + 'wp-includes/build', + // PHP manifests generated by gutenberg:copy. + SOURCE_DIR + 'wp-includes/assets/icon-library-manifest.php', + SOURCE_DIR + 'wp-includes/assets/script-loader-packages.php', + SOURCE_DIR + 'wp-includes/assets/script-modules-packages.php', ], // All files built by Webpack, in /src or /build. @@ -115,7 +140,6 @@ module.exports = function(grunt) { 'cssmin', 'imagemin', 'jshint', - 'qunit', 'uglify', 'watch' ], @@ -242,10 +266,32 @@ module.exports = function(grunt) { return setFilePath( WORKING_DIR, file ); } ), - // Clean files built by the tools/gutenberg scripts. - gutenberg: gutenbergFiles.map( function( file ) { - return setFilePath( WORKING_DIR, file ); - }), + /* + * Clean files sourced from the downloaded zip file built by the Gutenberg repository. + * + * All files originating from the Gutenberg repository's built assets (both tracked and untracked by version + * control) are deleted when `clean:gutenberg` is explicitly called. This ensures that versioned files that + * have been deleted upstream are also removed from version control in this repository. + * + * When `clean:gutenberg` is not explicitly called and run through `grunt clean`, only ignored files are + * cleaned. + */ + gutenberg: { + get src() { + const cli = grunt.cli.tasks; + // Preserve versioned files only when running bare `grunt clean`. + const isBareCleanSweep = + cli.includes( 'clean' ) && + ! cli.includes( 'clean:gutenberg' ); + + if ( isBareCleanSweep ) { + return gutenbergUnversionedFiles; + } else { + return gutenbergUnversionedFiles.concat( gutenbergVersionedFiles ); + } + }, + }, + dynamic: { dot: true, expand: true, @@ -290,7 +336,6 @@ module.exports = function(grunt) { expand: true, cwd: SOURCE_DIR, src: buildFiles.concat( [ - '!wp-includes/assets/**', // Assets is extracted into separate copy tasks. '!js/**', // JavaScript is extracted into separate copy tasks. '!.{svn,git}', // Exclude version control folders. '!wp-includes/version.php', // Exclude version.php. @@ -397,6 +442,55 @@ module.exports = function(grunt) { 'suggest*' ], dest: WORKING_DIR + 'wp-includes/js/jquery/' + }, + { + [ WORKING_DIR + 'wp-includes/js/dist/vendor/lodash.js' ]: [ './node_modules/lodash/lodash.js' ], + [ WORKING_DIR + 'wp-includes/js/dist/vendor/lodash.min.js' ]: [ './node_modules/lodash/lodash.min.js' ], + }, + { + [ WORKING_DIR + 'wp-includes/js/dist/vendor/moment.js' ]: [ './node_modules/moment/moment.js' ], + [ WORKING_DIR + 'wp-includes/js/dist/vendor/moment.min.js' ]: [ './node_modules/moment/min/moment.min.js' ], + }, + { + [ WORKING_DIR + 'wp-includes/js/dist/vendor/regenerator-runtime.js' ]: [ './node_modules/regenerator-runtime/runtime.js' ], + [ WORKING_DIR + 'wp-includes/js/dist/vendor/regenerator-runtime.min.js' ]: [ './node_modules/regenerator-runtime/runtime.js' ], + }, + // React libraries: react, react-dom + { + [ WORKING_DIR + 'wp-includes/js/dist/vendor/react.js' ]: [ './node_modules/react/umd/react.development.js' ], + [ WORKING_DIR + 'wp-includes/js/dist/vendor/react.min.js' ]: [ './node_modules/react/umd/react.production.min.js' ], + [ WORKING_DIR + 'wp-includes/js/dist/vendor/react-dom.js' ]: [ './node_modules/react-dom/umd/react-dom.development.js' ], + [ WORKING_DIR + 'wp-includes/js/dist/vendor/react-dom.min.js' ]: [ './node_modules/react-dom/umd/react-dom.production.min.js' ], + }, + // Polyfills + { + // @wordpress/babel-preset-default + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill.js' ]: [ './node_modules/@wordpress/babel-preset-default/build/polyfill.js' ], + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill.min.js' ]: [ './node_modules/@wordpress/babel-preset-default/build/polyfill.min.js' ], + // polyfill-library (DOMRect) + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-dom-rect.js' ]: [ './node_modules/polyfill-library/polyfills/__dist/DOMRect/raw.js' ], + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-dom-rect.min.js' ]: [ './node_modules/polyfill-library/polyfills/__dist/DOMRect/min.js' ], + // element-closest + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-element-closest.js' ]: [ './node_modules/element-closest/browser.js' ], + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-element-closest.min.js' ]: [ './node_modules/element-closest/browser.js' ], + // whatwg-fetch + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-fetch.js' ]: [ './node_modules/whatwg-fetch/dist/fetch.umd.js' ], + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-fetch.min.js' ]: [ './node_modules/whatwg-fetch/dist/fetch.umd.js' ], + // formdata-polyfill + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-formdata.js' ]: [ './node_modules/formdata-polyfill/FormData.js' ], + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-formdata.min.js' ]: [ './node_modules/formdata-polyfill/formdata.min.js' ], + // wicg-inert + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-inert.js' ]: [ './node_modules/wicg-inert/dist/inert.js' ], + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-inert.min.js' ]: [ './node_modules/wicg-inert/dist/inert.min.js' ], + // polyfill-library (Node.prototype.contains) + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-node-contains.js' ]: [ './node_modules/polyfill-library/polyfills/__dist/Node.prototype.contains/raw.js' ], + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-node-contains.min.js' ]: [ './node_modules/polyfill-library/polyfills/__dist/Node.prototype.contains/min.js' ], + // objectFitPolyfill + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-object-fit.js' ]: [ './node_modules/objectFitPolyfill/src/objectFitPolyfill.js' ], + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-object-fit.min.js' ]: [ './node_modules/objectFitPolyfill/dist/objectFitPolyfill.min.js' ], + // core-js-url-browser + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-url.js' ]: [ './node_modules/core-js-url-browser/url.js' ], + [ WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-url.min.js' ]: [ './node_modules/core-js-url-browser/url.min.js' ], } ].concat( // Copy tinymce.js only when building to /src. @@ -618,24 +712,18 @@ module.exports = function(grunt) { 'constants.php', 'pages/**/*.php', ], - dest: WORKING_DIR + 'wp-includes/build/', + dest: SOURCE_DIR + 'wp-includes/build/', } ], }, /* - * Only copy files relevant to the routes specified in the registry file. - * - * While the registry file does not contain any experimental routes, the `gutenberg/build/routes` directory - * includes the files for all registered routes. Only the files related to the routes specified in the - * registry should be included in the WordPress build. - * - * The `src` list is populated at task runtime by `routes:setup`, which reads the registry after - * `gutenberg:download` has run. See the `routes:setup` task registration for implementation details. + * The list of route source files is populated from the contents of the registry.php file at task runtime by + * `routes:setup`. */ routes: { expand: true, cwd: 'gutenberg/build', src: [], - dest: WORKING_DIR + 'wp-includes/build/', + dest: SOURCE_DIR + 'wp-includes/build/', }, 'gutenberg-js': { files: [ { @@ -644,7 +732,7 @@ module.exports = function(grunt) { src: [ 'pages/**/*.js', ], - dest: WORKING_DIR + 'wp-includes/build/', + dest: SOURCE_DIR + 'wp-includes/build/', } ], }, 'gutenberg-modules': { @@ -654,9 +742,11 @@ module.exports = function(grunt) { src: [ '**/*', '!**/*.map', - '!vips/**', + // Skip non-minified VIPS files — they are ~16MB of inlined WASM + // with no debugging value over the minified versions. + '!vips/!(*.min).js', ], - dest: WORKING_DIR + 'wp-includes/js/dist/script-modules/', + dest: SOURCE_DIR + 'wp-includes/js/dist/script-modules/', } ], }, 'gutenberg-styles': { @@ -669,7 +759,7 @@ module.exports = function(grunt) { // Per-block CSS is copied to wp-includes/blocks/ by tools/gutenberg/copy.js. '!block-library/*/**', ], - dest: WORKING_DIR + 'wp-includes/css/dist/', + dest: SOURCE_DIR + 'wp-includes/css/dist/', } ], }, 'gutenberg-theme-json': { @@ -688,11 +778,11 @@ module.exports = function(grunt) { files: [ { src: 'gutenberg/lib/theme.json', - dest: WORKING_DIR + 'wp-includes/theme.json', + dest: SOURCE_DIR + 'wp-includes/theme.json', }, { src: 'gutenberg/lib/theme-i18n.json', - dest: WORKING_DIR + 'wp-includes/theme-i18n.json', + dest: SOURCE_DIR + 'wp-includes/theme-i18n.json', }, ], }, @@ -700,8 +790,8 @@ module.exports = function(grunt) { files: [ { expand: true, cwd: 'gutenberg/packages/icons/src/library', - src: '*.svg', - dest: WORKING_DIR + 'wp-includes/images/icon-library', + src: [ '*.svg' ], + dest: SOURCE_DIR + 'wp-includes/images/icon-library', } ], }, 'icon-library-manifest': { @@ -723,7 +813,7 @@ module.exports = function(grunt) { }, files: [ { src: 'gutenberg/packages/icons/src/manifest.php', - dest: WORKING_DIR + 'wp-includes/assets/icon-library-manifest.php', + dest: SOURCE_DIR + 'wp-includes/assets/icon-library-manifest.php', } ], }, }, @@ -906,7 +996,8 @@ module.exports = function(grunt) { src: [ 'tests/qunit/**/*.js', '!tests/qunit/vendor/*', - '!tests/qunit/editor/**' + '!tests/qunit/qunit.js', + '!tests/qunit/playwright.config.js' ], options: grunt.file.readJSON( 'tests/qunit/.jshintrc' ) }, @@ -1010,12 +1101,6 @@ module.exports = function(grunt) { } } }, - qunit: { - files: [ - 'tests/qunit/**/*.html', - '!tests/qunit/editor/**' - ] - }, phpunit: { 'default': { args: ['--verbose', '-c', 'phpunit.xml.dist'] @@ -1107,6 +1192,14 @@ module.exports = function(grunt) { src: WORKING_DIR + 'wp-includes/js/dist/vendor/moment.js', dest: WORKING_DIR + 'wp-includes/js/dist/vendor/moment.min.js' }, + 'regenerator-runtime': { + src: WORKING_DIR + 'wp-includes/js/dist/vendor/regenerator-runtime.js', + dest: WORKING_DIR + 'wp-includes/js/dist/vendor/regenerator-runtime.min.js' + }, + 'wp-polyfill-fetch': { + src: WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-fetch.js', + dest: WORKING_DIR + 'wp-includes/js/dist/vendor/wp-polyfill-fetch.min.js' + }, dynamic: { expand: true, cwd: WORKING_DIR, @@ -1540,8 +1633,7 @@ module.exports = function(grunt) { }, test: { files: [ - 'tests/qunit/**', - '!tests/qunit/editor/**' + 'tests/qunit/**' ], tasks: ['qunit'] } @@ -1615,7 +1707,7 @@ module.exports = function(grunt) { */ grunt.util.spawn( { grunt: true, - args: [ 'build:gutenberg', '--dev' ], + args: [ 'build:gutenberg' ], opts: { stdio: 'inherit' } }, function( buildError ) { done( ! buildError ); @@ -1625,22 +1717,9 @@ module.exports = function(grunt) { grunt.registerTask( 'gutenberg:copy', 'Copies Gutenberg JS packages and block assets to WordPress Core.', function() { const done = this.async(); - const buildDir = grunt.option( 'dev' ) ? 'src' : 'build'; grunt.util.spawn( { cmd: 'node', - args: [ 'tools/gutenberg/copy.js', `--build-dir=${ buildDir }` ], - opts: { stdio: 'inherit' } - }, function( error ) { - done( ! error ); - } ); - } ); - - grunt.registerTask( 'copy-vendor-scripts', 'Copies vendor scripts from node_modules to wp-includes/js/dist/vendor/.', function() { - const done = this.async(); - const buildDir = grunt.option( 'dev' ) ? 'src' : 'build'; - grunt.util.spawn( { - cmd: 'node', - args: [ 'tools/vendors/copy-vendors.js', `--build-dir=${ buildDir }` ], + args: [ 'tools/gutenberg/copy.js' ], opts: { stdio: 'inherit' } }, function( error ) { done( ! error ); @@ -1675,6 +1754,8 @@ module.exports = function(grunt) { 'uglify:imgareaselect', 'uglify:jqueryform', 'uglify:moment', + 'uglify:regenerator-runtime', + 'uglify:wp-polyfill-fetch', 'qunit:compiled' ] ); @@ -1817,7 +1898,9 @@ module.exports = function(grunt) { 'uglify:jquery-ui', 'uglify:imgareaselect', 'uglify:jqueryform', - 'uglify:moment' + 'uglify:moment', + 'uglify:regenerator-runtime', + 'uglify:wp-polyfill-fetch' ] ); grunt.registerTask( 'build:codemirror', [ @@ -1837,7 +1920,6 @@ module.exports = function(grunt) { 'clean:js', 'build:webpack', 'copy:js', - 'copy-vendor-scripts', 'file_append', 'uglify:all', 'concat:tinymce', @@ -2111,12 +2193,33 @@ module.exports = function(grunt) { ]; } ) ) ); + + grunt.log.writeln( + 'Found ' + routeNames.length + ' route' + ( routeNames.length === 1 ? '' : 's' ) + + ' registered in ' + registryPath + ':' + ); + routeNames.forEach( function( name ) { + grunt.log.writeln( ' - ' + name ); + } ); } ); - grunt.registerTask( 'build:gutenberg', [ - 'copy:gutenberg-php', + // Detects and copies stable routes. + grunt.registerTask( 'build:routes', [ 'routes:setup', 'copy:routes', + ] ); + + /* + * Refresh the Gutenberg-sourced content in src/. + * + * clean:gutenberg must run first to ensure files removed upstream are purged. + * + * Because all of these tasks write to src/, the outcome is identical for build and build:dev. + */ + grunt.registerTask( 'build:gutenberg', [ + 'clean:gutenberg', + 'copy:gutenberg-php', + 'build:routes', 'copy:gutenberg-js', 'gutenberg:copy', 'copy:gutenberg-modules', @@ -2130,21 +2233,21 @@ module.exports = function(grunt) { if ( grunt.option( 'dev' ) ) { grunt.task.run( [ 'gutenberg:verify', + 'build:gutenberg', 'build:js', 'build:css', 'build:codemirror', - 'build:gutenberg', 'build:certificates' ] ); } else { grunt.task.run( [ 'gutenberg:verify', + 'build:gutenberg', 'build:certificates', 'build:files', 'build:js', 'build:css', 'build:codemirror', - 'build:gutenberg', 'replace:source-maps', 'verify:build' ] ); @@ -2172,6 +2275,20 @@ module.exports = function(grunt) { }, this.async()); }); + grunt.registerTask( 'qunit', 'Runs QUnit tests.', function() { + var done = this.async(); + grunt.util.spawn( { + cmd: 'npx', + args: [ 'playwright', 'test', '--config', 'tests/qunit/playwright.config.js' ], + opts: { stdio: 'inherit' } + }, function( error, result, code ) { + if ( code !== 0 ) { + grunt.fail.warn( 'QUnit tests failed.' ); + } + done(); + } ); + } ); + grunt.registerTask( 'qunit:compiled', 'Runs QUnit tests on compiled as well as uncompiled scripts.', ['build', 'copy:qunit', 'qunit'] ); @@ -2253,7 +2370,7 @@ module.exports = function(grunt) { grunt.registerTask( 'browserslist:update', 'Update the local database of browser supports', function() { grunt.log.writeln( `Updating browsers list` ); - spawn( 'npx', [ 'browserslist@latest', '--update-db' ], { + spawn( 'npx', [ 'update-browserslist-db@latest' ], { cwd: __dirname, stdio: 'inherit', } ); diff --git a/README.md b/README.md index 4c27999495f55..bb6d06c034651 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,9 @@ You can get started using the local development environment with these steps: 1. Then clone the forked repository to your computer using `git clone https://github.com//wordpress-develop.git`. 1. Navigate into the directory for the cloned repository using `cd wordpress-develop`. 1. Add the origin repo as an `upstream` remote via `git remote add upstream https://github.com/WordPress/wordpress-develop.git`. -1. Then you can keep your branches up to date via `git pull --ff upstream/trunk`, for example. +1. Then you can keep your branches up to date via `git pull --ff upstream trunk`, for example. -Alternatively, if you have the [GitHub CLI](https://cli.github.com/) installed, you can simply run `gh repo fork WordPress/wordpress-develop --clone --remote` ([docs](https://cli.github.com/manual/gh_repo_fork)). This command will: +Alternatively, if you have the [GitHub CLI](https://cli.github.com/) installed, you can simply run `gh repo fork WordPress/wordpress-develop --clone` ([docs](https://cli.github.com/manual/gh_repo_fork)). This command will: 1. Fork the repository to your account (use the `--org` flag to clone into an organization). 1. Clone the repository to your machine. 1. Add `WordPress/wordpress-develop` as `upstream` and set it to the default `remote` repository @@ -97,6 +97,29 @@ npm run test:php -- --filter npm run test:php -- --group ``` +#### To lint the workflow files + +GitHub Actions workflows operate in a privileged software supply chain environment, therefore all workflow files must adhere to a high degree of quality and security standards. + +All YAML workflow files within the `.github/workflows` directory are statically scanned when modified using [Actionlint](https://github.com/rhysd/actionlint) and [Zizmor](https://github.com/zizmorcore/zizmor). It's recommended that you install both of these tools locally using a package manager to run prior to submitting changes to workflow files. + +- [Actionlint installations instructions](https://github.com/rhysd/actionlint/blob/main/docs/install.md) +- [Zizmor installation instructions](https://docs.zizmor.sh/installation/) + +To run Actionlint: + +``` +actionlint +``` + +To run Zizmor for all workflow files (note the trailing period): + +``` +zizmor . +``` + +**Note:** A workflow run failure will not occur when issues are detected by Zizmor. Instead, the generated report is submitted to GitHub Code Scanning and surfaced through a status check. Some locally reported issues may be ignored based on the repository's configured Code Scanning settings. + #### Generating a code coverage report PHP code coverage reports are [generated daily](https://github.com/WordPress/wordpress-develop/actions/workflows/test-coverage.yml) and [submitted to Codecov.io](https://app.codecov.io/gh/WordPress/wordpress-develop). diff --git a/composer.json b/composer.json index ee5c5d0c0aa03..b847ec2b61b55 100644 --- a/composer.json +++ b/composer.json @@ -16,14 +16,18 @@ "php": ">=7.4" }, "suggest": { - "ext-dom": "*" + "ext-dom": "*", + "ext-ftp": "*", + "ext-mysqli": "*", + "ext-ssh2": "*" }, "require-dev": { - "composer/ca-bundle": "1.5.10", + "composer/ca-bundle": "1.5.12", "squizlabs/php_codesniffer": "3.13.5", "wp-coding-standards/wpcs": "~3.3.0", "phpcompatibility/phpcompatibility-wp": "~2.1.3", - "phpstan/phpstan": "2.1.39", + "phpstan/phpstan": "2.2.2", + "phpstan/phpstan-phpunit": "2.0.16", "yoast/phpunit-polyfills": "^1.1.0" }, "config": { @@ -32,6 +36,11 @@ }, "lock": false }, + "autoload-dev": { + "psr-4": { + "WordPress\\PHPStan\\": "tests/phpstan/" + } + }, "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", diff --git a/package-lock.json b/package-lock.json index a48bff6270b72..9eab40e217535 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,6 @@ "": { "name": "WordPress", "version": "7.1.0", - "hasInstallScript": true, "license": "GPL-2.0-or-later", "dependencies": { "backbone": "1.6.1", @@ -27,7 +26,7 @@ "jquery-form": "4.3.0", "jquery-hoverintent": "1.10.2", "jsonlint": "1.6.3", - "lodash": "4.17.23", + "lodash": "4.18.1", "masonry-layout": "4.2.2", "moment": "2.30.1", "objectFitPolyfill": "2.3.5", @@ -48,6 +47,7 @@ "@types/espree": "10.1.0", "@types/htmlhint": "1.1.5", "@types/jquery": "3.5.34", + "@types/node": "20.19.41", "@types/underscore": "1.13.0", "@wordpress/e2e-test-utils-playwright": "1.42.0", "@wordpress/prettier-config": "4.42.0", @@ -66,7 +66,6 @@ "grunt-contrib-cssmin": "~5.0.0", "grunt-contrib-imagemin": "~4.0.0", "grunt-contrib-jshint": "3.2.0", - "grunt-contrib-qunit": "~10.1.1", "grunt-contrib-uglify": "~5.2.2", "grunt-contrib-watch": "~1.1.0", "grunt-file-append": "0.0.7", @@ -4561,29 +4560,6 @@ "integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==", "dev": true }, - "node_modules/@puppeteer/browsers": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.3.0.tgz", - "integrity": "sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "debug": "^4.3.5", - "extract-zip": "^2.0.1", - "progress": "^2.0.3", - "proxy-agent": "^6.4.0", - "semver": "^7.6.3", - "tar-fs": "^3.0.6", - "unbzip2-stream": "^1.4.3", - "yargs": "^17.7.2" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -5635,10 +5611,14 @@ "dev": true }, "node_modules/@types/node": { - "version": "14.14.20", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz", - "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==", - "dev": true + "version": "20.19.41", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.41.tgz", + "integrity": "sha512-ECymXOukMnOoVkC2bb1Vc/w/836DXncOg5m8Xj1RH7xSHZJWNYY6Zh7EH477vcnD5egKNNfy2RpNOmuChhFPgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } }, "node_modules/@types/node-forge": { "version": "1.3.11", @@ -10617,21 +10597,6 @@ "node": ">=6.0" } }, - "node_modules/chromium-bidi": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.3.tgz", - "integrity": "sha512-qXlsCmpCZJAnoTYI83Iu6EdYQpMYdVkCfq08KDh2pmlVqK5t5IA9mGs4/LwCwp4fqisSOMXZxP3HIh8w8aRn0A==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "mitt": "3.0.1", - "urlpattern-polyfill": "10.0.0", - "zod": "3.23.8" - }, - "peerDependencies": { - "devtools-protocol": "*" - } - }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -17003,26 +16968,6 @@ "node": ">=8" } }, - "node_modules/grunt-contrib-qunit": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/grunt-contrib-qunit/-/grunt-contrib-qunit-10.1.1.tgz", - "integrity": "sha512-qSzY/aWl4xn8dQc2eAwKrXNB0171WHgb4aA3ZdKkN88csxS3tCD3Eh8ljfsscFAKIKZkhjierRgQypep/aV4NA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eventemitter2": "^6.4.9", - "puppeteer": "^22.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/grunt-contrib-qunit/node_modules/eventemitter2": { - "version": "6.4.9", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", - "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", - "dev": true - }, "node_modules/grunt-contrib-uglify": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-5.2.2.tgz", @@ -17291,6 +17236,13 @@ "node": ">=8" } }, + "node_modules/grunt-legacy-log-utils/node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "dev": true, + "license": "MIT" + }, "node_modules/grunt-legacy-log-utils/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -17303,6 +17255,13 @@ "node": ">=8" } }, + "node_modules/grunt-legacy-log/node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "dev": true, + "license": "MIT" + }, "node_modules/grunt-legacy-util": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz", @@ -17328,6 +17287,13 @@ "dev": true, "license": "MIT" }, + "node_modules/grunt-legacy-util/node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "dev": true, + "license": "MIT" + }, "node_modules/grunt-patch-wordpress": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/grunt-patch-wordpress/-/grunt-patch-wordpress-4.0.0.tgz", @@ -22576,6 +22542,13 @@ "date-now": "^0.1.4" } }, + "node_modules/jshint/node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "dev": true, + "license": "MIT" + }, "node_modules/jshint/node_modules/minimatch": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", @@ -23265,9 +23238,9 @@ } }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, "node_modules/lodash-es": { @@ -27510,27 +27483,6 @@ "node": ">=6" } }, - "node_modules/puppeteer": { - "version": "22.15.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.15.0.tgz", - "integrity": "sha512-XjCY1SiSEi1T7iSYuxS82ft85kwDJUS7wj1Z0eGVXKdtr5g4xnVcbjwxhq5xBnpK/E7x1VZZoJDxpjAOasHT4Q==", - "deprecated": "< 24.15.0 is no longer supported", - "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@puppeteer/browsers": "2.3.0", - "cosmiconfig": "^9.0.0", - "devtools-protocol": "0.0.1312386", - "puppeteer-core": "22.15.0" - }, - "bin": { - "puppeteer": "lib/esm/puppeteer/node/cli.js" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/puppeteer-core": { "version": "23.11.1", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.11.1.tgz", @@ -27611,91 +27563,6 @@ } } }, - "node_modules/puppeteer/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/puppeteer/node_modules/cosmiconfig": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", - "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/puppeteer/node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/puppeteer/node_modules/puppeteer-core": { - "version": "22.15.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.15.0.tgz", - "integrity": "sha512-cHArnywCiAAVXa3t4GGL2vttNxh7GqXtIYGym99egkNJ3oG//wL9LkvO4WE8W1TJe95t1F1ocu9X4xWaGsOKOA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@puppeteer/browsers": "2.3.0", - "chromium-bidi": "0.6.3", - "debug": "^4.3.6", - "devtools-protocol": "0.0.1312386", - "ws": "^8.18.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/puppeteer/node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/pure-rand": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.3.tgz", @@ -32176,6 +32043,13 @@ "node": "*" } }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", @@ -32481,13 +32355,6 @@ "node": ">= 4" } }, - "node_modules/urlpattern-polyfill": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", - "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", - "dev": true, - "license": "MIT" - }, "node_modules/use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", diff --git a/package.json b/package.json index 4d0b8110e0a9f..3c93ef37f8c27 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "url": "https://develop.svn.wordpress.org/trunk" }, "gutenberg": { - "sha": "e2970ba736edb99e08fb369d4fb0c378189468ee", + "sha": "98a796c8780c480ef7bcfe03c42302d9564d785c", "ghcrRepo": "WordPress/gutenberg/gutenberg-wp-develop-build" }, "engines": { @@ -35,6 +35,7 @@ "@types/espree": "10.1.0", "@types/htmlhint": "1.1.5", "@types/jquery": "3.5.34", + "@types/node": "20.19.41", "@types/underscore": "1.13.0", "@wordpress/e2e-test-utils-playwright": "1.42.0", "@wordpress/prettier-config": "4.42.0", @@ -53,7 +54,6 @@ "grunt-contrib-cssmin": "~5.0.0", "grunt-contrib-imagemin": "~4.0.0", "grunt-contrib-jshint": "3.2.0", - "grunt-contrib-qunit": "~10.1.1", "grunt-contrib-uglify": "~5.2.2", "grunt-contrib-watch": "~1.1.0", "grunt-file-append": "0.0.7", @@ -99,7 +99,7 @@ "jquery-form": "4.3.0", "jquery-hoverintent": "1.10.2", "jsonlint": "1.6.3", - "lodash": "4.17.23", + "lodash": "4.18.1", "masonry-layout": "4.2.2", "moment": "2.30.1", "objectFitPolyfill": "2.3.5", @@ -113,7 +113,6 @@ "wicg-inert": "3.1.3" }, "scripts": { - "postinstall": "npm run gutenberg:verify", "build": "grunt build", "build:dev": "grunt build --dev", "build:gutenberg": "grunt build:gutenberg", @@ -142,7 +141,6 @@ "typecheck:php": "node ./tools/local-env/scripts/docker.js run --rm php composer phpstan", "gutenberg:copy": "node tools/gutenberg/copy.js", "gutenberg:verify": "node tools/gutenberg/utils.js", - "gutenberg:download": "node tools/gutenberg/download.js && grunt build:gutenberg --dev", - "vendor:copy": "node tools/vendors/copy-vendors.js" + "gutenberg:download": "node tools/gutenberg/download.js && grunt build:gutenberg" } } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index e74e6ec1a441b..7ea25ab18e205 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -8,6 +8,12 @@ includes: # The base configuration file for using PHPStan with the WordPress core codebase. - tests/phpstan/base.neon + # Type-specifying extension so PHPUnit assertions (e.g. assertArrayHasKey(), + # assertInstanceOf(), assertNotNull()) narrow types in the analysis. Only the + # extension is included, not phpstan-phpunit's rules.neon, to avoid introducing + # new strict rules. + - vendor/phpstan/phpstan-phpunit/extension.neon + # The baseline file includes preexisting errors in the codebase that should be ignored. # https://phpstan.org/user-guide/baseline - tests/phpstan/baseline.php diff --git a/src/js/_enqueues/admin/edit-comments.js b/src/js/_enqueues/admin/edit-comments.js index 9a3d81a751bd8..78ee78de759ff 100644 --- a/src/js/_enqueues/admin/edit-comments.js +++ b/src/js/_enqueues/admin/edit-comments.js @@ -14,7 +14,7 @@ var getCount, updateCount, updateCountText, updatePending, updateApproved, updateHtmlTitle, updateDashboardText, updateInModerationText, adminTitle = document.title, isDashboard = $('#dashboard_right_now').length, titleDiv, titleRegEx, - __ = wp.i18n.__; + __ = wp.i18n.__, _x = wp.i18n._x; /** * Extracts a number from the content of a jQuery element. @@ -370,7 +370,8 @@ window.setCommentsList = function() { } else { if ( settings.data.id == replyID ) - replyButton.text( __( 'Reply' ) ); + /* translators: Comment reply button text. */ + replyButton.text( _x( 'Reply', 'verb' ) ); c.find( '.row-actions span.view' ).removeClass( 'hidden' ).end() .find( 'div.comment_status' ).html( '1' ); @@ -1012,7 +1013,8 @@ window.commentReply = { if ( c.hasClass('unapproved') ) { replyButton.text( __( 'Approve and Reply' ) ); } else { - replyButton.text( __( 'Reply' ) ); + /* translators: Comment reply button text. */ + replyButton.text( _x( 'Reply', 'verb' ) ); } $('#replyrow').fadeIn(300, function(){ $(this).show(); }); diff --git a/src/js/_enqueues/admin/inline-edit-post.js b/src/js/_enqueues/admin/inline-edit-post.js index 5e0eb2746a206..6e9f4e9f20503 100644 --- a/src/js/_enqueues/admin/inline-edit-post.js +++ b/src/js/_enqueues/admin/inline-edit-post.js @@ -614,8 +614,7 @@ $( function() { } }).on( 'heartbeat-tick.wp-check-locked-posts', function( e, data ) { var locked = data['wp-check-locked-posts'] || {}, - isRtc = window._wpCollaborationEnabled, - lockedClass = isRtc ? 'wp-collaborative-editing' : 'wp-locked'; + lockedClass = 'wp-locked'; $('#the-list tr').each( function(i, el) { var key = el.id, row = $(el), lock_data, avatar; @@ -626,7 +625,7 @@ $( function() { row.find('.column-title .locked-text').text( lock_data.text ); row.find('.check-column checkbox').prop('checked', false); - if ( ! isRtc && lock_data.avatar_src ) { + if ( lock_data.avatar_src ) { avatar = $( '', { 'class': 'avatar avatar-18 photo', width: 18, diff --git a/src/js/_enqueues/admin/post.js b/src/js/_enqueues/admin/post.js index 1dde10ffc8aae..445e79d8a6f05 100644 --- a/src/js/_enqueues/admin/post.js +++ b/src/js/_enqueues/admin/post.js @@ -35,13 +35,13 @@ window.wp = window.wp || {}; * @memberof commentsBox * * @param {number} total Total number of comments for this post. - * @param {number} num Optional. Number of comments to fetch, defaults to 20. + * @param {number} num Optional. Number of comments to fetch, defaults to 10. * @return {boolean} Always returns false. */ get : function(total, num) { var st = this.st, data; if ( ! num ) - num = 20; + num = 10; this.st += num; this.total = total; @@ -97,7 +97,7 @@ window.wp = window.wp || {}; * @param {number} total Total number of comments to load. */ load: function(total){ - this.st = jQuery('#the-comment-list tr.comment:visible').length; + this.st = jQuery('#the-comment-list tr[id^="comment-"]:visible').length; this.get(total); } }; @@ -1028,7 +1028,7 @@ jQuery( function($) { revert_e = $el.html(); buttons.html( - ' ' + + ' ' + '' ); diff --git a/src/js/_enqueues/deprecated/fakejshint.js b/src/js/_enqueues/deprecated/fakejshint.js index 2ab6326b96262..b3290c4406064 100644 --- a/src/js/_enqueues/deprecated/fakejshint.js +++ b/src/js/_enqueues/deprecated/fakejshint.js @@ -1,5 +1,5 @@ /** - * JSHINT has some GPL Compatability issues, so we are faking it out and using esprima for validation + * JSHINT has some GPL Compatibility issues, so we are faking it out and using esprima for validation * Based on https://github.com/jquery/esprima/blob/gh-pages/demo/validate.js which is MIT licensed. * This is now deprecated in favor of Espree. * diff --git a/src/js/_enqueues/lib/admin-bar.js b/src/js/_enqueues/lib/admin-bar.js index eb18c61f8b5b8..619694db37f5c 100644 --- a/src/js/_enqueues/lib/admin-bar.js +++ b/src/js/_enqueues/lib/admin-bar.js @@ -417,7 +417,7 @@ }; } - // Get the closest matching elent. + // Get the closest matching element. for ( ; el && el !== document; el = el.parentNode ) { if ( el.matches( selector ) ) { return el; diff --git a/src/js/_enqueues/lib/codemirror/javascript-lint.js b/src/js/_enqueues/lib/codemirror/javascript-lint.js index 592d077b80914..2c96798a20ae3 100644 --- a/src/js/_enqueues/lib/codemirror/javascript-lint.js +++ b/src/js/_enqueues/lib/codemirror/javascript-lint.js @@ -30,6 +30,7 @@ import CodeMirror from 'codemirror'; * @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." + * @property {string} [espreeModuleUrl] - The URL to the espree script module. */ /** @@ -42,9 +43,13 @@ import CodeMirror from 'codemirror'; * @returns {Promise} */ async function validator( text, options ) { + if ( ! options.espreeModuleUrl ) { + return []; + } + const errors = /** @type {CodeMirrorLintError[]} */ []; try { - const espree = await import( /* webpackIgnore: true */ 'espree' ); + const espree = await import( /* webpackIgnore: true */ options.espreeModuleUrl ); espree.parse( text, { ...getEspreeOptions( options ), loc: true, diff --git a/src/js/_enqueues/lib/comment-reply.js b/src/js/_enqueues/lib/comment-reply.js index b916dc54d16de..fabd579f5afc2 100644 --- a/src/js/_enqueues/lib/comment-reply.js +++ b/src/js/_enqueues/lib/comment-reply.js @@ -93,8 +93,7 @@ window.addComment = ( function( window ) { return; } - cancelElement.addEventListener( 'touchstart', cancelEvent ); - cancelElement.addEventListener( 'click', cancelEvent ); + cancelElement.addEventListener( 'click', cancelEvent ); // Submit the comment form when the user types [Ctrl] or [Cmd] + [Enter]. var submitFormHandler = function( e ) { @@ -117,8 +116,7 @@ window.addComment = ( function( window ) { for ( var i = 0, l = links.length; i < l; i++ ) { element = links[i]; - element.addEventListener( 'touchstart', clickEvent ); - element.addEventListener( 'click', clickEvent ); + element.addEventListener( 'click', clickEvent ); } } diff --git a/src/js/_enqueues/vendor/twemoji.js b/src/js/_enqueues/vendor/twemoji.js index c1d36bba9b2ec..914e77ec3aa74 100644 --- a/src/js/_enqueues/vendor/twemoji.js +++ b/src/js/_enqueues/vendor/twemoji.js @@ -230,7 +230,7 @@ var twemoji = (function ( // RegExp based on emoji's official Unicode standards // http://www.unicode.org/Public/UNIDATA/EmojiSources.txt - re = /(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83d\udc30\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udeef\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83d\udc30\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udeef\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83d\udc30\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udeef\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83d\udc30\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udeef\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83d\udc30\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udeef\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83d\udc30\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udeef\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83d\udc30\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udeef\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83d\udc30\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udeef\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83d\udc30\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udeef\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83d\udc30\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udeef\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83d\udc30\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udeef\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83d\udc30\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udeef\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83d\udc30\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udeef\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83d\udc30\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udeef\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83d\udc30\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udeef\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83e\udef1\ud83c\udffb\u200d\ud83e\udef2\ud83c[\udffc-\udfff]|\ud83e\udef1\ud83c\udffc\u200d\ud83e\udef2\ud83c[\udffb\udffd-\udfff]|\ud83e\udef1\ud83c\udffd\u200d\ud83e\udef2\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\udef1\ud83c\udffe\u200d\ud83e\udef2\ud83c[\udffb-\udffd\udfff]|\ud83e\udef1\ud83c\udfff\u200d\ud83e\udef2\ud83c[\udffb-\udffe]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6f\ud83c\udffb\u200d\u2640\ufe0f|\ud83d\udc6f\ud83c\udffb\u200d\u2642\ufe0f|\ud83d\udc6f\ud83c\udffc\u200d\u2640\ufe0f|\ud83d\udc6f\ud83c\udffc\u200d\u2642\ufe0f|\ud83d\udc6f\ud83c\udffd\u200d\u2640\ufe0f|\ud83d\udc6f\ud83c\udffd\u200d\u2642\ufe0f|\ud83d\udc6f\ud83c\udffe\u200d\u2640\ufe0f|\ud83d\udc6f\ud83c\udffe\u200d\u2642\ufe0f|\ud83d\udc6f\ud83c\udfff\u200d\u2640\ufe0f|\ud83d\udc6f\ud83c\udfff\u200d\u2642\ufe0f|\ud83e\udd3c\ud83c\udffb\u200d\u2640\ufe0f|\ud83e\udd3c\ud83c\udffb\u200d\u2642\ufe0f|\ud83e\udd3c\ud83c\udffc\u200d\u2640\ufe0f|\ud83e\udd3c\ud83c\udffc\u200d\u2642\ufe0f|\ud83e\udd3c\ud83c\udffd\u200d\u2640\ufe0f|\ud83e\udd3c\ud83c\udffd\u200d\u2642\ufe0f|\ud83e\udd3c\ud83c\udffe\u200d\u2640\ufe0f|\ud83e\udd3c\ud83c\udffe\u200d\u2642\ufe0f|\ud83e\udd3c\ud83c\udfff\u200d\u2640\ufe0f|\ud83e\udd3c\ud83c\udfff\u200d\u2642\ufe0f|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc6f\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83e\udd1d\ud83c[\udffb-\udfff]|\ud83e\udd3c\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc6f\udc8f\udc91]|\ud83e[\udd1d\udd3c])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd\ude70])(?:\u200d\u27a1\ufe0f)?|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f(?:\u200d\u27a1\ufe0f)?)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f(?:\u200d\u27a1\ufe0f)?|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83e\uddd1\u200d\ud83e\uddd1\u200d\ud83e\uddd2\u200d\ud83e\uddd2|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83e\uddd1\u200d\ud83e\uddd1\u200d\ud83e\uddd2|\ud83e\uddd1\u200d\ud83e\uddd2\u200d\ud83e\uddd2|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u26d3\ufe0f\u200d\ud83d\udca5|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udf44\u200d\ud83d\udfeb|\ud83c\udf4b\u200d\ud83d\udfe9|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc26\u200d\ud83d\udd25|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83d\ude42\u200d\u2194\ufe0f|\ud83d\ude42\u200d\u2195\ufe0f|\ud83e\uddd1\u200d\ud83e\uddd2|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b|\ud83d\udc26\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|\ud83e\udef0|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c\udfc3|\ud83d\udeb6|\ud83e\uddce)(?:\ud83c[\udffb-\udfff])?(?:\u200d\u27a1\ufe0f)?|(?:\ud83c[\udf85\udfc2\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4\udeb5\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd\uddcf\uddd1-\udddd\udec3-\udec5\udef1-\udef8]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded8\udedc-\udedf\udeeb\udeec\udef4-\udefc\udfe0-\udfeb\udff0]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd20-\udd25\udd27-\udd2f\udd3a\udd3f-\udd45\udd47-\udd76\udd78-\uddb4\uddb7\uddba\uddbc-\uddcc\uddd0\uddde-\uddff\ude70-\ude7c\ude80-\ude8a\ude8e-\udec2\udec6\udec8\udecd-\udedc\udedf-\udeea\udeef]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g, + re = /(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83d\udc30\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udeef\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83d\udc30\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udeef\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83d\udc30\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udeef\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83d\udc30\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udeef\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83d\udc30\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udeef\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83d\udc30\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udeef\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83d\udc30\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udeef\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83d\udc30\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udeef\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83d\udc30\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udeef\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83d\udc30\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udeef\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83d\udc30\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udeef\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83d\udc30\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udeef\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83d\udc30\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udeef\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83d\udc30\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udeef\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83d\udc30\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udeef\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83e\udef1\ud83c\udffb\u200d\ud83e\udef2\ud83c[\udffc-\udfff]|\ud83e\udef1\ud83c\udffc\u200d\ud83e\udef2\ud83c[\udffb\udffd-\udfff]|\ud83e\udef1\ud83c\udffd\u200d\ud83e\udef2\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\udef1\ud83c\udffe\u200d\ud83e\udef2\ud83c[\udffb-\udffd\udfff]|\ud83e\udef1\ud83c\udfff\u200d\ud83e\udef2\ud83c[\udffb-\udffe]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6f\ud83c\udffb\u200d\u2640\ufe0f|\ud83d\udc6f\ud83c\udffb\u200d\u2642\ufe0f|\ud83d\udc6f\ud83c\udffc\u200d\u2640\ufe0f|\ud83d\udc6f\ud83c\udffc\u200d\u2642\ufe0f|\ud83d\udc6f\ud83c\udffd\u200d\u2640\ufe0f|\ud83d\udc6f\ud83c\udffd\u200d\u2642\ufe0f|\ud83d\udc6f\ud83c\udffe\u200d\u2640\ufe0f|\ud83d\udc6f\ud83c\udffe\u200d\u2642\ufe0f|\ud83d\udc6f\ud83c\udfff\u200d\u2640\ufe0f|\ud83d\udc6f\ud83c\udfff\u200d\u2642\ufe0f|\ud83e\udd3c\ud83c\udffb\u200d\u2640\ufe0f|\ud83e\udd3c\ud83c\udffb\u200d\u2642\ufe0f|\ud83e\udd3c\ud83c\udffc\u200d\u2640\ufe0f|\ud83e\udd3c\ud83c\udffc\u200d\u2642\ufe0f|\ud83e\udd3c\ud83c\udffd\u200d\u2640\ufe0f|\ud83e\udd3c\ud83c\udffd\u200d\u2642\ufe0f|\ud83e\udd3c\ud83c\udffe\u200d\u2640\ufe0f|\ud83e\udd3c\ud83c\udffe\u200d\u2642\ufe0f|\ud83e\udd3c\ud83c\udfff\u200d\u2640\ufe0f|\ud83e\udd3c\ud83c\udfff\u200d\u2642\ufe0f|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc6f\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83e\udd1d\ud83c[\udffb-\udfff]|\ud83e\udd3c\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc6f\udc8f\udc91]|\ud83e[\udd1d\udd3c])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd\ude70])(?:\u200d\u27a1\ufe0f)?|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f(?:\u200d\u27a1\ufe0f)?)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f(?:\u200d\u27a1\ufe0f)?|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83e\uddd1\u200d\ud83e\uddd1\u200d\ud83e\uddd2\u200d\ud83e\uddd2|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83e\uddd1\u200d\ud83e\uddd1\u200d\ud83e\uddd2|\ud83e\uddd1\u200d\ud83e\uddd2\u200d\ud83e\uddd2|\ud83d\udc41\ufe0f\u200d\ud83d\udde8\ufe0f|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u26d3\ufe0f\u200d\ud83d\udca5|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udf44\u200d\ud83d\udfeb|\ud83c\udf4b\u200d\ud83d\udfe9|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc26\u200d\ud83d\udd25|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83d\ude42\u200d\u2194\ufe0f|\ud83d\ude42\u200d\u2195\ufe0f|\ud83e\uddd1\u200d\ud83e\uddd2|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b|\ud83d\udc26\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:(?:\ud83c[\udd70\udd71\udd7e\udd7f\ude02\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[©®\u203c\u2049\u2122\u2139\u2194-\u2199\u21a9\u21aa\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb\u25fc\u2600-\u2604\u260e\u2611\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u265f\u2660\u2663\u2665\u2666\u2668\u267b\u267e\u2692\u2694-\u2697\u2699\u269b\u269c\u26a0\u26a7\u26b0\u26b1\u26c8\u26cf\u26d1\u26d3\u26e9\u26f0\u26f1\u26f4\u26f8\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2763\u27a1\u2934\u2935\u2b05-\u2b07\u3030\u303d\u3297\u3299])\ufe0f)|(?:\ud83c[\udc04\ude1a\ude2f]|[\u231a\u231b\u25fd\u25fe\u2614\u2615\u2648-\u2653\u267f\u2693\u26a1\u26aa\u26ab\u26bd\u26be\u26c4\u26c5\u26d4\u26ea\u26f2\u26f3\u26f5\u26fa\u26fd\u2757\u2764\u2b1b\u2b1c\u2b50\u2b55])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83e\udef0)(?:\ufe0f|(?!\ufe0e))|(?:\ud83c\udfc3|\ud83d\udeb6|\ud83e\uddce)(?:\ud83c[\udffb-\udfff])?(?:\u200d\u27a1\ufe0f)?|(?:\ud83c[\udf85\udfc2\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4\udeb5\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd\uddcf\uddd1-\udddd\udec3-\udec5\udef1-\udef8]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded8\udedc-\udedf\udeeb\udeec\udef4-\udefc\udfe0-\udfeb\udff0]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd20-\udd25\udd27-\udd2f\udd3a\udd3f-\udd45\udd47-\udd76\udd78-\uddb4\uddb7\uddba\uddbc-\uddcc\uddd0\uddde-\uddff\ude70-\ude7c\ude80-\ude8a\ude8e-\udec2\udec6\udec8\udecd-\udedc\udedf-\udeea\udeef]|[\u23e9-\u23ec\u23f0\u23f3\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g, // avoid runtime RegExp creation for not so smart, // not JIT based, and old browsers / engines diff --git a/src/js/_enqueues/wp/api.js b/src/js/_enqueues/wp/api.js index 1d0baea8cdf28..9e11ff242fdc9 100644 --- a/src/js/_enqueues/wp/api.js +++ b/src/js/_enqueues/wp/api.js @@ -983,7 +983,7 @@ }, /** - * Extend Backbone.Collection.sync to add nince and pagination support. + * Extend Backbone.Collection.sync to add nonce and pagination support. * * Set nonce header before every Backbone sync. * @@ -1288,7 +1288,7 @@ parentName = wp.api.utils.extractRoutePart( modelRoute.index, 1, routeModel.get( 'versionString' ), false ), routeEnd = wp.api.utils.extractRoutePart( modelRoute.index, 1, routeModel.get( 'versionString' ), true ); - // Clear the parent part of the rouite if its actually the version string. + // Clear the parent part of the route if it's actually the version string. if ( parentName === routeModel.get( 'versionString' ) ) { parentName = ''; } diff --git a/src/js/_enqueues/wp/code-editor.js b/src/js/_enqueues/wp/code-editor.js index 86d5e03254166..ed8be9d6a5580 100644 --- a/src/js/_enqueues/wp/code-editor.js +++ b/src/js/_enqueues/wp/code-editor.js @@ -2,6 +2,8 @@ * @output wp-admin/js/code-editor.js */ +/* global console */ + /* eslint-env es2020 */ if ( 'undefined' === typeof window.wp ) { @@ -412,6 +414,10 @@ if ( 'undefined' === typeof window.wp.codeEditor ) { * @return {CodeEditorInstance} Instance. */ wp.codeEditor.initialize = function initialize( textarea, settings ) { + if ( document.readyState === 'loading' ) { + console.warn( 'wp.codeEditor.initialize() ran too early. Invoke this function in a `DOMContentLoaded` event listener.' ); + } + let $textarea; if ( 'string' === typeof textarea ) { $textarea = $( '#' + textarea ); diff --git a/src/js/_enqueues/wp/customize/controls.js b/src/js/_enqueues/wp/customize/controls.js index 921983e6bf78d..a5846d45f687c 100644 --- a/src/js/_enqueues/wp/customize/controls.js +++ b/src/js/_enqueues/wp/customize/controls.js @@ -590,7 +590,7 @@ return deferred.reject( { code: 'illegal_status_in_changeset_update' } ).promise(); } - // Dates not beung allowed for revisions are is a technical limitation of post revisions. + // Dates not being allowed for revisions is a technical limitation of post revisions. if ( submittedArgs.date && submittedArgs.autosave ) { return deferred.reject( { code: 'illegal_autosave_with_date_gmt' } ).promise(); } diff --git a/src/js/_enqueues/wp/customize/nav-menus.js b/src/js/_enqueues/wp/customize/nav-menus.js index 73e17df23aec5..607740014e5e4 100644 --- a/src/js/_enqueues/wp/customize/nav-menus.js +++ b/src/js/_enqueues/wp/customize/nav-menus.js @@ -3539,7 +3539,7 @@ /** * Apply sanitize_text_field()-like logic to the supplied name, returning a - * "unnammed" fallback string if the name is then empty. + * "unnamed" fallback string if the name is then empty. * * @alias wp.customize.Menus~displayNavMenuName * diff --git a/src/js/_enqueues/wp/dashboard.js b/src/js/_enqueues/wp/dashboard.js index 5216611d5dc3c..bea3373ae5c97 100644 --- a/src/js/_enqueues/wp/dashboard.js +++ b/src/js/_enqueues/wp/dashboard.js @@ -756,8 +756,8 @@ jQuery( function( $ ) { * * @since 5.5.2 * - * @param {int} startDate The Unix timestamp in milliseconds when the the event starts. - * @param {int} endDate The Unix timestamp in milliseconds when the the event ends. + * @param {int} startDate The Unix timestamp in milliseconds when the event starts. + * @param {int} endDate The Unix timestamp in milliseconds when the event ends. * @param {string} timeZone A time zone string or offset which is parsable by `wp.date.i18n()`. * * @returns {string} diff --git a/src/js/_enqueues/wp/widgets/custom-html.js b/src/js/_enqueues/wp/widgets/custom-html.js index d0be23eeb37af..0f1fde1642e94 100644 --- a/src/js/_enqueues/wp/widgets/custom-html.js +++ b/src/js/_enqueues/wp/widgets/custom-html.js @@ -307,7 +307,7 @@ wp.customHtmlWidgets = ( function( $ ) { /* * Create a container element for the widget control fields. - * This is inserted into the DOM immediately before the the .widget-content + * This is inserted into the DOM immediately before the .widget-content * element because the contents of this element are essentially "managed" * by PHP, where each widget update cause the entire element to be emptied * and replaced with the rendered output of WP_Widget::form() which is diff --git a/src/js/media/views/attachments/browser.js b/src/js/media/views/attachments/browser.js index 65936efc186ef..26218ea2fa1ae 100644 --- a/src/js/media/views/attachments/browser.js +++ b/src/js/media/views/attachments/browser.js @@ -198,44 +198,32 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro } if ( showFilterByType ) { - // "Filters" is a , a label element needs to be rendered before. + this.toolbar.set( 'filtersLabel', new wp.media.view.Label({ value: l10n.filterByType, attributes: { 'for': 'media-attachment-filters' }, priority: -80 - }); + }).render() ); if ( 'uploaded' === this.options.filters ) { - Filters = new wp.media.view.AttachmentFilters.Uploaded({ + this.toolbar.set( 'filters', new wp.media.view.AttachmentFilters.Uploaded({ controller: this.controller, model: this.collection.props, - }); + priority: -80 + }).render() ); } else { Filters = new wp.media.view.AttachmentFilters.All({ controller: this.controller, model: this.collection.props, + priority: -80 }); - } - - var filterContainer = wp.media.View.extend({ - tagname: 'div', - className: 'media-filter-container type-filter', - - initialize: function() { - this.views.add( [ filtersLabel, Filters ] ); - } - }); - this.toolbar.set( 'filters', new filterContainer({ - controller: this.controller, - model: this.controller.props, - priority: -80 - }).render() ); + this.toolbar.set( 'filters', Filters.render() ); + } } - var dateFilter, dateFilterLabel, dateFilterContainer; /* * Feels odd to bring the global media library switcher into the Attachment browser view. * Is this a use case for doAction( 'add:toolbar-items:attachments-browser', this.toolbar ); @@ -252,31 +240,18 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro priority: -90 }).render() ); - // DateFilter is a , a label element needs to be rendered before. + this.toolbar.set( 'dateFilter', new wp.media.view.Label({ value: l10n.filterByDate, attributes: { 'for': 'media-attachment-date-filters' }, - }); - dateFilter = new wp.media.view.DateFilter({ - controller: this.controller, - model: this.collection.props, - }); - - dateFilterContainer = wp.media.View.extend({ - tagname: 'div', - className: 'media-filter-container date-filter', - - initialize: function() { - this.views.add( [ dateFilterLabel, dateFilter ] ); - } - }); - - this.toolbar.set( 'dateFilters', new dateFilterContainer({ + priority: -75 + }).render() ); + this.toolbar.set( 'dateFilter', new wp.media.view.DateFilter({ controller: this.controller, model: this.collection.props, - priority: -75 + priority: -75, }).render() ); // BulkSelection is a
with subviews, including screen reader text. @@ -387,28 +362,15 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro } } else if ( this.options.date ) { - // DateFilter is a , a label element needs to be rendered before. + this.toolbar.set( 'dateFilterLabel', new wp.media.view.Label({ value: l10n.filterByDate, attributes: { 'for': 'media-attachment-date-filters' }, - }); - dateFilter = new wp.media.view.DateFilter({ - controller: this.controller, - model: this.collection.props, - }); - - dateFilterContainer = wp.media.View.extend({ - tagname: 'div', - className: 'media-filter-container date-filter', - - initialize: function() { - this.views.add( [ dateFilterLabel, dateFilter ] ); - } - }); - - this.toolbar.set( 'dateFilters', new dateFilterContainer({ + priority: -75 + }).render() ); + this.toolbar.set( 'dateFilter', new wp.media.view.DateFilter({ controller: this.controller, model: this.collection.props, priority: -75 diff --git a/src/js/media/views/button/select-mode-toggle.js b/src/js/media/views/button/select-mode-toggle.js index 2c2335bcd56f6..858c0e16cb2e4 100644 --- a/src/js/media/views/button/select-mode-toggle.js +++ b/src/js/media/views/button/select-mode-toggle.js @@ -40,7 +40,7 @@ SelectModeToggle = Button.extend(/** @lends wp.media.view.SelectModeToggle.proto render: function() { Button.prototype.render.apply( this, arguments ); - this.$el.addClass( 'select-mode-toggle-button' ); + this.$el.addClass( 'select-mode-toggle-button button-compact' ); return this; }, diff --git a/src/js/media/views/frame/manage.js b/src/js/media/views/frame/manage.js index bed774a2e2438..ea16637fdf7a5 100644 --- a/src/js/media/views/frame/manage.js +++ b/src/js/media/views/frame/manage.js @@ -98,8 +98,9 @@ Manage = MediaFrame.extend(/** @lends wp.media.view.MediaFrame.Manage.prototype if ( val ) { url += '?search=' + val; - this.gridRouter.navigate( this.gridRouter.baseUrl( url ), { replace: true } ); } + + this.gridRouter.navigate( this.gridRouter.baseUrl( url ), { replace: true } ); }, 1000 ); // Update the URL when entering search string (at most once per second). diff --git a/src/readme.html b/src/readme.html index c8dd83cdbd9a4..190c9aedfa348 100644 --- a/src/readme.html +++ b/src/readme.html @@ -59,7 +59,7 @@

System Requirements

Recommendations