Skip to content

Commit

Permalink
Store cacheablility on the scope
Browse files Browse the repository at this point in the history
Store "not cachable" state, simpler logic
Move ast node ordering out of parse and into `decorateStyles`
  • Loading branch information
dfreedm committed Jun 10, 2016
1 parent 57a6769 commit bc9519e
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 23 deletions.
12 changes: 3 additions & 9 deletions src/lib/css-parse.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@
// given a string of css, return a simple rule tree
parse: function(text) {
text = this._clean(text);
var info = {
styleIndex: 0,
mediaIndex: 0
};
return this._parseCss(this._lex(text), text, info);
return this._parseCss(this._lex(text), text);
},

// remove stuff we don't care about that may hinder parsing
Expand Down Expand Up @@ -58,7 +54,7 @@
},

// add selectors/cssText to node tree
_parseCss: function(node, text, info) {
_parseCss: function(node, text) {
var t = text.substring(node.start, node.end-1);
node.parsedCssText = node.cssText = t.trim();
if (node.parent) {
Expand All @@ -75,7 +71,6 @@
if (node.atRule) {
if (s.indexOf(this.MEDIA_START) === 0) {
node.type = this.types.MEDIA_RULE;
node.index = info.mediaIndex++;
} else if (s.match(this._rx.keyframesRule)) {
node.type = this.types.KEYFRAMES_RULE;
node.keyframesName =
Expand All @@ -86,14 +81,13 @@
node.type = this.types.MIXIN_RULE;
} else {
node.type = this.types.STYLE_RULE;
node.index = info.styleIndex++;
}
}
}
var r$ = node.rules;
if (r$) {
for (var i=0, l=r$.length, r; (i<l) && (r=r$[i]); i++) {
this._parseCss(r, text, info);
this._parseCss(r, text);
}
}
return node;
Expand Down
12 changes: 5 additions & 7 deletions src/lib/style-properties.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,23 @@
// decorates styles with rule info and returns an array of used style
// property names
decorateStyles: function(styles, scope) {
var self = this, props = {}, keyframes = [];
// assume all styles are cacheable
for (var idx = 0; i < styles.length; i++) {
styles[idx]._cacheable = true;
}
var self = this, props = {}, keyframes = [], styleIndex = 0;
styleUtil.forRulesInStyles(styles, function(rule, style) {
self.decorateRule(rule);
// mark in-order position of ast rule in styles block, used for cache key
rule.index = styleIndex++;
self.walkHostAndRootProperties(scope, rule, style, function(info) {
// we can't cache styles with :host and :root props in @media rules
if (rule.parent.type === styleUtil.ruleTypes.MEDIA_RULE) {
style._cacheable = false;
scope._notCacheable = true;
}
if (info.isHost) {
// check if the selector is in the form of `:host-context()` or `:host()`
// if so, this style is not cacheable
var hostContextOrFunction = info.selector.split(' ').some(function(s) {
return s.indexOf(scope.is) === 0 && s.length !== scope.is.length;
});
style._cacheable = style._cacheable && !hostContextOrFunction;
scope._notCacheable = scope._notCacheable || hostContextOrFunction;
}
});
self.collectPropertiesInCssText(rule.propertyInfo.cssText, props);
Expand Down
14 changes: 7 additions & 7 deletions src/standard/x-styling.html
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,14 @@
}
var scopeData = propertyUtils
.propertyDataFromStyles(scope._styles, this);
// the scope cache does not evaluate if @media rules, :host(), or :host-context() rules defined in this element have changed
// therefore, if we detect those rules, we opt-out of the scope cache
var scopeCacheable = !this._notCacheable;
// look in scope cache
scopeData.key.customStyle = this.customStyle;
info = scope._styleCache.retrieve(this.is, scopeData.key, this._styles);
if (scopeCacheable) {
scopeData.key.customStyle = this.customStyle;
info = scope._styleCache.retrieve(this.is, scopeData.key, this._styles);
}
// compute style properties (fast path, if cache hit)
var scopeCached = Boolean(info);
if (scopeCached) {
Expand Down Expand Up @@ -144,11 +149,6 @@
_scopeSelector: this._scopeSelector,
_styleProperties: this._styleProperties
};
// the scope cache does not evaluate if @media rules, :host(), or :host-context() rules defined in this element have changed
// therefore, if we detect those rules, we opt-out of the scope cache
var scopeCacheable = this._styles.every(function(s) {
return s._cacheable;
});
if (scopeCacheable) {
scopeData.key.customStyle = {};
this.mixin(scopeData.key.customStyle, this.customStyle);
Expand Down

0 comments on commit bc9519e

Please sign in to comment.