Skip to content
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
31 changes: 3 additions & 28 deletions src/js/utils/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -439,40 +439,15 @@ export function unblockTextSelection() {
* the method is supported at all (it is in all browsers we claim to support)
* and that the element is in the DOM before continuing.
*
* This wrapper function also shims properties which are not provided by some
* older browsers (namely, IE8).
*
* Additionally, some browsers do not support adding properties to a
* `ClientRect`/`DOMRect` object; so, we shallow-copy it with the standard
* properties (except `x` and `y` which are not widely supported). This helps
* avoid implementations where keys are non-enumerable.
*
* @param {Element} el
* Element whose `ClientRect` we want to calculate.
*
* @return {Object|undefined}
* Always returns a plain object - or `undefined` if it cannot.
* @return {DOMRect|undefined}
* The `DOMRect` for the element - or `undefined` if it cannot.
*/
export function getBoundingClientRect(el) {
if (el && el.getBoundingClientRect && el.parentNode) {
const rect = el.getBoundingClientRect();
const result = {};

['bottom', 'height', 'left', 'right', 'top', 'width'].forEach(k => {
if (rect[k] !== undefined) {
result[k] = rect[k];
}
});

if (!result.height) {
result.height = parseFloat(computedStyle(el, 'height'));
}

if (!result.width) {
result.width = parseFloat(computedStyle(el, 'width'));
}

return result;
return el.getBoundingClientRect();
}
}

Expand Down
30 changes: 11 additions & 19 deletions test/unit/utils/dom.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -609,31 +609,23 @@ QUnit.test('$() and $$()', function(assert) {
);
});

QUnit.test('getBoundingClientRect() returns an object for elements that support it', function(assert) {
QUnit.test('getBoundingClientRect() returns the native DOMRect for elements that support it', function(assert) {
const mockRect = {
bottom: 3,
height: 10,
left: 4,
right: 2,
top: 1,
width: 20
};
const mockEl = {
getBoundingClientRect: sinon.spy(() => {
return {
bottom: 3,
height: 10,
left: 4,
right: 2,
top: 1,
width: 20
};
}),
getBoundingClientRect: sinon.spy(() => mockRect),
parentNode: true
};

const actual = Dom.getBoundingClientRect(mockEl);

// The expected result is what is returned by the mock element.
const expected = mockEl.getBoundingClientRect.firstCall.returnValue;

assert.notStrictEqual(actual, expected, 'the object returned by the mock element was cloned and not returned directly');

Object.keys(expected).forEach(k => {
assert.strictEqual(actual[k], expected[k], `the "${k}" returned by the Dom util matches what was returned by the mock element`);
});
assert.strictEqual(actual, mockRect, 'returns the native DOMRect directly');
});

QUnit.test('isSingleLeftClick() returns false for mousemove event', function(assert) {
Expand Down