refactor: turn off view encapsulation for all components (#6563)

Fixes #6037.
This commit is contained in:
Kristiyan Kostadinov
2017-08-23 02:44:18 +02:00
committed by Kara
parent 0526689fde
commit 2fc6a4c782
14 changed files with 103 additions and 18 deletions
+4 -1
View File
@@ -15,7 +15,8 @@ import {
IterableDiffers,
SimpleChanges,
TemplateRef,
ViewContainerRef
ViewContainerRef,
ViewEncapsulation,
} from '@angular/core';
import {CdkCellDef} from './cell';
@@ -147,6 +148,7 @@ export class CdkCellOutlet {
'role': 'row',
},
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class CdkHeaderRow { }
@@ -159,5 +161,6 @@ export class CdkHeaderRow { }
'role': 'row',
},
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class CdkRow { }
+1
View File
@@ -122,6 +122,7 @@ export class MdDatepickerContent<D> implements AfterContentInit {
selector: 'md-datepicker, mat-datepicker',
template: '',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class MdDatepicker<D> implements OnDestroy {
/** The date to open the calendar to initially. */
+1
View File
@@ -62,6 +62,7 @@ export class MdGridTile {
selector: 'md-grid-tile-header, mat-grid-tile-header, md-grid-tile-footer, mat-grid-tile-footer',
templateUrl: 'grid-tile-text.html',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class MdGridTileText implements AfterContentInit {
/**
+8 -1
View File
@@ -6,7 +6,13 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Component, ElementRef, OnDestroy, ChangeDetectionStrategy} from '@angular/core';
import {
Component,
ElementRef,
OnDestroy,
ChangeDetectionStrategy,
ViewEncapsulation,
} from '@angular/core';
import {FocusableOption} from '../core/a11y/focus-key-manager';
import {CanDisable, mixinDisabled} from '../core/common-behaviors/disabled';
import {Subject} from 'rxjs/Subject';
@@ -36,6 +42,7 @@ export const _MdMenuItemMixinBase = mixinDisabled(MdMenuItemBase);
'(mouseenter)': '_emitHoverEvent()',
},
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
templateUrl: 'menu-item.html',
exportAs: 'mdMenuItem',
})
+7 -6
View File
@@ -5,7 +5,7 @@ $mat-progress-bar-full-animation-duration: 2000ms !default;
$mat-progress-bar-piece-animation-duration: 250ms !default;
:host {
.mat-progress-bar {
display: block;
// Height is provided for md-progress-bar to act as a default.
height: $mat-progress-bar-height;
@@ -59,6 +59,12 @@ $mat-progress-bar-piece-animation-duration: 250ms !default;
left: 0;
}
// Reverse the apparent directionality of progress vars for rtl.
&[dir='rtl'],
[dir='rtl'] & {
transform: rotateY(180deg);
}
&[mode='query'] {
transform: rotateZ(180deg);
}
@@ -99,11 +105,6 @@ $mat-progress-bar-piece-animation-duration: 250ms !default;
}
// Reverse the apparent directionality of progress vars for rtl.
:host-context([dir='rtl']) {
transform: rotateY(180deg);
}
// The values used for animations in md-progress-bar, both timing and transformation, can be
// considered magic values. They are sourced from the Material Design example spec and duplicate
// the values of the original designers definitions.
+2 -1
View File
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Component, ChangeDetectionStrategy, Input} from '@angular/core';
import {Component, ChangeDetectionStrategy, Input, ViewEncapsulation} from '@angular/core';
// TODO(josephperrott): Benchpress tests.
// TODO(josephperrott): Add ARIA attributes for progressbar "for".
@@ -32,6 +32,7 @@ import {Component, ChangeDetectionStrategy, Input} from '@angular/core';
templateUrl: 'progress-bar.html',
styleUrls: ['progress-bar.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class MdProgressBar {
/** Color of the progress bar. */
@@ -12,7 +12,7 @@ $mat-progress-spinner-stroke-width: 10px !default;
$mat-progress-spinner-viewport-size: 100px !default;
:host {
.mat-progress-spinner {
display: block;
// Height and width are provided for mat-progress-spinner to act as a default.
// The height and width are expected to be overwritten by application css.
+5 -1
View File
@@ -16,6 +16,7 @@ import {
Renderer2,
Directive,
ViewChild,
ViewEncapsulation,
} from '@angular/core';
import {CanColor, mixinColor} from '../core/common-behaviors/color';
@@ -70,6 +71,7 @@ export const _MdProgressSpinnerMixinBase = mixinColor(MdProgressSpinnerBase, 'pr
selector: 'md-progress-spinner, mat-progress-spinner',
host: {
'role': 'progressbar',
'class': 'mat-progress-spinner',
'[attr.aria-valuemin]': '_ariaValueMin',
'[attr.aria-valuemax]': '_ariaValueMax',
'[attr.aria-valuenow]': 'value',
@@ -79,6 +81,7 @@ export const _MdProgressSpinnerMixinBase = mixinColor(MdProgressSpinnerBase, 'pr
templateUrl: 'progress-spinner.html',
styleUrls: ['progress-spinner.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class MdProgressSpinner extends _MdProgressSpinnerMixinBase
implements OnDestroy, CanColor {
@@ -279,12 +282,13 @@ export class MdProgressSpinner extends _MdProgressSpinnerMixinBase
host: {
'role': 'progressbar',
'mode': 'indeterminate',
'class': 'mat-spinner',
'class': 'mat-spinner mat-progress-spinner',
},
inputs: ['color'],
templateUrl: 'progress-spinner.html',
styleUrls: ['progress-spinner.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class MdSpinner extends MdProgressSpinner {
constructor(elementRef: ElementRef, ngZone: NgZone, renderer: Renderer2) {
+3 -1
View File
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ChangeDetectionStrategy, Component, Directive} from '@angular/core';
import {ChangeDetectionStrategy, Component, Directive, ViewEncapsulation} from '@angular/core';
import {
CdkHeaderRow,
CdkRow,
@@ -52,6 +52,7 @@ export class MdRowDef extends _MdCdkRowDef { }
'role': 'row',
},
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class MdHeaderRow extends _MdHeaderRow { }
@@ -64,5 +65,6 @@ export class MdHeaderRow extends _MdHeaderRow { }
'role': 'row',
},
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class MdRow extends _MdRow { }
+4 -4
View File
@@ -2,7 +2,7 @@
@import '../core/style/layout-common';
@import 'tabs-common';
:host {
.mat-tab-group {
display: flex;
flex-direction: column;
@@ -23,8 +23,8 @@
}
}
:host[md-stretch-tabs] .mat-tab-label,
:host[mat-stretch-tabs] .mat-tab-label {
.mat-tab-group[md-stretch-tabs] .mat-tab-label,
.mat-tab-group[mat-stretch-tabs] .mat-tab-label {
flex-basis: 0;
flex-grow: 1;
}
@@ -51,7 +51,7 @@
flex-grow: 1;
}
:host.mat-tab-group-dynamic-height &.mat-tab-body-active {
.mat-tab-group.mat-tab-group-dynamic-height &.mat-tab-body-active {
overflow-y: hidden;
}
}
+2
View File
@@ -22,6 +22,7 @@ import {
AfterContentInit,
AfterContentChecked,
OnDestroy,
ViewEncapsulation,
} from '@angular/core';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {map} from '@angular/cdk/rxjs';
@@ -62,6 +63,7 @@ export const _MdTabGroupMixinBase = mixinColor(mixinDisableRipple(MdTabGroupBase
selector: 'md-tab-group, mat-tab-group',
templateUrl: 'tab-group.html',
styleUrls: ['tab-group.css'],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
inputs: ['color', 'disableRipple'],
host: {
+13 -2
View File
@@ -8,8 +8,18 @@
import {TemplatePortal} from '../core/portal/portal';
import {
ViewContainerRef, Input, TemplateRef, ViewChild, OnInit, ContentChild,
Component, ChangeDetectionStrategy, OnDestroy, OnChanges, SimpleChanges,
ChangeDetectionStrategy,
Component,
ContentChild,
Input,
OnChanges,
OnDestroy,
OnInit,
SimpleChanges,
TemplateRef,
ViewChild,
ViewContainerRef,
ViewEncapsulation,
} from '@angular/core';
import {CanDisable, mixinDisabled} from '../core/common-behaviors/disabled';
import {MdTabLabel} from './tab-label';
@@ -26,6 +36,7 @@ export const _MdTabMixinBase = mixinDisabled(MdTabBase);
templateUrl: 'tab.html',
inputs: ['disabled'],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
exportAs: 'mdTab',
})
export class MdTab extends _MdTabMixinBase implements OnInit, CanDisable, OnChanges, OnDestroy {
@@ -0,0 +1,48 @@
const Lint = require('tslint');
const ERROR_MESSAGE = 'Components must turn off view encapsulation.';
// TODO(crisbeto): combine this with the OnPush rule when it gets in.
/**
* Rule that enforces that view encapsulation is turned off on all components.
* Files can be whitelisted via `"no-view-encapsulation": [true, "\.spec\.ts$"]`.
*/
class Rule extends Lint.Rules.AbstractRule {
apply(file) {
return this.applyWithWalker(new Walker(file, this.getOptions()));
}
}
class Walker extends Lint.RuleWalker {
constructor(file, options) {
super(...arguments);
// Whitelist with regular expressions to use when determining which files to lint.
const whitelist = options.ruleArguments;
// Whether the file should be checked at all.
this._enabled = !whitelist.length || whitelist.some(p => new RegExp(p).test(file.fileName));
}
visitClassDeclaration(node) {
if (!this._enabled || !node.decorators) return;
node.decorators
.map(decorator => decorator.expression)
.filter(expression => expression.expression.getText() === 'Component')
.filter(expression => expression.arguments.length && expression.arguments[0].properties)
.forEach(expression => {
const hasTurnedOffEncapsulation = expression.arguments[0].properties.some(prop => {
const value = prop.initializer.getText();
return prop.name.getText() === 'encapsulation' && value.endsWith('.None');
});
if (!hasTurnedOffEncapsulation) {
this.addFailureAtNode(expression.parent, ERROR_MESSAGE);
}
});
}
}
exports.Rule = Rule;
+4
View File
@@ -79,6 +79,10 @@
"check-type",
"check-preblock"
],
"no-view-encapsulation": [
true,
"(lib|cdk)\/((?!spec.ts).)*.ts$"
],
// Bans jasmine helper functions that will prevent the CI from properly running tests.
"ban": [
true,