Skip to content

Commit eb2385a

Browse files
author
Steven Orvell
committed
Ensure className bindings work correctly when ShadyDOM.noPatch is used.
Puts `className` on `Polymer.dom` and ensures any sets to `className` in the binding system, go through that wrapper. Note, depends on webcomponents/shadydom#326.
1 parent b7c73bd commit eb2385a

File tree

4 files changed

+128
-2
lines changed

4 files changed

+128
-2
lines changed

lib/legacy/polymer.dom.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ if (window['ShadyDOM'] && window['ShadyDOM']['inUse'] && window['ShadyDOM']['noP
441441
]);
442442

443443
forwardProperties(DomApiNative.prototype, [
444-
'textContent', 'innerHTML'
444+
'textContent', 'innerHTML', 'className'
445445
]);
446446
}
447447

lib/mixins/property-effects.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,10 @@ function setupCompoundStorage(node, binding) {
727727
storage[target] = literals;
728728
// Configure properties with their literal parts
729729
if (binding.literal && binding.kind == 'property') {
730+
// Note, className needs style scoping so this needs wrapping.
731+
if (target === 'className') {
732+
node = wrap(node);
733+
}
730734
node[target] = binding.literal;
731735
}
732736
}
@@ -1407,6 +1411,10 @@ export const PropertyEffects = dedupingMixin(superClass => {
14071411
// implement a whitelist of tag & property values that should never
14081412
// be reset (e.g. <input>.value && <select>.value)
14091413
if (value !== node[prop] || typeof value == 'object') {
1414+
// Note, className needs style scoping so this needs wrapping.
1415+
if (prop === 'className') {
1416+
node = wrap(node);
1417+
}
14101418
node[prop] = value;
14111419
}
14121420
}

test/unit/polymer-dom-nopatch.html

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,37 @@
7272
</script>
7373
</dom-module>
7474

75+
<dom-module id="x-class-bindings">
76+
<template>
77+
<style>
78+
.a {
79+
border: 2px solid orange;
80+
}
81+
82+
.aa {
83+
border: 12px solid red;
84+
}
85+
86+
.b {
87+
padding: 4px;
88+
}
89+
</style>
90+
<div>
91+
<div id="class" class$="[[clazz]] b">class</div>
92+
<div id="className" class-name="[[clazz]] b">class</div>
93+
</div>
94+
</template>
95+
<script type="module">
96+
import { Polymer } from '../../polymer-legacy.js';
97+
Polymer({
98+
properties: {
99+
clazz: {type: String}
100+
},
101+
is: 'x-class-bindings'
102+
});
103+
</script>
104+
</dom-module>
105+
75106
<test-fixture id="scoped">
76107
<template>
77108
<x-event-scoped></x-event-scoped>
@@ -493,6 +524,37 @@
493524
assert.equal(el.className, 'foo');
494525
});
495526

527+
test('className', function() {
528+
dom(el).className = 'foo';
529+
assert.isTrue(el.classList.contains('foo'));
530+
});
531+
532+
test('class bindings work and remained scoped', function() {
533+
const el = document.createElement('x-class-bindings');
534+
document.body.appendChild(el);
535+
assert.equal(getComputedStyle(el.$.class)['border-top-width'], '0px');
536+
assert.equal(getComputedStyle(el.$.class)['padding-top'], '4px');
537+
assert.isTrue(el.$.class.classList.contains('style-scope'));
538+
assert.equal(getComputedStyle(el.$.className)['border-top-width'], '0px');
539+
assert.equal(getComputedStyle(el.$.className)['padding-top'], '4px');
540+
assert.isTrue(el.$.className.classList.contains('style-scope'));
541+
el.clazz = 'a';
542+
assert.equal(getComputedStyle(el.$.class)['border-top-width'], '2px');
543+
assert.equal(getComputedStyle(el.$.class)['padding-top'], '4px');
544+
assert.isTrue(el.$.class.classList.contains('style-scope'));
545+
assert.equal(getComputedStyle(el.$.className)['border-top-width'], '2px');
546+
assert.equal(getComputedStyle(el.$.className)['padding-top'], '4px');
547+
assert.isTrue(el.$.className.classList.contains('style-scope'));
548+
el.clazz = 'aa';
549+
assert.equal(getComputedStyle(el.$.class)['border-top-width'], '12px');
550+
assert.equal(getComputedStyle(el.$.class)['padding-top'], '4px');
551+
assert.isTrue(el.$.class.classList.contains('style-scope'));
552+
assert.equal(getComputedStyle(el.$.className)['border-top-width'], '12px');
553+
assert.equal(getComputedStyle(el.$.className)['padding-top'], '4px');
554+
assert.isTrue(el.$.className.classList.contains('style-scope'));
555+
document.body.removeChild(el);
556+
})
557+
496558
});
497559
</script>
498560

test/unit/polymer-dom.html

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,38 @@
6767
is: 'x-focusable-in-shadow'
6868
});
6969
</script>
70-
</dom-module>
70+
</dom-module>
71+
72+
<dom-module id="x-class-bindings">
73+
<template>
74+
<style>
75+
.a {
76+
border: 2px solid orange;
77+
}
78+
79+
.aa {
80+
border: 12px solid red;
81+
}
82+
83+
.b {
84+
padding: 4px;
85+
}
86+
</style>
87+
<div>
88+
<div id="class" class$="[[clazz]] b">class</div>
89+
<div id="className" class-name="[[clazz]] b">class</div>
90+
</div>
91+
</template>
92+
<script type="module">
93+
import { Polymer } from '../../polymer-legacy.js';
94+
Polymer({
95+
properties: {
96+
clazz: {type: String}
97+
},
98+
is: 'x-class-bindings'
99+
});
100+
</script>
101+
</dom-module>
71102

72103
<test-fixture id="scoped">
73104
<template>
@@ -480,6 +511,31 @@
480511
assert.equal(el.className, 'foo');
481512
});
482513

514+
test('className', function() {
515+
dom(el).className = 'foo';
516+
assert.isTrue(el.classList.contains('foo'));
517+
});
518+
519+
test('class bindings', function() {
520+
const el = document.createElement('x-class-bindings');
521+
document.body.appendChild(el);
522+
assert.equal(getComputedStyle(el.$.class)['border-top-width'], '0px');
523+
assert.equal(getComputedStyle(el.$.class)['padding-top'], '4px');
524+
assert.equal(getComputedStyle(el.$.className)['border-top-width'], '0px');
525+
assert.equal(getComputedStyle(el.$.className)['padding-top'], '4px');
526+
el.clazz = 'a';
527+
assert.equal(getComputedStyle(el.$.class)['border-top-width'], '2px');
528+
assert.equal(getComputedStyle(el.$.class)['padding-top'], '4px');
529+
assert.equal(getComputedStyle(el.$.className)['border-top-width'], '2px');
530+
assert.equal(getComputedStyle(el.$.className)['padding-top'], '4px');
531+
el.clazz = 'aa';
532+
assert.equal(getComputedStyle(el.$.class)['border-top-width'], '12px');
533+
assert.equal(getComputedStyle(el.$.class)['padding-top'], '4px');
534+
assert.equal(getComputedStyle(el.$.className)['border-top-width'], '12px');
535+
assert.equal(getComputedStyle(el.$.className)['padding-top'], '4px');
536+
document.body.removeChild(el);
537+
})
538+
483539
});
484540
</script>
485541

0 commit comments

Comments
 (0)