JSFiddle - React, Tailwind, and code Playground
by mgiuffrida
HTML
<script>Polymer = {dom: 'shadow', lazyRegister: true, useNativeCSSProperties: true};</script>
<base href="https://polygit.org/*+:master/components/">
<link rel="import" href="polymer/polymer.html">
<dom-module id="x-child">
<template>
<style>
span {
font-family: monospace;
/* --child-pretty has a color property. @apply will be replaced with
color: var(--child-pretty_-_color); */
@apply(--child-pretty);
font-weight: bold;
}
</style>
x-child's span: <span>This is a styled span</span>
</template>
</dom-module>
<dom-module id="x-parent1">
<template>
<style>
blah {
--child-pretty: {
font-size: 100px;
};
}
x-child {
/* --child-pretty first seen here, so its properties are ['color']. */
--child-pretty: {
/* Sets --child-pretty_-_color to green. */
color: green;
};
}
</style>
<header>Parent 1:</header>
<x-child></x-child>
</template>
</dom-module>
<dom-module id="x-parent2">
<template>
<style>
x-child {
/* The properties used by --child-pretty have already been set. */
--child-pretty: {
/* No effect: property not supported. */
text-decoration: underline;
/* Fine: color is a known property. */
color: red;
}
}
</style>
<header>Parent 2:</header>
<x-child></x-child>
</template>
</dom-module>
<div>
<x-child></x-child>
<x-parent1></x-parent1>
<x-parent2></x-parent2>
</div>
CSS
body {
color: grey;
}
body > div {
display: flex;
flex-direction: column;
}
body > div > * {
margin: 10px;
}
JavaScript
// Parses x-parent1, finding and processing --child-pretty.
// Adds it to the global map with properties ['color'].
Polymer({is: 'x-parent1'});
// Parses x-child, finding and processing --child-pretty.
Polymer({is: 'x-child'});
// Parses x-parent2, finding and processing --child-pretty.
Polymer({is: 'x-parent2'});
function assert(cond) {
if (!cond)
throw new Error('Failed: ' + cond);
}
function checkMixins() {
var mixins = new Map();
var mixinPropRe = new RegExp(/[\s{};]\-\-([\w\-]+)_-_([\w\-]+)\s*:/g);
var mixinAppliedPropRe = new RegExp(/[\s{};]([\w\-]+)\s*:\s*var\(\s*\-\-([\w\-]+)_-_\1\s*[,)]/g);
function parseStyle(style) {
var match;
while (match = mixinPropRe.exec(style.innerText)) {
assert(match.length == 3);
var mixinName = match[1];
var mixinProp = match[2];
if (!mixins.has(mixinName))
mixins.set(mixinName, new Map());
var mixin = mixins.get(mixinName);
if (!mixin.has(mixinProp))
mixin.set(mixinProp, {valueSet: true, applied: false});
else
mixin.get(mixinProp).valueSet = true;
}
while (match = mixinAppliedPropRe.exec(style.innerText)) {
assert(match.length == 3);
var mixinProp = match[1];
var mixinName = match[2];
if (!mixins.has(mixinName))
mixins.set(mixinName, new Map());
var mixin = mixins.get(mixinName);
if (!mixin.has(mixinProp))
mixin.set(mixinProp, {valueSet: false, applied: true});
else
mixin.get(mixinProp).applied = true;
}
}
var styles = document.querySelectorAll('style, * /deep/ style');
console.log('Processing ' + styles.length + ' styles...')
styles.forEach(parseStyle);
mixins.forEach(function(mixin, mixinName) {
mixin.forEach(function(detail, mixinProp) {
if (detail.valueSet && !detail.applied)
console.warn('Property "' + mixinProp + '" set for --' + mixinName + ' but never applied');
else if (!detail.valueSet)
...