Skip to content

Commit 14f344a

Browse files
authored
Merge pull request #3821 from Polymer/apply-shim-depend-before-create
[apply shim] Track dependencies for mixins before creation
2 parents d02aecd + 8de1bec commit 14f344a

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

src/lib/apply-shim.html

+20
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
function produceCssProperties(matchText, propertyName, valueProperty, valueMixin) {
135135
// handle case where property value is a mixin
136136
if (valueProperty) {
137+
// form: --mixin2: var(--mixin1), where --mixin1 is in the map
137138
styleUtil.processVariableAndFallback(valueProperty, function(prefix, value) {
138139
if (value && mapGet(value)) {
139140
valueMixin = '@apply ' + value + ';';
@@ -178,6 +179,19 @@
178179
if (mixinEntry) {
179180
mixinEntry.properties = combinedProps;
180181
}
182+
// because the mixinMap is global, the mixin might conflict with
183+
// a different scope's simple variable definition:
184+
// Example:
185+
// some style somewhere:
186+
// --mixin1:{ ... }
187+
// --mixin2: var(--mixin1);
188+
// some other element:
189+
// --mixin1: 10px solid red;
190+
// --foo: var(--mixin1);
191+
// In this case, we leave the original variable definition in place.
192+
if (valueProperty) {
193+
prefix = matchText + ';' + prefix;
194+
}
181195
return prefix + out.join('; ') + ';';
182196
}
183197

@@ -196,6 +210,12 @@
196210
mixinName = mixinName.replace(APPLY_NAME_CLEAN, '');
197211
var vars = [];
198212
var mixinEntry = mapGet(mixinName);
213+
// if we depend on a mixin before it is created
214+
// make a sentinel entry in the map to add this element as a dependency for when it is defined.
215+
if (!mixinEntry) {
216+
mapSet(mixinName, {});
217+
mixinEntry = mapGet(mixinName);
218+
}
199219
if (mixinEntry) {
200220
var currentProto = ApplyShim.__currentElementProto;
201221
if (currentProto) {

test/unit/styling-cross-scope-apply.html

+75
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,64 @@
533533
}
534534
</style>
535535

536+
<dom-module id="x-apply-depend-before-create">
537+
<template>
538+
<style>
539+
:host {
540+
@apply --before-create;
541+
}
542+
</style>
543+
</template>
544+
<script>
545+
HTMLImports.whenReady(function() {
546+
Polymer({
547+
is: 'x-apply-depend-before-create'
548+
})
549+
})
550+
</script>
551+
</dom-module>
552+
553+
<dom-module id="x-create-after-apply">
554+
<template>
555+
<style>
556+
:host {
557+
--before-create: {
558+
border: 2px solid green;
559+
};
560+
}
561+
</style>
562+
<x-apply-depend-before-create id="child"></x-apply-depend-before-create>
563+
</template>
564+
<script>
565+
HTMLImports.whenReady(function() {
566+
Polymer({
567+
is: 'x-create-after-apply'
568+
})
569+
})
570+
</script>
571+
</dom-module>
572+
573+
<dom-module id="x-reuse-mixin-name-for-variable">
574+
<template>
575+
<style>
576+
:host {
577+
/* --foo is used above as a mixin for color */
578+
--foo: 20px solid blue;
579+
/* this looks suspiciously like defining a mixin from another mixin */
580+
--color: var(--foo);
581+
border: var(--color);
582+
}
583+
</style>
584+
</template>
585+
<script>
586+
HTMLImports.whenReady(function() {
587+
Polymer({
588+
is: 'x-reuse-mixin-name-for-variable'
589+
})
590+
});
591+
</script>
592+
</dom-module>
593+
536594
<script>
537595
suite('scoped-styling-apply', function() {
538596
function assertComputed(element, value, property) {
@@ -736,6 +794,23 @@
736794
assert.equal(parent2Text, parent3Text, 'x-produce-mixin-3 should not have invalidated x-consume-mixin');
737795
}
738796
});
797+
798+
test('mixins can be depended on before creation', function() {
799+
var e = document.createElement('x-apply-depend-before-create');
800+
document.body.appendChild(e);
801+
CustomElements.takeRecords();
802+
var e2 = document.createElement('x-create-after-apply');
803+
document.body.appendChild(e2);
804+
CustomElements.takeRecords();
805+
assertComputed(e2.$.child, '2px');
806+
});
807+
808+
test('mixin names can be safely reused for variable definitions', function() {
809+
var e = document.createElement('x-reuse-mixin-name-for-variable');
810+
document.body.appendChild(e);
811+
CustomElements.takeRecords();
812+
assertComputed(e, '20px');
813+
});
739814
});
740815

741816
</script>

0 commit comments

Comments
 (0)