Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom style fix #1638

Merged
merged 12 commits into from
Jun 9, 2015
65 changes: 33 additions & 32 deletions src/lib/custom-style.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,40 +72,57 @@
var propertyUtils = Polymer.StyleProperties;
var styleUtil = Polymer.StyleUtil;
var styleDefaults = Polymer.StyleDefaults;
var styleTransformer = Polymer.StyleTransformer;

Polymer({

is: 'custom-style',
extends: 'style',

created: function() {
this._appliesToDocument = (this.parentNode.localName !== 'dom-module');
if (this._appliesToDocument) {
// used applied element from HTMLImports polyfill or this
var e = this.__appliedElement || this;
var rules = styleUtil.rulesForStyle(e);
propertyUtils.decorateStyles([e]);
this._rulesToDefaultProperties(rules);
// NOTE: go async to give a chance to collect properties into
// the StyleDefaults before applying
this.async(this._applyStyle);
// NOTE: we cannot just check attached because custom elements in
// HTMLImports do not get attached.
this._tryApply();
},

attached: function() {
this._tryApply();
},

_tryApply: function() {
if (!this._appliesToDocument) {
// only apply variables iff this style is not inside a dom-module
if (this.parentNode &&
(this.parentNode.localName !== 'dom-module')) {
this._appliesToDocument = true;
// used applied element from HTMLImports polyfill or this
var e = this.__appliedElement || this;
styleDefaults.addStyle(e);
// we may not have any textContent yet due to parser yielding
// if so, wait until we do...
if (e.textContent) {
this._apply();
} else {
var observer = new MutationObserver(function() {
observer.disconnect();
this._apply();
}.bind(this));
observer.observe(e, {childList: true});
}
}
}
},

// polyfill this style with root scoping and
// apply custom properties!
_applyStyle: function() {
_apply: function() {
// used applied element from HTMLImports polyfill or this
var e = this.__appliedElement || this;
this._computeStyleProperties();
var props = this._styleProperties;
var self = this;
e.textContent = styleUtil.toCssText(styleUtil.rulesForStyle(e),
function(rule) {
// polyfill lack of support for :root
if (rule.selector === ':root') {
rule.selector = 'body';
}
var css = rule.cssText = rule.parsedCssText;
if (rule.propertyInfo && rule.propertyInfo.cssText) {
// TODO(sorvell): factor better
Expand All @@ -114,25 +131,9 @@
// replace with reified properties, scenario is same as mixin
rule.cssText = propertyUtils.valueForProperties(css, props);
}
if (!nativeShadow) {
Polymer.StyleTransformer.rootRule(rule);
}
styleTransformer.documentRule(rule);
}
);
},

_rulesToDefaultProperties: function(rules) {
// produce css containing only property assignments.
styleUtil.forEachStyleRule(rules, function(rule) {
if (!rule.propertyInfo.properties) {
rule.cssText = '';
}
});
// tell parser to emit css that includes properties.
var cssText = styleUtil.parser.stringify(rules, true);
if (cssText) {
styleDefaults.applyCss(cssText);
}
}

});
Expand Down
21 changes: 14 additions & 7 deletions src/lib/style-defaults.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,13 @@
var styleProperties = Polymer.StyleProperties;
var styleUtil = Polymer.StyleUtil;

var style = document.createElement('style')

var api = {

style: style,
_styles: [style],
_styles: [],
_properties: null,

applyCss: function(cssText) {
this.style.textContent += cssText;
styleUtil.clearStyleRules(this.style);
addStyle: function(style) {
this._styles.push(style);
this._properties = null;
},

Expand All @@ -48,6 +44,17 @@

_computeStyleProperties: function() {
return this._styleProperties;
},

updateStyles: function() {
// invalidate the cache
this._styleCache.clear();
// update any custom-styles we are tracking
for (var i=0, s; i < this._styles.length; i++) {
s = this._styles[i];
s = s.__importElement || s;
s._apply();
}
}

};
Expand Down
16 changes: 14 additions & 2 deletions src/lib/style-transformer.html
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,19 @@
return p$.join(PSEUDO_PREFIX);
},

rootRule: function(rule) {
this._transformRule(rule, this._transformRootSelector);
documentRule: function(rule) {
// reset selector in case this is redone.
rule.selector = rule.parsedSelector;
this.normalizeRootSelector(rule);
if (!nativeShadow) {
this._transformRule(rule, this._transformRootSelector);
}
},

normalizeRootSelector: function(rule) {
if (rule.selector === ROOT) {
rule.selector = 'body';
}
},

_transformRootSelector: function(selector) {
Expand All @@ -225,6 +236,7 @@
var COMPLEX_SELECTOR_SEP = ',';
var SIMPLE_SELECTOR_SEP = /(^|[\s>+~]+)([^\s>+~]+)/g;
var HOST = ':host';
var ROOT = ':root';
// NOTE: this supports 1 nested () pair for things like
// :host(:not([selected]), more general support requires
// parsing which seems like overkill
Expand Down
4 changes: 2 additions & 2 deletions src/lib/style-util.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
},

rulesForStyle: function(style) {
if (!style.__cssRules) {
style.__cssRules = this.parser.parse(style.textContent);
if (!style.__cssRules && style.textContent) {
style.__cssRules = this.parser.parse(style.textContent);
}
return style.__cssRules;
},
Expand Down
4 changes: 3 additions & 1 deletion src/standard/x-styling.html
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,9 @@
* to update styling.
*/
Polymer.updateStyles = function() {
styleDefaults._styleCache.clear();
// update default/custom styles
styleDefaults.updateStyles();
// search the document for elements to update
Polymer.Base._updateRootStyles(document);
};

Expand Down
23 changes: 22 additions & 1 deletion test/unit/custom-style.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
border: 1px solid black;
};

margin: 10px;
/* mocha.css in the testing environment is hosing this test;
use !important as a workaround */
margin: 10px !important;
width: auto;

--special: var(--primary);
Expand Down Expand Up @@ -64,13 +66,19 @@
.import-var {
border: var(--import-var);
}

.dynamic {
border: var(--dynamic);
}
</style>
</head>
<body>
<div class="italic">italic</div>
<div class="bag">bag</div>
<div class="mix">mix</div>

<div class="dynamic">dynamic</div>

<div class="import-mixin">import-mixin</div>
<div class="import-var">import-var</div>

Expand Down Expand Up @@ -161,6 +169,19 @@
assertComputed(m, '4px');
});

test('dynamic custom-styles apply', function(done) {
var dynamic = document.querySelector('.dynamic');
assertComputed(dynamic, '0px');
var ds = document.createElement('style', 'custom-style');
ds.textContent = ':root { --dynamic: 11px solid orange; }';
document.head.appendChild(ds);
setTimeout(function() {
Polymer.updateStyles();
assertComputed(dynamic, '11px');
done();
}, 0);
});

test('custom-styles apply normal and property values to elements', function() {
var e = document.querySelector('x-foo').$.me;
assertComputed(e, '1px');
Expand Down
6 changes: 3 additions & 3 deletions test/unit/styling-cross-scope-var.html
Original file line number Diff line number Diff line change
Expand Up @@ -375,16 +375,16 @@

test('updateStyles changes property values and using style cache', function() {
styled.$.child.classList.add('special');
var l = document.styleSheets.length;
var l = document.querySelectorAll('style').length;
styled.updateStyles();
if (styled.shadyRoot) {
assert.equal(document.styleSheets.length, l+4);
assert.equal(document.querySelectorAll('style').length, l+4);
}
assertComputed(styled.$.child.$.me, '12px');
styled.$.child.classList.remove('special');
styled.updateStyles();
if (styled.shadyRoot) {
assert.equal(document.styleSheets.length, l);
assert.equal(document.querySelectorAll('style').length, l);
}
assertComputed(styled.$.child.$.me, '2px');
});
Expand Down