mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
Added scopeSubtree(container, shouldObserve) to support element use of normal dom api under shady dom in a specific subtree.
This commit is contained in:
@@ -245,7 +245,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
},
|
||||
|
||||
_addNodeToHost: function(node) {
|
||||
var root = this._ownerShadyRootForNode(node);
|
||||
var checkNode = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE ?
|
||||
node.firstChild : node;
|
||||
var root = this._ownerShadyRootForNode(checkNode);
|
||||
if (root) {
|
||||
root.host._elementAdd(node);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
var prepTemplate = Polymer.Base._prepTemplate;
|
||||
var prepElement = Polymer.Base._prepElement;
|
||||
var baseStampTemplate = Polymer.Base._stampTemplate;
|
||||
var nativeShadow = Polymer.Settings.useNativeShadow;
|
||||
|
||||
Polymer.Base.addFeature({
|
||||
|
||||
@@ -29,11 +30,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
var port = Polymer.DomModule.import(this.is);
|
||||
if (this._encapsulateStyle === undefined) {
|
||||
this._encapsulateStyle =
|
||||
Boolean(port && !Polymer.Settings.useNativeShadow);
|
||||
Boolean(port && !nativeShadow);
|
||||
}
|
||||
// scope css
|
||||
// NOTE: dom scoped via annotations
|
||||
if (Polymer.Settings.useNativeShadow || this._encapsulateStyle) {
|
||||
if (nativeShadow || this._encapsulateStyle) {
|
||||
this._scopeCss();
|
||||
}
|
||||
},
|
||||
@@ -107,7 +108,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
_scopeStyles: function(styles) {
|
||||
for (var i=0, l=styles.length, s; (i<l) && (s=styles[i]); i++) {
|
||||
// transform style if necessary and place in correct place
|
||||
if (Polymer.Settings.useNativeShadow) {
|
||||
if (nativeShadow) {
|
||||
if (this._template) {
|
||||
this._template.content.appendChild(s);
|
||||
}
|
||||
@@ -148,6 +149,41 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
if (this._encapsulateStyle) {
|
||||
Polymer.StyleTransformer.dom(node, this.is, this._scopeCssViaAttr, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Apply style scoping to the specified `container` and all its
|
||||
* descendants. If `shoudlObserve` is true, changes to the container are
|
||||
* monitored via mutation observer and scoping is applied.
|
||||
*/
|
||||
scopeSubtree: function(container, shouldObserve) {
|
||||
if (nativeShadow) {
|
||||
return;
|
||||
}
|
||||
var self = this;
|
||||
var scopify = function(node) {
|
||||
if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
node.className = self._scopeElementClass(node, node.className);
|
||||
var n$ = node.querySelectorAll('*');
|
||||
Array.prototype.forEach.call(n$, function(n) {
|
||||
n.className = self._scopeElementClass(n, n.className);
|
||||
});
|
||||
}
|
||||
};
|
||||
scopify(container);
|
||||
if (shouldObserve) {
|
||||
var mo = new MutationObserver(function(mxns) {
|
||||
mxns.forEach(function(m) {
|
||||
if (m.addedNodes) {
|
||||
for (var i=0; i < m.addedNodes.length; i++) {
|
||||
scopify(m.addedNodes[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
mo.observe(container, {childList: true, subtree: true});
|
||||
return mo;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -17,6 +17,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
var baseAttachedCallback = Polymer.Base.attachedCallback;
|
||||
var baseSerializeValueToAttribute = Polymer.Base.serializeValueToAttribute;
|
||||
|
||||
var nativeShadow = Polymer.Settings.useNativeShadow;
|
||||
|
||||
// TODO(sorvell): consider if calculating properties and applying
|
||||
// styles with properties should be separate modules.
|
||||
Polymer.Base.addFeature({
|
||||
@@ -133,10 +135,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
style = cssText ? this._applyCustomCss(cssText) : {};
|
||||
cacheStyle(this.is, style, this._xScopeSelector,
|
||||
this._styleProperties, s$);
|
||||
} else if (Polymer.Settings.useNativeShadow) {
|
||||
} else if (nativeShadow) {
|
||||
this._applyCustomCss(style.textContent);
|
||||
}
|
||||
if (style.textContent /*&& !Polymer.Settings.useNativeShadow*/) {
|
||||
if (style.textContent /*&& !nativeShadow*/) {
|
||||
this._applyXScopeSelector(this._xScopeSelector, old);
|
||||
}
|
||||
}
|
||||
@@ -168,7 +170,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
},
|
||||
|
||||
_transformCss: function(cssText, callback) {
|
||||
return Polymer.Settings.useNativeShadow ?
|
||||
return nativeShadow ?
|
||||
Polymer.StyleUtil.toCssText(cssText, callback) :
|
||||
Polymer.StyleTransformer.css(cssText, this.is, this.extends, callback,
|
||||
this._scopeCssViaAttr);
|
||||
@@ -189,13 +191,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
} else if (cssText) {
|
||||
this._customStyle = Polymer.StyleUtil.applyCss(cssText,
|
||||
this._xScopeSelector,
|
||||
Polymer.Settings.useNativeShadow ? this.root : null);
|
||||
nativeShadow ? this.root : null);
|
||||
}
|
||||
return this._customStyle;
|
||||
},
|
||||
|
||||
_applyPropertiesToRule: function(properties, rule) {
|
||||
if (!Polymer.Settings.useNativeShadow) {
|
||||
if (!nativeShadow) {
|
||||
this._scopifyRule(rule);
|
||||
}
|
||||
if (rule.cssText.match(CUSTOM_RULE_RX)) {
|
||||
@@ -258,7 +260,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
},
|
||||
|
||||
_scopeElementClass: function(element, selector) {
|
||||
if (!this._scopeCssViaAttr) {
|
||||
if (!nativeShadow && !this._scopeCssViaAttr) {
|
||||
selector += (selector ? ' ' : '') + SCOPE_NAME + ' ' + this.is +
|
||||
(element._xScopeSelector ? ' ' + XSCOPE_NAME + ' ' +
|
||||
element._xScopeSelector : '');
|
||||
|
||||
@@ -121,4 +121,46 @@
|
||||
is: 'x-button',
|
||||
extends: 'button'
|
||||
});
|
||||
</script>
|
||||
|
||||
<template id="dynamic">
|
||||
<div class="added">
|
||||
Added
|
||||
<div class="sub-added">
|
||||
Sub-added
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<dom-module id="x-dynamic-scope">
|
||||
<style>
|
||||
.added {
|
||||
border: 17px solid beige;
|
||||
}
|
||||
|
||||
.sub-added {
|
||||
border: 18px solid #fafafa;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div id="container"></div>
|
||||
</template>
|
||||
</dom-module>
|
||||
<script>
|
||||
(function() {
|
||||
var doc = document._currentScript.ownerDocument;
|
||||
var dynamic = doc.querySelector('template#dynamic');
|
||||
|
||||
Polymer({
|
||||
is: 'x-dynamic-scope',
|
||||
ready: function() {
|
||||
// setup node for scope watching
|
||||
this.scopeSubtree(this.$.container, true);
|
||||
// simulate 3rd party action by using normal dom to add to element.
|
||||
var dom = document.importNode(dynamic.content, true);
|
||||
this.$.container.appendChild(dom);
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
@@ -36,6 +36,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
<button is="x-button"></button>
|
||||
<button class="special" is="x-button"></button>
|
||||
|
||||
<x-dynamic-scope></x-dynamic-scope>
|
||||
|
||||
<script src="styling.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -148,4 +148,46 @@
|
||||
is: 'x-button',
|
||||
extends: 'button'
|
||||
});
|
||||
</script>
|
||||
|
||||
<template id="dynamic">
|
||||
<div class="added">
|
||||
Added
|
||||
<div class="sub-added">
|
||||
Sub-added
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<dom-module id="x-dynamic-scope">
|
||||
<style>
|
||||
.added {
|
||||
border: 17px solid beige;
|
||||
}
|
||||
|
||||
.sub-added {
|
||||
border: 18px solid #fafafa;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div id="container"></div>
|
||||
</template>
|
||||
</dom-module>
|
||||
<script>
|
||||
(function() {
|
||||
var doc = document._currentScript.ownerDocument;
|
||||
var dynamic = doc.querySelector('template#dynamic');
|
||||
|
||||
Polymer({
|
||||
is: 'x-dynamic-scope',
|
||||
ready: function() {
|
||||
// setup node for scope watching
|
||||
this.scopeSubtree(this.$.container, true);
|
||||
// simulate 3rd party action by using normal dom to add to element.
|
||||
var dom = document.importNode(dynamic.content, true);
|
||||
this.$.container.appendChild(dom);
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
@@ -36,6 +36,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
<button is="x-button"></button>
|
||||
<button class="special" is="x-button"></button>
|
||||
|
||||
<x-dynamic-scope></x-dynamic-scope>
|
||||
|
||||
<script src="styling.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -117,6 +117,14 @@ suite('scoped-styling', function() {
|
||||
assertComputed(specialButton, '11px');
|
||||
});
|
||||
|
||||
test('element subtree added via dom api', function() {
|
||||
var container = document.querySelector('x-dynamic-scope').$.container;
|
||||
var a = container.querySelector('.added');
|
||||
assertComputed(a, '17px');
|
||||
var b = container.querySelector('.sub-added');
|
||||
assertComputed(b, '18px');
|
||||
});
|
||||
|
||||
if (window.Polymer && !Polymer.Settings.useNativeShadow) {
|
||||
|
||||
suite('scoped-styling-shady-only', function() {
|
||||
@@ -127,7 +135,7 @@ suite('scoped-styling', function() {
|
||||
|
||||
test('styles shimmed in registration order', function() {
|
||||
var s$ = document.head.querySelectorAll('style[scope]');
|
||||
var expected = ['x-child2', 'x-styled', 'x-button'];
|
||||
var expected = ['x-child2', 'x-styled', 'x-button', 'x-dynamic-scope'];
|
||||
var actual = [];
|
||||
for (var i=0; i<s$.length; i++) {
|
||||
actual.push(s$[i].getAttribute('scope'));
|
||||
|
||||
Reference in New Issue
Block a user