feat(aio): set “avoid” class by convention (filename has “.avoid.”)

Most important for StyleGuide which lost example css class in migration.
Also hides copy for “avoid” files.
This commit is contained in:
Ward Bell 2017-05-02 22:39:14 -07:00 committed by Matias Niemelä
parent 673d8ae583
commit 9ca2b4c967
5 changed files with 58 additions and 42 deletions

View File

@ -12,7 +12,7 @@
} }
</code-pane> </code-pane>
<code-pane title='HTML content file' language='html'>&lt;h1&gt;Heading&lt;/h1&gt;</code-pane> <code-pane title='HTML content file' language='html'>&lt;h1&gt;Heading&lt;/h1&gt;</code-pane>
<code-pane title='JSON data file' language='json' class='is-anti-pattern'>{ "key": "value" }</code-pane> <code-pane title='JSON data file' language='json' class='avoid'>{ "key": "value" }</code-pane>
</code-tabs> </code-tabs>
<p></p> <p></p>
@ -24,7 +24,7 @@
} }
</code-pane> </code-pane>
<code-pane title='HTML content file' language='html'>&lt;h1&gt;Heading&lt;/h1&gt;</code-pane> <code-pane title='HTML content file' language='html'>&lt;h1&gt;Heading&lt;/h1&gt;</code-pane>
<code-pane title='JSON data file' language='json' class='is-anti-pattern'>{ "key": "value" }</code-pane> <code-pane title='JSON data file' language='json' class='avoid'>{ "key": "value" }</code-pane>
</code-tabs> </code-tabs>
<p></p> <p></p>
@ -36,7 +36,7 @@
} }
</code-pane> </code-pane>
<code-pane title='HTML content file' language='html' linenums='true'>&lt;h1&gt;Heading&lt;/h1&gt;</code-pane> <code-pane title='HTML content file' language='html' linenums='true'>&lt;h1&gt;Heading&lt;/h1&gt;</code-pane>
<code-pane title='JSON data file' language='json' class='is-anti-pattern'>{ "key": "value" }</code-pane> <code-pane title='JSON data file' language='json' class='avoid'>{ "key": "value" }</code-pane>
</code-tabs> </code-tabs>
<p></p> <p></p>
@ -76,7 +76,7 @@
</code-example> </code-example>
<p>An "avoid" header on this one.</p> <p>An "avoid" header on this one.</p>
<code-example class="is-anti-pattern" title="hero-details.component.ts (Avoid)"> <code-example class="avoid" title="hero-details.component.ts (Avoid)">
&lt;hero-details <em>nghost-pmm-5&gt; &lt;hero-details <em>nghost-pmm-5&gt;
&lt;h2 </em>ngcontent-pmm-5&gt;Mister Fantastic&lt;/h2&gt; &lt;h2 </em>ngcontent-pmm-5&gt;Mister Fantastic&lt;/h2&gt;
&lt;hero-team <em>ngcontent-pmm-5 </em>nghost-pmm-6&gt; &lt;hero-team <em>ngcontent-pmm-5 </em>nghost-pmm-6&gt;

View File

