Skip to content

Commit

Permalink
Merge pull request #1397 from Polymer/0.8-shim-class
Browse files Browse the repository at this point in the history
0.8 shim class
  • Loading branch information
kevinpschaaf committed Apr 10, 2015
2 parents ba0c926 + 89a2c0f commit bc6f5ba
Show file tree
Hide file tree
Showing 17 changed files with 621 additions and 380 deletions.
67 changes: 29 additions & 38 deletions src/lib/dom-api.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,12 @@
// 3. node is <content> (host of container needs distribution)
appendChild: function(node) {
var distributed;
if (node.lightParent) {
this._removeLogicalInfo(node, node.lightParent);
}
this._removeNodeFromHost(node);
if (this._nodeIsInLogicalTree(this.node)) {
var host = this._hostForNode(this.node);
this._addLogicalInfo(node, this.node, host && host.shadyRoot);
this._addNodeToHost(node);
if (host) {
host._elementAdd(node);
distributed = this._maybeDistribute(node, this.node, host);
}
}
Expand All @@ -115,9 +113,7 @@
return this.appendChild(node);
}
var distributed;
if (node.lightParent) {
this._removeLogicalInfo(node, node.lightParent);
}
this._removeNodeFromHost(node);
if (this._nodeIsInLogicalTree(this.node)) {
saveLightChildrenIfNeeded(this.node);
var children = this.childNodes;
Expand All @@ -128,8 +124,8 @@
}
var host = this._hostForNode(this.node);
this._addLogicalInfo(node, this.node, host && host.shadyRoot, index);
this._addNodeToHost(node);
if (host) {
host._elementAdd(node);
distributed = this._maybeDistribute(node, this.node, host);
}
}
Expand All @@ -152,30 +148,25 @@
var distributed;
if (this._nodeIsInLogicalTree(this.node)) {
var host = this._hostForNode(this.node);
this._removeLogicalInfo(node, this.node);
if (host) {
host._elementRemove(node);
distributed = this._maybeDistribute(node, this.node, host);
}
distributed = this._maybeDistribute(node, this.node, host);
this._removeNodeFromHost(node);
}
if (!distributed) {
// if removing from a shadyRoot, remove form host instead
var container = this.node._isShadyRoot ? this.node.host : this.node;
nativeRemoveChild.call(container, node);
}
return node;
},

replaceChild: function(node, ref_node) {
this.insertBefore(node, ref_node);
this.removeChild(ref_node);
},

_getOwnerShadyRoot: function() {
return this._ownerShadyRootForNode(this.node);
return node;
},

getOwnerRoot: function() {
return this._getOwnerShadyRoot();
return this._ownerShadyRootForNode(this.node);
},

_ownerShadyRootForNode: function(node) {
Expand Down Expand Up @@ -218,13 +209,14 @@

_nodeIsInLogicalTree: function(node) {
return Boolean(node._isShadyRoot ||
this._getOwnerShadyRoot(node) ||
this._ownerShadyRootForNode(node) ||
node.shadyRoot);
},

// note: a node is its own host
_hostForNode: function(node) {
var root = node.shadyRoot || (node._isShadyRoot ?
node : this._getOwnerShadyRoot(node));
node : this._ownerShadyRootForNode(node));
return root && root.host;
},

Expand All @@ -242,6 +234,23 @@
node.querySelector(CONTENT));
},

_removeNodeFromHost: function(node) {
if (node.lightParent) {
var root = this._ownerShadyRootForNode(node);
if (root) {
root.host._elementRemove(node);
}
this._removeLogicalInfo(node, node.lightParent);
}
},

_addNodeToHost: function(node) {
var root = this._ownerShadyRootForNode(node);
if (root) {
root.host._elementAdd(node);
}
},

_addLogicalInfo: function(node, container, root, index) {
saveLightChildrenIfNeeded(container);
var children = factory(container).childNodes;
Expand All @@ -257,14 +266,6 @@
} else {
children.splice(index, 0, node);
node.lightParent = container;
node._ownerShadyRoot = root;
}
// TODO(sorvell): consider not attaching this to every node and instead
// looking up the tree for this info.
// add _ownerShadyRoot info
var c$ = factory(node).childNodes;
if (c$.length) {
this._addRootToChildren(node, root);
}
},

