mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 98de185e53 | |||
| 0fb455f72e | |||
| 67bb310376 | |||
| a9460d08a0 | |||
| afc057ee92 | |||
| 0fffe5389f |
@@ -13,7 +13,7 @@ jobs:
|
||||
assistant_to_the_branch_manager:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: angular/dev-infra/github-actions/branch-manager@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
- uses: alessbell/pull-request-comment-branch@aad01d65d6982b8eacabed5e9a684cd8ceb98da6 # v1.1
|
||||
id: comment-branch
|
||||
|
||||
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
with:
|
||||
# Specify repository as the PR branch might be from a fork.
|
||||
repository: ${{steps.comment-branch.outputs.head_owner}}/${{steps.comment-branch.outputs.head_repo}}
|
||||
|
||||
+2
-183
@@ -5,7 +5,7 @@ on:
|
||||
branches:
|
||||
- main
|
||||
- '[0-9]+.[0-9]+.x'
|
||||
- 'remove-aio-stuff'
|
||||
- 'browser-update-test'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
@@ -20,157 +20,6 @@ defaults:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
./node_modules
|
||||
./aio/node_modules
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Install node modules in aio
|
||||
run: yarn install --frozen-lockfile --cwd aio
|
||||
- name: Check code lint
|
||||
run: yarn -s tslint
|
||||
- name: Check for circular dependencies
|
||||
run: yarn -s ts-circular-deps:check
|
||||
- name: Validate pull approve configuration
|
||||
run: yarn -s ng-dev pullapprove verify
|
||||
- name: Validate angular robot configuration
|
||||
run: yarn -s ng-dev ngbot verify
|
||||
- name: Confirm code builds with typescript as expected
|
||||
run: yarn -s check-tooling-setup
|
||||
- name: Check commit message
|
||||
# Commit message validation is only done on pull requests as its too late to validate once
|
||||
# it has been merged.
|
||||
if: github.event_name == 'pull_request'
|
||||
run: yarn ng-dev commit-message validate-range ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}
|
||||
- name: Check code format
|
||||
# Code formatting checks are only done on pull requests as its too late to validate once
|
||||
# it has been merged.
|
||||
if: github.event_name == 'pull_request'
|
||||
run: yarn ng-dev format changed --check ${{ github.event.pull_request.base.sha }}
|
||||
|
||||
devtools:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Run unit tests
|
||||
run: yarn devtools:test
|
||||
- name: Test build
|
||||
run: yarn devtools:build:chrome
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile --network-timeout 100000
|
||||
- name: Run CI tests for framework
|
||||
run: yarn test:ci
|
||||
|
||||
adev:
|
||||
runs-on:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Build adev in fast mode to ensure it continues to work
|
||||
run: yarn bazel build //adev:build --fast_adev
|
||||
- name: Run tests
|
||||
run: yarn bazel test //adev:test
|
||||
|
||||
publish-snapshots:
|
||||
if: github.event_name == 'push'
|
||||
runs-on:
|
||||
labels: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- run: echo "https://${{secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN}}:@github.com" > ${HOME}/.git_credentials
|
||||
- run: yarn build
|
||||
- run: ./scripts/ci/publish-build-artifacts.sh
|
||||
|
||||
zone-js:
|
||||
runs-on:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
./node_modules
|
||||
./packages/zone.js/node_modules
|
||||
./packages/zone.js/test/typings/node_modules
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- run: |
|
||||
yarn bazel build \
|
||||
//packages/zone.js/bundles:zone.umd.js \
|
||||
//packages/zone.js:npm_package \
|
||||
//packages/zone.js/test/closure:closure_js \
|
||||
|
||||
- run: |
|
||||
rm -Rf packages/zone.js/build
|
||||
rm -Rf packages/zone.js/test/extra/*.umd.js
|
||||
|
||||
mkdir -p packages/zone.js/build/
|
||||
mkdir -p packages/zone.js/build/test/
|
||||
|
||||
cp dist/bin/packages/zone.js/bundles/zone.umd.js packages/zone.js/build/zone.umd.js
|
||||
cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/
|
||||
cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/
|
||||
cp dist/bin/packages/zone.js/test/closure/zone.closure.mjs ./packages/zone.js/build/test/zone.closure.mjs
|
||||
|
||||
# Install
|
||||
- run: yarn --cwd packages/zone.js install --frozen-lockfile --non-interactive
|
||||
# Run zone.js tools tests
|
||||
- run: yarn --cwd packages/zone.js promisefinallytest
|
||||
- run: yarn --cwd packages/zone.js jest:test
|
||||
- run: yarn --cwd packages/zone.js jest:nodetest
|
||||
- run: yarn --cwd packages/zone.js electrontest
|
||||
- run: yarn --cwd packages/zone.js/test/typings install --frozen-lockfile --non-interactive
|
||||
- run: yarn --cwd packages/zone.js/test/typings test
|
||||
|
||||
bazel-saucelabs:
|
||||
# TODO: Replace legacy job with Bazel saucelabs job.
|
||||
if: github.event_name == 'push'
|
||||
@@ -247,34 +96,4 @@ jobs:
|
||||
- name: Stop Saucelabs tunnel service
|
||||
run: ./tools/saucelabs/sauce-service.sh stop
|
||||
|
||||
adev-deploy:
|
||||
needs: [adev]
|
||||
if: needs.adev.result == 'success' && github.event_name == 'push' && github.ref_name == 'main'
|
||||
env:
|
||||
DEPLOY_PROJECT: angular-dev-site
|
||||
DEPLOY_SITE: angular-dev-site
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Build adev to ensure it continues to work
|
||||
run: yarn bazel build //adev:build
|
||||
- name: Move generated project files into deployment directory
|
||||
run: cp -r dist/bin/adev/build adev/build
|
||||
- name: Setup firebase context
|
||||
run: |
|
||||
npx -y firebase-tools@latest target:clear --config adev/firebase.json --project ${{ env.DEPLOY_PROJECT }} hosting angular-docs
|
||||
npx -y firebase-tools@latest target:apply --config adev/firebase.json --project ${{ env.DEPLOY_PROJECT }} hosting angular-docs ${{ env.DEPLOY_SITE }}
|
||||
- name: Deploy to firebase
|
||||
uses: FirebaseExtended/action-hosting-deploy@120e124148ab7016bec2374e5050f15051255ba2 # v0.7.1
|
||||
with:
|
||||
entryPoint: './adev'
|
||||
firebaseServiceAccount: ${{ secrets.ANGULAR_DEV_SITE_DEPLOY }}
|
||||
projectId: ${{ env.DEPLOY_PROJECT }}
|
||||
channelId: live
|
||||
|
||||
@@ -12,14 +12,14 @@ jobs:
|
||||
labels:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
- uses: angular/dev-infra/github-actions/commit-message-based-labels@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
post_approval_changes:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
- uses: angular/dev-infra/github-actions/post-approval-changes@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
statuses: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
- uses: angular/dev-infra/github-actions/google-internal-tests@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
with:
|
||||
run-tests-guide-url: http://go/angular-g3sync-start
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
with:
|
||||
# Setting `persist-credentials: false` prevents the github-action account from being the
|
||||
# account that is attempted to be used for authentication, instead the remote is set to
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
The `output()` function declares an output in a directive or component.
|
||||
Outputs allow you to emit values to parent components.
|
||||
|
||||
HELPFUL: The `output()` function is currently in [developer preview](/guide/releases#developer-preview).
|
||||
HELPFUL: The `output()` function is currently in [developer preview](/reference/releases#developer-preview).
|
||||
|
||||
<docs-code language="ts" highlight="[[5], [8]]">
|
||||
import {Component, output} from '@angular/core';
|
||||
|
||||
@@ -22,22 +22,11 @@ const debugMode = false;
|
||||
// https://saucelabs.com/platform/platform-configurator
|
||||
const customLaunchers = {
|
||||
'SL_ANDROID11': {
|
||||
base: 'SauceLabs',
|
||||
browserName: 'Chrome',
|
||||
platformName: 'Android',
|
||||
platformVersion: '11.0',
|
||||
deviceName: 'Google Pixel 3a GoogleAPI Emulator',
|
||||
appiumVersion: '1.20.2',
|
||||
extendedDebugging: debugMode,
|
||||
},
|
||||
'SL_ANDROID12': {
|
||||
base: 'SauceLabs',
|
||||
browserName: 'Chrome',
|
||||
platformName: 'Android',
|
||||
platformVersion: '12.0',
|
||||
deviceName: 'Google Pixel 4a (5G) GoogleAPI Emulator',
|
||||
appiumVersion: '1.22.1',
|
||||
extendedDebugging: debugMode,
|
||||
browserName: 'Browser',
|
||||
'appium:deviceName': 'Android GoogleAPI Emulator',
|
||||
'appium:platformVersion': 'current_major',
|
||||
'appium:automationName': 'UiAutomator2',
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -77,7 +77,7 @@
|
||||
"@types/babel__core": "7.20.5",
|
||||
"@types/babel__generator": "7.6.8",
|
||||
"@types/bluebird": "^3.5.27",
|
||||
"@types/chrome": "^0.0.266",
|
||||
"@types/chrome": "^0.0.267",
|
||||
"@types/convert-source-map": "^2.0.0",
|
||||
"@types/diff": "^5.0.0",
|
||||
"@types/dom-view-transitions": "^1.0.1",
|
||||
@@ -132,7 +132,7 @@
|
||||
"rollup-plugin-sourcemaps": "^0.6.3",
|
||||
"rxjs": "^7.0.0",
|
||||
"selenium-webdriver": "3.5.0",
|
||||
"selenium-webdriver4": "npm:selenium-webdriver@4.19.0",
|
||||
"selenium-webdriver4": "npm:selenium-webdriver@4.20.0",
|
||||
"semver-dsl": "^1.0.1",
|
||||
"shelljs": "^0.8.5",
|
||||
"source-map": "0.7.4",
|
||||
|
||||
@@ -39,10 +39,7 @@ export class BaseDispatcher {
|
||||
* @param dispatchDelegate A function that should handle dispatching an `EventInfoWrapper` to handlers.
|
||||
*/
|
||||
constructor(
|
||||
private readonly dispatchDelegate: (
|
||||
eventInfoWrapper: EventInfoWrapper,
|
||||
isGlobalDispatch?: boolean,
|
||||
) => void,
|
||||
private readonly dispatchDelegate: (eventInfoWrapper: EventInfoWrapper) => void,
|
||||
{eventReplayer = undefined}: {eventReplayer?: Replayer} = {},
|
||||
) {
|
||||
this.eventReplayer = eventReplayer;
|
||||
@@ -67,20 +64,18 @@ export class BaseDispatcher {
|
||||
*
|
||||
* @param eventInfo The info for the event that triggered this call or the
|
||||
* queue of events from EventContract.
|
||||
* @param isGlobalDispatch If true, dispatches a global event instead of a
|
||||
* regular jsaction handler.
|
||||
*/
|
||||
dispatch(eventInfo: EventInfo, isGlobalDispatch?: boolean): void {
|
||||
dispatch(eventInfo: EventInfo): void {
|
||||
const eventInfoWrapper = new EventInfoWrapper(eventInfo);
|
||||
if (eventInfoWrapper.getIsReplay()) {
|
||||
if (isGlobalDispatch || !this.eventReplayer) {
|
||||
if (!this.eventReplayer) {
|
||||
return;
|
||||
}
|
||||
this.queueEventInfoWrapper(eventInfoWrapper);
|
||||
this.scheduleEventReplay();
|
||||
return;
|
||||
}
|
||||
this.dispatchDelegate(eventInfoWrapper, isGlobalDispatch);
|
||||
this.dispatchDelegate(eventInfoWrapper);
|
||||
}
|
||||
|
||||
/** Queue an `EventInfoWrapper` for replay. */
|
||||
@@ -117,7 +112,7 @@ export function registerDispatcher(
|
||||
eventContract: UnrenamedEventContract,
|
||||
dispatcher: BaseDispatcher,
|
||||
) {
|
||||
eventContract.ecrd((eventInfo: EventInfo, globalDispatch?: boolean) => {
|
||||
dispatcher.dispatch(eventInfo, globalDispatch);
|
||||
eventContract.ecrd((eventInfo: EventInfo) => {
|
||||
dispatcher.dispatch(eventInfo);
|
||||
}, Restriction.I_AM_THE_JSACTION_FRAMEWORK);
|
||||
}
|
||||
|
||||
@@ -71,8 +71,8 @@ export class Dispatcher {
|
||||
) {
|
||||
this.eventReplayer = eventReplayer;
|
||||
this.baseDispatcher = new BaseDispatcher(
|
||||
(eventInfoWrapper: EventInfoWrapper, isGlobalDispatch?: boolean) => {
|
||||
this.dispatchToHandler(eventInfoWrapper, isGlobalDispatch);
|
||||
(eventInfoWrapper: EventInfoWrapper) => {
|
||||
this.dispatchToHandler(eventInfoWrapper);
|
||||
},
|
||||
{
|
||||
eventReplayer: (eventInfoWrappers) => {
|
||||
@@ -102,33 +102,43 @@ export class Dispatcher {
|
||||
*
|
||||
* @param eventInfo The info for the event that triggered this call or the
|
||||
* queue of events from EventContract.
|
||||
* @param isGlobalDispatch If true, dispatches a global event instead of a
|
||||
* regular jsaction handler.
|
||||
*/
|
||||
dispatch(eventInfo: EventInfo, isGlobalDispatch?: boolean): void {
|
||||
this.baseDispatcher.dispatch(eventInfo, isGlobalDispatch);
|
||||
this.baseDispatcher.dispatch(eventInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches an `EventInfoWrapper`.
|
||||
*/
|
||||
private dispatchToHandler(eventInfoWrapper: EventInfoWrapper, isGlobalDispatch?: boolean) {
|
||||
if (isGlobalDispatch) {
|
||||
private dispatchToHandler(eventInfoWrapper: EventInfoWrapper) {
|
||||
if (this.globalHandlers.size) {
|
||||
const globalEventInfoWrapper = eventInfoWrapper.clone();
|
||||
|
||||
// In some cases, `populateAction` will rewrite `click` events to
|
||||
// `clickonly`. Revert back to a regular click, otherwise we won't be able
|
||||
// to execute global event handlers registered on click events.
|
||||
if (globalEventInfoWrapper.getEventType() === EventType.CLICKONLY) {
|
||||
globalEventInfoWrapper.setEventType(EventType.CLICK);
|
||||
}
|
||||
// Skip everything related to jsaction handlers, and execute the global
|
||||
// handlers.
|
||||
const ev = eventInfoWrapper.getEvent();
|
||||
const eventTypeHandlers = this.globalHandlers.get(eventInfoWrapper.getEventType());
|
||||
const event = globalEventInfoWrapper.getEvent();
|
||||
const eventTypeHandlers = this.globalHandlers.get(globalEventInfoWrapper.getEventType());
|
||||
let shouldPreventDefault = false;
|
||||
if (eventTypeHandlers) {
|
||||
for (const handler of eventTypeHandlers) {
|
||||
if (handler(ev) === false) {
|
||||
if (handler(event) === false) {
|
||||
shouldPreventDefault = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shouldPreventDefault) {
|
||||
eventLib.preventDefault(ev);
|
||||
eventLib.preventDefault(event);
|
||||
}
|
||||
}
|
||||
|
||||
const action = eventInfoWrapper.getAction();
|
||||
if (!action) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -136,8 +146,6 @@ export class Dispatcher {
|
||||
stopPropagation(eventInfoWrapper);
|
||||
}
|
||||
|
||||
const action = eventInfoWrapper.getAction()!;
|
||||
|
||||
let handler: EventInfoWrapperHandler | void = undefined;
|
||||
if (this.getHandler) {
|
||||
handler = this.getHandler(eventInfoWrapper);
|
||||
@@ -307,7 +315,7 @@ export function stopPropagation(eventInfoWrapper: EventInfoWrapper) {
|
||||
* Dispatcher.
|
||||
*/
|
||||
export function registerDispatcher(eventContract: UnrenamedEventContract, dispatcher: Dispatcher) {
|
||||
eventContract.ecrd((eventInfo: EventInfo, globalDispatch?: boolean) => {
|
||||
dispatcher.dispatch(eventInfo, globalDispatch);
|
||||
eventContract.ecrd((eventInfo: EventInfo) => {
|
||||
dispatcher.dispatch(eventInfo);
|
||||
}, Restriction.I_AM_THE_JSACTION_FRAMEWORK);
|
||||
}
|
||||
|
||||
@@ -163,29 +163,14 @@ export class EventContract implements UnrenamedEventContract {
|
||||
// All events are queued when the dispatcher isn't yet loaded.
|
||||
eventInfoLib.setIsReplay(eventInfo, true);
|
||||
this.queuedEventInfos?.push(eventInfo);
|
||||
return;
|
||||
}
|
||||
this.actionResolver.resolve(eventInfo);
|
||||
|
||||
if (!this.dispatcher) {
|
||||
return;
|
||||
}
|
||||
const globalEventInfo: eventInfoLib.EventInfo = eventInfoLib.cloneEventInfo(eventInfo);
|
||||
|
||||
// In some cases, `populateAction` will rewrite `click` events to
|
||||
// `clickonly`. Revert back to a regular click, otherwise we won't be able
|
||||
// to execute global event handlers registered on click events.
|
||||
if (eventInfoLib.getEventType(globalEventInfo) === EventType.CLICKONLY) {
|
||||
eventInfoLib.setEventType(globalEventInfo, EventType.CLICK);
|
||||
}
|
||||
|
||||
this.dispatcher(globalEventInfo, /* dispatch global event */ true);
|
||||
|
||||
const action = eventInfoLib.getAction(eventInfo);
|
||||
if (!action) {
|
||||
return;
|
||||
}
|
||||
if (shouldPreventDefaultBeforeDispatching(eventInfoLib.getActionElement(action), eventInfo)) {
|
||||
eventLib.preventDefault(eventInfoLib.getEvent(eventInfo));
|
||||
if (action) {
|
||||
if (shouldPreventDefaultBeforeDispatching(eventInfoLib.getActionElement(action), eventInfo)) {
|
||||
eventLib.preventDefault(eventInfoLib.getEvent(eventInfo));
|
||||
}
|
||||
}
|
||||
|
||||
this.dispatcher(eventInfo);
|
||||
|
||||
@@ -7,7 +7,13 @@
|
||||
*/
|
||||
|
||||
import {Dispatcher, Replayer} from '../src/dispatcher';
|
||||
import {ActionInfo, createEventInfo, EventInfo, EventInfoWrapper} from '../src/event_info';
|
||||
import {
|
||||
ActionInfo,
|
||||
createEventInfo,
|
||||
EventInfo,
|
||||
EventInfoWrapper,
|
||||
unsetAction,
|
||||
} from '../src/event_info';
|
||||
import {createEvent} from '../src/replay';
|
||||
|
||||
function createMockClickEvent() {
|
||||
@@ -137,7 +143,8 @@ describe('dispatcher test.ts', () => {
|
||||
await expectAsync(replayed).toBePending();
|
||||
|
||||
const eventInfo1 = createTestEventInfo({isReplay: true});
|
||||
dispatcher.dispatch(eventInfo1, /* globalDispatch= */ true);
|
||||
unsetAction(eventInfo1);
|
||||
dispatcher.dispatch(eventInfo1);
|
||||
|
||||
await expectAsync(replayed).toBePending();
|
||||
});
|
||||
@@ -199,7 +206,9 @@ describe('dispatcher test.ts', () => {
|
||||
const dispatcher = new Dispatcher();
|
||||
dispatcher.registerGlobalHandler('click', handler);
|
||||
|
||||
dispatcher.dispatch(createTestEventInfo(), true);
|
||||
const eventInfo = createTestEventInfo();
|
||||
unsetAction(eventInfo);
|
||||
dispatcher.dispatch(eventInfo);
|
||||
|
||||
expect(handler).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
@@ -213,7 +222,8 @@ describe('dispatcher test.ts', () => {
|
||||
event: createEvent({type: 'mousedown'} as Event),
|
||||
eventType: 'mousedown',
|
||||
});
|
||||
dispatcher.dispatch(eventInfo, true);
|
||||
unsetAction(eventInfo);
|
||||
dispatcher.dispatch(eventInfo);
|
||||
|
||||
expect(handler).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -234,7 +244,8 @@ describe('dispatcher test.ts', () => {
|
||||
container,
|
||||
action: {name: 'foo', element: targetElement},
|
||||
});
|
||||
dispatcher.dispatch(eventInfo, true);
|
||||
unsetAction(eventInfo);
|
||||
dispatcher.dispatch(eventInfo);
|
||||
});
|
||||
targetElement.addEventListener('click', targetHandler);
|
||||
const parentHandler = jasmine.createSpy('parentHandler');
|
||||
@@ -263,7 +274,8 @@ describe('dispatcher test.ts', () => {
|
||||
container,
|
||||
action: {name: 'foo', element: targetElement},
|
||||
});
|
||||
dispatcher.dispatch(eventInfo, /* globalDispatch= */ true);
|
||||
unsetAction(eventInfo);
|
||||
dispatcher.dispatch(eventInfo);
|
||||
});
|
||||
targetElement.addEventListener('click', targetHandler);
|
||||
const parentHandler = jasmine.createSpy('parentHandler');
|
||||
|
||||
@@ -427,9 +427,9 @@ describe('EventContract', () => {
|
||||
const dispatcher = jasmine.createSpy<Dispatcher>('dispatcher');
|
||||
eventContract.registerDispatcher(dispatcher, Restriction.I_AM_THE_JSACTION_FRAMEWORK);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe(EventType.CLICK);
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -453,9 +453,9 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(targetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe(EventType.CLICK);
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -477,9 +477,9 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(targetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe(EventType.CLICK);
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -502,7 +502,7 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(targetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -526,7 +526,7 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(targetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -558,7 +558,7 @@ describe('EventContract', () => {
|
||||
// tslint:enable:deprecation
|
||||
targetElement.dispatchEvent(animationEndEvent);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('animationend');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(animationEndEvent);
|
||||
@@ -581,7 +581,7 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(targetElement, {shiftKey: true});
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('clickmod');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -604,7 +604,7 @@ describe('EventContract', () => {
|
||||
|
||||
let clickEvent = dispatchMouseEvent(targetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
let eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -617,7 +617,7 @@ describe('EventContract', () => {
|
||||
|
||||
clickEvent = dispatchMouseEvent(targetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -640,7 +640,7 @@ describe('EventContract', () => {
|
||||
|
||||
let clickEvent = dispatchMouseEvent(targetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
let eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -655,7 +655,7 @@ describe('EventContract', () => {
|
||||
|
||||
clickEvent = dispatchMouseEvent(targetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -678,7 +678,7 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(targetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -701,7 +701,7 @@ describe('EventContract', () => {
|
||||
|
||||
const keydownEvent = dispatchKeyboardEvent(targetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('keydown');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(keydownEvent);
|
||||
@@ -724,7 +724,7 @@ describe('EventContract', () => {
|
||||
|
||||
const keyupEvent = dispatchKeyboardEvent(targetElement, {type: 'keyup'});
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('keyup');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(keyupEvent);
|
||||
@@ -776,7 +776,7 @@ describe('EventContract', () => {
|
||||
|
||||
shadowChild.click();
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
// Target element is set to the host from the event.
|
||||
@@ -832,7 +832,7 @@ describe('EventContract', () => {
|
||||
|
||||
clickHandler('click', clickEvent, container);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe(EventType.CLICK);
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -876,7 +876,7 @@ describe('EventContract', () => {
|
||||
// tslint:enable:deprecation
|
||||
targetElement.dispatchEvent(customEvent);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('custom-event');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(customEvent);
|
||||
@@ -900,7 +900,7 @@ describe('EventContract', () => {
|
||||
const data = {'test': 1};
|
||||
fireCustomEvent(targetElement, 'custom-event', data);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('custom-event');
|
||||
const customEvent = eventInfoWrapper.getEvent() as CustomEvent;
|
||||
@@ -936,7 +936,7 @@ describe('EventContract', () => {
|
||||
const data = {'test': 1};
|
||||
fireCustomEvent(targetElement, 'custom-event', data);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('custom-event');
|
||||
const customEvent = eventInfoWrapper.getEvent() as CustomEvent;
|
||||
@@ -962,7 +962,7 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(targetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -987,7 +987,7 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(targetElement, {shiftKey: true});
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('clickmod');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1031,7 +1031,7 @@ describe('EventContract', () => {
|
||||
|
||||
const keydownEvent = dispatchKeyboardEvent(targetElement, {key: 'Enter'});
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(keydownEvent);
|
||||
@@ -1054,9 +1054,9 @@ describe('EventContract', () => {
|
||||
|
||||
const keydownEvent = dispatchKeyboardEvent(targetElement, {key: 'a'});
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('keydown');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(keydownEvent);
|
||||
@@ -1079,7 +1079,7 @@ describe('EventContract', () => {
|
||||
|
||||
const keydownEvent = dispatchKeyboardEvent(targetElement, {key: 'Enter'});
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(keydownEvent);
|
||||
@@ -1104,9 +1104,9 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(targetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('clickonly');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1129,9 +1129,9 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(targetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1158,7 +1158,7 @@ describe('EventContract', () => {
|
||||
|
||||
const keydownEvent = dispatchKeyboardEvent(targetElement, {key: 'Enter'});
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(keydownEvent);
|
||||
@@ -1183,9 +1183,9 @@ describe('EventContract', () => {
|
||||
|
||||
const keydownEvent = dispatchKeyboardEvent(targetElement, {key: 'a'});
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('keydown');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(keydownEvent);
|
||||
@@ -1210,7 +1210,7 @@ describe('EventContract', () => {
|
||||
|
||||
const keydownEvent = dispatchKeyboardEvent(targetElement, {key: 'Enter'});
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(keydownEvent);
|
||||
@@ -1237,9 +1237,9 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(targetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('clickonly');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1264,9 +1264,9 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(targetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1307,7 +1307,7 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(outerTargetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1332,7 +1332,7 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(innerTargetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1357,7 +1357,7 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(outerTargetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1382,7 +1382,7 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(innerTargetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1408,7 +1408,7 @@ describe('EventContract', () => {
|
||||
|
||||
let clickEvent = dispatchMouseEvent(innerTargetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
let eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1425,7 +1425,7 @@ describe('EventContract', () => {
|
||||
|
||||
clickEvent = dispatchMouseEvent(innerTargetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1457,7 +1457,7 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(outerTargetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1488,7 +1488,7 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(innerTargetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1519,7 +1519,7 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(outerTargetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1550,7 +1550,7 @@ describe('EventContract', () => {
|
||||
|
||||
const clickEvent = dispatchMouseEvent(innerTargetElement);
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1587,7 +1587,7 @@ describe('EventContract', () => {
|
||||
relatedTarget: container,
|
||||
});
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('mouseenter');
|
||||
const syntheticMouseEvent = eventInfoWrapper.getEvent();
|
||||
@@ -1640,7 +1640,7 @@ describe('EventContract', () => {
|
||||
relatedTarget: container,
|
||||
});
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('mouseleave');
|
||||
const syntheticMouseEvent = eventInfoWrapper.getEvent();
|
||||
@@ -1693,7 +1693,7 @@ describe('EventContract', () => {
|
||||
relatedTarget: container,
|
||||
});
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('pointerenter');
|
||||
const syntheticMouseEvent = eventInfoWrapper.getEvent();
|
||||
@@ -1746,7 +1746,7 @@ describe('EventContract', () => {
|
||||
relatedTarget: container,
|
||||
});
|
||||
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('pointerleave');
|
||||
const syntheticMouseEvent = eventInfoWrapper.getEvent();
|
||||
@@ -1817,7 +1817,7 @@ describe('EventContract', () => {
|
||||
|
||||
expect(window._ejsa).toBeUndefined();
|
||||
expect(removeEventListenerSpy).toHaveBeenCalledTimes(1);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1854,7 +1854,7 @@ describe('EventContract', () => {
|
||||
|
||||
expect(replaySink._ejsa).toBeUndefined();
|
||||
expect(removeEventListenerSpy).toHaveBeenCalledTimes(1);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('focus');
|
||||
expect(eventInfoWrapper.getEvent().type).toBe('focus');
|
||||
@@ -1892,7 +1892,7 @@ describe('EventContract', () => {
|
||||
|
||||
expect(window._ejsa).toBeUndefined();
|
||||
expect(removeEventListenerSpy).toHaveBeenCalledTimes(1);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('click');
|
||||
expect(eventInfoWrapper.getEvent()).toBe(clickEvent);
|
||||
@@ -1939,7 +1939,7 @@ describe('EventContract', () => {
|
||||
|
||||
expect((window as EarlyJsactionDataContainer)._ejsa).toBeUndefined();
|
||||
expect(removeEventListenerSpy).toHaveBeenCalledTimes(1);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(3);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('mouseleave');
|
||||
const syntheticMouseEvent = eventInfoWrapper.getEvent();
|
||||
@@ -1981,7 +1981,7 @@ describe('EventContract', () => {
|
||||
|
||||
expect(window._ejsa).toBeUndefined();
|
||||
expect(removeEventListenerSpy).toHaveBeenCalledTimes(1);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(2);
|
||||
expect(dispatcher).toHaveBeenCalledTimes(1);
|
||||
const eventInfoWrapper = getLastDispatchedEventInfoWrapper(dispatcher);
|
||||
expect(eventInfoWrapper.getEventType()).toBe('mouseleave');
|
||||
const syntheticMouseEvent = eventInfoWrapper.getEvent();
|
||||
|
||||
@@ -36,6 +36,7 @@ declare global {
|
||||
}
|
||||
|
||||
const JSACTION_ATTRIBUTE = 'jsaction';
|
||||
const removeJsactionQueue: RElement[] = [];
|
||||
|
||||
/**
|
||||
* Returns a set of providers required to setup support for event replay.
|
||||
@@ -52,7 +53,9 @@ export function withEventReplay(): Provider[] {
|
||||
useValue: () => {
|
||||
setDisableEventReplayImpl((el: RElement) => {
|
||||
if (el.hasAttribute(JSACTION_ATTRIBUTE)) {
|
||||
el.removeAttribute(JSACTION_ATTRIBUTE);
|
||||
// We don't immediately remove the attribute here because
|
||||
// we need it for replay that happens after hydration.
|
||||
removeJsactionQueue.push(el);
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -79,6 +82,10 @@ export function withEventReplay(): Provider[] {
|
||||
setEventReplayer(dispatcher);
|
||||
// Event replay is kicked off as a side-effect of executing this function.
|
||||
registerDispatcher(eventContract, dispatcher);
|
||||
for (const el of removeJsactionQueue) {
|
||||
el.removeAttribute(JSACTION_ATTRIBUTE);
|
||||
}
|
||||
removeJsactionQueue.length = 0;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -427,13 +427,7 @@ export function patchEventTarget(
|
||||
const passive =
|
||||
passiveSupported && !!passiveEvents && passiveEvents.indexOf(eventName) !== -1;
|
||||
const options = buildEventListenerOptions(arguments[2], passive);
|
||||
const signal =
|
||||
options &&
|
||||
typeof options === 'object' &&
|
||||
options.signal &&
|
||||
typeof options.signal === 'object'
|
||||
? options.signal
|
||||
: undefined;
|
||||
const signal: AbortSignal | undefined = options?.signal;
|
||||
if (signal?.aborted) {
|
||||
// the signal is an aborted one, just return without attaching the event listener.
|
||||
return;
|
||||
@@ -528,14 +522,18 @@ export function patchEventTarget(
|
||||
if (signal) {
|
||||
// after task is scheduled, we need to store the signal back to task.options
|
||||
taskData.options.signal = signal;
|
||||
nativeListener.call(
|
||||
signal,
|
||||
'abort',
|
||||
() => {
|
||||
task.zone.cancelTask(task);
|
||||
},
|
||||
{once: true},
|
||||
);
|
||||
// Wrapping `task` in a weak reference would not prevent memory leaks. Weak references are
|
||||
// primarily used for preventing strong references cycles. `onAbort` is always reachable
|
||||
// as it's an event listener, so its closure retains a strong reference to the `task`.
|
||||
const onAbort = () => task.zone.cancelTask(task);
|
||||
nativeListener.call(signal, 'abort', onAbort, {once: true});
|
||||
// We need to remove the `abort` listener when the event listener is going to be removed,
|
||||
// as it creates a closure that captures `task`. This closure retains a reference to the
|
||||
// `task` object even after it goes out of scope, preventing `task` from being garbage
|
||||
// collected.
|
||||
if (data) {
|
||||
(data as any).removeAbortListener = () => signal.removeEventListener('abort', onAbort);
|
||||
}
|
||||
}
|
||||
|
||||
// should clear taskData.target to avoid memory leak
|
||||
@@ -620,7 +618,7 @@ export function patchEventTarget(
|
||||
if (symbolEventNames) {
|
||||
symbolEventName = symbolEventNames[capture ? TRUE_STR : FALSE_STR];
|
||||
}
|
||||
const existingTasks = symbolEventName && target[symbolEventName];
|
||||
const existingTasks: Task[] = symbolEventName && target[symbolEventName];
|
||||
if (existingTasks) {
|
||||
for (let i = 0; i < existingTasks.length; i++) {
|
||||
const existingTask = existingTasks[i];
|
||||
@@ -643,6 +641,15 @@ export function patchEventTarget(
|
||||
target[onPropertySymbol] = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Note that `removeAllListeners` would ultimately call `removeEventListener`,
|
||||
// so we're safe to remove the abort listener only once here.
|
||||
const taskData = existingTask.data as any;
|
||||
if (taskData?.removeAbortListener) {
|
||||
taskData.removeAbortListener();
|
||||
taskData.removeAbortListener = null;
|
||||
}
|
||||
|
||||
existingTask.zone.cancelTask(existingTask);
|
||||
if (returnTarget) {
|
||||
return target;
|
||||
|
||||
@@ -3609,10 +3609,10 @@
|
||||
"@types/node" "*"
|
||||
"@types/responselike" "^1.0.0"
|
||||
|
||||
"@types/chrome@^0.0.266":
|
||||
version "0.0.266"
|
||||
resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.266.tgz#1ef0c3076ea05489db2a04a057657587920d2390"
|
||||
integrity sha512-QSQWJTL7NjZElvq/6/E5C1+pHgEP8UAJzwoz7M4vSJ7AECt6NNehJ+tU6snnvuTqZOBjFCivvitYo5+8tNPmhg==
|
||||
"@types/chrome@^0.0.267":
|
||||
version "0.0.267"
|
||||
resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.267.tgz#eefb7d2085993437d8109eb495431dfc0e3dbda1"
|
||||
integrity sha512-vnCWPpYjazSPRMNmybRH+0q4f738F+Pbbls4ZPFsPr9/4TTNJyK1OLZDpSnghnEWb4stfmIUtq/GegnlfD4sPA==
|
||||
dependencies:
|
||||
"@types/filesystem" "*"
|
||||
"@types/har-format" "*"
|
||||
@@ -13922,10 +13922,10 @@ select-hose@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
||||
integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==
|
||||
|
||||
"selenium-webdriver4@npm:selenium-webdriver@4.19.0":
|
||||
version "4.19.0"
|
||||
resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.19.0.tgz#bdd001b6e534033664d8c1310a84c0f12eeafc67"
|
||||
integrity sha512-8XHW8m9V2XN2/SC1kr4bWzMtGvjmKUEZ6S0UBoDBqonhmwEIzKOLbzhanBd08HCOg1s1O0XrDWCD71NnA8Zt0g==
|
||||
"selenium-webdriver4@npm:selenium-webdriver@4.20.0", selenium-webdriver@^4.18.1:
|
||||
version "4.20.0"
|
||||
resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.20.0.tgz#14941ab4a59e8956a5e4b4491a8ba2bd6619d1ac"
|
||||
integrity sha512-s/G44lGQ1xB3tmtX6NNPomlkpL6CxLdmAvp/AGWWwi4qv5Te1+qji7tPSyr6gyuoPpdYiof1rKnWe3luy0MrYA==
|
||||
dependencies:
|
||||
jszip "^3.10.1"
|
||||
tmp "^0.2.3"
|
||||
@@ -13951,15 +13951,6 @@ selenium-webdriver@3.6.0, selenium-webdriver@^3.0.1:
|
||||
tmp "0.0.30"
|
||||
xml2js "^0.4.17"
|
||||
|
||||
selenium-webdriver@^4.18.1:
|
||||
version "4.20.0"
|
||||
resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.20.0.tgz#14941ab4a59e8956a5e4b4491a8ba2bd6619d1ac"
|
||||
integrity sha512-s/G44lGQ1xB3tmtX6NNPomlkpL6CxLdmAvp/AGWWwi4qv5Te1+qji7tPSyr6gyuoPpdYiof1rKnWe3luy0MrYA==
|
||||
dependencies:
|
||||
jszip "^3.10.1"
|
||||
tmp "^0.2.3"
|
||||
ws ">=8.16.0"
|
||||
|
||||
selfsigned@^2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0"
|
||||
|
||||
Reference in New Issue
Block a user