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

0.8 x style #1482

Merged
merged 9 commits into from
May 4, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion polymer.html
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@

</script>

<link rel="import" href="src/lib/x-style.html">
<link rel="import" href="src/lib/custom-style.html">
<link rel="import" href="src/lib/template/x-autobind.html">
<link rel="import" href="src/lib/template/x-template.html">
<link rel="import" href="src/lib/template/x-repeat.html">
Expand Down
18 changes: 10 additions & 8 deletions src/lib/css-parse.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@
// add selectors/cssText to node tree
function parseCss(node, text) {
var t = text.substring(node.start, node.end-1);
node.cssText = t.trim();
node.parsedCssText = node.cssText = t.trim();
if (node.parent) {
var ss = node.previous ? node.previous.end : node.parent.start;
t = text.substring(ss, node.start-1);
// TODO(sorvell): ad hoc; make selector include only after last ;
// helps with mixin syntax
t = t.substring(t.lastIndexOf(';')+1);
node.selector = t.trim();
node.parsedSelector = node.selector = t.trim();
}
var r$ = node.rules;
if (r$) {
Expand All @@ -74,18 +74,20 @@
}

// stringify parsed css.
function stringify(node, text) {
function stringify(node, preserveProperties, text) {
text = text || '';
// calc rule cssText
var cssText = '';
if (node.cssText || node.rules) {
var r$ = node.rules;
if (r$ && !hasMixinRules(r$)) {
if (r$ && (preserveProperties || !hasMixinRules(r$))) {
for (var i=0, l=r$.length, r; (i<l) && (r=r$[i]); i++) {
cssText = stringify(r, cssText);
cssText = stringify(r, preserveProperties, cssText);
}
} else {
cssText = removeCustomProps(node.cssText).trim();
cssText = preserveProperties ? node.cssText :
removeCustomProps(node.cssText);
cssText = cssText.trim();
if (cssText) {
cssText = ' ' + cssText + '\n';
}
Expand Down Expand Up @@ -125,8 +127,8 @@
comments: /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,
port: /@import[^;]*;/gim,
customProp: /--[^;{]*?:[^{};]*?;/gim,
mixinProp: /--[^;{]*?:[^{;]*?{[^}]*?}/gim,
mixinApply: /@mixin[\s]*\([^)]*?\)[\s]*;/gim
mixinProp: /--[^;{]*?:[^{;]*?{[^}]*?};?/gim,
mixinApply: /@apply[\s]*\([^)]*?\)[\s]*;/gim
};

// exports
Expand Down
137 changes: 137 additions & 0 deletions src/lib/custom-style.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<!--
@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">
<link rel="import" href="style-transformer.html">
<link rel="import" href="style-defaults.html">

<!--

The `x-style` extension of the native `<style>` element allows defining styles
in the main document that can take advantage of several special features of
Polymer's styling system:

* Document styles defined in an `x-style` will be shimmed to ensure they do
not leak into local DOM when running on browsers without non-native Shadow DOM.
* Shadow DOM-specific `/deep/` and `::shadow` combinators will be shimmed on
browsers without non-native Shadow DOM.
* Custom properties used by Polymer's experimental shim for cross-scope styling
may be defined in an `x-style`.

Example:

```html
<!doctype html>
<html>
<head>
<script src="components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="components/polymer/polymer.html">

<style is="custom-style">

/* Will be prevented from affecting local DOM of Polymer elements */
* {
box-sizing: border-box;
}

/* Can use /deep/ and ::shadow combinators */
body /deep/ .my-special-view::shadow #thing-inside {
background: yellow;
}

/* Custom properties that inherit down the document tree may be defined */
body {
--my-toolbar-title-color: green;
}

</style>

</head>
<body>

...

</body>
</html>
```

Note, all features of `custom-style` are available when defining styles as part of Polymer elements (e.g. `<style>` elements within `<dom-module>`'s used for defining Polymer elements. The `custom-style` extension should only be used for defining document styles, outside of a custom element's local DOM.

-->

<script>
(function() {

var nativeShadow = Polymer.Settings.useNativeShadow;
var propertyUtils = Polymer.StyleProperties;

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;
this.__cssRules = Polymer.StyleUtil.parser.parse(e.textContent);
propertyUtils.decorateRules(this.__cssRules);
this._rulesToDefaultProperties(this.__cssRules);
// NOTE: go async to give a chance to collect properties into
// the StyleDefaults before applying
this.async(this._applyStyle);
}
},

// polyfill this style with root scoping and
// apply custom properties!
_applyStyle: function() {
// used applied element from HTMLImports polyfill or this
var e = this.__appliedElement || this;
var props = this._styleProperties = this._computeStyleProperties();
var self = this;
e.textContent = Polymer.StyleUtil.toCssText(this.__cssRules,
function(rule) {
// polyfill lack of support for :root
if (rule.selector === ':root') {
rule.selector = 'body';
}
var css = rule.cssText = rule.parsedCssText;
if (rule.properties.consumes) {
// TODO(sorvell): factor better
// remove property assignments so next function isn't confused
css = css.replace(propertyUtils.rx.VAR_ASSIGN, '');
// replace with reified properties, scenario is same as mixin
rule.cssText = propertyUtils.valueForMixin(css, props);
}
if (!nativeShadow) {
Polymer.StyleTransformer.rootRule(rule);
}
});
},

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

});

})();
</script>
10 changes: 9 additions & 1 deletion src/lib/dom-api.html
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,14 @@
},

_removeOwnerShadyRoot: function(node) {
// TODO(sorvell): need to clear any children of element?
// optimization: only reset the tree if node is actually in a root
var hasCachedRoot = factory(node).getOwnerRoot() !== undefined;
if (hasCachedRoot) {
var c$ = factory(node).childNodes;
for (var i=0, l=c$.length, n; (i<l) && (n=c$[i]); i++) {
this._removeOwnerShadyRoot(n);
}
}
node._ownerShadyRoot = undefined;
},

Expand Down Expand Up @@ -295,6 +302,7 @@
},

_query: function(matcher, node) {
node = node || this.node;
var list = [];
this._queryElements(factory(node).childNodes, matcher, list);
return list;
Expand Down
29 changes: 24 additions & 5 deletions src/lib/style-defaults.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,39 @@

(function() {

var defaultSheet = document.createElement('style');
var style = document.createElement('style');
var properties;

function applyCss(cssText) {
defaultSheet.textContent += cssText;
defaultSheet.__cssRules =
Polymer.StyleUtil.parser.parse(defaultSheet.textContent);
style.textContent += cssText;
properties = null;
// TODO(sorvell): make this lazy at the point of consumption
// or better yet, pass in pre-parsed rules here.
style.__cssRules =
Polymer.StyleUtil.parser.parse(style.textContent);
Polymer.StyleProperties.decorateRules(style.__cssRules);
}

function getProperties() {
if (!properties) {
properties = {};
Polymer.StyleUtil.forEachStyleRule(style.__cssRules,
function(rule) {
Polymer.Base._rootCustomPropertiesFromRule(properties, rule);
});
Polymer.StyleProperties.reify(properties);
}
return properties;
}

applyCss('');

// exports
Polymer.StyleDefaults = {
applyCss: applyCss,
defaultSheet: defaultSheet
style: style,
styles: [style],
getProperties: getProperties
};

})();
Expand Down
Loading