Skip to content
This repository has been archived by the owner on Dec 19, 2024. It is now read-only.

Polyfill legacy offsetParent behavior #156

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
46 changes: 44 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,44 @@ 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;
josepharhar marked this conversation as resolved.
Show resolved Hide resolved
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;
}
});
53 changes: 53 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,48 @@
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));

debugger;

josepharhar marked this conversation as resolved.
Show resolved Hide resolved
var divRect = target.getBoundingClientRect();
expectToBasicallyEqual(divRect.width, 100);
expectToBasicallyEqual(divRect.height, 100);

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

expectToBasicallyEqual(contentRect.left, 415);
expectToBasicallyEqual(contentRect.top, 114);
josepharhar marked this conversation as resolved.
Show resolved Hide resolved
});
});

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