@ -1,5 +1,5 @@
/* tslint:disable component-selector */ /* tslint:disable component-selector */
import { Component, ElementRef, OnInit } from '@angular/core'; import { Component, ElementRef, HostBinding, OnInit } from '@angular/core';
import { getBoolFromAttribute } from 'app/shared/attribute-utils'; import { getBoolFromAttribute } from 'app/shared/attribute-utils';
/** /**
@ -17,12 +17,13 @@ import { getBoolFromAttribute } from 'app/shared/attribute-utils';
selector: 'code-example', selector: 'code-example',
template: ` template: `
<header *ngIf="title">{{title}}</header> <header *ngIf="title">{{title}}</header>
<aio-code [ngClass]="{'headed-code':title, 'simple-code':!title}" [code]="code" <aio-code [ngClass]="classes" [code]="code"
[language]="language" [linenums]="linenums" [path]="path" [region]="region" [hideCopy]="hideCopy"></aio-code> [language]="language" [linenums]="linenums" [path]="path" [region]="region" [hideCopy]="hideCopy"></aio-code>
` `
}) })
export class CodeExampleComponent implements OnInit { export class CodeExampleComponent implements OnInit {
classes: {};
code: string; code: string;
language: string; language: string;
linenums: boolean | number; linenums: boolean | number;
@ -31,6 +32,9 @@ export class CodeExampleComponent implements OnInit {
title: string; title: string;
hideCopy: boolean; hideCopy: boolean;
@HostBinding('class.avoidFile')
isAvoid = false;
constructor(private elementRef: ElementRef) { constructor(private elementRef: ElementRef) {
const element = this.elementRef.nativeElement; const element = this.elementRef.nativeElement;
@ -39,7 +43,14 @@ export class CodeExampleComponent implements OnInit {
this.path = element.getAttribute('path') || ''; this.path = element.getAttribute('path') || '';
this.region = element.getAttribute('region') || ''; this.region = element.getAttribute('region') || '';
this.title = element.getAttribute('title') || ''; this.title = element.getAttribute('title') || '';
this.hideCopy = getBoolFromAttribute(element, ['hidecopy', 'hide-copy']);
this.isAvoid = this.path.indexOf('.avoid.') !== -1;
this.hideCopy = this.isAvoid || getBoolFromAttribute(element, ['hidecopy', 'hide-copy']);
this.classes = {
'headed-code': !!this.title,
'simple-code': !this.title,
};
} }
ngOnInit() { ngOnInit() {

View File

@ -11,7 +11,7 @@ describe('Attribute Utilities', () => {
testEl = div.querySelector('div'); testEl = div.querySelector('div');
}); });
describe('#getAttrs', () => { describe('getAttrs', () => {
beforeEach(() => { beforeEach(() => {
this.expectedMap = { this.expectedMap = {
@ -34,7 +34,7 @@ describe('Attribute Utilities', () => {
}); });
}); });
describe('#getAttrValue', () => { describe('getAttrValue', () => {
let attrMap: { [index: string]: string }; let attrMap: { [index: string]: string };
beforeEach(() => { beforeEach(() => {
@ -46,7 +46,7 @@ describe('Attribute Utilities', () => {
}); });
it('should return empty string value for attribute "A"', () => { it('should return empty string value for attribute "A"', () => {
expect(getAttrValue(attrMap, 'a')).toBe(''); expect(getAttrValue(attrMap, 'A')).toBe('');
}); });
it('should return "true" for attribute "b"', () => { it('should return "true" for attribute "b"', () => {
@ -54,11 +54,10 @@ describe('Attribute Utilities', () => {
}); });
it('should return empty string value for attribute "d-E"', () => { it('should return empty string value for attribute "d-E"', () => {
expect(getAttrValue(attrMap, 'd-e')).toBe(''); expect(getAttrValue(attrMap, 'd-E')).toBe('');
}); });
it('should return empty string for attribute ["d-e"]', () => { it('should return empty string for attribute ["d-e"]', () => {
// because d-e will be found before d
expect(getAttrValue(attrMap, ['d-e'])).toBe(''); expect(getAttrValue(attrMap, ['d-e'])).toBe('');
}); });
@ -82,48 +81,48 @@ describe('Attribute Utilities', () => {
}); });
describe('#boolFromValue', () => { describe('boolFromValue', () => {
let attrMap: { [index: string]: string };
beforeEach(() => { it('should return true for "" as in present but unassigned attr "a"', () => {
attrMap = getAttrs(testEl); expect(boolFromValue('')).toBe(true);
}); });
it('should return true for present but unassigned attr "a"', () => { it('should return false for "false" as in attr "c"', () => {
expect(boolFromValue(getAttrValue(attrMap, 'a'))).toBe(true); expect(boolFromValue('false')).toBe(false);
});
it('should return true for "true" as in attr "b"', () => {
expect(boolFromValue('true')).toBe(true);
}); });
it('should return true for attr "b" which is "true"', () => { it('should return true for something other than "false"', () => {
expect(boolFromValue(getAttrValue(attrMap, 'b'))).toBe(true); expect(boolFromValue('foo')).toBe(true);
}); });
it('should return false for attr "c" which is "false"', () => { it('should return true for "False" because case-sensitive', () => {
expect(boolFromValue(getAttrValue(attrMap, 'c'))).toBe(false); expect(boolFromValue('False')).toBe(true);
}); });
it('should return false by default for undefined attr "x"', () => {
expect(boolFromValue(getAttrValue(attrMap, 'x'))).toBe(false); it('should return false by default as in undefined attr "x"', () => {
expect(boolFromValue(undefined)).toBe(false);
}); });
it('should return true for undefined attr "x" when default is true', () => { it('should return true for undefined value when default is true', () => {
const value = getAttrValue(attrMap, 'x'); expect(boolFromValue(undefined, true)).toBe(true);
expect(boolFromValue(value, true)).toBe(true);
}); });
it('should return false for undefined attr "x" when default is false', () => { it('should return false for undefined value when default is false', () => {
const value = getAttrValue(attrMap, 'x'); expect(boolFromValue(undefined, false)).toBe(false);
expect(boolFromValue(value, false)).toBe(false);
}); });
it('should return true for present but unassigned attr "a" even when default is false', () => { it('should return true for "" as in unassigned attr "a" even when default is false', () => {
// default value is only applied when the attribute is missing // default value is only applied when the attribute is missing
const value = getAttrValue(attrMap, 'a'); expect(boolFromValue('', false)).toBe(true);
expect(boolFromValue(value, false)).toBe(true);
}); });
}); });
// Combines the three utilities for convenience. // Combines the three utilities for convenience.
describe('#getBoolFromAttribute', () => { describe('getBoolFromAttribute', () => {
it('should return true for present but unassigned attr "a"', () => { it('should return true for present but unassigned attr "a"', () => {
expect(getBoolFromAttribute(testEl, 'a')).toBe(true); expect(getBoolFromAttribute(testEl, 'a')).toBe(true);
}); });

View File

@ -17,16 +17,19 @@ export function getAttrs(el: HTMLElement | ElementRef): StringMap {
} }
/** /**
* Return the attribute that matches `atty`. * Return the attribute that matches `attr`.
* @param atty Name of the attribute or a string of candidate attribute names * @param attr Name of the attribute or a string of candidate attribute names
*/ */
export function getAttrValue(attrs: StringMap, attr: string | string[] = ''): string { export function getAttrValue(attrs: StringMap, attr: string | string[] = ''): string {
return attrs[typeof attr === 'string' ? attr : attr.find(a => attrs[a] !== undefined)]; return attrs[typeof attr === 'string' ?
attr.toLowerCase() :
attr.find(a => attrs[a.toLowerCase()] !== undefined)
];
} }
/** /**
* Return the boolean state of an attribute value (if supplied) * Return the boolean state of an attribute value (if supplied)
* @param attyValue The string value of some attribute (or undefined if attribute not present) * @param attrValue The string value of some attribute (or undefined if attribute not present)
* @param def Default boolean value when attribute is undefined. * @param def Default boolean value when attribute is undefined.
*/ */
export function boolFromValue(attrValue: string, def: boolean = false) { export function boolFromValue(attrValue: string, def: boolean = false) {

View File

@ -28,13 +28,16 @@ code-example header {
margin: -17px; margin: -17px;
} }
code-example.is-anti-pattern header { code-example.avoid header,
code-example.avoidFile header {
border: 2px solid $anti-pattern; border: 2px solid $anti-pattern;
background: $anti-pattern; background: $anti-pattern;
} }
code-example.is-anti-pattern, code-example.avoid,
code-tabs.is-anti-pattern md-tab-body { code-example.avoidFile,
code-tabs.avoid md-tab-body,
code-tabs.avoidFile md-tab-body {
border: 0.5px solid $anti-pattern; border: 0.5px solid $anti-pattern;
} }