diff --git a/chrome/content/browser.js b/chrome/content/browser.js
--- a/chrome/content/browser.js
+++ b/chrome/content/browser.js
@@ -1350,27 +1350,29 @@ var Browser = {
let dummy = getComputedStyle(document.documentElement, "").width;
}
};
Browser.MainDragger = function MainDragger(browserView) {
this.bv = browserView;
this.draggedFrame = null;
this.contentScrollbox = null;
+ this.scrolledElement = null;
};
Browser.MainDragger.prototype = {
isDraggable: function isDraggable(target, scroller) { return true; },
dragStart: function dragStart(clientX, clientY, target, scroller) {
let [x, y] = Browser.transformClientToBrowser(clientX, clientY);
let element = Browser.elementFromPoint(x, y);
this.draggedFrame = null;
this.contentScrollbox = null;
+ this.scrolledElement = null;
// Check if we are in a scrollable HTML element
let htmlElement = element;
if (htmlElement && htmlElement instanceof HTMLElement) {
let win = htmlElement.ownerDocument.defaultView;
let oScroll;
let oAuto;
for (; htmlElement; htmlElement = htmlElement.parentNode) {
@@ -1380,67 +1382,146 @@ Browser.MainDragger.prototype = {
let overflowX = cs.getPropertyValue("overflow-x");
let overflowY = cs.getPropertyValue("overflow-y");
let cbr = htmlElement.getBoundingClientRect();
oScroll = (overflow == "scroll") || (overflowX == "scroll") || (overflowY == "scroll");
oAuto = (overflow == "auto") || (overflowX == "auto") || (overflowY == "auto");
if (oScroll ||
(oAuto && (cbr.height < target.scrollHeight || cbr.width < target.scrollWidth))) {
+ this.scrolledElement = htmlElement;
+ this.scrolledElement.setAttribute("panning", "true");
this.contentScrollbox = this._createDivScrollBox(htmlElement);
return;
}
} catch(e) {}
}
}
// Check if we are in XUL land
let xulElement = element;
if (xulElement && xulElement instanceof XULElement) {
for (; xulElement; xulElement = xulElement.parentNode) {
if (xulElement.localName == "treechildren") {
+ this.scrolledElement = xulElement.parentNode;
+ this.scrolledElement.setAttribute("panning", "true");
this.contentScrollbox = this._createTreeScrollBox(xulElement.parentNode);
return;
}
let wrapper = xulElement.wrappedJSObject;
let scrollable = false;
try {
scrollable = (wrapper.scrollBoxObject != null) || (wrapper.boxObject.QueryInterface(Ci.nsIScrollBoxObject));
} catch(e) {}
if (scrollable) {
+ this.scrolledElement = xulElement;
+ this.scrolledElement.setAttribute("panning", "true");
this.contentScrollbox = wrapper.scrollBoxObject || wrapper.boxObject.QueryInterface(Ci.nsIScrollBoxObject);
return;
}
}
}
+ this.showScrollBars();
+ this.drawScrollBars();
if (element)
this.draggedFrame = element.ownerDocument.defaultView;
this.bv.pauseRendering();
// XXX shouldn't know about observer
// adding pause in pauseRendering isn't so great, because tiles will hardly ever prefetch while
// loading state is going (and already, the idle timer is bigger during loading so it doesn't fit
// into the aggressive flag).
this.bv._idleServiceObserver.pause();
},
dragStop: function dragStop(dx, dy, scroller) {
+ if (this.scrolledElement)
+ this.scrolledElement.removeAttribute("panning");
+ this.scrolledElement = null;
this.draggedFrame = null;
this.dragMove(Browser.snapSidebars(), 0, scroller);
Browser.tryUnfloatToolbar();
+ this.hideScrollBars();
+
this.bv.resumeRendering();
// XXX shouldn't know about observer
this.bv._idleServiceObserver.resume();
},
+ kScrollBarWidth : 8,
+
+ showScrollBars: function showScrollBars() {
+ let [vpWidth, vpHeight] = Browser._browserView.getViewportDimensions();
+ let visibleRect = Browser._browserView.getVisibleRect();
+ if (vpHeight > visibleRect.height) {
+ let scroll = document.getElementById("scrollbar-y");
+ scroll.setAttribute("left", visibleRect.width - this.kScrollBarWidth - 4);
+ scroll.setAttribute("top", 0);
+ scroll.width = this.kScrollBarWidth;
+ scroll.height = visibleRect.height;
+ scroll.style.display = "block";
+ }
+ if (vpWidth > visibleRect.width) {
+ let scroll = document.getElementById("scrollbar-x");
+ scroll.setAttribute("left", 0);
+ scroll.setAttribute("top", visibleRect.height - this.kScrollBarWidth - 4);
+ scroll.width = visibleRect.width;
+ scroll.height = this.kScrollBarWidth;
+ scroll.style.display = "block";
+ }
+ },
+
+ drawScrollBars: function drawScrollBars() {
+ let [vpWidth, vpHeight] = Browser._browserView.getViewportDimensions();
+ let visibleRect = Browser._browserView.getVisibleRect();
+ let scrollpoint = Browser.getScrollboxPosition(Browser.contentScrollboxScroller);
+
+ // vertical scrollbar
+ if (vpHeight > visibleRect.height) {
+ let scroll = document.getElementById("scrollbar-y");
+ let y = Math.round(scrollpoint.y * visibleRect.height / vpHeight);
+ let height = Math.round(visibleRect.height * visibleRect.height / vpHeight);
+ let width = this.kScrollBarWidth;
+ let ctx = scroll.getContext("2d");
+ ctx.save();
+ ctx.clearRect(0, 0, scroll.width, scroll.height);
+ ctx.fillStyle = "rgba(192, 192, 192, 0.75)";
+ ctx.strokeStyle = "rgb(192, 192, 192)";
+ ctx.strokeRect(0, y, width, height);
+ ctx.fillRect(0, y, width, height);
+ ctx.restore();
+ }
+
+ // horizontal scrollbar
+ if (vpWidth > visibleRect.width) {
+ let scroll = document.getElementById("scrollbar-x");
+ x = Math.round(scrollpoint.x * visibleRect.width / vpWidth);
+ let width = Math.round(visibleRect.width * visibleRect.width / vpWidth);
+ let height = this.kScrollBarWidth;
+ let ctx = scroll.getContext("2d");
+ ctx.save();
+ ctx.clearRect(0, 0, scroll.width, scroll.height);
+ ctx.fillStyle = "rgba(192, 192, 192, 0.75)";
+ ctx.strokeStyle = "rgb(192, 192, 192)";
+ ctx.strokeRect(x, 0, width, height);
+ ctx.fillRect(x, 0, width, height);
+ ctx.restore();
+ }
+ },
+
+ hideScrollBars: function hideScrollBars() {
+ document.getElementById("scrollbar-y").style.display = "none";
+ document.getElementById("scrollbar-x").style.display = "none";
+ },
+
dragMove: function dragMove(dx, dy, scroller) {
let elem = this.draggedFrame;
let doffset = new Point(dx, dy);
let render = false;
this.bv.onBeforeVisibleMove(dx, dy);
// First calculate any panning to take sidebars out of view
@@ -1464,16 +1545,18 @@ Browser.MainDragger.prototype = {
// Any leftover panning in doffset would bring controls into view. Add to sidebar
// away panning for the total scroll offset.
doffset.add(panOffset);
Browser.tryFloatToolbar(doffset.x, 0);
this._panScroller(Browser.controlsScrollboxScroller, doffset);
this._panScroller(Browser.pageScrollboxScroller, doffset);
+ this.drawScrollBars();
+
this.bv.onAfterVisibleMove();
if (render)
this.bv.renderNow();
return !doffset.equals(dx, dy);
},
diff --git a/chrome/content/browser.xul b/chrome/content/browser.xul
--- a/chrome/content/browser.xul
+++ b/chrome/content/browser.xul
@@ -238,22 +238,22 @@
-
-
+
-
-
+
+
+