Expand All @@ -283,16 +284,6 @@
node._ownerShadyRoot = undefined;
},

_addRootToChildren: function(children, root) {
for (var i=0, l=children.length, c, cc; (i<l) && (c=children[i]); i++) {
c._ownerShadyRoot = root;
cc = factory(c).childNodes;
if (cc.length) {
this._addRootToChildren(cc, root);
}
}
},

// TODO(sorvell): This will fail if distribution that affects this
// question is pending; this is expected to be exceedingly rare, but if
// the issue comes up, we can force a flush in this case.
Expand Down
4 changes: 2 additions & 2 deletions src/lib/event-api.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@

get localTarget() {
var current = this.event.currentTarget;
var currentRoot = current && Polymer.dom(current)._getOwnerShadyRoot();
var currentRoot = current && Polymer.dom(current).getOwnerRoot();
var p$ = this.path;
for (var i=0; i < p$.length; i++) {
if (Polymer.dom(p$[i])._getOwnerShadyRoot() === currentRoot) {
if (Polymer.dom(p$[i]).getOwnerRoot() === currentRoot) {
return p$[i];
}
}
Expand Down
60 changes: 44 additions & 16 deletions src/lib/style-transformer.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,39 @@

// Given a node and scope name, add a scoping class to each node
// in the tree. This facilitates transforming css into scoped rules.
function transformDom(node, scope) {
_transformDom(node, scope ? scope + SCOPE_SUFFIX : '');
function transformDom(node, scope, useAttr, shouldRemoveScope) {
_transformDom(node, scope || '', useAttr, shouldRemoveScope);
}

function _transformDom(node, selector) {
function _transformDom(node, selector, useAttr, shouldRemoveScope) {
if (node.setAttribute) {
node.setAttribute(SCOPE_ATTR, selector);
transformElement(node, selector, useAttr, shouldRemoveScope);
}
var c$ = Polymer.dom(node).childNodes;
for (var i=0; i<c$.length; i++) {
_transformDom(c$[i], selector);
_transformDom(c$[i], selector, useAttr, shouldRemoveScope);
}
}

function transformElement(element, scope) {
element.setAttribute(SCOPE_ATTR, scope + SCOPE_SUFFIX);
function transformElement(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) {
if (shouldRemoveScope) {
element.classList.remove(SCOPE_NAME, scope);
} else {
element.classList.add(SCOPE_NAME, scope);
}
}
}
}

function transformHost(host, scope) {
Expand All @@ -64,8 +81,9 @@
// 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.
function transformCss(rules, scope, ext, callback) {
function transformCss(rules, scope, ext, callback, useAttr) {
var hostScope = calcHostScope(scope, ext);
scope = calcElementScope(scope, useAttr);
return Polymer.StyleUtil.toCssText(rules, function(rule) {
transformRule(rule, scope, hostScope);
if (callback) {
Expand All @@ -74,6 +92,16 @@
});
}

function calcElementScope(scope, useAttr) {
if (scope) {
return useAttr ?
CSS_ATTR_PREFIX + scope + CSS_ATTR_SUFFIX :
CSS_CLASS_PREFIX + scope;
} else {
return '';
}
}

function calcHostScope(scope, ext) {
return ext ? '[is=' + scope + ']' : scope;
}
Expand Down Expand Up @@ -138,7 +166,7 @@

function transformSimpleSelector(selector, scope) {
var p$ = selector.split(PSEUDO_PREFIX);
p$[0] += CSS_PREFIX + scope + SCOPE_SUFFIX + CSS_SUFFIX;
p$[0] += scope;
return p$.join(PSEUDO_PREFIX);
}

Expand All @@ -152,9 +180,9 @@
selector.trim() + SCOPE_ROOT_SELECTOR;
}

var SCOPE_ATTR = 'style-scope';
var SCOPE_ROOT_SELECTOR = ':not([' + SCOPE_ATTR + '])';
var SCOPE_SUFFIX = '';
var SCOPE_NAME = 'style-scope';
var SCOPE_ROOT_SELECTOR = ':not([' + SCOPE_NAME + '])' +
':not(.' + SCOPE_NAME + ')';
var COMPLEX_SELECTOR_SEP = ',';
var SIMPLE_SELECTOR_SEP = /(^|[\s>+~]+)([^\s>+~]+)/g;
var HOST = ':host';
Expand All @@ -164,10 +192,10 @@
var HOST_PAREN = /(\:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g;
var CONTENT = '::content';
var SCOPE_JUMP = /\:\:content|\:\:shadow|\/deep\//;
var CSS_PREFIX = '[' + SCOPE_ATTR + '=';
var CSS_SUFFIX = ']';
var CSS_CLASS_PREFIX = '.';
var CSS_ATTR_PREFIX = '[' + SCOPE_NAME + '~=';
var CSS_ATTR_SUFFIX = ']';
var PSEUDO_PREFIX = ':';
var SCOPING_CLASS = /(?:^|\s)([\S]*?-x)(?:$|\s)/;

// exports
Polymer.StyleTransformer = {
Expand All @@ -177,7 +205,7 @@
css: transformCss,
rule: transformRule,
rootRule: transformRootRule,
SCOPE_SUFFIX: SCOPE_SUFFIX
SCOPE_NAME: SCOPE_NAME
};

})();
Expand Down
9 changes: 5 additions & 4 deletions src/mini/shady.html
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
_beginDistribute: function() {
if (this._useContent && hasInsertionPoint(this.shadyRoot)) {
// reset distributions
this._resetDistribution(this.shadyRoot);
this._resetDistribution();
// compute which nodes should be distributed where
// TODO(jmesserly): this is simplified because we assume a single
// ShadowRoot per host and no `<shadow>`.
Expand Down Expand Up @@ -135,17 +135,18 @@
// Many of the following methods are all conceptually static, but they are
// included here as "protected" methods to allow overriding.

_resetDistribution: function(node) {
_resetDistribution: function() {
// light children
var children = getLightChildren(node);
var children = getLightChildren(this);
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (child._destinationInsertionPoints) {
child._destinationInsertionPoints = undefined;
}
}
// insertion points
var p$ = node._insertionPoints;
var root = this.shadyRoot;
var p$ = root._insertionPoints;
for (var j = 0; j < p$.length; j++) {
p$[j]._distributedNodes = [];
}
Expand Down
12 changes: 6 additions & 6 deletions src/standard/effects.html
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,12 @@
var property = info.property || info.name || 'textContent';
// TODO(sorvell): consider pre-processing this step so we don't need
// this lookup.
// if (info._class === undefined) {
// info._class = (property === 'class' || property === 'className');
// }
// if (info._class) {
// value = this._scopeElementClass(node, value);
// }
if (info._class === undefined) {
info._class = (property === 'class' || property === 'className');
}
if (info._class) {
value = this._scopeElementClass(node, value);
}
if (info.kind == 'attribute') {
this.serializeValueToAttribute(value, property, node);
} else {
Expand Down
10 changes: 6 additions & 4 deletions src/standard/styling.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@

_prepElement: function(element) {
if (this._encapsulateStyle) {
Polymer.StyleTransformer.element(element, this.is);
Polymer.StyleTransformer.element(element, this.is,
this._scopeCssViaAttr);
}
prepElement.call(this, element);
},
Expand Down Expand Up @@ -113,7 +114,8 @@
} else {
var rules = this._rulesForStyle(s);
Polymer.StyleUtil.applyCss(
Polymer.StyleTransformer.css(rules, this.is, this.extends),
Polymer.StyleTransformer.css(rules, this.is, this.extends,
null, this._scopeCssViaAttr),
this.is, null, true);
}
}
Expand All @@ -137,14 +139,14 @@
// add scoping class whenever an element is added to localDOM
_elementAdd: function(node) {
if (this._encapsulateStyle && !node.__styleScoped) {
Polymer.StyleTransformer.dom(node, this.is);
Polymer.StyleTransformer.dom(node, this.is, this._scopeCssViaAttr);
}
},

// remove scoping class whenever an element is removed from localDOM
_elementRemove: function(node) {
if (this._encapsulateStyle) {
Polymer.StyleTransformer.dom(node, '');
Polymer.StyleTransformer.dom(node, this.is, this._scopeCssViaAttr, true);
}
}

Expand Down
Loading

0 comments on commit bc6f5ba

Please sign in to comment.