Skip to content

Commit

Permalink
Fix auto-scrolling in Firefox (#113)
Browse files Browse the repository at this point in the history
* Update scrollIntoViewIfNeeded for Firefox. Closes #111

* Move scrollIntoViewIfNeeded polyfill to separate file

* Update NEWS
  • Loading branch information
wch committed Jul 12, 2019
1 parent e8d2fbe commit 51b0671
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 30 deletions.
1 change: 1 addition & 0 deletions NEWS.md
@@ -1,6 +1,7 @@
profvis 0.3.6.9000
=============

* Fixed [#111](https://github.com/rstudio/profvis/issues/111): auto-scrolling to lines of code did not work in some browsers. ([#113](https://github.com/rstudio/profvis/pull/113))

profvis 0.3.6
=============
Expand Down
29 changes: 0 additions & 29 deletions inst/htmlwidgets/lib/profvis/profvis.js
Expand Up @@ -2652,34 +2652,5 @@ profvis = (function() {
});
})();


if (!Element.prototype.scrollIntoViewIfNeeded) {
Element.prototype.scrollIntoViewIfNeeded = function (centerIfNeeded) {
centerIfNeeded = arguments.length === 0 ? true : !!centerIfNeeded;

var parent = this.parentNode,
parentComputedStyle = window.getComputedStyle(parent, null),
parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue('border-top-width')),
parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue('border-left-width')),
overTop = this.offsetTop - parent.offsetTop < parent.scrollTop,
overBottom = (this.offsetTop - parent.offsetTop + this.clientHeight - parentBorderTopWidth) > (parent.scrollTop + parent.clientHeight),
overLeft = this.offsetLeft - parent.offsetLeft < parent.scrollLeft,
overRight = (this.offsetLeft - parent.offsetLeft + this.clientWidth - parentBorderLeftWidth) > (parent.scrollLeft + parent.clientWidth),
alignWithTop = overTop && !overBottom;

if ((overTop || overBottom) && centerIfNeeded) {
parent.scrollTop = this.offsetTop - parent.offsetTop - parent.clientHeight / 2 - parentBorderTopWidth + this.clientHeight / 2;
}

if ((overLeft || overRight) && centerIfNeeded) {
parent.scrollLeft = this.offsetLeft - parent.offsetLeft - parent.clientWidth / 2 - parentBorderLeftWidth + this.clientWidth / 2;
}

if ((overTop || overBottom || overLeft || overRight) && !centerIfNeeded) {
this.scrollIntoView(alignWithTop);
}
};
}

return profvis;
})();
69 changes: 69 additions & 0 deletions inst/htmlwidgets/lib/profvis/scroll.js
@@ -0,0 +1,69 @@
(function() {

// Polyfill for scrollIntoViewIfNeeded()
// From https://gist.github.com/jocki84/6ffafd003387179a988e
// License: ISC
if (!Element.prototype.scrollIntoViewIfNeeded) {
Element.prototype.scrollIntoViewIfNeeded = function (centerIfNeeded) {
"use strict";

function makeRange(start, length) {
return {"start": start, "length": length, "end": start + length};
}

function coverRange(inner, outer) {
if (
false === centerIfNeeded ||
(outer.start < inner.end && inner.start < outer.end)
) {
return Math.max(
inner.end - outer.length,
Math.min(outer.start, inner.start)
);
}
return (inner.start + inner.end - outer.length) / 2;
}

function makePoint(x, y) {
return {
"x": x,
"y": y,
"translate": function translate(dX, dY) {
return makePoint(x + dX, y + dY);
}
};
}

function absolute(elem, pt) {
while (elem) {
pt = pt.translate(elem.offsetLeft, elem.offsetTop);
elem = elem.offsetParent;
}
return pt;
}

var target = absolute(this, makePoint(0, 0)),
extent = makePoint(this.offsetWidth, this.offsetHeight),
elem = this.parentNode,
origin;

while (elem instanceof HTMLElement) {
// Apply desired scroll amount.
origin = absolute(elem, makePoint(elem.clientLeft, elem.clientTop));
elem.scrollLeft = coverRange(
makeRange(target.x - origin.x, extent.x),
makeRange(elem.scrollLeft, elem.clientWidth)
);
elem.scrollTop = coverRange(
makeRange(target.y - origin.y, extent.y),
makeRange(elem.scrollTop, elem.clientHeight)
);

// Determine actual scroll amount by reading back scroll properties.
target = target.translate(-elem.scrollLeft, -elem.scrollTop);
elem = elem.parentNode;
}
};
}

})()
4 changes: 3 additions & 1 deletion inst/htmlwidgets/profvis.yaml
Expand Up @@ -12,7 +12,9 @@ dependencies:
- name: profvis
version: 0.3.6.9000
src: "htmlwidgets/lib/profvis"
script: profvis.js
script:
- profvis.js
- scroll.js
stylesheet: profvis.css
- name: highlight
version: 6.2.0
Expand Down

0 comments on commit 51b0671

Please sign in to comment.