diff --git a/src/features/mini/content.html b/src/features/mini/content.html
index 094444757b..0990cda902 100644
--- a/src/features/mini/content.html
+++ b/src/features/mini/content.html
@@ -285,7 +285,13 @@
node = node || this;
var list = node.querySelectorAll(selector);
return list;
- }
+ },
+
+ // system override point
+ _elementAdd: function() {},
+
+ // system override point
+ _elementRemove: function() {}
});
@@ -440,6 +446,7 @@
},
appendChild: function(node, container) {
+ this.host._elementAdd(node);
container = container || this.node;
if (this.host._useContent) {
saveLightChildrenIfNeeded(container);
@@ -475,6 +482,7 @@
insertBefore: function(node, ref_node, container) {
container = container || this.node;
if (ref_node) {
+ this.host._elementAdd(node);
if (this.host._useContent) {
saveLightChildrenIfNeeded(container);
var children = this.children(container);
@@ -520,6 +528,7 @@
This method also performs dom composition.
*/
removeChild: function(node, container) {
+ this.host._elementRemove(node);
container = container || this.node;
if (this.host._useContent) {
var children = this.children(container);
diff --git a/src/features/standard/styling.html b/src/features/standard/styling.html
index 32d9fb9077..2a0d103f00 100644
--- a/src/features/standard/styling.html
+++ b/src/features/standard/styling.html
@@ -125,6 +125,20 @@
transformer.host(this, this.is);
}
stampTemplate.call(this);
+ },
+
+ // add scoping class whenever an element is added to localDOM
+ _elementAdd: function(node) {
+ if (this._encapsulateStyle && !node.__styleScoped) {
+ transformer.dom(node, this.is);
+ }
+ },
+
+ // remove scoping class whenever an element is removed from localDOM
+ _elementRemove: function(node) {
+ if (this._encapsulateStyle) {
+ transformer.dom(node, '');
+ }
}
});
diff --git a/src/lib/style-transformer.html b/src/lib/style-transformer.html
index 044f82fba6..cdaaef1df6 100644
--- a/src/lib/style-transformer.html
+++ b/src/lib/style-transformer.html
@@ -38,12 +38,15 @@
// Given a node and scope name, add a scoping class to each node
// in the tree. This facilitates transforming css into scoped rules.
function transformDom(node, scope) {
- _transformDom(node, scope + SCOPE_SUFFIX);
+ _transformDom(node, scope ? scope + SCOPE_SUFFIX : '');
}
function _transformDom(node, selector) {
if (node.classList) {
- node.classList.add(selector);
+ node.className = node.className.replace(SCOPING_CLASS, '');
+ if (selector) {
+ node.classList.add(selector);
+ }
}
// NOTE: it'd be better to use *Element* but Safari does not support
// this api for document fragments.
@@ -141,6 +144,7 @@
var SCOPE_JUMP = /\:\:content|\:\:shadow|\/deep\//;
var CLASS_PREFIX = '.';
var PSEUDO_PREFIX = ':';
+ var SCOPING_CLASS = /(?:^|\s)([\S]*?-x)(?:$|\s)/;
// exports
return {
diff --git a/src/lib/template/x-repeat.html b/src/lib/template/x-repeat.html
index 4f3e531ec5..4c137f1dbe 100644
--- a/src/lib/template/x-repeat.html
+++ b/src/lib/template/x-repeat.html
@@ -330,6 +330,7 @@
var beforeNode = beforeRow ? beforeRow._children[0] : this;
var parentNode = this.lightDom.elementParent();
if (this._domTarget) {
+ row.root.__styleScoped = true;
this._domTarget.insertBefore(row.root, beforeNode, parentNode);
} else {
parentNode.insertBefore(row.root, beforeNode);
diff --git a/test/unit/scoped-styling.html b/test/unit/scoped-styling.html
index b07c4dd98c..c15fe1ca32 100644
--- a/test/unit/scoped-styling.html
+++ b/test/unit/scoped-styling.html
@@ -77,6 +77,15 @@
test('/deep/ selectors', function() {
assertComputed(styled.$.child.$.deep, '8px');
});
+
+ test('dynamically added elements', function() {
+ var d = document.createElement('div');
+ d.classList.add('scoped');
+ styled.localDom.appendChild(d);
+ assertComputed(d, '4px');
+ styled.localDom.removeChild(d);
+ assert.equal(d.className, 'scoped');
+ });
});