diff --git a/toolkit/content/widgets/scrollbox.xml b/toolkit/content/widgets/scrollbox.xml index ff1bc0040c11..df92aa238881 100644 --- a/toolkit/content/widgets/scrollbox.xml +++ b/toolkit/content/widgets/scrollbox.xml @@ -185,14 +185,18 @@ return innerRect; ]]> - - - + + - - - + null + + + + + @@ -611,40 +642,73 @@ ]]> + false - { + this._scrollButtonUpdatePending = false; + + this.setAttribute("scrolledtoend", "true"); + this.setAttribute("scrolledtostart", "true"); + }); + return; } - if (scrolledToEnd) - this.setAttribute("scrolledtoend", "true"); - else - this.removeAttribute("scrolledtoend"); + // Wait until after the next paint to get current layout data from + // getBoundsWithoutFlushing. + window.requestAnimationFrame(() => { + window.requestAnimationFrame(() => { + this._scrollButtonUpdatePending = false; - if (scrolledToStart) - this.setAttribute("scrolledtostart", "true"); - else - this.removeAttribute("scrolledtostart"); + let scrolledToStart = false; + let scrolledToEnd = false; + + if (this.hasAttribute("notoverflowing")) { + scrolledToStart = true; + scrolledToEnd = true; + } else { + let scrollboxPaddingStart = Math.round(this.scrollboxPaddingStart); + let scrollboxPaddingEnd = Math.round(this.scrollboxPaddingEnd); + let [start, end] = this._startEndProps; + if (this._isRTLScrollbox) { + [start, end] = [end, start]; + scrollboxPaddingStart = -scrollboxPaddingStart; + scrollboxPaddingEnd = -scrollboxPaddingEnd; + } + + let scrollboxRect = this._boundsWithoutFlushing(this._scrollbox); + let elements = this._getScrollableElements(); + let [firstElement, lastElement] = [elements[0], elements[elements.length - 1]]; + + if (firstElement && + this._boundsWithoutFlushing(firstElement)[start] - scrollboxPaddingStart == scrollboxRect[start]) { + scrolledToStart = true; + } else if (lastElement && + this._boundsWithoutFlushing(lastElement)[end] + scrollboxPaddingEnd == scrollboxRect[end]) { + scrolledToEnd = true; + } + } + + if (scrolledToEnd) { + this.setAttribute("scrolledtoend", "true"); + } else { + this.removeAttribute("scrolledtoend"); + } + + if (scrolledToStart) { + this.setAttribute("scrolledtostart", "true"); + } else { + this.removeAttribute("scrolledtostart"); + } + }); + }); ]]> @@ -797,27 +861,7 @@ ]]> { - // Scrolling animation has finished. - this._delayedUpdateScrollButtonsTimer = 0; - this._updateScrollButtonsDisabledState(); - }, 200); + this._updateScrollButtonsDisabledState(); ]]>