update(ripple): remove deprecated speed factor option (#12258)

* update(ripple): remove deprecated speed factor option.

* Removes the deprecated `[matRippleSpeedFactor]` and global `baseSpeedFactor` option.
* Adds update rules that can automatically switch to the new API (as much as possible) and even calculate the new durations based on the previously specified speed factor.

BREAKING CHANGE: deprecated `[matRippleSpeedFactor]` and `baseSpeedFactor` for the ripples have been removed. Use the new animation config instead.

* Add test case; fix NodeJS version target circular dependency; Support for rule version constraints
This commit is contained in:
Paul Gschwendtner
2018-09-21 19:17:49 +02:00
committed by mmalerba
parent e4c6cc98bf
commit a6c91bce3c
25 changed files with 385 additions and 96 deletions
+1 -2
View File
@@ -234,10 +234,9 @@ export class MatChip extends _MatChipMixinBase implements FocusableOption, OnDes
this._chipRipple.setupTriggerEvents(_elementRef.nativeElement);
if (globalOptions) {
// TODO(paul): Do not copy each option manually. Allow dynamic global option changes: #9729
this._ripplesGloballyDisabled = !!globalOptions.disabled;
// TODO(paul): Once the speedFactor is removed, we no longer need to copy each single option.
this.rippleConfig = {
speedFactor: globalOptions.baseSpeedFactor,
animation: globalOptions.animation,
terminateOnPointerUp: globalOptions.terminateOnPointerUp,
};
+1 -6
View File
@@ -17,11 +17,6 @@ export type RippleConfig = {
persistent?: boolean;
animation?: RippleAnimationConfig;
terminateOnPointerUp?: boolean;
/**
* @deprecated Use the `animation` property instead.
* @breaking-change 7.0.0
*/
speedFactor?: number;
};
/**
@@ -140,7 +135,7 @@ export class RippleRenderer {
const radius = config.radius || distanceToFurthestCorner(x, y, containerRect);
const offsetX = x - containerRect.left;
const offsetY = y - containerRect.top;
const duration = animationConfig.enterDuration / (config.speedFactor || 1);
const duration = animationConfig.enterDuration;
const ripple = document.createElement('div');
ripple.classList.add('mat-ripple-element');
+10 -46
View File
@@ -62,7 +62,7 @@ describe('MatRipple', () => {
fixture = TestBed.createComponent(BasicRippleContainer);
fixture.detectChanges();
rippleTarget = fixture.nativeElement.querySelector('[mat-ripple]');
rippleTarget = fixture.nativeElement.querySelector('.mat-ripple');
rippleDirective = fixture.componentInstance.ripple;
});
@@ -262,7 +262,7 @@ describe('MatRipple', () => {
fixture = TestBed.createComponent(RippleContainerWithNgIf);
fixture.detectChanges();
rippleTarget = fixture.debugElement.nativeElement.querySelector('[mat-ripple]');
rippleTarget = fixture.debugElement.nativeElement.querySelector('.mat-ripple');
fixture.componentInstance.isDestroyed = true;
fixture.detectChanges();
@@ -377,7 +377,7 @@ describe('MatRipple', () => {
fixture = TestBed.createComponent(BasicRippleContainer);
fixture.detectChanges();
rippleTarget = fixture.nativeElement.querySelector('[mat-ripple]');
rippleTarget = fixture.nativeElement.querySelector('.mat-ripple');
rippleDirective = fixture.componentInstance.ripple;
});
@@ -492,7 +492,7 @@ describe('MatRipple', () => {
fixture = TestBed.createComponent(testComponent);
fixture.detectChanges();
rippleTarget = fixture.nativeElement.querySelector('[mat-ripple]');
rippleTarget = fixture.nativeElement.querySelector('.mat-ripple');
rippleDirective = fixture.componentInstance.ripple;
}
@@ -534,41 +534,6 @@ describe('MatRipple', () => {
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(1);
});
it('should support changing the baseSpeedFactor', fakeAsync(() => {
createTestComponent({ baseSpeedFactor: 0.5 });
dispatchMouseEvent(rippleTarget, 'mousedown');
dispatchMouseEvent(rippleTarget, 'mouseup');
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(1);
// Calculates the speedFactor for the duration. Those factors needs to be inverted, because
// a lower speed factor, will make the duration longer. For example: 0.5 => 2x duration.
let fadeInFactor = 1 / 0.5;
// Calculates the duration for fading-in and fading-out the ripple.
tick(enterDuration * fadeInFactor + exitDuration);
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
}));
it('should combine individual speed factor with baseSpeedFactor', fakeAsync(() => {
createTestComponent({ baseSpeedFactor: 0.5 });
rippleDirective.launch(0, 0, { speedFactor: 1.5 });
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(1);
// Calculates the speedFactor for the duration. Those factors needs to be inverted, because
// a lower speed factor, will make the duration longer. For example: 0.5 => 2x duration.
let fadeInFactor = 1 / (0.5 * 1.5);
// Calculates the duration for fading-in and fading-out the ripple.
tick(enterDuration * fadeInFactor + exitDuration);
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
}));
it('should support changing the animation duration', fakeAsync(() => {
createTestComponent({
animation: {enterDuration: 100, exitDuration: 100}
@@ -619,7 +584,7 @@ describe('MatRipple', () => {
fixture = TestBed.createComponent(BasicRippleContainer);
fixture.detectChanges();
rippleTarget = fixture.nativeElement.querySelector('[mat-ripple]');
rippleTarget = fixture.nativeElement.querySelector('.mat-ripple');
rippleDirective = fixture.componentInstance.ripple;
});
@@ -637,7 +602,7 @@ describe('MatRipple', () => {
fixture.detectChanges();
controller = fixture.debugElement.componentInstance;
rippleTarget = fixture.debugElement.nativeElement.querySelector('[mat-ripple]');
rippleTarget = fixture.debugElement.nativeElement.querySelector('.mat-ripple');
});
it('sets ripple color', () => {
@@ -757,7 +722,7 @@ describe('MatRipple', () => {
@Component({
template: `
<div id="container" #ripple="matRipple" mat-ripple [matRippleSpeedFactor]="0"
<div id="container" #ripple="matRipple" matRipple
style="position: relative; width:300px; height:200px;">
</div>
`,
@@ -769,8 +734,7 @@ class BasicRippleContainer {
@Component({
template: `
<div id="container" style="position: relative; width:300px; height:200px;"
mat-ripple
[matRippleSpeedFactor]="0"
matRipple
[matRippleTrigger]="trigger"
[matRippleCentered]="centered"
[matRippleRadius]="radius"
@@ -792,11 +756,11 @@ class RippleContainerWithInputBindings {
}
@Component({
template: `<div id="container" #ripple="matRipple" mat-ripple></div>`,
template: `<div id="container" #ripple="matRipple" matRipple></div>`,
})
class RippleContainerWithoutBindings {}
@Component({ template: `<div id="container" mat-ripple [matRippleSpeedFactor]="0"
@Component({ template: `<div id="container" matRipple
*ngIf="!isDestroyed"></div>` })
class RippleContainerWithNgIf {
@ViewChild(MatRipple) ripple: MatRipple;
-19
View File
@@ -37,15 +37,6 @@ export interface RippleGlobalOptions {
*/
animation?: RippleAnimationConfig;
/**
* If set, the default duration of the fade-in animation is divided by this value. For example,
* setting it to 0.5 will cause the ripple fade-in animation to take twice as long.
* A changed speedFactor will not affect the fade-out duration of the ripples.
* @deprecated Use the `animation` global option instead.
* @breaking-change 7.0.0
*/
baseSpeedFactor?: number;
/**
* Whether ripples should start fading out immediately after the mouse our touch is released. By
* default, ripples will wait for the enter animation to complete and for mouse or touch release.
@@ -86,15 +77,6 @@ export class MatRipple implements OnInit, OnDestroy, RippleTarget {
*/
@Input('matRippleRadius') radius: number = 0;
/**
* If set, the normal duration of ripple animations is divided by this value. For example,
* setting it to 0.5 will cause the animations to take twice as long.
* A changed speedFactor will not modify the fade-out duration of the ripples.
* @deprecated Use the [matRippleAnimation] binding instead.
* @breaking-change 7.0.0
*/
@Input('matRippleSpeedFactor') speedFactor: number = 1;
/**
* Configuration for the ripple animation. Allows modifying the enter and exit animation
* duration of the ripples. The animation durations will be overwritten if the
@@ -174,7 +156,6 @@ export class MatRipple implements OnInit, OnDestroy, RippleTarget {
color: this.color,
animation: {...this._globalOptions.animation, ...this.animation},
terminateOnPointerUp: this._globalOptions.terminateOnPointerUp,
speedFactor: this.speedFactor * (this._globalOptions.baseSpeedFactor || 1),
};
}
+1 -6
View File
@@ -7,14 +7,9 @@
*/
import {Rule} from '@angular-devkit/schematics';
import {TargetVersion} from './target-version';
import {createUpdateRule} from './update';
/** Possible versions that can be automatically migrated by `ng update`. */
export enum TargetVersion {
V6,
V7,
}
/** Entry point for the migration schematics with target of Angular Material 6.0.0 */
export function updateToV6(): Rule {
return createUpdateRule(TargetVersion.V6);
@@ -6,8 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/
import {TargetVersion} from '../../target-version';
import {VersionChanges} from '../transform-change-data';
import {TargetVersion} from '../../index';
export interface MaterialAttributeSelectorData {
/** The attribute name to replace. */
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {TargetVersion} from '../../index';
import {TargetVersion} from '../../target-version';
import {VersionChanges} from '../transform-change-data';
export interface MaterialClassNameData {
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {TargetVersion} from '../../index';
import {TargetVersion} from '../../target-version';
import {VersionChanges} from '../transform-change-data';
/**
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {TargetVersion} from '../../index';
import {TargetVersion} from '../../target-version';
import {VersionChanges} from '../transform-change-data';
export interface MaterialCssSelectorData {
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {TargetVersion} from '../../index';
import {TargetVersion} from '../../target-version';
import {VersionChanges} from '../transform-change-data';
export interface MaterialElementSelectorData {
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {TargetVersion} from '../../index';
import {TargetVersion} from '../../target-version';
import {VersionChanges} from '../transform-change-data';
export interface MaterialInputNameData {
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {TargetVersion} from '../../index';
import {TargetVersion} from '../../target-version';
import {VersionChanges} from '../transform-change-data';
export interface MaterialMethodCallData {
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {TargetVersion} from '../../index';
import {TargetVersion} from '../../target-version';
import {VersionChanges} from '../transform-change-data';
export interface MaterialOutputNameData {
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {TargetVersion} from '../../index';
import {TargetVersion} from '../../target-version';
import {VersionChanges} from '../transform-change-data';
export interface MaterialPropertyNameData {
@@ -5,7 +5,8 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {TargetVersion} from '../index';
import {TargetVersion} from '../target-version';
export type VersionChanges<T> = {
[target in TargetVersion]?: ReadableChange<T>[];
@@ -0,0 +1,26 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/** Converts the specified speed factor into the exact static enter duration. */
export function convertSpeedFactorToDuration(factor: number) {
// Based on the numeric speed factor value that only affected the `enterDuration` we can
// now calculate the exact `enterDuration`. 450ms is the enter duration without factor.
return 450 / (factor || 1);
}
/**
* Creates a runtime TypeScript expression that can be used in order to calculate the duration
* from the speed factor expression that couldn't be statically analyzed.
*
* @param speedFactorValue Speed factor expression that couldn't be statically analyzed.
*/
export function createSpeedFactorConvertExpression(speedFactorValue: string): string {
// To be sure that the speed factor value expression is calculated properly, we need to add
// the according parenthesis.
return `450 / (${speedFactorValue})`;
}
@@ -0,0 +1,149 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {bold, red} from 'chalk';
import {ProgramAwareRuleWalker, RuleFailure, Rules} from 'tslint';
import * as ts from 'typescript';
import {
convertSpeedFactorToDuration,
createSpeedFactorConvertExpression,
} from './ripple-speed-factor';
/**
* Note that will be added whenever a speed factor expression has been converted to calculate
* the according duration. This note should encourage people to clean up their code by switching
* away from the speed factors to explicit durations.
*/
const removeNote = `TODO: Cleanup duration calculation.`;
/**
* Rule that walks through every property assignment and switches the global `baseSpeedFactor`
* ripple option to the new global animation config. Also updates every class member assignment
* that refers to MatRipple#speedFactor.
*/
export class Rule extends Rules.TypedRule {
applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): RuleFailure[] {
return this.applyWithWalker(new Walker(sourceFile, this.getOptions(), program));
}
}
export class Walker extends ProgramAwareRuleWalker {
/** Switches binary expressions (e.g. myRipple.speedFactor = 0.5) to the new animation config. */
visitBinaryExpression(expression: ts.BinaryExpression) {
if (!ts.isPropertyAccessExpression(expression.left)) {
return;
}
// Left side expression consists of target object and property name (e.g. myInstance.val)
const leftExpression = expression.left as ts.PropertyAccessExpression;
const targetTypeNode = this.getTypeChecker().getTypeAtLocation(leftExpression.expression);
if (!targetTypeNode.symbol) {
return;
}
const targetTypeName = targetTypeNode.symbol.getName();
const propertyName = leftExpression.name.getText();
if (targetTypeName === 'MatRipple' && propertyName === 'speedFactor') {
if (ts.isNumericLiteral(expression.right)) {
const numericValue = parseFloat(expression.right.text);
const newEnterDurationValue = convertSpeedFactorToDuration(numericValue);
// Replace the `speedFactor` property name with `animation`.
const propertyNameReplacement = this.createReplacement(leftExpression.name.getStart(),
leftExpression.name.getWidth(), 'animation');
// Replace the value assignment with the new animation config.
const rightExpressionReplacement = this.createReplacement(expression.right.getStart(),
expression.right.getWidth(), `{enterDuration: ${newEnterDurationValue}}`);
this.addFailureAtNode(expression,
`Found deprecated variable assignment for "${bold('MatRipple')}#${red('speedFactor')}"`,
[propertyNameReplacement, rightExpressionReplacement]);
} else {
// Handle the right expression differently if the previous speed factor value can't
// be resolved statically. In that case, we just create a TypeScript expression that
// calculates the explicit duration based on the non-static speed factor expression.
const newExpression = createSpeedFactorConvertExpression(expression.right.getText());
// Replace the `speedFactor` property name with `animation`.
const propertyNameReplacement = this.createReplacement(leftExpression.name.getStart(),
leftExpression.name.getWidth(), 'animation');
// Replace the value assignment with the new animation config and remove TODO.
const rightExpressionReplacement = this.createReplacement(expression.right.getStart(),
expression.right.getWidth(), `/** ${removeNote} */ {enterDuration: ${newExpression}}`);
this.addFailureAtNode(expression,
`Found deprecated variable assignment for "${bold('MatRipple')}#${red('speedFactor')}"`,
[propertyNameReplacement, rightExpressionReplacement]);
}
}
}
/**
* Switches a potential global option `baseSpeedFactor` to the new animation config. For this
* we assume that the `baseSpeedFactor` is not used in combination with individual speed factors.
*/
visitPropertyAssignment(assignment: ts.PropertyAssignment) {
// For switching the `baseSpeedFactor` global option we expect the property assignment
// to be inside of a normal object literal. Custom ripple global options cannot be switched
// automatically.
if (!ts.isObjectLiteralExpression(assignment.parent)) {
return;
}
// The assignment consists of a name (key) and initializer (value).
if (assignment.name.getText() !== 'baseSpeedFactor') {
return;
}
// We could technically lazily check for the MAT_RIPPLE_GLOBAL_OPTIONS injection token to
// be present, but it's not right to assume that everyone sets the ripple global options
// immediately in the provider object (e.g. it can happen that someone just imports the
// config from a separate file).
const {initializer, name} = assignment;
if (ts.isNumericLiteral(initializer)) {
const numericValue = parseFloat(initializer.text);
const newEnterDurationValue = convertSpeedFactorToDuration(numericValue);
const keyNameReplacement = this.createReplacement(name.getStart(),
assignment.name.getWidth(), `animation`);
const initializerReplacement = this.createReplacement(initializer.getStart(),
initializer.getWidth(), `{enterDuration: ${newEnterDurationValue}}`);
this.addFailureAtNode(assignment,
`Found deprecated property assignment for "${bold('MAT_RIPPLE_GLOBAL_OPTIONS')}:` +
`${red('baseSpeedFactor')}"`,
[keyNameReplacement, initializerReplacement]);
} else {
// Handle the right expression differently if the previous speed factor value can't
// be resolved statically. In that case, we just create a TypeScript expression that
// calculates the explicit duration based on the non-static speed factor expression.
const newExpression = createSpeedFactorConvertExpression(initializer.getText());
// Replace the `baseSpeedFactor` property name with `animation`.
const propertyNameReplacement = this.createReplacement(name.getStart(),
name.getWidth(), 'animation');
// Replace the value assignment with the new animation config and remove TODO.
const rightExpressionReplacement = this.createReplacement(initializer.getStart(),
initializer.getWidth(), `/** ${removeNote} */ {enterDuration: ${newExpression}}`);
this.addFailureAtNode(assignment,
`Found a deprecated property assignment for "${bold('MAT_RIPPLE_GLOBAL_OPTIONS')}:` +
`${red('baseSpeedFactor')}.`,
[propertyNameReplacement, rightExpressionReplacement]);
}
}
}
@@ -0,0 +1,90 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {Replacement, RuleFailure, Rules} from 'tslint';
import * as ts from 'typescript';
import {ExternalResource} from '../../tslint/component-file';
import {ComponentWalker} from '../../tslint/component-walker';
import {
addFailureAtReplacement,
createExternalReplacementFailure,
} from '../../tslint/rule-failures';
import {
convertSpeedFactorToDuration,
createSpeedFactorConvertExpression,
} from './ripple-speed-factor';
/** Regular expression that matches [matRippleSpeedFactor]="$NUMBER" in templates. */
const speedFactorNumberRegex = /\[matRippleSpeedFactor]="(\d+(?:\.\d+)?)"/g;
/** Regular expression that matches [matRippleSpeedFactor]="$NOT_A_NUMBER" in templates. */
const speedFactorNotParseable = /\[matRippleSpeedFactor]="(?!\d+(?:\.\d+)?")(.*)"/g;
/** Failure message that will be shown if a speed factor is set to a readable number. */
const failureMessageReadableNumber =
'Detected deprecated [matRippleSpeedFactor] input binding with readable number.';
/** Failure message that will be shown if a speed factor is set to a non-parseable value. */
const failureMessageNonParseableValue =
'Detected deprecated [matRippleSpeedFactor] input binding with non-parseable value.';
/**
* Rule that walks through every inline or external template and updates the deprecated
* [matRippleSpeedFactor] to [matRippleAnimation].
*/
export class Rule extends Rules.AbstractRule {
apply(sourceFile: ts.SourceFile): RuleFailure[] {
return this.applyWithWalker(new Walker(sourceFile, this.getOptions()));
}
}
export class Walker extends ComponentWalker {
visitInlineTemplate(template: ts.StringLiteralLike) {
this._createReplacementsForContent(template, template.getText())
.forEach(data => addFailureAtReplacement(this, data.failureMessage, data.replacement));
}
visitExternalTemplate(template: ExternalResource) {
this._createReplacementsForContent(template, template.getFullText())
.map(data => createExternalReplacementFailure(template, data.failureMessage,
this.getRuleName(), data.replacement))
.forEach(failure => this.addFailure(failure));
}
private _createReplacementsForContent(node: ts.Node, templateText: string) {
const replacements: {failureMessage: string, replacement: Replacement}[] = [];
const startPos = node.getStart();
let match: RegExpMatchArray | null;
while ((match = speedFactorNumberRegex.exec(templateText)) !== null) {
const newEnterDuration = convertSpeedFactorToDuration(parseFloat(match[1]));
const fix = this.createReplacement(startPos + match.index!, match[0].length,
`[matRippleAnimation]="{enterDuration: ${newEnterDuration}}"`);
replacements.push({
replacement: fix,
failureMessage: failureMessageReadableNumber,
});
}
while ((match = speedFactorNotParseable.exec(templateText)) !== null) {
const newDurationExpression = createSpeedFactorConvertExpression(match[1]);
const fix = this.createReplacement(startPos + match.index!, match[0].length,
`[matRippleAnimation]="{enterDuration: (${newDurationExpression})}"`);
replacements.push({
replacement: fix,
failureMessage: failureMessageNonParseableValue,
});
}
return replacements;
}
}
@@ -0,0 +1,13 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/** Possible versions that can be automatically migrated by `ng update`. */
export enum TargetVersion {
V6,
V7,
}
@@ -10,7 +10,8 @@ describe('v7 upgrade test cases', () => {
* a developers application.
*/
const testCases = [
'v7/property-names'
'v7/property-names',
'v7/ripple-speed-factor',
];
// Iterates through every test case directory and generates a jasmine test block that will
@@ -0,0 +1,33 @@
import {Component} from '@angular/core';
class MatRipple {
speedFactor: number;
}
class A {
self = {me: this.ripple};
constructor(protected ripple: MatRipple) {}
onClick() {
this.ripple.animation = {enterDuration: 900};
this.self.me.animation = {enterDuration: 300};
}
}
const b = new MatRipple();
const myConstant = 1;
b.animation = /** TODO: Cleanup duration calculation. */ {enterDuration: 450 / (0.5 + myConstant)};
@Component({
template: `<div matRipple [matRippleAnimation]="{enterDuration: 900}"></div>`
})
class C {}
@Component({
template: `<div matRipple [matRippleAnimation]="{enterDuration: (450 / (myValue))}"></div>`
})
class D {
myValue = 1.5;
}
@@ -0,0 +1,33 @@
import {Component} from '@angular/core';
class MatRipple {
speedFactor: number;
}
class A {
self = {me: this.ripple};
constructor(protected ripple: MatRipple) {}
onClick() {
this.ripple.speedFactor = 0.5;
this.self.me.speedFactor = 1.5;
}
}
const b = new MatRipple();
const myConstant = 1;
b.speedFactor = 0.5 + myConstant;
@Component({
template: `<div matRipple [matRippleSpeedFactor]="0.5"></div>`
})
class C {}
@Component({
template: `<div matRipple [matRippleSpeedFactor]="myValue"></div>`
})
class D {
myValue = 1.5;
}
+13 -3
View File
@@ -7,7 +7,7 @@
*/
import {sync as globSync} from 'glob';
import {TargetVersion} from './index';
import {TargetVersion} from './target-version';
/** List of rules that need to be enabled when running the TSLint fix task. */
const upgradeRules = [
@@ -52,6 +52,10 @@ const upgradeRules = [
// Additional misc rules.
'check-import-misc',
'check-template-misc',
// Ripple misc V7
['ripple-speed-factor-assignment', TargetVersion.V7],
['ripple-speed-factor-template', TargetVersion.V7],
];
/** List of absolute paths that refer to directories that contain the upgrade rules. */
@@ -66,8 +70,14 @@ const rulesDirectory = globSync('rules/**/', {cwd: __dirname, absolute: true});
* walker is not able to detect stylesheets which are not referenced by Angular.
*/
export function createTslintConfig(target: TargetVersion, extraStyleFiles: string[]) {
const rules = upgradeRules.reduce((result, ruleName) => {
result[ruleName] = [true, target, extraStyleFiles];
const rules = upgradeRules.reduce((result, data) => {
const ruleName = data instanceof Array ? data[0] : data;
const versionConstraints = data instanceof Array ? data.slice(1) : null;
if (!versionConstraints || versionConstraints.includes(target)) {
result[ruleName] = [true, target, extraStyleFiles];
}
return result;
}, {});
+1 -1
View File
@@ -9,8 +9,8 @@
import {Rule, SchematicContext, TaskId, Tree} from '@angular-devkit/schematics';
import {RunSchematicTask, TslintFixTask} from '@angular-devkit/schematics/tasks';
import {sync as globSync} from 'glob';
import {TargetVersion} from './index';
import {getProjectTsConfigPaths} from './project-tsconfig-paths';
import {TargetVersion} from './target-version';
import {createTslintConfig} from './tslint-config';
/** Entry point for `ng update` from Angular CLI. */
+1 -2
View File
@@ -239,11 +239,10 @@ export class MatTabLink extends _MatTabLinkMixinBase
this.tabIndex = parseInt(tabIndex) || 0;
if (globalOptions) {
// TODO(paul): Do not copy each option manually. Allow dynamic global option changes: #9729
this._ripplesGloballyDisabled = !!globalOptions.disabled;
// TODO(paul): Once the speedFactor is removed, we no longer need to copy each single option.
this.rippleConfig = {
terminateOnPointerUp: globalOptions.terminateOnPointerUp,
speedFactor: globalOptions.baseSpeedFactor,
animation: globalOptions.animation,
};
}