Bug 461843 - Show indication of where on the page you are when scrolling [r=mfinkle]

This commit is contained in:
Vivien Nicolas 2010-12-15 21:07:36 +01:00
parent fc38d3fc56
commit e9b21c9fd1
5 changed files with 123 additions and 1 deletions

View File

@ -1503,6 +1503,10 @@
let height = Math.floor(this.getBoundingClientRect().height);
this.top = window.innerHeight - height;
this._spacer.setAttribute("height", height);
let event = document.createEvent("Events");
event.initEvent("SizeChanged", true, false);
this.dispatchEvent(event);
]]></body>
</method>
@ -1542,6 +1546,7 @@
this.removeAttribute("type");
this.model = null;
this.contentHasChanged();
this._spacer.hidden = true;
]]></body>
</method>

View File

@ -1126,6 +1126,13 @@ var Browser = {
Browser.MainDragger = function MainDragger() {
this._horizontalScrollbar = document.getElementById("horizontal-scroller");
this._verticalScrollbar = document.getElementById("vertical-scroller");
this._scrollScales = { x: 0, y: 0 };
Elements.browsers.addEventListener("PanBegin", this, false);
window.addEventListener("PanFinished", this, false);
Elements.contentNavigator.addEventListener("SizeChanged", this, false);
};
Browser.MainDragger.prototype = {
@ -1156,10 +1163,41 @@ Browser.MainDragger.prototype = {
Browser.tryFloatToolbar(doffset.x, 0);
this._panScroller(Browser.controlsScrollboxScroller, doffset);
this._panScroller(Browser.pageScrollboxScroller, doffset);
this._updateScrollbars();
return !doffset.equals(dx, dy);
},
handleEvent: function handleEvent(aEvent) {
switch (aEvent.type) {
case "PanBegin": {
let browser = Browser.selectedBrowser;
let width = window.innerWidth, height = window.innerHeight;
let contentWidth = browser.contentDocumentWidth * browser.scale;
let contentHeight = browser.contentDocumentHeight * browser.scale;
// Allow a small margin on both sides to prevent adding scrollbars
// on small viewport approximation
const ALLOWED_MARGIN = 5;
const SCROLL_CORNER_SIZE = 8;
this._scrollScales = {
x: (width + ALLOWED_MARGIN) < contentWidth ? (width - SCROLL_CORNER_SIZE) / contentWidth : 0,
y: (height + ALLOWED_MARGIN) < contentHeight ? (height - SCROLL_CORNER_SIZE) / contentHeight : 0
}
this._showScrollbars();
break;
}
case "PanFinished":
this._hideScrollbars();
break;
case "SizeChanged":
let height = Elements.contentNavigator.getBoundingClientRect().height;
this._horizontalScrollbar.setAttribute("bottom", 2 + height);
break;
}
},
/** Return offset that pans controls away from screen. Updates doffset with leftovers. */
_panControlsAwayOffset: function(doffset) {
let x = 0, y = 0, rect;
@ -1188,6 +1226,46 @@ Browser.MainDragger.prototype = {
scroller.scrollBy(doffset.x, doffset.y);
let scroll1 = Browser.getScrollboxPosition(scroller);
doffset.subtract(scroll1.x - scroll.x, scroll1.y - scroll.y);
},
_updateScrollbars: function _updateScrollbars() {
let scaleX = this._scrollScales.x, scaleY = this._scrollScales.y;
let contentScroll = Browser.getScrollboxPosition(Browser.contentScrollboxScroller);
if (scaleX)
this._horizontalScrollbar.left = contentScroll.x * scaleX;
if (scaleY) {
const SCROLLER_MARGIN = 2;
this._verticalScrollbar.top = contentScroll.y * scaleY;
// right scrollbar is out of view when showing the left sidebar,
// the 'solution' for now is to reposition it if needed
if (Browser.floatedWhileDragging) {
let [leftVis,,leftW,] = Browser.computeSidebarVisibility();
this._verticalScrollbar.setAttribute("right", Math.max(SCROLLER_MARGIN, leftW * leftVis + SCROLLER_MARGIN));
}
else if (this._verticalScrollbar.getAttribute("right") != SCROLLER_MARGIN) {
this._verticalScrollbar.setAttribute("right", SCROLLER_MARGIN);
}
}
},
_showScrollbars: function _showScrollbars() {
let scaleX = this._scrollScales.x, scaleY = this._scrollScales.y;
if (scaleX) {
this._horizontalScrollbar.setAttribute("panning", "true");
this._horizontalScrollbar.width = window.innerWidth * scaleX;
}
if (scaleY) {
this._verticalScrollbar.setAttribute("panning", "true");
this._verticalScrollbar.height = window.innerHeight * scaleY;
}
},
_hideScrollbars: function _hideScrollbars() {
this._horizontalScrollbar.removeAttribute("panning");
this._verticalScrollbar.removeAttribute("panning");
}
};

View File

@ -280,7 +280,11 @@
<!-- Content viewport -->
<vbox id="content-viewport" class="window-width window-height">
<!-- Content viewport -->
<deck id="browsers" flex="1"/>
<stack>
<deck id="browsers" flex="1"/>
<!-- vertical scrollbar -->
<box id="vertical-scroller" class="scroller" orient="vertical" right="2" top="0"/>
</stack>
<box id="content-navigator-spacer" hidden="true"/>
</vbox>
</vbox>
@ -294,6 +298,9 @@
placeholder="&selectHelper.emptytext;" type="search" flex="1" hidden="true"/>
<textbox id="find-helper-textbox" class="search-bar content-navigator-item" oncommand="FindHelperUI.search(this.value)" oninput="FindHelperUI.updateCommands(this.value);" type="search" flex="1"/>
</vbox>
<!-- horizontal scrollbar -->
<box id="horizontal-scroller" class="scroller" orient="horizontal" left="0" bottom="2"/>
</stack>
<!-- Right toolbar -->

View File

@ -391,6 +391,9 @@ MouseModule.prototype = {
if (!dragData.dragging) {
this._dragger.dragStop(0, 0, this._targetScrollInterface);
this._dragger = null;
// bug 619412
// XXX why is PanFinished not dispatched on the same target as PanBegin
let event = document.createEvent("Events");
event.initEvent("PanFinished", true, false);
document.dispatchEvent(event);

View File

@ -1628,3 +1628,32 @@ pageaction:not([image]) > hbox >.pageaction-image {
#syncsetup-customserver {
-moz-margin-start: 12px;
}
/* content scrollbars */
.scroller {
opacity: 0;
background-color: rgba(0, 0, 0, 0.4) !important;
-moz-border-top-colors: none !important;
-moz-border-bottom-colors: none !important;
-moz-border-right-colors: none !important;
-moz-border-left-colors: none !important;
-moz-border-radius: 3px;
border: 1px solid rgba(255, 255, 255, 0.4) !important;
}
.scroller[panning="true"] {
opacity: 1;
}
.scroller[orient="vertical"] {
min-width: 6px;
width: 6px;
min-height: 12px;
}
.scroller[orient="horizontal"] {
min-height: 6px;
height: 6px;
min-width: 12px;
}