diff --git a/components-chromium/paper-tooltip/paper-tooltip.js b/components-chromium/paper-tooltip/paper-tooltip.js
index 853eee1990258..1b36aa4c38b3f 100644
--- a/components-chromium/paper-tooltip/paper-tooltip.js
+++ b/components-chromium/paper-tooltip/paper-tooltip.js
@@ -42,12 +42,14 @@ Custom property | Description | Default
`--paper-tooltip-background` | The background color of the tooltip | `#616161`
`--paper-tooltip-opacity` | The opacity of the tooltip | `0.9`
`--paper-tooltip-text-color` | The text color of the tooltip | `white`
-`--paper-tooltip` | Mixin applied to the tooltip | `{}`
`--paper-tooltip-delay-in` | Delay before tooltip starts to fade in | `500`
`--paper-tooltip-delay-out` | Delay before tooltip starts to fade out | `0`
`--paper-tooltip-duration-in` | Timing for animation when showing tooltip | `500`
`--paper-tooltip-duration-out` | Timing for animation when hiding tooltip | `0`
-`--paper-tooltip-animation` | Mixin applied to the tooltip animation | `{}`
+
+Also prefer using the exposed CSS part as follows where possible
+paper-tooltip::part(tooltip) {...}
+
@group Paper Elements
@element paper-tooltip
@demo demo/index.html
@@ -67,14 +69,12 @@ Polymer({
#tooltip {
display: block;
outline: none;
- @apply --paper-font-common-base;
font-size: 10px;
line-height: 1;
background-color: var(--paper-tooltip-background, #616161);
color: var(--paper-tooltip-text-color, white);
padding: 8px;
border-radius: 2px;
- @apply --paper-tooltip;
}
@keyframes keyFrameScaleUp {
@@ -149,7 +149,6 @@ Polymer({
animation-timing-function: ease-in;
animation-duration: var(--paper-tooltip-duration-in, 500ms);
animation-fill-mode: forwards;
- @apply --paper-tooltip-animation;
}
.fade-out-animation {
@@ -160,7 +159,6 @@ Polymer({
animation-timing-function: ease-in;
animation-duration: var(--paper-tooltip-duration-out, 500ms);
animation-fill-mode: forwards;
- @apply --paper-tooltip-animation;
}
.scale-up-animation {
@@ -172,7 +170,6 @@ Polymer({
animation-timing-function: ease-in;
animation-duration: var(--paper-tooltip-duration-in, 500ms);
animation-fill-mode: forwards;
- @apply --paper-tooltip-animation;
}
.scale-down-animation {
@@ -184,7 +181,6 @@ Polymer({
animation-timing-function: ease-in;
animation-duration: var(--paper-tooltip-duration-out, 500ms);
animation-fill-mode: forwards;
- @apply --paper-tooltip-animation;
}
.slide-down-animation {
@@ -196,7 +192,6 @@ Polymer({
animation-timing-function: cubic-bezier(0.0, 0.0, 0.2, 1);
animation-duration: var(--paper-tooltip-duration-out, 500ms);
animation-fill-mode: forwards;
- @apply --paper-tooltip-animation;
}
.slide-down-animation-out {
@@ -208,7 +203,6 @@ Polymer({
animation-timing-function: cubic-bezier(0.4, 0.0, 1, 1);
animation-duration: var(--paper-tooltip-duration-out, 500ms);
animation-fill-mode: forwards;
- @apply --paper-tooltip-animation;
}
.cancel-animation {
@@ -222,7 +216,7 @@ Polymer({
}
</style>
- <div id="tooltip" class="hidden">
+ <div id="tooltip" class="hidden" part="tooltip">
<slot></slot>
</div>
`,
@@ -282,8 +276,8 @@ Polymer({
*/
animationExit: {type: String, value: ''},
/**
- * This property is deprecated. Use --paper-tooltip-animation to change the
- * animation. The entry and exit animations that will be played when showing
+ * This property is deprecated.
+ * The entry and exit animations that will be played when showing
* and hiding the tooltip. If you want to override this, you must ensure
* that your animationConfig has the exact format below.
* @deprecated since version
@@ -311,12 +305,16 @@ Polymer({
/**
* Returns the target element that this tooltip is anchored to. It is
- * either the element given by the `for` attribute, or the immediate parent
- * of the tooltip.
+ * either the element given by the `for` attribute, the element manually
+ * specified through the `target` attribute, or the immediate parent of
+ * the tooltip.
*
* @type {Node}
*/
get target() {
+ if (this._manualTarget)
+ return this._manualTarget;
+
var parentNode = dom(this).parentNode;
// If the parentNode is a document fragment, then we need to use the host.
var ownerRoot = dom(this).getOwnerRoot();
@@ -331,6 +329,15 @@ Polymer({
return target;
},
+ /**
+ * Sets the target element that this tooltip will be anchored to.
+ * @param {Node} target
+ */
+ set target(target) {
+ this._manualTarget = target;
+ this._findTarget();
+ },
+
/**
* @return {void}
*/
@@ -429,13 +436,16 @@ Polymer({
* @return {void}
*/
updatePosition: function() {
- if (!this._target || !this.offsetParent)
+ if (!this._target)
+ return;
+ var offsetParent = this._composedOffsetParent();
+ if (!offsetParent)
return;
var offset = this.offset;
// If a marginTop has been provided by the user (pre 1.0.3), use it.
if (this.marginTop != 14 && this.offset == 14)
offset = this.marginTop;
- var parentRect = this.offsetParent.getBoundingClientRect();
+ var parentRect = offsetParent.getBoundingClientRect();
var targetRect = this._target.getBoundingClientRect();
var thisRect = this.getBoundingClientRect();
var horizontalCenterOffset = (targetRect.width - thisRect.width) / 2;
@@ -581,5 +591,45 @@ Polymer({
}
this.unlisten(this.$.tooltip, 'animationend', '_onAnimationEnd');
this.unlisten(this, 'mouseenter', 'hide');
+ },
+
+ /**
+ * Polyfills the old offsetParent behavior from before the spec was changed:
+ * https://github.com/w3c/csswg-drafts/issues/159
+ */
+ _composedOffsetParent: function() {
+ // Do an initial walk to check for display:none ancestors.
+ for (let ancestor = this; ancestor; ancestor = flatTreeParent(ancestor)) {
+ if (!(ancestor instanceof Element))
+ continue;
+ if (getComputedStyle(ancestor).display === 'none')
+ return null;
+ }
+
+ for (let ancestor = flatTreeParent(this); ancestor; ancestor = flatTreeParent(ancestor)) {
+ if (!(ancestor instanceof Element))
+ continue;
+ const style = getComputedStyle(ancestor);
+ if (style.display === 'contents') {
+ // display:contents nodes aren't in the layout tree so they should be skipped.
+ continue;
+ }
+ if (style.position !== 'static') {
+ return ancestor;
+ }
+ if (ancestor.tagName === 'BODY')
+ return ancestor;
+ }
+ return null;
+
+ function flatTreeParent(element) {
+ if (element.assignedSlot) {
+ return element.assignedSlot;
+ }
+ if (element.parentNode instanceof ShadowRoot) {
+ return element.parentNode.host;
+ }
+ return element.parentNode;
+ }
}
});