diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
deleted file mode 100644
index b6524c2c49caf..0000000000000
--- a/.devcontainer/devcontainer.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name": "Playwright",
- "image": "mcr.microsoft.com/playwright:next",
- "postCreateCommand": "npm install && npm run build && apt-get update && apt-get install -y software-properties-common && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - && add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable\" && apt-get install -y docker-ce-cli",
- "settings": {
- "terminal.integrated.shell.linux": "/bin/bash"
- },
- "runArgs": [
- "-v", "/var/run/docker.sock:/var/run/docker.sock"
- ]
-}
\ No newline at end of file
diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index 60b8fd360fcb9..0000000000000
--- a/.eslintignore
+++ /dev/null
@@ -1,21 +0,0 @@
-test/assets/modernizr.js
-/tests/third_party/
-/packages/*/lib/
-*.js
-/packages/playwright-core/src/generated/*
-/packages/playwright-core/src/third_party/
-/packages/playwright-core/types/*
-/packages/playwright-ct-core/src/generated/*
-/index.d.ts
-node_modules/
-browser_patches/*/checkout/
-browser_patches/chromium/output/
-**/*.d.ts
-output/
-test-results/
-tests/components/
-tests/installation/fixture-scripts/
-examples/
-DEPS
-.cache/
-utils/
diff --git a/.eslintrc-with-ts-config.js b/.eslintrc-with-ts-config.js
deleted file mode 100644
index b06ec001951bc..0000000000000
--- a/.eslintrc-with-ts-config.js
+++ /dev/null
@@ -1,15 +0,0 @@
-module.exports = {
- extends: "./.eslintrc.js",
- parserOptions: {
- ecmaVersion: 9,
- sourceType: "module",
- project: "./tsconfig.json",
- },
- rules: {
- "@typescript-eslint/no-base-to-string": "error",
- "@typescript-eslint/no-unnecessary-boolean-literal-compare": 2,
- },
- parserOptions: {
- project: "./tsconfig.json"
- },
-};
diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index bb351a8c5640d..0000000000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,128 +0,0 @@
-module.exports = {
- parser: "@typescript-eslint/parser",
- plugins: ["@typescript-eslint", "notice"],
- parserOptions: {
- ecmaVersion: 9,
- sourceType: "module",
- },
- extends: [
- "plugin:react-hooks/recommended"
- ],
-
- /**
- * ESLint rules
- *
- * All available rules: http://eslint.org/docs/rules/
- *
- * Rules take the following form:
- * "rule-name", [severity, { opts }]
- * Severity: 2 == error, 1 == warning, 0 == off.
- */
- rules: {
- "@typescript-eslint/no-unused-vars": [2, {args: "none"}],
- "@typescript-eslint/consistent-type-imports": [2, {disallowTypeAnnotations: false}],
- /**
- * Enforced rules
- */
- // syntax preferences
- "object-curly-spacing": ["error", "always"],
- "quotes": [2, "single", {
- "avoidEscape": true,
- "allowTemplateLiterals": true
- }],
- "jsx-quotes": [2, "prefer-single"],
- "no-extra-semi": 2,
- "@typescript-eslint/semi": [2],
- "comma-style": [2, "last"],
- "wrap-iife": [2, "inside"],
- "spaced-comment": [2, "always", {
- "markers": ["*"]
- }],
- "eqeqeq": [2],
- "accessor-pairs": [2, {
- "getWithoutSet": false,
- "setWithoutGet": false
- }],
- "brace-style": [2, "1tbs", {"allowSingleLine": true}],
- "curly": [2, "multi-or-nest", "consistent"],
- "new-parens": 2,
- "arrow-parens": [2, "as-needed"],
- "prefer-const": 2,
- "quote-props": [2, "consistent"],
- "nonblock-statement-body-position": [2, "below"],
-
- // anti-patterns
- "no-var": 2,
- "no-with": 2,
- "no-multi-str": 2,
- "no-caller": 2,
- "no-implied-eval": 2,
- "no-labels": 2,
- "no-new-object": 2,
- "no-octal-escape": 2,
- "no-self-compare": 2,
- "no-shadow-restricted-names": 2,
- "no-cond-assign": 2,
- "no-debugger": 2,
- "no-dupe-keys": 2,
- "no-duplicate-case": 2,
- "no-empty-character-class": 2,
- "no-unreachable": 2,
- "no-unsafe-negation": 2,
- "radix": 2,
- "valid-typeof": 2,
- "no-implicit-globals": [2],
- "no-unused-expressions": [2, { "allowShortCircuit": true, "allowTernary": true, "allowTaggedTemplates": true}],
- "no-proto": 2,
-
- // es2015 features
- "require-yield": 2,
- "template-curly-spacing": [2, "never"],
-
- // spacing details
- "space-infix-ops": 2,
- "space-in-parens": [2, "never"],
- "array-bracket-spacing": [2, "never"],
- "comma-spacing": [2, { "before": false, "after": true }],
- "keyword-spacing": [2, "always"],
- "space-before-function-paren": [2, {
- "anonymous": "never",
- "named": "never",
- "asyncArrow": "always"
- }],
- "no-whitespace-before-property": 2,
- "keyword-spacing": [2, {
- "overrides": {
- "if": {"after": true},
- "else": {"after": true},
- "for": {"after": true},
- "while": {"after": true},
- "do": {"after": true},
- "switch": {"after": true},
- "return": {"after": true}
- }
- }],
- "arrow-spacing": [2, {
- "after": true,
- "before": true
- }],
- "@typescript-eslint/func-call-spacing": 2,
- "@typescript-eslint/type-annotation-spacing": 2,
-
- // file whitespace
- "no-multiple-empty-lines": [2, {"max": 2}],
- "no-mixed-spaces-and-tabs": 2,
- "no-trailing-spaces": 2,
- "linebreak-style": [ process.platform === "win32" ? 0 : 2, "unix" ],
- "indent": [2, 2, { "SwitchCase": 1, "CallExpression": {"arguments": 2}, "MemberExpression": 2 }],
- "key-spacing": [2, {
- "beforeColon": false
- }],
-
- // copyright
- "notice/notice": [2, {
- "mustMatch": "Copyright",
- "templateFile": require("path").join(__dirname, "utils", "copyright.js"),
- }],
- }
-};
diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml
index 062d7c7e742d1..60fea176c8f0c 100644
--- a/.github/ISSUE_TEMPLATE/bug.yml
+++ b/.github/ISSUE_TEMPLATE/bug.yml
@@ -24,6 +24,7 @@ body:
## Make a minimal reproduction
To file the report, you will need a GitHub repository with a minimal (but complete) example and simple/clear steps on how to reproduce the bug.
The simpler you can make it, the more likely we are to successfully verify and fix the bug. You can create a new project with `npm init playwright@latest new-project` and then add the test code there.
+ Please make sure you only include the code and the dependencies absolutely necessary for your repro. Due to the security considerations, we can only run the code we trust. Major web frameworks are Ok to use, but smaller convenience libraries are not.
- type: markdown
attributes:
value: |
diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml
index 9615afdc8a2ec..b64936798031e 100644
--- a/.github/ISSUE_TEMPLATE/question.yml
+++ b/.github/ISSUE_TEMPLATE/question.yml
@@ -23,5 +23,5 @@ body:
> [!IMPORTANT]
> This issue will be closed.
options:
- - label: I understand
+ - label: I understand that this issue will be closed
required: true
diff --git a/.github/ISSUE_TEMPLATE/regression.yml b/.github/ISSUE_TEMPLATE/regression.yml
index bc0a101502a6f..632c67104b19b 100644
--- a/.github/ISSUE_TEMPLATE/regression.yml
+++ b/.github/ISSUE_TEMPLATE/regression.yml
@@ -1,7 +1,6 @@
name: Report regression
description: Functionality that used to work and does not any more
title: "[Regression]: "
-
body:
- type: markdown
attributes:
diff --git a/.github/actions/enable-microphone-access/action.yml b/.github/actions/enable-microphone-access/action.yml
index b94f48064711f..76ca24eebfc6d 100644
--- a/.github/actions/enable-microphone-access/action.yml
+++ b/.github/actions/enable-microphone-access/action.yml
@@ -14,12 +14,12 @@ runs:
fi
echo "Allowing microphone access to all apps"
version=$(sw_vers -productVersion | cut -d. -f1)
- if [[ "$version" == "14" ]]; then
+ if [[ "$version" == "14" || "$version" == "15" ]]; then
sqlite3 $HOME/Library/Application\ Support/com.apple.TCC/TCC.db "INSERT OR IGNORE INTO access VALUES ('kTCCServiceMicrophone','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159,NULL,NULL,'UNUSED',1687786159);"
elif [[ "$version" == "12" || "$version" == "13" ]]; then
sqlite3 $HOME/Library/Application\ Support/com.apple.TCC/TCC.db "INSERT OR REPLACE INTO access VALUES('kTCCServiceMicrophone','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159);"
else
- echo "macOS version is unsupported. Version is $version, exiting"
- exit 1
+ echo "Skipping unsupported macOS version $version"
+ exit 0
fi
echo "Successfully allowed microphone access"
diff --git a/.github/actions/run-test/action.yml b/.github/actions/run-test/action.yml
index c193515c4501d..3f458b8b6247f 100644
--- a/.github/actions/run-test/action.yml
+++ b/.github/actions/run-test/action.yml
@@ -41,9 +41,6 @@ runs:
npm ci
echo "::endgroup::"
shell: bash
- env:
- DEBUG: pw:install
- PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1'
- run: |
echo "::group::npm run build"
npm run build
diff --git a/.github/actions/upload-blob-report/action.yml b/.github/actions/upload-blob-report/action.yml
index 72a084142a77f..e407e67573928 100644
--- a/.github/actions/upload-blob-report/action.yml
+++ b/.github/actions/upload-blob-report/action.yml
@@ -22,13 +22,3 @@ runs:
name: blob-report-${{ inputs.job_name }}
path: ${{ inputs.report_dir }}/**
retention-days: 7
- - name: Write triggering pull request number in a file
- if: ${{ !cancelled() && github.event_name == 'pull_request' }}
- shell: bash
- run: echo '${{ github.event.number }}' > pull_request_number.txt;
- - name: Upload artifact with the pull request number
- if: ${{ !cancelled() && github.event_name == 'pull_request' }}
- uses: actions/upload-artifact@v4
- with:
- name: pull-request-${{ inputs.job_name }}
- path: pull_request_number.txt
\ No newline at end of file
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000000000..84a45f6df4322
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,14 @@
+version: 2
+updates:
+ - package-ecosystem: "pip"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ groups:
+ actions:
+ patterns:
+ - "*"
diff --git a/.github/workflows/cherry_pick_into_release_branch.yml b/.github/workflows/cherry_pick_into_release_branch.yml
index 08c5562f35f03..b0f635a69b199 100644
--- a/.github/workflows/cherry_pick_into_release_branch.yml
+++ b/.github/workflows/cherry_pick_into_release_branch.yml
@@ -33,8 +33,8 @@ jobs:
- name: Cherry-pick commits
id: cherry-pick
run: |
- git config --global user.name github-actions
- git config --global user.email 41898282+github-actions[bot]@users.noreply.github.com
+ git config --global user.name microsoft-playwright-automation[bot]
+ git config --global user.email 203992400+microsoft-playwright-automation[bot]@users.noreply.github.com
for COMMIT_HASH in $(echo "${{ github.event.inputs.commit_hashes }}" | tr "," "\n"); do
git cherry-pick --no-commit "$COMMIT_HASH"
@@ -59,10 +59,15 @@ jobs:
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_OUTPUT
git checkout -b "$BRANCH_NAME"
git push origin $BRANCH_NAME
+ - uses: actions/create-github-app-token@v2
+ id: app-token
+ with:
+ app-id: ${{ vars.PLAYWRIGHT_APP_ID }}
+ private-key: ${{ secrets.PLAYWRIGHT_PRIVATE_KEY }}
- name: Create Pull Request
uses: actions/github-script@v7
with:
- github-token: ${{ secrets.REPOSITORY_DISPATCH_PERSONAL_ACCESS_TOKEN }}
+ github-token: ${{ steps.app-token.outputs.token }}
script: |
const readableCommitHashesList = '${{ github.event.inputs.commit_hashes }}'.split(',').map(hash => `- ${hash}`).join('\n');
const response = await github.rest.pulls.create({
diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml
new file mode 100644
index 0000000000000..54cf652ae21b6
--- /dev/null
+++ b/.github/workflows/copilot-setup-steps.yml
@@ -0,0 +1,17 @@
+name: "Copilot Setup Steps"
+on: workflow_dispatch
+jobs:
+ copilot-setup-steps:
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: read
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: "22"
+ - run: npm ci
+ - run: npm run build
+ - run: npx playwright install --with-deps
diff --git a/.github/workflows/create_test_report.yml b/.github/workflows/create_test_report.yml
index 9d382f1ee632e..6758556deff7e 100644
--- a/.github/workflows/create_test_report.yml
+++ b/.github/workflows/create_test_report.yml
@@ -20,8 +20,7 @@ jobs:
node-version: 18
- run: npm ci
env:
- DEBUG: pw:install
- PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
+ ELECTRON_SKIP_BINARY_DOWNLOAD: 1
- run: npm run build
- name: Download blob report artifact
@@ -34,7 +33,9 @@ jobs:
run: |
npx playwright merge-reports --config .github/workflows/merge.config.ts ./all-blob-reports
env:
- NODE_OPTIONS: --max-old-space-size=4096
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ NODE_OPTIONS: --max-old-space-size=8192
+ HTML_REPORT_URL: 'https://mspwblobreport.z1.web.core.windows.net/run-${{ github.event.workflow_run.id }}-${{ github.event.workflow_run.run_attempt }}-${{ github.sha }}/index.html'
- name: Azure Login
uses: azure/login@v2
@@ -50,91 +51,3 @@ jobs:
echo "Report url: https://mspwblobreport.z1.web.core.windows.net/$REPORT_DIR/index.html"
env:
AZCOPY_AUTO_LOGIN_TYPE: AZCLI
-
- - name: Read pull request number
- uses: ./.github/actions/download-artifact
- with:
- namePrefix: 'pull-request'
- path: '.'
-
- - name: Comment on PR
- uses: actions/github-script@v7
- with:
- github-token: ${{ secrets.GITHUB_TOKEN }}
- script: |
- const fs = require('fs');
- let prNumber;
- if (context.payload.workflow_run.event === 'pull_request') {
- const prs = context.payload.workflow_run.pull_requests;
- if (prs.length) {
- prNumber = prs[0].number;
- } else {
- prNumber = parseInt(fs.readFileSync('pull_request_number.txt').toString());
- console.log('Read pull request number from file: ' + prNumber);
- }
- } else {
- core.error('Unsupported workflow trigger event: ' + context.payload.workflow_run.event);
- return;
- }
- if (!prNumber) {
- core.error('No pull request found for commit ' + context.sha + ' and workflow triggered by: ' + context.payload.workflow_run.event);
- return;
- }
- {
- // Mark previous comments as outdated by minimizing them.
- const { data: comments } = await github.rest.issues.listComments({
- ...context.repo,
- issue_number: prNumber,
- });
- for (const comment of comments) {
- if (comment.user.login === 'github-actions[bot]' && /\[Test results\]\(https:\/\/.+?\) for "${{ github.event.workflow_run.name }}"/.test(comment.body)) {
- await github.graphql(`
- mutation {
- minimizeComment(input: {subjectId: "${comment.node_id}", classifier: OUTDATED}) {
- clientMutationId
- }
- }
- `);
- }
- }
- }
- const reportDir = 'run-${{ github.event.workflow_run.id }}-${{ github.event.workflow_run.run_attempt }}-${{ github.sha }}';
- const reportUrl = `https://mspwblobreport.z1.web.core.windows.net/${reportDir}/index.html#?q=s%3Afailed%20s%3Aflaky`;
- core.notice('Report url: ' + reportUrl);
- const mergeWorkflowUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
- const reportMd = await fs.promises.readFile('report.md', 'utf8');
- function formatComment(lines) {
- let body = lines.join('\n');
- if (body.length > 65535)
- body = body.substring(0, 65000) + `... ${body.length - 65000} more characters`;
- return body;
- }
- const { data: response } = await github.rest.issues.createComment({
- ...context.repo,
- issue_number: prNumber,
- body: formatComment([
- `### [Test results](${reportUrl}) for "${{ github.event.workflow_run.name }}"`,
- reportMd,
- '',
- `Merge [workflow run](${mergeWorkflowUrl}).`
- ]),
- });
- core.info('Posted comment: ' + response.html_url);
-
- const check = await github.rest.checks.create({
- ...context.repo,
- name: 'Merge report (${{ github.event.workflow_run.name }})',
- head_sha: '${{ github.event.workflow_run.head_sha }}',
- status: 'completed',
- conclusion: 'success',
- details_url: reportUrl,
- output: {
- title: 'Test results for "${{ github.event.workflow_run.name }}"',
- summary: [
- reportMd,
- '',
- '---',
- `Full [HTML report](${reportUrl}). Merge [workflow run](${mergeWorkflowUrl}).`
- ].join('\n'),
- }
- });
diff --git a/.github/workflows/infra.yml b/.github/workflows/infra.yml
index 3580ecc97ad8d..0a03f10f1338a 100644
--- a/.github/workflows/infra.yml
+++ b/.github/workflows/infra.yml
@@ -16,7 +16,7 @@ env:
jobs:
doc-and-lint:
name: "docs & lint"
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
@@ -24,8 +24,7 @@ jobs:
node-version: 18
- run: npm ci
- run: npm run build
- - run: npx playwright install-deps
- - run: npx playwright install
+ - run: npx playwright install --with-deps
- run: npm run lint
- name: Verify clean tree
run: |
@@ -35,21 +34,28 @@ jobs:
exit 1
fi
- name: Audit prod NPM dependencies
- run: npm audit --omit dev
+ run: node utils/check_audit.js
+ continue-on-error: true
lint-snippets:
name: "Lint snippets"
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
- - uses: actions/setup-python@v4
+ - uses: actions/setup-python@v5
with:
python-version: '3.11'
- - uses: actions/setup-dotnet@v3
+ - uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
+ - uses: actions/setup-java@v4
+ with:
+ distribution: 'zulu'
+ java-version: '21'
- run: npm ci
- run: pip install -r utils/doclint/linting-code-snippets/python/requirements.txt
+ - run: mvn package
+ working-directory: utils/doclint/linting-code-snippets/java
- run: node utils/doclint/linting-code-snippets/cli.js
diff --git a/.github/workflows/merge.config.ts b/.github/workflows/merge.config.ts
index b39944bc809c1..222b728f7c134 100644
--- a/.github/workflows/merge.config.ts
+++ b/.github/workflows/merge.config.ts
@@ -1,4 +1,4 @@
export default {
testDir: '../../tests',
- reporter: [['markdown'], ['html']]
+ reporter: [[require.resolve('../../tests/config/ghaMarkdownReporter')], ['html']]
};
\ No newline at end of file
diff --git a/.github/workflows/pr_check_client_side_changes.yml b/.github/workflows/pr_check_client_side_changes.yml
index 7748b5d514af3..12b7e5dff9131 100644
--- a/.github/workflows/pr_check_client_side_changes.yml
+++ b/.github/workflows/pr_check_client_side_changes.yml
@@ -12,14 +12,24 @@ on:
jobs:
check:
name: Check
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
if: github.repository == 'microsoft/playwright'
steps:
- uses: actions/checkout@v4
+ - uses: actions/create-github-app-token@v2
+ id: app-token
+ with:
+ app-id: ${{ vars.PLAYWRIGHT_APP_ID }}
+ private-key: ${{ secrets.PLAYWRIGHT_PRIVATE_KEY }}
+ repositories: |
+ playwright
+ playwright-python
+ playwright-java
+ playwright-dotnet
- name: Create GitHub issue
uses: actions/github-script@v7
with:
- github-token: ${{ secrets.REPOSITORY_DISPATCH_PERSONAL_ACCESS_TOKEN }}
+ github-token: ${{ steps.app-token.outputs.token }}
script: |
const currentPlaywrightVersion = require('./package.json').version.match(/\d+\.\d+/)[0];
const { data } = await github.rest.git.getCommit({
@@ -28,11 +38,15 @@ jobs:
commit_sha: context.sha,
});
const commitHeader = data.message.split('\n')[0];
+ const prMatch = commitHeader.match(/#(\d+)/);
+ const formattedCommit = prMatch
+ ? `https://github.com/microsoft/playwright/pull/${prMatch[1]}`
+ : `https://github.com/${context.repo.owner}/${context.repo.repo}/commit/${context.sha} (${commitHeader})`;
const title = '[Ports]: Backport client side changes for ' + currentPlaywrightVersion;
for (const repo of ['playwright-python', 'playwright-java', 'playwright-dotnet']) {
const { data: issuesData } = await github.rest.search.issuesAndPullRequests({
- q: `is:issue is:open repo:microsoft/${repo} in:title "${title}" author:playwrightmachine`
+ q: `is:issue is:open repo:microsoft/${repo} in:title "${title}"`
})
let issueNumber = null;
let issueBody = '';
@@ -50,7 +64,7 @@ jobs:
issueBody = issueCreateData.body;
}
const newBody = issueBody.trimEnd() + `
- - [ ] https://github.com/${context.repo.owner}/${context.repo.repo}/commit/${context.sha} (${commitHeader})`;
+ - [ ] ${formattedCommit}`;
const data = await github.rest.issues.update({
owner: context.repo.owner,
repo: repo,
diff --git a/.github/workflows/publish_canary.yml b/.github/workflows/publish_canary.yml
index 50a156475529a..87ebcf27b3a5e 100644
--- a/.github/workflows/publish_canary.yml
+++ b/.github/workflows/publish_canary.yml
@@ -3,7 +3,7 @@ name: "publish canary"
on:
workflow_dispatch:
schedule:
- - cron: "10 0 * * *"
+ - cron: "10 5 * * *"
push:
branches:
- release-*
@@ -14,7 +14,7 @@ env:
jobs:
publish-canary:
name: "publish canary NPM"
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
if: github.repository == 'microsoft/playwright'
permissions:
id-token: write # This is required for OIDC login (azure/login) to succeed
@@ -28,7 +28,6 @@ jobs:
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm run build
- - run: npx playwright install-deps
- name: "@next: publish with commit timestamp (triggered manually)"
if: contains(github.ref, 'main') && github.event_name == 'workflow_dispatch'
run: |
@@ -65,20 +64,26 @@ jobs:
publish-trace-viewer:
name: "publish Trace Viewer to trace.playwright.dev"
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
if: github.repository == 'microsoft/playwright'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
+ - uses: actions/create-github-app-token@v2
+ id: app-token
+ with:
+ app-id: ${{ vars.PLAYWRIGHT_APP_ID }}
+ private-key: ${{ secrets.PLAYWRIGHT_PRIVATE_KEY }}
+ repositories: trace.playwright.dev
- name: Deploy Canary
run: bash utils/build/deploy-trace-viewer.sh --canary
if: contains(github.ref, 'main')
env:
- GH_SERVICE_ACCOUNT_TOKEN: ${{ secrets.REPOSITORY_DISPATCH_PERSONAL_ACCESS_TOKEN }}
+ GH_SERVICE_ACCOUNT_TOKEN: ${{ steps.app-token.outputs.token }}
- name: Deploy BETA
run: bash utils/build/deploy-trace-viewer.sh --beta
if: contains(github.ref, 'release')
env:
- GH_SERVICE_ACCOUNT_TOKEN: ${{ secrets.REPOSITORY_DISPATCH_PERSONAL_ACCESS_TOKEN }}
+ GH_SERVICE_ACCOUNT_TOKEN: ${{ steps.app-token.outputs.token }}
diff --git a/.github/workflows/publish_release_docker.yml b/.github/workflows/publish_release_docker.yml
index 6a9e6d85ae05e..c9603bffcdf21 100644
--- a/.github/workflows/publish_release_docker.yml
+++ b/.github/workflows/publish_release_docker.yml
@@ -2,12 +2,6 @@ name: "publish release - Docker"
on:
workflow_dispatch:
- inputs:
- is_release:
- required: true
- type: boolean
- description: "Is this a release image?"
-
release:
types: [published]
@@ -35,7 +29,6 @@ jobs:
platforms: arm64
- run: npm ci
- run: npm run build
- - run: npx playwright install-deps
- name: Azure Login
uses: azure/login@v2
with:
@@ -45,6 +38,3 @@ jobs:
- name: Login to ACR via OIDC
run: az acr login --name playwright
- run: ./utils/docker/publish_docker.sh stable
- if: (github.event_name != 'workflow_dispatch' && !github.event.release.prerelease) || (github.event_name == 'workflow_dispatch' && github.event.inputs.is_release == 'true')
- - run: ./utils/docker/publish_docker.sh canary
- if: (github.event_name != 'workflow_dispatch' && github.event.release.prerelease) || (github.event_name == 'workflow_dispatch' && github.event.inputs.is_release != 'true')
diff --git a/.github/workflows/publish_release_driver.yml b/.github/workflows/publish_release_driver.yml
index 8ad1a4184a185..328deaf01cb7a 100644
--- a/.github/workflows/publish_release_driver.yml
+++ b/.github/workflows/publish_release_driver.yml
@@ -10,7 +10,7 @@ env:
jobs:
publish-driver-release:
name: "publish playwright driver to CDN"
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
if: github.repository == 'microsoft/playwright'
permissions:
id-token: write # This is required for OIDC login (azure/login) to succeed
@@ -24,7 +24,6 @@ jobs:
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm run build
- - run: npx playwright install-deps
- run: utils/build/build-playwright-driver.sh
- name: Azure Login
uses: azure/login@v2
diff --git a/.github/workflows/publish_release_npm.yml b/.github/workflows/publish_release_npm.yml
index 46b58168345dc..cab5e13596467 100644
--- a/.github/workflows/publish_release_npm.yml
+++ b/.github/workflows/publish_release_npm.yml
@@ -10,7 +10,7 @@ env:
jobs:
publish-npm-release:
name: "publish to NPM"
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
if: github.repository == 'microsoft/playwright'
permissions:
contents: read
@@ -23,7 +23,6 @@ jobs:
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm run build
- - run: npx playwright install-deps
- run: utils/publish_all_packages.sh --release-candidate
if: ${{ github.event.release.prerelease }}
env:
diff --git a/.github/workflows/publish_release_traceviewer.yml b/.github/workflows/publish_release_traceviewer.yml
index 60af5442e95b2..b497f5290cdcc 100644
--- a/.github/workflows/publish_release_traceviewer.yml
+++ b/.github/workflows/publish_release_traceviewer.yml
@@ -7,14 +7,20 @@ on:
jobs:
publish-trace-viewer:
name: "publish Trace Viewer to trace.playwright.dev"
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
if: github.repository == 'microsoft/playwright'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
+ - uses: actions/create-github-app-token@v2
+ id: app-token
+ with:
+ app-id: ${{ vars.PLAYWRIGHT_APP_ID }}
+ private-key: ${{ secrets.PLAYWRIGHT_PRIVATE_KEY }}
+ repositories: trace.playwright.dev
- name: Deploy Stable
run: bash utils/build/deploy-trace-viewer.sh --stable
env:
- GH_SERVICE_ACCOUNT_TOKEN: ${{ secrets.REPOSITORY_DISPATCH_PERSONAL_ACCESS_TOKEN }}
+ GH_SERVICE_ACCOUNT_TOKEN: ${{ steps.app-token.outputs.token }}
diff --git a/.github/workflows/roll_browser_into_playwright.yml b/.github/workflows/roll_browser_into_playwright.yml
index da905131603e6..3dc822638e361 100644
--- a/.github/workflows/roll_browser_into_playwright.yml
+++ b/.github/workflows/roll_browser_into_playwright.yml
@@ -6,13 +6,18 @@ on:
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: 1
+ BROWSER: ${{ github.event.client_payload.browser }}
+ REVISION: ${{ github.event.client_payload.revision }}
permissions:
contents: write
+concurrency:
+ group: 'roll-browser-into-playwright-${{ github.event.client_payload.browser }}-${{ github.event.client_payload.revision }}'
+
jobs:
roll:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
@@ -24,30 +29,45 @@ jobs:
run: npx playwright install-deps
- name: Roll to new revision
run: |
- ./utils/roll_browser.js ${{ github.event.client_payload.browser }} ${{ github.event.client_payload.revision }}
+ ./utils/roll_browser.js $BROWSER $REVISION
npm run build
- name: Prepare branch
id: prepare-branch
run: |
- BRANCH_NAME="roll-into-pw-${{ github.event.client_payload.browser }}/${{ github.event.client_payload.revision }}"
+ BRANCH_NAME="roll-into-pw-${BROWSER}/${REVISION}"
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_OUTPUT
- git config --global user.name github-actions
- git config --global user.email 41898282+github-actions[bot]@users.noreply.github.com
+
+ git fetch origin $BRANCH_NAME:$BRANCH_NAME || true
+ if git show-ref --verify --quiet refs/heads/$BRANCH_NAME; then
+ echo "exists=1" >> $GITHUB_OUTPUT
+ echo "branch $BRANCH_NAME already exists, exiting"
+ exit 0
+ fi
+ echo "exists=0" >> $GITHUB_OUTPUT
+
+ git config --global user.name microsoft-playwright-automation[bot]
+ git config --global user.email 203992400+microsoft-playwright-automation[bot]@users.noreply.github.com
git checkout -b "$BRANCH_NAME"
git add .
- git commit -m "feat(${{ github.event.client_payload.browser }}): roll to r${{ github.event.client_payload.revision }}"
- git push origin $BRANCH_NAME
+ git commit -m "feat(${BROWSER}): roll to r${REVISION}"
+ git push origin $BRANCH_NAME --force
+ - uses: actions/create-github-app-token@v2
+ id: app-token
+ with:
+ app-id: ${{ vars.PLAYWRIGHT_APP_ID }}
+ private-key: ${{ secrets.PLAYWRIGHT_PRIVATE_KEY }}
- name: Create Pull Request
uses: actions/github-script@v7
+ if: ${{ steps.prepare-branch.outputs.exists == '0' }}
with:
- github-token: ${{ secrets.REPOSITORY_DISPATCH_PERSONAL_ACCESS_TOKEN }}
+ github-token: ${{ steps.app-token.outputs.token }}
script: |
const response = await github.rest.pulls.create({
owner: 'microsoft',
repo: 'playwright',
head: 'microsoft:${{ steps.prepare-branch.outputs.BRANCH_NAME }}',
base: 'main',
- title: 'feat(${{ github.event.client_payload.browser }}): roll to r${{ github.event.client_payload.revision }}',
+ title: 'feat(${{ env.BROWSER }}): roll to r${{ env.REVISION }}',
});
await github.rest.issues.addLabels({
owner: 'microsoft',
diff --git a/.github/workflows/roll_driver_nodejs.yml b/.github/workflows/roll_driver_nodejs.yml
index ee0d3d262ce36..ee993f980f12d 100644
--- a/.github/workflows/roll_driver_nodejs.yml
+++ b/.github/workflows/roll_driver_nodejs.yml
@@ -27,17 +27,22 @@ jobs:
echo "HAS_CHANGES=1" >> $GITHUB_OUTPUT
BRANCH_NAME="roll-driver-nodejs/$(date +%Y-%b-%d)"
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_OUTPUT
- git config --global user.name github-actions
- git config --global user.email 41898282+github-actions[bot]@users.noreply.github.com
+ git config --global user.name microsoft-playwright-automation[bot]
+ git config --global user.email 203992400+microsoft-playwright-automation[bot]@users.noreply.github.com
git checkout -b "$BRANCH_NAME"
git add .
git commit -m "chore(driver): roll driver to recent Node.js LTS version"
git push origin $BRANCH_NAME
+ - uses: actions/create-github-app-token@v2
+ id: app-token
+ with:
+ app-id: ${{ vars.PLAYWRIGHT_APP_ID }}
+ private-key: ${{ secrets.PLAYWRIGHT_PRIVATE_KEY }}
- name: Create Pull Request
if: ${{ steps.prepare-branch.outputs.HAS_CHANGES == '1' }}
uses: actions/github-script@v7
with:
- github-token: ${{ secrets.REPOSITORY_DISPATCH_PERSONAL_ACCESS_TOKEN }}
+ github-token: ${{ steps.app-token.outputs.token }}
script: |
await github.rest.pulls.create({
owner: 'microsoft',
diff --git a/.github/workflows/roll_stable_test_runner.yml b/.github/workflows/roll_stable_test_runner.yml
new file mode 100644
index 0000000000000..2c908520444d8
--- /dev/null
+++ b/.github/workflows/roll_stable_test_runner.yml
@@ -0,0 +1,58 @@
+name: "PR: bump stable-test-runner"
+on:
+ workflow_dispatch:
+ schedule:
+ # At 10:00am UTC (3AM PST) every Monday
+ - cron: "0 10 * * 1"
+jobs:
+ trigger-roll:
+ name: Trigger Roll
+ runs-on: ubuntu-24.04
+ if: github.repository == 'microsoft/playwright'
+ permissions:
+ contents: write
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 22
+ - run: |
+ npm install @playwright/test@next
+ VERSION=$(node -e "console.log(require('./package.json').dependencies['@playwright/test'].replace('^', ''))")
+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
+ working-directory: tests/playwright-test/stable-test-runner/
+ id: bump
+ - name: Prepare branch
+ id: prepare-branch
+ run: |
+ if [[ "$(git status --porcelain)" == "" ]]; then
+ echo "there are no changes";
+ exit 0;
+ fi
+ echo "HAS_CHANGES=1" >> $GITHUB_OUTPUT
+ BRANCH_NAME="roll-stable-test-runner/$(date +%Y-%b-%d)"
+ echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_OUTPUT
+ git config --global user.name microsoft-playwright-automation[bot]
+ git config --global user.email 203992400+microsoft-playwright-automation[bot]@users.noreply.github.com
+ git checkout -b "$BRANCH_NAME"
+ git add .
+ git commit -m "test: roll stable-test-runner to ${{ steps.bump.outputs.VERSION }}"
+ git push origin $BRANCH_NAME
+ - uses: actions/create-github-app-token@v2
+ id: app-token
+ with:
+ app-id: ${{ vars.PLAYWRIGHT_APP_ID }}
+ private-key: ${{ secrets.PLAYWRIGHT_PRIVATE_KEY }}
+ - name: Create Pull Request
+ if: ${{ steps.prepare-branch.outputs.HAS_CHANGES == '1' }}
+ uses: actions/github-script@v7
+ with:
+ github-token: ${{ steps.app-token.outputs.token }}
+ script: |
+ await github.rest.pulls.create({
+ owner: 'microsoft',
+ repo: 'playwright',
+ head: 'microsoft:${{ steps.prepare-branch.outputs.BRANCH_NAME }}',
+ base: 'main',
+ title: 'test: roll stable-test-runner to ${{ steps.bump.outputs.VERSION }}',
+ });
diff --git a/.github/workflows/tests_bidi.yml b/.github/workflows/tests_bidi.yml
new file mode 100644
index 0000000000000..4d6dc437325ce
--- /dev/null
+++ b/.github/workflows/tests_bidi.yml
@@ -0,0 +1,80 @@
+name: tests BiDi
+
+on:
+ workflow_dispatch:
+ inputs:
+ ref:
+ description: Playwright SHA / ref to test. Use 'refs/pull/PULL_REQUEST_ID/head' to test a PR. Defaults to the current branch.
+ required: false
+ default: ''
+ pull_request:
+ branches:
+ - main
+ paths:
+ - .github/workflows/tests_bidi.yml
+ - packages/playwright-core/src/server/bidi/**
+ - tests/bidi/**
+ schedule:
+ # Run every day at midnight
+ - cron: '0 0 * * *'
+
+env:
+ FORCE_COLOR: 1
+
+jobs:
+ test_bidi:
+ name: BiDi
+ environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
+ runs-on: ubuntu-24.04
+ permissions:
+ id-token: write # This is required for OIDC login (azure/login) to succeed
+ contents: read # This is required for actions/checkout to succeed
+ strategy:
+ fail-fast: false
+ matrix:
+ channel: [bidi-chromium, moz-firefox-nightly]
+ steps:
+ - uses: actions/checkout@v4
+ if: github.event_name != 'workflow_dispatch'
+ - uses: actions/checkout@v4
+ if: github.event_name == 'workflow_dispatch'
+ with:
+ ref: ${{ github.event.inputs.ref }}
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ - run: npm ci
+ - run: npm run build
+ - run: npx playwright install --with-deps chromium
+ if: matrix.channel == 'bidi-chromium'
+ - if: matrix.channel == 'moz-firefox-nightly'
+ run: |
+ echo "BIDI_FFPATH=$(npx -y @puppeteer/browsers install firefox@nightly | tail -n1 | sed 's/^[^ ]* *//')" >> "$GITHUB_ENV"
+ - name: Run tests
+ run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run biditest -- --project=${{ matrix.channel }}*
+ env:
+ PWTEST_USE_BIDI_EXPECTATIONS: '1'
+ - name: Upload csv report to GitHub
+ if: ${{ !cancelled() }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: csv-report-${{ matrix.channel }}
+ path: test-results/report.csv
+ retention-days: 7
+
+ - name: Azure Login
+ if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
+ uses: azure/login@v2
+ with:
+ client-id: ${{ secrets.AZURE_BLOB_REPORTS_CLIENT_ID }}
+ tenant-id: ${{ secrets.AZURE_BLOB_REPORTS_TENANT_ID }}
+ subscription-id: ${{ secrets.AZURE_BLOB_REPORTS_SUBSCRIPTION_ID }}
+
+ - name: Upload report.csv to Azure
+ if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
+ run: |
+ REPORT_DIR='bidi-reports'
+ azcopy cp "./test-results/report.csv" "https://mspwblobreport.blob.core.windows.net/\$web/$REPORT_DIR/${{ matrix.channel }}.csv"
+ echo "Report url: https://mspwblobreport.z1.web.core.windows.net/$REPORT_DIR/${{ matrix.channel }}.csv"
+ env:
+ AZCOPY_AUTO_LOGIN_TYPE: AZCLI
diff --git a/.github/workflows/tests_others.yml b/.github/workflows/tests_others.yml
index 783f3fe2ff800..ed18e1541c635 100644
--- a/.github/workflows/tests_others.yml
+++ b/.github/workflows/tests_others.yml
@@ -24,9 +24,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- # Stick with macos-latest-large for now which is Intel-based until
- # https://github.com/microsoft/playwright/issues/30705 is fixed.
- os: [ubuntu-latest, macos-latest-large, windows-latest]
+ os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
@@ -66,7 +64,7 @@ jobs:
contents: read # This is required for actions/checkout to succeed
steps:
- uses: actions/checkout@v4
- - uses: actions/setup-dotnet@v3
+ - uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- run: dotnet build
@@ -149,6 +147,13 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
+ - name: Setup Ubuntu Binary Installation # TODO: Remove when https://github.com/electron/electron/issues/42510 is fixed
+ if: ${{ runner.os == 'Linux' }}
+ run: |
+ if grep -q "Ubuntu 24" /etc/os-release; then
+ sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
+ fi
+ shell: bash
- uses: ./.github/actions/run-test
with:
browsers-to-install: chromium
diff --git a/.github/workflows/tests_primary.yml b/.github/workflows/tests_primary.yml
index 02847957c4fd7..ec575d808e798 100644
--- a/.github/workflows/tests_primary.yml
+++ b/.github/workflows/tests_primary.yml
@@ -23,6 +23,7 @@ env:
# Force terminal colors. @see https://www.npmjs.com/package/colors
FORCE_COLOR: 1
ELECTRON_SKIP_BINARY_DOWNLOAD: 1
+ DEBUG_GIT_COMMIT_INFO: 1
jobs:
test_linux:
@@ -41,6 +42,9 @@ jobs:
- os: ubuntu-22.04
node-version: 22
browser: chromium
+ - os: ubuntu-22.04
+ node-version: 24
+ browser: chromium
runs-on: ${{ matrix.os }}
permissions:
id-token: write # This is required for OIDC login (azure/login) to succeed
@@ -63,7 +67,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- os: [ubuntu-20.04]
+ os: [ubuntu-22.04]
runs-on: ${{ matrix.os }}
permissions:
id-token: write # This is required for OIDC login (azure/login) to succeed
@@ -108,6 +112,14 @@ jobs:
node-version: 22
shardIndex: 2
shardTotal: 2
+ - os: ubuntu-latest
+ node-version: 24
+ shardIndex: 1
+ shardTotal: 2
+ - os: ubuntu-latest
+ node-version: 24
+ shardIndex: 2
+ shardTotal: 2
runs-on: ${{ matrix.os }}
permissions:
id-token: write # This is required for OIDC login (azure/login) to succeed
@@ -134,8 +146,6 @@ jobs:
with:
node-version: 18
- run: npm ci
- env:
- DEBUG: pw:install
- run: npm run build
- run: npx playwright install --with-deps
@@ -165,6 +175,7 @@ jobs:
runs-on: ubuntu-latest
env:
PWTEST_BOT_NAME: "vscode-extension"
+ DEBUG_GIT_COMMIT_INFO: ""
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
@@ -184,7 +195,7 @@ jobs:
run: node -e "const p = require('./package.json'); delete p.devDependencies['@playwright/test']; fs.writeFileSync('./package.json', JSON.stringify(p, null, 2));"
working-directory: ./playwright-vscode
- name: Build extension
- run: npm install && npm run build
+ run: npm ci && npm run build
working-directory: ./playwright-vscode
- name: Run extension tests
run: npm run test -- --workers=1
@@ -215,6 +226,13 @@ jobs:
- uses: actions/checkout@v4
- run: npm install -g yarn@1
- run: npm install -g pnpm@8
+ - name: Setup Ubuntu Binary Installation # TODO: Remove when https://github.com/electron/electron/issues/42510 is fixed
+ if: ${{ runner.os == 'Linux' }}
+ run: |
+ if grep -q "Ubuntu 24" /etc/os-release; then
+ sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
+ fi
+ shell: bash
- uses: ./.github/actions/run-test
with:
command: npm run itest
diff --git a/.github/workflows/tests_secondary.yml b/.github/workflows/tests_secondary.yml
index fd5458fb89f04..eafe68cd60f3e 100644
--- a/.github/workflows/tests_secondary.yml
+++ b/.github/workflows/tests_secondary.yml
@@ -31,7 +31,7 @@ jobs:
fail-fast: false
matrix:
browser: [chromium, firefox, webkit]
- os: [ubuntu-20.04, ubuntu-24.04]
+ os: [ubuntu-24.04]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
@@ -50,8 +50,15 @@ jobs:
strategy:
fail-fast: false
matrix:
- os: [macos-12, macos-13, macos-14]
+ # Intel: *-large
+ # Arm64: *-xlarge
+ os: [macos-13-large, macos-13-xlarge, macos-14-large, macos-14-xlarge]
browser: [chromium, firefox, webkit]
+ include:
+ - os: macos-15-large
+ browser: webkit
+ - os: macos-15-xlarge
+ browser: webkit
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
@@ -95,11 +102,20 @@ jobs:
node_version: 20
- os: ubuntu-latest
node_version: 22
+ - os: ubuntu-latest
+ node_version: 24
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- run: npm install -g yarn@1
- run: npm install -g pnpm@8
+ - name: Setup Ubuntu Binary Installation # TODO: Remove when https://github.com/electron/electron/issues/42510 is fixed
+ if: ${{ runner.os == 'Linux' }}
+ run: |
+ if grep -q "Ubuntu 24" /etc/os-release; then
+ sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
+ fi
+ shell: bash
- uses: ./.github/actions/run-test
with:
node-version: ${{ matrix.node_version }}
@@ -116,7 +132,11 @@ jobs:
fail-fast: false
matrix:
browser: [chromium, firefox, webkit]
- os: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, macos-14, windows-latest]
+ os: [ubuntu-24.04, macos-14-xlarge, windows-latest]
+ include:
+ # We have different binaries per Ubuntu version for WebKit.
+ - browser: webkit
+ os: ubuntu-22.04
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
@@ -136,7 +156,7 @@ jobs:
fail-fast: false
matrix:
mode: [driver, service]
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/run-test
@@ -158,11 +178,16 @@ jobs:
matrix:
include:
- browser: chromium
+ runs-on: ubuntu-22.04
- browser: firefox
+ runs-on: ubuntu-22.04
+ # See https://github.com/microsoft/playwright/issues/35586
- browser: webkit
+ runs-on: ubuntu-24.04
- browser: chromium
+ runs-on: ubuntu-22.04
channel: chromium-tip-of-tree
- runs-on: ubuntu-20.04
+ runs-on: ${{ matrix.runs-on }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/run-test
@@ -177,359 +202,99 @@ jobs:
PWTEST_TRACE: 1
PWTEST_CHANNEL: ${{ matrix.channel }}
- chrome_stable_linux:
- name: "Chrome Stable (Linux)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: ubuntu-20.04
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: chrome
- command: npm run ctest
- bot-name: "chrome-stable-linux"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: chrome
-
- chrome_stable_win:
- name: "Chrome Stable (Win)"
+ test_chromium_channels:
+ name: Test ${{ matrix.channel }} on ${{ matrix.runs-on }}
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: windows-latest
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: chrome
- command: npm run ctest
- bot-name: "chrome-stable-windows"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: chrome
-
- chrome_stable_mac:
- name: "Chrome Stable (Mac)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: macos-latest
+ runs-on: ${{ matrix.runs-on }}
+ strategy:
+ fail-fast: false
+ matrix:
+ channel: [chrome, chrome-beta, msedge, msedge-beta, msedge-dev]
+ runs-on: [ubuntu-22.04, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/run-test
with:
- browsers-to-install: chrome
+ browsers-to-install: ${{ matrix.channel }}
command: npm run ctest
- bot-name: "chrome-stable-mac"
+ bot-name: ${{ matrix.channel }}-${{ matrix.runs-on }}
flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
env:
- PWTEST_CHANNEL: chrome
+ PWTEST_CHANNEL: ${{ matrix.channel }}
chromium_tot:
- name: Chromium tip-of-tree ${{ matrix.os }}
+ name: Chromium tip-of-tree ${{ matrix.os }}${{ matrix.headed }}
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
- os: [ubuntu-20.04, macos-12, windows-latest]
+ os: [ubuntu-22.04, macos-13, windows-latest]
+ headed: ['--headed', '']
+ exclude:
+ # Tested in tests_primary.yml already
+ - os: ubuntu-22.04
+ headed: ''
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/run-test
with:
browsers-to-install: chromium-tip-of-tree
- command: npm run ctest
- bot-name: "tip-of-tree-${{ matrix.os }}"
+ command: npm run ctest -- ${{ matrix.headed }}
+ bot-name: "chromium-tip-of-tree-${{ matrix.os }}${{ matrix.headed }}"
flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
env:
PWTEST_CHANNEL: chromium-tip-of-tree
- chromium_tot_headed:
- name: Chromium tip-of-tree headed ${{ matrix.os }}
+ chromium_tot_headless_shell:
+ name: Chromium tip-of-tree headless-shell-${{ matrix.os }}
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
- os: [ubuntu-latest, macos-latest, windows-latest]
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: chromium-tip-of-tree
- command: npm run ctest -- --headed
- bot-name: "tip-of-tree-headed-${{ matrix.os }}"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: chromium-tip-of-tree
-
- firefox_beta_linux:
- name: "Firefox Beta (Linux)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: ubuntu-20.04
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: firefox-beta chromium
- command: npm run ftest
- bot-name: "firefox-beta-linux"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: firefox-beta
-
- firefox_beta_win:
- name: "Firefox Beta (Win)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: windows-latest
+ os: [ubuntu-22.04]
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/run-test
with:
- browsers-to-install: firefox-beta chromium
- command: npm run ftest -- --workers=1
- bot-name: "firefox-beta-windows"
+ browsers-to-install: chromium-tip-of-tree-headless-shell
+ command: npm run ctest
+ bot-name: "chromium-tip-of-tree-headless-shell-${{ matrix.os }}"
flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
env:
- PWTEST_CHANNEL: firefox-beta
+ PWTEST_CHANNEL: chromium-tip-of-tree-headless-shell
- firefox_beta_mac:
- name: "Firefox Beta (Mac)"
+ firefox_beta:
+ name: Firefox Beta ${{ matrix.os }}
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- # Stick with macos-latest-large for now which is Intel-based until
- # https://github.com/microsoft/playwright/issues/30705 is fixed.
- runs-on: macos-latest-large
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-22.04, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/run-test
with:
browsers-to-install: firefox-beta chromium
command: npm run ftest
- bot-name: "firefox-beta-mac"
+ bot-name: "firefox-beta-${{ matrix.os }}"
flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
env:
PWTEST_CHANNEL: firefox-beta
- edge_stable_mac:
- name: "Edge Stable (Mac)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: macos-latest
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: msedge
- command: npm run ctest
- bot-name: "edge-stable-mac"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: msedge
-
- edge_stable_win:
- name: "Edge Stable (Win)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: windows-latest
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: msedge
- command: npm run ctest
- bot-name: "edge-stable-windows"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: msedge
-
- edge_stable_linux:
- name: "Edge Stable (Linux)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: ubuntu-20.04
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: msedge
- command: npm run ctest
- bot-name: "edge-stable-linux"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: msedge
-
- edge_beta_mac:
- name: "Edge Beta (Mac)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: macos-latest
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: msedge-beta
- command: npm run ctest
- bot-name: "edge-beta-mac"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: msedge-beta
-
- edge_beta_win:
- name: "Edge Beta (Win)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: windows-latest
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: msedge-beta
- command: npm run ctest
- bot-name: "edge-beta-windows"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: msedge-beta
-
- edge_beta_linux:
- name: "Edge Beta (Linux)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: ubuntu-20.04
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: msedge-beta
- command: npm run ctest
- bot-name: "edge-beta-linux"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: msedge-beta
-
- edge_dev_mac:
- name: "Edge Dev (Mac)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: macos-latest
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: msedge-dev
- command: npm run ctest
- bot-name: "edge-dev-mac"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: msedge-dev
-
- edge_dev_win:
- name: "Edge Dev (Win)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: windows-latest
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: msedge-dev
- command: npm run ctest
- bot-name: "edge-dev-windows"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: msedge-dev
-
- edge_dev_linux:
- name: "Edge Dev (Linux)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: ubuntu-20.04
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: msedge-dev
- command: npm run ctest
- bot-name: "edge-dev-linux"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: msedge-dev
-
- chrome_beta_linux:
- name: "Chrome Beta (Linux)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: ubuntu-20.04
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: chrome-beta
- command: npm run ctest
- bot-name: "chrome-beta-linux"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: chrome-beta
-
- chrome_beta_win:
- name: "Chrome Beta (Win)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: windows-latest
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: chrome-beta
- command: npm run ctest
- bot-name: "chrome-beta-windows"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: chrome-beta
-
- chrome_beta_mac:
- name: "Chrome Beta (Mac)"
- environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: macos-latest
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/run-test
- with:
- browsers-to-install: chrome-beta
- command: npm run ctest
- bot-name: "chrome-beta-mac"
- flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
- flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
- flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
- env:
- PWTEST_CHANNEL: chrome-beta
-
build-playwright-driver:
name: "build-playwright-driver"
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
@@ -537,22 +302,27 @@ jobs:
node-version: 18
- run: npm ci
- run: npm run build
- - run: npx playwright install-deps
- run: utils/build/build-playwright-driver.sh
- test_linux_chromium_headless_new:
- name: Linux Chromium Headless New
+ test_channel_chromium:
+ name: Test channel=chromium
environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }}
- runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ runs-on: [ubuntu-latest, windows-latest, macos-latest]
+ runs-on: ${{ matrix.runs-on }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/run-test
with:
+ # TODO: this should pass --no-shell.
+ # However, codegen tests do not inherit the channel and try to launch headless shell.
browsers-to-install: chromium
command: npm run ctest
- bot-name: "headless-new"
+ bot-name: "channel-chromium-${{ matrix.runs-on }}"
flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }}
flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }}
flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }}
env:
- PLAYWRIGHT_CHROMIUM_USE_HEADLESS_NEW: 1
+ PWTEST_CHANNEL: chromium
diff --git a/.github/workflows/tests_service.yml b/.github/workflows/tests_service.yml
deleted file mode 100644
index 2739680712d66..0000000000000
--- a/.github/workflows/tests_service.yml
+++ /dev/null
@@ -1,70 +0,0 @@
-name: "tests service"
-
-on:
- workflow_dispatch:
-
-env:
- FORCE_COLOR: 1
- ELECTRON_SKIP_BINARY_DOWNLOAD: 1
-
-jobs:
- test:
- name: "Service"
- strategy:
- fail-fast: false
- matrix:
- service-os: [linux, windows]
- browser: [chromium, firefox, webkit]
- runs-on: ubuntu-20.04
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- - run: npm ci
- env:
- PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
- - run: npm run build
- - run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test -- --project=${{ matrix.browser }}-* --workers=10 --retries=0
- env:
- PWTEST_MODE: service2
- PWTEST_TRACE: 1
- PWTEST_BOT_NAME: "${{ matrix.browser }}-${{ matrix.service-os }}-service"
- PLAYWRIGHT_SERVICE_ACCESS_KEY: ${{ secrets.PLAYWRIGHT_SERVICE_ACCESS_KEY }}
- PLAYWRIGHT_SERVICE_URL: ${{ secrets.PLAYWRIGHT_SERVICE_URL }}
- PLAYWRIGHT_SERVICE_OS: ${{ matrix.service-os }}
- PLAYWRIGHT_SERVICE_RUN_ID: ${{ github.run_id }}-${{ github.run_attempt }}-${{ github.sha }}
- - name: Upload blob report to GitHub
- if: ${{ !cancelled() }}
- uses: actions/upload-artifact@v3
- with:
- name: all-blob-reports
- path: blob-report
- retention-days: 2
-
- merge_reports:
- name: "Merge reports"
- needs: [test]
- if: ${{ !cancelled() }}
- runs-on: ubuntu-20.04
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- - run: npm ci
- env:
- PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
- - run: npm run build
- - name: Download blob report artifact
- uses: actions/download-artifact@v3
- with:
- name: all-blob-reports
- path: all-blob-reports
- - run: npx playwright merge-reports --reporter markdown,html ./all-blob-reports
- - name: Upload HTML report to Azure
- run: |
- REPORT_DIR='run-service-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.sha }}'
- azcopy cp --recursive "./playwright-report/*" "https://mspwblobreport.blob.core.windows.net/\$web/$REPORT_DIR"
- echo "Report url: https://mspwblobreport.z1.web.core.windows.net/$REPORT_DIR/index.html#?q=s:failed"
- env:
- AZCOPY_AUTO_LOGIN_TYPE: SPN
- AZCOPY_SPA_APPLICATION_ID: '${{ secrets.AZCOPY_SPA_APPLICATION_ID }}'
- AZCOPY_SPA_CLIENT_SECRET: '${{ secrets.AZCOPY_SPA_CLIENT_SECRET }}'
- AZCOPY_TENANT_ID: '${{ secrets.AZCOPY_TENANT_ID }}'
diff --git a/.github/workflows/tests_video.yml b/.github/workflows/tests_video.yml
index 0733b082a0818..cc303d79c5aae 100644
--- a/.github/workflows/tests_video.yml
+++ b/.github/workflows/tests_video.yml
@@ -19,7 +19,7 @@ jobs:
fail-fast: false
matrix:
browser: [chromium, firefox, webkit]
- os: [ubuntu-20.04, ubuntu-22.04]
+ os: [ubuntu-22.04, ubuntu-24.04]
permissions:
id-token: write # This is required for OIDC login (azure/login) to succeed
contents: read # This is required for actions/checkout to succeed
diff --git a/.github/workflows/trigger_tests.yml b/.github/workflows/trigger_tests.yml
index dcd68dca37440..69a3d5f21b4e7 100644
--- a/.github/workflows/trigger_tests.yml
+++ b/.github/workflows/trigger_tests.yml
@@ -9,8 +9,14 @@ on:
jobs:
trigger:
name: "trigger"
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
steps:
+ - uses: actions/create-github-app-token@v2
+ id: app-token
+ with:
+ app-id: ${{ vars.PLAYWRIGHT_APP_ID }}
+ private-key: ${{ secrets.PLAYWRIGHT_PRIVATE_KEY }}
+ repositories: playwright-browsers
- run: |
curl -X POST \
-H "Accept: application/vnd.github.v3+json" \
@@ -18,4 +24,4 @@ jobs:
--data "{\"event_type\": \"playwright_tests\", \"client_payload\": {\"ref\": \"${GITHUB_SHA}\"}}" \
https://api.github.com/repos/microsoft/playwright-browsers/dispatches
env:
- GH_TOKEN: ${{ secrets.REPOSITORY_DISPATCH_PERSONAL_ACCESS_TOKEN }}
+ GH_TOKEN: ${{ steps.app-token.outputs.token }}
diff --git a/.gitignore b/.gitignore
index 69d85e4975adc..8e41e318108ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,4 +33,6 @@ test-results
/tests/installation/output/
/tests/installation/.registry.json
.cache/
-.eslintcache
\ No newline at end of file
+.eslintcache
+playwright.env
+/firefox/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 30e89e6beef6f..a945d57263589 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,92 +1,92 @@
# Contributing
-- [How to Contribute](#how-to-contribute)
- * [Getting Code](#getting-code)
- * [Code reviews](#code-reviews)
- * [Code Style](#code-style)
- * [API guidelines](#api-guidelines)
- * [Commit Messages](#commit-messages)
- * [Writing Documentation](#writing-documentation)
- * [Adding New Dependencies](#adding-new-dependencies)
- * [Running & Writing Tests](#running--writing-tests)
- * [Public API Coverage](#public-api-coverage)
-- [Contributor License Agreement](#contributor-license-agreement)
- * [Code of Conduct](#code-of-conduct)
+## Choose an issue
-## How to Contribute
+Playwright **requires an issue** for every contribution, except for minor documentation updates. We strongly recommend
+to pick an issue
+labeled [open-to-a-pull-request](https://github.com/microsoft/playwright/issues?q=is%3Aissue%20state%3Aopen%20label%3Aopen-to-a-pull-request)
+for your first contribution to the project.
-We strongly recommend that you open an issue before beginning any code modifications. This is particularly important if the changes involve complex logic or if the existing code isn't immediately clear. By doing so, we can discuss and agree upon the best approach to address a bug or implement a feature, ensuring that our efforts are aligned.
+If you are passionate about a bug/feature, but cannot find an issue describing it, **file an issue first**. This will
+facilitate the discussion, and you might get some early feedback from project maintainers before spending your time on
+creating a pull request.
-### Getting Code
-
-Make sure you're running Node.js 20 to verify and upgrade NPM do:
+## Make a change
+Make sure you're running Node.js 20 or later.
```bash
node --version
-npm --version
-npm i -g npm@latest
```
-1. Clone this repository
-
+Clone the repository. If you plan to send a pull request, it might be better to [fork the repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo) first.
```bash
git clone https://github.com/microsoft/playwright
cd playwright
```
-2. Install dependencies
-
+Install dependencies and run the build in watch mode.
```bash
npm ci
+npm run watch
+npx playwright install
```
-3. Build Playwright
+**Experimental dev mode with Hot Module Replacement for recorder/trace-viewer/UI Mode**
-```bash
-npm run build
+```
+PW_HMR=1 npm run watch
+PW_HMR=1 npx playwright show-trace
+PW_HMR=1 npm run ctest -- --ui
+PW_HMR=1 npx playwright codegen
+PW_HMR=1 npx playwright show-report
```
-4. Run tests
+Playwright is a multi-package repository that uses npm workspaces. For browser APIs, look at [`packages/playwright-core`](https://github.com/microsoft/playwright/blob/main/packages/playwright-core). For test runner, see [`packages/playwright`](https://github.com/microsoft/playwright/blob/main/packages/playwright).
-This will run a test on line `23` in `page-fill.spec.ts`:
+Note that some files are generated by the build, so the watch process might override your changes if done in the wrong file. For example, TypeScript types for the API are generated from the [`docs/src`](https://github.com/microsoft/playwright/blob/main/docs/src).
-```bash
-npm run ctest -- page-fill:23
-```
+Coding style is fully defined in [eslint.config.mjs](https://github.com/microsoft/playwright/blob/main/eslint.config.mjs). Before creating a pull request, or at any moment during development, run linter to check all kinds of things:
+ ```bash
+ npm run lint
+ ```
-See [here](#running--writing-tests) for more information about running and writing tests.
+Comments should have an explicit purpose and should improve readability rather than hinder it. If the code would not be understood without comments, consider re-writing the code to make it self-explanatory.
-### Code reviews
+### Write documentation
-All submissions, including submissions by project members, require review. We
-use GitHub pull requests for this purpose. Consult
-[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
-information on using pull requests.
+Every part of the public API should be documented in [`docs/src`](https://github.com/microsoft/playwright/blob/main/docs/src), in the same change that adds/changes the API. We use markdown files with custom structure to specify the API. Take a look around for an example.
-### Code Style
+Various other files are generated from the API specification. If you are running `npm run watch`, these will be re-generated automatically.
-- Coding style is fully defined in [.eslintrc](https://github.com/microsoft/playwright/blob/main/.eslintrc.js)
-- Comments should be generally avoided. If the code would not be understood without comments, consider re-writing the code to make it self-explanatory.
+Larger changes will require updates to the documentation guides as well. This will be made clear during the code review.
-To run code linter, use:
+## Add a test
-```bash
-npm run eslint
-```
+Playwright requires a test for almost any new or modified functionality. An exception would be a pure refactoring, but chances are you are doing more than that.
+
+There are multiple [test suites](https://github.com/microsoft/playwright/blob/main/tests) in Playwright that will be executed on the CI. The two most important that you need to run locally are:
-### API guidelines
+- Library tests cover APIs not related to the test runner.
+ ```bash
+ # fast path runs all tests in Chromium
+ npm run ctest
-When authoring new API methods, consider the following:
+ # slow path runs all tests in three browsers
+ npm run test
+ ```
-- Expose as little information as needed. When in doubt, don’t expose new information.
-- Methods are used in favor of getters/setters.
- - The only exception is namespaces, e.g. `page.keyboard` and `page.coverage`
-- All string literals must be lowercase. This includes event names and option values.
-- Avoid adding "sugar" API (API that is trivially implementable in user-space) unless they're **very** common.
+- Test runner tests.
+ ```bash
+ npm run ttest
+ ```
-### Commit Messages
+Since Playwright tests are using Playwright under the hood, everything from our documentation applies, for example [this guide on running and debugging tests](https://playwright.dev/docs/running-tests#running-tests).
-Commit messages should follow the Semantic Commit Messages format:
+Note that tests should be *hermetic*, and not depend on external services. Tests should work on all three platforms: macOS, Linux and Windows.
+
+## Write a commit message
+
+Commit messages should follow the [Semantic Commit Messages](https://www.conventionalcommits.org/en/v1.0.0/) format:
```
label(namespace): title
@@ -97,129 +97,59 @@ footer
```
1. *label* is one of the following:
- - `fix` - playwright bug fixes.
- - `feat` - playwright features.
- - `docs` - changes to docs, e.g. `docs(api): ..` to change documentation.
- - `test` - changes to playwright tests infrastructure.
- - `devops` - build-related work, e.g. CI related patches and general changes to the browser build infrastructure
+ - `fix` - bug fixes
+ - `feat` - new features
+ - `docs` - documentation-only changes
+ - `test` - test-only changes
+ - `devops` - changes to the CI or build
- `chore` - everything that doesn't fall under previous categories
-2. *namespace* is put in parenthesis after label and is optional. Must be lowercase.
+2. *namespace* is put in parentheses after label and is optional. Must be lowercase.
3. *title* is a brief summary of changes.
4. *description* is **optional**, new-line separated from title and is in present tense.
-5. *footer* is **optional**, new-line separated from *description* and contains "fixes" / "references" attribution to github issues.
+5. *footer* is **optional**, new-line separated from *description* and contains "fixes" / "references" attribution to GitHub issues.
Example:
```
-fix(firefox): make sure session cookies work
-
-This patch fixes session cookies in the firefox browser.
-
-Fixes #123, fixes #234
-```
-
-### Writing Documentation
-
-All API classes, methods, and events should have a description in [`docs/src`](https://github.com/microsoft/playwright/blob/main/docs/src). There's a [documentation linter](https://github.com/microsoft/playwright/tree/main/utils/doclint) which makes sure documentation is aligned with the codebase.
-
-To run the documentation linter, use:
-
-```bash
-npm run doc
-```
-
-To build the documentation site locally and test how your changes will look in practice:
-
-1. Clone the [microsoft/playwright.dev](https://github.com/microsoft/playwright.dev) repo
-1. Follow [the playwright.dev README instructions to "roll docs"](https://github.com/microsoft/playwright.dev/#roll-docs) against your local `playwright` repo with your changes in progress
-1. Follow [the playwright.dev README instructions to "run dev server"](https://github.com/microsoft/playwright.dev/#run-dev-server) to view your changes
-
-### Adding New Dependencies
-
-For all dependencies (both installation and development):
-- **Do not add** a dependency if the desired functionality is easily implementable.
-- If adding a dependency, it should be well-maintained and trustworthy.
-
-A barrier for introducing new installation dependencies is especially high:
-- **Do not add** installation dependency unless it's critical to project success.
-
-### Running & Writing Tests
-
-- Every feature should be accompanied by a test.
-- Every public api event/method should be accompanied by a test.
-- Tests should be *hermetic*. Tests should not depend on external services.
-- Tests should work on all three platforms: Mac, Linux and Win. This is especially important for screenshot tests.
-
-Playwright tests are located in [`tests`](https://github.com/microsoft/playwright/blob/main/tests) and use `@playwright/test` test runner.
-These are integration tests, making sure public API methods and events work as expected.
-
-- To run all tests:
-
-```bash
-npx playwright install
-npm run test
-```
+feat(trace viewer): network panel filtering
-Be sure to run `npm run build` or let `npm run watch` run before you re-run the
-tests after making your changes to check them.
+This patch adds a filtering toolbar to the network panel.
+
-- To run tests in Chromium
-```bash
-npm run ctest # also `ftest` for firefox and `wtest` for WebKit
-npm run ctest -- page-fill:23 # runs line 23 of page-fill.spec.ts
+Fixes #123, references #234.
```
-To run tests in WebKit / Firefox, use `wtest` or `ftest`.
+## Send a pull request
-- To run the Playwright test runner tests
-```bash
-npm run ttest
-npm run ttest -- --grep "specific test"
-```
+All submissions, including submissions by project members, require review. We use GitHub pull requests for this purpose.
+Make sure to keep your PR (diff) small and readable. If necessary, split your contribution into multiple PRs.
+Consult [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more information on using pull requests.
-- To run a specific test, substitute `it` with `it.only`, or use the `--grep 'My test'` CLI parameter:
-
-```js
-...
-// Using "it.only" to run a specific test
-it.only('should work', async ({server, page}) => {
- const response = await page.goto(server.EMPTY_PAGE);
- expect(response.ok).toBe(true);
-});
-// or
-playwright test --config=xxx --grep 'should work'
-```
+After a successful code review, one of the maintainers will merge your pull request. Congratulations!
-- To disable a specific test, substitute `it` with `it.skip`:
+## More details
-```js
-...
-// Using "it.skip" to skip a specific test
-it.skip('should work', async ({server, page}) => {
- const response = await page.goto(server.EMPTY_PAGE);
- expect(response.ok).toBe(true);
-});
-```
+**No new dependencies**
-- To run tests in non-headless (headed) mode:
+There is a very high bar for new dependencies, including updating to a new version of an existing dependency. We recommend to explicitly discuss this in an issue and get a green light from a maintainer, before creating a pull request that updates dependencies.
-```bash
-npm run ctest -- --headed
-```
-
-- To run tests with custom browser executable, specify `CRPATH`, `WKPATH` or `FFPATH` env variable that points to browser executable:
+**Custom browser build**
+To run tests with custom browser executable, specify `CRPATH`, `WKPATH` or `FFPATH` env variable that points to browser executable:
```bash
CRPATH= npm run ctest
```
-- When should a test be marked with `skip` or `fixme`?
+You will also find `DEBUG=pw:browser` useful for debugging custom-builds.
+
+**Building documentation site**
- - **`skip(condition)`**: This test *should ***never*** work* for `condition`
- where `condition` is usually something like: `test.skip(browserName === 'chromium', 'This does not work because of ...')`.
+The [playwright.dev](https://playwright.dev/) documentation site lives in a separate repository, and documentation from [`docs/src`](https://github.com/microsoft/playwright/blob/main/docs/src) is frequently rolled there.
- - **`fixme(condition)`**: This test *should ***eventually*** work* for `condition`
- where `condition` is usually something like: `test.fixme(browserName === 'chromium', 'We are waiting for version x')`.
+Most of the time this should not concern you. However, if you are doing something unusual in the docs, you can build locally and test how your changes will look in practice:
+1. Clone the [microsoft/playwright.dev](https://github.com/microsoft/playwright.dev) repo.
+1. Follow [the playwright.dev README instructions to "roll docs"](https://github.com/microsoft/playwright.dev/#roll-docs) against your local `playwright` repo with your changes in progress.
+1. Follow [the playwright.dev README instructions to "run dev server"](https://github.com/microsoft/playwright.dev/#run-dev-server) to view your changes.
## Contributor License Agreement
diff --git a/FILING_ISSUES.md b/FILING_ISSUES.md
new file mode 100644
index 0000000000000..b699cd2e50440
--- /dev/null
+++ b/FILING_ISSUES.md
@@ -0,0 +1,35 @@
+# How to File a Bug Report That Actually Gets Resolved
+
+Make sure you’re on the latest Playwright release before filing. Check existing GitHub issues to avoid duplicates.
+
+## Use the Template
+
+Follow the **Bug Report** template. It guides you step-by-step:
+
+- Fill it out thoroughly.
+- Clearly list the steps needed to reproduce the bug.
+- Provide what you expected to see versus what happened in reality.
+- Include system info from `npx envinfo --preset playwright`.
+
+## Keep Your Repro Minimal
+
+We can't parse your entire code base. Reduce it down to the absolute essentials:
+
+- Start a fresh project (`npm init playwright@latest new-project`).
+- Add only the code/DOM needed to show the problem.
+- Only use major frameworks if necessary (React, Angular, static HTTP server, etc.).
+- Avoid adding extra libraries unless absolutely necessary. Note that we won't install any suspect dependencies.
+
+## Why This Matters
+- Most issues that lack a repro turn out to be misconfigurations or usage errors.
+- We can't fix problems if we can’t reproduce them ourselves.
+- We can’t debug entire private projects or handle sensitive credentials.
+- Each confirmed bug will have a test in our repo, so your repro must be as clean as possible.
+
+## More Help
+
+- [Stack Overflow’s Minimal Reproducible Example Guide](https://stackoverflow.com/help/minimal-reproducible-example)
+- [Playwright Debugging Tools](https://playwright.dev/docs/debug)
+
+## Bottom Line
+A well-isolated bug speeds up verification and resolution. Minimal, public repro or it’s unlikely we can assist.
diff --git a/README.md b/README.md
index 3e2add10dcaeb..445b4613e4944 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# 🎭 Playwright
-[](https://www.npmjs.com/package/playwright) [](https://www.chromium.org/Home) [](https://www.mozilla.org/en-US/firefox/new/) [](https://webkit.org/)
+[](https://www.npmjs.com/package/playwright) [](https://www.chromium.org/Home) [](https://www.mozilla.org/en-US/firefox/new/) [](https://webkit.org/) [](https://aka.ms/playwright/discord)
## [Documentation](https://playwright.dev) | [API reference](https://playwright.dev/docs/api/class-playwright)
@@ -8,9 +8,9 @@ Playwright is a framework for Web Testing and Automation. It allows testing [Chr
| | Linux | macOS | Windows |
| :--- | :---: | :---: | :---: |
-| Chromium 128.0.6613.7 | :white_check_mark: | :white_check_mark: | :white_check_mark: |
-| WebKit 18.0 | :white_check_mark: | :white_check_mark: | :white_check_mark: |
-| Firefox 128.0 | :white_check_mark: | :white_check_mark: | :white_check_mark: |
+| Chromium 140.0.7339.186 | :white_check_mark: | :white_check_mark: | :white_check_mark: |
+| WebKit 26.0 | :white_check_mark: | :white_check_mark: | :white_check_mark: |
+| Firefox 141.0 | :white_check_mark: | :white_check_mark: | :white_check_mark: |
Headless execution is supported for all browsers on all platforms. Check out [system requirements](https://playwright.dev/docs/intro#system-requirements) for details.
@@ -46,7 +46,6 @@ npx playwright install
You can optionally install only selected browsers, see [install browsers](https://playwright.dev/docs/cli#install-browsers) for more details. Or you can install no browsers at all and use existing [browser channels](https://playwright.dev/docs/browsers).
* [Getting started](https://playwright.dev/docs/intro)
-* [Installation configuration](https://playwright.dev/docs/installation)
* [API reference](https://playwright.dev/docs/api/class-playwright)
## Capabilities
@@ -163,7 +162,7 @@ test('Intercept network requests', async ({ page }) => {
## Resources
-* [Documentation](https://playwright.dev/docs/intro)
+* [Documentation](https://playwright.dev)
* [API reference](https://playwright.dev/docs/api/class-playwright/)
* [Contribution guide](CONTRIBUTING.md)
* [Changelog](https://github.com/microsoft/playwright/releases)
diff --git a/SUPPORT.md b/SUPPORT.md
new file mode 100644
index 0000000000000..78cb929fb1bd4
--- /dev/null
+++ b/SUPPORT.md
@@ -0,0 +1,17 @@
+# Support
+
+## How to file issues and get help
+
+This project uses GitHub issues to track bugs and feature requests. Please search the [existing issues][gh-issues] before filing new ones to avoid duplicates. For new issues, file your bug or feature request as a new issue using corresponding template.
+
+For help and questions about using this project, please see the [docs site for Playwright][docs].
+
+Join our community [Discord Server][discord-server] to connect with other developers using Playwright and ask questions in our 'help-playwright' forum.
+
+## Microsoft Support Policy
+
+Support for Playwright is limited to the resources listed above.
+
+[gh-issues]: https://github.com/microsoft/playwright/issues/
+[docs]: https://playwright.dev/
+[discord-server]: https://aka.ms/playwright/discord
diff --git a/babel.config.json b/babel.config.json
deleted file mode 100644
index 3e345f427474a..0000000000000
--- a/babel.config.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "assumptions": {
- "setPublicClassFields": true
- },
- "plugins": [
- ["@babel/plugin-transform-typescript", { "allowDeclareFields": true } ],
- "@babel/plugin-transform-export-namespace-from",
- "@babel/plugin-transform-class-properties",
- "@babel/plugin-transform-logical-assignment-operators",
- "@babel/plugin-transform-nullish-coalescing-operator",
- "@babel/plugin-transform-optional-chaining",
- "@babel/plugin-transform-modules-commonjs"
- ],
- "ignore": [
- "**/*.d.ts"
- ]
-}
diff --git a/browser_patches/firefox/UPSTREAM_CONFIG.sh b/browser_patches/firefox/UPSTREAM_CONFIG.sh
index 10889141a731d..0513b8920832a 100644
--- a/browser_patches/firefox/UPSTREAM_CONFIG.sh
+++ b/browser_patches/firefox/UPSTREAM_CONFIG.sh
@@ -1,3 +1,3 @@
-REMOTE_URL="https://github.com/mozilla/gecko-dev"
+REMOTE_URL="https://github.com/mozilla-firefox/firefox"
BASE_BRANCH="release"
-BASE_REVISION="bd7e0ac24a6fb1cddde3e45ea191b7abcc90cf56"
+BASE_REVISION="00656c9425c51ee035578ca6ebebe13c755b0375"
diff --git a/browser_patches/firefox/juggler/Helper.js b/browser_patches/firefox/juggler/Helper.js
index f5a64d6c8bc33..875dd5ac2e8b3 100644
--- a/browser_patches/firefox/juggler/Helper.js
+++ b/browser_patches/firefox/juggler/Helper.js
@@ -4,9 +4,9 @@
const uuidGen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
-class Helper {
+export class Helper {
decorateAsEventEmitter(objectToDecorate) {
- const { EventEmitter } = ChromeUtils.import('resource://gre/modules/EventEmitter.jsm');
+ const { EventEmitter } = ChromeUtils.importESModule('resource://gre/modules/EventEmitter.sys.mjs');
const emitter = new EventEmitter();
objectToDecorate.on = emitter.on.bind(emitter);
objectToDecorate.addEventListener = emitter.on.bind(emitter);
@@ -172,7 +172,7 @@ class Helper {
const helper = new Helper();
-class EventWatcher {
+export class EventWatcher {
constructor(receiver, eventNames, pendingEventWatchers = new Set()) {
this._pendingEventWatchers = pendingEventWatchers;
this._pendingEventWatchers.add(this);
@@ -233,7 +233,3 @@ class EventWatcher {
}
}
-var EXPORTED_SYMBOLS = [ "Helper", "EventWatcher" ];
-this.Helper = Helper;
-this.EventWatcher = EventWatcher;
-
diff --git a/browser_patches/firefox/juggler/JugglerFrameParent.jsm b/browser_patches/firefox/juggler/JugglerFrameParent.jsm
index e621fab240680..9c3b58898955e 100644
--- a/browser_patches/firefox/juggler/JugglerFrameParent.jsm
+++ b/browser_patches/firefox/juggler/JugglerFrameParent.jsm
@@ -1,13 +1,11 @@
"use strict";
-const { TargetRegistry } = ChromeUtils.import('chrome://juggler/content/TargetRegistry.js');
-const { Helper } = ChromeUtils.import('chrome://juggler/content/Helper.js');
+const { TargetRegistry } = ChromeUtils.importESModule('chrome://juggler/content/TargetRegistry.js');
+const { Helper } = ChromeUtils.importESModule('chrome://juggler/content/Helper.js');
const helper = new Helper();
-var EXPORTED_SYMBOLS = ['JugglerFrameParent'];
-
-class JugglerFrameParent extends JSWindowActorParent {
+export class JugglerFrameParent extends JSWindowActorParent {
constructor() {
super();
}
diff --git a/browser_patches/firefox/juggler/NetworkObserver.js b/browser_patches/firefox/juggler/NetworkObserver.js
index 8eb69d813360e..c063e0484d71b 100644
--- a/browser_patches/firefox/juggler/NetworkObserver.js
+++ b/browser_patches/firefox/juggler/NetworkObserver.js
@@ -4,9 +4,9 @@
"use strict";
-const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
-const {NetUtil} = ChromeUtils.import('resource://gre/modules/NetUtil.jsm');
-const { ChannelEventSinkFactory } = ChromeUtils.import("chrome://remote/content/cdp/observers/ChannelEventSink.jsm");
+const {Helper} = ChromeUtils.importESModule('chrome://juggler/content/Helper.js');
+const {NetUtil} = ChromeUtils.importESModule('resource://gre/modules/NetUtil.sys.mjs');
+const { ChannelEventSinkFactory } = ChromeUtils.importESModule("chrome://remote/content/cdp/observers/ChannelEventSink.sys.mjs");
const Cc = Components.classes;
@@ -28,7 +28,7 @@ const MAX_RESPONSE_STORAGE_SIZE = 100 * 1024 * 1024;
const pageNetworkSymbol = Symbol('PageNetwork');
-class PageNetwork {
+export class PageNetwork {
static forPageTarget(target) {
if (!target)
return undefined;
@@ -143,12 +143,16 @@ class NetworkRequest {
const target = this._networkObserver._targetRegistry.targetForBrowserId(browsingContext.browserId);
this._pageNetwork = PageNetwork.forPageTarget(target);
}
- this._expectingInterception = false;
+ this._shouldYieldInterceptionToServiceWorker = false;
this._expectingResumedRequest = undefined; // { method, headers, postData }
+ this._overriddenHeadersForRedirect = redirectedFrom?._overriddenHeadersForRedirect;
+ this._sentOnRequest = false;
this._sentOnResponse = false;
this._fulfilled = false;
- if (this._pageNetwork)
+ if (this._overriddenHeadersForRedirect)
+ overrideRequestHeaders(httpChannel, this._overriddenHeadersForRedirect);
+ else if (this._pageNetwork)
appendExtraHTTPHeaders(httpChannel, this._pageNetwork.combinedExtraHTTPHeaders());
this._responseBodyChunks = [];
@@ -201,11 +205,13 @@ class NetworkRequest {
this._interceptedChannel.synthesizeHeader(header.name, header.value);
if (header.name.toLowerCase() === 'set-cookie') {
Services.cookies.QueryInterface(Ci.nsICookieService);
- Services.cookies.setCookieStringFromHttp(this.httpChannel.URI, header.value, this.httpChannel);
+ for (const cookieString of header.value.split('\n'))
+ Services.cookies.setCookieStringFromHttp(this.httpChannel.URI, cookieString, this.httpChannel);
}
}
const synthesized = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
- synthesized.data = base64body ? atob(base64body) : '';
+ if (base64body)
+ synthesized.setByteStringData(atob(base64body));
this._interceptedChannel.startSynthesizedResponse(synthesized, null, null, '', false);
this._interceptedChannel.finishSynthesizedResponse();
this._interceptedChannel = undefined;
@@ -230,20 +236,13 @@ class NetworkRequest {
if (!this._expectingResumedRequest)
return;
const { method, headers, postData } = this._expectingResumedRequest;
+ this._overriddenHeadersForRedirect = headers;
this._expectingResumedRequest = undefined;
- if (headers) {
- for (const header of requestHeaders(this.httpChannel)) {
- // We cannot remove the "host" header.
- if (header.name.toLowerCase() === 'host')
- continue;
- this.httpChannel.setRequestHeader(header.name, '', false /* merge */);
- }
- for (const header of headers)
- this.httpChannel.setRequestHeader(header.name, header.value, false /* merge */);
- } else if (this._pageNetwork) {
+ if (headers)
+ overrideRequestHeaders(this.httpChannel, headers);
+ else if (this._pageNetwork)
appendExtraHTTPHeaders(this.httpChannel, this._pageNetwork.combinedExtraHTTPHeaders());
- }
if (method)
this.httpChannel.requestMethod = method;
if (postData !== undefined)
@@ -320,9 +319,8 @@ class NetworkRequest {
const interceptController = this._fallThroughInterceptController();
if (interceptController && interceptController.shouldPrepareForIntercept(aURI, channel)) {
// We assume that interceptController is a service worker if there is one,
- // and yield interception to it. We are not going to intercept ourselves,
- // so we send onRequest now.
- this._sendOnRequest(false);
+ // and yield interception to it.
+ this._shouldYieldInterceptionToServiceWorker = true;
return true;
}
@@ -331,12 +329,6 @@ class NetworkRequest {
return false;
}
- // We do not want to intercept any redirects, because we are not able
- // to intercept subresource redirects, and it's unreliable for main requests.
- // We do not sendOnRequest here, because redirects do that in constructor.
- if (this.redirectedFromId)
- return false;
-
const shouldIntercept = this._shouldIntercept();
if (!shouldIntercept) {
// We are not intercepting - ready to issue onRequest.
@@ -344,21 +336,24 @@ class NetworkRequest {
return false;
}
- this._expectingInterception = true;
return true;
}
// nsINetworkInterceptController
channelIntercepted(intercepted) {
- if (!this._expectingInterception) {
- // We are not intercepting, fall-through.
- const interceptController = this._fallThroughInterceptController();
- if (interceptController)
- interceptController.channelIntercepted(intercepted);
+ // Yield to a service worker if determined so in shouldPrepareForIntercept().
+ const serviceWorker = this._shouldYieldInterceptionToServiceWorker ? this._fallThroughInterceptController() : undefined;
+ // Clear the flag to avoid an infinite loop. After service worker, we should intercept ourselves.
+ this._shouldYieldInterceptionToServiceWorker = false;
+
+ if (serviceWorker) {
+ const interceptedChannel = intercepted.QueryInterface(Ci.nsIInterceptedChannel);
+ // If service worker will not actually intercept the request, we want to be called again.
+ interceptedChannel.interceptAfterServiceWorkerResets();
+ serviceWorker.channelIntercepted(intercepted);
return;
}
- this._expectingInterception = false;
this._interceptedChannel = intercepted.QueryInterface(Ci.nsIInterceptedChannel);
const pageNetwork = this._pageNetwork;
@@ -412,6 +407,7 @@ class NetworkRequest {
// See https://github.com/microsoft/playwright/issues/9418#issuecomment-944836244
if (aRequest !== this.httpChannel)
return;
+ this._sendOnRequest(false);
try {
this._originalListener.onStartRequest(aRequest);
} catch (e) {
@@ -449,6 +445,10 @@ class NetworkRequest {
}
_shouldIntercept() {
+ // We do not want to intercept any redirects, because we are not able
+ // to intercept subresource redirects, and it's unreliable for main requests.
+ if (this.redirectedFromId)
+ return false;
const pageNetwork = this._pageNetwork;
if (!pageNetwork)
return false;
@@ -469,8 +469,15 @@ class NetworkRequest {
}
_sendOnRequest(isIntercepted) {
- // Note: we call _sendOnRequest either after we intercepted the request,
- // or at the first moment we know that we are not going to intercept.
+ if (this._sentOnRequest) {
+ // We can come here twice because:
+ // - Redirects call _sendOnRequest in the constructor and from inside interception.
+ // - All other requests might call _sendOnRequest from onStartRequest and from inside interception.
+ // - All requests call _sendOnRequest from _sendOnResponse to avoid responses without requests.
+ return;
+ }
+ this._sentOnRequest = true;
+
const pageNetwork = this._pageNetwork;
if (!pageNetwork)
return;
@@ -493,11 +500,21 @@ class NetworkRequest {
}
_sendOnResponse(fromCache, opt_statusCode, opt_statusText) {
+ // For internal redirects, and perhaps something else that we lack test coverage for,
+ // we can arrive here before onStartRequest has fired. Make sure we
+ // notify about the request first.
+ this._sendOnRequest(false);
+
if (this._sentOnResponse) {
- // We can come here twice because of internal redirects, e.g. service workers.
+ // We can come here twice because of an internal redirect, for example:
+ // - request was intercepted by a service worker;
+ // - HSTS redirect;
+ // - CORS preflight;
+ // - who knows what else?
return;
}
this._sentOnResponse = true;
+
const pageNetwork = this._pageNetwork;
if (!pageNetwork)
return;
@@ -516,6 +533,8 @@ class NetworkRequest {
};
const { status, statusText, headers } = responseHead(this.httpChannel, opt_statusCode, opt_statusText);
+ if (redirectStatus.includes(status) && this._overriddenHeadersForRedirect)
+ this._overriddenHeadersForRedirect = filterHeadersForRedirect(this._overriddenHeadersForRedirect, this.httpChannel.requestMethod, status);
let remoteIPAddress = undefined;
let remotePort = undefined;
try {
@@ -578,7 +597,7 @@ class NetworkRequest {
}
}
-class NetworkObserver {
+export class NetworkObserver {
static instance() {
return NetworkObserver._instance || null;
}
@@ -602,6 +621,8 @@ class NetworkObserver {
proxyFilter.onProxyFilterResult(defaultProxyInfo);
return;
}
+ if (this._targetRegistry.shouldBustHTTPAuthCacheForProxy(proxy))
+ Services.obs.notifyObservers(null, "net:clear-active-logins");
proxyFilter.onProxyFilterResult(protocolProxyService.newProxyInfo(
proxy.type,
proxy.host,
@@ -771,6 +792,36 @@ function requestHeaders(httpChannel) {
return headers;
}
+function clearRequestHeaders(httpChannel) {
+ for (const header of requestHeaders(httpChannel)) {
+ // We cannot remove the "host" header.
+ if (header.name.toLowerCase() === 'host')
+ continue;
+ // Keep the "cookie" header. If there is an override, it will be set anyway.
+ // Otherwise, we may delete a cookie that was set for a redirect.
+ if (header.name.toLowerCase() === 'cookie')
+ continue;
+ httpChannel.setRequestHeader(header.name, '', false /* merge */);
+ }
+}
+
+function overrideRequestHeaders(httpChannel, headers) {
+ clearRequestHeaders(httpChannel);
+ appendExtraHTTPHeaders(httpChannel, headers);
+}
+
+const redirectStatus = [301, 302, 303, 307, 308];
+
+function filterHeadersForRedirect(headers, requestMethod, status) {
+ // HTTP-redirect fetch step 13 (https://fetch.spec.whatwg.org/#http-redirect-fetch)
+ if ((status === 301 || status === 302) && requestMethod === 'POST' ||
+ status === 303 && !['GET', 'HEAD'].includes(requestMethod)) {
+ const requestBodyHeaders = ['content-encoding', 'content-language', 'content-length', 'content-location', 'content-type'];
+ return headers.filter(header => !requestBodyHeaders.includes(header.name.toLowerCase()));
+ }
+ return headers;
+}
+
function causeTypeToString(causeType) {
for (let key in Ci.nsIContentPolicy) {
if (Ci.nsIContentPolicy[key] === causeType)
@@ -858,7 +909,7 @@ function setPostData(httpChannel, postData, headers) {
return;
const synthesized = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
const body = atob(postData);
- synthesized.setData(body, body.length);
+ synthesized.setByteStringData(body);
const overriddenHeader = (lowerCaseName) => {
if (headers) {
@@ -890,7 +941,7 @@ function convertString(s, source, dest) {
const is = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
Ci.nsIStringInputStream
);
- is.setData(s, s.length);
+ is.setByteStringData(s);
const listener = Cc["@mozilla.org/network/stream-loader;1"].createInstance(
Ci.nsIStreamLoader
);
@@ -950,6 +1001,3 @@ PageNetwork.Events = {
RequestFailed: Symbol('PageNetwork.Events.RequestFailed'),
};
-var EXPORTED_SYMBOLS = ['NetworkObserver', 'PageNetwork'];
-this.NetworkObserver = NetworkObserver;
-this.PageNetwork = PageNetwork;
diff --git a/browser_patches/firefox/juggler/SimpleChannel.js b/browser_patches/firefox/juggler/SimpleChannel.js
index a4e1b19df4c6d..cc555451cdd49 100644
--- a/browser_patches/firefox/juggler/SimpleChannel.js
+++ b/browser_patches/firefox/juggler/SimpleChannel.js
@@ -79,7 +79,7 @@ class SimpleChannel {
_setTimeout(cb, timeout) {
// Lazy load on first call.
- this._setTimeout = ChromeUtils.import('resource://gre/modules/Timer.jsm').setTimeout;
+ this._setTimeout = ChromeUtils.importESModule('resource://gre/modules/Timer.sys.mjs').setTimeout;
this._setTimeout(cb, timeout);
}
@@ -251,6 +251,3 @@ class SimpleChannel {
}
}
}
-
-var EXPORTED_SYMBOLS = ['SimpleChannel'];
-this.SimpleChannel = SimpleChannel;
diff --git a/browser_patches/firefox/juggler/TargetRegistry.js b/browser_patches/firefox/juggler/TargetRegistry.js
index ea7b2afa4d734..4bdf162ab64f7 100644
--- a/browser_patches/firefox/juggler/TargetRegistry.js
+++ b/browser_patches/firefox/juggler/TargetRegistry.js
@@ -2,12 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
-const {SimpleChannel} = ChromeUtils.import('chrome://juggler/content/SimpleChannel.js');
-const {Preferences} = ChromeUtils.import("resource://gre/modules/Preferences.jsm");
-const {ContextualIdentityService} = ChromeUtils.import("resource://gre/modules/ContextualIdentityService.jsm");
-const {NetUtil} = ChromeUtils.import('resource://gre/modules/NetUtil.jsm');
-const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
+const {Helper} = ChromeUtils.importESModule('chrome://juggler/content/Helper.js');
+const {Preferences} = ChromeUtils.importESModule("resource://gre/modules/Preferences.sys.mjs");
+const {ContextualIdentityService} = ChromeUtils.importESModule("resource://gre/modules/ContextualIdentityService.sys.mjs");
+const {NetUtil} = ChromeUtils.importESModule('resource://gre/modules/NetUtil.sys.mjs');
+const {AppConstants} = ChromeUtils.importESModule("resource://gre/modules/AppConstants.sys.mjs");
const Cr = Components.results;
@@ -22,6 +21,9 @@ const ALL_PERMISSIONS = [
];
let globalTabAndWindowActivationChain = Promise.resolve();
+// This is a workaround for https://github.com/microsoft/playwright/issues/34586
+let didCreateFirstPage = false;
+let globalNewPageChain = Promise.resolve();
class DownloadInterceptor {
constructor(registry) {
@@ -102,7 +104,7 @@ class DownloadInterceptor {
const screencastService = Cc['@mozilla.org/juggler/screencast;1'].getService(Ci.nsIScreencastService);
-class TargetRegistry {
+export class TargetRegistry {
static instance() {
return TargetRegistry._instance || null;
}
@@ -116,6 +118,7 @@ class TargetRegistry {
this._browserToTarget = new Map();
this._browserIdToTarget = new Map();
+ this._proxiesWithClashingAuthCacheKeys = new Set();
this._browserProxy = null;
// Cleanup containers from previous runs (if any)
@@ -234,12 +237,50 @@ class TargetRegistry {
onOpenWindow(win);
}
+ // Firefox uses nsHttpAuthCache to cache authentication to the proxy.
+ // If we're provided with a single proxy with a multiple different authentications, then
+ // we should clear the nsHttpAuthCache on every request.
+ shouldBustHTTPAuthCacheForProxy(proxy) {
+ return this._proxiesWithClashingAuthCacheKeys.has(proxy);
+ }
+
+ _updateProxiesWithSameAuthCacheAndDifferentCredentials() {
+ const proxyIdToCredentials = new Map();
+ const allProxies = [...this._browserContextIdToBrowserContext.values()].map(bc => bc._proxy).filter(Boolean);
+ if (this._browserProxy)
+ allProxies.push(this._browserProxy);
+ const proxyAuthCacheKeyAndProxy = allProxies.map(proxy => [
+ JSON.stringify({
+ type: proxy.type,
+ host: proxy.host,
+ port: proxy.port,
+ }),
+ proxy,
+ ]);
+ this._proxiesWithClashingAuthCacheKeys.clear();
+
+ proxyAuthCacheKeyAndProxy.sort(([cacheKey1], [cacheKey2]) => cacheKey1 < cacheKey2 ? -1 : 1);
+ for (let i = 0; i < proxyAuthCacheKeyAndProxy.length - 1; ++i) {
+ const [cacheKey1, proxy1] = proxyAuthCacheKeyAndProxy[i];
+ const [cacheKey2, proxy2] = proxyAuthCacheKeyAndProxy[i + 1];
+ if (cacheKey1 !== cacheKey2)
+ continue;
+ if (proxy1.username === proxy2.username && proxy1.password === proxy2.password)
+ continue;
+ // `proxy1` and `proxy2` have the same caching key, but serve different credentials.
+ // We have to bust HTTP Auth Cache everytime there's a request that will use either of the proxies.
+ this._proxiesWithClashingAuthCacheKeys.add(proxy1);
+ this._proxiesWithClashingAuthCacheKeys.add(proxy2);
+ }
+ }
+
async cancelDownload(options) {
this._downloadInterceptor.cancelDownload(options.uuid);
}
setBrowserProxy(proxy) {
this._browserProxy = proxy;
+ this._updateProxiesWithSameAuthCacheAndDifferentCredentials();
}
getProxyInfo(channel) {
@@ -269,6 +310,16 @@ class TargetRegistry {
}
async newPage({browserContextId}) {
+ // When creating the very first page, we cannot create multiple in parallel.
+ // See https://github.com/microsoft/playwright/issues/34586.
+ if (didCreateFirstPage)
+ return this._newPageInternal({browserContextId});
+ const result = globalNewPageChain.then(() => this._newPageInternal({browserContextId}));
+ globalNewPageChain = result.catch(error => { /* swallow errors to keep chain running */ });
+ return result;
+ }
+
+ async _newPageInternal({browserContextId}) {
const browserContext = this.browserContextForId(browserContextId);
const features = "chrome,dialog=no,all";
// See _callWithURIToLoad in browser.js for the structure of window.arguments
@@ -317,6 +368,7 @@ class TargetRegistry {
if (await target.hasFailedToOverrideTimezone())
throw new Error('Failed to override timezone');
}
+ didCreateFirstPage = true;
return target.id();
}
@@ -333,7 +385,7 @@ class TargetRegistry {
}
}
-class PageTarget {
+export class PageTarget {
constructor(registry, win, tab, browserContext, opener) {
helper.decorateAsEventEmitter(this);
@@ -345,6 +397,7 @@ class PageTarget {
this._linkedBrowser = tab.linkedBrowser;
this._browserContext = browserContext;
this._viewportSize = undefined;
+ this._zoom = 1;
this._initialDPPX = this._linkedBrowser.browsingContext.overrideDPPX;
this._url = 'about:blank';
this._openerId = opener ? opener.id() : undefined;
@@ -354,7 +407,7 @@ class PageTarget {
this._videoRecordingInfo = undefined;
this._screencastRecordingInfo = undefined;
this._dialogs = new Map();
- this.forcedColors = 'no-override';
+ this.forcedColors = 'none';
this.disableCache = false;
this.mediumOverride = '';
this.crossProcessCookie = {
@@ -368,7 +421,7 @@ class PageTarget {
onLocationChange: (aWebProgress, aRequest, aLocation) => this._onNavigated(aLocation),
};
this._eventListeners = [
- helper.addObserver(this._updateModalDialogs.bind(this), 'tabmodal-dialog-loaded'),
+ helper.addObserver(this._updateModalDialogs.bind(this), 'common-dialog-loaded'),
helper.addProgressListener(tab.linkedBrowser, navigationListener, Ci.nsIWebProgress.NOTIFY_LOCATION),
helper.addEventListener(this._linkedBrowser, 'DOMModalDialogClosed', event => this._updateModalDialogs()),
helper.addEventListener(this._linkedBrowser, 'WillChangeBrowserRemoteness', event => this._willChangeBrowserRemoteness()),
@@ -457,9 +510,11 @@ class PageTarget {
this.updateUserAgent(browsingContext);
this.updatePlatform(browsingContext);
this.updateDPPXOverride(browsingContext);
+ this.updateZoom(browsingContext);
this.updateEmulatedMedia(browsingContext);
this.updateColorSchemeOverride(browsingContext);
this.updateReducedMotionOverride(browsingContext);
+ this.updateContrastOverride(browsingContext);
this.updateForcedColorsOverride(browsingContext);
this.updateForceOffline(browsingContext);
this.updateCacheDisabled(browsingContext);
@@ -495,11 +550,20 @@ class PageTarget {
}
updateDPPXOverride(browsingContext = undefined) {
- (browsingContext || this._linkedBrowser.browsingContext).overrideDPPX = this._browserContext.deviceScaleFactor || this._initialDPPX;
+ browsingContext ||= this._linkedBrowser.browsingContext;
+ const dppx = this._zoom * (this._browserContext.deviceScaleFactor || this._initialDPPX);
+ browsingContext.overrideDPPX = dppx;
+ }
+
+ async updateZoom(browsingContext = undefined) {
+ browsingContext ||= this._linkedBrowser.browsingContext;
+ // Update dpr first, and then UI zoom.
+ this.updateDPPXOverride(browsingContext);
+ browsingContext.fullZoom = this._zoom;
}
_updateModalDialogs() {
- const prompts = new Set(this._linkedBrowser.tabModalPromptBox ? this._linkedBrowser.tabModalPromptBox.listPrompts() : []);
+ const prompts = new Set(this._linkedBrowser.tabDialogBox.getContentDialogManager().dialogs.map(dialog => dialog.frameContentWindow.Dialog));
for (const dialog of this._dialogs.values()) {
if (!prompts.has(dialog.prompt())) {
this._dialogs.delete(dialog.id());
@@ -545,7 +609,7 @@ class PageTarget {
const toolbarTop = stackRect.y;
this._window.resizeBy(width - this._window.innerWidth, height + toolbarTop - this._window.innerHeight);
- await this._channel.connect('').send('awaitViewportDimensions', { width, height });
+ await this._channel.connect('').send('awaitViewportDimensions', { width: width / this._zoom, height: height / this._zoom });
} else {
this._linkedBrowser.style.removeProperty('width');
this._linkedBrowser.style.removeProperty('height');
@@ -557,8 +621,8 @@ class PageTarget {
const actualSize = this._linkedBrowser.getBoundingClientRect();
await this._channel.connect('').send('awaitViewportDimensions', {
- width: actualSize.width,
- height: actualSize.height,
+ width: actualSize.width / this._zoom,
+ height: actualSize.height / this._zoom,
});
}
}
@@ -590,13 +654,23 @@ class PageTarget {
(browsingContext || this._linkedBrowser.browsingContext).prefersReducedMotionOverride = this.reducedMotion || this._browserContext.reducedMotion || 'none';
}
+ setContrast(contrast) {
+ this.contrast = fromProtocolContrast(contrast);
+ this.updateContrastOverride();
+ }
+
+ updateContrastOverride(browsingContext = undefined) {
+ (browsingContext || this._linkedBrowser.browsingContext).prefersContrastOverride = this.contrast || this._browserContext.contrast || 'none';
+ }
+
setForcedColors(forcedColors) {
this.forcedColors = fromProtocolForcedColors(forcedColors);
this.updateForcedColorsOverride();
}
updateForcedColorsOverride(browsingContext = undefined) {
- (browsingContext || this._linkedBrowser.browsingContext).forcedColorsOverride = (this.forcedColors !== 'no-override' ? this.forcedColors : this._browserContext.forcedColors) || 'no-override';
+ const isActive = this.forcedColors === 'active' || this._browserContext.forcedColors === 'active';
+ (browsingContext || this._linkedBrowser.browsingContext).forcedColorsOverride = isActive ? 'active' : 'none';
}
async setInterceptFileChooserDialog(enabled) {
@@ -610,6 +684,14 @@ class PageTarget {
await this.updateViewportSize();
}
+ async setZoom(zoom) {
+ // This is default range from the ZoomManager.
+ if (zoom < 0.3 || zoom > 5)
+ throw new Error('Invalid zoom value, must be between 0.3 and 5');
+ this._zoom = zoom;
+ await this.updateZoom();
+ }
+
close(runBeforeUnload = false) {
this._gBrowser.removeTab(this._tab, {
skipPermitUnload: !runBeforeUnload,
@@ -816,11 +898,19 @@ function fromProtocolReducedMotion(reducedMotion) {
throw new Error('Unknown reduced motion: ' + reducedMotion);
}
+function fromProtocolContrast(contrast) {
+ if (contrast === 'more' || contrast === 'less' || contrast === 'custom' || contrast === 'no-preference')
+ return contrast;
+ if (contrast === null)
+ return undefined;
+ throw new Error('Unknown contrast: ' + contrast);
+}
+
function fromProtocolForcedColors(forcedColors) {
if (forcedColors === 'active' || forcedColors === 'none')
return forcedColors;
- if (forcedColors === null)
- return undefined;
+ if (!forcedColors)
+ return 'none';
throw new Error('Unknown forced colors: ' + forcedColors);
}
@@ -854,8 +944,9 @@ class BrowserContext {
this.forceOffline = false;
this.disableCache = false;
this.colorScheme = 'none';
- this.forcedColors = 'no-override';
+ this.forcedColors = 'none';
this.reducedMotion = 'none';
+ this.contrast = 'none';
this.videoRecordingOptions = undefined;
this.crossProcessCookie = {
initScripts: [],
@@ -882,6 +973,12 @@ class BrowserContext {
page.updateReducedMotionOverride();
}
+ setContrast(contrast) {
+ this.contrast = fromProtocolContrast(contrast);
+ for (const page of this.pages)
+ page.updateContrastOverride();
+ }
+
setForcedColors(forcedColors) {
this.forcedColors = fromProtocolForcedColors(forcedColors);
for (const page of this.pages)
@@ -906,12 +1003,14 @@ class BrowserContext {
}
this._registry._browserContextIdToBrowserContext.delete(this.browserContextId);
this._registry._userContextIdToBrowserContext.delete(this.userContextId);
+ this._registry._updateProxiesWithSameAuthCacheAndDifferentCredentials();
}
setProxy(proxy) {
// Clear AuthCache.
Services.obs.notifyObservers(null, "net:clear-active-logins");
this._proxy = proxy;
+ this._registry._updateProxiesWithSameAuthCacheAndDifferentCredentials();
}
setIgnoreHTTPSErrors(ignoreHTTPSErrors) {
@@ -1194,7 +1293,3 @@ TargetRegistry.Events = {
DownloadFinished: Symbol('TargetRegistry.Events.DownloadFinished'),
ScreencastStopped: Symbol('TargetRegistry.ScreencastStopped'),
};
-
-var EXPORTED_SYMBOLS = ['TargetRegistry', 'PageTarget'];
-this.TargetRegistry = TargetRegistry;
-this.PageTarget = PageTarget;
diff --git a/browser_patches/firefox/juggler/components/Juggler.js b/browser_patches/firefox/juggler/components/Juggler.js
index d919935fb50ac..6121c4d3928bc 100644
--- a/browser_patches/firefox/juggler/components/Juggler.js
+++ b/browser_patches/firefox/juggler/components/Juggler.js
@@ -2,16 +2,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-var EXPORTED_SYMBOLS = ["Juggler", "JugglerFactory"];
-
-const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-const {ComponentUtils} = ChromeUtils.import("resource://gre/modules/ComponentUtils.jsm");
-const {Dispatcher} = ChromeUtils.import("chrome://juggler/content/protocol/Dispatcher.js");
-const {BrowserHandler} = ChromeUtils.import("chrome://juggler/content/protocol/BrowserHandler.js");
-const {NetworkObserver} = ChromeUtils.import("chrome://juggler/content/NetworkObserver.js");
-const {TargetRegistry} = ChromeUtils.import("chrome://juggler/content/TargetRegistry.js");
-const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
-const {ActorManagerParent} = ChromeUtils.import('resource://gre/modules/ActorManagerParent.jsm');
+// Load SimpleChannel in browser-process global.
+Services.scriptloader.loadSubScript('chrome://juggler/content/SimpleChannel.js');
+
+const {XPCOMUtils} = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs");
+const {ComponentUtils} = ChromeUtils.importESModule("resource://gre/modules/ComponentUtils.sys.mjs");
+const {Dispatcher} = ChromeUtils.importESModule("chrome://juggler/content/protocol/Dispatcher.js");
+const {BrowserHandler} = ChromeUtils.importESModule("chrome://juggler/content/protocol/BrowserHandler.js");
+const {NetworkObserver} = ChromeUtils.importESModule("chrome://juggler/content/NetworkObserver.js");
+const {TargetRegistry} = ChromeUtils.importESModule("chrome://juggler/content/TargetRegistry.js");
+const {Helper} = ChromeUtils.importESModule('chrome://juggler/content/Helper.js');
+const {ActorManagerParent} = ChromeUtils.importESModule('resource://gre/modules/ActorManagerParent.sys.mjs');
const helper = new Helper();
const Cc = Components.classes;
@@ -21,10 +22,10 @@ const Ci = Components.interfaces;
ActorManagerParent.addJSWindowActors({
JugglerFrame: {
parent: {
- moduleURI: 'chrome://juggler/content/JugglerFrameParent.jsm',
+ esModuleURI: 'chrome://juggler/content/JugglerFrameParent.jsm',
},
child: {
- moduleURI: 'chrome://juggler/content/content/JugglerFrameChild.jsm',
+ esModuleURI: 'chrome://juggler/content/content/JugglerFrameChild.jsm',
events: {
// Normally, we instantiate an actor when a new window is created.
DOMWindowCreated: {},
@@ -45,7 +46,7 @@ ActorManagerParent.addJSWindowActors({
let browserStartupFinishedCallback;
let browserStartupFinishedPromise = new Promise(x => browserStartupFinishedCallback = x);
-class Juggler {
+export class Juggler {
get classDescription() { return "Sample command-line handler"; }
get classID() { return Components.ID('{f7a74a33-e2ab-422d-b022-4fb213dd2639}'); }
get contractID() { return "@mozilla.org/remote/juggler;1" }
@@ -105,7 +106,10 @@ class Juggler {
};
// Force create hidden window here, otherwise its creation later closes the web socket!
- Services.appShell.hiddenDOMWindow;
+ // Since https://phabricator.services.mozilla.com/D219834, hiddenDOMWindow is only available on MacOS.
+ if (Services.appShell.hasHiddenWindow) {
+ Services.appShell.hiddenDOMWindow;
+ }
let pipeStopped = false;
let browserHandler;
@@ -151,7 +155,7 @@ class Juggler {
const jugglerInstance = new Juggler();
// This is used by the XPCOM codepath which expects a constructor
-var JugglerFactory = function() {
+export var JugglerFactory = function() {
return jugglerInstance;
};
diff --git a/browser_patches/firefox/juggler/components/components.conf b/browser_patches/firefox/juggler/components/components.conf
index e5bc6523b10cd..955b38ab9ccec 100644
--- a/browser_patches/firefox/juggler/components/components.conf
+++ b/browser_patches/firefox/juggler/components/components.conf
@@ -11,7 +11,7 @@ Classes = [
"command-line-handler": "m-remote",
"profile-after-change": "Juggler",
},
- "jsm": "chrome://juggler/content/components/Juggler.js",
+ "esModule": "chrome://juggler/content/components/Juggler.js",
"constructor": "JugglerFactory",
},
]
diff --git a/browser_patches/firefox/juggler/content/FrameTree.js b/browser_patches/firefox/juggler/content/FrameTree.js
index 2d59b3c43aa23..09a95b3548df9 100644
--- a/browser_patches/firefox/juggler/content/FrameTree.js
+++ b/browser_patches/firefox/juggler/content/FrameTree.js
@@ -7,13 +7,11 @@ const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
-const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
-const {SimpleChannel} = ChromeUtils.import('chrome://juggler/content/SimpleChannel.js');
-const {Runtime} = ChromeUtils.import('chrome://juggler/content/content/Runtime.js');
+const {Helper} = ChromeUtils.importESModule('chrome://juggler/content/Helper.js');
const helper = new Helper();
-class FrameTree {
+export class FrameTree {
constructor(rootBrowsingContext) {
helper.decorateAsEventEmitter(this);
@@ -46,8 +44,6 @@ class FrameTree {
Ci.nsISupportsWeakReference,
]);
- this._addedScrollbarsStylesheetSymbol = Symbol('_addedScrollbarsStylesheetSymbol');
-
this._wdm = Cc["@mozilla.org/dom/workers/workerdebuggermanager;1"].createInstance(Ci.nsIWorkerDebuggerManager);
this._wdmListener = {
QueryInterface: ChromeUtils.generateQI([Ci.nsIWorkerDebuggerManagerListener]),
@@ -130,24 +126,12 @@ class FrameTree {
}
_onDOMWindowCreated(window) {
- if (!window[this._addedScrollbarsStylesheetSymbol] && this.scrollbarsHidden) {
- const styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Components.interfaces.nsIStyleSheetService);
- const ioService = Cc["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
- const uri = ioService.newURI('chrome://juggler/content/content/hidden-scrollbars.css', null, null);
- const sheet = styleSheetService.preloadSheet(uri, styleSheetService.AGENT_SHEET);
- window.windowUtils.addSheet(sheet, styleSheetService.AGENT_SHEET);
- window[this._addedScrollbarsStylesheetSymbol] = true;
- }
const frame = this.frameForDocShell(window.docShell);
if (!frame)
return;
frame._onGlobalObjectCleared();
}
- setScrollbarsHidden(hidden) {
- this.scrollbarsHidden = hidden;
- }
-
setJavaScriptDisabled(javaScriptDisabled) {
this._javaScriptDisabled = javaScriptDisabled;
for (const frame of this.frames())
@@ -704,6 +688,3 @@ function channelId(channel) {
}
-var EXPORTED_SYMBOLS = ['FrameTree'];
-this.FrameTree = FrameTree;
-
diff --git a/browser_patches/firefox/juggler/content/JugglerFrameChild.jsm b/browser_patches/firefox/juggler/content/JugglerFrameChild.jsm
index 529f6d3b5898e..af060c57aac90 100644
--- a/browser_patches/firefox/juggler/content/JugglerFrameChild.jsm
+++ b/browser_patches/firefox/juggler/content/JugglerFrameChild.jsm
@@ -1,14 +1,16 @@
"use strict";
-const { Helper } = ChromeUtils.import('chrome://juggler/content/Helper.js');
-const { initialize } = ChromeUtils.import('chrome://juggler/content/content/main.js');
+const { Helper } = ChromeUtils.importESModule('chrome://juggler/content/Helper.js');
+const { initialize } = ChromeUtils.importESModule('chrome://juggler/content/content/main.js');
const Ci = Components.interfaces;
const helper = new Helper();
let sameProcessInstanceNumber = 0;
-class JugglerFrameChild extends JSWindowActorChild {
+const topBrowingContextToAgents = new Map();
+
+export class JugglerFrameChild extends JSWindowActorChild {
constructor() {
super();
@@ -16,49 +18,68 @@ class JugglerFrameChild extends JSWindowActorChild {
}
handleEvent(aEvent) {
- if (this._agents && aEvent.type === 'DOMWillOpenModalDialog') {
- this._agents.channel.pause();
+ const agents = this._agents();
+ if (!agents)
+ return;
+ if (aEvent.type === 'DOMWillOpenModalDialog') {
+ agents.channel.pause();
return;
}
- if (this._agents && aEvent.type === 'DOMModalDialogClosed') {
- this._agents.channel.resumeSoon();
+ if (aEvent.type === 'DOMModalDialogClosed') {
+ agents.channel.resumeSoon();
return;
}
- if (this._agents && aEvent.target === this.document)
- this._agents.pageAgent.onWindowEvent(aEvent);
- if (this._agents && aEvent.target === this.document)
- this._agents.frameTree.onWindowEvent(aEvent);
+ if (aEvent.target === this.document) {
+ agents.pageAgent.onWindowEvent(aEvent);
+ agents.frameTree.onWindowEvent(aEvent);
+ }
+ }
+
+ _agents() {
+ return topBrowingContextToAgents.get(this.browsingContext.top);
}
actorCreated() {
this.actorName = `content::${this.browsingContext.browserId}/${this.browsingContext.id}/${++sameProcessInstanceNumber}`;
this._eventListeners.push(helper.addEventListener(this.contentWindow, 'load', event => {
- this._agents?.pageAgent.onWindowEvent(event);
+ this._agents()?.pageAgent.onWindowEvent(event);
}));
if (this.document.documentURI.startsWith('moz-extension://'))
return;
- this._agents = initialize(this.browsingContext, this.docShell, this);
- }
- _dispose() {
- helper.removeListeners(this._eventListeners);
- // We do not cleanup since agents are shared for all frames in the process.
-
- // TODO: restore the cleanup.
- // Reset transport so that all messages will be pending and will not throw any errors.
- // this._channel.resetTransport();
- // this._agents.pageAgent.dispose();
- // this._agents.frameTree.dispose();
- // this._agents = undefined;
+ // Child frame events will be forwarded to related top-level agents.
+ if (this.browsingContext.parent)
+ return;
+
+ let agents = topBrowingContextToAgents.get(this.browsingContext);
+ if (!agents) {
+ agents = initialize(this.browsingContext, this.docShell);
+ topBrowingContextToAgents.set(this.browsingContext, agents);
+ }
+ agents.channel.bindToActor(this);
+ agents.actor = this;
}
didDestroy() {
- this._dispose();
+ helper.removeListeners(this._eventListeners);
+
+ if (this.browsingContext.parent)
+ return;
+
+ const agents = topBrowingContextToAgents.get(this.browsingContext);
+ // The agents are already re-bound to a new actor.
+ if (agents?.actor !== this)
+ return;
+
+ topBrowingContextToAgents.delete(this.browsingContext);
+
+ agents.channel.resetTransport();
+ agents.pageAgent.dispose();
+ agents.frameTree.dispose();
}
receiveMessage() { }
}
-var EXPORTED_SYMBOLS = ['JugglerFrameChild'];
diff --git a/browser_patches/firefox/juggler/content/PageAgent.js b/browser_patches/firefox/juggler/content/PageAgent.js
index 6aee921e87779..2ff5e6b922b55 100644
--- a/browser_patches/firefox/juggler/content/PageAgent.js
+++ b/browser_patches/firefox/juggler/content/PageAgent.js
@@ -8,9 +8,9 @@ const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
-const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
-const {NetUtil} = ChromeUtils.import('resource://gre/modules/NetUtil.jsm');
-const {setTimeout} = ChromeUtils.import('resource://gre/modules/Timer.jsm');
+const {Helper} = ChromeUtils.importESModule('chrome://juggler/content/Helper.js');
+const {NetUtil} = ChromeUtils.importESModule('resource://gre/modules/NetUtil.sys.mjs');
+const {setTimeout} = ChromeUtils.importESModule('resource://gre/modules/Timer.sys.mjs');
const dragService = Cc["@mozilla.org/widget/dragservice;1"].getService(
Ci.nsIDragService
@@ -51,7 +51,7 @@ class WorkerData {
}
}
-class PageAgent {
+export class PageAgent {
constructor(browserChannel, frameTree) {
this._browserChannel = browserChannel;
this._browserPage = browserChannel.connect('page');
@@ -120,7 +120,8 @@ class PageAgent {
// After the dragStart event is dispatched and handled by Web,
// it might or might not create a new drag session, depending on its preventing default.
setTimeout(() => {
- this._browserPage.emit('pageInputEvent', { type: 'juggler-drag-finalized', dragSessionStarted: !!dragService.getCurrentSession() });
+ const session = this._getCurrentDragSession();
+ this._browserPage.emit('pageInputEvent', { type: 'juggler-drag-finalized', dragSessionStarted: !!session });
}, 0);
}
}),
@@ -370,7 +371,12 @@ class PageAgent {
const unsafeObject = frame.unsafeObject(objectId);
if (!unsafeObject)
throw new Error('Object is not input!');
- const nsFiles = await Promise.all(files.map(filePath => File.createFromFileName(filePath)));
+ let nsFiles;
+ if (unsafeObject.webkitdirectory) {
+ nsFiles = await new Directory(files[0]).getFiles(true);
+ } else {
+ nsFiles = await Promise.all(files.map(filePath => File.createFromFileName(filePath)));
+ }
unsafeObject.mozSetFileArray(nsFiles);
const events = [
new (frame.domWindow().Event)('input', { bubbles: true, cancelable: true, composed: true }),
@@ -521,8 +527,14 @@ class PageAgent {
});
}
+ _getCurrentDragSession() {
+ const frame = this._frameTree.mainFrame();
+ const domWindow = frame?.domWindow();
+ return domWindow ? dragService.getCurrentSession(domWindow) : undefined;
+ }
+
async _dispatchDragEvent({type, x, y, modifiers}) {
- const session = dragService.getCurrentSession();
+ const session = this._getCurrentDragSession();
const dropEffect = session.dataTransfer.dropEffect;
if ((type === 'drop' && dropEffect !== 'none') || type === 'dragover') {
@@ -546,9 +558,8 @@ class PageAgent {
return;
}
if (type === 'dragend') {
- const session = dragService.getCurrentSession();
- if (session)
- dragService.endDragSession(true);
+ const session = this._getCurrentDragSession();
+ session?.endDragSession(true);
return;
}
}
@@ -564,7 +575,7 @@ class PageAgent {
// We crash by using js-ctypes and dereferencing
// a bad pointer. The crash should happen immediately
// upon loading this frame script.
- const { ctypes } = ChromeUtils.import('resource://gre/modules/ctypes.jsm');
+ const { ctypes } = ChromeUtils.importESModule('resource://gre/modules/ctypes.sys.mjs');
ChromeUtils.privateNoteIntentionalCrash();
const zero = new ctypes.intptr_t(8);
const badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
@@ -698,6 +709,3 @@ class PageAgent {
}
}
-var EXPORTED_SYMBOLS = ['PageAgent'];
-this.PageAgent = PageAgent;
-
diff --git a/browser_patches/firefox/juggler/content/Runtime.js b/browser_patches/firefox/juggler/content/Runtime.js
index a5fa7a03dd343..ad8720a1d3e36 100644
--- a/browser_patches/firefox/juggler/content/Runtime.js
+++ b/browser_patches/firefox/juggler/content/Runtime.js
@@ -8,8 +8,8 @@
if (!this.Debugger) {
// Worker has a Debugger defined already.
- const {addDebuggerToGlobal} = ChromeUtils.import("resource://gre/modules/jsdebugger.jsm", {});
- addDebuggerToGlobal(Components.utils.getGlobalForObject(this));
+ const {addDebuggerToGlobal} = ChromeUtils.importESModule("resource://gre/modules/jsdebugger.sys.mjs");
+ addDebuggerToGlobal(Components.utils.getGlobalForObject(globalThis));
}
let lastId = 0;
@@ -596,5 +596,5 @@ function emitEvent(event, ...args) {
listener.call(null, ...args);
}
-var EXPORTED_SYMBOLS = ['Runtime'];
-this.Runtime = Runtime;
+// Export Runtime to global.
+globalThis.Runtime = Runtime;
diff --git a/browser_patches/firefox/juggler/content/main.js b/browser_patches/firefox/juggler/content/main.js
index 022b1e3a5e87c..68fb364eadb4e 100644
--- a/browser_patches/firefox/juggler/content/main.js
+++ b/browser_patches/firefox/juggler/content/main.js
@@ -2,29 +2,21 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
-const {FrameTree} = ChromeUtils.import('chrome://juggler/content/content/FrameTree.js');
-const {SimpleChannel} = ChromeUtils.import('chrome://juggler/content/SimpleChannel.js');
-const {PageAgent} = ChromeUtils.import('chrome://juggler/content/content/PageAgent.js');
+// Load SimpleChannel and Runtime in content process's global.
+// NOTE: since these have to exist in both Worker and main threads, and we do
+// not know a way to load ES Modules in worker threads, we have to use the loadSubScript
+// utility instead.
+Services.scriptloader.loadSubScript('chrome://juggler/content/SimpleChannel.js');
+Services.scriptloader.loadSubScript('chrome://juggler/content/content/Runtime.js');
-const browsingContextToAgents = new Map();
-const helper = new Helper();
-
-function initialize(browsingContext, docShell, actor) {
- if (browsingContext.parent) {
- // For child frames, return agents from the main frame.
- return browsingContextToAgents.get(browsingContext.top);
- }
+const {Helper} = ChromeUtils.importESModule('chrome://juggler/content/Helper.js');
+const {FrameTree} = ChromeUtils.importESModule('chrome://juggler/content/content/FrameTree.js');
+const {PageAgent} = ChromeUtils.importESModule('chrome://juggler/content/content/PageAgent.js');
- let data = browsingContextToAgents.get(browsingContext);
- if (data) {
- // Rebind from one main frame actor to another one.
- data.channel.bindToActor(actor);
- return data;
- }
+const helper = new Helper();
- data = { channel: undefined, pageAgent: undefined, frameTree: undefined, failedToOverrideTimezone: false };
- browsingContextToAgents.set(browsingContext, data);
+export function initialize(browsingContext, docShell) {
+ const data = { channel: undefined, pageAgent: undefined, frameTree: undefined, failedToOverrideTimezone: false };
const applySetting = {
geolocation: (geolocation) => {
@@ -59,10 +51,6 @@ function initialize(browsingContext, docShell, actor) {
docShell.languageOverride = locale;
},
- scrollbarsHidden: (hidden) => {
- data.frameTree.setScrollbarsHidden(hidden);
- },
-
javaScriptDisabled: (javaScriptDisabled) => {
data.frameTree.setJavaScriptDisabled(javaScriptDisabled);
},
@@ -84,7 +72,6 @@ function initialize(browsingContext, docShell, actor) {
data.frameTree.addBinding(worldName, name, script);
data.frameTree.setInitScripts([...contextCrossProcessCookie.initScripts, ...pageCrossProcessCookie.initScripts]);
data.channel = new SimpleChannel('', 'process-' + Services.appinfo.processID);
- data.channel.bindToActor(actor);
data.pageAgent = new PageAgent(data.channel, data.frameTree);
docShell.fileInputInterceptionEnabled = !!pageCrossProcessCookie.interceptFileChooserDialog;
@@ -133,6 +120,3 @@ function initialize(browsingContext, docShell, actor) {
return data;
}
-
-var EXPORTED_SYMBOLS = ['initialize'];
-this.initialize = initialize;
diff --git a/browser_patches/firefox/juggler/protocol/BrowserHandler.js b/browser_patches/firefox/juggler/protocol/BrowserHandler.js
index 7de276d017b26..035a53bb688c9 100644
--- a/browser_patches/firefox/juggler/protocol/BrowserHandler.js
+++ b/browser_patches/firefox/juggler/protocol/BrowserHandler.js
@@ -4,15 +4,15 @@
"use strict";
-const {AddonManager} = ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
-const {TargetRegistry} = ChromeUtils.import("chrome://juggler/content/TargetRegistry.js");
-const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
-const {PageHandler} = ChromeUtils.import("chrome://juggler/content/protocol/PageHandler.js");
-const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
+const {AddonManager} = ChromeUtils.importESModule("resource://gre/modules/AddonManager.sys.mjs");
+const {TargetRegistry} = ChromeUtils.importESModule("chrome://juggler/content/TargetRegistry.js");
+const {Helper} = ChromeUtils.importESModule('chrome://juggler/content/Helper.js');
+const {PageHandler} = ChromeUtils.importESModule("chrome://juggler/content/protocol/PageHandler.js");
+const {AppConstants} = ChromeUtils.importESModule("resource://gre/modules/AppConstants.sys.mjs");
const helper = new Helper();
-class BrowserHandler {
+export class BrowserHandler {
constructor(session, dispatcher, targetRegistry, startCompletePromise, onclose) {
this._session = session;
this._dispatcher = dispatcher;
@@ -219,6 +219,10 @@ class BrowserHandler {
await this._targetRegistry.browserContextForId(browserContextId).setForcedColors(nullToUndefined(forcedColors));
}
+ async ['Browser.setContrast']({browserContextId, contrast}) {
+ await this._targetRegistry.browserContextForId(browserContextId).setContrast(nullToUndefined(contrast));
+ }
+
async ['Browser.setVideoRecordingOptions']({browserContextId, options}) {
await this._targetRegistry.browserContextForId(browserContextId).setVideoRecordingOptions(options);
}
@@ -255,10 +259,6 @@ class BrowserHandler {
await this._targetRegistry.browserContextForId(browserContextId).setDefaultViewport(nullToUndefined(viewport));
}
- async ['Browser.setScrollbarsHidden']({browserContextId, hidden}) {
- await this._targetRegistry.browserContextForId(browserContextId).applySetting('scrollbarsHidden', nullToUndefined(hidden));
- }
-
async ['Browser.setInitScripts']({browserContextId, scripts}) {
await this._targetRegistry.browserContextForId(browserContextId).setInitScripts(scripts);
}
@@ -313,6 +313,3 @@ async function waitForWindowClosed(browserWindow) {
function nullToUndefined(value) {
return value === null ? undefined : value;
}
-
-var EXPORTED_SYMBOLS = ['BrowserHandler'];
-this.BrowserHandler = BrowserHandler;
diff --git a/browser_patches/firefox/juggler/protocol/Dispatcher.js b/browser_patches/firefox/juggler/protocol/Dispatcher.js
index 8542461d529eb..7a65d0a1170c1 100644
--- a/browser_patches/firefox/juggler/protocol/Dispatcher.js
+++ b/browser_patches/firefox/juggler/protocol/Dispatcher.js
@@ -2,12 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-const {protocol, checkScheme} = ChromeUtils.import("chrome://juggler/content/protocol/Protocol.js");
-const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
+const {protocol} = ChromeUtils.importESModule("chrome://juggler/content/protocol/Protocol.js");
+const {checkScheme} = ChromeUtils.importESModule("chrome://juggler/content/protocol/PrimitiveTypes.js");
+const {Helper} = ChromeUtils.importESModule('chrome://juggler/content/Helper.js');
const helper = new Helper();
-class Dispatcher {
+export class Dispatcher {
/**
* @param {Connection} connection
*/
@@ -132,7 +133,3 @@ class ProtocolSession {
return await this._handler[method](params);
}
}
-
-this.EXPORTED_SYMBOLS = ['Dispatcher'];
-this.Dispatcher = Dispatcher;
-
diff --git a/browser_patches/firefox/juggler/protocol/PageHandler.js b/browser_patches/firefox/juggler/protocol/PageHandler.js
index 8fa9a06361b71..1dab7d8803782 100644
--- a/browser_patches/firefox/juggler/protocol/PageHandler.js
+++ b/browser_patches/firefox/juggler/protocol/PageHandler.js
@@ -4,11 +4,11 @@
"use strict";
-const {Helper, EventWatcher} = ChromeUtils.import('chrome://juggler/content/Helper.js');
-const {NetUtil} = ChromeUtils.import('resource://gre/modules/NetUtil.jsm');
-const {NetworkObserver, PageNetwork} = ChromeUtils.import('chrome://juggler/content/NetworkObserver.js');
-const {PageTarget} = ChromeUtils.import('chrome://juggler/content/TargetRegistry.js');
-const {setTimeout} = ChromeUtils.import('resource://gre/modules/Timer.jsm');
+const {Helper, EventWatcher} = ChromeUtils.importESModule('chrome://juggler/content/Helper.js');
+const {NetUtil} = ChromeUtils.importESModule('resource://gre/modules/NetUtil.sys.mjs');
+const {NetworkObserver, PageNetwork} = ChromeUtils.importESModule('chrome://juggler/content/NetworkObserver.js');
+const {PageTarget} = ChromeUtils.importESModule('chrome://juggler/content/TargetRegistry.js');
+const {setTimeout} = ChromeUtils.importESModule('resource://gre/modules/Timer.sys.mjs');
const Cc = Components.classes;
const Ci = Components.interfaces;
@@ -65,7 +65,7 @@ class WorkerHandler {
}
}
-class PageHandler {
+export class PageHandler {
constructor(target, session, contentChannel) {
this._session = session;
this._contentChannel = contentChannel;
@@ -240,6 +240,10 @@ class PageHandler {
await this._pageTarget.setViewportSize(viewportSize === null ? undefined : viewportSize);
}
+ async ['Page.setZoom']({zoom}) {
+ await this._pageTarget.setZoom(zoom);
+ }
+
async ['Runtime.evaluate'](options) {
return await this._contentPage.send('evaluate', options);
}
@@ -256,6 +260,13 @@ class PageHandler {
return await this._contentPage.send('disposeObject', options);
}
+ async ['Heap.collectGarbage']() {
+ Services.obs.notifyObservers(null, "child-gc-request");
+ Cu.forceGC();
+ Services.obs.notifyObservers(null, "child-cc-request");
+ Cu.forceCC();
+ }
+
async ['Network.getResponseBody']({requestId}) {
return this._pageNetwork.getResponseBody(requestId);
}
@@ -291,10 +302,11 @@ class PageHandler {
return await this._contentPage.send('setFileInputFiles', options);
}
- async ['Page.setEmulatedMedia']({colorScheme, type, reducedMotion, forcedColors}) {
+ async ['Page.setEmulatedMedia']({colorScheme, type, reducedMotion, forcedColors, contrast}) {
this._pageTarget.setColorScheme(colorScheme || null);
this._pageTarget.setReducedMotion(reducedMotion || null);
this._pageTarget.setForcedColors(forcedColors || null);
+ this._pageTarget.setContrast(contrast || null);
this._pageTarget.setEmulatedMedia(type);
}
@@ -679,6 +691,3 @@ class PageHandler {
return await worker.sendMessage(JSON.parse(message));
}
}
-
-var EXPORTED_SYMBOLS = ['PageHandler'];
-this.PageHandler = PageHandler;
diff --git a/browser_patches/firefox/juggler/protocol/PrimitiveTypes.js b/browser_patches/firefox/juggler/protocol/PrimitiveTypes.js
index 5799038f19cbc..ca6d1ec4f60f2 100644
--- a/browser_patches/firefox/juggler/protocol/PrimitiveTypes.js
+++ b/browser_patches/firefox/juggler/protocol/PrimitiveTypes.js
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-const t = {};
+export const t = {};
t.String = function(x, details = {}, path = ['']) {
if (typeof x === 'string' || typeof x === 'String')
@@ -96,7 +96,7 @@ function beauty(path, obj) {
return `property "${path.join('.')}" - ${JSON.stringify(obj, null, 2)}`;
}
-function checkScheme(scheme, x, details = {}, path = ['']) {
+export function checkScheme(scheme, x, details = {}, path = ['']) {
if (!scheme)
throw new Error(`ILLDEFINED SCHEME: ${path.join('.')}`);
if (typeof scheme === 'object') {
@@ -142,6 +142,3 @@ test(t.Either(t.String, t.Number), {});
*/
-this.t = t;
-this.checkScheme = checkScheme;
-this.EXPORTED_SYMBOLS = ['t', 'checkScheme'];
diff --git a/browser_patches/firefox/juggler/protocol/Protocol.js b/browser_patches/firefox/juggler/protocol/Protocol.js
index 6c9b700f05fec..4cb44d679ce0b 100644
--- a/browser_patches/firefox/juggler/protocol/Protocol.js
+++ b/browser_patches/firefox/juggler/protocol/Protocol.js
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-const {t, checkScheme} = ChromeUtils.import('chrome://juggler/content/protocol/PrimitiveTypes.js');
+const {t} = ChromeUtils.importESModule('chrome://juggler/content/protocol/PrimitiveTypes.js');
// Protocol-specific types.
const browserTypes = {};
@@ -394,12 +394,6 @@ const Browser = {
viewport: t.Nullable(pageTypes.Viewport),
}
},
- 'setScrollbarsHidden': {
- params: {
- browserContextId: t.Optional(t.String),
- hidden: t.Boolean,
- }
- },
'setInitScripts': {
params: {
browserContextId: t.Optional(t.String),
@@ -469,6 +463,12 @@ const Browser = {
forcedColors: t.Nullable(t.Enum(['active', 'none'])),
},
},
+ 'setContrast': {
+ params: {
+ browserContextId: t.Optional(t.String),
+ contrast: t.Nullable(t.Enum(['less', 'more', 'custom', 'no-preference'])),
+ },
+ },
'setVideoRecordingOptions': {
params: {
browserContextId: t.Optional(t.String),
@@ -487,6 +487,17 @@ const Browser = {
},
};
+const Heap = {
+ targets: ['page'],
+ types: {},
+ events: {},
+ methods: {
+ 'collectGarbage': {
+ params: {},
+ },
+ },
+};
+
const Network = {
targets: ['page'],
types: networkTypes,
@@ -789,6 +800,11 @@ const Page = {
viewportSize: t.Nullable(pageTypes.Size),
},
},
+ 'setZoom': {
+ params: {
+ zoom: t.Number,
+ },
+ },
'bringToFront': {
params: {
},
@@ -799,6 +815,7 @@ const Page = {
colorScheme: t.Optional(t.Enum(['dark', 'light', 'no-preference'])),
reducedMotion: t.Optional(t.Enum(['reduce', 'no-preference'])),
forcedColors: t.Optional(t.Enum(['active', 'none'])),
+ contrast: t.Optional(t.Enum(['less', 'more', 'custom', 'no-preference'])),
},
},
'setCacheDisabled': {
@@ -1001,8 +1018,6 @@ const Accessibility = {
}
}
-this.protocol = {
- domains: {Browser, Page, Runtime, Network, Accessibility},
+export const protocol = {
+ domains: {Browser, Heap, Page, Runtime, Network, Accessibility},
};
-this.checkScheme = checkScheme;
-this.EXPORTED_SYMBOLS = ['protocol', 'checkScheme'];
diff --git a/browser_patches/firefox/juggler/screencast/moz.build b/browser_patches/firefox/juggler/screencast/moz.build
index e21b177c3965c..f89c54e037e39 100644
--- a/browser_patches/firefox/juggler/screencast/moz.build
+++ b/browser_patches/firefox/juggler/screencast/moz.build
@@ -23,8 +23,8 @@ XPCOM_MANIFESTS += [
LOCAL_INCLUDES += [
'/dom/media/systemservices',
'/media/libyuv/libyuv/include',
+ '/third_party/abseil-cpp',
'/third_party/libwebrtc',
- '/third_party/libwebrtc/third_party/abseil-cpp',
]
LOCAL_INCLUDES += [
diff --git a/browser_patches/firefox/juggler/screencast/nsScreencastService.cpp b/browser_patches/firefox/juggler/screencast/nsScreencastService.cpp
index 25f6171801414..7256c8c8ea416 100644
--- a/browser_patches/firefox/juggler/screencast/nsScreencastService.cpp
+++ b/browser_patches/firefox/juggler/screencast/nsScreencastService.cpp
@@ -129,7 +129,7 @@ class nsScreencastService::Session : public rtc::VideoSinkInterfaceStartCapture(capability);
+ int error = mCaptureModule->StartCaptureCounted(capability);
if (error) {
fprintf(stderr, "StartCapture error %d\n", error);
return false;
@@ -152,7 +152,7 @@ class nsScreencastService::Session : public rtc::VideoSinkInterfaceDeRegisterCaptureDataCallback(this);
else
mCaptureModule->DeRegisterRawFrameCallback(this);
- mCaptureModule->StopCapture();
+ mCaptureModule->StopCaptureCounted();
if (mEncoder) {
mEncoder->finish([this, protect = RefPtr{this}] {
NS_DispatchToMainThread(NS_NewRunnableFunction(
@@ -343,10 +343,17 @@ nsresult nsScreencastService::StartVideoRecording(nsIScreencastServiceClient* aC
return NS_ERROR_FAILURE;
gfx::IntMargin margin;
- auto bounds = widget->GetScreenBounds().ToUnknownRect();
+ // Screen bounds is the widget location on screen.
+ auto screenBounds = widget->GetScreenBounds().ToUnknownRect();
+ // Client bounds is the content location, in terms of parent widget.
+ // To use it, we need to translate it to screen coordinates first.
auto clientBounds = widget->GetClientBounds().ToUnknownRect();
+ for (auto parent = widget->GetParent(); parent != nullptr; parent = parent->GetParent()) {
+ auto pb = parent->GetClientBounds().ToUnknownRect();
+ clientBounds.MoveBy(pb.X(), pb.Y());
+ }
// Crop the image to exclude frame (if any).
- margin = bounds - clientBounds;
+ margin = screenBounds - clientBounds;
// Crop the image to exclude controls.
margin.top += offsetTop;
diff --git a/browser_patches/firefox/patches/bootstrap.diff b/browser_patches/firefox/patches/bootstrap.diff
index 6291e775e6a7f..6f70b0342c8ec 100644
--- a/browser_patches/firefox/patches/bootstrap.diff
+++ b/browser_patches/firefox/patches/bootstrap.diff
@@ -1,5 +1,5 @@
diff --git a/accessible/base/NotificationController.h b/accessible/base/NotificationController.h
-index 137963f1170927ae0262e0dc26ef721d496376f4..41fa27bc4a3da41814a7f326792990df3424e81f 100644
+index 1bcd464d3bd6b8465f78c62b074b0d57dbc6a082..f878ac9db2d800542dabcc2f48e8ae4727ec4b9a 100644
--- a/accessible/base/NotificationController.h
+++ b/accessible/base/NotificationController.h
@@ -244,6 +244,8 @@ class NotificationController final : public EventQueue,
@@ -57,10 +57,10 @@ index 8e9bf2b413585b5a3db9370eee5d57fb6c6716ed..5a3b194b54e3813c89989f13a214c989
* Return XPCOM wrapper for the internal accessible.
*/
diff --git a/browser/app/winlauncher/LauncherProcessWin.cpp b/browser/app/winlauncher/LauncherProcessWin.cpp
-index 81d4ee91e9383693d794dbf68184a80b49b582c6..1a07e3511f73199fe0b248412d01d7b8a3744a66 100644
+index 8167d2b81c918e02ce757f7f448f22e07c29d140..3ae798880acfd8aa965ae08051f2f81855133711 100644
--- a/browser/app/winlauncher/LauncherProcessWin.cpp
+++ b/browser/app/winlauncher/LauncherProcessWin.cpp
-@@ -22,6 +22,7 @@
+@@ -23,6 +23,7 @@
#include "mozilla/WinHeaderOnlyUtils.h"
#include "nsWindowsHelpers.h"
@@ -68,7 +68,7 @@ index 81d4ee91e9383693d794dbf68184a80b49b582c6..1a07e3511f73199fe0b248412d01d7b8
#include
#include
-@@ -425,8 +426,18 @@ Maybe LauncherMain(int& argc, wchar_t* argv[],
+@@ -422,8 +423,18 @@ Maybe LauncherMain(int& argc, wchar_t* argv[],
HANDLE stdHandles[] = {::GetStdHandle(STD_INPUT_HANDLE),
::GetStdHandle(STD_OUTPUT_HANDLE),
::GetStdHandle(STD_ERROR_HANDLE)};
@@ -89,10 +89,10 @@ index 81d4ee91e9383693d794dbf68184a80b49b582c6..1a07e3511f73199fe0b248412d01d7b8
DWORD creationFlags = CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT;
diff --git a/browser/installer/allowed-dupes.mn b/browser/installer/allowed-dupes.mn
-index f6d425f36a965f03ac82dbe3ab6cde06f12751ac..d60999ab2658b1e1e5f07a8aee530451c44f2957 100644
+index a097c2c56a665204ff7b5593c7faf836366801cf..235a4e224e08c22870c6913e335f0b6020b3e7da 100644
--- a/browser/installer/allowed-dupes.mn
+++ b/browser/installer/allowed-dupes.mn
-@@ -73,6 +73,12 @@ browser/features/webcompat@mozilla.org/shims/empty-shim.txt
+@@ -67,6 +67,12 @@ browser/features/webcompat@mozilla.org/shims/empty-shim.txt
removed-files
#endif
@@ -102,14 +102,14 @@ index f6d425f36a965f03ac82dbe3ab6cde06f12751ac..d60999ab2658b1e1e5f07a8aee530451
+chrome/juggler/content/server/stream-utils.js
+chrome/marionette/content/stream-utils.js
+
- # Bug 1496075 - Switch searchplugins to Web Extensions
- browser/chrome/browser/search-extensions/amazon/favicon.ico
- browser/chrome/browser/search-extensions/amazondotcn/favicon.ico
+ # Bug 1606928 - There's no reliable way to connect Top Sites favicons with the favicons in the Search Service
+ browser/chrome/browser/content/activity-stream/data/content/tippytop/favicons/allegro-pl.ico
+ browser/defaults/settings/main/search-config-icons/96327a73-c433-5eb4-a16d-b090cadfb80b
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
-index 1b87a9ab4aec939acac1da54a2b6670cc581fe86..a638dbe8e2f260d8be550fa8eb5bf6f6c2c31080 100644
+index 89cff6b562a82bd3a9a5d268abd4373199b31fac..e58dbf0ab0b06e84f6dac64698d11c6268091204 100644
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
-@@ -185,6 +185,9 @@
+@@ -196,6 +196,9 @@
@RESPATH@/chrome/remote.manifest
#endif
@@ -167,10 +167,10 @@ index d49c6fbf1bf83b832795fa674f6b41f223eef812..7ea3540947ff5f61b15f27fbf4b95564
const transportProvider = {
setListener(upgradeListener) {
diff --git a/docshell/base/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp
-index 6e1a1b689398fa6c3c73f2f243ae02c67a4476c8..9dcf71ce753cf11f295d83eb7653e940065c8e2c 100644
+index 2425779a7767e9350ee2afc4aea111a090c7f909..393eb86bf2d9a8f778bfce560a9fb3bf528ba558 100644
--- a/docshell/base/BrowsingContext.cpp
+++ b/docshell/base/BrowsingContext.cpp
-@@ -106,8 +106,15 @@ struct ParamTraits
+@@ -108,8 +108,15 @@ struct ParamTraits
template <>
struct ParamTraits
@@ -183,36 +183,28 @@ index 6e1a1b689398fa6c3c73f2f243ae02c67a4476c8..9dcf71ce753cf11f295d83eb7653e940
+ : public mozilla::dom::WebIDLEnumSerializer {};
+
+template <>
-+struct ParamTraits
-+ : public mozilla::dom::WebIDLEnumSerializer {};
++struct ParamTraits
++ : public mozilla::dom::WebIDLEnumSerializer {};
template <>
- struct ParamTraits
-@@ -2804,6 +2811,40 @@ void BrowsingContext::DidSet(FieldIndex,
+ struct ParamTraits
+@@ -2891,6 +2898,32 @@ void BrowsingContext::DidSet(FieldIndex,
PresContextAffectingFieldChanged();
}
-+void BrowsingContext::DidSet(FieldIndex,
-+ dom::PrefersReducedMotionOverride aOldValue) {
++void BrowsingContext::DidSet(FieldIndex,
++ dom::PrefersContrastOverride aOldValue) {
+ MOZ_ASSERT(IsTop());
-+ if (PrefersReducedMotionOverride() == aOldValue) {
++ if (PrefersContrastOverride() == aOldValue) {
+ return;
+ }
-+ PreOrderWalk([&](BrowsingContext* aContext) {
-+ if (nsIDocShell* shell = aContext->GetDocShell()) {
-+ if (nsPresContext* pc = shell->GetPresContext()) {
-+ pc->MediaFeatureValuesChanged(
-+ {MediaFeatureChangeReason::SystemMetricsChange},
-+ MediaFeatureChangePropagation::JustThisDocument);
-+ }
-+ }
-+ });
++ PresContextAffectingFieldChanged();
+}
+
-+void BrowsingContext::DidSet(FieldIndex,
-+ dom::ForcedColorsOverride aOldValue) {
++void BrowsingContext::DidSet(FieldIndex,
++ dom::PrefersReducedMotionOverride aOldValue) {
+ MOZ_ASSERT(IsTop());
-+ if (ForcedColorsOverride() == aOldValue) {
++ if (PrefersReducedMotionOverride() == aOldValue) {
+ return;
+ }
+ PreOrderWalk([&](BrowsingContext* aContext) {
@@ -230,10 +222,10 @@ index 6e1a1b689398fa6c3c73f2f243ae02c67a4476c8..9dcf71ce753cf11f295d83eb7653e940
nsString&& aOldValue) {
MOZ_ASSERT(IsTop());
diff --git a/docshell/base/BrowsingContext.h b/docshell/base/BrowsingContext.h
-index 5ec95a61e4d3af265cbe7dd9d83f6535da1d103e..f8acafe6d58c429af27a38363e06ad546dfbfddd 100644
+index eb183cb5c0751e43ea674f9e52441a5a82f186e0..79c5d8110faa89779dd0c16ba00620e7e65d06f5 100644
--- a/docshell/base/BrowsingContext.h
+++ b/docshell/base/BrowsingContext.h
-@@ -199,10 +199,10 @@ struct EmbedderColorSchemes {
+@@ -203,10 +203,10 @@ struct EmbedderColorSchemes {
FIELD(GVInaudibleAutoplayRequestStatus, GVAutoplayRequestStatus) \
/* ScreenOrientation-related APIs */ \
FIELD(CurrentOrientationAngle, float) \
@@ -246,33 +238,51 @@ index 5ec95a61e4d3af265cbe7dd9d83f6535da1d103e..f8acafe6d58c429af27a38363e06ad54
FIELD(EmbedderElementType, Maybe) \
FIELD(MessageManagerGroup, nsString) \
FIELD(MaxTouchPointsOverride, uint8_t) \
-@@ -240,6 +240,10 @@ struct EmbedderColorSchemes {
+@@ -246,6 +246,9 @@ struct EmbedderColorSchemes {
* embedder element. */ \
FIELD(EmbedderColorSchemes, EmbedderColorSchemes) \
FIELD(DisplayMode, dom::DisplayMode) \
+ /* playwright addition */ \
+ FIELD(PrefersReducedMotionOverride, dom::PrefersReducedMotionOverride) \
-+ /* playwright addition */ \
-+ FIELD(ForcedColorsOverride, dom::ForcedColorsOverride) \
++ FIELD(PrefersContrastOverride, dom::PrefersContrastOverride) \
/* The number of entries added to the session history because of this \
* browsing context. */ \
FIELD(HistoryEntryCount, uint32_t) \
-@@ -926,6 +930,14 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
- return GetPrefersColorSchemeOverride();
+@@ -950,6 +953,14 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
+ return GetForcedColorsOverride();
}
+ dom::PrefersReducedMotionOverride PrefersReducedMotionOverride() const {
+ return GetPrefersReducedMotionOverride();
+ }
+
-+ dom::ForcedColorsOverride ForcedColorsOverride() const {
-+ return GetForcedColorsOverride();
++ dom::PrefersContrastOverride PrefersContrastOverride() const {
++ return GetPrefersContrastOverride();
+ }
+
bool IsInBFCache() const;
bool AllowJavascript() const { return GetAllowJavascript(); }
-@@ -1090,6 +1102,23 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
+@@ -1112,6 +1123,11 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
+ return IsTop();
+ }
+
++ bool CanSet(FieldIndex,
++ dom::PrefersContrastOverride, ContentParent*) {
++ return IsTop();
++ }
++
+ bool CanSet(FieldIndex, dom::ForcedColorsOverride,
+ ContentParent*) {
+ return IsTop();
+@@ -1130,10 +1146,22 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
+ void DidSet(FieldIndex,
+ dom::ForcedColorsOverride aOldValue);
+
++ void DidSet(FieldIndex,
++ dom::PrefersContrastOverride aOldValue);
++
+ template
void WalkPresContexts(Callback&&);
void PresContextAffectingFieldChanged();
@@ -284,23 +294,24 @@ index 5ec95a61e4d3af265cbe7dd9d83f6535da1d103e..f8acafe6d58c429af27a38363e06ad54
+ void DidSet(FieldIndex,
+ dom::PrefersReducedMotionOverride aOldValue);
+
-+
-+ bool CanSet(FieldIndex,
-+ dom::ForcedColorsOverride, ContentParent*) {
-+ return IsTop();
-+ }
-+
-+ void DidSet(FieldIndex,
-+ dom::ForcedColorsOverride aOldValue);
+
void DidSet(FieldIndex, nsString&& aOldValue);
bool CanSet(FieldIndex, bool, ContentParent*) {
diff --git a/docshell/base/CanonicalBrowsingContext.cpp b/docshell/base/CanonicalBrowsingContext.cpp
-index 84f2d2960a3fa642754e0c909f92d96865e39984..e91fc85fc7a7966d2d536839fab823ae88d1b4bd 100644
+index bef42c91d6f88922c8c101f3675325d828872aaf..8eb68c441fbef8ecbe5e90c118ccc00813564577 100644
--- a/docshell/base/CanonicalBrowsingContext.cpp
+++ b/docshell/base/CanonicalBrowsingContext.cpp
-@@ -1477,6 +1477,12 @@ void CanonicalBrowsingContext::LoadURI(nsIURI* aURI,
+@@ -324,6 +324,8 @@ void CanonicalBrowsingContext::ReplacedBy(
+ txn.SetShouldDelayMediaFromStart(GetShouldDelayMediaFromStart());
+ txn.SetForceOffline(GetForceOffline());
+ txn.SetTopInnerSizeForRFP(GetTopInnerSizeForRFP());
++ txn.SetPrefersReducedMotionOverride(GetPrefersReducedMotionOverride());
++ txn.SetForcedColorsOverride(GetForcedColorsOverride());
+
+ // Propagate some settings on BrowsingContext replacement so they're not lost
+ // on bfcached navigations. These are important for GeckoView (see bug
+@@ -1635,6 +1637,12 @@ void CanonicalBrowsingContext::LoadURI(nsIURI* aURI,
return;
}
@@ -314,7 +325,7 @@ index 84f2d2960a3fa642754e0c909f92d96865e39984..e91fc85fc7a7966d2d536839fab823ae
}
diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
-index 3404597343e0d21c42c5adc2f2849888869cf75a..558f03f30672b9f0fdb68ba8d23a0d878d33643d 100644
+index 32c537d6be90247af8d778048c6d27f3800d4b02..b72196b0694828489f8ad27c209f49f0d41c43cb 100644
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -15,6 +15,12 @@
@@ -330,23 +341,23 @@ index 3404597343e0d21c42c5adc2f2849888869cf75a..558f03f30672b9f0fdb68ba8d23a0d87
#include "mozilla/ArrayUtils.h"
#include "mozilla/Attributes.h"
#include "mozilla/AutoRestore.h"
-@@ -64,6 +70,7 @@
- #include "mozilla/dom/ContentFrameMessageManager.h"
+@@ -66,6 +72,7 @@
#include "mozilla/dom/DocGroup.h"
#include "mozilla/dom/Element.h"
+ #include "mozilla/dom/FragmentDirective.h"
+#include "mozilla/dom/Geolocation.h"
#include "mozilla/dom/HTMLAnchorElement.h"
#include "mozilla/dom/HTMLIFrameElement.h"
- #include "mozilla/dom/PerformanceNavigation.h"
-@@ -88,6 +95,7 @@
- #include "mozilla/dom/JSWindowActorChild.h"
+ #include "mozilla/dom/Navigation.h"
+@@ -94,6 +101,7 @@
#include "mozilla/dom/DocumentBinding.h"
+ #include "mozilla/glean/DocshellMetrics.h"
#include "mozilla/ipc/ProtocolUtils.h"
+#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/net/DocumentChannel.h"
#include "mozilla/net/DocumentChannelChild.h"
#include "mozilla/net/ParentChannelWrapper.h"
-@@ -111,6 +119,7 @@
+@@ -117,6 +125,7 @@
#include "nsIDocumentViewer.h"
#include "mozilla/dom/Document.h"
#include "nsHTMLDocument.h"
@@ -354,7 +365,7 @@ index 3404597343e0d21c42c5adc2f2849888869cf75a..558f03f30672b9f0fdb68ba8d23a0d87
#include "nsIDocumentLoaderFactory.h"
#include "nsIDOMWindow.h"
#include "nsIEditingSession.h"
-@@ -206,6 +215,7 @@
+@@ -211,6 +220,7 @@
#include "nsGlobalWindowInner.h"
#include "nsGlobalWindowOuter.h"
#include "nsJSEnvironment.h"
@@ -362,7 +373,7 @@ index 3404597343e0d21c42c5adc2f2849888869cf75a..558f03f30672b9f0fdb68ba8d23a0d87
#include "nsNetCID.h"
#include "nsNetUtil.h"
#include "nsObjectLoadingContent.h"
-@@ -346,6 +356,13 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
+@@ -352,6 +362,14 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
mAllowDNSPrefetch(true),
mAllowWindowControl(true),
mCSSErrorReportingEnabled(false),
@@ -373,10 +384,11 @@ index 3404597343e0d21c42c5adc2f2849888869cf75a..558f03f30672b9f0fdb68ba8d23a0d87
+ mDisallowBFCache(false),
+ mReducedMotionOverride(REDUCED_MOTION_OVERRIDE_NONE),
+ mForcedColorsOverride(FORCED_COLORS_OVERRIDE_NO_OVERRIDE),
++ mContrastOverride(CONTRAST_OVERRIDE_NONE),
mAllowAuth(mItemType == typeContent),
mAllowKeywordFixup(false),
mDisableMetaRefreshWhenInactive(false),
-@@ -3101,6 +3118,214 @@ nsDocShell::GetMessageManager(ContentFrameMessageManager** aMessageManager) {
+@@ -3024,6 +3042,232 @@ nsDocShell::GetMessageManager(ContentFrameMessageManager** aMessageManager) {
return NS_OK;
}
@@ -586,12 +598,30 @@ index 3404597343e0d21c42c5adc2f2849888869cf75a..558f03f30672b9f0fdb68ba8d23a0d87
+ return NS_OK;
+}
+
++NS_IMETHODIMP
++nsDocShell::GetContrastOverride(ContrastOverride* aContrastOverride) {
++ *aContrastOverride = GetRootDocShell()->mContrastOverride;
++ return NS_OK;
++}
++
++NS_IMETHODIMP
++nsDocShell::SetContrastOverride(ContrastOverride aContrastOverride) {
++ mContrastOverride = aContrastOverride;
++ RefPtr presContext = GetPresContext();
++ if (presContext) {
++ presContext->MediaFeatureValuesChanged(
++ {MediaFeatureChangeReason::SystemMetricsChange},
++ MediaFeatureChangePropagation::JustThisDocument);
++ }
++ return NS_OK;
++}
++
+// =============== Juggler End =======================
+
NS_IMETHODIMP
nsDocShell::GetIsNavigating(bool* aOut) {
*aOut = mIsNavigating;
-@@ -4789,7 +5014,7 @@ nsDocShell::GetVisibility(bool* aVisibility) {
+@@ -4731,7 +4975,7 @@ nsDocShell::GetVisibility(bool* aVisibility) {
}
void nsDocShell::ActivenessMaybeChanged() {
@@ -600,7 +630,7 @@ index 3404597343e0d21c42c5adc2f2849888869cf75a..558f03f30672b9f0fdb68ba8d23a0d87
if (RefPtr presShell = GetPresShell()) {
presShell->ActivenessMaybeChanged();
}
-@@ -6711,6 +6936,10 @@ bool nsDocShell::CanSavePresentation(uint32_t aLoadType,
+@@ -6658,6 +6902,10 @@ bool nsDocShell::CanSavePresentation(uint32_t aLoadType,
return false; // no entry to save into
}
@@ -611,7 +641,7 @@ index 3404597343e0d21c42c5adc2f2849888869cf75a..558f03f30672b9f0fdb68ba8d23a0d87
MOZ_ASSERT(!mozilla::SessionHistoryInParent(),
"mOSHE cannot be non-null with SHIP");
nsCOMPtr viewer = mOSHE->GetDocumentViewer();
-@@ -8443,6 +8672,12 @@ nsresult nsDocShell::PerformRetargeting(nsDocShellLoadState* aLoadState) {
+@@ -8399,6 +8647,12 @@ nsresult nsDocShell::PerformRetargeting(nsDocShellLoadState* aLoadState) {
true, // aForceNoOpener
getter_AddRefs(newBC));
MOZ_ASSERT(!newBC);
@@ -624,7 +654,7 @@ index 3404597343e0d21c42c5adc2f2849888869cf75a..558f03f30672b9f0fdb68ba8d23a0d87
return rv;
}
-@@ -9569,6 +9804,16 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
+@@ -9572,6 +9826,16 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
nsINetworkPredictor::PREDICT_LOAD, attrs, nullptr);
nsCOMPtr req;
@@ -641,7 +671,7 @@ index 3404597343e0d21c42c5adc2f2849888869cf75a..558f03f30672b9f0fdb68ba8d23a0d87
rv = DoURILoad(aLoadState, aCacheKey, getter_AddRefs(req));
if (NS_SUCCEEDED(rv)) {
-@@ -12732,6 +12977,9 @@ class OnLinkClickEvent : public Runnable {
+@@ -12791,6 +13055,9 @@ class OnLinkClickEvent : public Runnable {
mHandler->OnLinkClickSync(mContent, mLoadState, mNoOpenerImplied,
mTriggeringPrincipal);
}
@@ -651,17 +681,17 @@ index 3404597343e0d21c42c5adc2f2849888869cf75a..558f03f30672b9f0fdb68ba8d23a0d87
return NS_OK;
}
-@@ -12816,6 +13064,8 @@ nsresult nsDocShell::OnLinkClick(
- nsCOMPtr ev =
- new OnLinkClickEvent(this, aContent, loadState, noOpenerImplied,
- aIsTrusted, aTriggeringPrincipal);
+@@ -12877,6 +13144,8 @@ nsresult nsDocShell::OnLinkClick(
+
+ nsCOMPtr ev = new OnLinkClickEvent(
+ this, aContent, loadState, noOpenerImplied, aTriggeringPrincipal);
+ nsCOMPtr observerService = mozilla::services::GetObserverService();
+ observerService->NotifyObservers(ToSupports(aContent), "juggler-link-click", nullptr);
return Dispatch(ev.forget());
}
diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h
-index 82ac6c9ab9dbc102a429ab0fe6cb24b8fcdf477f..f6328c25349cf39fcce973adcf908782e8721447 100644
+index f22a333733322ad17f097d7edd46af21a687906c..6bcf8ca9f9cd64dc9f5695d00e0a3e6a97978f02 100644
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -15,6 +15,7 @@
@@ -672,7 +702,7 @@ index 82ac6c9ab9dbc102a429ab0fe6cb24b8fcdf477f..f6328c25349cf39fcce973adcf908782
#include "mozilla/dom/WindowProxyHolder.h"
#include "nsCOMPtr.h"
#include "nsCharsetSource.h"
-@@ -76,6 +77,7 @@ class nsCommandManager;
+@@ -77,6 +78,7 @@ class nsCommandManager;
class nsDocShellEditorData;
class nsDOMNavigationTiming;
class nsDSURIContentListener;
@@ -680,7 +710,7 @@ index 82ac6c9ab9dbc102a429ab0fe6cb24b8fcdf477f..f6328c25349cf39fcce973adcf908782
class nsGlobalWindowOuter;
class FramingChecker;
-@@ -401,6 +403,15 @@ class nsDocShell final : public nsDocLoader,
+@@ -403,6 +405,15 @@ class nsDocShell final : public nsDocLoader,
void SetWillChangeProcess() { mWillChangeProcess = true; }
bool WillChangeProcess() { return mWillChangeProcess; }
@@ -696,7 +726,7 @@ index 82ac6c9ab9dbc102a429ab0fe6cb24b8fcdf477f..f6328c25349cf39fcce973adcf908782
// Create a content viewer within this nsDocShell for the given
// `WindowGlobalChild` actor.
nsresult CreateDocumentViewerForActor(
-@@ -1004,6 +1015,8 @@ class nsDocShell final : public nsDocLoader,
+@@ -1006,6 +1017,8 @@ class nsDocShell final : public nsDocLoader,
bool CSSErrorReportingEnabled() const { return mCSSErrorReportingEnabled; }
@@ -705,7 +735,7 @@ index 82ac6c9ab9dbc102a429ab0fe6cb24b8fcdf477f..f6328c25349cf39fcce973adcf908782
// Handles retrieval of subframe session history for nsDocShell::LoadURI. If a
// load is requested in a subframe of the current DocShell, the subframe
// loadType may need to reflect the loadType of the parent document, or in
-@@ -1295,6 +1308,16 @@ class nsDocShell final : public nsDocLoader,
+@@ -1285,6 +1298,17 @@ class nsDocShell final : public nsDocLoader,
bool mAllowDNSPrefetch : 1;
bool mAllowWindowControl : 1;
bool mCSSErrorReportingEnabled : 1;
@@ -718,12 +748,13 @@ index 82ac6c9ab9dbc102a429ab0fe6cb24b8fcdf477f..f6328c25349cf39fcce973adcf908782
+ RefPtr mGeolocationServiceOverride;
+ ReducedMotionOverride mReducedMotionOverride;
+ ForcedColorsOverride mForcedColorsOverride;
++ ContrastOverride mContrastOverride;
+
bool mAllowAuth : 1;
bool mAllowKeywordFixup : 1;
bool mDisableMetaRefreshWhenInactive : 1;
diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl
-index 21f09a517e91644f81f5bb823f556c15cd06e51f..a68d30e0a60f03a0942ac1cd8a1f83804fdfd3e0 100644
+index 84e821e33e8164829dfee4f05340784e189b90ee..aa690eb747cb73bc6bff40a62546037c2e64c485 100644
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -44,6 +44,7 @@ interface nsIURI;
@@ -734,7 +765,7 @@ index 21f09a517e91644f81f5bb823f556c15cd06e51f..a68d30e0a60f03a0942ac1cd8a1f8380
interface nsIEditor;
interface nsIEditingSession;
interface nsIInputStream;
-@@ -754,6 +755,36 @@ interface nsIDocShell : nsIDocShellTreeItem
+@@ -719,6 +720,45 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
void synchronizeLayoutHistoryState();
@@ -766,16 +797,25 @@ index 21f09a517e91644f81f5bb823f556c15cd06e51f..a68d30e0a60f03a0942ac1cd8a1f8380
+ };
+ [infallible] attribute nsIDocShell_ForcedColorsOverride forcedColorsOverride;
+
++ cenum ContrastOverride : 8 {
++ CONTRAST_OVERRIDE_LESS,
++ CONTRAST_OVERRIDE_MORE,
++ CONTRAST_OVERRIDE_CUSTOM,
++ CONTRAST_OVERRIDE_NO_PREFERENCE,
++ CONTRAST_OVERRIDE_NONE, /* This clears the override. */
++ };
++ [infallible] attribute nsIDocShell_ContrastOverride contrastOverride;
++
+ void setGeolocationOverride(in nsIDOMGeoPosition position);
+
/**
* This attempts to save any applicable layout history state (like
* scroll position) in the nsISHEntry. This is normally done
diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp
-index 4e9286a91e3b0f1114aa0a7aa6ff81dde615a73d..941a0c3dac71008ca760024a1e828f75f6af5182 100644
+index fd2d0be5f7755e64fc134515ea138c4ed0d28daf..ae48159ddbfb98d03e538d077a33260c639a74ac 100644
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
-@@ -3676,6 +3676,9 @@ void Document::SendToConsole(nsCOMArray& aMessages) {
+@@ -3752,6 +3752,9 @@ void Document::SendToConsole(nsCOMArray& aMessages) {
}
void Document::ApplySettingsFromCSP(bool aSpeculative) {
@@ -785,7 +825,7 @@ index 4e9286a91e3b0f1114aa0a7aa6ff81dde615a73d..941a0c3dac71008ca760024a1e828f75
nsresult rv = NS_OK;
if (!aSpeculative) {
// 1) apply settings from regular CSP
-@@ -3733,6 +3736,11 @@ nsresult Document::InitCSP(nsIChannel* aChannel) {
+@@ -3809,6 +3812,11 @@ nsresult Document::InitCSP(nsIChannel* aChannel) {
MOZ_ASSERT(!mScriptGlobalObject,
"CSP must be initialized before mScriptGlobalObject is set!");
@@ -797,7 +837,7 @@ index 4e9286a91e3b0f1114aa0a7aa6ff81dde615a73d..941a0c3dac71008ca760024a1e828f75
// If this is a data document - no need to set CSP.
if (mLoadedAsData) {
return NS_OK;
-@@ -4500,6 +4508,10 @@ bool Document::HasFocus(ErrorResult& rv) const {
+@@ -4617,6 +4625,10 @@ bool Document::HasFocus(ErrorResult& rv) const {
return false;
}
@@ -808,7 +848,7 @@ index 4e9286a91e3b0f1114aa0a7aa6ff81dde615a73d..941a0c3dac71008ca760024a1e828f75
if (!fm->IsInActiveWindow(bc)) {
return false;
}
-@@ -18849,6 +18861,66 @@ ColorScheme Document::PreferredColorScheme(IgnoreRFP aIgnoreRFP) const {
+@@ -19688,6 +19700,35 @@ ColorScheme Document::PreferredColorScheme(IgnoreRFP aIgnoreRFP) const {
return PreferenceSheet::PrefsFor(*this).mColorScheme;
}
@@ -840,60 +880,28 @@ index 4e9286a91e3b0f1114aa0a7aa6ff81dde615a73d..941a0c3dac71008ca760024a1e828f75
+
+ return LookAndFeel::GetInt(LookAndFeel::IntID::PrefersReducedMotion, 0) == 1;
+}
-+
-+bool Document::ForcedColors() const {
-+ auto* docShell = static_cast(GetDocShell());
-+ nsIDocShell::ForcedColorsOverride forcedColors;
-+ if (docShell && docShell->GetForcedColorsOverride(&forcedColors) == NS_OK) {
-+ switch (forcedColors) {
-+ case nsIDocShell::FORCED_COLORS_OVERRIDE_ACTIVE:
-+ return true;
-+ case nsIDocShell::FORCED_COLORS_OVERRIDE_NONE:
-+ return false;
-+ case nsIDocShell::FORCED_COLORS_OVERRIDE_NO_OVERRIDE:
-+ break;
-+ };
-+ }
-+
-+ if (auto* bc = GetBrowsingContext()) {
-+ switch (bc->Top()->ForcedColorsOverride()) {
-+ case dom::ForcedColorsOverride::Active:
-+ return true;
-+ case dom::ForcedColorsOverride::None:
-+ return false;
-+ case dom::ForcedColorsOverride::No_override:
-+ break;
-+ }
-+ }
-+
-+ if (mIsBeingUsedAsImage) {
-+ return false;
-+ }
-+ return !PreferenceSheet::PrefsFor(*this).mUseDocumentColors;
-+}
+
bool Document::HasRecentlyStartedForegroundLoads() {
if (!sLoadingForegroundTopLevelContentDocument) {
return false;
diff --git a/dom/base/Document.h b/dom/base/Document.h
-index a52c61addffc4a2344fa06cb0bceebe6a7ca9075..b0f8d65e5341bf277e48bef3b88cb4cc384fbc49 100644
+index 622f54e369d324a4cc2800dd4b331bd628339bed..2ef6ed20cf35febeff75b22dfa5bb2fbb4e295fe 100644
--- a/dom/base/Document.h
+++ b/dom/base/Document.h
-@@ -4044,6 +4044,9 @@ class Document : public nsINode,
+@@ -4140,6 +4140,8 @@ class Document : public nsINode,
// color-scheme meta tag.
ColorScheme DefaultColorScheme() const;
+ bool PrefersReducedMotion() const;
-+ bool ForcedColors() const;
+
static bool HasRecentlyStartedForegroundLoads();
static bool AutomaticStorageAccessPermissionCanBeGranted(
diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp
-index 14a00b8ed85f69312a89990acbb5e0f9755bd832..4b07c28615920a95a2ba59247f8575515cac4235 100644
+index a13cae5b990fb2f750e62f5117ad63aa981d787f..bc0f2d674aadd8eba867f56e873595a8885d1798 100644
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
-@@ -338,14 +338,18 @@ void Navigator::GetAppName(nsAString& aAppName) const {
+@@ -344,14 +344,18 @@ void Navigator::GetAppName(nsAString& aAppName) const {
* for more detail.
*/
/* static */
@@ -914,7 +922,7 @@ index 14a00b8ed85f69312a89990acbb5e0f9755bd832..4b07c28615920a95a2ba59247f857551
// Split values on commas.
for (nsDependentSubstring lang :
-@@ -397,7 +401,13 @@ void Navigator::GetLanguage(nsAString& aLanguage) {
+@@ -403,7 +407,13 @@ void Navigator::GetLanguage(nsAString& aLanguage) {
}
void Navigator::GetLanguages(nsTArray& aLanguages) {
@@ -929,11 +937,21 @@ index 14a00b8ed85f69312a89990acbb5e0f9755bd832..4b07c28615920a95a2ba59247f857551
// The returned value is cached by the binding code. The window listens to the
// accept languages change and will clear the cache when needed. It has to
+@@ -2298,7 +2308,8 @@ bool Navigator::Webdriver() {
+ }
+ #endif
+
+- return false;
++ // Playwright is automating the browser, so we should pretend to be a webdriver
++ return true;
+ }
+
+ AutoplayPolicy Navigator::GetAutoplayPolicy(AutoplayPolicyMediaType aType) {
diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h
-index e559dc4d6aef61b7012a27f3d6c3186a12a15319..9798a50789ce972c4d9e94419e20a5cde4cd552a 100644
+index 6abf6cef230c97815f17f6b7abf9f1b1de274a6f..46ead1f32e0d710b5b32e61dff72a4f772d5421e 100644
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
-@@ -215,7 +215,7 @@ class Navigator final : public nsISupports, public nsWrapperCache {
+@@ -218,7 +218,7 @@ class Navigator final : public nsISupports, public nsWrapperCache {
StorageManager* Storage();
@@ -943,94 +961,95 @@ index e559dc4d6aef61b7012a27f3d6c3186a12a15319..9798a50789ce972c4d9e94419e20a5cd
dom::MediaCapabilities* MediaCapabilities();
dom::MediaSession* MediaSession();
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
-index c6f1687f73df6b1849a191ff8722dc9fc26fc3eb..9fdface27d5c9bd0c61b8af229a31be2356c46b5 100644
+index f362a444a0f5ed247582646754dffd54d0b4540a..bbd72dab7ff4fbac8c247961e530764cb5c68d11 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
-@@ -8711,7 +8711,8 @@ nsresult nsContentUtils::SendMouseEvent(
- bool aIgnoreRootScrollFrame, float aPressure,
- unsigned short aInputSourceArg, uint32_t aIdentifier, bool aToWindow,
- PreventDefaultResult* aPreventDefault, bool aIsDOMEventSynthesized,
+@@ -9151,11 +9151,13 @@ nsresult nsContentUtils::SendMouseEvent(
+ int32_t aClickCount, int32_t aModifiers, bool aIgnoreRootScrollFrame,
+ float aPressure, unsigned short aInputSourceArg, uint32_t aIdentifier,
+ bool aToWindow, bool* aPreventDefault, bool aIsDOMEventSynthesized,
- bool aIsWidgetEventSynthesized) {
+ bool aIsWidgetEventSynthesized,
+ bool convertToPointer, uint32_t aJugglerEventId) {
- nsPoint offset;
- nsCOMPtr widget = GetWidget(aPresShell, &offset);
- if (!widget) return NS_ERROR_FAILURE;
-@@ -8719,6 +8720,7 @@ nsresult nsContentUtils::SendMouseEvent(
+ MOZ_ASSERT(aWidget);
EventMessage msg;
Maybe exitFrom;
bool contextMenuKey = false;
-+ bool isDragEvent = false;
++ bool isPWDragEventMessage = false;
if (aType.EqualsLiteral("mousedown")) {
msg = eMouseDown;
} else if (aType.EqualsLiteral("mouseup")) {
-@@ -8743,6 +8745,12 @@ nsresult nsContentUtils::SendMouseEvent(
+@@ -9181,6 +9183,12 @@ nsresult nsContentUtils::SendMouseEvent(
msg = eMouseHitTest;
} else if (aType.EqualsLiteral("MozMouseExploreByTouch")) {
msg = eMouseExploreByTouch;
+ } else if (aType.EqualsLiteral("dragover")) {
+ msg = eDragOver;
-+ isDragEvent = true;
++ isPWDragEventMessage = true;
+ } else if (aType.EqualsLiteral("drop")) {
+ msg = eDrop;
-+ isDragEvent = true;
++ isPWDragEventMessage = true;
} else {
return NS_ERROR_FAILURE;
}
-@@ -8751,12 +8759,21 @@ nsresult nsContentUtils::SendMouseEvent(
- aInputSourceArg = MouseEvent_Binding::MOZ_SOURCE_MOUSE;
- }
+@@ -9191,7 +9199,14 @@ nsresult nsContentUtils::SendMouseEvent(
-- WidgetMouseEvent event(true, msg, widget,
-+ std::unique_ptr eventOwner;
-+ if (isDragEvent) {
-+ eventOwner.reset(new WidgetDragEvent(true, msg, widget));
-+ eventOwner->mReason = aIsWidgetEventSynthesized
+ Maybe pointerEvent;
+ Maybe mouseEvent;
+- if (IsPointerEventMessage(msg)) {
++ Maybe pwDragEvent;
++
++ if (isPWDragEventMessage) {
++ pwDragEvent.emplace(true, msg, aWidget);
++ pwDragEvent->mReason = aIsWidgetEventSynthesized
+ ? WidgetMouseEvent::eSynthesized
+ : WidgetMouseEvent::eReal;
-+ } else {
-+ eventOwner.reset(new WidgetMouseEvent(true, msg, widget,
- aIsWidgetEventSynthesized
- ? WidgetMouseEvent::eSynthesized
- : WidgetMouseEvent::eReal,
- contextMenuKey ? WidgetMouseEvent::eContextMenuKey
-- : WidgetMouseEvent::eNormal);
-+ : WidgetMouseEvent::eNormal));
-+ }
-+ WidgetMouseEvent& event = *eventOwner.get();
- event.pointerId = aIdentifier;
- event.mModifiers = GetWidgetModifiers(aModifiers);
- event.mButton = aButton;
-@@ -8767,8 +8784,10 @@ nsresult nsContentUtils::SendMouseEvent(
- event.mPressure = aPressure;
- event.mInputSource = aInputSourceArg;
- event.mClickCount = aClickCount;
-+ event.mJugglerEventId = aJugglerEventId;
- event.mFlags.mIsSynthesizedForTests = aIsDOMEventSynthesized;
- event.mExitFrom = exitFrom;
-+ event.convertToPointer = convertToPointer;
++ } else if (IsPointerEventMessage(msg)) {
+ MOZ_ASSERT(!aIsWidgetEventSynthesized,
+ "The event shouldn't be dispatched as a synthesized event");
+ if (MOZ_UNLIKELY(aIsWidgetEventSynthesized)) {
+@@ -9210,8 +9225,11 @@ nsresult nsContentUtils::SendMouseEvent(
+ contextMenuKey ? WidgetMouseEvent::eContextMenuKey
+ : WidgetMouseEvent::eNormal);
+ }
++
+ WidgetMouseEvent& mouseOrPointerEvent =
++ pwDragEvent.isSome() ? pwDragEvent.ref() :
+ pointerEvent.isSome() ? pointerEvent.ref() : mouseEvent.ref();
++
+ mouseOrPointerEvent.pointerId = aIdentifier;
+ mouseOrPointerEvent.mModifiers = GetWidgetModifiers(aModifiers);
+ mouseOrPointerEvent.mButton = aButton;
+@@ -9224,6 +9242,8 @@ nsresult nsContentUtils::SendMouseEvent(
+ mouseOrPointerEvent.mClickCount = aClickCount;
+ mouseOrPointerEvent.mFlags.mIsSynthesizedForTests = aIsDOMEventSynthesized;
+ mouseOrPointerEvent.mExitFrom = exitFrom;
++ mouseOrPointerEvent.mJugglerEventId = aJugglerEventId;
++ mouseOrPointerEvent.convertToPointer = convertToPointer;
nsPresContext* presContext = aPresShell->GetPresContext();
if (!presContext) return NS_ERROR_FAILURE;
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
-index 338fc097dede02a538f240ba4cc66307086c7f56..8345e47237bc40490bd17019a053cce4c3d74a91 100644
+index 779cd9e544bfb2d135f12c3558c0ca8164b37029..041eba4bcbf40f51fc40ce7609ea81408e6a788d 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
-@@ -3055,7 +3055,8 @@ class nsContentUtils {
+@@ -3015,8 +3015,9 @@ class nsContentUtils {
+ int32_t aButton, int32_t aButtons, int32_t aClickCount,
int32_t aModifiers, bool aIgnoreRootScrollFrame, float aPressure,
unsigned short aInputSourceArg, uint32_t aIdentifier, bool aToWindow,
- mozilla::PreventDefaultResult* aPreventDefault,
-- bool aIsDOMEventSynthesized, bool aIsWidgetEventSynthesized);
+- bool* aPreventDefault, bool aIsDOMEventSynthesized,
+- bool aIsWidgetEventSynthesized);
++ bool* aPreventDefault,
+ bool aIsDOMEventSynthesized, bool aIsWidgetEventSynthesized,
+ bool convertToPointer = true, uint32_t aJugglerEventId = 0);
static void FirePageShowEventForFrameLoaderSwap(
nsIDocShellTreeItem* aItem,
diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp
-index 9bc8340b9009717e0feecd5c14ff02be07a03daf..70ea04c7f11e6ccfadf72a82ec1741fac10ef5fd 100644
+index 15fe1db8a28ed2592b61aaf2006ddaa656f12389..2642c18bebcdfdd467be557171ba4ee204fcabde 100644
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
-@@ -685,6 +685,26 @@ nsDOMWindowUtils::GetPresShellId(uint32_t* aPresShellId) {
+@@ -710,6 +710,26 @@ nsDOMWindowUtils::GetPresShellId(uint32_t* aPresShellId) {
return NS_ERROR_FAILURE;
}
@@ -1057,7 +1076,7 @@ index 9bc8340b9009717e0feecd5c14ff02be07a03daf..70ea04c7f11e6ccfadf72a82ec1741fa
NS_IMETHODIMP
nsDOMWindowUtils::SendMouseEvent(
const nsAString& aType, float aX, float aY, int32_t aButton,
-@@ -699,7 +719,7 @@ nsDOMWindowUtils::SendMouseEvent(
+@@ -724,7 +744,7 @@ nsDOMWindowUtils::SendMouseEvent(
aOptionalArgCount >= 7 ? aIdentifier : DEFAULT_MOUSE_POINTER_ID, false,
aPreventDefault, aOptionalArgCount >= 4 ? aIsDOMEventSynthesized : true,
aOptionalArgCount >= 5 ? aIsWidgetEventSynthesized : false,
@@ -1066,7 +1085,7 @@ index 9bc8340b9009717e0feecd5c14ff02be07a03daf..70ea04c7f11e6ccfadf72a82ec1741fa
}
NS_IMETHODIMP
-@@ -717,7 +737,7 @@ nsDOMWindowUtils::SendMouseEventToWindow(
+@@ -742,7 +762,7 @@ nsDOMWindowUtils::SendMouseEventToWindow(
aOptionalArgCount >= 7 ? aIdentifier : DEFAULT_MOUSE_POINTER_ID, true,
nullptr, aOptionalArgCount >= 4 ? aIsDOMEventSynthesized : true,
aOptionalArgCount >= 5 ? aIsWidgetEventSynthesized : false,
@@ -1075,27 +1094,29 @@ index 9bc8340b9009717e0feecd5c14ff02be07a03daf..70ea04c7f11e6ccfadf72a82ec1741fa
}
NS_IMETHODIMP
-@@ -726,13 +746,13 @@ nsDOMWindowUtils::SendMouseEventCommon(
+@@ -751,7 +771,7 @@ nsDOMWindowUtils::SendMouseEventCommon(
int32_t aClickCount, int32_t aModifiers, bool aIgnoreRootScrollFrame,
float aPressure, unsigned short aInputSourceArg, uint32_t aPointerId,
bool aToWindow, bool* aPreventDefault, bool aIsDOMEventSynthesized,
- bool aIsWidgetEventSynthesized, int32_t aButtons) {
+ bool aIsWidgetEventSynthesized, int32_t aButtons, bool aConvertToPointer, uint32_t aJugglerEventId) {
RefPtr presShell = GetPresShell();
- PreventDefaultResult preventDefaultResult;
- nsresult rv = nsContentUtils::SendMouseEvent(
- presShell, aType, aX, aY, aButton, aButtons, aClickCount, aModifiers,
- aIgnoreRootScrollFrame, aPressure, aInputSourceArg, aPointerId, aToWindow,
-- &preventDefaultResult, aIsDOMEventSynthesized, aIsWidgetEventSynthesized);
-+ &preventDefaultResult, aIsDOMEventSynthesized, aIsWidgetEventSynthesized, aConvertToPointer, aJugglerEventId);
-
- if (aPreventDefault) {
- *aPreventDefault = preventDefaultResult != PreventDefaultResult::No;
+ if (!presShell) {
+ return NS_ERROR_FAILURE;
+@@ -768,7 +788,7 @@ nsDOMWindowUtils::SendMouseEventCommon(
+ presShell, widget, aType, refPoint, aButton, aButtons, aClickCount,
+ aModifiers, aIgnoreRootScrollFrame, aPressure, aInputSourceArg,
+ aPointerId, aToWindow, aPreventDefault, aIsDOMEventSynthesized,
+- aIsWidgetEventSynthesized);
++ aIsWidgetEventSynthesized, aConvertToPointer, aJugglerEventId);
+ }
+
+ NS_IMETHODIMP
diff --git a/dom/base/nsDOMWindowUtils.h b/dom/base/nsDOMWindowUtils.h
-index 63968c9b7a4e418e4c0de6e7a75fa215a36a9105..decf3ea3833ccdffd49a7aded2d600f9416e8306 100644
+index a8a48d28fc4ef612f8234bc2490a41672f1704f5..f702b0c9a0783ec547a41bbefd68e18a27a239fe 100644
--- a/dom/base/nsDOMWindowUtils.h
+++ b/dom/base/nsDOMWindowUtils.h
-@@ -93,7 +93,7 @@ class nsDOMWindowUtils final : public nsIDOMWindowUtils,
+@@ -94,7 +94,7 @@ class nsDOMWindowUtils final : public nsIDOMWindowUtils,
int32_t aClickCount, int32_t aModifiers, bool aIgnoreRootScrollFrame,
float aPressure, unsigned short aInputSourceArg, uint32_t aIdentifier,
bool aToWindow, bool* aPreventDefault, bool aIsDOMEventSynthesized,
@@ -1105,10 +1126,10 @@ index 63968c9b7a4e418e4c0de6e7a75fa215a36a9105..decf3ea3833ccdffd49a7aded2d600f9
MOZ_CAN_RUN_SCRIPT
nsresult SendTouchEventCommon(
diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp
-index 5a4cf78d65eee0adcbeca33787706113eca19de7..7c8016e422ccc9e86563eaa83c9acc1dad0e5967 100644
+index 555a08b4b3fcd0d0c7986014d2e3516c6e5991c0..74a39e000b0e68042f1f51f6fafbc39ac9b42e51 100644
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
-@@ -1675,6 +1675,10 @@ Maybe nsFocusManager::SetFocusInner(Element* aNewContent,
+@@ -1720,6 +1720,10 @@ Maybe nsFocusManager::SetFocusInner(Element* aNewContent,
(GetActiveBrowsingContext() == newRootBrowsingContext);
}
@@ -1119,7 +1140,7 @@ index 5a4cf78d65eee0adcbeca33787706113eca19de7..7c8016e422ccc9e86563eaa83c9acc1d
// Exit fullscreen if a website focuses another window
if (StaticPrefs::full_screen_api_exit_on_windowRaise() &&
!isElementInActiveWindow && (aFlags & FLAG_RAISE)) {
-@@ -2242,6 +2246,7 @@ bool nsFocusManager::BlurImpl(BrowsingContext* aBrowsingContextToClear,
+@@ -2306,6 +2310,7 @@ bool nsFocusManager::BlurImpl(BrowsingContext* aBrowsingContextToClear,
bool aIsLeavingDocument, bool aAdjustWidget,
bool aRemainActive, Element* aElementToFocus,
uint64_t aActionId) {
@@ -1127,7 +1148,7 @@ index 5a4cf78d65eee0adcbeca33787706113eca19de7..7c8016e422ccc9e86563eaa83c9acc1d
LOGFOCUS(("<>", aActionId));
// hold a reference to the focused content, which may be null
-@@ -2288,6 +2293,11 @@ bool nsFocusManager::BlurImpl(BrowsingContext* aBrowsingContextToClear,
+@@ -2352,6 +2357,11 @@ bool nsFocusManager::BlurImpl(BrowsingContext* aBrowsingContextToClear,
return true;
}
@@ -1139,7 +1160,7 @@ index 5a4cf78d65eee0adcbeca33787706113eca19de7..7c8016e422ccc9e86563eaa83c9acc1d
// Keep a ref to presShell since dispatching the DOM event may cause
// the document to be destroyed.
RefPtr presShell = docShell->GetPresShell();
-@@ -2947,7 +2957,9 @@ void nsFocusManager::RaiseWindow(nsPIDOMWindowOuter* aWindow,
+@@ -3066,7 +3076,9 @@ void nsFocusManager::RaiseWindow(nsPIDOMWindowOuter* aWindow,
}
}
@@ -1151,10 +1172,10 @@ index 5a4cf78d65eee0adcbeca33787706113eca19de7..7c8016e422ccc9e86563eaa83c9acc1d
// care of lowering the present active window. This happens in
// a separate runnable to avoid touching multiple windows in
diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp
-index e28dcdb092b23558702377af32eece5d273d4cf3..a37ae9d6ccd978d5e84562450e7039d6a75d517b 100644
+index 99a5049a3aff2efb208895d60622fd9c8d7f337a..9a9b039a46f1294a8b4af0613fb4f4173ac6a8a0 100644
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
-@@ -2509,10 +2509,16 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
+@@ -2512,10 +2512,16 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
}();
if (!isContentAboutBlankInChromeDocshell) {
@@ -1175,7 +1196,7 @@ index e28dcdb092b23558702377af32eece5d273d4cf3..a37ae9d6ccd978d5e84562450e7039d6
}
}
-@@ -2632,6 +2638,19 @@ void nsGlobalWindowOuter::DispatchDOMWindowCreated() {
+@@ -2635,6 +2641,19 @@ void nsGlobalWindowOuter::DispatchDOMWindowCreated() {
}
}
@@ -1196,10 +1217,10 @@ index e28dcdb092b23558702377af32eece5d273d4cf3..a37ae9d6ccd978d5e84562450e7039d6
void nsGlobalWindowOuter::SetDocShell(nsDocShell* aDocShell) {
diff --git a/dom/base/nsGlobalWindowOuter.h b/dom/base/nsGlobalWindowOuter.h
-index 8337a7353fb8e97372f0b57bd0fd867506a9129f..e7dedd6d26125e481e1145337a0be6ab864c1e1b 100644
+index 0453a18ec10c1434d1692f10b1b4acee754e6b7e..ee7bad691515bb51f6b4345e88944b02ad173180 100644
--- a/dom/base/nsGlobalWindowOuter.h
+++ b/dom/base/nsGlobalWindowOuter.h
-@@ -315,6 +315,7 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
+@@ -320,6 +320,7 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
// Outer windows only.
void DispatchDOMWindowCreated();
@@ -1208,10 +1229,10 @@ index 8337a7353fb8e97372f0b57bd0fd867506a9129f..e7dedd6d26125e481e1145337a0be6ab
// Outer windows only.
virtual void EnsureSizeAndPositionUpToDate() override;
diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp
-index d5455e559639aee9328905b50f02c52e94db950b..3fbd1e0459e5391066fc6b3a4e30a841594b31bf 100644
+index 8e2bbed21c13f23745e2eaad4ded831106ebd930..a17b0c7b9730737f178c05703b08d0f5f6d9ecd1 100644
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
-@@ -1365,6 +1365,61 @@ void nsINode::GetBoxQuadsFromWindowOrigin(const BoxQuadOptions& aOptions,
+@@ -1449,6 +1449,61 @@ void nsINode::GetBoxQuadsFromWindowOrigin(const BoxQuadOptions& aOptions,
mozilla::GetBoxQuadsFromWindowOrigin(this, aOptions, aResult, aRv);
}
@@ -1274,10 +1295,10 @@ index d5455e559639aee9328905b50f02c52e94db950b..3fbd1e0459e5391066fc6b3a4e30a841
DOMQuad& aQuad, const GeometryNode& aFrom,
const ConvertCoordinateOptions& aOptions, CallerType aCallerType,
diff --git a/dom/base/nsINode.h b/dom/base/nsINode.h
-index 3a47992cc89176fe9500f7b1d5b74e4422cb9625..27e6da8498af5e4a3c37407a3a8ab592e28dc372 100644
+index eb75f281630f8ca1b901686207c9fc97336d675f..e607f0ae454d52fc2bfe19046b492352a84b4ebd 100644
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
-@@ -2248,6 +2248,10 @@ class nsINode : public mozilla::dom::EventTarget {
+@@ -2397,6 +2397,10 @@ class nsINode : public mozilla::dom::EventTarget {
nsTArray>& aResult,
ErrorResult& aRv);
@@ -1289,10 +1310,10 @@ index 3a47992cc89176fe9500f7b1d5b74e4422cb9625..27e6da8498af5e4a3c37407a3a8ab592
DOMQuad& aQuad, const TextOrElementOrDocument& aFrom,
const ConvertCoordinateOptions& aOptions, CallerType aCallerType,
diff --git a/dom/base/nsJSUtils.cpp b/dom/base/nsJSUtils.cpp
-index cf8037cd580013efe5eb578c43f45c0d21946c6a..583460796fdef633e8075013597f7c315ce4ab06 100644
+index bf7eb34da03c0958de688deecb53b407d430f645..a2ec3b1b7e86f72bee38d890c0834abfe4be8637 100644
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
-@@ -177,6 +177,11 @@ bool nsJSUtils::GetScopeChainForElement(
+@@ -149,6 +149,11 @@ bool nsJSUtils::GetEnvironmentChainForElement(JSContext* aCx, Element* aElement,
return true;
}
@@ -1305,23 +1326,23 @@ index cf8037cd580013efe5eb578c43f45c0d21946c6a..583460796fdef633e8075013597f7c31
void nsJSUtils::ResetTimeZone() { JS::ResetTimeZone(); }
diff --git a/dom/base/nsJSUtils.h b/dom/base/nsJSUtils.h
-index cceb725d393d5e5f83c8f87491089c3fa1d57cc3..e906a7fb7c3fd72554613f640dcc272e6984d929 100644
+index f32e21752d5013bf143eb45391ab9218debab08e..83763d2354dade2f8d2b7930ba18ae91c55133ad 100644
--- a/dom/base/nsJSUtils.h
+++ b/dom/base/nsJSUtils.h
-@@ -79,6 +79,7 @@ class nsJSUtils {
- JSContext* aCx, mozilla::dom::Element* aElement,
- JS::MutableHandleVector aScopeChain);
+@@ -75,6 +75,7 @@ class nsJSUtils {
+ mozilla::dom::Element* aElement,
+ JS::EnvironmentChain& aEnvChain);
+ static bool SetTimeZoneOverride(const char* timezoneId);
static void ResetTimeZone();
static bool DumpEnabled();
diff --git a/dom/chrome-webidl/BrowsingContext.webidl b/dom/chrome-webidl/BrowsingContext.webidl
-index d70f3e18cc8e8f749e5057297161206129871453..2f2be2a6539203d1957bfe580a06ab70a512c053 100644
+index 6ec88536141126c97c9b599e3237bb5670d42ce8..41c6cc56738bdaf711adf2cf5b00c7fad5d71ba8 100644
--- a/dom/chrome-webidl/BrowsingContext.webidl
+++ b/dom/chrome-webidl/BrowsingContext.webidl
-@@ -53,6 +53,24 @@ enum PrefersColorSchemeOverride {
- "dark",
+@@ -61,6 +61,26 @@ enum ForcedColorsOverride {
+ "active",
};
+/**
@@ -1334,35 +1355,73 @@ index d70f3e18cc8e8f749e5057297161206129871453..2f2be2a6539203d1957bfe580a06ab70
+};
+
+/**
-+ * CSS forced-colors values.
++ * CSS prefers-contrast values.
+ */
-+enum ForcedColorsOverride {
++enum PrefersContrastOverride {
+ "none",
-+ "active",
-+ "no-override", /* This clears the override. */
++ "no-preference",
++ "more",
++ "less",
++ "custom",
+};
+
/**
* Allowed overrides of platform/pref default behaviour for touch events.
*/
-@@ -209,6 +227,12 @@ interface BrowsingContext {
- // Color-scheme simulation, for DevTools.
- [SetterThrows] attribute PrefersColorSchemeOverride prefersColorSchemeOverride;
+@@ -220,6 +240,12 @@ interface BrowsingContext {
+ // Forced-colors simulation, for DevTools
+ [SetterThrows] attribute ForcedColorsOverride forcedColorsOverride;
+ // Reduced-Motion simulation, for DevTools.
+ [SetterThrows] attribute PrefersReducedMotionOverride prefersReducedMotionOverride;
+
-+ // Forced-Colors simulation, for DevTools.
-+ [SetterThrows] attribute ForcedColorsOverride forcedColorsOverride;
++ // Contrast simulation, for DevTools.
++ [SetterThrows] attribute PrefersContrastOverride prefersContrastOverride;
+
/**
* A unique identifier for the browser element that is hosting this
* BrowsingContext tree. Every BrowsingContext in the element's tree will
+diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp
+index 0bd219694282347309680fc9b53b945e1fd0ad92..c5c2e2d32a380ec72379b05a8b84f187431f7309 100644
+--- a/dom/fetch/Fetch.cpp
++++ b/dom/fetch/Fetch.cpp
+@@ -701,6 +701,12 @@ already_AddRefed FetchRequest(nsIGlobalObject* aGlobal,
+ ipcArgs.hasCSPEventListener() = false;
+ ipcArgs.isWorkerRequest() = false;
+
++ /* --> Playwright: associate keep-alive fetch with the window */
++ BrowsingContext* bc = window ? window->GetBrowsingContext() : nullptr;
++ if (bc)
++ ipcArgs.associatedBrowsingContextID() = bc->Id();
++ /* <-- Playwright */
++
+ actor->DoFetchOp(ipcArgs);
+
+ mozilla::glean::networking::fetch_keepalive_request_count.Get("main"_ns)
+diff --git a/dom/fetch/FetchService.cpp b/dom/fetch/FetchService.cpp
+index b5e60bbd27fbb2f033d233e9ae2ebc728f442512..0adc568ece34d2c0f35eeacd81e2db9125b7c327 100644
+--- a/dom/fetch/FetchService.cpp
++++ b/dom/fetch/FetchService.cpp
+@@ -268,6 +268,14 @@ RefPtr FetchService::FetchInstance::Fetch() {
+ false // IsTrackingFetch
+ );
+
++ /* --> Playwright: associate keep-alive fetch with the window */
++ if (mArgsType == FetchArgsType::MainThreadFetch) {
++ auto& args = mArgs.as();
++ mFetchDriver->SetAssociatedBrowsingContextID(
++ args.mAssociatedBrowsingContextID);
++ }
++ /* <-- Playwright */
++
+ if (mArgsType == FetchArgsType::WorkerFetch) {
+ auto& args = mArgs.as();
+ mFetchDriver->SetWorkerScript(args.mWorkerScript);
diff --git a/dom/geolocation/Geolocation.cpp b/dom/geolocation/Geolocation.cpp
-index cb9107deb1acfc6f9f3efe87144fcd9bbccd9231..5034c066db8e13dbd01b9bbe79ac2447135f3360 100644
+index 7c653fe131dc34d35ffdc030950071adb31a9fc9..b23442a42ba8ee270e8e38930e59ae15c2a29039 100644
--- a/dom/geolocation/Geolocation.cpp
+++ b/dom/geolocation/Geolocation.cpp
-@@ -23,6 +23,7 @@
+@@ -28,6 +28,7 @@
#include "nsComponentManagerUtils.h"
#include "nsContentPermissionHelper.h"
#include "nsContentUtils.h"
@@ -1370,7 +1429,7 @@ index cb9107deb1acfc6f9f3efe87144fcd9bbccd9231..5034c066db8e13dbd01b9bbe79ac2447
#include "nsGlobalWindowInner.h"
#include "mozilla/dom/Document.h"
#include "nsINamed.h"
-@@ -256,10 +257,8 @@ nsGeolocationRequest::Allow(JS::Handle aChoices) {
+@@ -428,10 +429,8 @@ nsGeolocationRequest::Allow(JS::Handle aChoices) {
return NS_OK;
}
@@ -1383,7 +1442,7 @@ index cb9107deb1acfc6f9f3efe87144fcd9bbccd9231..5034c066db8e13dbd01b9bbe79ac2447
CachedPositionAndAccuracy lastPosition = gs->GetCachedPosition();
if (lastPosition.position) {
EpochTimeStamp cachedPositionTime_ms;
-@@ -437,8 +436,7 @@ void nsGeolocationRequest::Shutdown() {
+@@ -639,8 +638,7 @@ void nsGeolocationRequest::Shutdown() {
// If there are no other high accuracy requests, the geolocation service will
// notify the provider to switch to the default accuracy.
if (mOptions && mOptions->mEnableHighAccuracy) {
@@ -1393,7 +1452,7 @@ index cb9107deb1acfc6f9f3efe87144fcd9bbccd9231..5034c066db8e13dbd01b9bbe79ac2447
if (gs) {
gs->UpdateAccuracy();
}
-@@ -727,8 +725,14 @@ void nsGeolocationService::StopDevice() {
+@@ -957,8 +955,14 @@ void nsGeolocationService::StopDevice() {
StaticRefPtr nsGeolocationService::sService;
already_AddRefed
@@ -1409,7 +1468,7 @@ index cb9107deb1acfc6f9f3efe87144fcd9bbccd9231..5034c066db8e13dbd01b9bbe79ac2447
if (nsGeolocationService::sService) {
result = nsGeolocationService::sService;
-@@ -820,7 +824,9 @@ nsresult Geolocation::Init(nsPIDOMWindowInner* aContentDom) {
+@@ -1050,7 +1054,9 @@ nsresult Geolocation::Init(nsPIDOMWindowInner* aContentDom) {
// If no aContentDom was passed into us, we are being used
// by chrome/c++ and have no mOwner, no mPrincipal, and no need
// to prompt.
@@ -1421,7 +1480,7 @@ index cb9107deb1acfc6f9f3efe87144fcd9bbccd9231..5034c066db8e13dbd01b9bbe79ac2447
mService->AddLocator(this);
}
diff --git a/dom/geolocation/Geolocation.h b/dom/geolocation/Geolocation.h
-index 7e1af00d05fbafa2d828e2c7e4dcc5c82d115f5b..e85af9718d064e4d2865bc944e9d4ba1efb9a5d7 100644
+index 992de29b5d2d09c19e55ebb2502215ec9d05a171..cdc20567b693283b0fd5a5923f7ea54210bd1712 100644
--- a/dom/geolocation/Geolocation.h
+++ b/dom/geolocation/Geolocation.h
@@ -31,6 +31,7 @@
@@ -1432,7 +1491,7 @@ index 7e1af00d05fbafa2d828e2c7e4dcc5c82d115f5b..e85af9718d064e4d2865bc944e9d4ba1
class nsGeolocationService;
class nsGeolocationRequest;
-@@ -48,13 +49,14 @@ struct CachedPositionAndAccuracy {
+@@ -51,13 +52,14 @@ struct CachedPositionAndAccuracy {
bool isHighAccuracy;
};
@@ -1448,9 +1507,9 @@ index 7e1af00d05fbafa2d828e2c7e4dcc5c82d115f5b..e85af9718d064e4d2865bc944e9d4ba1
static mozilla::StaticRefPtr sService;
NS_DECL_THREADSAFE_ISUPPORTS
-@@ -179,6 +181,8 @@ class Geolocation final : public nsIGeolocationUpdate, public nsWrapperCache {
- // null.
- static already_AddRefed NonWindowSingleton();
+@@ -189,6 +191,8 @@ class Geolocation final : public nsIGeolocationUpdate, public nsWrapperCache {
+ BrowsingContext* aBrowsingContext,
+ geolocation::ParentRequestResolver&& aResolver);
+ nsGeolocationService* GetGeolocationService() { return mService; };
+
@@ -1458,18 +1517,18 @@ index 7e1af00d05fbafa2d828e2c7e4dcc5c82d115f5b..e85af9718d064e4d2865bc944e9d4ba1
~Geolocation();
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
-index d5a65a17555b7764611803f7fb298712b2c60fd7..fdee7deaf0b14e01702b902f8b73256c281e76b8 100644
+index c3e7de8f41e06e11155620b75c4d8a830d908b37..39eb9d31258693dce3a26c3227f28d92bccdb019 100644
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
-@@ -57,6 +57,7 @@
+@@ -64,6 +64,7 @@
#include "mozilla/dom/Document.h"
#include "mozilla/dom/HTMLDataListElement.h"
#include "mozilla/dom/HTMLOptionElement.h"
+#include "nsDocShell.h"
- #include "nsIFormControlFrame.h"
- #include "nsITextControlFrame.h"
#include "nsIFrame.h"
-@@ -783,6 +784,13 @@ nsresult HTMLInputElement::InitFilePicker(FilePickerType aType) {
+ #include "nsRangeFrame.h"
+ #include "nsError.h"
+@@ -790,6 +791,13 @@ nsresult HTMLInputElement::InitFilePicker(FilePickerType aType) {
return NS_ERROR_FAILURE;
}
@@ -1480,14 +1539,14 @@ index d5a65a17555b7764611803f7fb298712b2c60fd7..fdee7deaf0b14e01702b902f8b73256c
+ return NS_OK;
+ }
+
- if (IsPopupBlocked(doc)) {
+ if (IsPickerBlocked(doc)) {
return NS_OK;
}
diff --git a/dom/interfaces/base/nsIDOMWindowUtils.idl b/dom/interfaces/base/nsIDOMWindowUtils.idl
-index 6a0df1b435cee9cea3b7d7ca30d0aff0e31f8ac0..c17b24823dd873c025e407fcc635b7c678dfd8ed 100644
+index 5e417145c4f21d8f2aa65088611477b681c9c327..bc84c509659c7556077e69c652e5b19639eb88bb 100644
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
-@@ -373,6 +373,26 @@ interface nsIDOMWindowUtils : nsISupports {
+@@ -374,6 +374,26 @@ interface nsIDOMWindowUtils : nsISupports {
[optional] in long aButtons,
[optional] in unsigned long aIdentifier);
@@ -1515,10 +1574,10 @@ index 6a0df1b435cee9cea3b7d7ca30d0aff0e31f8ac0..c17b24823dd873c025e407fcc635b7c6
* touchstart, touchend, touchmove, and touchcancel
*
diff --git a/dom/ipc/BrowserChild.cpp b/dom/ipc/BrowserChild.cpp
-index bdd10fdcb285e43778b55907ac05bfa973207e5e..d98808918ff8eccd6c51b4fbce1cce5e3745206a 100644
+index 93f20a36acef74947d5377df5ff916546218d8b8..22b706b985d22a8c0c278a12ab4944e26ded51a4 100644
--- a/dom/ipc/BrowserChild.cpp
+++ b/dom/ipc/BrowserChild.cpp
-@@ -1652,6 +1652,21 @@ void BrowserChild::HandleRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
+@@ -1676,6 +1676,21 @@ void BrowserChild::HandleRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
if (postLayerization) {
postLayerization->Register();
}
@@ -1555,15 +1614,12 @@ index 5aa445d2e0a6169e57c44569974d557b3baf7064..671f71979b407f0ca17c66f13805e851
}
diff --git a/dom/media/systemservices/video_engine/desktop_capture_impl.cc b/dom/media/systemservices/video_engine/desktop_capture_impl.cc
-index a966ff06d4a52e2ff70ce71df3a6a607a67e3eda..eb6bb16413df43217ddd85048c02d41d15e8431f 100644
+index c43a1b3b245101c974742c5e50f54857e538bbfb..c07a568da3342cbf2af07471fa6959cb242b9a4e 100644
--- a/dom/media/systemservices/video_engine/desktop_capture_impl.cc
+++ b/dom/media/systemservices/video_engine/desktop_capture_impl.cc
-@@ -135,11 +135,12 @@ int32_t ScreenDeviceInfoImpl::GetOrientation(const char* aDeviceUniqueIdUTF8,
- return 0;
- }
+@@ -52,9 +52,10 @@ namespace webrtc {
--VideoCaptureModule* DesktopCaptureImpl::Create(const int32_t aModuleId,
-+VideoCaptureModuleEx* DesktopCaptureImpl::Create(const int32_t aModuleId,
+ DesktopCaptureImpl* DesktopCaptureImpl::Create(const int32_t aModuleId,
const char* aUniqueId,
- const CaptureDeviceType aType) {
+ const CaptureDeviceType aType,
@@ -1573,30 +1629,20 @@ index a966ff06d4a52e2ff70ce71df3a6a607a67e3eda..eb6bb16413df43217ddd85048c02d41d
+ aType, aCaptureCursor);
}
- int32_t WindowDeviceInfoImpl::Init() {
-@@ -412,7 +413,7 @@ static bool UsePipewire() {
+ static DesktopCaptureOptions CreateDesktopCaptureOptions() {
+@@ -155,8 +156,10 @@ static std::unique_ptr CreateTabCapturer(
static std::unique_ptr CreateDesktopCapturerAndThread(
CaptureDeviceType aDeviceType, DesktopCapturer::SourceId aSourceId,
- nsIThread** aOutThread) {
+ nsIThread** aOutThread, bool aCaptureCursor) {
DesktopCaptureOptions options = CreateDesktopCaptureOptions();
- std::unique_ptr capturer;
-
-@@ -462,8 +463,10 @@ static std::unique_ptr CreateDesktopCapturerAndThread(
-
- capturer->SelectSource(aSourceId);
-
-- capturer = std::make_unique(std::move(capturer),
-- options);
-+ if (aCaptureCursor) {
-+ capturer = std::make_unique(
-+ std::move(capturer), options);
-+ }
- } else if (aDeviceType == CaptureDeviceType::Browser) {
- // XXX We don't capture cursors, so avoid the extra indirection layer. We
- // could also pass null for the pMouseCursorMonitor.
-@@ -480,7 +483,8 @@ static std::unique_ptr CreateDesktopCapturerAndThread(
++ if (aCaptureCursor)
++ options.set_prefer_cursor_embedded(aCaptureCursor);
+ auto ensureThread = [&]() {
+ if (*aOutThread) {
+ return *aOutThread;
+@@ -253,7 +256,8 @@ static std::unique_ptr CreateDesktopCapturerAndThread(
}
DesktopCaptureImpl::DesktopCaptureImpl(const int32_t aId, const char* aUniqueId,
@@ -1606,7 +1652,7 @@ index a966ff06d4a52e2ff70ce71df3a6a607a67e3eda..eb6bb16413df43217ddd85048c02d41d
: mModuleId(aId),
mTrackingId(mozilla::TrackingId(CaptureEngineToTrackingSourceStr([&] {
switch (aType) {
-@@ -497,6 +501,7 @@ DesktopCaptureImpl::DesktopCaptureImpl(const int32_t aId, const char* aUniqueId,
+@@ -270,6 +274,7 @@ DesktopCaptureImpl::DesktopCaptureImpl(const int32_t aId, const char* aUniqueId,
aId)),
mDeviceUniqueId(aUniqueId),
mDeviceType(aType),
@@ -1614,7 +1660,7 @@ index a966ff06d4a52e2ff70ce71df3a6a607a67e3eda..eb6bb16413df43217ddd85048c02d41d
mControlThread(mozilla::GetCurrentSerialEventTarget()),
mNextFrameMinimumTime(Timestamp::Zero()),
mCallbacks("DesktopCaptureImpl::mCallbacks") {}
-@@ -521,6 +526,19 @@ void DesktopCaptureImpl::DeRegisterCaptureDataCallback(
+@@ -294,6 +299,19 @@ void DesktopCaptureImpl::DeRegisterCaptureDataCallback(
}
}
@@ -1634,7 +1680,7 @@ index a966ff06d4a52e2ff70ce71df3a6a607a67e3eda..eb6bb16413df43217ddd85048c02d41d
int32_t DesktopCaptureImpl::StopCaptureIfAllClientsClose() {
{
auto callbacks = mCallbacks.Lock();
-@@ -553,7 +571,7 @@ int32_t DesktopCaptureImpl::StartCapture(
+@@ -333,7 +351,7 @@ int32_t DesktopCaptureImpl::StartCapture(
DesktopCapturer::SourceId sourceId = std::stoi(mDeviceUniqueId);
std::unique_ptr capturer = CreateDesktopCapturerAndThread(
@@ -1643,7 +1689,7 @@ index a966ff06d4a52e2ff70ce71df3a6a607a67e3eda..eb6bb16413df43217ddd85048c02d41d
MOZ_ASSERT(!capturer == !mCaptureThread);
if (!capturer) {
-@@ -654,6 +672,15 @@ void DesktopCaptureImpl::OnCaptureResult(DesktopCapturer::Result aResult,
+@@ -441,6 +459,15 @@ void DesktopCaptureImpl::OnCaptureResult(DesktopCapturer::Result aResult,
frameInfo.height = aFrame->size().height();
frameInfo.videoType = VideoType::kARGB;
@@ -1660,18 +1706,18 @@ index a966ff06d4a52e2ff70ce71df3a6a607a67e3eda..eb6bb16413df43217ddd85048c02d41d
frameInfo.width * frameInfo.height * DesktopFrame::kBytesPerPixel;
diff --git a/dom/media/systemservices/video_engine/desktop_capture_impl.h b/dom/media/systemservices/video_engine/desktop_capture_impl.h
-index 7292f6c8a70298d4bf103080804843fa9bba1d15..7a50fee0d2fcaad475302d010892800a6e3c4e75 100644
+index a76b7de569db1cb42728a5514fb80e5c46e0344e..3d61ad8d3aa4a7eaf96957dcd680e1e1ee8abdf4 100644
--- a/dom/media/systemservices/video_engine/desktop_capture_impl.h
+++ b/dom/media/systemservices/video_engine/desktop_capture_impl.h
-@@ -24,6 +24,7 @@
+@@ -26,6 +26,7 @@
#include "api/video/video_sink_interface.h"
#include "modules/desktop_capture/desktop_capturer.h"
#include "modules/video_capture/video_capture.h"
+#include "rtc_base/deprecated/recursive_critical_section.h"
-
- #include "desktop_device_info.h"
#include "mozilla/DataMutex.h"
-@@ -43,6 +44,21 @@ namespace webrtc {
+ #include "mozilla/Maybe.h"
+ #include "mozilla/TimeStamp.h"
+@@ -42,17 +43,44 @@ namespace webrtc {
class VideoCaptureEncodeInterface;
@@ -1688,12 +1734,21 @@ index 7292f6c8a70298d4bf103080804843fa9bba1d15..7a50fee0d2fcaad475302d010892800a
+
+ virtual void RegisterRawFrameCallback(RawFrameCallback* rawFrameCallback) = 0;
+ virtual void DeRegisterRawFrameCallback(RawFrameCallback* rawFrameCallback) = 0;
++ int32_t StartCaptureCounted(const VideoCaptureCapability& aCapability) {
++ ++capture_counter_;
++ return capture_counter_ == 1 ? StartCapture(aCapability) : 0;
++ }
++
++ int32_t StopCaptureCounted() {
++ --capture_counter_;
++ return capture_counter_ == 0 ? StopCapture() : 0;
++ }
++
++ private:
++ int32_t capture_counter_ = 0;
+};
+
- // simulate deviceInfo interface for video engine, bridge screen/application and
- // real screen/application device info
-
-@@ -158,13 +174,13 @@ class BrowserDeviceInfoImpl : public VideoCaptureModule::DeviceInfo {
+ // Reuses the video engine pipeline for screen sharing.
// As with video, DesktopCaptureImpl is a proxy for screen sharing
// and follows the video pipeline design
class DesktopCaptureImpl : public DesktopCapturer::Callback,
@@ -1702,15 +1757,14 @@ index 7292f6c8a70298d4bf103080804843fa9bba1d15..7a50fee0d2fcaad475302d010892800a
public:
/* Create a screen capture modules object
*/
-- static VideoCaptureModule* Create(
-+ static VideoCaptureModuleEx* Create(
+ static DesktopCaptureImpl* Create(
const int32_t aModuleId, const char* aUniqueId,
- const mozilla::camera::CaptureDeviceType aType);
+ const mozilla::camera::CaptureDeviceType aType, bool aCaptureCursor = true);
[[nodiscard]] static std::shared_ptr
CreateDeviceInfo(const int32_t aId,
-@@ -178,6 +194,8 @@ class DesktopCaptureImpl : public DesktopCapturer::Callback,
+@@ -66,6 +94,8 @@ class DesktopCaptureImpl : public DesktopCapturer::Callback,
void DeRegisterCaptureDataCallback(
rtc::VideoSinkInterface* aCallback) override;
int32_t StopCaptureIfAllClientsClose() override;
@@ -1719,7 +1773,7 @@ index 7292f6c8a70298d4bf103080804843fa9bba1d15..7a50fee0d2fcaad475302d010892800a
int32_t SetCaptureRotation(VideoRotation aRotation) override;
bool SetApplyRotation(bool aEnable) override;
-@@ -200,7 +218,8 @@ class DesktopCaptureImpl : public DesktopCapturer::Callback,
+@@ -89,7 +119,8 @@ class DesktopCaptureImpl : public DesktopCapturer::Callback,
protected:
DesktopCaptureImpl(const int32_t aId, const char* aUniqueId,
@@ -1729,9 +1783,9 @@ index 7292f6c8a70298d4bf103080804843fa9bba1d15..7a50fee0d2fcaad475302d010892800a
virtual ~DesktopCaptureImpl();
private:
-@@ -208,6 +227,9 @@ class DesktopCaptureImpl : public DesktopCapturer::Callback,
- static constexpr uint32_t kMaxDesktopCaptureCpuUsage = 50;
+@@ -98,6 +129,9 @@ class DesktopCaptureImpl : public DesktopCapturer::Callback,
void InitOnThread(std::unique_ptr aCapturer, int aFramerate);
+ void UpdateOnThread(int aFramerate);
void ShutdownOnThread();
+
+ rtc::RecursiveCriticalSection mApiCs;
@@ -1739,7 +1793,7 @@ index 7292f6c8a70298d4bf103080804843fa9bba1d15..7a50fee0d2fcaad475302d010892800a
// DesktopCapturer::Callback interface.
void OnCaptureResult(DesktopCapturer::Result aResult,
std::unique_ptr aFrame) override;
-@@ -215,6 +237,8 @@ class DesktopCaptureImpl : public DesktopCapturer::Callback,
+@@ -105,6 +139,8 @@ class DesktopCaptureImpl : public DesktopCapturer::Callback,
// Notifies all mCallbacks of OnFrame(). mCaptureThread only.
void NotifyOnFrame(const VideoFrame& aFrame);
@@ -1793,18 +1847,18 @@ index 3b39538e51840cd9b1685b2efd2ff2e9ec83608a..c7bf4f2d53b58bbacb22b3ebebf6f3fc
return aGlobalOrNull;
diff --git a/dom/security/nsCSPUtils.cpp b/dom/security/nsCSPUtils.cpp
-index 11d09909f73fee425fd0f50b384c396a52e02a36..b0e668881bcd3b850de709ebf2557ae8391b8fe8 100644
+index 5ec21c1c7f975a372399748e8bab2b21ce347f20..ed16831e549afa3d6623398d35eb61e26ab5f2b0 100644
--- a/dom/security/nsCSPUtils.cpp
+++ b/dom/security/nsCSPUtils.cpp
-@@ -22,6 +22,7 @@
+@@ -23,6 +23,7 @@
#include "nsSandboxFlags.h"
#include "nsServiceManagerUtils.h"
#include "nsWhitespaceTokenizer.h"
+#include "nsDocShell.h"
+ #include "mozilla/Assertions.h"
#include "mozilla/Components.h"
- #include "mozilla/dom/CSPDictionariesBinding.h"
-@@ -132,6 +133,11 @@ void CSP_ApplyMetaCSPToDoc(mozilla::dom::Document& aDoc,
+@@ -135,6 +136,11 @@ void CSP_ApplyMetaCSPToDoc(mozilla::dom::Document& aDoc,
return;
}
@@ -1817,19 +1871,19 @@ index 11d09909f73fee425fd0f50b384c396a52e02a36..b0e668881bcd3b850de709ebf2557ae8
nsContentUtils::TrimWhitespace(
aPolicyStr));
diff --git a/dom/webidl/GeometryUtils.webidl b/dom/webidl/GeometryUtils.webidl
-index 2f71b284ee5f7e11f117c447834b48355784448c..2640bd57123c2b03bf4b06a2419cd020ba95f155 100644
+index aee376e971ae01ac1e512c3920b115bfaf06afa8..1701311534bf77e6cd9bafc0e3a283610476aa8f 100644
--- a/dom/webidl/GeometryUtils.webidl
+++ b/dom/webidl/GeometryUtils.webidl
-@@ -16,6 +16,8 @@ dictionary BoxQuadOptions {
- GeometryNode relativeTo;
- [ChromeOnly]
+@@ -17,6 +17,8 @@ dictionary GeometryUtilsOptions {
boolean createFramesForSuppressedWhitespace = true;
+ [ChromeOnly]
+ boolean flush = true;
+ [ChromeOnly]
+ boolean recurseWhenNoFrame = false;
};
- dictionary ConvertCoordinateOptions {
-@@ -27,6 +29,9 @@ interface mixin GeometryUtils {
+ dictionary BoxQuadOptions : GeometryUtilsOptions {
+@@ -35,6 +37,9 @@ interface mixin GeometryUtils {
[Throws, Func="nsINode::HasBoxQuadsSupport", NeedsCallerType]
sequence getBoxQuads(optional BoxQuadOptions options = {});
@@ -1840,10 +1894,10 @@ index 2f71b284ee5f7e11f117c447834b48355784448c..2640bd57123c2b03bf4b06a2419cd020
* returned quads are further translated relative to the window
* origin -- which is not the layout origin. Further translation
diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
-index 02efb1205382850b41c38d5f6ee47092adcdc63e..28c8d05d0b5cc415f3d13a4588248f3844faf4f2 100644
+index a23637c4a887b66a1b4c709a648762b84151bf01..d8da9063261482f1da3257e3f95a8a49d94325f8 100644
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
-@@ -995,7 +995,7 @@ void PrefLanguagesChanged(const char* /* aPrefName */, void* /* aClosure */) {
+@@ -1026,7 +1026,7 @@ void PrefLanguagesChanged(const char* /* aPrefName */, void* /* aClosure */) {
AssertIsOnMainThread();
nsTArray languages;
@@ -1852,7 +1906,7 @@ index 02efb1205382850b41c38d5f6ee47092adcdc63e..28c8d05d0b5cc415f3d13a4588248f38
RuntimeService* runtime = RuntimeService::GetService();
if (runtime) {
-@@ -1182,8 +1182,7 @@ bool RuntimeService::RegisterWorker(WorkerPrivate& aWorkerPrivate) {
+@@ -1214,8 +1214,7 @@ bool RuntimeService::RegisterWorker(WorkerPrivate& aWorkerPrivate) {
}
// The navigator overridden properties should have already been read.
@@ -1862,7 +1916,7 @@ index 02efb1205382850b41c38d5f6ee47092adcdc63e..28c8d05d0b5cc415f3d13a4588248f38
mNavigatorPropertiesLoaded = true;
}
-@@ -1789,6 +1788,13 @@ void RuntimeService::PropagateStorageAccessPermissionGranted(
+@@ -1836,6 +1835,13 @@ void RuntimeService::PropagateStorageAccessPermissionGranted(
}
}
@@ -1876,7 +1930,7 @@ index 02efb1205382850b41c38d5f6ee47092adcdc63e..28c8d05d0b5cc415f3d13a4588248f38
template
void RuntimeService::BroadcastAllWorkers(const Func& aFunc) {
AssertIsOnMainThread();
-@@ -2304,6 +2310,14 @@ void PropagateStorageAccessPermissionGrantedToWorkers(
+@@ -2361,6 +2367,14 @@ void PropagateStorageAccessPermissionGrantedToWorkers(
}
}
@@ -1892,10 +1946,10 @@ index 02efb1205382850b41c38d5f6ee47092adcdc63e..28c8d05d0b5cc415f3d13a4588248f38
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aCx);
diff --git a/dom/workers/RuntimeService.h b/dom/workers/RuntimeService.h
-index f51076ac1480794989999d00577bc9cf1566d5f9..fe15b2e00dc8f0bf203f2af9aad86e16c996d43d 100644
+index 534bbe9ec4f0261189eb3322c1229c1eb5d8802e..6aa99b64fdbbff3704602e944b129879fbdf8c15 100644
--- a/dom/workers/RuntimeService.h
+++ b/dom/workers/RuntimeService.h
-@@ -109,6 +109,8 @@ class RuntimeService final : public nsIObserver {
+@@ -112,6 +112,8 @@ class RuntimeService final : public nsIObserver {
void PropagateStorageAccessPermissionGranted(
const nsPIDOMWindowInner& aWindow);
@@ -1905,10 +1959,10 @@ index f51076ac1480794989999d00577bc9cf1566d5f9..fe15b2e00dc8f0bf203f2af9aad86e16
return mNavigatorProperties;
}
diff --git a/dom/workers/WorkerCommon.h b/dom/workers/WorkerCommon.h
-index d10dabb5c5ff8e17851edf2bd2efc08e74584d8e..53c4070c5fde43b27fb8fbfdcf4c23d8af57fba3 100644
+index 58894a8361c7ef1dddd481ca5877a209a8b8ff5c..c481d40d79b6397b7f1d571bd9f6ae5c0a946217 100644
--- a/dom/workers/WorkerCommon.h
+++ b/dom/workers/WorkerCommon.h
-@@ -44,6 +44,8 @@ void ResumeWorkersForWindow(const nsPIDOMWindowInner& aWindow);
+@@ -47,6 +47,8 @@ void ResumeWorkersForWindow(const nsPIDOMWindowInner& aWindow);
void PropagateStorageAccessPermissionGrantedToWorkers(
const nsPIDOMWindowInner& aWindow);
@@ -1918,17 +1972,17 @@ index d10dabb5c5ff8e17851edf2bd2efc08e74584d8e..53c4070c5fde43b27fb8fbfdcf4c23d8
bool IsWorkerGlobal(JSObject* global);
diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
-index a8643981aa966e9324a5dbdb09b4fe57210dc581..5120df2607584a7cd50ea03aa997ef5ade5c8ee2 100644
+index 5d918a82708a26125f7322e43f6436d7eafaa812..b230baead02e05d87a211c276066ec7939ea8251 100644
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
-@@ -682,6 +682,18 @@ class UpdateContextOptionsRunnable final : public WorkerControlRunnable {
+@@ -736,6 +736,18 @@ class UpdateContextOptionsRunnable final : public WorkerControlRunnable {
}
};
+class ResetDefaultLocaleRunnable final : public WorkerControlRunnable {
+ public:
+ explicit ResetDefaultLocaleRunnable(WorkerPrivate* aWorkerPrivate)
-+ : WorkerControlRunnable(aWorkerPrivate, "ResetDefaultLocaleRunnable", WorkerThread) {}
++ : WorkerControlRunnable("ResetDefaultLocaleRunnable") {}
+
+ virtual bool WorkerRun(JSContext* aCx,
+ WorkerPrivate* aWorkerPrivate) override {
@@ -1937,10 +1991,10 @@ index a8643981aa966e9324a5dbdb09b4fe57210dc581..5120df2607584a7cd50ea03aa997ef5a
+ }
+};
+
- class UpdateLanguagesRunnable final : public WorkerRunnable {
+ class UpdateLanguagesRunnable final : public WorkerThreadRunnable {
nsTArray mLanguages;
-@@ -1993,6 +2005,16 @@ void WorkerPrivate::UpdateContextOptions(
+@@ -2159,6 +2171,16 @@ void WorkerPrivate::UpdateContextOptions(
}
}
@@ -1949,7 +2003,7 @@ index a8643981aa966e9324a5dbdb09b4fe57210dc581..5120df2607584a7cd50ea03aa997ef5a
+
+ RefPtr runnable =
+ new ResetDefaultLocaleRunnable(this);
-+ if (!runnable->Dispatch()) {
++ if (!runnable->Dispatch(this)) {
+ NS_WARNING("Failed to reset default locale in worker!");
+ }
+}
@@ -1957,7 +2011,7 @@ index a8643981aa966e9324a5dbdb09b4fe57210dc581..5120df2607584a7cd50ea03aa997ef5a
void WorkerPrivate::UpdateLanguages(const nsTArray& aLanguages) {
AssertIsOnParentThread();
-@@ -5489,6 +5511,15 @@ void WorkerPrivate::UpdateContextOptionsInternal(
+@@ -5946,6 +5968,15 @@ void WorkerPrivate::UpdateContextOptionsInternal(
}
}
@@ -1974,10 +2028,10 @@ index a8643981aa966e9324a5dbdb09b4fe57210dc581..5120df2607584a7cd50ea03aa997ef5a
const nsTArray& aLanguages) {
WorkerGlobalScope* globalScope = GlobalScope();
diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h
-index a670d009759d101cf9574cde3c2481b8aa2737f6..ac87b7f27dfcc060adb52387b146c45eed996fa7 100644
+index 7bccdc8c0c2cd53f7aa7a6d9a74435344dd27980..86bba2128a7c0f4e5efa4bfbc939937aec146695 100644
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
-@@ -417,6 +417,8 @@ class WorkerPrivate final
+@@ -443,6 +443,8 @@ class WorkerPrivate final
void UpdateContextOptionsInternal(JSContext* aCx,
const JS::ContextOptions& aContextOptions);
@@ -1986,7 +2040,7 @@ index a670d009759d101cf9574cde3c2481b8aa2737f6..ac87b7f27dfcc060adb52387b146c45e
void UpdateLanguagesInternal(const nsTArray& aLanguages);
void UpdateJSWorkerMemoryParameterInternal(JSContext* aCx, JSGCParamKey key,
-@@ -1036,6 +1038,8 @@ class WorkerPrivate final
+@@ -1091,6 +1093,8 @@ class WorkerPrivate final
void UpdateContextOptions(const JS::ContextOptions& aContextOptions);
@@ -2022,10 +2076,10 @@ index 7a069ef0c59895cf1f8dc35d612f1494c9c9f1ef..5b09dfdcc5323def65c35b0696141b44
Span aTimeZone) {
#if MOZ_INTL_USE_ICU_CPP_TIMEZONE
diff --git a/intl/components/src/TimeZone.h b/intl/components/src/TimeZone.h
-index 9d0423ef13958d5c443cc3531269603c4801c338..f0c4ba7c528d2be466e0f7669a1e37e876f9091e 100644
+index 89770839ae108b5f3462a7f20684fdb72c4ab2fb..a7e40d6b7c33c234b41e586eac573ba4ce3a7d18 100644
--- a/intl/components/src/TimeZone.h
+++ b/intl/components/src/TimeZone.h
-@@ -190,6 +190,8 @@ class TimeZone final {
+@@ -191,6 +191,8 @@ class TimeZone final {
return FillBufferWithICUCall(aBuffer, ucal_getHostTimeZone);
}
@@ -2048,10 +2102,10 @@ index 523e84c8c93f4221701f90f2e8ee146ec8e1adbd..98d5b1176e5378431b859a2dbd4d4e77
inline ClippedTime TimeClip(double time);
diff --git a/js/src/debugger/Object.cpp b/js/src/debugger/Object.cpp
-index 17528b0fd99ce8274e702746ff5674de4c3d4f2d..37fa52ae07381bec3504136b9bec0aa1ca110d6b 100644
+index b7ea4b6f66d14db0324397cdc1b0ed8c5ea167e2..1c59e328079e7e43b65f7cb7bc31636a48a93263 100644
--- a/js/src/debugger/Object.cpp
+++ b/js/src/debugger/Object.cpp
-@@ -2468,7 +2468,11 @@ Maybe DebuggerObject::call(JSContext* cx,
+@@ -2484,7 +2484,11 @@ Maybe DebuggerObject::call(JSContext* cx,
invokeArgs[i].set(args2[i]);
}
@@ -2064,10 +2118,10 @@ index 17528b0fd99ce8274e702746ff5674de4c3d4f2d..37fa52ae07381bec3504136b9bec0aa1
}
diff --git a/js/src/vm/DateTime.cpp b/js/src/vm/DateTime.cpp
-index 21ecc2e9f50a16357ace3320335d31a4929fc146..c4b1444ce53b20a700d2ff9f18521bd67623e7d2 100644
+index a57b8fefa104f966393a99f5a81876b9a95f9743..adc42dd227e52643b06fb101170aeafb490c0acc 100644
--- a/js/src/vm/DateTime.cpp
+++ b/js/src/vm/DateTime.cpp
-@@ -186,6 +186,11 @@ void js::DateTimeInfo::internalResetTimeZone(ResetTimeZoneMode mode) {
+@@ -185,6 +185,11 @@ void js::DateTimeInfo::internalResetTimeZone(ResetTimeZoneMode mode) {
}
}
@@ -2079,7 +2133,7 @@ index 21ecc2e9f50a16357ace3320335d31a4929fc146..c4b1444ce53b20a700d2ff9f18521bd6
void js::DateTimeInfo::updateTimeZone() {
MOZ_ASSERT(timeZoneStatus_ != TimeZoneStatus::Valid);
-@@ -527,10 +532,24 @@ void js::ResetTimeZoneInternal(ResetTimeZoneMode mode) {
+@@ -528,10 +533,24 @@ void js::ResetTimeZoneInternal(ResetTimeZoneMode mode) {
js::DateTimeInfo::resetTimeZone(mode);
}
@@ -2104,7 +2158,7 @@ index 21ecc2e9f50a16357ace3320335d31a4929fc146..c4b1444ce53b20a700d2ff9f18521bd6
#if JS_HAS_INTL_API
# if defined(XP_WIN)
static bool IsOlsonCompatibleWindowsTimeZoneId(std::string_view tz) {
-@@ -748,6 +767,15 @@ static bool ReadTimeZoneLink(std::string_view tz,
+@@ -749,6 +768,15 @@ static bool ReadTimeZoneLink(std::string_view tz,
void js::DateTimeInfo::internalResyncICUDefaultTimeZone() {
#if JS_HAS_INTL_API
@@ -2120,7 +2174,7 @@ index 21ecc2e9f50a16357ace3320335d31a4929fc146..c4b1444ce53b20a700d2ff9f18521bd6
// In the future we should not be setting a default ICU time zone at all,
// instead all accesses should go through the appropriate DateTimeInfo
// instance depending on the resist fingerprinting status. For now we return
-@@ -759,7 +787,6 @@ void js::DateTimeInfo::internalResyncICUDefaultTimeZone() {
+@@ -760,7 +788,6 @@ void js::DateTimeInfo::internalResyncICUDefaultTimeZone() {
if (const char* tzenv = std::getenv("TZ")) {
std::string_view tz(tzenv);
@@ -2129,7 +2183,7 @@ index 21ecc2e9f50a16357ace3320335d31a4929fc146..c4b1444ce53b20a700d2ff9f18521bd6
# if defined(XP_WIN)
diff --git a/js/src/vm/DateTime.h b/js/src/vm/DateTime.h
-index fd6d7ae078b8f6b3cc46a4a993a1e044a7128c90..4743094e489122dd9ee8ab9a7a175dd7e928859d 100644
+index e3cf82daa3749664aa8ced7e6553b8c6434dfec8..b45b49c4f3bbf12853c4afb12de21d99ac88d77b 100644
--- a/js/src/vm/DateTime.h
+++ b/js/src/vm/DateTime.h
@@ -65,6 +65,8 @@ enum class ResetTimeZoneMode : bool {
@@ -2141,7 +2195,7 @@ index fd6d7ae078b8f6b3cc46a4a993a1e044a7128c90..4743094e489122dd9ee8ab9a7a175dd7
/**
* Stores date/time information, particularly concerning the current local
* time zone, and implements a small cache for daylight saving time offset
-@@ -225,6 +227,7 @@ class DateTimeInfo {
+@@ -253,6 +255,7 @@ class DateTimeInfo {
private:
// The method below should only be called via js::ResetTimeZoneInternal().
friend void js::ResetTimeZoneInternal(ResetTimeZoneMode);
@@ -2149,7 +2203,7 @@ index fd6d7ae078b8f6b3cc46a4a993a1e044a7128c90..4743094e489122dd9ee8ab9a7a175dd7
static void resetTimeZone(ResetTimeZoneMode mode) {
{
-@@ -321,6 +324,8 @@ class DateTimeInfo {
+@@ -352,6 +355,8 @@ class DateTimeInfo {
JS::UniqueChars locale_;
JS::UniqueTwoByteChars standardName_;
JS::UniqueTwoByteChars daylightSavingsName_;
@@ -2158,7 +2212,7 @@ index fd6d7ae078b8f6b3cc46a4a993a1e044a7128c90..4743094e489122dd9ee8ab9a7a175dd7
#else
// Restrict the data-time range to the minimum required time_t range as
// specified in POSIX. Most operating systems support 64-bit time_t
-@@ -336,6 +341,8 @@ class DateTimeInfo {
+@@ -367,6 +372,8 @@ class DateTimeInfo {
void internalResetTimeZone(ResetTimeZoneMode mode);
@@ -2168,7 +2222,7 @@ index fd6d7ae078b8f6b3cc46a4a993a1e044a7128c90..4743094e489122dd9ee8ab9a7a175dd7
void internalResyncICUDefaultTimeZone();
diff --git a/layout/base/GeometryUtils.cpp b/layout/base/GeometryUtils.cpp
-index dac899f7558b26d6848da8b98ed8a93555c8751a..2a07d67fa1c2840b25085566e84dc3b2d9b789cf 100644
+index 4bfd336ddcbee8004ac538ca7b7d8216d04a61c3..cd22351c4aeacea8afc9828972222aca1b3063bf 100644
--- a/layout/base/GeometryUtils.cpp
+++ b/layout/base/GeometryUtils.cpp
@@ -23,6 +23,7 @@
@@ -2179,18 +2233,18 @@ index dac899f7558b26d6848da8b98ed8a93555c8751a..2a07d67fa1c2840b25085566e84dc3b2
using namespace mozilla;
using namespace mozilla::dom;
-@@ -261,11 +262,27 @@ static bool CheckFramesInSameTopLevelBrowsingContext(nsIFrame* aFrame1,
+@@ -265,10 +266,27 @@ static bool CheckFramesInSameTopLevelBrowsingContext(nsIFrame* aFrame1,
return false;
}
-+static nsIFrame* GetFrameForNode(nsINode* aNode,
-+ bool aCreateFramesForSuppressedWhitespace,
++static nsIFrame* GetFrameForNodeRecursive(nsINode* aNode,
++ const GeometryUtilsOptions& aOptions,
+ bool aRecurseWhenNoFrame) {
-+ nsIFrame* frame = GetFrameForNode(aNode, aCreateFramesForSuppressedWhitespace);
++ nsIFrame* frame = GetFrameForNode(aNode, aOptions);
+ if (!frame && aRecurseWhenNoFrame && aNode->IsContent()) {
+ dom::FlattenedChildIterator iter(aNode->AsContent());
+ for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
-+ frame = GetFrameForNode(child, aCreateFramesForSuppressedWhitespace, aRecurseWhenNoFrame);
++ frame = GetFrameForNodeRecursive(child, aOptions, aRecurseWhenNoFrame);
+ if (frame) {
+ break;
+ }
@@ -2200,28 +2254,29 @@ index dac899f7558b26d6848da8b98ed8a93555c8751a..2a07d67fa1c2840b25085566e84dc3b2
+}
+
void GetBoxQuads(nsINode* aNode, const dom::BoxQuadOptions& aOptions,
- nsTArray >& aResult, CallerType aCallerType,
+ nsTArray>& aResult, CallerType aCallerType,
ErrorResult& aRv) {
- nsIFrame* frame =
-- GetFrameForNode(aNode, aOptions.mCreateFramesForSuppressedWhitespace);
-+ GetFrameForNode(aNode, aOptions.mCreateFramesForSuppressedWhitespace, aOptions.mRecurseWhenNoFrame);
+- nsIFrame* frame = GetFrameForNode(aNode, aOptions);
++ nsIFrame* frame =
++ GetFrameForNodeRecursive(aNode, aOptions, aOptions.mRecurseWhenNoFrame);
if (!frame) {
// No boxes to return
return;
-@@ -280,7 +297,7 @@ void GetBoxQuads(nsINode* aNode, const dom::BoxQuadOptions& aOptions,
+@@ -281,7 +299,8 @@ void GetBoxQuads(nsINode* aNode, const dom::BoxQuadOptions& aOptions,
+ // EnsureFrameForTextNode call. We need to get the first frame again
// when that happens and re-check it.
if (!weakFrame.IsAlive()) {
- frame =
-- GetFrameForNode(aNode, aOptions.mCreateFramesForSuppressedWhitespace);
-+ GetFrameForNode(aNode, aOptions.mCreateFramesForSuppressedWhitespace, aOptions.mRecurseWhenNoFrame);
+- frame = GetFrameForNode(aNode, aOptions);
++ frame =
++ GetFrameForNodeRecursive(aNode, aOptions, aOptions.mRecurseWhenNoFrame);
if (!frame) {
// No boxes to return
return;
diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp
-index 31c21c337786b76306029149a925293a44c45c28..7aa4eb0b4980bb8ecdc4e10c91b1cd70e5d0ad08 100644
+index e8fb3a8304b27814e6e84355f24410c820667f9d..211c86fe55b8b650e40275a427b30a1ee8a9a3d7 100644
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
-@@ -11127,7 +11127,9 @@ bool PresShell::ComputeActiveness() const {
+@@ -11512,7 +11512,9 @@ bool PresShell::ComputeActiveness() const {
if (!browserChild->IsVisible()) {
MOZ_LOG(gLog, LogLevel::Debug,
(" > BrowserChild %p is not visible", browserChild));
@@ -2232,11 +2287,36 @@ index 31c21c337786b76306029149a925293a44c45c28..7aa4eb0b4980bb8ecdc4e10c91b1cd70
}
// If the browser is visible but just due to be preserving layers
+diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
+index 315d532eab56dab13b6c8bc2380a5cda2a17ffc1..7c4552137149e8c7fc9ac08a09bd4242952b53b6 100644
+--- a/layout/base/nsLayoutUtils.cpp
++++ b/layout/base/nsLayoutUtils.cpp
+@@ -708,6 +708,10 @@ bool nsLayoutUtils::AllowZoomingForDocument(
+ !aDocument->GetPresShell()->AsyncPanZoomEnabled()) {
+ return false;
+ }
++
++ /* Playwright: disable zooming as we don't support meta viewport tag */
++ if (1 == 1) return false;
++
+ // True if we allow zooming for all documents on this platform, or if we are
+ // in RDM.
+ BrowsingContext* bc = aDocument->GetBrowsingContext();
+@@ -9770,6 +9774,9 @@ void nsLayoutUtils::ComputeSystemFont(nsFont* aSystemFont,
+
+ /* static */
+ bool nsLayoutUtils::ShouldHandleMetaViewport(const Document* aDocument) {
++ /* Playwright: disable meta viewport handling since we don't require one */
++ if (1 == 1) return false;
++
+ BrowsingContext* bc = aDocument->GetBrowsingContext();
+ return StaticPrefs::dom_meta_viewport_enabled() || (bc && bc->InRDMPane());
+ }
diff --git a/layout/style/GeckoBindings.h b/layout/style/GeckoBindings.h
-index 7bb839ae18835d128dc9285b7f9dc5b5e06335af..09e3979d07447522ace740daf2b818a6c551ceba 100644
+index c7cf59c2661c7e203384c9b82789879f756b44b7..21e32dab4e60112c073bdd5070a308da2b4e0373 100644
--- a/layout/style/GeckoBindings.h
+++ b/layout/style/GeckoBindings.h
-@@ -625,6 +625,7 @@ float Gecko_MediaFeatures_GetResolution(const mozilla::dom::Document*);
+@@ -596,6 +596,7 @@ float Gecko_MediaFeatures_GetResolution(const mozilla::dom::Document*);
bool Gecko_MediaFeatures_PrefersReducedMotion(const mozilla::dom::Document*);
bool Gecko_MediaFeatures_PrefersReducedTransparency(
const mozilla::dom::Document*);
@@ -2245,10 +2325,10 @@ index 7bb839ae18835d128dc9285b7f9dc5b5e06335af..09e3979d07447522ace740daf2b818a6
const mozilla::dom::Document*);
mozilla::StylePrefersColorScheme Gecko_MediaFeatures_PrefersColorScheme(
diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp
-index f888c127d4423336a8f51e2011fc42eaf6c33f11..51d6e069f4a81c42b4bf270ba44ae4f82b8df592 100644
+index ca382a3cfba8ce5839890d6e4cb3cf9789287e3b..5800fc23dc77ee5764beddd6fa48a7fd701d2939 100644
--- a/layout/style/nsMediaFeatures.cpp
+++ b/layout/style/nsMediaFeatures.cpp
-@@ -260,11 +260,11 @@ bool Gecko_MediaFeatures_MatchesPlatform(StylePlatform aPlatform) {
+@@ -264,11 +264,7 @@ bool Gecko_MediaFeatures_MatchesPlatform(StylePlatform aPlatform) {
}
bool Gecko_MediaFeatures_PrefersReducedMotion(const Document* aDocument) {
@@ -2258,28 +2338,45 @@ index f888c127d4423336a8f51e2011fc42eaf6c33f11..51d6e069f4a81c42b4bf270ba44ae4f8
- }
- return LookAndFeel::GetInt(LookAndFeel::IntID::PrefersReducedMotion, 0) == 1;
+ return aDocument->PrefersReducedMotion();
-+}
-+
-+bool Gecko_MediaFeatures_ForcedColors(const Document* aDocument) {
-+ return aDocument->ForcedColors();
}
bool Gecko_MediaFeatures_PrefersReducedTransparency(const Document* aDocument) {
+@@ -293,6 +289,20 @@ StylePrefersColorScheme Gecko_MediaFeatures_PrefersColorScheme(
+ // as a signal.
+ StylePrefersContrast Gecko_MediaFeatures_PrefersContrast(
+ const Document* aDocument) {
++ if (auto* bc = aDocument->GetBrowsingContext()) {
++ switch (bc->Top()->PrefersContrastOverride()) {
++ case dom::PrefersContrastOverride::No_preference:
++ return StylePrefersContrast::NoPreference;
++ case dom::PrefersContrastOverride::Less:
++ return StylePrefersContrast::Less;
++ case dom::PrefersContrastOverride::More:
++ return StylePrefersContrast::More;
++ case dom::PrefersContrastOverride::Custom:
++ return StylePrefersContrast::Custom;
++ }
++ }
++
++
+ if (aDocument->ShouldResistFingerprinting(RFPTarget::CSSPrefersContrast)) {
+ return StylePrefersContrast::NoPreference;
+ }
diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp
-index eb90324c37ce515e5a0fcf75412605ae57ead9ee..6733dd6c99d77399529945386caa3926960e4176 100644
+index 1ec2c64193206d31702e22e5c4783f084b1cff31..fb463eb12ee39cd1e448369f3b47fbcfbb2473b9 100644
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
-@@ -653,7 +653,8 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
- mInterceptionInfo(rhs.mInterceptionInfo),
- mHasInjectedCookieForCookieBannerHandling(
+@@ -696,7 +696,8 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
rhs.mHasInjectedCookieForCookieBannerHandling),
-- mWasSchemelessInput(rhs.mWasSchemelessInput) {
-+ mWasSchemelessInput(rhs.mWasSchemelessInput),
+ mSchemelessInput(rhs.mSchemelessInput),
+ mHttpsUpgradeTelemetry(rhs.mHttpsUpgradeTelemetry),
+- mIsNewWindowTarget(rhs.mIsNewWindowTarget) {
++ mIsNewWindowTarget(rhs.mIsNewWindowTarget),
+ mJugglerLoadIdentifier(rhs.mJugglerLoadIdentifier) {
}
LoadInfo::LoadInfo(
-@@ -2369,4 +2370,16 @@ LoadInfo::SetWasSchemelessInput(bool aWasSchemelessInput) {
+@@ -2534,4 +2535,16 @@ LoadInfo::SetSkipHTTPSUpgrade(bool aSkipHTTPSUpgrade) {
return NS_OK;
}
@@ -2297,23 +2394,23 @@ index eb90324c37ce515e5a0fcf75412605ae57ead9ee..6733dd6c99d77399529945386caa3926
+
} // namespace mozilla::net
diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h
-index a8631b09b26708ca10f683f1a9dd6b8467d3fe8e..a0bd72113e3539d815d32382946581ee62f39b6c 100644
+index 93cc8d3630f7029303240555ae72d41b68047375..8a09863af399e25ba3f01caff2f6b3af1260e8b8 100644
--- a/netwerk/base/LoadInfo.h
+++ b/netwerk/base/LoadInfo.h
-@@ -401,6 +401,8 @@ class LoadInfo final : public nsILoadInfo {
+@@ -426,6 +426,8 @@ class LoadInfo final : public nsILoadInfo {
- bool mHasInjectedCookieForCookieBannerHandling = false;
- bool mWasSchemelessInput = false;
+ bool mIsNewWindowTarget = false;
+ bool mSkipHTTPSUpgrade = false;
+
+ uint64_t mJugglerLoadIdentifier = 0;
};
// This is exposed solely for testing purposes and should not be used outside of
diff --git a/netwerk/base/TRRLoadInfo.cpp b/netwerk/base/TRRLoadInfo.cpp
-index 920e7623a7f912296fc23361f66ab35a30c35f1e..dfea0d0f7a72da9699615d7ff778e429e7ae40fb 100644
+index d1650595f8cf28a704f94a99c1f6bfe1deb9cc77..2072a3990ff6f4496626dcebb277291ad845cac3 100644
--- a/netwerk/base/TRRLoadInfo.cpp
+++ b/netwerk/base/TRRLoadInfo.cpp
-@@ -861,5 +861,15 @@ TRRLoadInfo::SetWasSchemelessInput(bool aWasSchemelessInput) {
+@@ -950,5 +950,15 @@ TRRLoadInfo::GetFetchDestination(nsACString& aDestination) {
return NS_ERROR_NOT_IMPLEMENTED;
}
@@ -2330,48 +2427,63 @@ index 920e7623a7f912296fc23361f66ab35a30c35f1e..dfea0d0f7a72da9699615d7ff778e429
} // namespace net
} // namespace mozilla
diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl
-index ddfcb223e6126c943b58e9d198f0e2fa767c3de1..4280b836c55e5778ad4c94226ea537facb19c436 100644
+index 774ec045c0b18310e8cb86e8a9d6b1788d028435..cbf303a0ed872c27d580b4b6615f3dd9c76a8a19 100644
--- a/netwerk/base/nsILoadInfo.idl
+++ b/netwerk/base/nsILoadInfo.idl
-@@ -1532,4 +1532,6 @@ interface nsILoadInfo : nsISupports
- * Whether the load has gone through the URL bar, where the fixup had to add * the protocol scheme.
- */
- [infallible] attribute boolean wasSchemelessInput;
+@@ -1626,4 +1626,6 @@ interface nsILoadInfo : nsISupports
+ return static_cast(userNavigationInvolvement);
+ }
+ %}
+
+ [infallible] attribute unsigned long long jugglerLoadIdentifier;
};
diff --git a/netwerk/base/nsINetworkInterceptController.idl b/netwerk/base/nsINetworkInterceptController.idl
-index 155daa5cd52c4e93e1cc4559875868f4faf2c37e..02e8a2614a27a4cc9e1de760d4c48617eba25d4d 100644
+index 7f91d2df6f8bb4020c75c132dc8f6bf26625fa1e..aaa5541a17039d6b13ad83ab176fdaaf79edb2a0 100644
--- a/netwerk/base/nsINetworkInterceptController.idl
+++ b/netwerk/base/nsINetworkInterceptController.idl
-@@ -59,6 +59,7 @@ interface nsIInterceptedChannel : nsISupports
- * results in the resulting client not being controlled.
+@@ -60,6 +60,16 @@ interface nsIInterceptedChannel : nsISupports
*/
void resetInterception(in boolean bypass);
-+ void resetInterceptionWithURI(in nsIURI aURI);
++ // ----- Playwright begin -----
++
++ // Same as resetInterception, but updates the URI.
++ void resetInterceptionWithURI(in nsIURI aURI);
++
++ // After resetInterception is called, this request will be intercepted again.
++ void interceptAfterServiceWorkerResets();
++
++ // ----- Playwright end -------
++
/**
* Set the status and reason for the forthcoming synthesized response.
+ * Multiple calls overwrite existing values.
diff --git a/netwerk/ipc/DocumentLoadListener.cpp b/netwerk/ipc/DocumentLoadListener.cpp
-index d849eab7507f0665a8a79a1b11759afa3481f1ad..3a95d5201a1c1f2161a95e15beae86f2833a875f 100644
+index 771ae1fbe3d54aa25443eea675cf3abd26a21ce9..a916cb49c16dc6c7809ccbb7c8d4172446a5ac07 100644
--- a/netwerk/ipc/DocumentLoadListener.cpp
+++ b/netwerk/ipc/DocumentLoadListener.cpp
-@@ -167,6 +167,7 @@ static auto CreateDocumentLoadInfo(CanonicalBrowsingContext* aBrowsingContext,
- loadInfo->SetHasValidUserGestureActivation(
- aLoadState->HasValidUserGestureActivation());
+@@ -177,6 +177,7 @@ static auto CreateDocumentLoadInfo(CanonicalBrowsingContext* aBrowsingContext,
+ loadInfo->SetTextDirectiveUserActivation(
+ aLoadState->GetTextDirectiveUserActivation());
loadInfo->SetIsMetaRefresh(aLoadState->IsMetaRefresh());
+ loadInfo->SetJugglerLoadIdentifier(aLoadState->GetLoadIdentifier());
return loadInfo.forget();
}
diff --git a/netwerk/protocol/http/InterceptedHttpChannel.cpp b/netwerk/protocol/http/InterceptedHttpChannel.cpp
-index c58fbc96391f8dcb585bd00b5ae8cba9088abd82..c121c891b61c9d60df770020c4ad09521d2bbfe6 100644
+index fbf4bdf1e24d1102df113984be6c8dc3a7d0d810..787bf014d3bf0b8537f99bf5eb4074e100c78c18 100644
--- a/netwerk/protocol/http/InterceptedHttpChannel.cpp
+++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp
-@@ -727,6 +727,14 @@ NS_IMPL_ISUPPORTS(ResetInterceptionHeaderVisitor, nsIHttpHeaderVisitor)
+@@ -728,10 +728,33 @@ NS_IMPL_ISUPPORTS(ResetInterceptionHeaderVisitor, nsIHttpHeaderVisitor)
} // anonymous namespace
++NS_IMETHODIMP
++InterceptedHttpChannel::InterceptAfterServiceWorkerResets() {
++ mInterceptAfterServiceWorkerResets = true;
++ return NS_OK;
++}
++
+NS_IMETHODIMP
+InterceptedHttpChannel::ResetInterceptionWithURI(nsIURI* aURI) {
+ if (aURI) {
@@ -2383,7 +2495,20 @@ index c58fbc96391f8dcb585bd00b5ae8cba9088abd82..c121c891b61c9d60df770020c4ad0952
NS_IMETHODIMP
InterceptedHttpChannel::ResetInterception(bool aBypass) {
INTERCEPTED_LOG(("InterceptedHttpChannel::ResetInterception [%p] bypass: %s",
-@@ -1140,11 +1148,18 @@ InterceptedHttpChannel::OnStartRequest(nsIRequest* aRequest) {
+ this, aBypass ? "true" : "false"));
++ if (mInterceptAfterServiceWorkerResets) {
++ mInterceptAfterServiceWorkerResets = false;
++ nsCOMPtr controller;
++ GetCallback(controller);
++ if (!controller)
++ return NS_ERROR_DOM_INVALID_STATE_ERR;
++ return controller->ChannelIntercepted(this);
++ }
++
+ if (mCanceled) {
+ return mStatus;
+ }
+@@ -1146,11 +1169,18 @@ InterceptedHttpChannel::OnStartRequest(nsIRequest* aRequest) {
GetCallback(mProgressSink);
}
@@ -2402,11 +2527,151 @@ index c58fbc96391f8dcb585bd00b5ae8cba9088abd82..c121c891b61c9d60df770020c4ad0952
if (mPump && mLoadFlags & LOAD_CALL_CONTENT_SNIFFERS) {
mPump->PeekStream(CallTypeSniffers, static_cast(this));
+diff --git a/netwerk/protocol/http/InterceptedHttpChannel.h b/netwerk/protocol/http/InterceptedHttpChannel.h
+index 704404c9f094640ad63b685d64bd5a396e733e4b..92bdc21b4d6a015cc2f2bb22781ec6750c7789ec 100644
+--- a/netwerk/protocol/http/InterceptedHttpChannel.h
++++ b/netwerk/protocol/http/InterceptedHttpChannel.h
+@@ -90,6 +90,11 @@ class InterceptedHttpChannel final
+ Atomic mCallingStatusAndProgress;
+ bool mInterceptionReset{false};
+
++ // ----- Playwright begin -----
++ // After resetInterception is called, this request will call into interceptors again.
++ bool mInterceptAfterServiceWorkerResets{false};
++ // ----- Playwright end -------
++
+ /**
+ * InterceptionTimeStamps is used to record the time stamps of the
+ * interception.
+diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
+index e4479400a4c574f652befbee7d83bd664aa2b840..2761dce9477f7f1622a82fe1da6472597ae82534 100644
+--- a/netwerk/protocol/http/nsHttpChannel.cpp
++++ b/netwerk/protocol/http/nsHttpChannel.cpp
+@@ -688,11 +688,9 @@ nsresult nsHttpChannel::OnBeforeConnect() {
+ // SecurityInfo.sys.mjs
+ mLoadInfo->SetHstsStatus(isSecureURI);
+
+- RefPtr bc;
+- mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
+ // If bypassing the cache and we're forced offline
+ // we can just return the error here.
+- if (bc && bc->Top()->GetForceOffline() &&
++ if (IsForcedOffline() &&
+ BYPASS_LOCAL_CACHE(mLoadFlags, LoadPreferCacheLoadOverBypass())) {
+ return NS_ERROR_OFFLINE;
+ }
+@@ -805,9 +803,7 @@ nsresult nsHttpChannel::MaybeUseHTTPSRRForUpgrade(bool aShouldUpgrade,
+ return aStatus;
+ }
+
+- RefPtr bc;
+- mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
+- bool forceOffline = bc && bc->Top()->GetForceOffline();
++ bool forceOffline = IsForcedOffline();
+
+ if (mURI->SchemeIs("https") || aShouldUpgrade || !LoadUseHTTPSSVC() ||
+ forceOffline) {
+@@ -1266,15 +1262,14 @@ nsresult nsHttpChannel::ContinueConnect() {
+ "CORS preflight must have been finished by the time we "
+ "do the rest of ContinueConnect");
+
+- RefPtr bc;
+- mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
++ bool isForcedOffline = IsForcedOffline();
+
+ // we may or may not have a cache entry at this point
+ if (mCacheEntry) {
+ // read straight from the cache if possible...
+ if (CachedContentIsValid()) {
+ // If we're forced offline, and set to bypass the cache, return offline.
+- if (bc && bc->Top()->GetForceOffline() &&
++ if (isForcedOffline &&
+ BYPASS_LOCAL_CACHE(mLoadFlags, LoadPreferCacheLoadOverBypass())) {
+ return NS_ERROR_OFFLINE;
+ }
+@@ -1316,7 +1311,7 @@ nsresult nsHttpChannel::ContinueConnect() {
+ }
+
+ // We're about to hit the network. Don't if we're forced offline.
+- if (bc && bc->Top()->GetForceOffline()) {
++ if (isForcedOffline) {
+ return NS_ERROR_OFFLINE;
+ }
+
+@@ -1421,12 +1416,9 @@ void nsHttpChannel::SpeculativeConnect() {
+ // don't speculate if we are offline, when doing http upgrade (i.e.
+ // websockets bootstrap), or if we can't do keep-alive (because then we
+ // couldn't reuse the speculative connection anyhow).
+- RefPtr bc;
+- mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
+-
+ if (gIOService->IsOffline() || mUpgradeProtocolCallback ||
+ !(mCaps & NS_HTTP_ALLOW_KEEPALIVE) ||
+- (bc && bc->Top()->GetForceOffline())) {
++ IsForcedOffline()) {
+ return;
+ }
+
+@@ -4214,9 +4206,6 @@ nsresult nsHttpChannel::OpenCacheEntryInternal(bool isHttps) {
+ uint32_t cacheEntryOpenFlags;
+ bool offline = gIOService->IsOffline();
+
+- RefPtr bc;
+- mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
+-
+ bool maybeRCWN = false;
+
+ nsAutoCString cacheControlRequestHeader;
+@@ -4227,7 +4216,7 @@ nsresult nsHttpChannel::OpenCacheEntryInternal(bool isHttps) {
+ return NS_OK;
+ }
+
+- bool forceOffline = bc && bc->Top()->GetForceOffline();
++ bool forceOffline = IsForcedOffline();
+ if (offline || (mLoadFlags & INHIBIT_CACHING) || forceOffline) {
+ if (BYPASS_LOCAL_CACHE(mLoadFlags, LoadPreferCacheLoadOverBypass()) &&
+ !offline && !forceOffline) {
+@@ -7300,6 +7289,20 @@ void nsHttpChannel::MaybeStartDNSPrefetch() {
+ }
+ }
+
++bool nsHttpChannel::IsForcedOffline() {
++ RefPtr bc;
++ mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
++ if (bc && bc->Top()->GetForceOffline())
++ return true;
++
++ RefPtr wbc;
++ mLoadInfo->GetWorkerAssociatedBrowsingContext(getter_AddRefs(wbc));
++ if (wbc && wbc->Top()->GetForceOffline())
++ return true;
++
++ return false;
++}
++
+ NS_IMETHODIMP
+ nsHttpChannel::GetEncodedBodySize(uint64_t* aEncodedBodySize) {
+ if (mCacheEntry && !LoadCacheEntryIsWriteOnly()) {
+diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h
+index cb8b8b7406411edceb30aa53c9b9007a38058f84..ebdc5384ca20feda399b70532a3036174f1a7431 100644
+--- a/netwerk/protocol/http/nsHttpChannel.h
++++ b/netwerk/protocol/http/nsHttpChannel.h
+@@ -307,6 +307,10 @@ class nsHttpChannel final : public HttpBaseChannel,
+ void MaybeResolveProxyAndBeginConnect();
+ void MaybeStartDNSPrefetch();
+
++ // ---- Playwright begin
++ bool IsForcedOffline();
++ // ---- Playwright end
++
+ // Based on the proxy configuration determine the strategy for resolving the
+ // end server host name.
+ ProxyDNSStrategy GetProxyDNSStrategy();
diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp
-index f2c47c42a6b6448ede3a6fef1510a3982336d5af..9e35df57102c93238de2e4d548bbe1205d227f3b 100644
+index d3b44cc62d3df49bbf842356cbdb153c82c3163c..23cf9bc83fb1faaf1c7406331b78e522b307cbf0 100644
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
-@@ -1382,6 +1382,10 @@ void nsHtml5TreeOpExecutor::UpdateReferrerInfoFromMeta(
+@@ -1349,6 +1349,10 @@ void nsHtml5TreeOpExecutor::UpdateReferrerInfoFromMeta(
void nsHtml5TreeOpExecutor::AddSpeculationCSP(const nsAString& aCSP) {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@@ -2418,10 +2683,10 @@ index f2c47c42a6b6448ede3a6fef1510a3982336d5af..9e35df57102c93238de2e4d548bbe120
nsCOMPtr preloadCsp = mDocument->GetPreloadCsp();
if (!preloadCsp) {
diff --git a/security/manager/ssl/nsCertOverrideService.cpp b/security/manager/ssl/nsCertOverrideService.cpp
-index b8d0bbc3a12f74c19284b26eadada361abeb7946..a50379c57158748684e2ea5065550af81c1e9b86 100644
+index 8413eb5916f1f857e18972a14292d14f32684aee..66a3c7b01fdc56c29d789ff786aa91d8b0f02cd6 100644
--- a/security/manager/ssl/nsCertOverrideService.cpp
+++ b/security/manager/ssl/nsCertOverrideService.cpp
-@@ -438,7 +438,12 @@ nsCertOverrideService::HasMatchingOverride(
+@@ -433,7 +433,12 @@ nsCertOverrideService::HasMatchingOverride(
bool disableAllSecurityCheck = false;
{
MutexAutoLock lock(mMutex);
@@ -2435,7 +2700,7 @@ index b8d0bbc3a12f74c19284b26eadada361abeb7946..a50379c57158748684e2ea5065550af8
}
if (disableAllSecurityCheck) {
*aIsTemporary = false;
-@@ -650,14 +655,24 @@ static bool IsDebugger() {
+@@ -645,14 +650,24 @@ static bool IsDebugger() {
NS_IMETHODIMP
nsCertOverrideService::
@@ -2491,10 +2756,10 @@ index 6dfd07d6b676a99993408921de8dea9d561f201d..e3c6794363cd6336effbeac83a179f37
readonly attribute boolean securityCheckDisabled;
};
diff --git a/services/settings/Utils.sys.mjs b/services/settings/Utils.sys.mjs
-index 73c83e526be1a3a252f995d0718e3975d50bffa7..db5977c54221e19e107a8325a0834302c2e84546 100644
+index d3643aedf21a26594268a47bc0f6ac53e3977f75..795c6f3b28278b9f65a596799d4e424880fcffa7 100644
--- a/services/settings/Utils.sys.mjs
+++ b/services/settings/Utils.sys.mjs
-@@ -95,7 +95,7 @@ function _isUndefined(value) {
+@@ -97,7 +97,7 @@ const _cdnURLs = {};
export var Utils = {
get SERVER_URL() {
@@ -2503,7 +2768,7 @@ index 73c83e526be1a3a252f995d0718e3975d50bffa7..db5977c54221e19e107a8325a0834302
? lazy.gServerURL
: AppConstants.REMOTE_SETTINGS_SERVER_URL;
},
-@@ -108,6 +108,9 @@ export var Utils = {
+@@ -110,6 +110,9 @@ export var Utils = {
log,
get shouldSkipRemoteActivityDueToTests() {
@@ -2513,31 +2778,8 @@ index 73c83e526be1a3a252f995d0718e3975d50bffa7..db5977c54221e19e107a8325a0834302
return (
(lazy.isRunningTests || Cu.isInAutomation) &&
this.SERVER_URL == "data:,#remote-settings-dummy/v1"
-diff --git a/servo/components/style/gecko/media_features.rs b/servo/components/style/gecko/media_features.rs
-index 8de45d95c2b942f069c898c93702bc7db2219369..be72e9678c3de31b1eaa72cfcb2c8be886f4a80f 100644
---- a/servo/components/style/gecko/media_features.rs
-+++ b/servo/components/style/gecko/media_features.rs
-@@ -292,10 +292,15 @@ pub enum ForcedColors {
-
- /// https://drafts.csswg.org/mediaqueries-5/#forced-colors
- fn eval_forced_colors(context: &Context, query_value: Option) -> bool {
-- let forced = !context.device().use_document_colors();
-+ let prefers_forced_colors =
-+ unsafe { bindings::Gecko_MediaFeatures_ForcedColors(context.device().document()) };
-+ let query_value = match query_value {
-+ Some(v) => v,
-+ None => return prefers_forced_colors,
-+ };
- match query_value {
-- Some(query_value) => forced == (query_value == ForcedColors::Active),
-- None => forced,
-+ ForcedColors::Active => prefers_forced_colors,
-+ ForcedColors::None => !prefers_forced_colors,
- }
- }
-
diff --git a/toolkit/components/browser/nsIWebBrowserChrome.idl b/toolkit/components/browser/nsIWebBrowserChrome.idl
-index 517c87a285dd93220cb2654d6ba7bb05c66cdeb7..e3010421d8dbe5ed5ed72feedb9f15805b32503e 100644
+index 75555352b8a15a50e4a21e34fc8ede4e9246c7cc..72855a404effa42b6c55cd0c2fcb8bdd6c2b3f9f 100644
--- a/toolkit/components/browser/nsIWebBrowserChrome.idl
+++ b/toolkit/components/browser/nsIWebBrowserChrome.idl
@@ -74,6 +74,9 @@ interface nsIWebBrowserChrome : nsISupports
@@ -2551,27 +2793,58 @@ index 517c87a285dd93220cb2654d6ba7bb05c66cdeb7..e3010421d8dbe5ed5ed72feedb9f1580
// ignored for Linux.
const unsigned long CHROME_SUPPRESS_ANIMATION = 1 << 24;
diff --git a/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.sys.mjs b/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.sys.mjs
-index 15fa2193c6116b5bd0cf2ee608eb5971f3d24370..aa92eb63b8f907e0df9ef8df60fd076aa3d6a472 100644
+index 76fb919603e8d2b7864d351eb47be2a38e40e31e..9f1e880fe9027d1a2540ffeaa11fc0c4e1a36133 100644
--- a/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.sys.mjs
+++ b/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.sys.mjs
-@@ -108,6 +108,12 @@ EnterprisePoliciesManager.prototype = {
+@@ -108,7 +108,9 @@ EnterprisePoliciesManager.prototype = {
Services.prefs.clearUserPref(PREF_POLICIES_APPLIED);
}
-+ // Playwright: Disable enterprise policies
-+ if (true) {
-+ this.status = Ci.nsIEnterprisePolicies.INACTIVE;
-+ return;
-+ }
-+
- let provider = this._chooseProvider();
+- let provider = this._chooseProvider();
++ // --- Playwright begin ---
++ let provider = new PlaywrightPoliciesProvider();
++ // --- Playwright end ---
if (provider.failed) {
+ this.status = Ci.nsIEnterprisePolicies.FAILED;
+@@ -631,6 +633,19 @@ class JSONPoliciesProvider {
+ }
+ }
+
++class PlaywrightPoliciesProvider extends JSONPoliciesProvider {
++ _getConfigurationFile() {
++ let prefPath = Services.prefs.getStringPref(PREF_ALTERNATE_PATH, "");
++ if (!prefPath)
++ return null;
++
++ dump(`Playwright: loading enterprise policies from ${prefPath}\n`);
++ let configFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
++ configFile.initWithPath(prefPath);
++ return configFile;
++ }
++}
++
+ class WindowsGPOPoliciesProvider {
+ constructor() {
+ this._policies = null;
+diff --git a/toolkit/components/resistfingerprinting/nsUserCharacteristics.cpp b/toolkit/components/resistfingerprinting/nsUserCharacteristics.cpp
+index 253171bed4dea54fc28bb4ddc9920823dbd9351c..6dc0e620b399ed9ee6b53f97bc080ec17ee4e1b5 100644
+--- a/toolkit/components/resistfingerprinting/nsUserCharacteristics.cpp
++++ b/toolkit/components/resistfingerprinting/nsUserCharacteristics.cpp
+@@ -490,7 +490,7 @@ void PopulateLanguages() {
+ // sufficient to only collect this information as the other properties are
+ // just reformats of Navigator::GetAcceptLanguages.
+ nsTArray languages;
+- dom::Navigator::GetAcceptLanguages(languages);
++ dom::Navigator::GetAcceptLanguages(nullptr, languages);
+ nsCString output = "["_ns;
+
+ for (const auto& language : languages) {
diff --git a/toolkit/components/startup/nsAppStartup.cpp b/toolkit/components/startup/nsAppStartup.cpp
-index 3314cb813f6ceb67096eeda0864ad3b16c0616cb..5aac63649e186d624a9905a5d16513f8353f5515 100644
+index dc0826f72134b91482e30d183ddf52e95146e12f..119a324e162b6965ddd3d6b2d53bd2856a174452 100644
--- a/toolkit/components/startup/nsAppStartup.cpp
+++ b/toolkit/components/startup/nsAppStartup.cpp
-@@ -371,7 +371,7 @@ nsAppStartup::Quit(uint32_t aMode, int aExitCode, bool* aUserAllowedQuit) {
+@@ -361,7 +361,7 @@ nsAppStartup::Quit(uint32_t aMode, int aExitCode, bool* aUserAllowedQuit) {
nsCOMPtr windowEnumerator;
nsCOMPtr mediator(
do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
@@ -2596,10 +2869,10 @@ index 654903fadb709be976b72f36f155e23bc0622152..815b3dc24c9fda6b1db6c4666ac68904
int32_t aMaxSelfProgress,
int32_t aCurTotalProgress,
diff --git a/toolkit/components/windowwatcher/nsWindowWatcher.cpp b/toolkit/components/windowwatcher/nsWindowWatcher.cpp
-index 209af157a35cf9c4586424421ee19b3f680796b6..1feb61e2f18e9a13631addc935f00da07739291e 100644
+index 811fb16410e8cf900ad873797269e5fe715579a5..821f5b0c2af8e1dc8754cd023571d1d0ff09eeb6 100644
--- a/toolkit/components/windowwatcher/nsWindowWatcher.cpp
+++ b/toolkit/components/windowwatcher/nsWindowWatcher.cpp
-@@ -1853,7 +1853,11 @@ uint32_t nsWindowWatcher::CalculateChromeFlagsForContent(
+@@ -1880,7 +1880,11 @@ uint32_t nsWindowWatcher::CalculateChromeFlagsForContent(
// Open a minimal popup.
*aIsPopupRequested = true;
@@ -2613,23 +2886,23 @@ index 209af157a35cf9c4586424421ee19b3f680796b6..1feb61e2f18e9a13631addc935f00da0
/**
diff --git a/toolkit/mozapps/update/UpdateService.sys.mjs b/toolkit/mozapps/update/UpdateService.sys.mjs
-index 34bf1b9e19ae54f78d134b023af96820bc13a905..b85793edcd1996833420a026cb08706d648ece14 100644
+index 40f04aeace0efd701e9454bb8dc6260dec90807e..5b70f65f3e78fc0889b15651ff203bb82e79d202 100644
--- a/toolkit/mozapps/update/UpdateService.sys.mjs
+++ b/toolkit/mozapps/update/UpdateService.sys.mjs
-@@ -3852,6 +3852,8 @@ UpdateService.prototype = {
- },
+@@ -3814,6 +3814,8 @@ export class UpdateService {
+ }
get disabledForTesting() {
+ /* playwright */
+ return true;
- return (
- (Cu.isInAutomation ||
- lazy.Marionette.running ||
+ return lazy.UpdateServiceStub.updateDisabledForTesting;
+ }
+
diff --git a/toolkit/toolkit.mozbuild b/toolkit/toolkit.mozbuild
-index b697eb1e3b02b0ffcc95a6e492dc23eb888488cc..0f4059341dbb3c2ecb2c46be0850e0d56e2a7453 100644
+index c50b7f3932e18da9fad4b673e353974a001e78c4..708e0d75594ddcd62276d4e08c4bd5c64d7f0698 100644
--- a/toolkit/toolkit.mozbuild
+++ b/toolkit/toolkit.mozbuild
-@@ -155,6 +155,7 @@ if CONFIG["ENABLE_WEBDRIVER"]:
+@@ -152,6 +152,7 @@ if CONFIG["ENABLE_WEBDRIVER"]:
"/remote",
"/testing/firefox-ui",
"/testing/marionette",
@@ -2638,7 +2911,7 @@ index b697eb1e3b02b0ffcc95a6e492dc23eb888488cc..0f4059341dbb3c2ecb2c46be0850e0d5
]
diff --git a/toolkit/xre/nsWindowsWMain.cpp b/toolkit/xre/nsWindowsWMain.cpp
-index 2a91deec5c10f87ed09f99b659baab77b2b638f2..78f4f30a0efe314563c6405f7b0848d2c3ca0551 100644
+index 7eb9e1104682d4eb47060654f43a1efa8b2a6bb2..a8315d6decf654b5302bea5beeea34140c300ded 100644
--- a/toolkit/xre/nsWindowsWMain.cpp
+++ b/toolkit/xre/nsWindowsWMain.cpp
@@ -14,8 +14,10 @@
@@ -2652,10 +2925,10 @@ index 2a91deec5c10f87ed09f99b659baab77b2b638f2..78f4f30a0efe314563c6405f7b0848d2
#include
#ifdef __MINGW32__
-@@ -137,6 +139,19 @@ int wmain(int argc, WCHAR** argv) {
+@@ -114,6 +116,19 @@ static void FreeAllocStrings(int argc, char** argv) {
+ int wmain(int argc, WCHAR** argv) {
SanitizeEnvironmentVariables();
SetDllDirectoryW(L"");
- RemovePrefetchArguments(argc, argv);
+ bool hasJugglerPipe =
+ mozilla::CheckArg(argc, argv, "juggler-pipe", nullptr,
+ mozilla::CheckArgFlag::None) == mozilla::ARG_FOUND;
@@ -2673,10 +2946,10 @@ index 2a91deec5c10f87ed09f99b659baab77b2b638f2..78f4f30a0efe314563c6405f7b0848d2
// Only run this code if LauncherProcessWin.h was included beforehand, thus
// signalling that the hosting process should support launcher mode.
diff --git a/uriloader/base/nsDocLoader.cpp b/uriloader/base/nsDocLoader.cpp
-index fe72a2715da8846146377e719559c16e6ef1f7ff..a5959143bac8f62ee359fa3883a844f3fe541685 100644
+index e5cc386651e192710b61858ab5625c97a02b92da..e560ad4fef232a26ce1e1b244f4ccea05f4aea71 100644
--- a/uriloader/base/nsDocLoader.cpp
+++ b/uriloader/base/nsDocLoader.cpp
-@@ -813,6 +813,12 @@ void nsDocLoader::DocLoaderIsEmpty(bool aFlushLayout,
+@@ -812,6 +812,12 @@ void nsDocLoader::DocLoaderIsEmpty(bool aFlushLayout,
("DocLoader:%p: Firing load event for document.open\n",
this));
@@ -2690,7 +2963,7 @@ index fe72a2715da8846146377e719559c16e6ef1f7ff..a5959143bac8f62ee359fa3883a844f3
// nsDocumentViewer::LoadComplete that doesn't do various things
// that are not relevant here because this wasn't an actual
diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp
-index 4573e28470c5112f5ac2c5dd53e7a9d1ceedb943..b53b86d8e39f1de4b0d0f1a8d5d7295ea050b878 100644
+index e23df8e6f982ea71eb1f07dd677ed13109d2831b..d98f49d34a346113fd0ed5c242d5ef228ea0e0cd 100644
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -112,6 +112,7 @@
@@ -2701,7 +2974,7 @@ index 4573e28470c5112f5ac2c5dd53e7a9d1ceedb943..b53b86d8e39f1de4b0d0f1a8d5d7295e
#include "mozilla/Preferences.h"
#include "mozilla/ipc/URIUtils.h"
-@@ -831,6 +832,12 @@ NS_IMETHODIMP nsExternalHelperAppService::ApplyDecodingForExtension(
+@@ -865,6 +866,12 @@ NS_IMETHODIMP nsExternalHelperAppService::ApplyDecodingForExtension(
return NS_OK;
}
@@ -2714,9 +2987,9 @@ index 4573e28470c5112f5ac2c5dd53e7a9d1ceedb943..b53b86d8e39f1de4b0d0f1a8d5d7295e
nsresult nsExternalHelperAppService::GetFileTokenForPath(
const char16_t* aPlatformAppPath, nsIFile** aFile) {
nsDependentString platformAppPath(aPlatformAppPath);
-@@ -1442,7 +1449,12 @@ nsresult nsExternalAppHandler::SetUpTempFile(nsIChannel* aChannel) {
+@@ -1486,7 +1493,12 @@ nsresult nsExternalAppHandler::SetUpTempFile(nsIChannel* aChannel) {
// Strip off the ".part" from mTempLeafName
- mTempLeafName.Truncate(mTempLeafName.Length() - ArrayLength(".part") + 1);
+ mTempLeafName.Truncate(mTempLeafName.Length() - std::size(".part") + 1);
+ return CreateSaverForTempFile();
+}
@@ -2727,7 +3000,7 @@ index 4573e28470c5112f5ac2c5dd53e7a9d1ceedb943..b53b86d8e39f1de4b0d0f1a8d5d7295e
mSaver =
do_CreateInstance(NS_BACKGROUNDFILESAVERSTREAMLISTENER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
-@@ -1631,7 +1643,36 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) {
+@@ -1672,7 +1684,36 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) {
return NS_OK;
}
@@ -2765,7 +3038,7 @@ index 4573e28470c5112f5ac2c5dd53e7a9d1ceedb943..b53b86d8e39f1de4b0d0f1a8d5d7295e
if (NS_FAILED(rv)) {
nsresult transferError = rv;
-@@ -1683,6 +1724,9 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) {
+@@ -1733,6 +1774,9 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) {
bool alwaysAsk = true;
mMimeInfo->GetAlwaysAskBeforeHandling(&alwaysAsk);
@@ -2775,7 +3048,7 @@ index 4573e28470c5112f5ac2c5dd53e7a9d1ceedb943..b53b86d8e39f1de4b0d0f1a8d5d7295e
if (alwaysAsk) {
// But we *don't* ask if this mimeInfo didn't come from
// our user configuration datastore and the user has said
-@@ -2199,6 +2243,16 @@ nsExternalAppHandler::OnSaveComplete(nsIBackgroundFileSaver* aSaver,
+@@ -2249,6 +2293,16 @@ nsExternalAppHandler::OnSaveComplete(nsIBackgroundFileSaver* aSaver,
NotifyTransfer(aStatus);
}
@@ -2792,7 +3065,7 @@ index 4573e28470c5112f5ac2c5dd53e7a9d1ceedb943..b53b86d8e39f1de4b0d0f1a8d5d7295e
return NS_OK;
}
-@@ -2680,6 +2734,15 @@ NS_IMETHODIMP nsExternalAppHandler::Cancel(nsresult aReason) {
+@@ -2732,6 +2786,15 @@ NS_IMETHODIMP nsExternalAppHandler::Cancel(nsresult aReason) {
}
}
@@ -2809,10 +3082,10 @@ index 4573e28470c5112f5ac2c5dd53e7a9d1ceedb943..b53b86d8e39f1de4b0d0f1a8d5d7295e
// OnStartRequest)
mDialog = nullptr;
diff --git a/uriloader/exthandler/nsExternalHelperAppService.h b/uriloader/exthandler/nsExternalHelperAppService.h
-index 1f77e095dbfa3acc046779114007d83fc1cfa087..2354abbab7af6f6bdc3bd628722f03ea401d236a 100644
+index 2dd4ff87bda3e0ba395cca168c42b37db1713ddf..83e8a3d328e325b3f50f593c9ea71692f9c7d401 100644
--- a/uriloader/exthandler/nsExternalHelperAppService.h
+++ b/uriloader/exthandler/nsExternalHelperAppService.h
-@@ -257,6 +257,8 @@ class nsExternalHelperAppService : public nsIExternalHelperAppService,
+@@ -258,6 +258,8 @@ class nsExternalHelperAppService : public nsIExternalHelperAppService,
mozilla::dom::BrowsingContext* aContentContext, bool aForceSave,
nsIInterfaceRequestor* aWindowContext,
nsIStreamListener** aStreamListener);
@@ -2821,7 +3094,7 @@ index 1f77e095dbfa3acc046779114007d83fc1cfa087..2354abbab7af6f6bdc3bd628722f03ea
};
/**
-@@ -462,6 +464,9 @@ class nsExternalAppHandler final : public nsIStreamListener,
+@@ -455,6 +457,9 @@ class nsExternalAppHandler final : public nsIStreamListener,
* Upon successful return, both mTempFile and mSaver will be valid.
*/
nsresult SetUpTempFile(nsIChannel* aChannel);
@@ -2832,7 +3105,7 @@ index 1f77e095dbfa3acc046779114007d83fc1cfa087..2354abbab7af6f6bdc3bd628722f03ea
* When we download a helper app, we are going to retarget all load
* notifications into our own docloader and load group instead of
diff --git a/uriloader/exthandler/nsIExternalHelperAppService.idl b/uriloader/exthandler/nsIExternalHelperAppService.idl
-index 4a399acb72d4fd475c9ae43e9eadbc32f261e290..31e9490a7dfd7d7eff69ad23c9ce277f367d1524 100644
+index 53ea934dd4876e4b491b724385c8fbf7d00ee6cd..0b7b88c853b21ce778d8e87fea0a2bfe839ad412 100644
--- a/uriloader/exthandler/nsIExternalHelperAppService.idl
+++ b/uriloader/exthandler/nsIExternalHelperAppService.idl
@@ -6,8 +6,11 @@
@@ -2857,7 +3130,7 @@ index 4a399acb72d4fd475c9ae43e9eadbc32f261e290..31e9490a7dfd7d7eff69ad23c9ce277f
+[scriptable, uuid(9a20e9b0-75d0-11ea-bc55-0242ac130003)]
+interface nsIDownloadInterceptor : nsISupports
+{
-+ bool interceptDownloadRequest(in nsIHelperAppLauncher aHandler, in nsIRequest aRequest, in BrowsingContext aBrowsingContext, out nsIFile file);
++ boolean interceptDownloadRequest(in nsIHelperAppLauncher aHandler, in nsIRequest aRequest, in BrowsingContext aBrowsingContext, out nsIFile file);
+
+ void onDownloadComplete(in nsIHelperAppLauncher aHandler, in ACString aErrorName);
+};
@@ -2865,10 +3138,11 @@ index 4a399acb72d4fd475c9ae43e9eadbc32f261e290..31e9490a7dfd7d7eff69ad23c9ce277f
/**
* The external helper app service is used for finding and launching
* platform specific external applications for a given mime content type.
-@@ -76,6 +90,7 @@ interface nsIExternalHelperAppService : nsISupports
- boolean applyDecodingForExtension(in AUTF8String aExtension,
- in ACString aEncodingType);
-
+@@ -87,6 +101,8 @@ interface nsIExternalHelperAppService : nsISupports
+ * `DownloadIntegration.sys.mjs`, which is implemented on all platforms.
+ */
+ nsIFile getPreferredDownloadsDirectory();
++
+ void setDownloadInterceptor(in nsIDownloadInterceptor interceptor);
};
@@ -2902,56 +3176,32 @@ index 1c25e9d9a101233f71e92288a0f93125b81ac1c5..22cf67b0f6e3ddd2b3ed725a314ba6a9
}
#endif
diff --git a/widget/MouseEvents.h b/widget/MouseEvents.h
-index d29b406524c8b4afe437b559e33b4b2b5824ee58..6bef9c1657f93f90f96735d76fedb6ba3888b5c1 100644
+index 5ca1a6fa13233b1bd00ee0467732c5875c51d343..0d3b8ebe127e59516802e8819f4bbed961f0992b 100644
--- a/widget/MouseEvents.h
+++ b/widget/MouseEvents.h
-@@ -258,6 +258,7 @@ class WidgetMouseEvent : public WidgetMouseEventBase,
- : mReason(eReal),
- mContextMenuTrigger(eNormal),
- mClickCount(0),
-+ mJugglerEventId(0),
- mIgnoreRootScrollFrame(false),
- mClickEventPrevented(false) {}
-
-@@ -269,6 +270,7 @@ class WidgetMouseEvent : public WidgetMouseEventBase,
- mReason(aReason),
- mContextMenuTrigger(eNormal),
- mClickCount(0),
-+ mJugglerEventId(0),
- mIgnoreRootScrollFrame(false),
- mClickEventPrevented(false) {}
-
-@@ -288,6 +290,7 @@ class WidgetMouseEvent : public WidgetMouseEventBase,
- mReason(aReason),
- mContextMenuTrigger(aContextMenuTrigger),
- mClickCount(0),
-+ mJugglerEventId(0),
- mIgnoreRootScrollFrame(false),
- mClickEventPrevented(false) {
- if (aMessage == eContextMenu) {
-@@ -336,6 +339,9 @@ class WidgetMouseEvent : public WidgetMouseEventBase,
+@@ -368,6 +368,9 @@ class WidgetMouseEvent : public WidgetMouseEventBase,
// Otherwise, this must be 0.
- uint32_t mClickCount;
+ uint32_t mClickCount = 0;
+ // Unique event ID
-+ uint32_t mJugglerEventId;
++ uint32_t mJugglerEventId = 0;
+
// Whether the event should ignore scroll frame bounds during dispatch.
- bool mIgnoreRootScrollFrame;
-
-@@ -348,6 +354,7 @@ class WidgetMouseEvent : public WidgetMouseEventBase,
+ bool mIgnoreRootScrollFrame = false;
+@@ -391,6 +394,7 @@ class WidgetMouseEvent : public WidgetMouseEventBase,
+ mContextMenuTrigger = aEvent.mContextMenuTrigger;
mExitFrom = aEvent.mExitFrom;
mClickCount = aEvent.mClickCount;
+ mJugglerEventId = aEvent.mJugglerEventId;
mIgnoreRootScrollFrame = aEvent.mIgnoreRootScrollFrame;
+ mIgnoreCapturingContent = aEvent.mIgnoreCapturingContent;
mClickEventPrevented = aEvent.mClickEventPrevented;
- }
diff --git a/widget/cocoa/NativeKeyBindings.mm b/widget/cocoa/NativeKeyBindings.mm
-index e4bdf715e2fb899e97a5bfeb2e147127460d6047..3554f919480278b7353617481c7ce8050630a1aa 100644
+index 24b70173c2e8bb9be9fd6255984a70efe3b14099..75ac367a1c4bb44d4b68b5f4ecc6adf56dbd408e 100644
--- a/widget/cocoa/NativeKeyBindings.mm
+++ b/widget/cocoa/NativeKeyBindings.mm
-@@ -528,6 +528,13 @@
+@@ -549,6 +549,13 @@
break;
case KEY_NAME_INDEX_ArrowLeft:
if (aEvent.IsAlt()) {
@@ -2965,7 +3215,7 @@ index e4bdf715e2fb899e97a5bfeb2e147127460d6047..3554f919480278b7353617481c7ce805
break;
}
if (aEvent.IsMeta() || (aEvent.IsControl() && aEvent.IsShift())) {
-@@ -550,6 +557,13 @@
+@@ -571,6 +578,13 @@
break;
case KEY_NAME_INDEX_ArrowRight:
if (aEvent.IsAlt()) {
@@ -2979,7 +3229,7 @@ index e4bdf715e2fb899e97a5bfeb2e147127460d6047..3554f919480278b7353617481c7ce805
break;
}
if (aEvent.IsMeta() || (aEvent.IsControl() && aEvent.IsShift())) {
-@@ -572,6 +586,10 @@
+@@ -593,6 +607,10 @@
break;
case KEY_NAME_INDEX_ArrowUp:
if (aEvent.IsControl()) {
@@ -2990,7 +3240,7 @@ index e4bdf715e2fb899e97a5bfeb2e147127460d6047..3554f919480278b7353617481c7ce805
break;
}
if (aEvent.IsMeta()) {
-@@ -582,7 +600,7 @@
+@@ -603,7 +621,7 @@
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(moveToBeginningOfDocument:))
: ToObjcSelectorPtr(
@@ -2999,7 +3249,7 @@ index e4bdf715e2fb899e97a5bfeb2e147127460d6047..3554f919480278b7353617481c7ce805
aCommands);
break;
}
-@@ -609,6 +627,10 @@
+@@ -630,6 +648,10 @@
break;
case KEY_NAME_INDEX_ArrowDown:
if (aEvent.IsControl()) {
@@ -3010,6 +3260,18 @@ index e4bdf715e2fb899e97a5bfeb2e147127460d6047..3554f919480278b7353617481c7ce805
break;
}
if (aEvent.IsMeta()) {
+diff --git a/widget/gtk/nsFilePicker.cpp b/widget/gtk/nsFilePicker.cpp
+index f4bded345e95674c66e4d4ad56b50844fce0871b..321e22d334a8bbc6057ee78e77e139a2804b2403 100644
+--- a/widget/gtk/nsFilePicker.cpp
++++ b/widget/gtk/nsFilePicker.cpp
+@@ -21,6 +21,7 @@
+ #include "mozilla/Components.h"
+ #include "mozilla/Preferences.h"
+ #include "mozilla/dom/Promise.h"
++#include "gfxPlatform.h"
+
+ #include "nsArrayEnumerator.h"
+ #include "nsEnumeratorUtils.h"
diff --git a/widget/headless/HeadlessCompositorWidget.cpp b/widget/headless/HeadlessCompositorWidget.cpp
index bb4ee9175e66dc40de1871a7f91368fe309494a3..747625e3869882300bfbc18b184db5151dd90c1a 100644
--- a/widget/headless/HeadlessCompositorWidget.cpp
@@ -3160,7 +3422,7 @@ index facd2bc65afab8ec1aa322faa20a67464964dfb9..d6dea95472bec6006411753c3dfdab2e
} // namespace widget
diff --git a/widget/headless/HeadlessWidget.cpp b/widget/headless/HeadlessWidget.cpp
-index 083d026d3c019cb76fff2b8f605f3d6ef8dd578f..84c049709ead92c980b86230513a634bf6337085 100644
+index daa2d455374fd9f75a5c6ac9f7b91696d88b065c..f45184137b52db0a5774bf3365b15f784532fbdf 100644
--- a/widget/headless/HeadlessWidget.cpp
+++ b/widget/headless/HeadlessWidget.cpp
@@ -111,6 +111,8 @@ void HeadlessWidget::Destroy() {
@@ -3172,7 +3434,7 @@ index 083d026d3c019cb76fff2b8f605f3d6ef8dd578f..84c049709ead92c980b86230513a634b
nsBaseWidget::OnDestroy();
nsBaseWidget::Destroy();
-@@ -621,5 +623,14 @@ nsresult HeadlessWidget::SynthesizeNativeTouchpadPan(
+@@ -593,5 +595,14 @@ nsresult HeadlessWidget::SynthesizeNativeTouchpadPan(
return NS_OK;
}
@@ -3188,12 +3450,12 @@ index 083d026d3c019cb76fff2b8f605f3d6ef8dd578f..84c049709ead92c980b86230513a634b
} // namespace widget
} // namespace mozilla
diff --git a/widget/headless/HeadlessWidget.h b/widget/headless/HeadlessWidget.h
-index 9856991ef32f25f51942f8cd664a09bec2192c70..948947a421179e91c51005aeb83ed0d18cfc84ce 100644
+index 39833c28e40c61e354119cde429b8389056bafac..a638fb7520b857219ce58fcbf9ca0ed939528924 100644
--- a/widget/headless/HeadlessWidget.h
+++ b/widget/headless/HeadlessWidget.h
-@@ -141,6 +141,9 @@ class HeadlessWidget : public nsBaseWidget {
- int32_t aModifierFlags,
- nsIObserver* aObserver) override;
+@@ -132,6 +132,9 @@ class HeadlessWidget final : public nsBaseWidget {
+ int32_t aModifierFlags,
+ nsIObserver* aObserver) override;
+ using SnapshotListener = std::function&&)>;
+ void SetSnapshotListener(SnapshotListener&& listener);
@@ -3202,10 +3464,10 @@ index 9856991ef32f25f51942f8cd664a09bec2192c70..948947a421179e91c51005aeb83ed0d1
~HeadlessWidget();
bool mEnabled;
diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h
-index 8ba46829357fc4acc47bf20842fd869902efa000..a1b5b2c5230d90981bd563d4df2d2bf1c2e05cef 100644
+index f7262978239665cbe20470da0790d4d177d4c501..70d11aca3d5b509cf5b37d626299a23fede73ba3 100644
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
-@@ -234,6 +234,7 @@ struct ParamTraits {
+@@ -244,6 +244,7 @@ struct ParamTraits {
aParam.mExitFrom.value()));
}
WriteParam(aWriter, aParam.mClickCount);
@@ -3213,7 +3475,7 @@ index 8ba46829357fc4acc47bf20842fd869902efa000..a1b5b2c5230d90981bd563d4df2d2bf1
}
static bool Read(MessageReader* aReader, paramType* aResult) {
-@@ -258,6 +259,7 @@ struct ParamTraits {
+@@ -268,6 +269,7 @@ struct ParamTraits {
aResult->mExitFrom = Some(static_cast(exitFrom));
}
rv = rv && ReadParam(aReader, &aResult->mClickCount);
@@ -3222,10 +3484,10 @@ index 8ba46829357fc4acc47bf20842fd869902efa000..a1b5b2c5230d90981bd563d4df2d2bf1
}
};
diff --git a/xpcom/reflect/xptinfo/xptinfo.h b/xpcom/reflect/xptinfo/xptinfo.h
-index 2456c2c2b58b27cd595880b547ed20fb687a1835..e967c089b2331c7cd36d34e511543fbc84320b7d 100644
+index 787d30d881adedd57d2025ca57bff4bc6c57e803..ae1a0172c960ab16919133485722d2ae0cdbcbd4 100644
--- a/xpcom/reflect/xptinfo/xptinfo.h
+++ b/xpcom/reflect/xptinfo/xptinfo.h
-@@ -514,7 +514,7 @@ static_assert(sizeof(nsXPTMethodInfo) == 8, "wrong size");
+@@ -505,7 +505,7 @@ static_assert(sizeof(nsXPTMethodInfo) == 8, "wrong size");
#if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
# define PARAM_BUFFER_COUNT 18
#else
diff --git a/browser_patches/firefox/preferences/playwright.cfg b/browser_patches/firefox/preferences/playwright.cfg
index 99fbf39420999..5dc8986c19c4d 100644
--- a/browser_patches/firefox/preferences/playwright.cfg
+++ b/browser_patches/firefox/preferences/playwright.cfg
@@ -8,6 +8,13 @@ pref("dom.input_events.security.minTimeElapsedInMS", 0);
pref("dom.iframe_lazy_loading.enabled", false);
+// Allows a custom "policies.json" file.
+pref("browser.policies.alternatePath", getenv("PLAYWRIGHT_FIREFOX_POLICIES_JSON") || "");
+
+// This setting is experimental and is only enabled on early betas.
+// Disable it unconditionally since it breaks proxy tests.
+pref("dom.security.https_first", false);
+
pref("datareporting.policy.dataSubmissionEnabled", false);
pref("datareporting.policy.dataSubmissionPolicyAccepted", false);
pref("datareporting.policy.dataSubmissionPolicyBypassNotification", true);
@@ -47,6 +54,9 @@ pref("permissions.isolateBy.userContext", true);
// |Page.setFileInputFiles| protocol method.
pref("dom.file.createInChild", true);
+// Allow uploading directorys in content process.
+pref("dom.filesystem.pathcheck.disabled", true);
+
// Do not warn when closing all open tabs
pref("browser.tabs.warnOnClose", false);
@@ -85,6 +95,18 @@ pref("geo.provider.testing", true);
// THESE ARE NICHE PROPERTIES THAT ARE NICE TO HAVE
// =================================================================
+// We never want to have interactive screen capture picker enabled in FF build.
+pref("media.getdisplaymedia.screencapturekit.enabled", false);
+pref("media.getdisplaymedia.screencapturekit.picker.enabled", false);
+
+// Allow proxying loopback URLs; see https://phabricator.services.mozilla.com/D237187
+pref("network.proxy.allow_hijacking_localhost", true);
+pref("network.proxy.testing_localhost_is_secure_when_hijacked", true);
+
+// Disable double-dispatching of "input" event for the text composition.
+// See https://phabricator.services.mozilla.com/D234620 for details.
+pref("dom.input_events.dispatch_before_compositionend", false);
+
// Enable software-backed webgl. See https://phabricator.services.mozilla.com/D164016
pref("webgl.forbid-software", false);
@@ -97,6 +119,11 @@ pref("extensions.formautofill.addresses.supported", "off");
// firefox behavior with other browser defaults.
pref("security.enterprise_roots.enabled", true);
+// There's a security features warning that might be shown on certain Linux distributions & configurations:
+// https://support.mozilla.org/en-US/kb/install-firefox-linux#w_security-features-warning
+// This notification should never be shown in automation scenarios.
+pref("security.sandbox.warn_unprivileged_namespaces", false);
+
// Avoid stalling on shutdown, after "xpcom-will-shutdown" phase.
// This at least happens when shutting down soon after launching.
// See AppShutdown.cpp for more details on shutdown phases.
diff --git a/browser_patches/webkit/UPSTREAM_CONFIG.sh b/browser_patches/webkit/UPSTREAM_CONFIG.sh
index 069f24571c3c3..574e1f310aa7f 100644
--- a/browser_patches/webkit/UPSTREAM_CONFIG.sh
+++ b/browser_patches/webkit/UPSTREAM_CONFIG.sh
@@ -1,3 +1,3 @@
REMOTE_URL="https://github.com/WebKit/WebKit.git"
BASE_BRANCH="main"
-BASE_REVISION="b2ca06dc3d84b356d01cdf09a82049f80515fbfe"
+BASE_REVISION="153da00a252619799ba4b32cd0ac6c5b8faf6a35"
diff --git a/browser_patches/webkit/embedder/Playwright/mac/AppDelegate.m b/browser_patches/webkit/embedder/Playwright/mac/AppDelegate.m
index a6c7be8ae48a9..b4d08b700ac91 100644
--- a/browser_patches/webkit/embedder/Playwright/mac/AppDelegate.m
+++ b/browser_patches/webkit/embedder/Playwright/mac/AppDelegate.m
@@ -33,6 +33,7 @@
#import
#import
#import
+#import
#import
#import
#import
@@ -97,7 +98,7 @@ - (id)init
for (NSString *argument in subArray) {
if (![argument hasPrefix:@"--"])
- _initialURL = argument;
+ _initialURL = [argument copy];
if ([argument hasPrefix:@"--user-data-dir="]) {
NSRange range = NSMakeRange(16, [argument length] - 16);
_userDataDir = [[argument substringWithRange:range] copy];
@@ -230,7 +231,7 @@ - (WKWebViewConfiguration *)defaultConfiguration
configuration = [[WKWebViewConfiguration alloc] init];
configuration.websiteDataStore = [self persistentDataStore];
configuration._controlledByAutomation = true;
- configuration.preferences._fullScreenEnabled = YES;
+ configuration.preferences.elementFullscreenEnabled = YES;
configuration.preferences._developerExtrasEnabled = YES;
configuration.preferences._mediaDevicesEnabled = YES;
configuration.preferences._mockCaptureDevicesEnabled = YES;
@@ -240,6 +241,8 @@ - (WKWebViewConfiguration *)defaultConfiguration
configuration.preferences._hiddenPageDOMTimerThrottlingAutoIncreases = NO;
configuration.preferences._pageVisibilityBasedProcessSuppressionEnabled = NO;
configuration.preferences._domTimersThrottlingEnabled = NO;
+ // Do not auto play audio and video with sound.
+ configuration.defaultWebpagePreferences._autoplayPolicy = _WKWebsiteAutoplayPolicyAllowWithoutSound;
_WKProcessPoolConfiguration *processConfiguration = [[[_WKProcessPoolConfiguration alloc] init] autorelease];
processConfiguration.forceOverlayScrollbars = YES;
configuration.processPool = [[[WKProcessPool alloc] _initWithConfiguration:processConfiguration] autorelease];
diff --git a/browser_patches/webkit/embedder/Playwright/win/Common.cpp b/browser_patches/webkit/embedder/Playwright/win/Common.cpp
index 66dee5b68ba49..01a10f7be9ced 100644
--- a/browser_patches/webkit/embedder/Playwright/win/Common.cpp
+++ b/browser_patches/webkit/embedder/Playwright/win/Common.cpp
@@ -44,6 +44,8 @@ HINSTANCE hInst;
POINT s_windowPosition = { 100, 100 };
SIZE s_windowSize = { 500, 200 };
+bool s_headless;
+
namespace WebCore {
float deviceScaleFactorForWindow(HWND);
}
diff --git a/browser_patches/webkit/embedder/Playwright/win/Common.h b/browser_patches/webkit/embedder/Playwright/win/Common.h
index 3c534fd3701c3..29edbe39dad34 100644
--- a/browser_patches/webkit/embedder/Playwright/win/Common.h
+++ b/browser_patches/webkit/embedder/Playwright/win/Common.h
@@ -64,6 +64,7 @@ std::wstring replaceString(std::wstring src, const std::wstring& oldValue, const
extern HINSTANCE hInst;
extern POINT s_windowPosition;
extern SIZE s_windowSize;
+extern bool s_headless;
std::wstring createString(WKStringRef wkString);
std::wstring createString(WKURLRef wkURL);
diff --git a/browser_patches/webkit/embedder/Playwright/win/MainWindow.cpp b/browser_patches/webkit/embedder/Playwright/win/MainWindow.cpp
index e74590c491860..ca65ccb0221fc 100644
--- a/browser_patches/webkit/embedder/Playwright/win/MainWindow.cpp
+++ b/browser_patches/webkit/embedder/Playwright/win/MainWindow.cpp
@@ -48,12 +48,10 @@ static INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
std::wstring MainWindow::s_windowClass;
size_t MainWindow::s_numInstances;
-bool MainWindow::s_headless = false;
bool MainWindow::s_controlledRemotely = false;
bool MainWindow::s_disableAcceleratedCompositing = false;
-void MainWindow::configure(bool headless, bool controlledRemotely, bool disableAcceleratedCompositing) {
- s_headless = headless;
+void MainWindow::configure(bool controlledRemotely, bool disableAcceleratedCompositing) {
s_controlledRemotely = controlledRemotely;
s_disableAcceleratedCompositing = disableAcceleratedCompositing;
}
@@ -140,7 +138,7 @@ void MainWindow::createToolbar(HINSTANCE hInstance)
SendMessage(m_hToolbarWnd, TB_ADDBUTTONS, _countof(tbButtons), reinterpret_cast(&tbButtons));
ShowWindow(m_hToolbarWnd, true);
- m_hURLBarWnd = CreateWindow(L"EDIT", 0, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL, 0, 0, 0, 0, m_hToolbarWnd, 0, hInstance, 0);
+ m_hURLBarWnd = CreateWindow(L"EDIT", 0, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOHSCROLL, 0, 0, 0, 0, m_hToolbarWnd, 0, hInstance, 0);
DefEditProc = reinterpret_cast(GetWindowLongPtr(m_hURLBarWnd, GWLP_WNDPROC));
SetWindowLongPtr(m_hURLBarWnd, GWLP_WNDPROC, reinterpret_cast(EditProc));
@@ -210,7 +208,9 @@ bool MainWindow::init(HINSTANCE hInstance, WKPageConfigurationRef conf)
resizeSubViews();
if (s_headless) {
+ auto menu = GetMenu(m_hMainWnd);
SetMenu(m_hMainWnd, NULL);
+ DestroyMenu(menu);
} else {
SetFocus(m_hURLBarWnd);
ShowWindow(m_hMainWnd, SW_SHOW);
diff --git a/browser_patches/webkit/embedder/Playwright/win/MainWindow.h b/browser_patches/webkit/embedder/Playwright/win/MainWindow.h
index c34241fb1df15..e0af565f4b98b 100644
--- a/browser_patches/webkit/embedder/Playwright/win/MainWindow.h
+++ b/browser_patches/webkit/embedder/Playwright/win/MainWindow.h
@@ -35,7 +35,7 @@
class MainWindow : public BrowserWindowClient {
public:
- static void configure(bool headless, bool controlledRemotely, bool disableAcceleratedCompositing);
+ static void configure(bool controlledRemotely, bool disableAcceleratedCompositing);
MainWindow();
@@ -55,7 +55,6 @@ class MainWindow : public BrowserWindowClient {
static void registerClass(HINSTANCE hInstance);
static std::wstring s_windowClass;
static size_t s_numInstances;
- static bool s_headless;
static bool s_controlledRemotely;
static bool s_disableAcceleratedCompositing;
diff --git a/browser_patches/webkit/embedder/Playwright/win/Playwright.ico b/browser_patches/webkit/embedder/Playwright/win/Playwright.ico
index 0137fe83a54dd..cea0bdebc38b2 100644
Binary files a/browser_patches/webkit/embedder/Playwright/win/Playwright.ico and b/browser_patches/webkit/embedder/Playwright/win/Playwright.ico differ
diff --git a/browser_patches/webkit/embedder/Playwright/win/WebKitBrowserWindow.cpp b/browser_patches/webkit/embedder/Playwright/win/WebKitBrowserWindow.cpp
index ee4ea065a71b2..c850d820763a5 100644
--- a/browser_patches/webkit/embedder/Playwright/win/WebKitBrowserWindow.cpp
+++ b/browser_patches/webkit/embedder/Playwright/win/WebKitBrowserWindow.cpp
@@ -41,16 +41,18 @@
#include
#include
-std::wstring createPEMString(WKCertificateInfoRef certificateInfo)
+std::wstring createPEMString(WKProtectionSpaceRef protectionSpace)
{
- auto chainSize = WKCertificateInfoGetCertificateChainSize(certificateInfo);
+ auto chain = adoptWK(WKProtectionSpaceCopyCertificateChain(protectionSpace));
std::wstring pems;
- for (auto i = 0; i < chainSize; i++) {
- auto certificate = adoptWK(WKCertificateInfoCopyCertificateAtIndex(certificateInfo, i));
- auto size = WKDataGetSize(certificate.get());
- auto data = WKDataGetBytes(certificate.get());
+ for (size_t i = 0; i < WKArrayGetSize(chain.get()); i++) {
+ auto item = WKArrayGetItemAtIndex(chain.get(), i);
+ assert(WKGetTypeID(item) == WKDataGetTypeID());
+ auto certificate = static_cast(item);
+ auto size = WKDataGetSize(certificate);
+ auto data = WKDataGetBytes(certificate);
for (size_t i = 0; i < size; i++)
pems.push_back(data[i]);
@@ -241,7 +243,7 @@ void WebKitBrowserWindow::didReceiveAuthenticationChallenge(WKPageRef page, WKAu
WKAuthenticationDecisionListenerUseCredential(decisionListener, wkCredential.get());
return;
}
- } else {
+ } else if (!s_headless) {
WKRetainPtr realm(WKProtectionSpaceCopyRealm(protectionSpace));
if (auto credential = askCredential(thisWindow.hwnd(), createString(realm.get()))) {
@@ -259,10 +261,9 @@ void WebKitBrowserWindow::didReceiveAuthenticationChallenge(WKPageRef page, WKAu
bool WebKitBrowserWindow::canTrustServerCertificate(WKProtectionSpaceRef protectionSpace)
{
auto host = createString(adoptWK(WKProtectionSpaceCopyHost(protectionSpace)).get());
- auto certificateInfo = adoptWK(WKProtectionSpaceCopyCertificateInfo(protectionSpace));
- auto verificationError = WKCertificateInfoGetVerificationError(certificateInfo.get());
- auto description = createString(adoptWK(WKCertificateInfoCopyVerificationErrorDescription(certificateInfo.get())).get());
- auto pem = createPEMString(certificateInfo.get());
+ auto verificationError = WKProtectionSpaceGetCertificateVerificationError(protectionSpace);
+ auto description = createString(adoptWK(WKProtectionSpaceCopyCertificateVerificationErrorDescription(protectionSpace)).get());
+ auto pem = createPEMString(protectionSpace);
auto it = m_acceptedServerTrustCerts.find(host);
if (it != m_acceptedServerTrustCerts.end() && it->second == pem)
@@ -273,6 +274,9 @@ bool WebKitBrowserWindow::canTrustServerCertificate(WKProtectionSpaceRef protect
textString.append(L"[DESCRIPTION] " + description + L"\r\n");
textString.append(pem);
+ if (s_headless)
+ return false;
+
if (askServerTrustEvaluation(hwnd(), textString)) {
m_acceptedServerTrustCerts.emplace(host, pem);
return true;
diff --git a/browser_patches/webkit/embedder/Playwright/win/WinMain.cpp b/browser_patches/webkit/embedder/Playwright/win/WinMain.cpp
index d80ba9f7bd28c..2261c2b810d2e 100644
--- a/browser_patches/webkit/embedder/Playwright/win/WinMain.cpp
+++ b/browser_patches/webkit/embedder/Playwright/win/WinMain.cpp
@@ -102,7 +102,8 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
if (SetProcessDpiAwarenessContextPtr())
SetProcessDpiAwarenessContextPtr()(DPI_AWARENESS_CONTEXT_UNAWARE);
- MainWindow::configure(g_options.headless, g_options.inspectorPipe, g_options.disableAcceleratedCompositing);
+ s_headless = g_options.headless;
+ MainWindow::configure(g_options.inspectorPipe, g_options.disableAcceleratedCompositing);
if (!g_options.noStartupWindow) {
auto configuration = adoptWK(WKWebsiteDataStoreConfigurationCreate());
diff --git a/browser_patches/webkit/patches/bootstrap.diff b/browser_patches/webkit/patches/bootstrap.diff
index 5df5d455da9cc..9d644885f063b 100644
--- a/browser_patches/webkit/patches/bootstrap.diff
+++ b/browser_patches/webkit/patches/bootstrap.diff
@@ -1,8 +1,8 @@
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
-index dcd4c26b1cd99333e9498a483ff4139a8d42d14b..f041439eff7f2649b1560faf18661165b1fd7771 100644
+index 458e1d4118805169ee6f9139af942cc5c3f88f8e..238f2a33ba150fae735915244910eaa66f5fd267 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
-@@ -1400,22 +1400,27 @@ set(JavaScriptCore_INSPECTOR_DOMAINS
+@@ -1411,21 +1411,26 @@ set(JavaScriptCore_INSPECTOR_DOMAINS
${JAVASCRIPTCORE_DIR}/inspector/protocol/CSS.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Canvas.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Console.json
@@ -10,7 +10,6 @@ index dcd4c26b1cd99333e9498a483ff4139a8d42d14b..f041439eff7f2649b1560faf18661165
${JAVASCRIPTCORE_DIR}/inspector/protocol/DOM.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/DOMDebugger.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/DOMStorage.json
- ${JAVASCRIPTCORE_DIR}/inspector/protocol/Database.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Debugger.json
+ ${JAVASCRIPTCORE_DIR}/inspector/protocol/Emulation.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/GenericTypes.json
@@ -31,10 +30,10 @@ index dcd4c26b1cd99333e9498a483ff4139a8d42d14b..f041439eff7f2649b1560faf18661165
${JAVASCRIPTCORE_DIR}/inspector/protocol/ServiceWorker.json
${JAVASCRIPTCORE_DIR}/inspector/protocol/Target.json
diff --git a/Source/JavaScriptCore/DerivedSources-input.xcfilelist b/Source/JavaScriptCore/DerivedSources-input.xcfilelist
-index b26ef7b2b8f732160ddee36697a61ca7776fc2c3..9a442a4cda7efd7f2bd4e225d8bcbfedf8c4a0c5 100644
+index 9fd3a4e6a53eb3339ced1e87f0b4cacd16f73167..a77d72ab052625c7b5a4d7c56a71befbad884871 100644
--- a/Source/JavaScriptCore/DerivedSources-input.xcfilelist
+++ b/Source/JavaScriptCore/DerivedSources-input.xcfilelist
-@@ -98,21 +98,26 @@ $(PROJECT_DIR)/inspector/protocol/CPUProfiler.json
+@@ -98,20 +98,25 @@ $(PROJECT_DIR)/inspector/protocol/CPUProfiler.json
$(PROJECT_DIR)/inspector/protocol/CSS.json
$(PROJECT_DIR)/inspector/protocol/Canvas.json
$(PROJECT_DIR)/inspector/protocol/Console.json
@@ -42,7 +41,6 @@ index b26ef7b2b8f732160ddee36697a61ca7776fc2c3..9a442a4cda7efd7f2bd4e225d8bcbfed
$(PROJECT_DIR)/inspector/protocol/DOM.json
$(PROJECT_DIR)/inspector/protocol/DOMDebugger.json
$(PROJECT_DIR)/inspector/protocol/DOMStorage.json
- $(PROJECT_DIR)/inspector/protocol/Database.json
$(PROJECT_DIR)/inspector/protocol/Debugger.json
+$(PROJECT_DIR)/inspector/protocol/Emulation.json
$(PROJECT_DIR)/inspector/protocol/GenericTypes.json
@@ -62,10 +60,10 @@ index b26ef7b2b8f732160ddee36697a61ca7776fc2c3..9a442a4cda7efd7f2bd4e225d8bcbfed
$(PROJECT_DIR)/inspector/protocol/Security.json
$(PROJECT_DIR)/inspector/protocol/ServiceWorker.json
diff --git a/Source/JavaScriptCore/DerivedSources.make b/Source/JavaScriptCore/DerivedSources.make
-index 15d6e32cd525905b116f25a5bdd50bd1ef390cee..74b1415d21dcddc49e842e077e87e06724af8365 100644
+index 3db6c2e250371dedc6a9f88bf1688112d467434a..a3832759ea36fb50bdbea6809b9fd13e6f66e46b 100644
--- a/Source/JavaScriptCore/DerivedSources.make
+++ b/Source/JavaScriptCore/DerivedSources.make
-@@ -298,22 +298,27 @@ INSPECTOR_DOMAINS := \
+@@ -301,21 +301,26 @@ INSPECTOR_DOMAINS := \
$(JavaScriptCore)/inspector/protocol/CSS.json \
$(JavaScriptCore)/inspector/protocol/Canvas.json \
$(JavaScriptCore)/inspector/protocol/Console.json \
@@ -73,7 +71,6 @@ index 15d6e32cd525905b116f25a5bdd50bd1ef390cee..74b1415d21dcddc49e842e077e87e067
$(JavaScriptCore)/inspector/protocol/DOM.json \
$(JavaScriptCore)/inspector/protocol/DOMDebugger.json \
$(JavaScriptCore)/inspector/protocol/DOMStorage.json \
- $(JavaScriptCore)/inspector/protocol/Database.json \
$(JavaScriptCore)/inspector/protocol/Debugger.json \
+ $(JavaScriptCore)/inspector/protocol/Emulation.json \
$(JavaScriptCore)/inspector/protocol/GenericTypes.json \
@@ -94,7 +91,7 @@ index 15d6e32cd525905b116f25a5bdd50bd1ef390cee..74b1415d21dcddc49e842e077e87e067
$(JavaScriptCore)/inspector/protocol/ServiceWorker.json \
$(JavaScriptCore)/inspector/protocol/Target.json \
diff --git a/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp b/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
-index 528cceee66a1b1c91a0d0e59d5f1a1770a050c17..0f3a341056f429ff282abcab22be4843c60f546c 100644
+index 9bc5d1fd8e2a7e576be046b3c6ae1266696cf552..610f810db1dd6865c500c0796386a8284f4178e9 100644
--- a/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
+++ b/Source/JavaScriptCore/inspector/IdentifiersFactory.cpp
@@ -32,14 +32,21 @@
@@ -108,7 +105,7 @@ index 528cceee66a1b1c91a0d0e59d5f1a1770a050c17..0f3a341056f429ff282abcab22be4843
static String addPrefixToIdentifier(unsigned long identifier)
{
- return makeString("0."_s, identifier);
-+ return makeString(s_processID, ".", identifier);
++ return makeString(s_processID, '.', identifier);
}
+void IdentifiersFactory::initializeWithProcessID(uint64_t processID) {
@@ -121,22 +118,22 @@ index 528cceee66a1b1c91a0d0e59d5f1a1770a050c17..0f3a341056f429ff282abcab22be4843
{
return addPrefixToIdentifier(++s_lastUsedIdentifier);
diff --git a/Source/JavaScriptCore/inspector/IdentifiersFactory.h b/Source/JavaScriptCore/inspector/IdentifiersFactory.h
-index eb25aedee4cd9ebe007e06c2515b37ee095b06f4..badf6559595c8377db1089ca3c25008e1be2c8f1 100644
+index 4113ddb45d4a8d08379d4dc56c44cde56162accf..e00cb9cb01a7a241f3f25b1e4cdc2fcaee92b3ac 100644
--- a/Source/JavaScriptCore/inspector/IdentifiersFactory.h
+++ b/Source/JavaScriptCore/inspector/IdentifiersFactory.h
@@ -31,6 +31,7 @@ namespace Inspector {
- class JS_EXPORT_PRIVATE IdentifiersFactory {
+ class IdentifiersFactory {
public:
-+ static void initializeWithProcessID(uint64_t);
- static String createIdentifier();
- static String requestId(unsigned long identifier);
++ JS_EXPORT_PRIVATE static void initializeWithProcessID(uint64_t);
+ JS_EXPORT_PRIVATE static String createIdentifier();
+ JS_EXPORT_PRIVATE static String requestId(unsigned long identifier);
};
diff --git a/Source/JavaScriptCore/inspector/InjectedScriptBase.cpp b/Source/JavaScriptCore/inspector/InjectedScriptBase.cpp
-index 731a91727561c1507d074ad27f592d274dfeb324..9320b24579466bb1baa8b68430fe9cbb6c152770 100644
+index 8b39848154ecab9f7daa2d21c85562a319cd06d7..c8a1f44cb4516993899ffe1404b6c3865d42433a 100644
--- a/Source/JavaScriptCore/inspector/InjectedScriptBase.cpp
+++ b/Source/JavaScriptCore/inspector/InjectedScriptBase.cpp
-@@ -84,7 +84,10 @@ static RefPtr jsToInspectorValue(JSC::JSGlobalObject* globalObject,
+@@ -85,7 +85,10 @@ static RefPtr jsToInspectorValue(JSC::JSGlobalObject* globalObject,
JSC::PropertyNameArray propertyNames(vm, JSC::PropertyNameMode::Strings, JSC::PrivateSymbolMode::Exclude);
object.methodTable()->getOwnPropertyNames(&object, globalObject, propertyNames, JSC::DontEnumPropertiesMode::Exclude);
for (auto& name : propertyNames) {
@@ -149,10 +146,10 @@ index 731a91727561c1507d074ad27f592d274dfeb324..9320b24579466bb1baa8b68430fe9cbb
return nullptr;
inspectorObject->setValue(name.string(), inspectorValue.releaseNonNull());
diff --git a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
-index 820a08fc660633e09675d0e647bd0c50d2fa905a..5ca5ee5a6897b7ef332d906018b457122096df98 100644
+index 1f5d0adbf624bd24ef1e525967e6e82e8c37b4e5..4fe0f364b4ccd11774bf29f772e0a568549a4322 100644
--- a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
+++ b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
-@@ -101,7 +101,7 @@ void BackendDispatcher::registerDispatcherForDomain(const String& domain, Supple
+@@ -102,7 +102,7 @@ void BackendDispatcher::registerDispatcherForDomain(const String& domain, Supple
m_dispatchers.set(domain, dispatcher);
}
@@ -161,7 +158,7 @@ index 820a08fc660633e09675d0e647bd0c50d2fa905a..5ca5ee5a6897b7ef332d906018b45712
{
Ref protect(*this);
-@@ -146,6 +146,9 @@ void BackendDispatcher::dispatch(const String& message)
+@@ -147,6 +147,9 @@ void BackendDispatcher::dispatch(const String& message)
requestId = *requestIdInt;
}
@@ -172,18 +169,19 @@ index 820a08fc660633e09675d0e647bd0c50d2fa905a..5ca5ee5a6897b7ef332d906018b45712
// We could be called re-entrantly from a nested run loop, so restore the previous id.
SetForScope scopedRequestId(m_currentRequestId, requestId);
diff --git a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
-index 31957be19b946aa90d316dc978a301f80956dd9c..d1a01e7546996535eb3884524c251c50a998eb33 100644
+index 28f4cdacf6ebd7037a42a75872618436332d90ec..463f014be2bd29a75bee7b2113b6f929da13aca5 100644
--- a/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
+++ b/Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
-@@ -83,7 +83,10 @@ public:
+@@ -95,8 +95,11 @@ public:
+ ServerError
};
- void registerDispatcherForDomain(const String& domain, SupplementalBackendDispatcher*);
-- void dispatch(const String& message);
-+
+ enum class InterceptionResult { Intercepted, Continue };
+ using Interceptor = WTF::Function&)>;
-+ void dispatch(const String& message, Interceptor&& interceptor = Interceptor());
++
+ JS_EXPORT_PRIVATE void registerDispatcherForDomain(const String& domain, SupplementalBackendDispatcher*);
+- JS_EXPORT_PRIVATE void dispatch(const String& message);
++ JS_EXPORT_PRIVATE void dispatch(const String& message, Interceptor&& interceptor = Interceptor());
// Note that 'unused' is a workaround so the compiler can pick the right sendResponse based on arity.
// When is fixed or this class is renamed for the JSON::Object case,
@@ -222,10 +220,10 @@ index 0cc2127c9c12c2d82dea9550bad73f4ffb99ba24..8ca65cc042d435cbc0e05dcc5c5dfc95
}
diff --git a/Source/JavaScriptCore/inspector/InspectorTarget.h b/Source/JavaScriptCore/inspector/InspectorTarget.h
-index 88b72e94c4e8636de88419733b0a63ad4e0b9a73..153ee84f2c7ef86c548c62a65d6ad99214090230 100644
+index b555c2e5a071d0a6a016061cc60755449557556d..d019346f0932296d15212c76a4a9b56beb565ff4 100644
--- a/Source/JavaScriptCore/inspector/InspectorTarget.h
+++ b/Source/JavaScriptCore/inspector/InspectorTarget.h
-@@ -57,8 +57,12 @@ public:
+@@ -66,8 +66,12 @@ public:
virtual void connect(FrontendChannel::ConnectionType) = 0;
virtual void disconnect() = 0;
virtual void sendMessageToTargetBackend(const String&) = 0;
@@ -239,16 +237,16 @@ index 88b72e94c4e8636de88419733b0a63ad4e0b9a73..153ee84f2c7ef86c548c62a65d6ad992
bool m_isPaused { false };
};
diff --git a/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp b/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp
-index 15d2592d36b402bf2210dc4970ff40957022e84a..99ac14dc75ff5296e1f6c42bdbf8c128f2d82254 100644
+index 13eb84b3cba851e14eae8894f8f7aeb242b6f9d4..30bfdf65a7b891420a25bbc54bfe7f03db694273 100644
--- a/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp
+++ b/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp
-@@ -221,6 +221,14 @@ void JSGlobalObjectConsoleClient::screenshot(JSGlobalObject*, RefdeveloperExtrasEnabled()))
++ if (!m_consoleAgent->developerExtrasEnabled())
+ return;
+
+ warnUnimplemented("console.bindingCalled"_s);
@@ -256,7 +254,7 @@ index 15d2592d36b402bf2210dc4970ff40957022e84a..99ac14dc75ff5296e1f6c42bdbf8c128
+
void JSGlobalObjectConsoleClient::warnUnimplemented(const String& method)
{
- String message = method + " is currently ignored in JavaScript context inspection."_s;
+ auto message = makeString(method, " is currently ignored in JavaScript context inspection."_s);
diff --git a/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.h b/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.h
index 6bbd0729a65b4a901e7da4dc50cc47c669bd9897..452b25d0e8eba3df1d5f6623dc222048bef120cd 100644
--- a/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.h
@@ -270,7 +268,7 @@ index 6bbd0729a65b4a901e7da4dc50cc47c669bd9897..452b25d0e8eba3df1d5f6623dc222048
void warnUnimplemented(const String& method);
void internalAddMessage(MessageType, MessageLevel, JSC::JSGlobalObject*, Ref&&);
diff --git a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
-index 594584db96a3de67b92910f472f1403bc9b26ce2..8ba453f9ae8726ccfb26c55180371c20bed6962e 100644
+index 0cb6efeef2430faa5dbd812f71d4abfd5f6eb9df..787ec6a5f8413c0a9dc133cb0e51ccdab58d40d0 100644
--- a/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
+++ b/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
@@ -194,9 +194,8 @@ void InspectorRuntimeAgent::callFunctionOn(const Protocol::Runtime::RemoteObject
@@ -367,10 +365,10 @@ index e47c6ca59f37fbf18ca8a393df72e0472363fabd..b393465540595220561ae00afb854082
void InspectorTargetAgent::didCommitProvisionalTarget(const String& oldTargetID, const String& committedTargetID)
diff --git a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
-index 4edcbf5f4aee2eb8e5675a23b9db67e9d640ef7f..a32b0f3a5de49e58b8a35cec9202b7880e91a2f0 100644
+index 04377b714a6ccb5294c65d592e74350621d470ba..b6de937bfa3e6185ce29f4e432d327a3cedee6df 100644
--- a/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
+++ b/Source/JavaScriptCore/inspector/agents/InspectorTargetAgent.h
-@@ -51,15 +51,20 @@ public:
+@@ -53,8 +53,11 @@ public:
Protocol::ErrorStringOr setPauseOnStart(bool) final;
Protocol::ErrorStringOr resume(const String& targetId) final;
Protocol::ErrorStringOr sendMessageToTarget(const String& targetId, const String& message) final;
@@ -378,21 +376,22 @@ index 4edcbf5f4aee2eb8e5675a23b9db67e9d640ef7f..a32b0f3a5de49e58b8a35cec9202b788
+ Protocol::ErrorStringOr close(const String& targetId, std::optional&& runBeforeUnload) override;
// Target lifecycle.
++ void targetCrashed(InspectorTarget&);
void targetCreated(InspectorTarget&);
void targetDestroyed(InspectorTarget&);
-+ void targetCrashed(InspectorTarget&);
void didCommitProvisionalTarget(const String& oldTargetID, const String& committedTargetID);
-
+@@ -62,6 +65,9 @@ public:
// Target messages.
void sendMessageFromTargetToFrontend(const String& targetId, const String& message);
++ bool shouldPauseOnStart() const { return m_shouldPauseOnStart; }
+ bool isConnected() { return m_isConnected; }
+
private:
// FrontendChannel
FrontendChannel::ConnectionType connectionType() const;
diff --git a/Source/JavaScriptCore/inspector/protocol/DOM.json b/Source/JavaScriptCore/inspector/protocol/DOM.json
-index fc7612613d09e03f481c567a8a4a121884e2cb6c..b0a7b284684bccaa7dfb0892a64d4a803357ccc1 100644
+index 25711ac1aa269d7e0231a6169be1bc495f2c8dc0..bcb4d83e58a51458de6e070ef7cb859ee333bdbc 100644
--- a/Source/JavaScriptCore/inspector/protocol/DOM.json
+++ b/Source/JavaScriptCore/inspector/protocol/DOM.json
@@ -80,6 +80,16 @@
@@ -412,24 +411,7 @@ index fc7612613d09e03f481c567a8a4a121884e2cb6c..b0a7b284684bccaa7dfb0892a64d4a80
{
"id": "EventListener",
"type": "object",
-@@ -267,6 +277,16 @@
- { "name": "width", "type": "number" },
- { "name": "height", "type": "number" }
- ]
-+ },
-+ {
-+ "id": "FilePayload",
-+ "type": "object",
-+ "description": "Data to construct File object.",
-+ "properties": [
-+ { "name": "name", "type": "string", "description": "File name." },
-+ { "name": "type", "type": "string", "description": "File type." },
-+ { "name": "data", "type": "string", "description": "Base64-encoded file data." }
-+ ]
- }
- ],
- "commands": [
-@@ -696,7 +716,10 @@
+@@ -745,7 +755,10 @@
"description": "Resolves JavaScript node object for given node id.",
"targetTypes": ["page"],
"parameters": [
@@ -441,7 +423,7 @@ index fc7612613d09e03f481c567a8a4a121884e2cb6c..b0a7b284684bccaa7dfb0892a64d4a80
{ "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name that can be used to release multiple objects." }
],
"returns": [
-@@ -773,6 +796,46 @@
+@@ -822,6 +835,46 @@
"returns": [
{ "name": "mediaStats", "$ref": "MediaStats", "description": "An interleaved array of node attribute names and values." }
]
@@ -482,9 +464,9 @@ index fc7612613d09e03f481c567a8a4a121884e2cb6c..b0a7b284684bccaa7dfb0892a64d4a80
+ "description": "Sets input files for given ",
+ "parameters": [
+ { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "Input element handle." },
-+ { "name": "files", "type": "array", "items": { "$ref": "FilePayload" }, "optional": true, "description": "Files to set" },
-+ { "name": "paths", "type": "array", "items": { "type": "string" }, "optional": true, "description": "File paths to set" }
-+ ]
++ { "name": "paths", "type": "array", "items": { "type": "string" }, "description": "File paths to set" }
++ ],
++ "async": true
}
],
"events": [
@@ -532,10 +514,10 @@ index 0000000000000000000000000000000000000000..79edea03fed4e9be5da96e1275e182a4
+}
diff --git a/Source/JavaScriptCore/inspector/protocol/Emulation.json b/Source/JavaScriptCore/inspector/protocol/Emulation.json
new file mode 100644
-index 0000000000000000000000000000000000000000..2a49dd417360da37c83c4d375de468f949dce5db
+index 0000000000000000000000000000000000000000..8377901cb3ad75c29532a1f0f547efb53558a327
--- /dev/null
+++ b/Source/JavaScriptCore/inspector/protocol/Emulation.json
-@@ -0,0 +1,52 @@
+@@ -0,0 +1,59 @@
+{
+ "domain": "Emulation",
+ "availability": ["web"],
@@ -585,15 +567,22 @@ index 0000000000000000000000000000000000000000..2a49dd417360da37c83c4d375de468f9
+ {
+ "name": "resetPermissions",
+ "description": "Clears permission overrides."
++ },
++ {
++ "name": "setOrientationOverride",
++ "description": "Overrides window.orientation with provided value.",
++ "parameters": [
++ { "name": "angle", "type": "integer", "optional": true }
++ ]
+ }
+ ]
+}
diff --git a/Source/JavaScriptCore/inspector/protocol/Input.json b/Source/JavaScriptCore/inspector/protocol/Input.json
new file mode 100644
-index 0000000000000000000000000000000000000000..b9ab57a2b5739ed997231399b4bd4042a0cb0935
+index 0000000000000000000000000000000000000000..1c43b476603325fa412bcfded9163e7a00aebbfa
--- /dev/null
+++ b/Source/JavaScriptCore/inspector/protocol/Input.json
-@@ -0,0 +1,223 @@
+@@ -0,0 +1,264 @@
+{
+ "domain": "Input",
+ "availability": ["web"],
@@ -602,6 +591,16 @@ index 0000000000000000000000000000000000000000..b9ab57a2b5739ed997231399b4bd4042
+ "id": "TimeSinceEpoch",
+ "description": "UTC time in seconds, counted from January 1, 1970.",
+ "type": "number"
++ },
++ {
++ "id": "TouchPoint",
++ "type": "object",
++ "description": "Touch point.",
++ "properties": [
++ { "name": "x", "type": "integer", "description": "X coordinate of the event relative to the main frame's viewport in CSS pixels." },
++ { "name": "y", "type": "integer", "description": "Y coordinate of the event relative to the main frame's viewport in CSS pixels." },
++ { "name": "id", "type": "integer", "description": "Identifier used to track touch sources between events, must be unique within an event." }
++ ]
+ }
+ ],
+ "commands": [
@@ -814,6 +813,37 @@ index 0000000000000000000000000000000000000000..b9ab57a2b5739ed997231399b4bd4042
+ "type": "integer"
+ }
+ ]
++ },
++ {
++ "name": "dispatchTouchEvent",
++ "description": "Dispatches a touch event to the page.",
++ "async": true,
++ "parameters": [
++ {
++ "name": "type",
++ "description": "Type of the touch event.",
++ "type": "string",
++ "enum": [
++ "touchStart",
++ "touchMove",
++ "touchEnd",
++ "touchCancel"
++ ]
++ },
++ {
++ "name": "modifiers",
++ "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8\n(default: 0).",
++ "optional": true,
++ "type": "integer"
++ },
++ {
++ "name": "touchPoints",
++ "description": "List of touch points",
++ "type": "array",
++ "optional": true,
++ "items": { "$ref": "TouchPoint" }
++ }
++ ]
+ }
+ ]
+}
@@ -836,10 +866,10 @@ index 96af27ece2ac200e11c4311b3ca0d9d3b5a048da..3168f7806fcbdabec07acc5e304bae1e
],
"events": [
diff --git a/Source/JavaScriptCore/inspector/protocol/Page.json b/Source/JavaScriptCore/inspector/protocol/Page.json
-index b5e2bb2eb58765ec20392b36bf5ef1ac35857a69..7e6c8b8954ed3d5d4ac77dfe51d0e08c56a7a5fc 100644
+index 3d032713a7f3bb9645bfc7d42455a0494b5376c0..913dda5e90b86cc5f8e4ca6881f6db57520a7f66 100644
--- a/Source/JavaScriptCore/inspector/protocol/Page.json
+++ b/Source/JavaScriptCore/inspector/protocol/Page.json
-@@ -20,7 +20,14 @@
+@@ -20,7 +20,15 @@
"ScriptEnabled",
"ShowDebugBorders",
"ShowRepaintCounter",
@@ -851,11 +881,12 @@ index b5e2bb2eb58765ec20392b36bf5ef1ac35857a69..7e6c8b8954ed3d5d4ac77dfe51d0e08c
+ "NotificationsEnabled",
+ "FullScreenEnabled",
+ "InputTypeMonthEnabled",
-+ "InputTypeWeekEnabled"
++ "InputTypeWeekEnabled",
++ "FixedBackgroundsPaintRelativeToDocument"
]
},
{
-@@ -62,6 +69,12 @@
+@@ -62,6 +70,12 @@
"enum": ["None", "Lax", "Strict"],
"description": "Same-Site policy of a cookie."
},
@@ -868,9 +899,9 @@ index b5e2bb2eb58765ec20392b36bf5ef1ac35857a69..7e6c8b8954ed3d5d4ac77dfe51d0e08c
{
"id": "Frame",
"type": "object",
-@@ -125,6 +138,50 @@
- { "name": "secure", "type": "boolean", "description": "True if cookie is secure." },
- { "name": "sameSite", "$ref": "CookieSameSitePolicy", "description": "Cookie Same-Site policy." }
+@@ -126,6 +140,50 @@
+ { "name": "sameSite", "$ref": "CookieSameSitePolicy", "description": "Cookie Same-Site policy." },
+ { "name": "partitionKey", "type": "string", "optional": true, "description": "Cookie partition key. If null and partitioned property is true, then key must be computed." }
]
+ },
+ {
@@ -919,7 +950,7 @@ index b5e2bb2eb58765ec20392b36bf5ef1ac35857a69..7e6c8b8954ed3d5d4ac77dfe51d0e08c
}
],
"commands": [
-@@ -144,6 +201,14 @@
+@@ -145,6 +203,14 @@
{ "name": "revalidateAllResources", "type": "boolean", "optional": true, "description": "If true, all cached subresources will be revalidated when the main resource loads. Otherwise, only expired cached subresources will be revalidated (the default behavior for most WebKit clients)." }
]
},
@@ -934,7 +965,7 @@ index b5e2bb2eb58765ec20392b36bf5ef1ac35857a69..7e6c8b8954ed3d5d4ac77dfe51d0e08c
{
"name": "navigate",
"description": "Navigates current page to the given URL.",
-@@ -160,6 +225,14 @@
+@@ -161,6 +227,14 @@
{ "name": "value", "type": "string", "optional": true, "description": "Value to override the user agent with. If this value is not provided, the override is removed. Overrides are removed when Web Inspector closes/disconnects." }
]
},
@@ -949,7 +980,7 @@ index b5e2bb2eb58765ec20392b36bf5ef1ac35857a69..7e6c8b8954ed3d5d4ac77dfe51d0e08c
{
"name": "overrideSetting",
"description": "Allows the frontend to override the inspected page's settings.",
-@@ -283,6 +356,28 @@
+@@ -285,6 +359,28 @@
{ "name": "media", "type": "string", "description": "Media type to emulate. Empty string disables the override." }
]
},
@@ -978,7 +1009,7 @@ index b5e2bb2eb58765ec20392b36bf5ef1ac35857a69..7e6c8b8954ed3d5d4ac77dfe51d0e08c
{
"name": "snapshotNode",
"description": "Capture a snapshot of the specified node that does not include unrelated layers.",
-@@ -303,7 +398,8 @@
+@@ -305,7 +401,8 @@
{ "name": "y", "type": "integer", "description": "Y coordinate" },
{ "name": "width", "type": "integer", "description": "Rectangle width" },
{ "name": "height", "type": "integer", "description": "Rectangle height" },
@@ -988,7 +1019,7 @@ index b5e2bb2eb58765ec20392b36bf5ef1ac35857a69..7e6c8b8954ed3d5d4ac77dfe51d0e08c
],
"returns": [
{ "name": "dataURL", "type": "string", "description": "Base64-encoded image data (PNG)." }
-@@ -321,12 +417,71 @@
+@@ -323,12 +420,64 @@
{
"name": "setScreenSizeOverride",
"description": "Overrides screen size exposed to DOM and used in media queries for testing with provided values.",
@@ -1049,19 +1080,12 @@ index b5e2bb2eb58765ec20392b36bf5ef1ac35857a69..7e6c8b8954ed3d5d4ac77dfe51d0e08c
+ "description": "Crashes the page process"
+ },
+ {
-+ "name": "setOrientationOverride",
-+ "description": "Overrides window.orientation with provided value.",
-+ "parameters": [
-+ { "name": "angle", "type": "integer", "optional": true }
-+ ]
-+ },
-+ {
+ "name": "updateScrollingState",
+ "description": "Ensures that the scroll regions are up to date."
}
],
"events": [
-@@ -334,14 +489,16 @@
+@@ -336,14 +485,16 @@
"name": "domContentEventFired",
"targetTypes": ["page"],
"parameters": [
@@ -1080,7 +1104,7 @@ index b5e2bb2eb58765ec20392b36bf5ef1ac35857a69..7e6c8b8954ed3d5d4ac77dfe51d0e08c
]
},
{
-@@ -351,6 +508,14 @@
+@@ -353,6 +504,14 @@
{ "name": "frame", "$ref": "Frame", "description": "Frame object." }
]
},
@@ -1095,7 +1119,7 @@ index b5e2bb2eb58765ec20392b36bf5ef1ac35857a69..7e6c8b8954ed3d5d4ac77dfe51d0e08c
{
"name": "frameDetached",
"description": "Fired when frame has been detached from its parent.",
-@@ -379,7 +544,8 @@
+@@ -381,7 +540,8 @@
"targetTypes": ["page"],
"parameters": [
{ "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has scheduled a navigation." },
@@ -1105,7 +1129,7 @@ index b5e2bb2eb58765ec20392b36bf5ef1ac35857a69..7e6c8b8954ed3d5d4ac77dfe51d0e08c
]
},
{
-@@ -390,6 +556,22 @@
+@@ -392,6 +552,22 @@
{ "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has cleared its scheduled navigation." }
]
},
@@ -1128,7 +1152,7 @@ index b5e2bb2eb58765ec20392b36bf5ef1ac35857a69..7e6c8b8954ed3d5d4ac77dfe51d0e08c
{
"name": "defaultUserPreferencesDidChange",
"description": "Fired when the default value of a user preference changes at the system level.",
-@@ -397,6 +579,42 @@
+@@ -399,6 +575,42 @@
"parameters": [
{ "name": "preferences", "type": "array", "items": { "$ref": "UserPreference" }, "description": "List of user preferences that can be overriden and their new system (default) values." }
]
@@ -1173,10 +1197,10 @@ index b5e2bb2eb58765ec20392b36bf5ef1ac35857a69..7e6c8b8954ed3d5d4ac77dfe51d0e08c
}
diff --git a/Source/JavaScriptCore/inspector/protocol/Playwright.json b/Source/JavaScriptCore/inspector/protocol/Playwright.json
new file mode 100644
-index 0000000000000000000000000000000000000000..978d6f92b18498633c982969299f068332eb2884
+index 0000000000000000000000000000000000000000..440dd95173e066a886de120fb3dab7597d85feb6
--- /dev/null
+++ b/Source/JavaScriptCore/inspector/protocol/Playwright.json
-@@ -0,0 +1,307 @@
+@@ -0,0 +1,315 @@
+{
+ "domain": "Playwright",
+ "availability": ["web"],
@@ -1352,6 +1376,14 @@ index 0000000000000000000000000000000000000000..978d6f92b18498633c982969299f0683
+ ]
+ },
+ {
++ "name": "setPageZoomFactor",
++ "description": "Changes page zoom factor.",
++ "parameters": [
++ { "name": "pageProxyId", "$ref": "PageProxyID", "description": "Unique identifier of the page proxy." },
++ { "name": "zoomFactor", "type": "number" }
++ ]
++ },
++ {
+ "name": "getAllCookies",
+ "description": "Returns all cookies in the given browser context.",
+ "async": true,
@@ -1634,23 +1666,11 @@ index 52920cded24a9c6b0ef6fb4e518664955db4f9fa..bbbabc4e7259088b9404e8cc07eecd6f
]
},
{
-diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp
-index dd1286cec6e77895f519911c89719b6064db6949..b732e0eab0fd29e1a1c9a2179cc86a951768c062 100644
---- a/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp
-+++ b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp
-@@ -28,7 +28,6 @@
-
- #include "CodeBlock.h"
- #include "JSCInlines.h"
--#include "ProfilerDumper.h"
- #include
-
- namespace JSC { namespace Profiler {
diff --git a/Source/JavaScriptCore/runtime/ConsoleClient.h b/Source/JavaScriptCore/runtime/ConsoleClient.h
-index 72c81757450ad5ebacd5fd20d2a16095514802ec..b7d8ab1e04d3850180079870468b28eff504626a 100644
+index 24891ad836086fd23024fcb4d08ca63f6974c812..29f4b6b1923383fec7a99d28a4e815dc4536d160 100644
--- a/Source/JavaScriptCore/runtime/ConsoleClient.h
+++ b/Source/JavaScriptCore/runtime/ConsoleClient.h
-@@ -69,6 +69,7 @@ public:
+@@ -78,6 +78,7 @@ public:
virtual void record(JSGlobalObject*, Ref&&) = 0;
virtual void recordEnd(JSGlobalObject*, Ref&&) = 0;
virtual void screenshot(JSGlobalObject*, Ref&&) = 0;
@@ -1659,18 +1679,10 @@ index 72c81757450ad5ebacd5fd20d2a16095514802ec..b7d8ab1e04d3850180079870468b28ef
private:
enum ArgumentRequirement { ArgumentRequired, ArgumentNotRequired };
diff --git a/Source/ThirdParty/libwebrtc/CMakeLists.txt b/Source/ThirdParty/libwebrtc/CMakeLists.txt
-index d6b1e73b1268a1224c2d77b936ce46347be62dac..acd1950327608988059a7e972fb4d40f9efc0c68 100644
+index ca4f3508a44e3c6677a72fbe3d7c853714b4f2c6..ae117f5f402a7eb259e376ca9440e00062e22d9f 100644
--- a/Source/ThirdParty/libwebrtc/CMakeLists.txt
+++ b/Source/ThirdParty/libwebrtc/CMakeLists.txt
-@@ -452,6 +452,7 @@ set(webrtc_SOURCES
- Source/third_party/boringssl/src/crypto/x509/x_val.c
- Source/third_party/boringssl/src/crypto/x509/x_x509a.c
- Source/third_party/boringssl/src/crypto/x509/x_x509.c
-+
- Source/third_party/boringssl/src/decrepit/bio/base64_bio.c
- Source/third_party/boringssl/src/decrepit/blowfish/blowfish.c
- Source/third_party/boringssl/src/decrepit/cast/cast.c
-@@ -530,6 +531,11 @@ set(webrtc_SOURCES
+@@ -532,6 +532,11 @@ set(webrtc_SOURCES
Source/third_party/crc32c/src/src/crc32c.cc
Source/third_party/crc32c/src/src/crc32c_portable.cc
Source/third_party/crc32c/src/src/crc32c_sse42.cc
@@ -1682,47 +1694,40 @@ index d6b1e73b1268a1224c2d77b936ce46347be62dac..acd1950327608988059a7e972fb4d40f
Source/third_party/libyuv/source/compare.cc
Source/third_party/libyuv/source/compare_common.cc
Source/third_party/libyuv/source/compare_gcc.cc
-@@ -2270,6 +2276,10 @@ set(webrtc_INCLUDE_DIRECTORIES PRIVATE
+@@ -2348,6 +2353,11 @@ set(webrtc_INCLUDE_DIRECTORIES PRIVATE
Source/third_party/libsrtp/config
Source/third_party/libsrtp/crypto/include
Source/third_party/libsrtp/include
+# Playwright begin
+ Source/third_party/libwebm
+ Source/third_party/libvpx/source/libvpx
++ Source/third_party/libvpx/source/libvpx/third_party/googletest/src/include
+# Playwright end
Source/third_party/libyuv/include
Source/third_party/opus/src/celt
Source/third_party/opus/src/include
diff --git a/Source/ThirdParty/libwebrtc/Configurations/Base-libwebrtc.xcconfig b/Source/ThirdParty/libwebrtc/Configurations/Base-libwebrtc.xcconfig
-index 94f6675a8b7ca64e12aaf1c3b01848f0a6b737a8..20660f511914ebb7877e050bb5bc232c3df2daa5 100644
+index 0c5c8e689bdddec766f9de5bffd4444a5e068d77..330dd1f585e530722178c65c883641a2b8c0f1bd 100644
--- a/Source/ThirdParty/libwebrtc/Configurations/Base-libwebrtc.xcconfig
+++ b/Source/ThirdParty/libwebrtc/Configurations/Base-libwebrtc.xcconfig
-@@ -21,7 +21,7 @@
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--HEADER_SEARCH_PATHS = Source Source/third_party/libsrtp/crypto/include Source/third_party/libsrtp/include Source/third_party/boringssl/src/include Source/third_party/libyuv/include Source/webrtc/sdk/objc/Framework/Headers Source/webrtc/common_audio/signal_processing/include Source/webrtc/modules/audio_coding/codecs/isac/main/include Source/third_party/opus/src/celt Source/third_party/opus/src/include Source/third_party/opus/src/src Source/webrtc/modules/audio_device/mac Source/webrtc/modules/audio_device/ios Source/webrtc Source/webrtc/sdk/objc Source/webrtc/sdk/objc/base Source/webrtc/sdk/objc/Framework/Classes Source/third_party/libsrtp/config Source/webrtc/sdk/objc/Framework/Classes/Common Source/webrtc/sdk/objc/Framework/Classes/Video Source/webrtc/sdk/objc/Framework/Classes/PeerConnection Source/third_party/abseil-cpp Source/third_party/libvpx/source/libvpx Source/third_party/libwebm/webm_parser/include Source/third_party/crc32c/config Source/third_party/crc32c/include Source/third_party/crc32c/src/include Source/third_party/libaom/source/libaom;
-+HEADER_SEARCH_PATHS = Source Source/third_party/libsrtp/crypto/include Source/third_party/libsrtp/include Source/third_party/boringssl/src/include Source/third_party/libyuv/include Source/webrtc/sdk/objc/Framework/Headers Source/webrtc/common_audio/signal_processing/include Source/webrtc/modules/audio_coding/codecs/isac/main/include Source/third_party/opus/src/celt Source/third_party/opus/src/include Source/third_party/opus/src/src Source/webrtc/modules/audio_device/mac Source/webrtc/modules/audio_device/ios Source/webrtc Source/webrtc/sdk/objc Source/webrtc/sdk/objc/base Source/webrtc/sdk/objc/Framework/Classes Source/third_party/libsrtp/config Source/webrtc/sdk/objc/Framework/Classes/Common Source/webrtc/sdk/objc/Framework/Classes/Video Source/webrtc/sdk/objc/Framework/Classes/PeerConnection Source/third_party/abseil-cpp Source/third_party/libvpx/source/libvpx Source/third_party/libwebm/webm_parser/include Source/third_party/crc32c/config Source/third_party/crc32c/include Source/third_party/crc32c/src/include Source/third_party/libaom/source/libaom Source/third_party/libwebm/mkvmuxer Source/third_party/libvpx/source/libvpx/third_party/libwebm;
+@@ -24,6 +24,8 @@
+ HEADER_SEARCH_PATHS = Source Source/third_party/libsrtp/crypto/include Source/third_party/libsrtp/include Source/third_party/boringssl/src/include Source/third_party/libyuv/include Source/webrtc/webkit_sdk/objc/Framework/Headers Source/webrtc/common_audio/signal_processing/include Source/webrtc/modules/audio_coding/codecs/isac/main/include Source/third_party/opus/src/celt Source/third_party/opus/src/include Source/third_party/opus/src/src Source/webrtc/modules/audio_device/mac Source/webrtc/modules/audio_device/ios Source/webrtc Source/webrtc/webkit_sdk/objc Source/webrtc/webkit_sdk/objc/base Source/webrtc/webkit_sdk/objc/Framework/Classes Source/third_party/libsrtp/config Source/webrtc/webkit_sdk/objc/Framework/Classes/Common Source/webrtc/webkit_sdk/objc/Framework/Classes/Video Source/webrtc/webkit_sdk/objc/Framework/Classes/PeerConnection Source/third_party/abseil-cpp Source/third_party/libvpx/source/libvpx Source/third_party/libwebm/webm_parser/include Source/third_party/crc32c/config Source/third_party/crc32c/include Source/third_party/crc32c/src/include Source/third_party/libaom/source/libaom;
USE_HEADERMAP = NO;
++HEADER_SEARCH_PATHS = ${HEADER_SEARCH_PATHS} Source/third_party/libwebm/mkvmuxer Source/third_party/libvpx/source/libvpx/third_party/libwebm;
++
WARNING_CFLAGS = -Wno-deprecated-declarations $(inherited);
+
+ // FIXME: Set WEBRTC_USE_BUILTIN_ISAC_FIX and WEBRTC_USE_BUILTIN_ISAC_FLOAT for iOS and Mac
diff --git a/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.exp b/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.exp
-index a01284369bedab3d44e7a3c2671590b3ca2b18fc..6a75fd2d366386e12dc612bdcfb914613c636478 100644
+index 13c5b5ea562fe808a3251c3ae789f8106632cd25..36b77e7d6bc78ba2e982cad5a2b4792775d3280d 100644
--- a/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.exp
+++ b/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.exp
-@@ -402,3 +402,24 @@ __ZN3rtc7LogSink12OnLogMessageENSt3__117basic_string_viewIcNS1_11char_traitsIcEE
- __ZN3rtc7LogSink12OnLogMessageERKNS_10LogLineRefE
- __ZN3rtc7LogSink12OnLogMessageERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS_15LoggingSeverityEPKc
- __ZTVN3rtc7LogSinkE
-+__ZN8mkvmuxer11SegmentInfo15set_writing_appEPKc
+@@ -434,3 +434,16 @@ __ZN6webrtc18VideoFrameMetadata7SetSsrcEj
+ __ZN6webrtc18VideoFrameMetadata8SetCsrcsENSt3__16vectorIjNS1_9allocatorIjEEEE
+ __ZN6webrtc18VideoFrameMetadata8SetWidthEt
+ __ZN6webrtc18VideoFrameMetadata9SetHeightEt
+__ZN8mkvmuxer11SegmentInfo4InitEv
-+__ZN8mkvmuxer7Segment10OutputCuesEb
-+__ZN8mkvmuxer7Segment13AddVideoTrackEiii
-+__ZN8mkvmuxer7Segment4InitEPNS_10IMkvWriterE
-+__ZN8mkvmuxer7Segment8AddFrameEPKhyyyb
-+__ZN8mkvmuxer7Segment8FinalizeEv
-+__ZN8mkvmuxer7SegmentC1Ev
-+__ZN8mkvmuxer7SegmentD1Ev
+__ZN8mkvmuxer9MkvWriterC1EP7__sFILE
+_ARGBToI420
+_vpx_codec_destroy
@@ -1735,35 +1740,11 @@ index a01284369bedab3d44e7a3c2671590b3ca2b18fc..6a75fd2d366386e12dc612bdcfb91461
+_vpx_codec_iface_name
+_vpx_codec_version_str
+_vpx_codec_vp8_cx
-diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
-index 625cb7fefc6a699d9e2f28c6acc1bc7681ea3984..cd6677a7ffd3321978427a9fc6fbed5179aebb60 100644
---- a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
-+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
-@@ -16,6 +16,7 @@
- #include "absl/algorithm/container.h"
- #include "absl/memory/memory.h"
- #include "absl/types/optional.h"
-+#include "api/call/transport.h"
- #include "api/video/video_bitrate_allocation.h"
- #include "modules/rtp_rtcp/include/receive_statistics.h"
- #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
-diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_format_h264.h b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_format_h264.h
-index f95c3b6c6b73a01974f26d88bcc533e5032ddb66..6a9368c60824cd32649c93286522d779cac59bd2 100644
---- a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_format_h264.h
-+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_format_h264.h
-@@ -16,6 +16,7 @@
-
- #include
- #include
-+#include
- #include
-
- #include "api/array_view.h"
diff --git a/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj b/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
-index f5f1d0ef71f7fcf175b016ddaefd99f18d96c1c3..5632dcb4919eb22133a62810b91e143329e31ee0 100644
+index 7585b2e5e9bffdc8cabd888dd822313d53b30141..5909d33b9726cdc7d2d53b538f7da18bc221e30b 100644
--- a/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
+++ b/Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
-@@ -35,6 +35,20 @@
+@@ -56,6 +56,20 @@
};
/* End PBXAggregateTarget section */
@@ -1784,17 +1765,7 @@ index f5f1d0ef71f7fcf175b016ddaefd99f18d96c1c3..5632dcb4919eb22133a62810b91e1433
/* Begin PBXBuildFile section */
2D6BFF60280A93DF00A1A74F /* video_coding.h in Headers */ = {isa = PBXBuildFile; fileRef = 4131C45B234C81710028A615 /* video_coding.h */; settings = {ATTRIBUTES = (Public, ); }; };
2D6BFF61280A93EC00A1A74F /* video_codec_initializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4131C45E234C81720028A615 /* video_codec_initializer.h */; settings = {ATTRIBUTES = (Public, ); }; };
-@@ -5118,6 +5132,9 @@
- DDF30D9127C5C725006A526F /* receive_side_congestion_controller.h in Headers */ = {isa = PBXBuildFile; fileRef = DDF30D9027C5C725006A526F /* receive_side_congestion_controller.h */; };
- DDF30D9527C5C756006A526F /* bwe_defines.h in Headers */ = {isa = PBXBuildFile; fileRef = DDF30D9327C5C756006A526F /* bwe_defines.h */; };
- DDF30D9627C5C756006A526F /* remote_bitrate_estimator.h in Headers */ = {isa = PBXBuildFile; fileRef = DDF30D9427C5C756006A526F /* remote_bitrate_estimator.h */; };
-+ F3B7819924C7CC5200FCB122 /* mkvmuxerutil.cc in Sources */ = {isa = PBXBuildFile; fileRef = F3B7819624C7CC5100FCB122 /* mkvmuxerutil.cc */; };
-+ F3B7819A24C7CC5200FCB122 /* mkvmuxer.cc in Sources */ = {isa = PBXBuildFile; fileRef = F3B7819724C7CC5200FCB122 /* mkvmuxer.cc */; };
-+ F3B7819B24C7CC5200FCB122 /* mkvwriter.cc in Sources */ = {isa = PBXBuildFile; fileRef = F3B7819824C7CC5200FCB122 /* mkvwriter.cc */; };
- /* End PBXBuildFile section */
-
- /* Begin PBXBuildRule section */
-@@ -5606,6 +5623,13 @@
+@@ -5786,6 +5800,13 @@
remoteGlobalIDString = DDF30D0527C5C003006A526F;
remoteInfo = absl;
};
@@ -1808,42 +1779,7 @@ index f5f1d0ef71f7fcf175b016ddaefd99f18d96c1c3..5632dcb4919eb22133a62810b91e1433
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
-@@ -11165,6 +11189,9 @@
- DDF30D9027C5C725006A526F /* receive_side_congestion_controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = receive_side_congestion_controller.h; sourceTree = ""; };
- DDF30D9327C5C756006A526F /* bwe_defines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bwe_defines.h; sourceTree = ""; };
- DDF30D9427C5C756006A526F /* remote_bitrate_estimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = remote_bitrate_estimator.h; sourceTree = ""; };
-+ F3B7819624C7CC5100FCB122 /* mkvmuxerutil.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mkvmuxerutil.cc; path = mkvmuxer/mkvmuxerutil.cc; sourceTree = ""; };
-+ F3B7819724C7CC5200FCB122 /* mkvmuxer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mkvmuxer.cc; path = mkvmuxer/mkvmuxer.cc; sourceTree = ""; };
-+ F3B7819824C7CC5200FCB122 /* mkvwriter.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mkvwriter.cc; path = mkvmuxer/mkvwriter.cc; sourceTree = ""; };
- FB39D0D11200F0E300088E69 /* libwebrtc.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libwebrtc.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
- /* End PBXFileReference section */
-
-@@ -19991,6 +20018,7 @@
- isa = PBXGroup;
- children = (
- CDFD2F9224C4B2F90048DAC3 /* common */,
-+ F3B7819524C7CC1300FCB122 /* mkvmuxer */,
- CDEBB19224C0191800ADBD44 /* webm_parser */,
- );
- path = libwebm;
-@@ -20418,6 +20446,16 @@
- path = include;
- sourceTree = "";
- };
-+ F3B7819524C7CC1300FCB122 /* mkvmuxer */ = {
-+ isa = PBXGroup;
-+ children = (
-+ F3B7819724C7CC5200FCB122 /* mkvmuxer.cc */,
-+ F3B7819624C7CC5100FCB122 /* mkvmuxerutil.cc */,
-+ F3B7819824C7CC5200FCB122 /* mkvwriter.cc */,
-+ );
-+ name = mkvmuxer;
-+ sourceTree = "";
-+ };
- FB39D06E1200ED9200088E69 = {
- isa = PBXGroup;
- children = (
-@@ -23693,6 +23731,7 @@
+@@ -24271,6 +24292,7 @@
);
dependencies = (
410B3827292B73E90003E515 /* PBXTargetDependency */,
@@ -1851,7 +1787,7 @@ index f5f1d0ef71f7fcf175b016ddaefd99f18d96c1c3..5632dcb4919eb22133a62810b91e1433
DD2E76E827C6B69A00F2A74C /* PBXTargetDependency */,
CDEBB4CC24C01AB400ADBD44 /* PBXTargetDependency */,
411ED040212E0811004320BA /* PBXTargetDependency */,
-@@ -23775,6 +23814,7 @@
+@@ -24364,6 +24386,7 @@
4460B8B92B155B6A00392062 /* vp9_qp_parser_fuzzer */,
444A6EF02AEADFC9005FE121 /* vp9_replay_fuzzer */,
44945C512B9BA1C300447FFD /* webm_fuzzer */,
@@ -1859,9 +1795,9 @@ index f5f1d0ef71f7fcf175b016ddaefd99f18d96c1c3..5632dcb4919eb22133a62810b91e1433
);
};
/* End PBXProject section */
-@@ -23858,6 +23898,23 @@
+@@ -24467,6 +24490,23 @@
shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Scripts/create-symlink-to-altroot.sh\"\n";
+ shellScript = "[ -z \"${WK_DERIVED_SDK_HEADERS_DIR}\" -o -d \"${WK_DERIVED_SDK_HEADERS_DIR}\" ] && touch \"${SCRIPT_OUTPUT_FILE_0}\"\n";
};
+ F31720B127FE216400EEE407 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
@@ -1883,17 +1819,7 @@ index f5f1d0ef71f7fcf175b016ddaefd99f18d96c1c3..5632dcb4919eb22133a62810b91e1433
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
-@@ -25831,6 +25888,9 @@
- 5CDD865E1E43B8B500621E92 /* min_max_operations.c in Sources */,
- 4189395B242A71F5007FDC41 /* min_video_bitrate_experiment.cc in Sources */,
- 41B8D8FB28CB85CB00E5FA37 /* missing_mandatory_parameter_cause.cc in Sources */,
-+ F3B7819A24C7CC5200FCB122 /* mkvmuxer.cc in Sources */,
-+ F3B7819924C7CC5200FCB122 /* mkvmuxerutil.cc in Sources */,
-+ F3B7819B24C7CC5200FCB122 /* mkvwriter.cc in Sources */,
- 4131C387234B957D0028A615 /* moving_average.cc in Sources */,
- 41FCBB1521B1F7AA00A5DF27 /* moving_average.cc in Sources */,
- 5CD286101E6A64C90094FDC8 /* moving_max.cc in Sources */,
-@@ -26708,6 +26768,11 @@
+@@ -27437,6 +27477,11 @@
target = DDF30D0527C5C003006A526F /* absl */;
targetProxy = DD2E76E727C6B69A00F2A74C /* PBXContainerItemProxy */;
};
@@ -1905,7 +1831,7 @@ index f5f1d0ef71f7fcf175b016ddaefd99f18d96c1c3..5632dcb4919eb22133a62810b91e1433
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
-@@ -27283,6 +27348,27 @@
+@@ -28204,6 +28249,27 @@
};
name = Production;
};
@@ -1933,7 +1859,7 @@ index f5f1d0ef71f7fcf175b016ddaefd99f18d96c1c3..5632dcb4919eb22133a62810b91e1433
FB39D0711200ED9200088E69 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 5D7C59C71208C68B001C873E /* DebugRelease.xcconfig */;
-@@ -27585,6 +27671,16 @@
+@@ -28586,6 +28652,16 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Production;
};
@@ -1950,116 +1876,206 @@ index f5f1d0ef71f7fcf175b016ddaefd99f18d96c1c3..5632dcb4919eb22133a62810b91e1433
FB39D0731200ED9200088E69 /* Build configuration list for PBXProject "libwebrtc" */ = {
isa = XCConfigurationList;
buildConfigurations = (
+diff --git a/Source/ThirdParty/skia/CMakeLists.txt b/Source/ThirdParty/skia/CMakeLists.txt
+index 6bfc5cba986488f3d808ebd0583c476cd93da70e..f4c4222d17bce640355ba52e00152069d5b14432 100644
+--- a/Source/ThirdParty/skia/CMakeLists.txt
++++ b/Source/ThirdParty/skia/CMakeLists.txt
+@@ -10,6 +10,8 @@ if (USE_SKIA_ENCODERS)
+ find_package(WebP REQUIRED COMPONENTS mux)
+ endif ()
+
++find_package(Threads REQUIRED)
++
+ if (ANDROID)
+ find_package(EXPAT REQUIRED)
+ endif ()
+@@ -948,6 +950,7 @@ endif ()
+ target_link_libraries(Skia PRIVATE
+ JPEG::JPEG
+ PNG::PNG
++ Threads::Threads
+ )
+
+ WEBKIT_ADD_TARGET_CXX_FLAGS(Skia
+diff --git a/Source/ThirdParty/skia/src/opts/SkOpts_SetTarget.h b/Source/ThirdParty/skia/src/opts/SkOpts_SetTarget.h
+index 525cfcb862ae96bf8573d00b67dc9e5e23c10d22..f2debc0444cb8f5b80a0e99a2214bceaab3960c1 100644
+--- a/Source/ThirdParty/skia/src/opts/SkOpts_SetTarget.h
++++ b/Source/ThirdParty/skia/src/opts/SkOpts_SetTarget.h
+@@ -65,6 +65,7 @@
+ // Each of the specific intrinsic headers also checks to ensure that immintrin.h has been
+ // included, so do that here, first.
+ #if defined(__clang__) && defined(_MSC_VER)
++ #define __RTMINTRIN_H // Workaround for https://github.com/llvm/llvm-project/issues/95133
+ #include
+ #endif
+
diff --git a/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml b/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml
-index 110e762586d9dc98b3a11a5cf5d1501334b2463f..870e1950740d745588cbfdc8abd3f3709867ab8f 100644
+index 3437d1ccf6e9a78bb9a42158e54ba99f4d9d25f9..b67f7d77bdf4090ec9c29abd221562cd7bf5a80f 100644
--- a/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml
+++ b/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml
-@@ -562,6 +562,7 @@ ApplePayEnabled:
- default: false
+@@ -588,6 +588,7 @@ ApplePayEnabled:
+ richJavaScript: true
# FIXME: This is on by default in WebKit2 PLATFORM(COCOA). Perhaps we should consider turning it on for WebKitLegacy as well.
+# Playwright: enable on all platforms to align with Safari.
AsyncClipboardAPIEnabled:
type: bool
status: mature
-@@ -572,7 +573,7 @@ AsyncClipboardAPIEnabled:
+@@ -598,7 +599,7 @@ AsyncClipboardAPIEnabled:
default: false
WebKit:
- "PLATFORM(COCOA) || PLATFORM(GTK)" : true
+ "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)" : true
- default: false
+ default: true
WebCore:
default: false
-@@ -1739,9 +1740,10 @@ CrossOriginEmbedderPolicyEnabled:
+@@ -857,13 +858,10 @@ BlobFileAccessEnforcementEnabled:
+ sharedPreferenceForWebProcess: true
+ defaultValue:
+ WebKitLegacy:
+- "PLATFORM(COCOA)": true
+ default: false
+ WebKit:
+- "PLATFORM(COCOA)": true
+ default: false
+ WebCore:
+- "PLATFORM(COCOA)": true
+ default: false
+
+ BlockFontServiceInWebContentSandbox:
+@@ -2143,6 +2141,7 @@ CrossOriginEmbedderPolicyEnabled:
WebCore:
default: false
+# Playwright: disable setting.
CrossOriginOpenerPolicyEnabled:
type: bool
-- status: stable
-+ status: preview
- category: security
- humanReadableName: "Cross-Origin-Opener-Policy (COOP) header"
- humanReadableDescription: "Support for Cross-Origin-Opener-Policy (COOP) header"
-@@ -1749,7 +1751,7 @@ CrossOriginOpenerPolicyEnabled:
+ status: stable
+@@ -2216,6 +2215,7 @@ DOMAudioSessionFullEnabled:
+ WebCore:
+ default: false
+
++# Playwright: enable on all platforms to align with Safari.
+ DOMPasteAccessRequestsEnabled:
+ type: bool
+ status: internal
+@@ -2227,7 +2227,7 @@ DOMPasteAccessRequestsEnabled:
+ default: false
+ WebKit:
+ "PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(VISION)": true
+- default: false
++ default: true
+ WebCore:
+ default: false
+
+@@ -2293,10 +2293,10 @@ DataListElementEnabled:
WebKitLegacy:
default: false
WebKit:
-- default: true
-+ default: false
+- "(PLATFORM(COCOA) && !PLATFORM(WATCHOS)) || PLATFORM(GTK)": true
++ "(PLATFORM(COCOA) && !PLATFORM(WATCHOS)) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)": true
+ default: false
WebCore:
+- "(PLATFORM(COCOA) && !PLATFORM(WATCHOS)) || PLATFORM(GTK)": true
++ "(PLATFORM(COCOA) && !PLATFORM(WATCHOS)) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)": true
default: false
+ sharedPreferenceForWebProcess: true
-@@ -1793,7 +1795,7 @@ CustomPasteboardDataEnabled:
+@@ -2309,7 +2309,7 @@ DataTransferItemsEnabled:
+ WebKitLegacy:
+ default: true
+ WebKit:
+- "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)": true
++ "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)": true
+ default: false
+ WebCore:
+ default: false
+@@ -2537,7 +2537,7 @@ DirectoryUploadEnabled:
WebKitLegacy:
default: false
WebKit:
-- "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WIN)": true
+- "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)": true
+ "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)": true
default: false
-
- CustomStateSetEnabled:
-@@ -1852,6 +1854,7 @@ DOMAudioSessionFullEnabled:
WebCore:
default: false
-
-+# Playwright: enable on all platforms to align with Safari.
- DOMPasteAccessRequestsEnabled:
- type: bool
- status: internal
-@@ -1863,7 +1866,7 @@ DOMPasteAccessRequestsEnabled:
+@@ -3020,10 +3020,10 @@ FullScreenEnabled:
+ WebKitLegacy:
default: false
WebKit:
- "PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(VISION)": true
-- default: false
-+ default: true
+- "PLATFORM(GTK) || PLATFORM(WPE)": true
++ "PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(WPE)": true
+ default: false
WebCore:
+- "PLATFORM(GTK) || PLATFORM(WPE)": true
++ "PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(WPE)": true
default: false
+ sharedPreferenceForWebProcess: true
-@@ -3232,6 +3235,7 @@ InspectorAttachmentSide:
+@@ -3614,7 +3614,7 @@ InputTypeColorEnabled:
+ WebKitLegacy:
+ default: false
WebKit:
- default: 0
+- "PLATFORM(COCOA) && !PLATFORM(WATCHOS) || PLATFORM(GTK)": true
++ "PLATFORM(COCOA) && !PLATFORM(WATCHOS) || PLATFORM(GTK) || PLATFORM(WPE)": true
+ default: false
+ WebCore:
+ default: false
+@@ -3647,7 +3647,7 @@ InputTypeDateEnabled:
+ "PLATFORM(IOS_FAMILY)": true
+ default: false
+ WebKit:
+- "PLATFORM(COCOA) || PLATFORM(GTK)": true
++ "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)": true
+ default: false
+ WebCore:
+ default: false
+@@ -3663,7 +3663,7 @@ InputTypeDateTimeLocalEnabled:
+ "PLATFORM(IOS_FAMILY)": true
+ default: false
+ WebKit:
+- "PLATFORM(COCOA) || PLATFORM(GTK)": true
++ "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)": true
+ default: false
+ WebCore:
+ default: false
+@@ -3695,7 +3695,7 @@ InputTypeTimeEnabled:
+ "PLATFORM(IOS_FAMILY)": true
+ default: false
+ WebKit:
+- "PLATFORM(COCOA) || PLATFORM(GTK)": true
++ "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)": true
+ default: false
+ WebCore:
+ default: false
+@@ -3756,6 +3756,7 @@ InspectorMaximumResourcesContentSize:
+ "PLATFORM(WPE)": 50
+ default: 200
+# Playwright: disable setting.
InspectorStartsAttached:
type: bool
status: embedder
-@@ -3239,7 +3243,7 @@ InspectorStartsAttached:
+@@ -3763,7 +3764,7 @@ InspectorStartsAttached:
exposed: [ WebKit ]
defaultValue:
WebKit:
- default: true
+ default: false
- InspectorWindowFrame:
- type: String
-@@ -3593,9 +3597,10 @@ LayoutViewportHeightExpansionFactor:
- WebCore:
- default: 0
-
-+# Playwright: disable setting.
- LazyIframeLoadingEnabled:
+ InspectorSupportsShowingCertificate:
type: bool
-- status: stable
-+ status: preview
- category: html
- humanReadableName: "Lazy iframe loading"
- humanReadableDescription: "Enable lazy iframe loading support"
-@@ -3603,9 +3608,9 @@ LazyIframeLoadingEnabled:
+@@ -5683,7 +5684,7 @@ PermissionsAPIEnabled:
WebKitLegacy:
- default: true
+ default: false
WebKit:
-- default: true
-+ default: false
+- "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)" : true
++ "PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)" : true
+ default: false
WebCore:
-- default: true
-+ default: false
-
- LazyImageLoadingEnabled:
- type: bool
-@@ -5028,6 +5033,19 @@ PitchCorrectionAlgorithm:
+ default: false
+@@ -5762,6 +5763,19 @@ PitchCorrectionAlgorithm:
WebCore:
default: MediaPlayerEnums::PitchCorrectionAlgorithm::BestAllAround
@@ -2078,16 +2094,25 @@ index 110e762586d9dc98b3a11a5cf5d1501334b2463f..870e1950740d745588cbfdc8abd3f370
+
PointerLockOptionsEnabled:
type: bool
- status: testable
-@@ -6778,6 +6796,7 @@ UseCGDisplayListsForDOMRendering:
+ status: stable
+@@ -6344,7 +6358,7 @@ ScreenOrientationAPIEnabled:
+ WebKitLegacy:
+ default: false
WebKit:
+- default: WebKit::defaultShouldEnableScreenOrientationAPI()
++ default: true
+ WebCore:
+ default: false
+ sharedPreferenceForWebProcess: true
+@@ -7806,6 +7820,7 @@ UseCGDisplayListsForDOMRendering:
default: true
+ sharedPreferenceForWebProcess: true
+# Playwright: force-disable on Windows.
UseGPUProcessForCanvasRenderingEnabled:
type: bool
status: stable
-@@ -6790,7 +6809,7 @@ UseGPUProcessForCanvasRenderingEnabled:
+@@ -7818,7 +7833,7 @@ UseGPUProcessForCanvasRenderingEnabled:
defaultValue:
WebKit:
"ENABLE(GPU_PROCESS_BY_DEFAULT)": true
@@ -2096,24 +2121,15 @@ index 110e762586d9dc98b3a11a5cf5d1501334b2463f..870e1950740d745588cbfdc8abd3f370
default: false
UseGPUProcessForDOMRenderingEnabled:
-@@ -6800,7 +6819,7 @@ UseGPUProcessForDOMRenderingEnabled:
- humanReadableName: "GPU Process: DOM Rendering"
- humanReadableDescription: "Enable DOM rendering in GPU Process"
- webcoreBinding: none
-- condition: ENABLE(GPU_PROCESS)
-+ condition: ENABLE(GPU_PROCESS) && !PLATFORM(WIN)
- exposed: [ WebKit ]
- defaultValue:
- WebKit:
-@@ -6832,6 +6851,7 @@ UseGPUProcessForMediaEnabled:
- "ENABLE(GPU_PROCESS_BY_DEFAULT)": true
- default: false
+@@ -7863,6 +7878,7 @@ UseGPUProcessForMediaEnabled:
+ sharedPreferenceForWebProcess: true
+ mediaPlaybackRelated: true
+# Playwright: force-disable on Windows.
UseGPUProcessForWebGLEnabled:
type: bool
status: internal
-@@ -6843,7 +6863,7 @@ UseGPUProcessForWebGLEnabled:
+@@ -7874,7 +7890,7 @@ UseGPUProcessForWebGLEnabled:
default: false
WebKit:
"ENABLE(GPU_PROCESS_BY_DEFAULT) && ENABLE(GPU_PROCESS_WEBGL_BY_DEFAULT)": true
@@ -2123,10 +2139,10 @@ index 110e762586d9dc98b3a11a5cf5d1501334b2463f..870e1950740d745588cbfdc8abd3f370
WebCore:
"ENABLE(GPU_PROCESS_BY_DEFAULT) && ENABLE(GPU_PROCESS_WEBGL_BY_DEFAULT)": true
diff --git a/Source/WTF/wtf/PlatformEnable.h b/Source/WTF/wtf/PlatformEnable.h
-index 6f547f01a22d1aba86b813fc77679124a643ef72..34fbae99c2e64f2a34a83d878da76f9c75d0bea5 100644
+index a36395e83c53617c2f894695846f8798fc277624..f0b8dd0fd12b4cde24975c20015cee30292abf9d 100644
--- a/Source/WTF/wtf/PlatformEnable.h
+++ b/Source/WTF/wtf/PlatformEnable.h
-@@ -401,7 +401,7 @@
+@@ -385,7 +385,7 @@
// ORIENTATION_EVENTS should never get enabled on Desktop, only Mobile.
#if !defined(ENABLE_ORIENTATION_EVENTS)
@@ -2135,7 +2151,7 @@ index 6f547f01a22d1aba86b813fc77679124a643ef72..34fbae99c2e64f2a34a83d878da76f9c
#endif
#if !defined(ENABLE_OVERFLOW_SCROLLING_TOUCH)
-@@ -506,7 +506,7 @@
+@@ -502,7 +502,7 @@
#endif
#if !defined(ENABLE_TOUCH_EVENTS)
@@ -2145,10 +2161,10 @@ index 6f547f01a22d1aba86b813fc77679124a643ef72..34fbae99c2e64f2a34a83d878da76f9c
#if !defined(ENABLE_TOUCH_ACTION_REGIONS)
diff --git a/Source/WTF/wtf/PlatformEnableCocoa.h b/Source/WTF/wtf/PlatformEnableCocoa.h
-index d797c28eccac0578c7c504fa0c7b34d517746b17..32e815241e2513c979d1af01ef88b494851a2409 100644
+index 8304147ff102789180b2682eb64d599791528c93..af8cb85981bda7b91edfa21b6cc321849d93b909 100644
--- a/Source/WTF/wtf/PlatformEnableCocoa.h
+++ b/Source/WTF/wtf/PlatformEnableCocoa.h
-@@ -775,7 +775,7 @@
+@@ -808,7 +808,7 @@
#endif
#if !defined(ENABLE_SEC_ITEM_SHIM)
@@ -2158,19 +2174,10 @@ index d797c28eccac0578c7c504fa0c7b34d517746b17..32e815241e2513c979d1af01ef88b494
#if !defined(ENABLE_SERVER_PRECONNECT)
diff --git a/Source/WTF/wtf/PlatformHave.h b/Source/WTF/wtf/PlatformHave.h
-index cb5e806040f4e6e2bf94a4c27b05892af7e4301d..81fd915ce2643522b225139661da9f7dedf32469 100644
+index 9e91a26aac61faea9634328f9a46421a4b4b7c38..b70776d97be4025435dc3c0364105cb17c429f6a 100644
--- a/Source/WTF/wtf/PlatformHave.h
+++ b/Source/WTF/wtf/PlatformHave.h
-@@ -419,7 +419,7 @@
- #define HAVE_FOUNDATION_WITH_SAME_SITE_COOKIE_SUPPORT 1
- #endif
-
--#if PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(MACCATALYST) || PLATFORM(VISION) || PLATFORM(GTK) || PLATFORM(WPE)
-+#if PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(MACCATALYST) || PLATFORM(VISION) || PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(WIN)
- #define HAVE_OS_DARK_MODE_SUPPORT 1
- #endif
-
-@@ -1274,7 +1274,8 @@
+@@ -1189,7 +1189,8 @@
#endif
#if PLATFORM(MAC)
@@ -2181,13 +2188,14 @@ index cb5e806040f4e6e2bf94a4c27b05892af7e4301d..81fd915ce2643522b225139661da9f7d
#if !defined(HAVE_LOCKDOWN_MODE_PDF_ADDITIONS) && \
diff --git a/Source/WTF/wtf/unicode/UTF8Conversion.h b/Source/WTF/wtf/unicode/UTF8Conversion.h
-index f45ef73d81bd02c0b542e98ff01f59d88f57b8a0..0fb91174b8e6641d20b4ee084ec48910cdf7b836 100644
+index 007b8fe3292f326504013be8198ae020f7aacf35..1c722c473732ffe05fdb61010fa4417e3e399d1f 100644
--- a/Source/WTF/wtf/unicode/UTF8Conversion.h
+++ b/Source/WTF/wtf/unicode/UTF8Conversion.h
-@@ -28,6 +28,10 @@
- #include
+@@ -27,6 +27,11 @@
+
#include
++// Can be probably removed when we drop Debian 11.
+#ifdef Success
+#undef Success
+#endif
@@ -2196,13 +2204,13 @@ index f45ef73d81bd02c0b542e98ff01f59d88f57b8a0..0fb91174b8e6641d20b4ee084ec48910
namespace Unicode {
diff --git a/Source/WebCore/DerivedSources.make b/Source/WebCore/DerivedSources.make
-index 9dd05dd4e7ad824cae7c47d61117a2bbde10c3e5..015b2ce422f594860a77b0382e9a3857f2db4ff6 100644
+index 0f0341624503ae9744b71d3675dc96545371456a..cc73c79374f07fbf1f83e7075e53a3d99da0705c 100644
--- a/Source/WebCore/DerivedSources.make
+++ b/Source/WebCore/DerivedSources.make
-@@ -1149,6 +1149,10 @@ JS_BINDING_IDLS := \
- $(WebCore)/dom/Slotable.idl \
- $(WebCore)/dom/StaticRange.idl \
- $(WebCore)/dom/StringCallback.idl \
+@@ -1229,6 +1229,10 @@ JS_BINDING_IDLS := \
+ $(WebCore)/dom/SubscriberCallback.idl \
+ $(WebCore)/dom/SubscriptionObserver.idl \
+ $(WebCore)/dom/SubscriptionObserverCallback.idl \
+ $(WebCore)/dom/Document+Touch.idl \
+ $(WebCore)/dom/Touch.idl \
+ $(WebCore)/dom/TouchEvent.idl \
@@ -2210,7 +2218,7 @@ index 9dd05dd4e7ad824cae7c47d61117a2bbde10c3e5..015b2ce422f594860a77b0382e9a3857
$(WebCore)/dom/Text.idl \
$(WebCore)/dom/TextDecoder.idl \
$(WebCore)/dom/TextDecoderStream.idl \
-@@ -1735,9 +1739,6 @@ JS_BINDING_IDLS := \
+@@ -1829,9 +1833,6 @@ JS_BINDING_IDLS := \
ADDITIONAL_BINDING_IDLS = \
DocumentTouch.idl \
GestureEvent.idl \
@@ -2221,22 +2229,22 @@ index 9dd05dd4e7ad824cae7c47d61117a2bbde10c3e5..015b2ce422f594860a77b0382e9a3857
vpath %.in $(WEBKITADDITIONS_HEADER_SEARCH_PATHS)
diff --git a/Source/WebCore/Modules/geolocation/Geolocation.cpp b/Source/WebCore/Modules/geolocation/Geolocation.cpp
-index 32fde85425cbb82eb30bcc7aef58155026d2b7b7..a35495d97fcf0346e4696e26df80cf4a8fb890d6 100644
+index 7d0ca9a308e7aeaf132dccfddeae129fc8c9e093..0eeac0eec23fbc8c3df6c56d63603acc46e8590c 100644
--- a/Source/WebCore/Modules/geolocation/Geolocation.cpp
+++ b/Source/WebCore/Modules/geolocation/Geolocation.cpp
-@@ -357,8 +357,9 @@ bool Geolocation::shouldBlockGeolocationRequests()
- bool isSecure = SecurityOrigin::isSecure(document()->url()) || document()->isSecureContext();
- bool hasMixedContent = !document()->foundMixedContent().isEmpty();
+@@ -362,8 +362,9 @@ bool Geolocation::shouldBlockGeolocationRequests()
+ bool isSecure = SecurityOrigin::isSecure(document->url()) || document->isSecureContext();
+ bool hasMixedContent = !document->foundMixedContent().isEmpty();
bool isLocalOrigin = securityOrigin()->isLocal();
+ bool isPotentiallyTrustworthy = securityOrigin()->isPotentiallyTrustworthy();
- if (document()->canAccessResource(ScriptExecutionContext::ResourceType::Geolocation) != ScriptExecutionContext::HasResourceAccess::No) {
+ if (document->canAccessResource(ScriptExecutionContext::ResourceType::Geolocation) != ScriptExecutionContext::HasResourceAccess::No) {
- if (isLocalOrigin || (isSecure && !hasMixedContent))
-+ if (isLocalOrigin || isPotentiallyTrustworthy || (isSecure && !hasMixedContent))
++ if (isLocalOrigin || (isSecure && !hasMixedContent) || isPotentiallyTrustworthy)
return false;
}
diff --git a/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm b/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm
-index 506ebb25fa290f27a75674a6fe5506fc311910d6..07d34c567b42aca08b188243c3f036f64a8da0c4 100644
+index b2b0391c120d527a9ab4bc6daf8bff7ea5d03cf7..d490a95f89f21536fce4f403b86399160abefc23 100644
--- a/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm
+++ b/Source/WebCore/Modules/speech/cocoa/WebSpeechRecognizerTask.mm
@@ -195,6 +195,7 @@ - (void)sendEndIfNeeded
@@ -2271,26 +2279,14 @@ index 506ebb25fa290f27a75674a6fe5506fc311910d6..07d34c567b42aca08b188243c3f036f6
ASSERT(isMainThread());
[self sendSpeechEndIfNeeded];
-diff --git a/Source/WebCore/PlatformWPE.cmake b/Source/WebCore/PlatformWPE.cmake
-index c6a03b56d8358316c9ce422c1a11438bd216f80f..69fbd319b7cd084ca125a8db1b5d92ef6a4dc10f 100644
---- a/Source/WebCore/PlatformWPE.cmake
-+++ b/Source/WebCore/PlatformWPE.cmake
-@@ -60,6 +60,7 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
- platform/graphics/libwpe/PlatformDisplayLibWPE.h
-
- platform/graphics/wayland/PlatformDisplayWayland.h
-+ platform/wpe/SelectionData.h
- )
-
- set(CSS_VALUE_PLATFORM_DEFINES "HAVE_OS_DARK_MODE_SUPPORT=1")
diff --git a/Source/WebCore/SourcesCocoa.txt b/Source/WebCore/SourcesCocoa.txt
-index eece14fded1942140af81dede0861fb5f79fb532..cd3c5ebaccd268695d9e7bc0b96f30522c42e43e 100644
+index 06a9accfc8e6c46493733663b5d76b07fc80db22..4946d012d166c84b25d4d954266c4dc528f7d8ad 100644
--- a/Source/WebCore/SourcesCocoa.txt
+++ b/Source/WebCore/SourcesCocoa.txt
-@@ -713,3 +713,9 @@ testing/cocoa/WebViewVisualIdentificationOverlay.mm
+@@ -734,3 +734,9 @@ testing/cocoa/WebViewVisualIdentificationOverlay.mm
platform/graphics/angle/GraphicsContextGLANGLE.cpp @no-unify
platform/graphics/cocoa/GraphicsContextGLCocoa.mm @no-unify
- platform/graphics/cv/GraphicsContextGLCVCocoa.cpp @no-unify
+ platform/graphics/cv/GraphicsContextGLCVCocoa.mm @no-unify
+
+// Playwright begin
+JSTouch.cpp
@@ -2298,10 +2294,10 @@ index eece14fded1942140af81dede0861fb5f79fb532..cd3c5ebaccd268695d9e7bc0b96f3052
+JSTouchList.cpp
+// Playwright end
diff --git a/Source/WebCore/SourcesGTK.txt b/Source/WebCore/SourcesGTK.txt
-index af2081f34b9d8d97864a6e9507805abc9e8eb6d7..06ed467b2c6e529baba22a04e03a4858f8552e19 100644
+index 2b22eb2071e32741cb1383601466e537dca917f2..4da3cb8c1f1247bbc9886b060cd2d53047ca6572 100644
--- a/Source/WebCore/SourcesGTK.txt
+++ b/Source/WebCore/SourcesGTK.txt
-@@ -110,3 +110,10 @@ platform/unix/LoggingUnix.cpp
+@@ -112,3 +112,10 @@ platform/unix/LoggingUnix.cpp
platform/unix/SharedMemoryUnix.cpp
platform/xdg/MIMETypeRegistryXdg.cpp
@@ -2313,10 +2309,10 @@ index af2081f34b9d8d97864a6e9507805abc9e8eb6d7..06ed467b2c6e529baba22a04e03a4858
+JSSpeechSynthesisEventInit.cpp
+// Playwright: end.
diff --git a/Source/WebCore/SourcesWPE.txt b/Source/WebCore/SourcesWPE.txt
-index 92f1879df295fc63a9194dc54d3f7499c5fe3041..67c40d056aee6a8149ed1ff16ce4c835e19f7f6c 100644
+index ce3cf51287e5891289bd23580084b8137ee4276b..c46e4e0c6faaca888e3ea62afd0e16d6f4cfda35 100644
--- a/Source/WebCore/SourcesWPE.txt
+++ b/Source/WebCore/SourcesWPE.txt
-@@ -46,6 +46,8 @@ editing/libwpe/EditorLibWPE.cpp
+@@ -48,6 +48,8 @@ editing/glib/WebContentReaderGLib.cpp
loader/soup/ResourceLoaderSoup.cpp
@@ -2325,18 +2321,14 @@ index 92f1879df295fc63a9194dc54d3f7499c5fe3041..67c40d056aee6a8149ed1ff16ce4c835
page/linux/ResourceUsageOverlayLinux.cpp
page/linux/ResourceUsageThreadLinux.cpp
-@@ -87,6 +89,17 @@ platform/text/LocaleICU.cpp
- platform/unix/LoggingUnix.cpp
- platform/unix/SharedMemoryUnix.cpp
-
-+platform/wpe/DragDataWPE.cpp
-+platform/wpe/DragImageWPE.cpp
+@@ -97,3 +99,13 @@ platform/wpe/PasteboardWPE.cpp
platform/wpe/PlatformScreenWPE.cpp
platform/xdg/MIMETypeRegistryXdg.cpp
+
+// Playwright: begin.
-+platform/wpe/SelectionData.cpp
++platform/wpe/DragDataWPE.cpp
++platform/wpe/DragImageWPE.cpp
+
+JSSpeechSynthesisErrorCode.cpp
+JSSpeechSynthesisErrorEvent.cpp
@@ -2344,12 +2336,12 @@ index 92f1879df295fc63a9194dc54d3f7499c5fe3041..67c40d056aee6a8149ed1ff16ce4c835
+JSSpeechSynthesisEventInit.cpp
+// Playwright: end.
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
-index 8807578bc8e503fce83e9acc30029cef75b7f071..7fffb6499c200dca0c3ee777feaf284999d5d763 100644
+index e522afd2d6f038d2a2c9804313d1d8e75c63e914..03f521d898bd7d80a94e7e3c0fc4c904d279a0ba 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
-@@ -6216,6 +6216,13 @@
- EDE3A5000C7A430600956A37 /* ColorMac.h in Headers */ = {isa = PBXBuildFile; fileRef = EDE3A4FF0C7A430600956A37 /* ColorMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
- EDEC98030AED7E170059137F /* WebCorePrefix.h in Headers */ = {isa = PBXBuildFile; fileRef = EDEC98020AED7E170059137F /* WebCorePrefix.h */; };
+@@ -6452,6 +6452,13 @@
+ EE0C7E042CE845CB0043DAF8 /* CSSPositionTryRule.h in Headers */ = {isa = PBXBuildFile; fileRef = EE0C7E002CE845CB0043DAF8 /* CSSPositionTryRule.h */; };
+ EE0D3C492D2F4B4C00072978 /* StageModeOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = EE0D3C482D2F4AE600072978 /* StageModeOperations.h */; settings = {ATTRIBUTES = (Private, ); }; };
EFCC6C8F20FE914400A2321B /* CanvasActivityRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = EFCC6C8D20FE914000A2321B /* CanvasActivityRecord.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ F050E16823AC9C080011CE47 /* PlatformTouchEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F050E16623AC9C070011CE47 /* PlatformTouchEvent.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ F050E16A23AD660C0011CE47 /* Touch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F050E16923AD660C0011CE47 /* Touch.cpp */; };
@@ -2361,8 +2353,8 @@ index 8807578bc8e503fce83e9acc30029cef75b7f071..7fffb6499c200dca0c3ee777feaf2849
F12171F616A8CF0B000053CA /* WebVTTElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F12171F416A8BC63000053CA /* WebVTTElement.h */; };
F32BDCD92363AACA0073B6AE /* UserGestureEmulationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = F32BDCD72363AACA0073B6AE /* UserGestureEmulationScope.h */; };
F344C7141125B82C00F26EEE /* InspectorFrontendClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F344C7121125B82C00F26EEE /* InspectorFrontendClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
-@@ -20126,6 +20133,14 @@
- EDEC98020AED7E170059137F /* WebCorePrefix.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebCorePrefix.h; sourceTree = ""; tabWidth = 4; usesTabs = 0; };
+@@ -21141,6 +21148,14 @@
+ EE7A169F2C607BFA0057B563 /* StartViewTransitionOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StartViewTransitionOptions.h; sourceTree = ""; };
EFB7287B2124C73D005C2558 /* CanvasActivityRecord.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CanvasActivityRecord.cpp; sourceTree = ""; };
EFCC6C8D20FE914000A2321B /* CanvasActivityRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CanvasActivityRecord.h; sourceTree = ""; };
+ F050E16623AC9C070011CE47 /* PlatformTouchEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformTouchEvent.h; sourceTree = ""; };
@@ -2376,7 +2368,7 @@ index 8807578bc8e503fce83e9acc30029cef75b7f071..7fffb6499c200dca0c3ee777feaf2849
F12171F316A8BC63000053CA /* WebVTTElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebVTTElement.cpp; sourceTree = ""; };
F12171F416A8BC63000053CA /* WebVTTElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebVTTElement.h; sourceTree = ""; };
F32BDCD52363AAC90073B6AE /* UserGestureEmulationScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserGestureEmulationScope.cpp; sourceTree = ""; };
-@@ -27745,6 +27760,11 @@
+@@ -28928,6 +28943,11 @@
BC4A5324256055590028C592 /* TextDirectionSubmenuInclusionBehavior.h */,
2D4F96F11A1ECC240098BF88 /* TextIndicator.cpp */,
2D4F96F21A1ECC240098BF88 /* TextIndicator.h */,
@@ -2388,16 +2380,16 @@ index 8807578bc8e503fce83e9acc30029cef75b7f071..7fffb6499c200dca0c3ee777feaf2849
F48570A42644C76D00C05F71 /* TranslationContextMenuInfo.h */,
F4E1965F21F26E4E00285078 /* UndoItem.cpp */,
2ECDBAD521D8906300F00ECD /* UndoItem.h */,
-@@ -34075,6 +34095,8 @@
+@@ -35916,6 +35936,8 @@
29E4D8DF16B0940F00C84704 /* PlatformSpeechSynthesizer.h */,
1AD8F81A11CAB9E900E93E54 /* PlatformStrategies.cpp */,
1AD8F81911CAB9E900E93E54 /* PlatformStrategies.h */,
+ F050E16623AC9C070011CE47 /* PlatformTouchEvent.h */,
+ F050E17623AD70C40011CE47 /* PlatformTouchPoint.h */,
+ FE3DC9932D0C063C0021B6FC /* PlatformTZoneImpls.cpp */,
0FD7C21D23CE41E30096D102 /* PlatformWheelEvent.cpp */,
935C476A09AC4D4F00A6AAB4 /* PlatformWheelEvent.h */,
- F491A66A2A9FEFA300F96146 /* PlatformWheelEvent.serialization.in */,
-@@ -36745,6 +36767,7 @@
+@@ -38777,6 +38799,7 @@
AD6E71AB1668899D00320C13 /* DocumentSharedObjectPool.h */,
6BDB5DC1227BD3B800919770 /* DocumentStorageAccess.cpp */,
6BDB5DC0227BD3B800919770 /* DocumentStorageAccess.h */,
@@ -2405,7 +2397,7 @@ index 8807578bc8e503fce83e9acc30029cef75b7f071..7fffb6499c200dca0c3ee777feaf2849
7CE7FA5B1EF882300060C9D6 /* DocumentTouch.cpp */,
7CE7FA591EF882300060C9D6 /* DocumentTouch.h */,
A8185F3209765765005826D9 /* DocumentType.cpp */,
-@@ -41482,6 +41505,8 @@
+@@ -43729,6 +43752,8 @@
F4E90A3C2B52038E002DA469 /* PlatformTextAlternatives.h in Headers */,
0F7D07331884C56C00B4AF86 /* PlatformTextTrack.h in Headers */,
074E82BB18A69F0E007EF54C /* PlatformTimeRanges.h in Headers */,
@@ -2414,7 +2406,7 @@ index 8807578bc8e503fce83e9acc30029cef75b7f071..7fffb6499c200dca0c3ee777feaf2849
CDD08ABD277E542600EA3755 /* PlatformTrackConfiguration.h in Headers */,
CD1F9B022700323D00617EB6 /* PlatformVideoColorPrimaries.h in Headers */,
CD1F9B01270020B700617EB6 /* PlatformVideoColorSpace.h in Headers */,
-@@ -42762,6 +42787,7 @@
+@@ -45097,6 +45122,7 @@
0F54DD081881D5F5003EEDBB /* Touch.h in Headers */,
71B7EE0D21B5C6870031C1EF /* TouchAction.h in Headers */,
0F54DD091881D5F5003EEDBB /* TouchEvent.h in Headers */,
@@ -2422,7 +2414,7 @@ index 8807578bc8e503fce83e9acc30029cef75b7f071..7fffb6499c200dca0c3ee777feaf2849
0F54DD0A1881D5F5003EEDBB /* TouchList.h in Headers */,
070334D71459FFD5008D8D45 /* TrackBase.h in Headers */,
BE88E0C21715CE2600658D98 /* TrackListBase.h in Headers */,
-@@ -43910,6 +43936,8 @@
+@@ -46300,6 +46326,8 @@
2D22830323A8470700364B7E /* CursorMac.mm in Sources */,
5CBD59592280E926002B22AA /* CustomHeaderFields.cpp in Sources */,
07E4BDBF2A3A5FAB000D5509 /* DictationCaretAnimator.cpp in Sources */,
@@ -2431,7 +2423,7 @@ index 8807578bc8e503fce83e9acc30029cef75b7f071..7fffb6499c200dca0c3ee777feaf2849
7CE6CBFD187F394900D46BF5 /* FormatConverter.cpp in Sources */,
4667EA3E2968D9DA00BAB1E2 /* GameControllerHapticEffect.mm in Sources */,
46FE73D32968E52000B8064C /* GameControllerHapticEngines.mm in Sources */,
-@@ -43997,6 +44025,9 @@
+@@ -46390,6 +46418,9 @@
CE88EE262414467B007F29C2 /* TextAlternativeWithRange.mm in Sources */,
BE39137129B267F500FA5D4F /* TextTransformCocoa.cpp in Sources */,
51DF6D800B92A18E00C2DC85 /* ThreadCheck.mm in Sources */,
@@ -2442,18 +2434,18 @@ index 8807578bc8e503fce83e9acc30029cef75b7f071..7fffb6499c200dca0c3ee777feaf2849
538EC8021F96AF81004D22A8 /* UnifiedSource1.cpp in Sources */,
538EC8051F96AF81004D22A8 /* UnifiedSource2-mm.mm in Sources */,
diff --git a/Source/WebCore/accessibility/AccessibilityObject.cpp b/Source/WebCore/accessibility/AccessibilityObject.cpp
-index 9253fbb9de00b2768dd67c6efa20a2242e2e6621..c758a4e9b6f779458a611b6458ba89de1c17e4c8 100644
+index 3f19caf891dfa1cc70aa630f4e82c405825ab40c..62b2978c8d5e8af5e337d8b27c1d2ad938b773fe 100644
--- a/Source/WebCore/accessibility/AccessibilityObject.cpp
+++ b/Source/WebCore/accessibility/AccessibilityObject.cpp
-@@ -66,6 +66,7 @@
- #include "HTMLSlotElement.h"
+@@ -72,6 +72,7 @@
+ #include "HTMLTableSectionElement.h"
#include "HTMLTextAreaElement.h"
#include "HitTestResult.h"
+#include "InspectorInstrumentation.h"
#include "LocalFrame.h"
#include "LocalizedStrings.h"
#include "MathMLNames.h"
-@@ -4075,9 +4076,14 @@ AccessibilityObjectInclusion AccessibilityObject::defaultObjectInclusion() const
+@@ -3931,7 +3932,12 @@ AccessibilityObjectInclusion AccessibilityObject::defaultObjectInclusion() const
if (roleValue() == AccessibilityRole::ApplicationDialog)
return AccessibilityObjectInclusion::IncludeObject;
@@ -2465,16 +2457,13 @@ index 9253fbb9de00b2768dd67c6efa20a2242e2e6621..c758a4e9b6f779458a611b6458ba89de
+ }
+ return platformBehavior;
}
--
-+
- bool AccessibilityObject::accessibilityIsIgnored() const
- {
- AXComputedObjectAttributeCache* attributeCache = nullptr;
+
+ bool AccessibilityObject::isWithinHiddenWebArea() const
diff --git a/Source/WebCore/bindings/js/WebCoreBuiltinNames.h b/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
-index f20ac9d4d61a6f396e9ed796c8e6c5b8a7ea0577..3151b5e54ea17c0d979d22a0cc43c5ce0688c183 100644
+index 158dc6af1464896ac4c4727c52581729ac132352..b8bd22a7d80d08d6dd56ea1bc10addbe3f839b6d 100644
--- a/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
+++ b/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
-@@ -183,6 +183,8 @@ namespace WebCore {
+@@ -190,6 +190,8 @@ namespace WebCore {
macro(DelayNode) \
macro(DeprecationReportBody) \
macro(DigitalCredential) \
@@ -2484,13 +2473,13 @@ index f20ac9d4d61a6f396e9ed796c8e6c5b8a7ea0577..3151b5e54ea17c0d979d22a0cc43c5ce
macro(DynamicsCompressorNode) \
macro(ElementInternals) \
diff --git a/Source/WebCore/css/query/MediaQueryFeatures.cpp b/Source/WebCore/css/query/MediaQueryFeatures.cpp
-index 9892fda4291cae0e0d338fac8b0f98cd0126807d..7ecfd659809ab30e82a9c00ec7710292a1bd5611 100644
+index aec43490053f95341ef979385b5e6c1daf03a090..4e44b7e341c8247f916f8597092248d8ec884518 100644
--- a/Source/WebCore/css/query/MediaQueryFeatures.cpp
+++ b/Source/WebCore/css/query/MediaQueryFeatures.cpp
-@@ -368,7 +368,11 @@ const FeatureSchema& forcedColors()
- static MainThreadNeverDestroyed schema {
+@@ -498,7 +498,11 @@ static const IdentifierSchema& forcedColorsFeatureSchema()
"forced-colors"_s,
FixedVector { CSSValueNone, CSSValueActive },
+ OptionSet(),
- [](auto&) {
+ [](auto& context) {
+ auto* page = context.document->frame()->page();
@@ -2500,7 +2489,7 @@ index 9892fda4291cae0e0d338fac8b0f98cd0126807d..7ecfd659809ab30e82a9c00ec7710292
return MatchingIdentifiers { CSSValueNone };
}
};
-@@ -547,6 +551,9 @@ const FeatureSchema& prefersReducedMotion()
+@@ -686,6 +690,9 @@ static const IdentifierSchema& prefersReducedMotionFeatureSchema()
[](auto& context) {
bool userPrefersReducedMotion = [&] {
Ref frame = *context.document->frame();
@@ -2511,10 +2500,10 @@ index 9892fda4291cae0e0d338fac8b0f98cd0126807d..7ecfd659809ab30e82a9c00ec7710292
case ForcedAccessibilityValue::On:
return true;
diff --git a/Source/WebCore/dom/DataTransfer.cpp b/Source/WebCore/dom/DataTransfer.cpp
-index b56c600b6159973dc8a33db1deba0cfbb77abf48..a347a85381888e2f6423393552d619938ad34f21 100644
+index c6f2dca0d4aede2bea015d1cca45dff434425938..e6f41af39befe69f47d0e0953f7d689c338ca184 100644
--- a/Source/WebCore/dom/DataTransfer.cpp
+++ b/Source/WebCore/dom/DataTransfer.cpp
-@@ -510,6 +510,14 @@ Ref DataTransfer::createForDrag(const Document& document)
+@@ -523,6 +523,14 @@ Ref DataTransfer::createForDrag(const Document& document)
return adoptRef(*new DataTransfer(StoreMode::ReadWrite, Pasteboard::createForDragAndDrop(PagePasteboardContext::create(document.pageID())), Type::DragAndDropData));
}
@@ -2530,10 +2519,10 @@ index b56c600b6159973dc8a33db1deba0cfbb77abf48..a347a85381888e2f6423393552d61993
{
auto dataTransfer = adoptRef(*new DataTransfer(StoreMode::ReadWrite, makeUnique(), Type::DragAndDropData));
diff --git a/Source/WebCore/dom/DataTransfer.h b/Source/WebCore/dom/DataTransfer.h
-index 6ca2550bf509381165e5da22cc894ccf6378f45c..535bd1b05e8d90b291235cfc3cb425084455ff26 100644
+index 34ef2f454a732d39acae04987584cab5638b8c60..5e7b788612718dffe3423c89d96141b5b53621fb 100644
--- a/Source/WebCore/dom/DataTransfer.h
+++ b/Source/WebCore/dom/DataTransfer.h
-@@ -91,6 +91,9 @@ public:
+@@ -92,6 +92,9 @@ public:
#if ENABLE(DRAG_SUPPORT)
static Ref createForDrag(const Document&);
@@ -2544,7 +2533,7 @@ index 6ca2550bf509381165e5da22cc894ccf6378f45c..535bd1b05e8d90b291235cfc3cb42508
static Ref createForDrop(const Document&, std::unique_ptr&&, OptionSet, bool draggingFiles);
static Ref createForUpdatingDropTarget(const Document&, std::unique_ptr&&, OptionSet, bool draggingFiles);
diff --git a/Source/WebCore/dom/DeviceMotionEvent.idl b/Source/WebCore/dom/DeviceMotionEvent.idl
-index ea39a33a6250b4d10b20802f98aa9a5d57e63a7b..300a763508d311fd7b34cb3df3cc93080bb52930 100644
+index d59cba0b1c3e1876614476cd887fa1b2a9619d0c..565987a3f9ef7dc29edf8315cebe51b00953dc84 100644
--- a/Source/WebCore/dom/DeviceMotionEvent.idl
+++ b/Source/WebCore/dom/DeviceMotionEvent.idl
@@ -25,6 +25,7 @@
@@ -2604,24 +2593,26 @@ index 9b344003de17b96d8b9ca8c7f32143a27543b1ea..2208a3f2b7d930bcd291e65b474d4c30
] partial interface Element {
// Returns Promise if PointerLockOptionsEnabled Runtime Flag is set, otherwise returns undefined.
diff --git a/Source/WebCore/dom/PointerEvent.cpp b/Source/WebCore/dom/PointerEvent.cpp
-index c35c7851f168954a0c5265ea218a2173b7b079a8..500b267351d2e4ac9864129650b6c00627a8ea6f 100644
+index 6b0390aba75731707ce48ea206b87974ffb15857..8c634c0748f0d447476d460ee2800f82d232d7ff 100644
--- a/Source/WebCore/dom/PointerEvent.cpp
+++ b/Source/WebCore/dom/PointerEvent.cpp
-@@ -27,9 +27,11 @@
- #include "PointerEvent.h"
+@@ -28,10 +28,13 @@
#include "EventNames.h"
+ #include "MouseEventTypes.h"
+#include "MouseEvent.h"
#include "Node.h"
- #include "PlatformMouseEvent.h"
- #include "PointerEventTypeNames.h"
+#include "PlatformTouchEvent.h"
- #include
+ #include "PointerEventTypeNames.h"
+ #include
+ #include
++#include
namespace WebCore {
-@@ -122,4 +124,51 @@ PointerEvent::PointerEvent(const AtomString& type, PointerID pointerId, const St
- PointerEvent::~PointerEvent() = default;
+@@ -293,4 +296,59 @@ void PointerEvent::receivedTarget()
+ predictedEvent->setTarget(this->target());
+ }
+#if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS_FAMILY) && !PLATFORM(WPE)
+
@@ -2645,26 +2636,34 @@ index c35c7851f168954a0c5265ea218a2173b7b079a8..500b267351d2e4ac9864129650b6c006
+ return nullAtom();
+}
+
-+Ref PointerEvent::create(const PlatformTouchEvent& event, unsigned index, bool isPrimary, Ref&& view, const IntPoint& touchDelta)
++Ref PointerEvent::create(const PlatformTouchEvent& event, const Vector[>& coalescedEvents, const Vector][>& predictedEvents, unsigned touchIndex, bool isPrimary, Ref&& view, const IntPoint& touchDelta)
++{
++ const auto& type = pointerEventType(event.touchPoints().at(touchIndex).state());
++ return adoptRef(*new PointerEvent(type, event, coalescedEvents, predictedEvents, typeCanBubble(type), typeIsCancelable(type), touchIndex, isPrimary, WTFMove(view), touchDelta));
++}
++
++Ref PointerEvent::create(const PlatformTouchEvent& event, const Vector][>& coalescedEvents, const Vector][>& predictedEvents, CanBubble canBubble, IsCancelable isCancelable, unsigned touchIndex, bool isPrimary, Ref&& view, const IntPoint& touchDelta)
+{
-+ const auto& type = pointerEventType(event.touchPoints().at(index).state());
-+ return adoptRef(*new PointerEvent(type, event, typeIsCancelable(type), index, isPrimary, WTFMove(view), touchDelta));
++ const auto& type = pointerEventType(event.touchPoints().at(touchIndex).state());
++ return adoptRef(*new PointerEvent(type, event, coalescedEvents, predictedEvents, canBubble, isCancelable, touchIndex, isPrimary, WTFMove(view), touchDelta));
+}
+
-+Ref PointerEvent::create(const AtomString& type, const PlatformTouchEvent& event, unsigned index, bool isPrimary, Ref&& view, const IntPoint& touchDelta)
++Ref PointerEvent::create(const AtomString& type, const PlatformTouchEvent& event, const Vector][>& coalescedEvents, const Vector][>& predictedEvents, unsigned touchIndex, bool isPrimary, Ref&& view, const IntPoint& touchDelta)
+{
-+ return adoptRef(*new PointerEvent(type, event, typeIsCancelable(type), index, isPrimary, WTFMove(view), touchDelta));
++ return adoptRef(*new PointerEvent(type, event, coalescedEvents, predictedEvents, typeCanBubble(type), typeIsCancelable(type), touchIndex, isPrimary, WTFMove(view), touchDelta));
+}
+
-+PointerEvent::PointerEvent(const AtomString& type, const PlatformTouchEvent& event, IsCancelable isCancelable, unsigned index, bool isPrimary, Ref&& view, const IntPoint& touchDelta)
-+ : MouseEvent(EventInterfaceType::PointerEvent, type, typeCanBubble(type), isCancelable, typeIsComposed(type), event.timestamp().approximateMonotonicTime(), WTFMove(view), 0,
-+ event.touchPoints().at(index).pos(), event.touchPoints().at(index).pos(), touchDelta.x(), touchDelta.y(), event.modifiers(), buttonForType(type), buttonsForType(type), nullptr, 0, SyntheticClickType::NoTap, IsSimulated::No, IsTrusted::Yes)
-+ , m_pointerId(event.touchPoints().at(index).id())
-+ , m_width(2 * event.touchPoints().at(index).radiusX())
-+ , m_height(2 * event.touchPoints().at(index).radiusY())
-+ , m_pressure(event.touchPoints().at(index).force())
++PointerEvent::PointerEvent(const AtomString& type, const PlatformTouchEvent& event, const Vector][>& coalescedEvents, const Vector][>& predictedEvents, CanBubble canBubble, IsCancelable isCancelable, unsigned touchIndex, bool isPrimary, Ref&& view, const IntPoint& touchDelta)
++ : MouseEvent(EventInterfaceType::PointerEvent, type, canBubble, isCancelable, typeIsComposed(type), event.timestamp().approximateMonotonicTime(), WTFMove(view), 0,
++ event.touchPoints().at(touchIndex).pos(), event.touchPoints().at(touchIndex).pos(), touchDelta.x(), touchDelta.y(), event.modifiers(), buttonForType(type), buttonsForType(type), nullptr, 0, SyntheticClickType::NoTap, { }, { }, IsSimulated::No, IsTrusted::Yes)
++ , m_pointerId(event.touchPoints().at(touchIndex).id())
++ , m_width(2 * event.touchPoints().at(touchIndex).radiusX())
++ , m_height(2 * event.touchPoints().at(touchIndex).radiusY())
++ , m_pressure(event.touchPoints().at(touchIndex).force())
+ , m_pointerType(touchPointerEventType())
+ , m_isPrimary(isPrimary)
++ , m_coalescedEvents(coalescedEvents)
++ , m_predictedEvents(predictedEvents)
+{
+}
+
@@ -2672,7 +2671,7 @@ index c35c7851f168954a0c5265ea218a2173b7b079a8..500b267351d2e4ac9864129650b6c006
+
} // namespace WebCore
diff --git a/Source/WebCore/dom/PointerEvent.h b/Source/WebCore/dom/PointerEvent.h
-index 261a8c7e8946cac87b9ebc5fc5e3b697f326b7f4..02645d3bdce44f40a648e720e99a6b296f371fb2 100644
+index b034595d01bb63f3d72183c427fcc14695339ae2..1886e4bbba04c6177fad1562c891f2aeff0a8247 100644
--- a/Source/WebCore/dom/PointerEvent.h
+++ b/Source/WebCore/dom/PointerEvent.h
@@ -34,6 +34,8 @@
@@ -2684,37 +2683,37 @@ index 261a8c7e8946cac87b9ebc5fc5e3b697f326b7f4..02645d3bdce44f40a648e720e99a6b29
#endif
#if ENABLE(TOUCH_EVENTS) && PLATFORM(WPE)
-@@ -86,7 +88,7 @@ public:
- static Ref create(const AtomString& type, MouseButton, const MouseEvent&, PointerID, const String& pointerType);
+@@ -94,7 +96,7 @@ public:
+ static Ref create(const AtomString& type, MouseButton, const MouseEvent&, PointerID, const String& pointerType, CanBubble, IsCancelable);
static Ref create(const AtomString& type, PointerID, const String& pointerType, IsPrimary = IsPrimary::No);
-#if ENABLE(TOUCH_EVENTS) && (PLATFORM(IOS_FAMILY) || PLATFORM(WPE))
+#if ENABLE(TOUCH_EVENTS)
- static Ref create(const PlatformTouchEvent&, unsigned touchIndex, bool isPrimary, Ref&&, const IntPoint& touchDelta = { });
- static Ref create(const AtomString& type, const PlatformTouchEvent&, unsigned touchIndex, bool isPrimary, Ref&&, const IntPoint& touchDelta = { });
- #endif
-@@ -140,7 +142,7 @@ private:
- PointerEvent(const AtomString&, Init&&);
- PointerEvent(const AtomString& type, MouseButton, const MouseEvent&, PointerID, const String& pointerType);
+ static Ref create(const PlatformTouchEvent&, const Vector][>& coalescedEvents, const Vector][>& predictedEvents, unsigned touchIndex, bool isPrimary, Ref&&, const IntPoint& touchDelta = { });
+ static Ref create(const PlatformTouchEvent&, const Vector][>& coalescedEvents, const Vector][>& predictedEvents, CanBubble, IsCancelable, unsigned touchIndex, bool isPrimary, Ref&& view, const IntPoint& touchDelta = { });
+ static Ref create(const AtomString& type, const PlatformTouchEvent&, const Vector][>& coalescedEvents, const Vector][>& predictedEvents, unsigned touchIndex, bool isPrimary, Ref&&, const IntPoint& touchDelta = { });
+@@ -173,7 +175,7 @@ private:
+ PointerEvent();
+ PointerEvent(const AtomString&, Init&&, IsTrusted);
PointerEvent(const AtomString& type, PointerID, const String& pointerType, IsPrimary);
-#if ENABLE(TOUCH_EVENTS) && (PLATFORM(IOS_FAMILY) || PLATFORM(WPE))
+#if ENABLE(TOUCH_EVENTS)
- PointerEvent(const AtomString& type, const PlatformTouchEvent&, IsCancelable isCancelable, unsigned touchIndex, bool isPrimary, Ref&&, const IntPoint& touchDelta = { });
+ PointerEvent(const AtomString& type, const PlatformTouchEvent&, const Vector][>& coalescedEvents, const Vector][>& predictedEvents, CanBubble canBubble, IsCancelable isCancelable, unsigned touchIndex, bool isPrimary, Ref&&, const IntPoint& touchDelta = { });
#endif
diff --git a/Source/WebCore/editing/libwpe/EditorLibWPE.cpp b/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
-index 7813532cc52d582c42aebc979a1ecd1137765f08..c01cbd53ad2430a6ffab9a80fc73e74a8523800a 100644
+index d0a3d5c048647b07772e1581c76c4eb60ecf41b0..bec324636991079264e620c0dfdaf9842ff585cd 100644
--- a/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
+++ b/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
-@@ -34,6 +34,7 @@
- #include "NotImplemented.h"
+@@ -35,6 +35,7 @@
#include "Pasteboard.h"
#include "Settings.h"
+ #include "SimpleRange.h"
+#include "WebContentReader.h"
#include "markup.h"
namespace WebCore {
-@@ -99,6 +100,14 @@ void Editor::platformPasteFont()
+@@ -100,6 +101,14 @@ void Editor::platformPasteFont()
{
}
@@ -2730,10 +2729,10 @@ index 7813532cc52d582c42aebc979a1ecd1137765f08..c01cbd53ad2430a6ffab9a80fc73e74a
#endif // USE(LIBWPE)
diff --git a/Source/WebCore/html/FileInputType.cpp b/Source/WebCore/html/FileInputType.cpp
-index dde92a4942d3f6679b6ef2455fa15d023544dfbc..c6ed18b40209195d1cf5c7785091d37fd40dad80 100644
+index d5234a678a77e24ce0a95fe08740416ab8acbadb..c9a42fd354e88c5a8c3ee53974442ec9d4cb1224 100644
--- a/Source/WebCore/html/FileInputType.cpp
+++ b/Source/WebCore/html/FileInputType.cpp
-@@ -37,6 +37,7 @@
+@@ -38,6 +38,7 @@
#include "HTMLNames.h"
#include "Icon.h"
#include "InputTypeNames.h"
@@ -2741,52 +2740,41 @@ index dde92a4942d3f6679b6ef2455fa15d023544dfbc..c6ed18b40209195d1cf5c7785091d37f
#include "LocalFrame.h"
#include "LocalizedStrings.h"
#include "MIMETypeRegistry.h"
-@@ -157,6 +158,11 @@ void FileInputType::handleDOMActivateEvent(Event& event)
- if (input.isDisabledFormControl())
+@@ -161,6 +162,11 @@ void FileInputType::handleDOMActivateEvent(Event& event)
+ if (protectedElement()->isDisabledFormControl())
return;
+ bool intercept = false;
-+ InspectorInstrumentation::runOpenPanel(input.document().frame(), element(), &intercept);
++ InspectorInstrumentation::runOpenPanel(element()->document().frame(), element(), &intercept);
+ if (intercept)
+ return;
+
if (!UserGestureIndicator::processingUserGesture())
return;
-@@ -345,7 +351,9 @@ void FileInputType::setFiles(RefPtr&& files, RequestIcon shouldRequest
- pathsChanged = true;
- else {
- for (unsigned i = 0; i < length; ++i) {
-- if (files->file(i).path() != m_fileList->file(i).path() || !FileSystem::fileIDsAreEqual(files->file(i).fileID(), m_fileList->file(i).fileID())) {
-+ if (files->file(i).path() != m_fileList->file(i).path() || !FileSystem::fileIDsAreEqual(files->file(i).fileID(), m_fileList->file(i).fileID()) ||
-+ // Files created from Blob have empty path.
-+ (files->file(i).path().isEmpty() && files->file(i).name() != m_fileList->file(i).name())) {
- pathsChanged = true;
- break;
- }
diff --git a/Source/WebCore/inspector/InspectorController.cpp b/Source/WebCore/inspector/InspectorController.cpp
-index 3844ae7bab48f46b77cfd85530e4ab19392a71dd..8d705215457f89711e78e3bee9c983d131b08245 100644
+index 48efc5356601313e907846283f753e44d6a0f983..f153fd7da52da98d033e4070d79c64d4a38ff197 100644
--- a/Source/WebCore/inspector/InspectorController.cpp
+++ b/Source/WebCore/inspector/InspectorController.cpp
-@@ -287,6 +287,8 @@ void InspectorController::disconnectFrontend(FrontendChannel& frontendChannel)
+@@ -296,6 +296,8 @@ void InspectorController::disconnectFrontend(FrontendChannel& frontendChannel)
// Unplug all instrumentations since they aren't needed now.
InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get());
+
-+ m_pauseWhenShown = false;
++ m_pauseOnStart = PauseCondition::DONT_PAUSE;
}
m_inspectorClient->frontendCountChanged(m_frontendRouter->frontendCount());
-@@ -306,6 +308,8 @@ void InspectorController::disconnectAllFrontends()
+@@ -315,6 +317,8 @@ void InspectorController::disconnectAllFrontends()
// The frontend should call setInspectorFrontendClient(nullptr) under closeWindow().
ASSERT(!m_inspectorFrontendClient);
-+ m_pauseWhenShown = false;
++ m_pauseOnStart = PauseCondition::DONT_PAUSE;
+
if (!m_frontendRouter->hasFrontends())
return;
-@@ -394,8 +398,8 @@ void InspectorController::inspect(Node* node)
+@@ -398,8 +402,8 @@ void InspectorController::inspect(Node* node)
if (!enabled())
return;
@@ -2797,25 +2785,35 @@ index 3844ae7bab48f46b77cfd85530e4ab19392a71dd..8d705215457f89711e78e3bee9c983d1
ensureDOMAgent().inspect(node);
}
-@@ -538,4 +542,24 @@ void InspectorController::didComposite(LocalFrame& frame)
+@@ -542,4 +546,34 @@ void InspectorController::didComposite(LocalFrame& frame)
InspectorInstrumentation::didComposite(frame);
}
-+void InspectorController::pauseWhenShown()
++void InspectorController::pauseOnStart(PauseCondition condition)
+{
-+ m_pauseWhenShown = true;
++ m_pauseOnStart = condition;
+}
+
+void InspectorController::resumeIfPausedInNewWindow()
+{
-+ m_pauseWhenShown = false;
++ m_pauseOnStart = PauseCondition::DONT_PAUSE;
+}
+
-+void InspectorController::didShowNewWindow()
++void InspectorController::didFinishPageCreation()
+{
-+ if (!m_pauseWhenShown)
-+ return;
-+ while (m_pauseWhenShown) {
++ if (m_pauseOnStart == PauseCondition::WHEN_CREATION_FINISHED)
++ runLoopWhilePaused();
++}
++
++void InspectorController::didShowPage()
++{
++ if (m_pauseOnStart == PauseCondition::WHEN_SHOWN)
++ runLoopWhilePaused();
++}
++
++void InspectorController::runLoopWhilePaused()
++{
++ while (m_pauseOnStart != PauseCondition::DONT_PAUSE) {
+ if (RunLoop::cycle() == RunLoop::CycleResult::Stop)
+ break;
+ }
@@ -2823,33 +2821,43 @@ index 3844ae7bab48f46b77cfd85530e4ab19392a71dd..8d705215457f89711e78e3bee9c983d1
+
} // namespace WebCore
diff --git a/Source/WebCore/inspector/InspectorController.h b/Source/WebCore/inspector/InspectorController.h
-index 3a981b5bf5ca0bbf4d1c9f0b125564742cd8cad9..f8fc2ca6700461627933f149c5837075226a51a9 100644
+index 4f5c1e836876710a554455ec53733f72db63de58..774c4a66af84664a7a83ba0790d147f7bbb4236a 100644
--- a/Source/WebCore/inspector/InspectorController.h
+++ b/Source/WebCore/inspector/InspectorController.h
-@@ -101,6 +101,10 @@ public:
+@@ -106,6 +106,12 @@ public:
WEBCORE_EXPORT void willComposite(LocalFrame&);
WEBCORE_EXPORT void didComposite(LocalFrame&);
-+ WEBCORE_EXPORT void pauseWhenShown();
++ enum class PauseCondition { DONT_PAUSE, WHEN_SHOWN, WHEN_CREATION_FINISHED };
++ WEBCORE_EXPORT void pauseOnStart(PauseCondition);
+ WEBCORE_EXPORT void resumeIfPausedInNewWindow();
-+ WEBCORE_EXPORT void didShowNewWindow();
++ WEBCORE_EXPORT void didShowPage();
++ WEBCORE_EXPORT void didFinishPageCreation();
+
// Testing support.
- WEBCORE_EXPORT bool isUnderTest() const;
+ bool isUnderTest() const { return m_isUnderTest; }
void setIsUnderTest(bool isUnderTest) { m_isUnderTest = isUnderTest; }
-@@ -154,6 +158,7 @@ private:
+@@ -136,6 +142,7 @@ private:
+
+ PageAgentContext pageAgentContext();
+ void createLazyAgents();
++ void runLoopWhilePaused();
+
+ WeakRef m_page;
+ Ref m_instrumentingAgents;
+@@ -159,6 +166,7 @@ private:
bool m_isAutomaticInspection { false };
bool m_pauseAfterInitialization = { false };
bool m_didCreateLazyAgents { false };
-+ bool m_pauseWhenShown { false };
++ PauseCondition m_pauseOnStart { PauseCondition::DONT_PAUSE };
};
} // namespace WebCore
diff --git a/Source/WebCore/inspector/InspectorInstrumentation.cpp b/Source/WebCore/inspector/InspectorInstrumentation.cpp
-index 8c7b186092793bf301511be969030c92674ce211..bcad9353cd568ed435b42d5b9d505b3ca973aaea 100644
+index 1c660f381ad7e9a9201aeced2906f39135e810f6..6c47abc2f32b39fd5c0bf9048b9c1224959ba08c 100644
--- a/Source/WebCore/inspector/InspectorInstrumentation.cpp
+++ b/Source/WebCore/inspector/InspectorInstrumentation.cpp
-@@ -597,6 +597,12 @@ void InspectorInstrumentation::applyUserAgentOverrideImpl(InstrumentingAgents& i
+@@ -595,6 +595,12 @@ void InspectorInstrumentation::applyUserAgentOverrideImpl(InstrumentingAgents& i
pageAgent->applyUserAgentOverride(userAgent);
}
@@ -2862,7 +2870,7 @@ index 8c7b186092793bf301511be969030c92674ce211..bcad9353cd568ed435b42d5b9d505b3c
void InspectorInstrumentation::applyEmulatedMediaImpl(InstrumentingAgents& instrumentingAgents, AtomString& media)
{
if (auto* pageAgent = instrumentingAgents.enabledPageAgent())
-@@ -680,6 +686,12 @@ void InspectorInstrumentation::didFailLoadingImpl(InstrumentingAgents& instrumen
+@@ -678,6 +684,12 @@ void InspectorInstrumentation::didFailLoadingImpl(InstrumentingAgents& instrumen
consoleAgent->didFailLoading(identifier, error); // This should come AFTER resource notification, front-end relies on this.
}
@@ -2875,7 +2883,7 @@ index 8c7b186092793bf301511be969030c92674ce211..bcad9353cd568ed435b42d5b9d505b3c
void InspectorInstrumentation::willLoadXHRSynchronouslyImpl(InstrumentingAgents& instrumentingAgents)
{
if (auto* networkAgent = instrumentingAgents.enabledNetworkAgent())
-@@ -712,20 +724,17 @@ void InspectorInstrumentation::didReceiveScriptResponseImpl(InstrumentingAgents&
+@@ -710,20 +722,17 @@ void InspectorInstrumentation::didReceiveScriptResponseImpl(InstrumentingAgents&
void InspectorInstrumentation::domContentLoadedEventFiredImpl(InstrumentingAgents& instrumentingAgents, LocalFrame& frame)
{
@@ -2899,7 +2907,7 @@ index 8c7b186092793bf301511be969030c92674ce211..bcad9353cd568ed435b42d5b9d505b3c
}
void InspectorInstrumentation::frameDetachedFromParentImpl(InstrumentingAgents& instrumentingAgents, LocalFrame& frame)
-@@ -808,12 +817,6 @@ void InspectorInstrumentation::frameDocumentUpdatedImpl(InstrumentingAgents& ins
+@@ -803,12 +812,6 @@ void InspectorInstrumentation::frameDocumentUpdatedImpl(InstrumentingAgents& ins
pageDOMDebuggerAgent->frameDocumentUpdated(frame);
}
@@ -2912,7 +2920,7 @@ index 8c7b186092793bf301511be969030c92674ce211..bcad9353cd568ed435b42d5b9d505b3c
void InspectorInstrumentation::frameStartedLoadingImpl(InstrumentingAgents& instrumentingAgents, LocalFrame& frame)
{
if (frame.isMainFrame()) {
-@@ -844,10 +847,10 @@ void InspectorInstrumentation::frameStoppedLoadingImpl(InstrumentingAgents& inst
+@@ -839,10 +842,10 @@ void InspectorInstrumentation::frameStoppedLoadingImpl(InstrumentingAgents& inst
inspectorPageAgent->frameStoppedLoading(frame);
}
@@ -2925,7 +2933,7 @@ index 8c7b186092793bf301511be969030c92674ce211..bcad9353cd568ed435b42d5b9d505b3c
}
void InspectorInstrumentation::frameClearedScheduledNavigationImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
-@@ -862,6 +865,12 @@ void InspectorInstrumentation::accessibilitySettingsDidChangeImpl(InstrumentingA
+@@ -857,6 +860,12 @@ void InspectorInstrumentation::accessibilitySettingsDidChangeImpl(InstrumentingA
inspectorPageAgent->accessibilitySettingsDidChange();
}
@@ -2935,10 +2943,23 @@ index 8c7b186092793bf301511be969030c92674ce211..bcad9353cd568ed435b42d5b9d505b3c
+ inspectorPageAgent->didNavigateWithinPage(frame);
+}
+
- #if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
+ #if ENABLE(DARK_MODE_CSS)
void InspectorInstrumentation::defaultAppearanceDidChangeImpl(InstrumentingAgents& instrumentingAgents)
{
-@@ -1050,6 +1059,12 @@ void InspectorInstrumentation::consoleStopRecordingCanvasImpl(InstrumentingAgent
+@@ -909,6 +918,12 @@ void InspectorInstrumentation::interceptResponseImpl(InstrumentingAgents& instru
+ networkAgent->interceptResponse(response, identifier, WTFMove(handler));
+ }
+
++void InspectorInstrumentation::setStoppingLoadingDueToProcessSwapImpl(InstrumentingAgents& instrumentingAgents, bool value)
++{
++ if (auto* networkAgent = instrumentingAgents.enabledNetworkAgent())
++ networkAgent->setStoppingLoadingDueToProcessSwap(value);
++}
++
+ // JavaScriptCore InspectorDebuggerAgent should know Console MessageTypes.
+ static bool isConsoleAssertMessage(MessageSource source, MessageType type)
+ {
+@@ -1027,6 +1042,12 @@ void InspectorInstrumentation::consoleStopRecordingCanvasImpl(InstrumentingAgent
canvasAgent->consoleStopRecordingCanvas(context);
}
@@ -2948,10 +2969,10 @@ index 8c7b186092793bf301511be969030c92674ce211..bcad9353cd568ed435b42d5b9d505b3c
+ pageRuntimeAgent->bindingCalled(globalObject, name, arg);
+}
+
- void InspectorInstrumentation::didOpenDatabaseImpl(InstrumentingAgents& instrumentingAgents, Database& database)
+ void InspectorInstrumentation::didDispatchDOMStorageEventImpl(InstrumentingAgents& instrumentingAgents, const String& key, const String& oldValue, const String& newValue, StorageType storageType, const SecurityOrigin& securityOrigin)
{
- if (auto* databaseAgent = instrumentingAgents.enabledDatabaseAgent())
-@@ -1356,6 +1371,36 @@ void InspectorInstrumentation::renderLayerDestroyedImpl(InstrumentingAgents& ins
+ if (auto* domStorageAgent = instrumentingAgents.enabledDOMStorageAgent())
+@@ -1317,6 +1338,36 @@ void InspectorInstrumentation::renderLayerDestroyedImpl(InstrumentingAgents& ins
layerTreeAgent->renderLayerDestroyed(renderLayer);
}
@@ -2988,7 +3009,7 @@ index 8c7b186092793bf301511be969030c92674ce211..bcad9353cd568ed435b42d5b9d505b3c
InstrumentingAgents& InspectorInstrumentation::instrumentingAgents(WorkerOrWorkletGlobalScope& globalScope)
{
return globalScope.inspectorController().m_instrumentingAgents;
-@@ -1367,6 +1412,13 @@ InstrumentingAgents& InspectorInstrumentation::instrumentingAgents(Page& page)
+@@ -1333,6 +1384,13 @@ InstrumentingAgents& InspectorInstrumentation::instrumentingAgents(Page& page)
return page.inspectorController().m_instrumentingAgents.get();
}
@@ -3003,7 +3024,7 @@ index 8c7b186092793bf301511be969030c92674ce211..bcad9353cd568ed435b42d5b9d505b3c
{
// Using RefPtr makes us hit the m_inRemovedLastRefFunction assert.
diff --git a/Source/WebCore/inspector/InspectorInstrumentation.h b/Source/WebCore/inspector/InspectorInstrumentation.h
-index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114fca4d82a 100644
+index ed15dcc0dd1eb8d22dc48d8c6515b2258db574c5..c297c2d0e61b8ca1f881bb7942c463626bf0118f 100644
--- a/Source/WebCore/inspector/InspectorInstrumentation.h
+++ b/Source/WebCore/inspector/InspectorInstrumentation.h
@@ -31,6 +31,7 @@
@@ -3030,7 +3051,7 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114
class HTTPHeaderMap;
class InspectorTimelineAgent;
class InstrumentingAgents;
-@@ -192,6 +195,7 @@ public:
+@@ -197,6 +200,7 @@ public:
static void didRecalculateStyle(Document&);
static void didScheduleStyleRecalculation(Document&);
static void applyUserAgentOverride(LocalFrame&, String&);
@@ -3038,39 +3059,47 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114
static void applyEmulatedMedia(LocalFrame&, AtomString&);
static void flexibleBoxRendererBeganLayout(const RenderObject&);
-@@ -204,6 +208,7 @@ public:
+@@ -209,6 +213,7 @@ public:
static void didReceiveData(LocalFrame*, ResourceLoaderIdentifier, const SharedBuffer*, int encodedDataLength);
static void didFinishLoading(LocalFrame*, DocumentLoader*, ResourceLoaderIdentifier, const NetworkLoadMetrics&, ResourceLoader*);
static void didFailLoading(LocalFrame*, DocumentLoader*, ResourceLoaderIdentifier, const ResourceError&);
+ static void didReceiveMainResourceError(LocalFrame&, const ResourceError&);
- static void willSendRequest(WorkerOrWorkletGlobalScope&, ResourceLoaderIdentifier, ResourceRequest&);
- static void didReceiveResourceResponse(WorkerOrWorkletGlobalScope&, ResourceLoaderIdentifier, const ResourceResponse&);
-@@ -230,13 +235,13 @@ public:
+ static void willSendRequest(ServiceWorkerGlobalScope&, ResourceLoaderIdentifier, ResourceRequest&);
+ static void didReceiveResourceResponse(ServiceWorkerGlobalScope&, ResourceLoaderIdentifier, const ResourceResponse&);
+@@ -235,13 +240,13 @@ public:
static void frameDetachedFromParent(LocalFrame&);
static void didCommitLoad(LocalFrame&, DocumentLoader*);
static void frameDocumentUpdated(LocalFrame&);
- static void loaderDetachedFromFrame(LocalFrame&, DocumentLoader&);
static void frameStartedLoading(LocalFrame&);
static void frameStoppedLoading(LocalFrame&);
- static void didCompleteRenderingFrame(LocalFrame&);
+ static void didCompleteRenderingFrame(Frame&);
- static void frameScheduledNavigation(Frame&, Seconds delay);
+ static void frameScheduledNavigation(Frame&, Seconds delay, bool targetIsCurrentFrame);
static void frameClearedScheduledNavigation(Frame&);
static void accessibilitySettingsDidChange(Page&);
+ static void didNavigateWithinPage(LocalFrame&);
- #if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
+ #if ENABLE(DARK_MODE_CSS)
static void defaultAppearanceDidChange(Page&);
#endif
-@@ -268,6 +273,7 @@ public:
- static void stopProfiling(Page&, JSC::JSGlobalObject*, const String& title);
+@@ -252,6 +257,7 @@ public:
+ static bool shouldInterceptResponse(const LocalFrame&, const ResourceResponse&);
+ static void interceptRequest(ResourceLoader&, Function&&);
+ static void interceptResponse(const LocalFrame&, const ResourceResponse&, ResourceLoaderIdentifier, CompletionHandler)>&&);
++ static void setStoppingLoadingDueToProcessSwap(Page*, bool);
+
+ static void addMessageToConsole(Page&, std::unique_ptr);
+ static void addMessageToConsole(WorkerOrWorkletGlobalScope&, std::unique_ptr);
+@@ -277,6 +283,7 @@ public:
+ static void stopProfiling(WorkerOrWorkletGlobalScope&, const String& title);
static void consoleStartRecordingCanvas(CanvasRenderingContext&, JSC::JSGlobalObject&, JSC::JSObject* options);
static void consoleStopRecordingCanvas(CanvasRenderingContext&);
+ static void bindingCalled(Page& , JSC::JSGlobalObject*, const String& name, const String& arg);
- static void performanceMark(ScriptExecutionContext&, const String&, std::optional, LocalFrame*);
+ static void performanceMark(ScriptExecutionContext&, const String&, std::optional);
-@@ -326,6 +332,12 @@ public:
+@@ -330,6 +337,12 @@ public:
static void layerTreeDidChange(Page*);
static void renderLayerDestroyed(Page*, const RenderLayer&);
@@ -3083,7 +3112,7 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114
static void frontendCreated();
static void frontendDeleted();
static bool hasFrontends() { return InspectorInstrumentationPublic::hasFrontends(); }
-@@ -342,6 +354,8 @@ public:
+@@ -346,6 +359,8 @@ public:
static void registerInstrumentingAgents(InstrumentingAgents&);
static void unregisterInstrumentingAgents(InstrumentingAgents&);
@@ -3092,7 +3121,7 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114
private:
static void didClearWindowObjectInWorldImpl(InstrumentingAgents&, LocalFrame&, DOMWrapperWorld&);
static bool isDebuggerPausedImpl(InstrumentingAgents&);
-@@ -421,6 +435,7 @@ private:
+@@ -427,6 +442,7 @@ private:
static void didRecalculateStyleImpl(InstrumentingAgents&);
static void didScheduleStyleRecalculationImpl(InstrumentingAgents&, Document&);
static void applyUserAgentOverrideImpl(InstrumentingAgents&, String&);
@@ -3100,7 +3129,7 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114
static void applyEmulatedMediaImpl(InstrumentingAgents&, AtomString&);
static void flexibleBoxRendererBeganLayoutImpl(InstrumentingAgents&, const RenderObject&);
-@@ -435,6 +450,7 @@ private:
+@@ -441,6 +457,7 @@ private:
static void didReceiveDataImpl(InstrumentingAgents&, ResourceLoaderIdentifier, const SharedBuffer*, int encodedDataLength);
static void didFinishLoadingImpl(InstrumentingAgents&, ResourceLoaderIdentifier, DocumentLoader*, const NetworkLoadMetrics&, ResourceLoader*);
static void didFailLoadingImpl(InstrumentingAgents&, ResourceLoaderIdentifier, DocumentLoader*, const ResourceError&);
@@ -3108,7 +3137,7 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114
static void willLoadXHRSynchronouslyImpl(InstrumentingAgents&);
static void didLoadXHRSynchronouslyImpl(InstrumentingAgents&);
static void scriptImportedImpl(InstrumentingAgents&, ResourceLoaderIdentifier, const String& sourceString);
-@@ -445,13 +461,13 @@ private:
+@@ -451,13 +468,13 @@ private:
static void frameDetachedFromParentImpl(InstrumentingAgents&, LocalFrame&);
static void didCommitLoadImpl(InstrumentingAgents&, LocalFrame&, DocumentLoader*);
static void frameDocumentUpdatedImpl(InstrumentingAgents&, LocalFrame&);
@@ -3121,18 +3150,26 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114
static void frameClearedScheduledNavigationImpl(InstrumentingAgents&, Frame&);
static void accessibilitySettingsDidChangeImpl(InstrumentingAgents&);
+ static void didNavigateWithinPageImpl(InstrumentingAgents&, LocalFrame&);
- #if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
+ #if ENABLE(DARK_MODE_CSS)
static void defaultAppearanceDidChangeImpl(InstrumentingAgents&);
#endif
-@@ -478,6 +494,7 @@ private:
- static void stopProfilingImpl(InstrumentingAgents&, JSC::JSGlobalObject*, const String& title);
+@@ -468,6 +485,7 @@ private:
+ static bool shouldInterceptResponseImpl(InstrumentingAgents&, const ResourceResponse&);
+ static void interceptRequestImpl(InstrumentingAgents&, ResourceLoader&, Function&&);
+ static void interceptResponseImpl(InstrumentingAgents&, const ResourceResponse&, ResourceLoaderIdentifier, CompletionHandler)>&&);
++ static void setStoppingLoadingDueToProcessSwapImpl(InstrumentingAgents&, bool);
+
+ static void addMessageToConsoleImpl(InstrumentingAgents&, std::unique_ptr);
+
+@@ -482,6 +500,7 @@ private:
+ static void stopProfilingImpl(InstrumentingAgents&, const String& title);
static void consoleStartRecordingCanvasImpl(InstrumentingAgents&, CanvasRenderingContext&, JSC::JSGlobalObject&, JSC::JSObject* options);
static void consoleStopRecordingCanvasImpl(InstrumentingAgents&, CanvasRenderingContext&);
+ static void bindingCalledImpl(InstrumentingAgents&, JSC::JSGlobalObject*, const String& name, const String& arg);
- static void performanceMarkImpl(InstrumentingAgents&, const String& label, std::optional, LocalFrame*);
+ static void performanceMarkImpl(InstrumentingAgents&, const String& label, std::optional);
-@@ -536,6 +553,12 @@ private:
+@@ -535,6 +554,12 @@ private:
static void layerTreeDidChangeImpl(InstrumentingAgents&);
static void renderLayerDestroyedImpl(InstrumentingAgents&, const RenderLayer&);
@@ -3144,8 +3181,8 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114
+
static InstrumentingAgents& instrumentingAgents(Page&);
static InstrumentingAgents& instrumentingAgents(WorkerOrWorkletGlobalScope&);
-
-@@ -1068,6 +1091,13 @@ inline void InspectorInstrumentation::applyUserAgentOverride(LocalFrame& frame,
+ static InstrumentingAgents& instrumentingAgents(ServiceWorkerGlobalScope&);
+@@ -1094,6 +1119,13 @@ inline void InspectorInstrumentation::applyUserAgentOverride(LocalFrame& frame,
applyUserAgentOverrideImpl(*agents, userAgent);
}
@@ -3159,7 +3196,7 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114
inline void InspectorInstrumentation::applyEmulatedMedia(LocalFrame& frame, AtomString& media)
{
FAST_RETURN_IF_NO_FRONTENDS(void());
-@@ -1170,6 +1200,13 @@ inline void InspectorInstrumentation::didFailLoading(WorkerOrWorkletGlobalScope&
+@@ -1196,6 +1228,13 @@ inline void InspectorInstrumentation::didFailLoading(ServiceWorkerGlobalScope& g
didFailLoadingImpl(instrumentingAgents(globalScope), identifier, nullptr, error);
}
@@ -3173,7 +3210,7 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114
inline void InspectorInstrumentation::continueAfterXFrameOptionsDenied(LocalFrame& frame, ResourceLoaderIdentifier identifier, DocumentLoader& loader, const ResourceResponse& response)
{
// Treat the same as didReceiveResponse.
-@@ -1260,13 +1297,6 @@ inline void InspectorInstrumentation::frameDocumentUpdated(LocalFrame& frame)
+@@ -1286,13 +1325,6 @@ inline void InspectorInstrumentation::frameDocumentUpdated(LocalFrame& frame)
frameDocumentUpdatedImpl(*agents, frame);
}
@@ -3187,7 +3224,7 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114
inline void InspectorInstrumentation::frameStartedLoading(LocalFrame& frame)
{
FAST_RETURN_IF_NO_FRONTENDS(void());
-@@ -1288,11 +1318,11 @@ inline void InspectorInstrumentation::frameStoppedLoading(LocalFrame& frame)
+@@ -1314,11 +1346,11 @@ inline void InspectorInstrumentation::frameStoppedLoading(LocalFrame& frame)
frameStoppedLoadingImpl(*agents, frame);
}
@@ -3201,7 +3238,7 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114
}
inline void InspectorInstrumentation::frameClearedScheduledNavigation(Frame& frame)
-@@ -1308,6 +1338,13 @@ inline void InspectorInstrumentation::accessibilitySettingsDidChange(Page& page)
+@@ -1334,6 +1366,13 @@ inline void InspectorInstrumentation::accessibilitySettingsDidChange(Page& page)
accessibilitySettingsDidChangeImpl(instrumentingAgents(page));
}
@@ -3212,11 +3249,25 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114
+ didNavigateWithinPageImpl(*agents, frame);
+}
+
- #if ENABLE(DARK_MODE_CSS) || HAVE(OS_DARK_MODE_SUPPORT)
+ #if ENABLE(DARK_MODE_CSS)
inline void InspectorInstrumentation::defaultAppearanceDidChange(Page& page)
{
-@@ -1696,6 +1733,11 @@ inline void InspectorInstrumentation::performanceMark(ScriptExecutionContext& co
- performanceMarkImpl(*agents, label, WTFMove(startTime), frame);
+@@ -1386,6 +1425,13 @@ inline void InspectorInstrumentation::interceptResponse(const LocalFrame& frame,
+ interceptResponseImpl(*agents, response, identifier, WTFMove(handler));
+ }
+
++inline void InspectorInstrumentation::setStoppingLoadingDueToProcessSwap(Page* page, bool value)
++{
++ ASSERT(InspectorInstrumentationPublic::hasFrontends());
++ if (auto* agents = instrumentingAgents(page))
++ setStoppingLoadingDueToProcessSwapImpl(*agents, value);
++}
++
+ inline void InspectorInstrumentation::didDispatchDOMStorageEvent(Page& page, const String& key, const String& oldValue, const String& newValue, StorageType storageType, const SecurityOrigin& securityOrigin)
+ {
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+@@ -1726,6 +1772,11 @@ inline void InspectorInstrumentation::performanceMark(ScriptExecutionContext& co
+ performanceMarkImpl(*agents, label, WTFMove(startTime));
}
+inline void InspectorInstrumentation::bindingCalled(Page& page, JSC::JSGlobalObject* globalObject, const String& name, const String& arg)
@@ -3224,10 +3275,10 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114
+ bindingCalledImpl(instrumentingAgents(page), globalObject, name, arg);
+}
+
- inline void InspectorInstrumentation::didRequestAnimationFrame(Document& document, int callbackId)
+ inline void InspectorInstrumentation::didRequestAnimationFrame(ScriptExecutionContext& scriptExecutionContext, int callbackId)
{
FAST_RETURN_IF_NO_FRONTENDS(void());
-@@ -1752,6 +1794,42 @@ inline void InspectorInstrumentation::renderLayerDestroyed(Page* page, const Ren
+@@ -1782,6 +1833,42 @@ inline void InspectorInstrumentation::renderLayerDestroyed(Page* page, const Ren
renderLayerDestroyedImpl(*agents, renderLayer);
}
@@ -3270,26 +3321,86 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114
inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgents(ScriptExecutionContext* context)
{
return context ? instrumentingAgents(*context) : nullptr;
+diff --git a/Source/WebCore/inspector/InspectorInstrumentationWebKit.cpp b/Source/WebCore/inspector/InspectorInstrumentationWebKit.cpp
+index a67a1244fa526ad5759068e97e0d220f59565d6e..0048589109fccb9472fe35a410337771b1063d72 100644
+--- a/Source/WebCore/inspector/InspectorInstrumentationWebKit.cpp
++++ b/Source/WebCore/inspector/InspectorInstrumentationWebKit.cpp
+@@ -50,4 +50,9 @@ void InspectorInstrumentationWebKit::interceptResponseInternal(const LocalFrame&
+ InspectorInstrumentation::interceptResponse(frame, response, identifier, WTFMove(handler));
+ }
+
++void InspectorInstrumentationWebKit::setStoppingLoadingDueToProcessSwapInternal(Page* page, bool value)
++{
++ InspectorInstrumentation::setStoppingLoadingDueToProcessSwap(page, value);
++}
++
+ } // namespace WebCore
+diff --git a/Source/WebCore/inspector/InspectorInstrumentationWebKit.h b/Source/WebCore/inspector/InspectorInstrumentationWebKit.h
+index c028341e84e59a6b1b16107fd74feb21f70b12ab..d385418ac34e8f315f201801a2c65226c8f6fee2 100644
+--- a/Source/WebCore/inspector/InspectorInstrumentationWebKit.h
++++ b/Source/WebCore/inspector/InspectorInstrumentationWebKit.h
+@@ -33,6 +33,7 @@
+ namespace WebCore {
+
+ class LocalFrame;
++class Page;
+ class ResourceLoader;
+ class ResourceRequest;
+ class ResourceResponse;
+@@ -44,12 +45,14 @@ public:
+ static bool shouldInterceptResponse(const LocalFrame*, const ResourceResponse&);
+ static void interceptRequest(ResourceLoader&, Function&&);
+ static void interceptResponse(const LocalFrame*, const ResourceResponse&, ResourceLoaderIdentifier, CompletionHandler)>&&);
++ static void setStoppingLoadingDueToProcessSwap(Page*, bool);
+
+ private:
+ static bool shouldInterceptRequestInternal(const ResourceLoader&);
+ static bool shouldInterceptResponseInternal(const LocalFrame&, const ResourceResponse&);
+ static void interceptRequestInternal(ResourceLoader&, Function&&);
+ static void interceptResponseInternal(const LocalFrame&, const ResourceResponse&, ResourceLoaderIdentifier, CompletionHandler)>&&);
++ static void setStoppingLoadingDueToProcessSwapInternal(Page*, bool);
+ };
+
+ inline bool InspectorInstrumentationWebKit::shouldInterceptRequest(const ResourceLoader& loader)
+@@ -79,4 +82,10 @@ inline void InspectorInstrumentationWebKit::interceptResponse(const LocalFrame*
+ interceptResponseInternal(*frame, response, identifier, WTFMove(handler));
+ }
+
++inline void InspectorInstrumentationWebKit::setStoppingLoadingDueToProcessSwap(Page* page, bool value)
++{
++ FAST_RETURN_IF_NO_FRONTENDS(void());
++ setStoppingLoadingDueToProcessSwapInternal(page, value);
++}
++
+ }
diff --git a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
-index a5167242b6b1ee9d6ccfcd81ef86a5729882d3a4..d64c560f86db46786ba47fe55654c140efd1d31b 100644
+index 94492280fc724f299655a5df34492f929d82c57c..af0aafa701a9c697650aad2d86ddcf6b3022dcc5 100644
--- a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
+++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
-@@ -65,10 +65,14 @@
+@@ -54,6 +54,7 @@
+ #include "Cookie.h"
+ #include "CookieJar.h"
+ #include "CustomElementRegistry.h"
++#include "DirectoryFileListCreator.h"
+ #include "DOMEditor.h"
+ #include "DOMException.h"
+ #include "DOMPatchSupport.h"
+@@ -65,9 +66,14 @@
#include "Event.h"
#include "EventListener.h"
#include "EventNames.h"
+#include "File.h"
++#include
+#include "FileList.h"
- #include "FrameTree.h"
- #include "FullscreenManager.h"
+#include "FloatQuad.h"
+ #include "FrameTree.h"
#include "HTMLElement.h"
#include "HTMLFrameOwnerElement.h"
+#include "HTMLInputElement.h"
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
#include "HTMLScriptElement.h"
-@@ -102,12 +106,14 @@
+@@ -102,12 +108,14 @@
#include "Pasteboard.h"
#include "PseudoElement.h"
#include "RenderGrid.h"
@@ -3304,7 +3415,7 @@ index a5167242b6b1ee9d6ccfcd81ef86a5729882d3a4..d64c560f86db46786ba47fe55654c140
#include "StaticNodeList.h"
#include "StyleProperties.h"
#include "StyleResolver.h"
-@@ -145,7 +151,8 @@ using namespace HTMLNames;
+@@ -149,7 +157,8 @@ using namespace HTMLNames;
static const size_t maxTextSize = 10000;
static const UChar horizontalEllipsisUChar[] = { horizontalEllipsis, 0 };
@@ -3314,7 +3425,7 @@ index a5167242b6b1ee9d6ccfcd81ef86a5729882d3a4..d64c560f86db46786ba47fe55654c140
{
if (!colorObject)
return std::nullopt;
-@@ -164,7 +171,7 @@ static std::optional]