mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
Ugh
This commit is contained in:
parent
b1ea014529
commit
172d93cf4f
@ -1,275 +1,275 @@
|
||||
<!--
|
||||
@license
|
||||
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||
Code distributed by Google as part of the polymer project is also
|
||||
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
-->
|
||||
|
||||
<link rel="import" href="style-util.html">
|
||||
|
||||
<script>
|
||||
|
||||
Polymer.StyleTransformer = (function() {
|
||||
|
||||
var nativeShadow = Polymer.Settings.useNativeShadow;
|
||||
var styleUtil = Polymer.StyleUtil;
|
||||
|
||||
/* Transforms ShadowDOM styling into ShadyDOM styling
|
||||
|
||||
* scoping:
|
||||
|
||||
* elements in scope get scoping selector class="x-foo-scope"
|
||||
* selectors re-written as follows:
|
||||
|
||||
div button -> div.x-foo-scope button.x-foo-scope
|
||||
|
||||
* :host -> scopeName
|
||||
|
||||
* :host(...) -> scopeName...
|
||||
|
||||
* ::content -> ' ' NOTE: requires use of scoping selector and selectors
|
||||
cannot otherwise be scoped:
|
||||
e.g. :host ::content > .bar -> x-foo > .bar
|
||||
|
||||
* ::shadow, /deep/: processed similar to ::content
|
||||
|
||||
* :host-context(...): scopeName..., ... scopeName
|
||||
|
||||
*/
|
||||
var api = {
|
||||
|
||||
// Given a node and scope name, add a scoping class to each node
|
||||
// in the tree. This facilitates transforming css into scoped rules.
|
||||
dom: function(node, scope, useAttr, shouldRemoveScope) {
|
||||
this._transformDom(node, scope || '', useAttr, shouldRemoveScope);
|
||||
},
|
||||
|
||||
_transformDom: function(node, selector, useAttr, shouldRemoveScope) {
|
||||
if (node.setAttribute) {
|
||||
this.element(node, selector, useAttr, shouldRemoveScope);
|
||||
}
|
||||
var c$ = Polymer.dom(node).childNodes;
|
||||
for (var i=0; i<c$.length; i++) {
|
||||
this._transformDom(c$[i], selector, useAttr, shouldRemoveScope);
|
||||
}
|
||||
},
|
||||
|
||||
element: function(element, scope, useAttr, shouldRemoveScope) {
|
||||
if (useAttr) {
|
||||
if (shouldRemoveScope) {
|
||||
element.removeAttribute(SCOPE_NAME);
|
||||
} else {
|
||||
element.setAttribute(SCOPE_NAME, scope);
|
||||
}
|
||||
} else {
|
||||
// note: if using classes, we add both the general 'style-scope' class
|
||||
// as well as the specific scope. This enables easy filtering of all
|
||||
// `style-scope` elements
|
||||
if (scope) {
|
||||
// note: svg on IE does not have classList so fallback to class
|
||||
if (element.classList) {
|
||||
if (shouldRemoveScope) {
|
||||
element.classList.remove(SCOPE_NAME);
|
||||
element.classList.remove(scope);
|
||||
} else {
|
||||
element.classList.add(SCOPE_NAME);
|
||||
element.classList.add(scope);
|
||||
}
|
||||
} else if (element.getAttribute) {
|
||||
var c = element.getAttribute(CLASS);
|
||||
if (shouldRemoveScope) {
|
||||
if (c) {
|
||||
element.setAttribute(CLASS, c.replace(SCOPE_NAME, '')
|
||||
.replace(scope, ''));
|
||||
}
|
||||
} else {
|
||||
element.setAttribute(CLASS, c + (c ? ' ' : '') +
|
||||
SCOPE_NAME + ' ' + scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
elementStyles: function(element, callback) {
|
||||
var styles = element._styles;
|
||||
var cssText = '';
|
||||
for (var i=0, l=styles.length, s; (i<l) && (s=styles[i]); i++) {
|
||||
var rules = styleUtil.rulesForStyle(s);
|
||||
cssText += nativeShadow ?
|
||||
styleUtil.toCssText(rules, callback) :
|
||||
this.css(rules, element.is, element.extends, callback,
|
||||
element._scopeCssViaAttr) + '\n\n';
|
||||
}
|
||||
return cssText.trim();
|
||||
},
|
||||
|
||||
// Given a string of cssText and a scoping string (scope), returns
|
||||
// a string of scoped css where each selector is transformed to include
|
||||
// a class created from the scope. ShadowDOM selectors are also transformed
|
||||
// (e.g. :host) to use the scoping selector.
|
||||
css: function(rules, scope, ext, callback, useAttr) {
|
||||
var hostScope = this._calcHostScope(scope, ext);
|
||||
scope = this._calcElementScope(scope, useAttr);
|
||||
var self = this;
|
||||
return styleUtil.toCssText(rules, function(rule) {
|
||||
if (!rule.isScoped) {
|
||||
self.rule(rule, scope, hostScope);
|
||||
rule.isScoped = true;
|
||||
}
|
||||
if (callback) {
|
||||
callback(rule, scope, hostScope);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_calcElementScope: function (scope, useAttr) {
|
||||
if (scope) {
|
||||
return useAttr ?
|
||||
CSS_ATTR_PREFIX + scope + CSS_ATTR_SUFFIX :
|
||||
CSS_CLASS_PREFIX + scope;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
_calcHostScope: function(scope, ext) {
|
||||
return ext ? '[is=' + scope + ']' : scope;
|
||||
},
|
||||
|
||||
rule: function (rule, scope, hostScope) {
|
||||
this._transformRule(rule, this._transformComplexSelector,
|
||||
scope, hostScope);
|
||||
},
|
||||
|
||||
// transforms a css rule to a scoped rule.
|
||||
_transformRule: function(rule, transformer, scope, hostScope) {
|
||||
var p$ = rule.selector.split(COMPLEX_SELECTOR_SEP);
|
||||
for (var i=0, l=p$.length, p; (i<l) && (p=p$[i]); i++) {
|
||||
p$[i] = transformer.call(this, p, scope, hostScope);
|
||||
}
|
||||
// NOTE: save transformedSelector for subsequent matching of elements
|
||||
// against selectors (e.g. when calculating style properties)
|
||||
rule.selector = rule.transformedSelector =
|
||||
p$.join(COMPLEX_SELECTOR_SEP);
|
||||
},
|
||||
|
||||
_transformComplexSelector: function(selector, scope, hostScope) {
|
||||
var stop = false;
|
||||
var hostContext = false;
|
||||
var self = this;
|
||||
selector = selector.replace(SIMPLE_SELECTOR_SEP, function(m, c, s) {
|
||||
if (!stop) {
|
||||
var info = self._transformCompoundSelector(s, c, scope, hostScope);
|
||||
stop = stop || info.stop;
|
||||
hostContext = hostContext || info.hostContext;
|
||||
c = info.combinator;
|
||||
s = info.value;
|
||||
} else {
|
||||
s = s.replace(SCOPE_JUMP, ' ');
|
||||
}
|
||||
return c + s;
|
||||
});
|
||||
if (hostContext) {
|
||||
selector = selector.replace(HOST_CONTEXT_PAREN,
|
||||
function(m, pre, paren, post) {
|
||||
return pre + paren + ' ' + hostScope + post +
|
||||
COMPLEX_SELECTOR_SEP + ' ' + pre + hostScope + paren + post;
|
||||
});
|
||||
}
|
||||
return selector;
|
||||
},
|
||||
|
||||
_transformCompoundSelector: function(selector, combinator, scope, hostScope) {
|
||||
// replace :host with host scoping class
|
||||
var jumpIndex = selector.search(SCOPE_JUMP);
|
||||
var hostContext = false;
|
||||
if (selector.indexOf(HOST_CONTEXT) >=0) {
|
||||
hostContext = true;
|
||||
} else if (selector.indexOf(HOST) >=0) {
|
||||
// :host(...) -> scopeName...
|
||||
selector = selector.replace(HOST_PAREN, function(m, host, paren) {
|
||||
return hostScope + paren;
|
||||
});
|
||||
// now normal :host
|
||||
selector = selector.replace(HOST, hostScope);
|
||||
// replace other selectors with scoping class
|
||||
} else if (jumpIndex !== 0) {
|
||||
selector = scope ? this._transformSimpleSelector(selector, scope) :
|
||||
selector;
|
||||
}
|
||||
// remove left-side combinator when dealing with ::content.
|
||||
if (selector.indexOf(CONTENT) >= 0) {
|
||||
combinator = '';
|
||||
}
|
||||
// process scope jumping selectors up to the scope jump and then stop
|
||||
// e.g. .zonk ::content > .foo ==> .zonk.scope > .foo
|
||||
var stop;
|
||||
if (jumpIndex >= 0) {
|
||||
selector = selector.replace(SCOPE_JUMP, ' ');
|
||||
stop = true;
|
||||
}
|
||||
return {value: selector, combinator: combinator, stop: stop,
|
||||
hostContext: hostContext};
|
||||
},
|
||||
|
||||
_transformSimpleSelector: function(selector, scope) {
|
||||
var p$ = selector.split(PSEUDO_PREFIX);
|
||||
p$[0] += scope;
|
||||
return p$.join(PSEUDO_PREFIX);
|
||||
},
|
||||
|
||||
documentRule: function(rule) {
|
||||
// reset selector in case this is redone.
|
||||
rule.selector = rule.parsedSelector;
|
||||
this.normalizeRootSelector(rule);
|
||||
if (!nativeShadow) {
|
||||
this._transformRule(rule, this._transformDocumentSelector);
|
||||
}
|
||||
},
|
||||
|
||||
normalizeRootSelector: function(rule) {
|
||||
if (rule.selector === ROOT) {
|
||||
rule.selector = 'body';
|
||||
}
|
||||
},
|
||||
|
||||
_transformDocumentSelector: function(selector) {
|
||||
return selector.match(SCOPE_JUMP) ?
|
||||
this._transformComplexSelector(selector, SCOPE_DOC_SELECTOR) :
|
||||
this._transformSimpleSelector(selector.trim(), SCOPE_DOC_SELECTOR);
|
||||
},
|
||||
|
||||
SCOPE_NAME: 'style-scope'
|
||||
};
|
||||
|
||||
var SCOPE_NAME = api.SCOPE_NAME;
|
||||
var SCOPE_DOC_SELECTOR = ':not([' + SCOPE_NAME + '])' +
|
||||
':not(.' + SCOPE_NAME + ')';
|
||||
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
|
||||
var HOST_PAREN = /(\:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g;
|
||||
var HOST_CONTEXT = ':host-context';
|
||||
var HOST_CONTEXT_PAREN = /(.*)(?::host-context)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))(.*)/;
|
||||
var CONTENT = '::content';
|
||||
var SCOPE_JUMP = /::content|::shadow|\/deep\//;
|
||||
var CSS_CLASS_PREFIX = '.';
|
||||
var CSS_ATTR_PREFIX = '[' + SCOPE_NAME + '~=';
|
||||
var CSS_ATTR_SUFFIX = ']';
|
||||
var PSEUDO_PREFIX = ':';
|
||||
var CLASS = 'class';
|
||||
|
||||
// exports
|
||||
return api;
|
||||
|
||||
})();
|
||||
|
||||
</script>
|
||||
<!--
|
||||
@license
|
||||
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||
Code distributed by Google as part of the polymer project is also
|
||||
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
-->
|
||||
|
||||
<link rel="import" href="style-util.html">
|
||||
|
||||
<script>
|
||||
|
||||
Polymer.StyleTransformer = (function() {
|
||||
|
||||
var nativeShadow = Polymer.Settings.useNativeShadow;
|
||||
var styleUtil = Polymer.StyleUtil;
|
||||
|
||||
/* Transforms ShadowDOM styling into ShadyDOM styling
|
||||
|
||||
* scoping:
|
||||
|
||||
* elements in scope get scoping selector class="x-foo-scope"
|
||||
* selectors re-written as follows:
|
||||
|
||||
div button -> div.x-foo-scope button.x-foo-scope
|
||||
|
||||
* :host -> scopeName
|
||||
|
||||
* :host(...) -> scopeName...
|
||||
|
||||
* ::content -> ' ' NOTE: requires use of scoping selector and selectors
|
||||
cannot otherwise be scoped:
|
||||
e.g. :host ::content > .bar -> x-foo > .bar
|
||||
|
||||
* ::shadow, /deep/: processed similar to ::content
|
||||
|
||||
* :host-context(...): scopeName..., ... scopeName
|
||||
|
||||
*/
|
||||
var api = {
|
||||
|
||||
// Given a node and scope name, add a scoping class to each node
|
||||
// in the tree. This facilitates transforming css into scoped rules.
|
||||
dom: function(node, scope, useAttr, shouldRemoveScope) {
|
||||
this._transformDom(node, scope || '', useAttr, shouldRemoveScope);
|
||||
},
|
||||
|
||||
_transformDom: function(node, selector, useAttr, shouldRemoveScope) {
|
||||
if (node.setAttribute) {
|
||||
this.element(node, selector, useAttr, shouldRemoveScope);
|
||||
}
|
||||
var c$ = Polymer.dom(node).childNodes;
|
||||
for (var i=0; i<c$.length; i++) {
|
||||
this._transformDom(c$[i], selector, useAttr, shouldRemoveScope);
|
||||
}
|
||||
},
|
||||
|
||||
element: function(element, scope, useAttr, shouldRemoveScope) {
|
||||
if (useAttr) {
|
||||
if (shouldRemoveScope) {
|
||||
element.removeAttribute(SCOPE_NAME);
|
||||
} else {
|
||||
element.setAttribute(SCOPE_NAME, scope);
|
||||
}
|
||||
} else {
|
||||
// note: if using classes, we add both the general 'style-scope' class
|
||||
// as well as the specific scope. This enables easy filtering of all
|
||||
// `style-scope` elements
|
||||
if (scope) {
|
||||
// note: svg on IE does not have classList so fallback to class
|
||||
if (element.classList) {
|
||||
if (shouldRemoveScope) {
|
||||
element.classList.remove(SCOPE_NAME);
|
||||
element.classList.remove(scope);
|
||||
} else {
|
||||
element.classList.add(SCOPE_NAME);
|
||||
element.classList.add(scope);
|
||||
}
|
||||
} else if (element.getAttribute) {
|
||||
var c = element.getAttribute(CLASS);
|
||||
if (shouldRemoveScope) {
|
||||
if (c) {
|
||||
element.setAttribute(CLASS, c.replace(SCOPE_NAME, '')
|
||||
.replace(scope, ''));
|
||||
}
|
||||
} else {
|
||||
element.setAttribute(CLASS, (c ? c + ' ' : '') +
|
||||
SCOPE_NAME + ' ' + scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
elementStyles: function(element, callback) {
|
||||
var styles = element._styles;
|
||||
var cssText = '';
|
||||
for (var i=0, l=styles.length, s; (i<l) && (s=styles[i]); i++) {
|
||||
var rules = styleUtil.rulesForStyle(s);
|
||||
cssText += nativeShadow ?
|
||||
styleUtil.toCssText(rules, callback) :
|
||||
this.css(rules, element.is, element.extends, callback,
|
||||
element._scopeCssViaAttr) + '\n\n';
|
||||
}
|
||||
return cssText.trim();
|
||||
},
|
||||
|
||||
// Given a string of cssText and a scoping string (scope), returns
|
||||
// a string of scoped css where each selector is transformed to include
|
||||
// a class created from the scope. ShadowDOM selectors are also transformed
|
||||
// (e.g. :host) to use the scoping selector.
|
||||
css: function(rules, scope, ext, callback, useAttr) {
|
||||
var hostScope = this._calcHostScope(scope, ext);
|
||||
scope = this._calcElementScope(scope, useAttr);
|
||||
var self = this;
|
||||
return styleUtil.toCssText(rules, function(rule) {
|
||||
if (!rule.isScoped) {
|
||||
self.rule(rule, scope, hostScope);
|
||||
rule.isScoped = true;
|
||||
}
|
||||
if (callback) {
|
||||
callback(rule, scope, hostScope);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_calcElementScope: function (scope, useAttr) {
|
||||
if (scope) {
|
||||
return useAttr ?
|
||||
CSS_ATTR_PREFIX + scope + CSS_ATTR_SUFFIX :
|
||||
CSS_CLASS_PREFIX + scope;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
_calcHostScope: function(scope, ext) {
|
||||
return ext ? '[is=' + scope + ']' : scope;
|
||||
},
|
||||
|
||||
rule: function (rule, scope, hostScope) {
|
||||
this._transformRule(rule, this._transformComplexSelector,
|
||||
scope, hostScope);
|
||||
},
|
||||
|
||||
// transforms a css rule to a scoped rule.
|
||||
_transformRule: function(rule, transformer, scope, hostScope) {
|
||||
var p$ = rule.selector.split(COMPLEX_SELECTOR_SEP);
|
||||
for (var i=0, l=p$.length, p; (i<l) && (p=p$[i]); i++) {
|
||||
p$[i] = transformer.call(this, p, scope, hostScope);
|
||||
}
|
||||
// NOTE: save transformedSelector for subsequent matching of elements
|
||||
// against selectors (e.g. when calculating style properties)
|
||||
rule.selector = rule.transformedSelector =
|
||||
p$.join(COMPLEX_SELECTOR_SEP);
|
||||
},
|
||||
|
||||
_transformComplexSelector: function(selector, scope, hostScope) {
|
||||
var stop = false;
|
||||
var hostContext = false;
|
||||
var self = this;
|
||||
selector = selector.replace(SIMPLE_SELECTOR_SEP, function(m, c, s) {
|
||||
if (!stop) {
|
||||
var info = self._transformCompoundSelector(s, c, scope, hostScope);
|
||||
stop = stop || info.stop;
|
||||
hostContext = hostContext || info.hostContext;
|
||||
c = info.combinator;
|
||||
s = info.value;
|
||||
} else {
|
||||
s = s.replace(SCOPE_JUMP, ' ');
|
||||
}
|
||||
return c + s;
|
||||
});
|
||||
if (hostContext) {
|
||||
selector = selector.replace(HOST_CONTEXT_PAREN,
|
||||
function(m, pre, paren, post) {
|
||||
return pre + paren + ' ' + hostScope + post +
|
||||
COMPLEX_SELECTOR_SEP + ' ' + pre + hostScope + paren + post;
|
||||
});
|
||||
}
|
||||
return selector;
|
||||
},
|
||||
|
||||
_transformCompoundSelector: function(selector, combinator, scope, hostScope) {
|
||||
// replace :host with host scoping class
|
||||
var jumpIndex = selector.search(SCOPE_JUMP);
|
||||
var hostContext = false;
|
||||
if (selector.indexOf(HOST_CONTEXT) >=0) {
|
||||
hostContext = true;
|
||||
} else if (selector.indexOf(HOST) >=0) {
|
||||
// :host(...) -> scopeName...
|
||||
selector = selector.replace(HOST_PAREN, function(m, host, paren) {
|
||||
return hostScope + paren;
|
||||
});
|
||||
// now normal :host
|
||||
selector = selector.replace(HOST, hostScope);
|
||||
// replace other selectors with scoping class
|
||||
} else if (jumpIndex !== 0) {
|
||||
selector = scope ? this._transformSimpleSelector(selector, scope) :
|
||||
selector;
|
||||
}
|
||||
// remove left-side combinator when dealing with ::content.
|
||||
if (selector.indexOf(CONTENT) >= 0) {
|
||||
combinator = '';
|
||||
}
|
||||
// process scope jumping selectors up to the scope jump and then stop
|
||||
// e.g. .zonk ::content > .foo ==> .zonk.scope > .foo
|
||||
var stop;
|
||||
if (jumpIndex >= 0) {
|
||||
selector = selector.replace(SCOPE_JUMP, ' ');
|
||||
stop = true;
|
||||
}
|
||||
return {value: selector, combinator: combinator, stop: stop,
|
||||
hostContext: hostContext};
|
||||
},
|
||||
|
||||
_transformSimpleSelector: function(selector, scope) {
|
||||
var p$ = selector.split(PSEUDO_PREFIX);
|
||||
p$[0] += scope;
|
||||
return p$.join(PSEUDO_PREFIX);
|
||||
},
|
||||
|
||||
documentRule: function(rule) {
|
||||
// reset selector in case this is redone.
|
||||
rule.selector = rule.parsedSelector;
|
||||
this.normalizeRootSelector(rule);
|
||||
if (!nativeShadow) {
|
||||
this._transformRule(rule, this._transformDocumentSelector);
|
||||
}
|
||||
},
|
||||
|
||||
normalizeRootSelector: function(rule) {
|
||||
if (rule.selector === ROOT) {
|
||||
rule.selector = 'body';
|
||||
}
|
||||
},
|
||||
|
||||
_transformDocumentSelector: function(selector) {
|
||||
return selector.match(SCOPE_JUMP) ?
|
||||
this._transformComplexSelector(selector, SCOPE_DOC_SELECTOR) :
|
||||
this._transformSimpleSelector(selector.trim(), SCOPE_DOC_SELECTOR);
|
||||
},
|
||||
|
||||
SCOPE_NAME: 'style-scope'
|
||||
};
|
||||
|
||||
var SCOPE_NAME = api.SCOPE_NAME;
|
||||
var SCOPE_DOC_SELECTOR = ':not([' + SCOPE_NAME + '])' +
|
||||
':not(.' + SCOPE_NAME + ')';
|
||||
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
|
||||
var HOST_PAREN = /(\:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g;
|
||||
var HOST_CONTEXT = ':host-context';
|
||||
var HOST_CONTEXT_PAREN = /(.*)(?::host-context)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))(.*)/;
|
||||
var CONTENT = '::content';
|
||||
var SCOPE_JUMP = /::content|::shadow|\/deep\//;
|
||||
var CSS_CLASS_PREFIX = '.';
|
||||
var CSS_ATTR_PREFIX = '[' + SCOPE_NAME + '~=';
|
||||
var CSS_ATTR_SUFFIX = ']';
|
||||
var PSEUDO_PREFIX = ':';
|
||||
var CLASS = 'class';
|
||||
|
||||
// exports
|
||||
return api;
|
||||
|
||||
})();
|
||||
|
||||
</script>
|
||||
|
@ -1,292 +1,292 @@
|
||||
<!--
|
||||
@license
|
||||
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||
Code distributed by Google as part of the polymer project is also
|
||||
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
-->
|
||||
<link rel="import" href="../lib/style-properties.html">
|
||||
<link rel="import" href="../lib/settings.html">
|
||||
<link rel="import" href="../lib/style-defaults.html">
|
||||
<link rel="import" href="../lib/style-cache.html">
|
||||
<script>
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var serializeValueToAttribute = Polymer.Base.serializeValueToAttribute;
|
||||
|
||||
var propertyUtils = Polymer.StyleProperties;
|
||||
var styleTransformer = Polymer.StyleTransformer;
|
||||
var styleUtil = Polymer.StyleUtil;
|
||||
var styleDefaults = Polymer.StyleDefaults;
|
||||
|
||||
var nativeShadow = Polymer.Settings.useNativeShadow;
|
||||
|
||||
Polymer.Base._addFeature({
|
||||
|
||||
_prepStyleProperties: function() {
|
||||
// note: an element should produce an x-scope stylesheet
|
||||
// if it has any _stylePropertyNames
|
||||
this._ownStylePropertyNames = this._styles ?
|
||||
propertyUtils.decorateStyles(this._styles) :
|
||||
null;
|
||||
},
|
||||
|
||||
/**
|
||||
* An element's style properties can be directly modified by
|
||||
* setting key-value pairs in `customStyle` on the element
|
||||
* (analogous to setting `style`) and then calling `updateStyles()`.
|
||||
*
|
||||
*/
|
||||
customStyle: null,
|
||||
|
||||
/**
|
||||
* Returns the computed style value for the given property.
|
||||
* @param {String} property
|
||||
* @return {String} the computed value
|
||||
*/
|
||||
getComputedStyleValue: function(property) {
|
||||
return this._styleProperties && this._styleProperties[property] ||
|
||||
getComputedStyle(this).getPropertyValue(property);
|
||||
},
|
||||
|
||||
// here we have an instance time spot to put custom property data
|
||||
_setupStyleProperties: function() {
|
||||
this.customStyle = {};
|
||||
this._styleCache = null;
|
||||
this._styleProperties = null;
|
||||
this._scopeSelector = null;
|
||||
this._ownStyleProperties = null;
|
||||
this._customStyle = null;
|
||||
},
|
||||
|
||||
_needsStyleProperties: function() {
|
||||
return Boolean(this._ownStylePropertyNames &&
|
||||
this._ownStylePropertyNames.length);
|
||||
},
|
||||
|
||||
_beforeAttached: function() {
|
||||
// note: do this once automatically,
|
||||
// then requires calling `updateStyles`
|
||||
if (!this._scopeSelector && this._needsStyleProperties()) {
|
||||
this._updateStyleProperties();
|
||||
}
|
||||
},
|
||||
|
||||
_findStyleHost: function() {
|
||||
var e = this, root;
|
||||
while (root = Polymer.dom(e).getOwnerRoot()) {
|
||||
if (Polymer.isInstance(root.host)) {
|
||||
return root.host;
|
||||
}
|
||||
e = root.host;
|
||||
}
|
||||
return styleDefaults;
|
||||
},
|
||||
|
||||
_updateStyleProperties: function() {
|
||||
var info, scope = this._findStyleHost();
|
||||
// install cache in host if it doesn't exist.
|
||||
if (!scope._styleCache) {
|
||||
scope._styleCache = new Polymer.StyleCache();
|
||||
}
|
||||
var scopeData = propertyUtils
|
||||
.propertyDataFromStyles(scope._styles, this);
|
||||
// look in scope cache
|
||||
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) {
|
||||
// when scope cached, we can safely take style propertis out of the
|
||||
// scope cache because they are only for this scope.
|
||||
this._styleProperties = info._styleProperties;
|
||||
} else {
|
||||
this._computeStyleProperties(scopeData.properties);
|
||||
}
|
||||
this._computeOwnStyleProperties();
|
||||
// cache miss, do work!
|
||||
if (!scopeCached) {
|
||||
// and look in 2ndary global cache
|
||||
info = styleCache.retrieve(this.is,
|
||||
this._ownStyleProperties, this._styles);
|
||||
}
|
||||
var globalCached = Boolean(info) && !scopeCached;
|
||||
// now we have properties and a cached style if one
|
||||
// is available.
|
||||
var style = this._applyStyleProperties(info);
|
||||
// no cache so store in cache
|
||||
//console.warn(this.is, scopeCached, globalCached, info && info._scopeSelector);
|
||||
if (!scopeCached) {
|
||||
// create an info object for caching
|
||||
// TODO(sorvell): clone style node when using native Shadow DOM
|
||||
// so a style used in a root does not itself get stored in the cache
|
||||
// This can lead to incorrect sharing, but should be fixed
|
||||
// in `Polymer.StyleProperties.applyElementStyle`
|
||||
style = style && nativeShadow ? style.cloneNode(true) : style;
|
||||
info = {
|
||||
style: style,
|
||||
_scopeSelector: this._scopeSelector,
|
||||
_styleProperties: this._styleProperties
|
||||
};
|
||||
scopeData.key.customStyle = {};
|
||||
this.mixin(scopeData.key.customStyle, this.customStyle);
|
||||
scope._styleCache.store(this.is, info, scopeData.key, this._styles);
|
||||
if (!globalCached) {
|
||||
// save in global cache
|
||||
styleCache.store(this.is, Object.create(info), this._ownStyleProperties,
|
||||
this._styles);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_computeStyleProperties: function(scopeProps) {
|
||||
// get scope and make sure it has properties
|
||||
var scope = this._findStyleHost();
|
||||
// force scope to compute properties if they don't exist or if forcing
|
||||
// and it doesn't need properties
|
||||
if (!scope._styleProperties) {
|
||||
scope._computeStyleProperties();
|
||||
}
|
||||
// start with scope style properties
|
||||
var props = Object.create(scope._styleProperties);
|
||||
// mixin own host properties (lower specifity than scope props)
|
||||
this.mixin(props, propertyUtils.hostPropertiesFromStyles(this._styles));
|
||||
// mixin properties matching this element in scope
|
||||
scopeProps = scopeProps ||
|
||||
propertyUtils.propertyDataFromStyles(scope._styles, this).properties;
|
||||
this.mixin(props, scopeProps);
|
||||
// finally mixin properties inherent to this element
|
||||
this.mixin(props,
|
||||
propertyUtils.scopePropertiesFromStyles(this._styles));
|
||||
propertyUtils.mixinCustomStyle(props, this.customStyle);
|
||||
// reify properties (note: only does own properties)
|
||||
propertyUtils.reify(props);
|
||||
this._styleProperties = props;
|
||||
},
|
||||
|
||||
_computeOwnStyleProperties: function() {
|
||||
var props = {};
|
||||
for (var i=0, n; i < this._ownStylePropertyNames.length; i++) {
|
||||
n = this._ownStylePropertyNames[i];
|
||||
props[n] = this._styleProperties[n];
|
||||
}
|
||||
this._ownStyleProperties = props;
|
||||
},
|
||||
|
||||
_scopeCount: 0,
|
||||
|
||||
_applyStyleProperties: function(info) {
|
||||
// update scope selector (needed for style transformation)
|
||||
var oldScopeSelector = this._scopeSelector;
|
||||
// note, the scope selector is incremented per class counter
|
||||
this._scopeSelector = info ? info._scopeSelector :
|
||||
this.is + '-' + this.__proto__._scopeCount++;
|
||||
var style = propertyUtils.applyElementStyle(this,
|
||||
this._styleProperties, this._scopeSelector, info && info.style);
|
||||
// apply scope selector
|
||||
if (!nativeShadow) {
|
||||
propertyUtils.applyElementScopeSelector(this, this._scopeSelector,
|
||||
oldScopeSelector, this._scopeCssViaAttr);
|
||||
}
|
||||
return style;
|
||||
},
|
||||
|
||||
serializeValueToAttribute: function(value, attribute, node) {
|
||||
// override to ensure whenever classes are set, we need to shim them.
|
||||
node = node || this;
|
||||
if (attribute === 'class' && !nativeShadow) {
|
||||
// host needed to scope styling.
|
||||
// Under Shady DOM, domHost is safe to use here because we know it
|
||||
// is a Polymer element
|
||||
var host = node === this ? (this.domHost || this.dataHost) : this;
|
||||
if (host) {
|
||||
value = host._scopeElementClass(node, value);
|
||||
}
|
||||
}
|
||||
// note: using Polymer.dom here ensures that any attribute sets
|
||||
// will provoke distribution if necessary; do this iff necessary
|
||||
node = (this.shadyRoot && this.shadyRoot._hasDistributed) ?
|
||||
Polymer.dom(node) : node;
|
||||
serializeValueToAttribute.call(this, value, attribute, node);
|
||||
},
|
||||
|
||||
_scopeElementClass: function(element, selector) {
|
||||
if (!nativeShadow && !this._scopeCssViaAttr) {
|
||||
selector += (selector ? ' ' : '') + SCOPE_NAME + ' ' + this.is +
|
||||
(element._scopeSelector ? ' ' + XSCOPE_NAME + ' ' +
|
||||
element._scopeSelector : '');
|
||||
}
|
||||
return selector;
|
||||
},
|
||||
|
||||
/**
|
||||
* Re-evaluates and applies custom CSS properties based on dynamic
|
||||
* changes to this element's scope, such as adding or removing classes
|
||||
* in this element's local DOM.
|
||||
*
|
||||
* For performance reasons, Polymer's custom CSS property shim relies
|
||||
* on this explicit signal from the user to indicate when changes have
|
||||
* been made that affect the values of custom properties.
|
||||
*
|
||||
* @method updateStyles
|
||||
* @param {Object=} properties Properties object which is mixed into
|
||||
* the element's `customStyle` property. This argument provides a shortcut
|
||||
* for setting `customStyle` and then calling `updateStyles`.
|
||||
*/
|
||||
updateStyles: function(properties) {
|
||||
if (this.isAttached) {
|
||||
if (properties) {
|
||||
this.mixin(this.customStyle, properties);
|
||||
}
|
||||
// skip applying properties to self if not used
|
||||
if (this._needsStyleProperties()) {
|
||||
this._updateStyleProperties();
|
||||
// when an element doesn't use style properties, its own properties
|
||||
// should be invalidated so elements down the tree update ok.
|
||||
} else {
|
||||
this._styleProperties = null;
|
||||
}
|
||||
if (this._styleCache) {
|
||||
this._styleCache.clear();
|
||||
}
|
||||
// always apply properties to root
|
||||
this._updateRootStyles();
|
||||
}
|
||||
},
|
||||
|
||||
_updateRootStyles: function(root) {
|
||||
root = root || this.root;
|
||||
var c$ = Polymer.dom(root)._query(function(e) {
|
||||
return e.shadyRoot || e.shadowRoot;
|
||||
});
|
||||
for (var i=0, l= c$.length, c; (i<l) && (c=c$[i]); i++) {
|
||||
if (c.updateStyles) {
|
||||
c.updateStyles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Force all custom elements using cross scope custom properties,
|
||||
* to update styling.
|
||||
*/
|
||||
Polymer.updateStyles = function(properties) {
|
||||
// update default/custom styles
|
||||
styleDefaults.updateStyles(properties);
|
||||
// search the document for elements to update
|
||||
Polymer.Base._updateRootStyles(document);
|
||||
};
|
||||
|
||||
var styleCache = new Polymer.StyleCache();
|
||||
Polymer.customStyleCache = styleCache;
|
||||
|
||||
var SCOPE_NAME = styleTransformer.SCOPE_NAME;
|
||||
var XSCOPE_NAME = propertyUtils.XSCOPE_NAME;
|
||||
|
||||
})();
|
||||
</script>
|
||||
<!--
|
||||
@license
|
||||
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||
Code distributed by Google as part of the polymer project is also
|
||||
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
-->
|
||||
<link rel="import" href="../lib/style-properties.html">
|
||||
<link rel="import" href="../lib/settings.html">
|
||||
<link rel="import" href="../lib/style-defaults.html">
|
||||
<link rel="import" href="../lib/style-cache.html">
|
||||
<script>
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var serializeValueToAttribute = Polymer.Base.serializeValueToAttribute;
|
||||
|
||||
var propertyUtils = Polymer.StyleProperties;
|
||||
var styleTransformer = Polymer.StyleTransformer;
|
||||
var styleUtil = Polymer.StyleUtil;
|
||||
var styleDefaults = Polymer.StyleDefaults;
|
||||
|
||||
var nativeShadow = Polymer.Settings.useNativeShadow;
|
||||
|
||||
Polymer.Base._addFeature({
|
||||
|
||||
_prepStyleProperties: function() {
|
||||
// note: an element should produce an x-scope stylesheet
|
||||
// if it has any _stylePropertyNames
|
||||
this._ownStylePropertyNames = this._styles ?
|
||||
propertyUtils.decorateStyles(this._styles) :
|
||||
null;
|
||||
},
|
||||
|
||||
/**
|
||||
* An element's style properties can be directly modified by
|
||||
* setting key-value pairs in `customStyle` on the element
|
||||
* (analogous to setting `style`) and then calling `updateStyles()`.
|
||||
*
|
||||
*/
|
||||
customStyle: null,
|
||||
|
||||
/**
|
||||
* Returns the computed style value for the given property.
|
||||
* @param {String} property
|
||||
* @return {String} the computed value
|
||||
*/
|
||||
getComputedStyleValue: function(property) {
|
||||
return this._styleProperties && this._styleProperties[property] ||
|
||||
getComputedStyle(this).getPropertyValue(property);
|
||||
},
|
||||
|
||||
// here we have an instance time spot to put custom property data
|
||||
_setupStyleProperties: function() {
|
||||
this.customStyle = {};
|
||||
this._styleCache = null;
|
||||
this._styleProperties = null;
|
||||
this._scopeSelector = null;
|
||||
this._ownStyleProperties = null;
|
||||
this._customStyle = null;
|
||||
},
|
||||
|
||||
_needsStyleProperties: function() {
|
||||
return Boolean(this._ownStylePropertyNames &&
|
||||
this._ownStylePropertyNames.length);
|
||||
},
|
||||
|
||||
_beforeAttached: function() {
|
||||
// note: do this once automatically,
|
||||
// then requires calling `updateStyles`
|
||||
if (!this._scopeSelector && this._needsStyleProperties()) {
|
||||
this._updateStyleProperties();
|
||||
}
|
||||
},
|
||||
|
||||
_findStyleHost: function() {
|
||||
var e = this, root;
|
||||
while (root = Polymer.dom(e).getOwnerRoot()) {
|
||||
if (Polymer.isInstance(root.host)) {
|
||||
return root.host;
|
||||
}
|
||||
e = root.host;
|
||||
}
|
||||
return styleDefaults;
|
||||
},
|
||||
|
||||
_updateStyleProperties: function() {
|
||||
var info, scope = this._findStyleHost();
|
||||
// install cache in host if it doesn't exist.
|
||||
if (!scope._styleCache) {
|
||||
scope._styleCache = new Polymer.StyleCache();
|
||||
}
|
||||
var scopeData = propertyUtils
|
||||
.propertyDataFromStyles(scope._styles, this);
|
||||
// look in scope cache
|
||||
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) {
|
||||
// when scope cached, we can safely take style propertis out of the
|
||||
// scope cache because they are only for this scope.
|
||||
this._styleProperties = info._styleProperties;
|
||||
} else {
|
||||
this._computeStyleProperties(scopeData.properties);
|
||||
}
|
||||
this._computeOwnStyleProperties();
|
||||
// cache miss, do work!
|
||||
if (!scopeCached) {
|
||||
// and look in 2ndary global cache
|
||||
info = styleCache.retrieve(this.is,
|
||||
this._ownStyleProperties, this._styles);
|
||||
}
|
||||
var globalCached = Boolean(info) && !scopeCached;
|
||||
// now we have properties and a cached style if one
|
||||
// is available.
|
||||
var style = this._applyStyleProperties(info);
|
||||
// no cache so store in cache
|
||||
//console.warn(this.is, scopeCached, globalCached, info && info._scopeSelector);
|
||||
if (!scopeCached) {
|
||||
// create an info object for caching
|
||||
// TODO(sorvell): clone style node when using native Shadow DOM
|
||||
// so a style used in a root does not itself get stored in the cache
|
||||
// This can lead to incorrect sharing, but should be fixed
|
||||
// in `Polymer.StyleProperties.applyElementStyle`
|
||||
style = style && nativeShadow ? style.cloneNode(true) : style;
|
||||
info = {
|
||||
style: style,
|
||||
_scopeSelector: this._scopeSelector,
|
||||
_styleProperties: this._styleProperties
|
||||
};
|
||||
scopeData.key.customStyle = {};
|
||||
this.mixin(scopeData.key.customStyle, this.customStyle);
|
||||
scope._styleCache.store(this.is, info, scopeData.key, this._styles);
|
||||
if (!globalCached) {
|
||||
// save in global cache
|
||||
styleCache.store(this.is, Object.create(info), this._ownStyleProperties,
|
||||
this._styles);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_computeStyleProperties: function(scopeProps) {
|
||||
// get scope and make sure it has properties
|
||||
var scope = this._findStyleHost();
|
||||
// force scope to compute properties if they don't exist or if forcing
|
||||
// and it doesn't need properties
|
||||
if (!scope._styleProperties) {
|
||||
scope._computeStyleProperties();
|
||||
}
|
||||
// start with scope style properties
|
||||
var props = Object.create(scope._styleProperties);
|
||||
// mixin own host properties (lower specifity than scope props)
|
||||
this.mixin(props, propertyUtils.hostPropertiesFromStyles(this._styles));
|
||||
// mixin properties matching this element in scope
|
||||
scopeProps = scopeProps ||
|
||||
propertyUtils.propertyDataFromStyles(scope._styles, this).properties;
|
||||
this.mixin(props, scopeProps);
|
||||
// finally mixin properties inherent to this element
|
||||
this.mixin(props,
|
||||
propertyUtils.scopePropertiesFromStyles(this._styles));
|
||||
propertyUtils.mixinCustomStyle(props, this.customStyle);
|
||||
// reify properties (note: only does own properties)
|
||||
propertyUtils.reify(props);
|
||||
this._styleProperties = props;
|
||||
},
|
||||
|
||||
_computeOwnStyleProperties: function() {
|
||||
var props = {};
|
||||
for (var i=0, n; i < this._ownStylePropertyNames.length; i++) {
|
||||
n = this._ownStylePropertyNames[i];
|
||||
props[n] = this._styleProperties[n];
|
||||
}
|
||||
this._ownStyleProperties = props;
|
||||
},
|
||||
|
||||
_scopeCount: 0,
|
||||
|
||||
_applyStyleProperties: function(info) {
|
||||
// update scope selector (needed for style transformation)
|
||||
var oldScopeSelector = this._scopeSelector;
|
||||
// note, the scope selector is incremented per class counter
|
||||
this._scopeSelector = info ? info._scopeSelector :
|
||||
this.is + '-' + this.__proto__._scopeCount++;
|
||||
var style = propertyUtils.applyElementStyle(this,
|
||||
this._styleProperties, this._scopeSelector, info && info.style);
|
||||
// apply scope selector
|
||||
if (!nativeShadow) {
|
||||
propertyUtils.applyElementScopeSelector(this, this._scopeSelector,
|
||||
oldScopeSelector, this._scopeCssViaAttr);
|
||||
}
|
||||
return style;
|
||||
},
|
||||
|
||||
serializeValueToAttribute: function(value, attribute, node) {
|
||||
// override to ensure whenever classes are set, we need to shim them.
|
||||
node = node || this;
|
||||
if (attribute === 'class' && !nativeShadow) {
|
||||
// host needed to scope styling.
|
||||
// Under Shady DOM, domHost is safe to use here because we know it
|
||||
// is a Polymer element
|
||||
var host = node === this ? (this.domHost || this.dataHost) : this;
|
||||
if (host) {
|
||||
value = host._scopeElementClass(node, value);
|
||||
}
|
||||
}
|
||||
// note: using Polymer.dom here ensures that any attribute sets
|
||||
// will provoke distribution if necessary; do this iff necessary
|
||||
node = (this.shadyRoot && this.shadyRoot._hasDistributed) ?
|
||||
Polymer.dom(node) : node;
|
||||
serializeValueToAttribute.call(this, value, attribute, node);
|
||||
},
|
||||
|
||||
_scopeElementClass: function(element, selector) {
|
||||
if (!nativeShadow && !this._scopeCssViaAttr) {
|
||||
selector += (selector ? ' ' : '') + SCOPE_NAME + ' ' + this.is +
|
||||
(element._scopeSelector ? ' ' + XSCOPE_NAME + ' ' +
|
||||
element._scopeSelector : '');
|
||||
}
|
||||
return selector;
|
||||
},
|
||||
|
||||
/**
|
||||
* Re-evaluates and applies custom CSS properties based on dynamic
|
||||
* changes to this element's scope, such as adding or removing classes
|
||||
* in this element's local DOM.
|
||||
*
|
||||
* For performance reasons, Polymer's custom CSS property shim relies
|
||||
* on this explicit signal from the user to indicate when changes have
|
||||
* been made that affect the values of custom properties.
|
||||
*
|
||||
* @method updateStyles
|
||||
* @param {Object=} properties Properties object which is mixed into
|
||||
* the element's `customStyle` property. This argument provides a shortcut
|
||||
* for setting `customStyle` and then calling `updateStyles`.
|
||||
*/
|
||||
updateStyles: function(properties) {
|
||||
if (this.isAttached) {
|
||||
if (properties) {
|
||||
this.mixin(this.customStyle, properties);
|
||||
}
|
||||
// skip applying properties to self if not used
|
||||
if (this._needsStyleProperties()) {
|
||||
this._updateStyleProperties();
|
||||
// when an element doesn't use style properties, its own properties
|
||||
// should be invalidated so elements down the tree update ok.
|
||||
} else {
|
||||
this._styleProperties = null;
|
||||
}
|
||||
if (this._styleCache) {
|
||||
this._styleCache.clear();
|
||||
}
|
||||
// always apply properties to root
|
||||
this._updateRootStyles();
|
||||
}
|
||||
},
|
||||
|
||||
_updateRootStyles: function(root) {
|
||||
root = root || this.root;
|
||||
var c$ = Polymer.dom(root)._query(function(e) {
|
||||
return e.shadyRoot || e.shadowRoot;
|
||||
});
|
||||
for (var i=0, l= c$.length, c; (i<l) && (c=c$[i]); i++) {
|
||||
if (c.updateStyles) {
|
||||
c.updateStyles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Force all custom elements using cross scope custom properties,
|
||||
* to update styling.
|
||||
*/
|
||||
Polymer.updateStyles = function(properties) {
|
||||
// update default/custom styles
|
||||
styleDefaults.updateStyles(properties);
|
||||
// search the document for elements to update
|
||||
Polymer.Base._updateRootStyles(document);
|
||||
};
|
||||
|
||||
var styleCache = new Polymer.StyleCache();
|
||||
Polymer.customStyleCache = styleCache;
|
||||
|
||||
var SCOPE_NAME = styleTransformer.SCOPE_NAME;
|
||||
var XSCOPE_NAME = propertyUtils.XSCOPE_NAME;
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user