mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
Merge branch 'fix-for-selectors-specificity' of https://github.com/nazar-pc/polymer into nazar-pc-fix-for-selectors-specificity
This commit is contained in:
commit
f2b65881e2
@ -11,11 +11,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
/*
|
||||
Extremely simple css parser. Intended to be not more than what we need
|
||||
and definitely not necessarly correct =).
|
||||
and definitely not necessarily correct =).
|
||||
*/
|
||||
Polymer.CssParse = (function() {
|
||||
|
||||
var api = {
|
||||
return {
|
||||
// given a string of css, return a simple rule tree
|
||||
parse: function(text) {
|
||||
text = this._clean(text);
|
||||
@ -31,7 +31,7 @@ Polymer.CssParse = (function() {
|
||||
_lex: function(text) {
|
||||
var root = {start: 0, end: text.length};
|
||||
var n = root;
|
||||
for (var i=0, s=0, l=text.length; i < l; i++) {
|
||||
for (var i=0, l=text.length; i < l; i++) {
|
||||
switch (text[i]) {
|
||||
case this.OPEN_BRACE:
|
||||
//console.group(i);
|
||||
@ -123,7 +123,7 @@ Polymer.CssParse = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
// emit rule iff there is cssText
|
||||
// emit rule if there is cssText
|
||||
if (cssText) {
|
||||
if (node.selector) {
|
||||
text += node.selector + ' ' + this.OPEN_BRACE + '\n';
|
||||
@ -185,10 +185,6 @@ Polymer.CssParse = (function() {
|
||||
|
||||
};
|
||||
|
||||
|
||||
// exports
|
||||
return api;
|
||||
|
||||
})();
|
||||
|
||||
</script>
|
||||
|
@ -87,9 +87,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
var parts = cssText.split(';');
|
||||
for (var i=0, p; i<parts.length; i++) {
|
||||
p = parts[i];
|
||||
if (p.match(this.rx.MIXIN_MATCH) || p.match(this.rx.VAR_MATCH)) {
|
||||
customCssText += p + ';\n';
|
||||
}
|
||||
customCssText += p + ';\n';
|
||||
}
|
||||
return customCssText;
|
||||
},
|
||||
@ -181,7 +179,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
rule.cssText = output;
|
||||
},
|
||||
|
||||
// Test if the rules in these styles matche the given `element` and if so,
|
||||
// Test if the rules in these styles matches the given `element` and if so,
|
||||
// collect any custom properties into `props`.
|
||||
propertyDataFromStyles: function(styles, element) {
|
||||
var props = {}, self = this;
|
||||
@ -208,7 +206,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
return {properties: props, key: o};
|
||||
},
|
||||
|
||||
// Test if a rule matches scope crteria (* or :root) and if so,
|
||||
// Test if a rule matches scope criteria (* or :root) and if so,
|
||||
// collect any custom properties into `props`.
|
||||
scopePropertiesFromStyles: function(styles) {
|
||||
if (!styles._scopeStyleProperties) {
|
||||
@ -218,7 +216,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
return styles._scopeStyleProperties;
|
||||
},
|
||||
|
||||
// Test if a rule matches host crteria (:host) and if so,
|
||||
// Test if a rule matches host criteria (:host) and if so,
|
||||
// collect any custom properties into `props`.
|
||||
//
|
||||
// TODO(sorvell): this should change to collecting properties from any
|
||||
@ -319,7 +317,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
// otherwise, if we have css to apply, do so
|
||||
} else if (cssText) {
|
||||
// apply css after the scope style of the element to help with
|
||||
// style predence rules.
|
||||
// style precedence rules.
|
||||
style = styleUtil.applyCss(cssText, selector,
|
||||
nativeShadow ? element.root : null, element._scopeStyle);
|
||||
}
|
||||
@ -356,7 +354,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
// var(--a)
|
||||
// var(--a, --b)
|
||||
// var(--a, fallback-literal)
|
||||
// var(--a, fallback-literal(with-one-nested-parens))
|
||||
// var(--a, fallback-literal(with-one-nested-parentheses))
|
||||
VAR_MATCH: /(^|\W+)var\([\s]*([^,)]*)[\s]*,?[\s]*((?:[^,)]*)|(?:[^;]*\([^;)]*\)))[\s]*?\)/gi,
|
||||
VAR_CAPTURE: /\([\s]*(--[^,\s)]*)(?:,[\s]*(--[^,\s)]*))?(?:\)|,)/gi,
|
||||
IS_VAR: /^--/,
|
||||
|
@ -34,7 +34,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
cannot otherwise be scoped:
|
||||
e.g. :host ::content > .bar -> x-foo > .bar
|
||||
|
||||
* ::shadow, /deep/: processed simimlar to ::content
|
||||
* ::shadow, /deep/: processed similar to ::content
|
||||
|
||||
* :host-context(...): scopeName..., ... scopeName
|
||||
|
||||
@ -97,7 +97,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
elementStyles: function(element, callback) {
|
||||
var styles = element._styles;
|
||||
var cssText = '';
|
||||
for (var i=0, l=styles.length, s, text; (i<l) && (s=styles[i]); i++) {
|
||||
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) :
|
||||
@ -152,7 +152,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
p$[i] = transformer.call(this, p, scope, hostScope);
|
||||
}
|
||||
// NOTE: save transformedSelector for subsequent matching of elements
|
||||
// agsinst selectors (e.g. when calculating style properties)
|
||||
// against selectors (e.g. when calculating style properties)
|
||||
rule.selector = rule.transformedSelector =
|
||||
p$.join(COMPLEX_SELECTOR_SEP);
|
||||
},
|
||||
@ -258,9 +258,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
// parsing which seems like overkill
|
||||
var HOST_PAREN = /(\:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g;
|
||||
var HOST_CONTEXT = ':host-context';
|
||||
var HOST_CONTEXT_PAREN = /(.*)(?:\:host-context)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))(.*)/;
|
||||
var HOST_CONTEXT_PAREN = /(.*)(?::host-context)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))(.*)/;
|
||||
var CONTENT = '::content';
|
||||
var SCOPE_JUMP = /\:\:content|\:\:shadow|\/deep\//;
|
||||
var SCOPE_JUMP = /::content|::shadow|\/deep\//;
|
||||
var CSS_CLASS_PREFIX = '.';
|
||||
var CSS_ATTR_PREFIX = '[' + SCOPE_NAME + '~=';
|
||||
var CSS_ATTR_SUFFIX = ']';
|
||||
|
@ -44,15 +44,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
return style.__cssRules;
|
||||
},
|
||||
|
||||
clearStyleRules: function(style) {
|
||||
style.__cssRules = null;
|
||||
},
|
||||
|
||||
forEachStyleRule: function(node, callback) {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
var s = node.parsedSelector;
|
||||
var skipRules = false;
|
||||
if (node.type === this.ruleTypes.STYLE_RULE) {
|
||||
callback(node);
|
||||
|
@ -79,6 +79,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
style.textContent = cssText;
|
||||
// extends!!
|
||||
if (styleExtends.hasExtends(style.textContent)) {
|
||||
// TODO(sorvell): variable is not used, should it update `style.textContent`?
|
||||
cssText = styleExtends.transform(style);
|
||||
}
|
||||
styles.push(style);
|
||||
@ -109,7 +110,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
/**
|
||||
* Apply style scoping to the specified `container` and all its
|
||||
* descendants. If `shoudlObserve` is true, changes to the container are
|
||||
* descendants. If `shouldObserve` is true, changes to the container are
|
||||
* monitored via mutation observer and scoping is applied.
|
||||
*
|
||||
* This method is useful for ensuring proper local DOM CSS scoping
|
||||
|
@ -166,7 +166,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
assert.equal(t.rules[3].selector, '.\\0c3333d-model');
|
||||
assert.equal(t.rules[4].selector, '.\\d33333d-model');
|
||||
assert.equal(t.rules[5].selector, '.\\e33333d-model');
|
||||
});
|
||||
});
|
||||
|
||||
test('multiple consequent spaces in CSS selector', function() {
|
||||
var s4 = document.querySelector('#multiple-spaces');
|
||||
var t = css.parse(s4.textContent);
|
||||
|
@ -57,7 +57,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
test(':host, :host(...)', function() {
|
||||
assertComputed(styled, '1px');
|
||||
assertComputed(styledWide, '2px');
|
||||
|
||||
|
||||
});
|
||||
|
||||
test('scoped selectors, simple and complex', function() {
|
||||
@ -209,7 +209,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
@ -286,7 +286,6 @@
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<template id="dynamic-style-template">
|
||||
<style>
|
||||
:host {
|
||||
@ -346,3 +345,100 @@
|
||||
})();
|
||||
</script>
|
||||
</dom-module>
|
||||
|
||||
<dom-module id="x-specificity">
|
||||
<template>
|
||||
<style>
|
||||
:host {
|
||||
border-top: 1px solid red;
|
||||
}
|
||||
:host(.bar) {
|
||||
border-top: 2px solid red;
|
||||
}
|
||||
</style>
|
||||
<content></content>
|
||||
</template>
|
||||
<script>
|
||||
Polymer({is: 'x-specificity'});
|
||||
</script>
|
||||
</dom-module>
|
||||
|
||||
<style is="custom-style">
|
||||
:root {
|
||||
--x-specificity-parent : {
|
||||
border: 10px solid blue;
|
||||
};
|
||||
--x-specificity-nested : {
|
||||
border: 3px solid red;
|
||||
};
|
||||
}
|
||||
</style>
|
||||
|
||||
<dom-module id="x-specificity-parent">
|
||||
<template>
|
||||
<style>
|
||||
/* TODO remove `:host` when https://github.com/Polymer/polymer/pull/2419 merged */
|
||||
:host ::content > :not(template) {
|
||||
@apply(--x-specificity-parent);
|
||||
}
|
||||
</style>
|
||||
<content></content>
|
||||
</template>
|
||||
<script>
|
||||
Polymer({is: 'x-specificity-parent', extends: 'div'});
|
||||
</script>
|
||||
</dom-module>
|
||||
|
||||
<dom-module id="x-specificity-nested">
|
||||
<template>
|
||||
<style>
|
||||
:host {
|
||||
@apply(--x-specificity-nested);
|
||||
}
|
||||
</style>
|
||||
</template>
|
||||
<script>
|
||||
Polymer({is: 'x-specificity-nested', extends: 'div'});
|
||||
</script>
|
||||
</dom-module>
|
||||
|
||||
<style is="custom-style">
|
||||
:root {
|
||||
--x-overriding : {
|
||||
border-top: 1px solid red;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<dom-module id="x-overriding">
|
||||
<template>
|
||||
<style>
|
||||
.red {
|
||||
@apply(--x-overriding);
|
||||
}
|
||||
.green {
|
||||
@apply(--x-overriding);
|
||||
border-top: 2px solid green;
|
||||
}
|
||||
.red-2 {
|
||||
border-top: 2px solid green;
|
||||
@apply(--x-overriding);
|
||||
}
|
||||
.blue {
|
||||
@apply(--x-overriding);
|
||||
border-top: 3px solid blue;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="red">red</div>
|
||||
<div class="green">green</div>
|
||||
<div class="red-2">green-2</div>
|
||||
<div class="blue">blue</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'x-overriding'
|
||||
});
|
||||
</script>
|
||||
|
@ -44,6 +44,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
</template>
|
||||
|
||||
<x-dynamic-svg></x-dynamic-svg>
|
||||
<x-specificity></x-specificity>
|
||||
<x-specificity class="bar"></x-specificity>
|
||||
<div is="x-specificity-parent">
|
||||
<div is="x-specificity-nested"></div>
|
||||
</div>
|
||||
<x-overriding></x-overriding>
|
||||
|
||||
<script>
|
||||
suite('scoped-styling', function() {
|
||||
@ -212,9 +218,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
test('styles shimmed in registration order', function() {
|
||||
var s$ = document.head.querySelectorAll('style[scope]');
|
||||
var expected = ['x-gchild', 'x-child2', 'x-styled', 'x-button',
|
||||
'x-mixed-case', 'x-mixed-case-button', 'x-dynamic-scope',
|
||||
'x-dynamic-template', 'x-dynamic-svg'];
|
||||
var expected = ['x-gchild', 'x-child2', 'x-styled', 'x-button', 'x-mixed-case',
|
||||
'x-mixed-case-button', 'x-dynamic-scope', 'x-dynamic-template',
|
||||
'x-dynamic-svg', 'x-specificity', 'x-overriding',
|
||||
'x-overriding-0', 'x-specificity-parent-0', 'x-specificity-nested-0'];
|
||||
var actual = [];
|
||||
for (var i=0; i<s$.length; i++) {
|
||||
actual.push(s$[i].getAttribute('scope'));
|
||||
@ -255,7 +262,23 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
x = document.createElement('button', 'x-mixed-case-button');
|
||||
document.body.appendChild(x);
|
||||
assertComputed(x, '14px');
|
||||
});
|
||||
|
||||
test('specificity of :host selector with class', function() {
|
||||
assertComputed(document.querySelector('x-specificity'), '1px');
|
||||
assertComputed(document.querySelector('x-specificity.bar'), '2px');
|
||||
});
|
||||
|
||||
test('specificity of ::content > :not(template) selector', function() {
|
||||
assertComputed(document.querySelector('[is=x-specificity-nested]'), '10px');
|
||||
});
|
||||
|
||||
test('overwriting mixin properties', function() {
|
||||
var root = document.querySelector('x-overriding');
|
||||
assertComputed(root.querySelector('.red'), '1px');
|
||||
assertComputed(root.querySelector('.green'), '2px');
|
||||
assertComputed(root.querySelector('.red-2'), '1px');
|
||||
assertComputed(root.querySelector('.blue'), '3px');
|
||||
});
|
||||
});
|
||||
|
||||
@ -269,7 +292,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
computed = getComputedStyle(circle);
|
||||
assert.equal(computed['fill-opacity'], '0.5');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user