Skip to content

Commit

Permalink
Handle mixins with property values of inherit and initial
Browse files Browse the repository at this point in the history
Fixes #3818
  • Loading branch information
dfreedm committed Jul 28, 2016
1 parent 14f344a commit c7571e5
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 1 deletion.
35 changes: 34 additions & 1 deletion src/lib/apply-shim.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
// match var(--a, --b) to make var(--a, var(--b));
var BAD_VAR = /var\(\s*(--[^,]*),\s*(--[^)]*)\)/g;
var APPLY_NAME_CLEAN = /;\s*/m;
var INITIAL_INHERIT = /^\s*(initial)|(inherit)\s*$/;

// separator used between mixin-name and mixin-property-name when producing properties
// NOTE: plain '-' may cause collisions in user styles
Expand All @@ -102,19 +103,51 @@
return mixinMap[name];
}

var measureElement;
function getInitialValueForProperty(property) {
if (!measureElement) {
measureElement = document.createElement('meta');
measureElement.style.all = 'initial';
document.head.appendChild(measureElement);
}
return window.getComputedStyle(measureElement).getPropertyValue(property);
}

function replaceInitialOrInherit(property, value) {
var match = INITIAL_INHERIT.exec(value);
if (match) {
if (match[1]) {
// initial
// replace `initial` with the concrete initial value for this property
value = getInitialValueForProperty(property);
} else {
// inherit
// with this purposfully illegal value, the variable will be invalid at
// compute time (https://www.w3.org/TR/css-variables/#invalid-at-computed-value-time)
// and for inheriting values, will behave similarly
// we cannot support the same behavior for non inheriting values like 'border'
value = 'apply-shim-inherit';
}
}
return value;
}

// "parse" a mixin definition into a map of properties and values
// cssTextToMap('border: 2px solid black') -> ('border', '2px solid black')
function cssTextToMap(text) {
var props = text.split(';');
var property, value;
var out = {};
for (var i = 0, p, sp; i < props.length; i++) {
p = props[i];
if (p) {
sp = p.split(':');
// ignore lines that aren't definitions like @media
if (sp.length > 1) {
property = sp[0].trim();
// some properties may have ':' in the value, like data urls
out[sp[0].trim()] = sp.slice(1).join(':');
value = replaceInitialOrInherit(property, sp.slice(1).join(':'));
out[property] = value;
}
}
}
Expand Down
88 changes: 88 additions & 0 deletions test/unit/styling-cross-scope-apply.html
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,71 @@
</script>
</dom-module>

<dom-module id="x-apply">
<template>
<style>
:host {
color: rgb(255, 0, 0);
border: 1px solid black;
@apply --initial-inherit;
}
</style>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-apply'
})
});
</script>
</dom-module>

<dom-module id="x-initial">
<template>
<style>
:host {
--initial-inherit: {
color: initial;
border: initial;
};
color: rgb(0, 255, 0);
border: 2px solid blue;
}
</style>
<x-apply id="child"></x-apply>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-initial'
})
});
</script>
</dom-module>

<dom-module id="x-inherit">
<template>
<style>
:host {
--initial-inherit: {
color: inherit;
border: inherit;
};
color: rgb(0, 255, 0);
border: 2px solid blue;
}
</style>
<x-apply id="child"></x-apply>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-inherit'
})
});
</script>
</dom-module>

<script>
suite('scoped-styling-apply', function() {
function assertComputed(element, value, property) {
Expand Down Expand Up @@ -811,6 +876,29 @@
CustomElements.takeRecords();
assertComputed(e, '20px');
});

test('Mixins can set "inherit" for a property', function() {
var e = document.createElement('x-inherit');
document.body.appendChild(e);
CustomElements.takeRecords();
assertComputed(e.$.child, 'rgb(0, 255, 0)', 'color');
if (!Polymer.Settings.useNativeCSSProperties) {
assertComputed(e.$.child, '2px');
} else {
// this is not supported for the apply shim
assert.throws(function() {
assertComputed(e.$.child, '2px');
})
}
});

test('Mixins can set "initial" for a property', function() {
var e = document.createElement('x-initial');
document.body.appendChild(e);
CustomElements.takeRecords();
assertComputed(e.$.child, 'rgb(0, 0, 0)', 'color');
assertComputed(e.$.child, '0px');
});
});

</script>
Expand Down

0 comments on commit c7571e5

Please sign in to comment.