From 73f1ac098b0e2b3bb8ba26b072a2e6c198640b45 Mon Sep 17 00:00:00 2001 From: Winston Chang Date: Thu, 11 Jul 2019 12:12:48 -0500 Subject: [PATCH 1/3] Update scrollIntoViewIfNeeded for Firefox. Closes #111 --- inst/htmlwidgets/lib/profvis/profvis.js | 70 +++++++++++++++++++------ 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/inst/htmlwidgets/lib/profvis/profvis.js b/inst/htmlwidgets/lib/profvis/profvis.js index 43134204..c65285d3 100644 --- a/inst/htmlwidgets/lib/profvis/profvis.js +++ b/inst/htmlwidgets/lib/profvis/profvis.js @@ -2653,30 +2653,68 @@ profvis = (function() { })(); + // Polyfill for scrollIntoViewIfNeeded() + // From https://gist.github.com/jocki84/6ffafd003387179a988e + // License: CC-BY if (!Element.prototype.scrollIntoViewIfNeeded) { Element.prototype.scrollIntoViewIfNeeded = function (centerIfNeeded) { - centerIfNeeded = arguments.length === 0 ? true : !!centerIfNeeded; + "use strict"; - 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; + function makeRange(start, length) { + return {"start": start, "length": length, "end": start + length}; + } - if ((overTop || overBottom) && centerIfNeeded) { - parent.scrollTop = this.offsetTop - parent.offsetTop - parent.clientHeight / 2 - parentBorderTopWidth + this.clientHeight / 2; + 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; } - if ((overLeft || overRight) && centerIfNeeded) { - parent.scrollLeft = this.offsetLeft - parent.offsetLeft - parent.clientWidth / 2 - parentBorderLeftWidth + this.clientWidth / 2; + function makePoint(x, y) { + return { + "x": x, + "y": y, + "translate": function translate(dX, dY) { + return makePoint(x + dX, y + dY); + } + }; } - if ((overTop || overBottom || overLeft || overRight) && !centerIfNeeded) { - this.scrollIntoView(alignWithTop); + 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; } }; } From 1175c0d1b2a6c4ae29f5befc764bd91b58f71d79 Mon Sep 17 00:00:00 2001 From: Winston Chang Date: Fri, 12 Jul 2019 10:57:14 -0500 Subject: [PATCH 2/3] Move scrollIntoViewIfNeeded polyfill to separate file --- inst/htmlwidgets/lib/profvis/profvis.js | 67 ------------------------ inst/htmlwidgets/lib/profvis/scroll.js | 69 +++++++++++++++++++++++++ inst/htmlwidgets/profvis.yaml | 4 +- 3 files changed, 72 insertions(+), 68 deletions(-) create mode 100644 inst/htmlwidgets/lib/profvis/scroll.js diff --git a/inst/htmlwidgets/lib/profvis/profvis.js b/inst/htmlwidgets/lib/profvis/profvis.js index c65285d3..af3e3a3f 100644 --- a/inst/htmlwidgets/lib/profvis/profvis.js +++ b/inst/htmlwidgets/lib/profvis/profvis.js @@ -2652,72 +2652,5 @@ profvis = (function() { }); })(); - - // Polyfill for scrollIntoViewIfNeeded() - // From https://gist.github.com/jocki84/6ffafd003387179a988e - // License: CC-BY - 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; - } - }; - } - return profvis; })(); diff --git a/inst/htmlwidgets/lib/profvis/scroll.js b/inst/htmlwidgets/lib/profvis/scroll.js new file mode 100644 index 00000000..62eb7634 --- /dev/null +++ b/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; + } + }; + } + +})() \ No newline at end of file diff --git a/inst/htmlwidgets/profvis.yaml b/inst/htmlwidgets/profvis.yaml index f4fd3194..e1813c62 100644 --- a/inst/htmlwidgets/profvis.yaml +++ b/inst/htmlwidgets/profvis.yaml @@ -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 From 70efd8283283f47cffd45ebcef08044d8e083a05 Mon Sep 17 00:00:00 2001 From: Winston Chang Date: Fri, 12 Jul 2019 11:02:12 -0500 Subject: [PATCH 3/3] Update NEWS --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index c6fd0c0e..740b7dc4 100644 --- a/NEWS.md +++ b/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 =============