Skip to content

Commit

Permalink
Flatten styles array
Browse files Browse the repository at this point in the history
  • Loading branch information
LarsDenBakker committed Jan 11, 2019
1 parent eb40e0c commit 0a51f5d
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 5 deletions.
30 changes: 26 additions & 4 deletions src/lit-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,28 @@ export {html, svg, TemplateResult, SVGTemplateResult} from 'lit-html/lit-html';
import {supportsAdoptingStyleSheets, CSSResult} from './lib/css-tag.js';
export * from './lib/css-tag.js';

export interface LitElementStyles extends Array<CSSResult | CSSResult[] | LitElementStyles> {}

/**
* Minimal implementation of Array.prototype.flat
* @param arr the array to flatten
* @param result the accumlated result
*/
function arrayFlat(styles: LitElementStyles, result: CSSResult[] = []): CSSResult[] {
for (let i = 0, length = styles.length; i < length; i++) {
const value = styles[i];
if (Array.isArray(value)) {
arrayFlat(value, result);
} else {
result.push(value);
}
}
return result;
}

/** Deeply flattens styles array. Uses native flat if available. */
const flattenStyles = (styles: LitElementStyles): CSSResult[] => styles.flat ? styles.flat(Infinity) : arrayFlat(styles);

export class LitElement extends UpdatingElement {

/**
Expand All @@ -44,13 +66,13 @@ export class LitElement extends UpdatingElement {
* Array of styles to apply to the element. The styles should be defined
* using the `css` tag function.
*/
static get styles(): CSSResult[] { return []; }
static get styles(): LitElementStyles { return []; }

private static _styles: CSSResult[]|undefined;

private static get _uniqueStyles(): CSSResult[] {
if (this._styles === undefined) {
const styles = this.styles;
const styles = flattenStyles(this.styles);
// As a performance optimization to avoid duplicated styling that can
// occur especially when composing via subclassing, de-duplicate styles
// preserving the last item in the list. The last item is kept to
Expand All @@ -60,8 +82,8 @@ export class LitElement extends UpdatingElement {
set.add(s);
// on IE set.add does not return the set.
return set;
}, new Set());
// Array.form does not work on Set in IE
}, new Set<CSSResult>());
// Array.from does not work on Set in IE
this._styles = [];
styleSet.forEach((v) => this._styles!.unshift(v));
}
Expand Down
46 changes: 46 additions & 0 deletions src/test/lit-element_styling_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,52 @@ suite('Static get styles', () => {
const div = el.shadowRoot!.querySelector('div');
assert.equal(getComputedStyleValue(div!, 'border-top-width').trim(), '2px');
});

test.only('`static get styles` array is flattened', async () => {
const name = generateElementName();
const styles = [
css`.level1 {
border: 1px solid blue;
}`,
[
css`.level2 {
border: 2px solid blue;
}`,
[
css`.level3 {
border: 3px solid blue;
}`,
[
css`.level4 {
border: 4px solid blue;
}`,
],
],
],
];
customElements.define(name, class extends LitElement {
static get styles() { return [ styles ]; }

render() {
return htmlWithStyles`
<div class="level1">Testing1</div>
<div class="level2">Testing2</div>
<div class="level3">Testing3</div>
<div class="level4">Testing4</div>`;
}
});
const el = document.createElement(name);
container.appendChild(el);
await (el as LitElement).updateComplete;
const level1 = el.shadowRoot!.querySelector('.level1');
const level2 = el.shadowRoot!.querySelector('.level2');
const level3 = el.shadowRoot!.querySelector('.level3');
const level4 = el.shadowRoot!.querySelector('.level4');
assert.equal(getComputedStyleValue(level1!, 'border-top-width').trim(), '1px');
assert.equal(getComputedStyleValue(level2!, 'border-top-width').trim(), '2px');
assert.equal(getComputedStyleValue(level3!, 'border-top-width').trim(), '3px');
assert.equal(getComputedStyleValue(level4!, 'border-top-width').trim(), '4px');
});
});

suite('ShadyDOM', () => {
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"target": "es2017",
"module": "es2015",
"moduleResolution": "node",
"lib": ["es2017", "dom"],
"lib": ["es2017", "dom", "esnext"],
"declaration": true,
"declarationMap": true,
"sourceMap": true,
Expand Down

0 comments on commit 0a51f5d

Please sign in to comment.