mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(ng-update): form-field css name incorrectly updated (#12768)
* Cleans up the `class-names` and `css-names` update rules. Moves them into separate directories for a better overview (similar to the attribute selectors; grouped by data input) * Fixes that the `css-name` rules incorrectly replace `mat-form-field-placeholder-wrapper` with `mat-form-field-labeler`. This happens because we first look for `mat-form-field-placeholder` -> create the replacement -> and then check on the same content (for proper offsets and reporting) and create another replacement for `mat-form-field-placeholder-wrapper`. `mat-form-field-placeholder-wrapper` should be just updated as part of `mat-form-field-placeholder`. * Updates an incorrect Github PR link for the `$mat-font-family` removal.
This commit is contained in:
committed by
Jeremy Elbourn
parent
8673e40e9f
commit
4830be8ab6
@@ -15,8 +15,8 @@ export interface MaterialCssNameData {
|
||||
replaceWith: string;
|
||||
/** Whitelist where this replacement is made. If omitted it is made in all files. */
|
||||
whitelist?: {
|
||||
/** Replace this name in CSS files. */
|
||||
css?: boolean,
|
||||
/** Replace this name in stylesheet files. */
|
||||
stylesheet?: boolean,
|
||||
/** Replace this name in HTML files. */
|
||||
html?: boolean,
|
||||
/** Replace this name in TypeScript strings. */
|
||||
@@ -32,10 +32,6 @@ export const cssNames = transformChanges<MaterialCssNameData>([
|
||||
replace: 'mat-form-field-placeholder',
|
||||
replaceWith: 'mat-form-field-label'
|
||||
},
|
||||
{
|
||||
replace: 'mat-form-field-placeholder-wrapper',
|
||||
replaceWith: 'mat-form-field-label-wrapper'
|
||||
},
|
||||
{
|
||||
replace: 'mat-input-container',
|
||||
replaceWith: 'mat-form-field'
|
||||
@@ -96,13 +92,13 @@ export const cssNames = transformChanges<MaterialCssNameData>([
|
||||
},
|
||||
|
||||
{
|
||||
pr: 'https://github.com/angular/material2/pull/10325',
|
||||
pr: 'https://github.com/angular/material2/pull/10430',
|
||||
changes: [
|
||||
{
|
||||
replace: '$mat-font-family',
|
||||
replaceWith: "Roboto, 'Helvetica Neue', sans-serif",
|
||||
whitelist: {
|
||||
css: true
|
||||
stylesheet: true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
+9
-8
@@ -7,21 +7,22 @@
|
||||
*/
|
||||
|
||||
import {bold, red} from 'chalk';
|
||||
import {ProgramAwareRuleWalker, RuleFailure, Rules} from 'tslint';
|
||||
import {RuleFailure, Rules, RuleWalker} from 'tslint';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
/**
|
||||
* Rule that walks through every identifier that is part of Angular Material and replaces the
|
||||
* outdated name with the new one.
|
||||
* Rule that looks for class name identifiers that have been removed but cannot be
|
||||
* automatically migrated.
|
||||
*/
|
||||
export class Rule extends Rules.TypedRule {
|
||||
applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): RuleFailure[] {
|
||||
return this.applyWithWalker(
|
||||
new CheckIdentifierMiscWalker(sourceFile, this.getOptions(), program));
|
||||
export class Rule extends Rules.AbstractRule {
|
||||
|
||||
apply(sourceFile: ts.SourceFile): RuleFailure[] {
|
||||
return this.applyWithWalker(new Walker(sourceFile, this.getOptions()));
|
||||
}
|
||||
}
|
||||
|
||||
export class CheckIdentifierMiscWalker extends ProgramAwareRuleWalker {
|
||||
export class Walker extends RuleWalker {
|
||||
|
||||
visitIdentifier(identifier: ts.Identifier) {
|
||||
if (identifier.getText() === 'MatDrawerToggleResult') {
|
||||
this.addFailureAtNode(
|
||||
+5
-5
@@ -9,16 +9,16 @@
|
||||
import {green, red} from 'chalk';
|
||||
import {RuleFailure, Rules, RuleWalker} from 'tslint';
|
||||
import * as ts from 'typescript';
|
||||
import {classNames} from '../material/data/class-names';
|
||||
import {classNames} from '../../material/data/class-names';
|
||||
import {
|
||||
isMaterialExportDeclaration,
|
||||
isMaterialImportDeclaration,
|
||||
} from '../material/typescript-specifiers';
|
||||
} from '../../material/typescript-specifiers';
|
||||
import {
|
||||
isExportSpecifierNode,
|
||||
isImportSpecifierNode,
|
||||
isNamespaceImportNode,
|
||||
} from '../typescript/imports';
|
||||
} from '../../typescript/imports';
|
||||
|
||||
/**
|
||||
* Rule that walks through every identifier that is part of Angular Material and replaces the
|
||||
@@ -27,11 +27,11 @@ import {
|
||||
export class Rule extends Rules.AbstractRule {
|
||||
|
||||
apply(sourceFile: ts.SourceFile): RuleFailure[] {
|
||||
return this.applyWithWalker(new SwitchIdentifiersWalker(sourceFile, this.getOptions()));
|
||||
return this.applyWithWalker(new Walker(sourceFile, this.getOptions()));
|
||||
}
|
||||
}
|
||||
|
||||
export class SwitchIdentifiersWalker extends RuleWalker {
|
||||
export class Walker extends RuleWalker {
|
||||
|
||||
/**
|
||||
* List of identifier names that have been imported from `@angular/material` or `@angular/cdk`
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @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 {green, red} from 'chalk';
|
||||
import {Replacement, RuleFailure, Rules, RuleWalker} from 'tslint';
|
||||
import * as ts from 'typescript';
|
||||
import {cssNames, MaterialCssNameData} from '../../material/data/css-names';
|
||||
import {findAllSubstringIndices} from '../../typescript/literal';
|
||||
|
||||
/**
|
||||
* Rule that walks through every string literal that is wrapped inside of a call expression.
|
||||
* All string literals which include an outdated CSS class name will be migrated.
|
||||
*/
|
||||
export class Rule extends Rules.AbstractRule {
|
||||
apply(sourceFile: ts.SourceFile): RuleFailure[] {
|
||||
return this.applyWithWalker(new Walker(sourceFile, this.getOptions()));
|
||||
}
|
||||
}
|
||||
|
||||
export class Walker extends RuleWalker {
|
||||
|
||||
visitStringLiteral(node: ts.StringLiteral) {
|
||||
if (node.parent && node.parent.kind !== ts.SyntaxKind.CallExpression) {
|
||||
return;
|
||||
}
|
||||
|
||||
const textContent = node.getFullText();
|
||||
|
||||
cssNames.forEach(name => {
|
||||
if (name.whitelist && !name.whitelist.strings) {
|
||||
return;
|
||||
}
|
||||
|
||||
findAllSubstringIndices(textContent, name.replace)
|
||||
.map(offset => node.getStart() + offset)
|
||||
.map(start => new Replacement(start, name.replace.length, name.replaceWith))
|
||||
.forEach(replacement => this._addFailureWithReplacement(node, replacement, name));
|
||||
});
|
||||
}
|
||||
|
||||
/** Adds a css name failure with the given replacement at the specified node. */
|
||||
private _addFailureWithReplacement(node: ts.Node, replacement: Replacement,
|
||||
name: MaterialCssNameData) {
|
||||
this.addFailureAtNode(node, `Found deprecated CSS class "${red(name.replace)}" which has ` +
|
||||
`been renamed to "${green(name.replaceWith)}"`, replacement);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @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 {green, red} from 'chalk';
|
||||
import {sync as globSync} from 'glob';
|
||||
import {IOptions, Replacement, RuleFailure, Rules} from 'tslint';
|
||||
import * as ts from 'typescript';
|
||||
import {cssNames} from '../../material/data/css-names';
|
||||
import {ExternalResource} from '../../tslint/component-file';
|
||||
import {ComponentWalker} from '../../tslint/component-walker';
|
||||
import {
|
||||
addFailureAtReplacement,
|
||||
createExternalReplacementFailure,
|
||||
} from '../../tslint/rule-failures';
|
||||
import {findAllSubstringIndices} from '../../typescript/literal';
|
||||
|
||||
/**
|
||||
* Rule that walks through every inline or external CSs stylesheet and updates outdated
|
||||
* CSS classes.
|
||||
*/
|
||||
export class Rule extends Rules.AbstractRule {
|
||||
apply(sourceFile: ts.SourceFile): RuleFailure[] {
|
||||
return this.applyWithWalker(new Walker(sourceFile, this.getOptions()));
|
||||
}
|
||||
}
|
||||
|
||||
export class Walker extends ComponentWalker {
|
||||
|
||||
constructor(sourceFile: ts.SourceFile, options: IOptions) {
|
||||
// In some applications, developers will have global stylesheets that are not specified in any
|
||||
// Angular component. Therefore we glob up all css and scss files outside of node_modules and
|
||||
// dist and check them as well.
|
||||
const extraFiles = globSync('!(node_modules|dist)/**/*.+(css|scss)');
|
||||
super(sourceFile, options, extraFiles);
|
||||
extraFiles.forEach(styleUrl => this._reportExternalStyle(styleUrl));
|
||||
}
|
||||
|
||||
|
||||
visitInlineStylesheet(literal: ts.StringLiteral) {
|
||||
this._createReplacementsForContent(literal, literal.getText())
|
||||
.forEach(data => addFailureAtReplacement(this, data.failureMessage, data.replacement));
|
||||
}
|
||||
|
||||
visitExternalStylesheet(node: ExternalResource) {
|
||||
this._createReplacementsForContent(node, node.getFullText())
|
||||
.map(data => createExternalReplacementFailure(node, data.failureMessage,
|
||||
this.getRuleName(), data.replacement))
|
||||
.forEach(failure => this.addFailure(failure));
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for outdated CSs classes in the specified content and creates replacements
|
||||
* with the according messages that can be added to a rule failure.
|
||||
*/
|
||||
private _createReplacementsForContent(node: ts.Node, stylesheetContent: string) {
|
||||
const replacements: {failureMessage: string, replacement: Replacement}[] = [];
|
||||
|
||||
cssNames.forEach(name => {
|
||||
if (name.whitelist && !name.whitelist.stylesheet) {
|
||||
return;
|
||||
}
|
||||
|
||||
const failureMessage = `Found deprecated CSS class "${red(name.replace)}" ` +
|
||||
`which has been renamed to "${green(name.replaceWith)}"`;
|
||||
|
||||
findAllSubstringIndices(stylesheetContent, name.replace)
|
||||
.map(offset => node.getStart() + offset)
|
||||
.map(start => new Replacement(start, name.replace.length, name.replaceWith))
|
||||
.forEach(replacement => replacements.push({replacement, failureMessage}));
|
||||
});
|
||||
|
||||
return replacements;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @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 {green, red} from 'chalk';
|
||||
import {Replacement, RuleFailure, Rules} from 'tslint';
|
||||
import * as ts from 'typescript';
|
||||
import {cssNames} from '../../material/data/css-names';
|
||||
import {ExternalResource} from '../../tslint/component-file';
|
||||
import {ComponentWalker} from '../../tslint/component-walker';
|
||||
import {
|
||||
addFailureAtReplacement,
|
||||
createExternalReplacementFailure,
|
||||
} from '../../tslint/rule-failures';
|
||||
import {findAllSubstringIndices} from '../../typescript/literal';
|
||||
|
||||
/**
|
||||
* Rule that walks through every inline or external HTML template and updates outdated
|
||||
* CSS classes.
|
||||
*/
|
||||
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.StringLiteral) {
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for outdated css names in the specified content and creates replacements
|
||||
* with the according messages that can be added to a rule failure.
|
||||
*/
|
||||
private _createReplacementsForContent(node: ts.Node, templateContent: string) {
|
||||
const replacements: {failureMessage: string, replacement: Replacement}[] = [];
|
||||
|
||||
cssNames.forEach(selector => {
|
||||
if (selector.whitelist && !selector.whitelist.html) {
|
||||
return;
|
||||
}
|
||||
|
||||
const failureMessage = `Found deprecated CSS class "${red(selector.replace)}"` +
|
||||
` which has been renamed to "${green(selector.replaceWith)}"`;
|
||||
|
||||
findAllSubstringIndices(templateContent, selector.replace)
|
||||
.map(offset => node.getStart() + offset)
|
||||
.map(start => new Replacement(start, selector.replace.length, selector.replaceWith))
|
||||
.forEach(replacement => replacements.push({replacement, failureMessage}));
|
||||
});
|
||||
|
||||
return replacements;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/**
|
||||
* @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 {green, red} from 'chalk';
|
||||
import {Replacement, RuleFailure, Rules, RuleWalker} from 'tslint';
|
||||
import * as ts from 'typescript';
|
||||
import {cssNames} from '../material/data/css-names';
|
||||
import {findAllSubstringIndices} from '../typescript/literal';
|
||||
|
||||
/**
|
||||
* Rule that walks through every string literal, which includes the outdated Material name and
|
||||
* is part of a call expression. Those string literals will be changed to the new name.
|
||||
*/
|
||||
export class Rule extends Rules.AbstractRule {
|
||||
apply(sourceFile: ts.SourceFile): RuleFailure[] {
|
||||
return this.applyWithWalker(
|
||||
new SwitchStringLiteralCssNamesWalker(sourceFile, this.getOptions()));
|
||||
}
|
||||
}
|
||||
|
||||
export class SwitchStringLiteralCssNamesWalker extends RuleWalker {
|
||||
visitStringLiteral(stringLiteral: ts.StringLiteral) {
|
||||
if (stringLiteral.parent && stringLiteral.parent.kind !== ts.SyntaxKind.CallExpression) {
|
||||
return;
|
||||
}
|
||||
|
||||
let stringLiteralText = stringLiteral.getFullText();
|
||||
|
||||
cssNames.forEach(name => {
|
||||
if (!name.whitelist || name.whitelist.strings) {
|
||||
this.createReplacementsForOffsets(stringLiteral, name,
|
||||
findAllSubstringIndices(stringLiteralText, name.replace)).forEach(replacement => {
|
||||
this.addFailureAtNode(
|
||||
stringLiteral,
|
||||
`Found deprecated CSS class "${red(name.replace)}" which has been renamed to` +
|
||||
` "${green(name.replaceWith)}"`,
|
||||
replacement);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private createReplacementsForOffsets(node: ts.Node,
|
||||
update: {replace: string, replaceWith: string},
|
||||
offsets: number[]): Replacement[] {
|
||||
return offsets.map(offset => this.createReplacement(
|
||||
node.getStart() + offset, update.replace.length, update.replaceWith));
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/**
|
||||
* @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 {green, red} from 'chalk';
|
||||
import {sync as globSync} from 'glob';
|
||||
import {IOptions, Replacement, RuleFailure, Rules} from 'tslint';
|
||||
import * as ts from 'typescript';
|
||||
import {cssNames} from '../material/data/css-names';
|
||||
import {ExternalResource} from '../tslint/component-file';
|
||||
import {ComponentWalker} from '../tslint/component-walker';
|
||||
import {findAllSubstringIndices} from '../typescript/literal';
|
||||
|
||||
/**
|
||||
* Rule that walks through every component decorator and updates their inline or external
|
||||
* stylesheets.
|
||||
*/
|
||||
export class Rule extends Rules.AbstractRule {
|
||||
apply(sourceFile: ts.SourceFile): RuleFailure[] {
|
||||
return this.applyWithWalker(new SwitchStylesheetCssNamesWalker(sourceFile, this.getOptions()));
|
||||
}
|
||||
}
|
||||
|
||||
export class SwitchStylesheetCssNamesWalker extends ComponentWalker {
|
||||
|
||||
constructor(sourceFile: ts.SourceFile, options: IOptions) {
|
||||
// In some applications, developers will have global stylesheets that are not specified in any
|
||||
// Angular component. Therefore we glob up all css and scss files outside of node_modules and
|
||||
// dist and check them as well.
|
||||
const extraFiles = globSync('!(node_modules|dist)/**/*.+(css|scss)');
|
||||
super(sourceFile, options, extraFiles);
|
||||
extraFiles.forEach(styleUrl => this._reportExternalStyle(styleUrl));
|
||||
}
|
||||
|
||||
visitInlineStylesheet(stylesheet: ts.StringLiteral) {
|
||||
this.replaceNamesInStylesheet(stylesheet, stylesheet.getText()).forEach(replacement => {
|
||||
const fix = replacement.replacement;
|
||||
const ruleFailure = new RuleFailure(stylesheet.getSourceFile(), fix.start, fix.end,
|
||||
replacement.message, this.getRuleName(), fix);
|
||||
this.addFailure(ruleFailure);
|
||||
});
|
||||
}
|
||||
|
||||
visitExternalStylesheet(stylesheet: ExternalResource) {
|
||||
this.replaceNamesInStylesheet(stylesheet, stylesheet.getFullText()).forEach(replacement => {
|
||||
const fix = replacement.replacement;
|
||||
const ruleFailure = new RuleFailure(stylesheet, fix.start + 1, fix.end + 1,
|
||||
replacement.message, this.getRuleName(), fix);
|
||||
this.addFailure(ruleFailure);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the outdated name in the stylesheet with the new one and returns an updated
|
||||
* stylesheet.
|
||||
*/
|
||||
private replaceNamesInStylesheet(node: ts.Node, stylesheetContent: string):
|
||||
{message: string, replacement: Replacement}[] {
|
||||
const replacements: {message: string, replacement: Replacement}[] = [];
|
||||
|
||||
cssNames.forEach(name => {
|
||||
if (!name.whitelist || name.whitelist.css) {
|
||||
const foundOffsets = findAllSubstringIndices(stylesheetContent, name.replace);
|
||||
|
||||
this.createReplacementsForOffsets(node, name, foundOffsets).forEach(replacement => {
|
||||
replacements.push({
|
||||
message: `Found CSS class "${red(name.replace)}" which has been renamed to` +
|
||||
` "${green(name.replaceWith)}"`,
|
||||
replacement
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return replacements;
|
||||
}
|
||||
|
||||
private createReplacementsForOffsets(node: ts.Node,
|
||||
update: {replace: string, replaceWith: string},
|
||||
offsets: number[]): Replacement[] {
|
||||
return offsets.map(offset => this.createReplacement(
|
||||
node.getStart() + offset, update.replace.length, update.replaceWith));
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/**
|
||||
* @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 {green, red} from 'chalk';
|
||||
import {Replacement, RuleFailure, Rules} from 'tslint';
|
||||
import * as ts from 'typescript';
|
||||
import {cssNames} from '../material/data/css-names';
|
||||
import {ExternalResource} from '../tslint/component-file';
|
||||
import {ComponentWalker} from '../tslint/component-walker';
|
||||
import {findAllSubstringIndices} from '../typescript/literal';
|
||||
|
||||
/**
|
||||
* Rule that walks through every component decorator and updates their inline or external
|
||||
* templates.
|
||||
*/
|
||||
export class Rule extends Rules.AbstractRule {
|
||||
apply(sourceFile: ts.SourceFile): RuleFailure[] {
|
||||
return this.applyWithWalker(new SwitchTemplateCaaNamesWalker(sourceFile, this.getOptions()));
|
||||
}
|
||||
}
|
||||
|
||||
export class SwitchTemplateCaaNamesWalker extends ComponentWalker {
|
||||
visitInlineTemplate(template: ts.StringLiteral) {
|
||||
this.replaceNamesInTemplate(template, template.getText()).forEach(replacement => {
|
||||
const fix = replacement.replacement;
|
||||
const ruleFailure = new RuleFailure(template.getSourceFile(), fix.start, fix.end,
|
||||
replacement.message, this.getRuleName(), fix);
|
||||
this.addFailure(ruleFailure);
|
||||
});
|
||||
}
|
||||
|
||||
visitExternalTemplate(template: ExternalResource) {
|
||||
this.replaceNamesInTemplate(template, template.getFullText()).forEach(replacement => {
|
||||
const fix = replacement.replacement;
|
||||
const ruleFailure = new RuleFailure(template, fix.start + 1, fix.end + 1,
|
||||
replacement.message, this.getRuleName(), fix);
|
||||
this.addFailure(ruleFailure);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the outdated name in the template with the new one and returns an updated template.
|
||||
*/
|
||||
private replaceNamesInTemplate(node: ts.Node, templateContent: string):
|
||||
{message: string, replacement: Replacement}[] {
|
||||
const replacements: {message: string, replacement: Replacement}[] = [];
|
||||
|
||||
cssNames.forEach(name => {
|
||||
if (!name.whitelist || name.whitelist.html) {
|
||||
const foundOffsets = findAllSubstringIndices(templateContent, name.replace);
|
||||
|
||||
this.createReplacementsForOffsets(node, name, foundOffsets).forEach(replacement => {
|
||||
replacements.push({
|
||||
message: `Found deprecated CSS class "${red(name.replace)}" which has been` +
|
||||
` renamed to "${green(name.replaceWith)}"`,
|
||||
replacement
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return replacements;
|
||||
}
|
||||
|
||||
private createReplacementsForOffsets(node: ts.Node,
|
||||
update: {replace: string, replaceWith: string},
|
||||
offsets: number[]): Replacement[] {
|
||||
return offsets.map(offset => this.createReplacement(
|
||||
node.getStart() + offset, update.replace.length, update.replaceWith));
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ describe('test cases', () => {
|
||||
*/
|
||||
const testCases = [
|
||||
'v5/attribute-selectors',
|
||||
'v5/css-names',
|
||||
'v5/ts-class-names',
|
||||
];
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {By} from '@angular/platform-browser';
|
||||
|
||||
const a = By.css('.mat-form-field-label');
|
||||
const b = By.css('.mat-form-field-label-wrapper');
|
||||
const c = By.css('.mat-form-field');
|
||||
const d = By.css('.mat-form-field-flex');
|
||||
const e = By.css('.mat-form-field-hint-spacer');
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<ng-content select=".mat-form-field-suffix"></ng-content>
|
||||
<div [panelClass]="mat-form-field-underline">Content</div>
|
||||
|
||||
<style>
|
||||
.mat-form-field-suffix {
|
||||
border: red 1px solid;
|
||||
}
|
||||
|
||||
.mat-form-field-underline {
|
||||
background: blue;
|
||||
}
|
||||
</style>
|
||||
`
|
||||
})
|
||||
class F {}
|
||||
|
||||
@Component({
|
||||
styles: [`
|
||||
.mat-form-field-subscript-wrapper {
|
||||
flex-direction: row;
|
||||
}
|
||||
.mat-form-field .mat-form-field-label {
|
||||
color: lightcoral;
|
||||
}
|
||||
`]
|
||||
})
|
||||
class G {}
|
||||
|
||||
@Component({
|
||||
// Considering this is SCSS that will be transformed by Webpack loaders.
|
||||
styles: [`
|
||||
body, html {
|
||||
font-family: Roboto, 'Helvetica Neue', sans-serif;
|
||||
}
|
||||
`]
|
||||
})
|
||||
class H {}
|
||||
@@ -0,0 +1,48 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {By} from '@angular/platform-browser';
|
||||
|
||||
const a = By.css('.mat-form-field-placeholder');
|
||||
const b = By.css('.mat-form-field-placeholder-wrapper');
|
||||
const c = By.css('.mat-input-container');
|
||||
const d = By.css('.mat-input-flex');
|
||||
const e = By.css('.mat-input-hint-spacer');
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<ng-content select=".mat-input-suffix"></ng-content>
|
||||
<div [panelClass]="mat-input-underline">Content</div>
|
||||
|
||||
<style>
|
||||
.mat-input-suffix {
|
||||
border: red 1px solid;
|
||||
}
|
||||
|
||||
.mat-input-underline {
|
||||
background: blue;
|
||||
}
|
||||
</style>
|
||||
`
|
||||
})
|
||||
class F {}
|
||||
|
||||
@Component({
|
||||
styles: [`
|
||||
.mat-input-subscript-wrapper {
|
||||
flex-direction: row;
|
||||
}
|
||||
.mat-input-container .mat-input-placeholder {
|
||||
color: lightcoral;
|
||||
}
|
||||
`]
|
||||
})
|
||||
class G {}
|
||||
|
||||
@Component({
|
||||
// Considering this is SCSS that will be transformed by Webpack loaders.
|
||||
styles: [`
|
||||
body, html {
|
||||
font-family: $mat-font-family;
|
||||
}
|
||||
`]
|
||||
})
|
||||
class H {}
|
||||
@@ -29,18 +29,16 @@ export default function(): Rule {
|
||||
rulesDirectory: [
|
||||
path.join(__dirname, 'rules/'),
|
||||
path.join(__dirname, 'rules/attribute-selectors'),
|
||||
path.join(__dirname, 'rules/class-names'),
|
||||
path.join(__dirname, 'rules/css-names'),
|
||||
],
|
||||
rules: {
|
||||
// Automatic fixes.
|
||||
'switch-identifiers': true,
|
||||
'switch-property-names': true,
|
||||
'switch-string-literal-css-names': true,
|
||||
'switch-string-literal-element-selectors': true,
|
||||
'switch-stylesheet-css-names': true,
|
||||
'switch-stylesheet-element-selectors': true,
|
||||
'switch-stylesheet-input-names': true,
|
||||
'switch-stylesheet-output-names': true,
|
||||
'switch-template-css-names': true,
|
||||
'switch-template-element-selectors': true,
|
||||
'switch-template-export-as-names': true,
|
||||
'switch-template-input-names': true,
|
||||
@@ -51,9 +49,17 @@ export default function(): Rule {
|
||||
'attribute-selectors-stylesheet': true,
|
||||
'attribute-selectors-template': true,
|
||||
|
||||
// Class name update rules
|
||||
'class-names-identifier': true,
|
||||
'class-names-identifier-misc': true,
|
||||
|
||||
// CSS class name update rules
|
||||
'css-names-string-literal': true,
|
||||
'css-names-stylesheet': true,
|
||||
'css-names-template': true,
|
||||
|
||||
// Additional issues we can detect but not automatically fix.
|
||||
'check-class-declaration-misc': true,
|
||||
'check-identifier-misc': true,
|
||||
'check-import-misc': true,
|
||||
'check-inheritance': true,
|
||||
'check-method-calls': true,
|
||||
|
||||
Reference in New Issue
Block a user