Skip to content
This repository was archived by the owner on Dec 19, 2024. It is now read-only.
Open
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
50 changes: 48 additions & 2 deletions paper-tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -435,13 +435,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;
Expand Down Expand Up @@ -587,5 +590,48 @@ 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() {
let offsetParent = this.offsetParent;
Comment thread
josepharhar marked this conversation as resolved.
if (window.ShadyDOM && window.ShadyDOM.inUse) {
return offsetParent;
}

let ancestor = this;
let foundInsideSlot = false;
while (ancestor && ancestor !== offsetParent) {
const assignedSlot = ancestor.assignedSlot;
if (assignedSlot) {
let newOffsetParent = assignedSlot.offsetParent;

if (getComputedStyle(assignedSlot)['display'] === 'contents') {
const hadStyleAttribute = assignedSlot.hasAttribute('style');
const oldDisplay = assignedSlot.style.display;
assignedSlot.style.display = getComputedStyle(ancestor).display;

newOffsetParent = assignedSlot.offsetParent;

assignedSlot.style.display = oldDisplay;
if (!hadStyleAttribute) {
assignedSlot.removeAttribute('style');
}
}

ancestor = assignedSlot;
if (offsetParent !== newOffsetParent) {
offsetParent = newOffsetParent;
foundInsideSlot = true;
}
} else if (ancestor.host && foundInsideSlot) {
break;
}
ancestor = ancestor.host || ancestor.parentNode;
}
return offsetParent;
}
});
56 changes: 56 additions & 0 deletions test/basic.html
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,17 @@
</template>
</test-fixture>

<test-fixture id="offset-parent-new-behavior">
<template>
<div id=container>
<div>
<div id=target style="height: 100px; width: 100px; background-color: red"></div>
<paper-tooltip for="target">tooltip text</paper-tooltip>
</div>
</div>
</template>
</test-fixture>

<script type="module">
import '@polymer/iron-test-helpers/mock-interactions.js';
import '../paper-tooltip.js';
Expand Down Expand Up @@ -492,6 +503,51 @@
expect(tooltip._removeListeners.callCount).to.be.equal(1);
expect(tooltip._addListeners.callCount).to.be.equal(1);
});

test('offsetParent new spec behavior', function() {
var f = fixture('offset-parent-new-behavior');
var target = f.querySelector('#target');
var tooltip = f.querySelector('paper-tooltip');

var shadowRoot = f.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<style>
.dialog {
display: block;
position: absolute;
left: 0px;
right: 0px;
width: 100px;
margin: auto;
}
</style>
<div class=dialog>
<slot></slot>
</div>
`;

var actualTooltip = dom(tooltip.root).querySelector('#tooltip');
assert.isTrue(isHidden(actualTooltip));

MockInteractions.focus(target);
assert.isFalse(isHidden(actualTooltip));

var divRect = target.getBoundingClientRect();
expectToBasicallyEqual(divRect.width, 100);
expectToBasicallyEqual(divRect.height, 100);

var contentRect = tooltip.getBoundingClientRect();
expectToBasicallyEqual(contentRect.width, 70);
expectToBasicallyEqual(contentRect.height, 30);

// Check for correct 'bottom' positioning: the horizontal center of the
// target and tooltip are aligned, and the top of the tooltip is
// `offset` pixels below the bottom of the target.
expectToBasicallyEqual(
contentRect.left + contentRect.width / 2,
divRect.left + divRect.width / 2);
expectToBasicallyEqual(contentRect.top - divRect.bottom, tooltip.offset);
});
});

suite('tooltip is inside a custom element', function() {
Expand Down