ttrss/lib/dojo/dnd/autoscroll.js.uncompressed.js

150 lines
4.5 KiB
JavaScript

define("dojo/dnd/autoscroll", ["../_base/lang", "../sniff", "../_base/window", "../dom-geometry", "../dom-style", "../window"],
function(lang, has, win, domGeom, domStyle, winUtils){
// module:
// dojo/dnd/autoscroll
var exports = {
// summary:
// Used by dojo/dnd/Manager to scroll document or internal node when the user
// drags near the edge of the viewport or a scrollable node
};
lang.setObject("dojo.dnd.autoscroll", exports);
exports.getViewport = winUtils.getBox;
exports.V_TRIGGER_AUTOSCROLL = 32;
exports.H_TRIGGER_AUTOSCROLL = 32;
exports.V_AUTOSCROLL_VALUE = 16;
exports.H_AUTOSCROLL_VALUE = 16;
// These are set by autoScrollStart().
// Set to default values in case autoScrollStart() isn't called. (back-compat, remove for 2.0)
var viewport,
doc = win.doc,
maxScrollTop = Infinity,
maxScrollLeft = Infinity;
exports.autoScrollStart = function(d){
// summary:
// Called at the start of a drag.
// d: Document
// The document of the node being dragged.
doc = d;
viewport = winUtils.getBox(doc);
// Save height/width of document at start of drag, before it gets distorted by a user dragging an avatar past
// the document's edge
var html = win.body(doc).parentNode;
maxScrollTop = Math.max(html.scrollHeight - viewport.h, 0);
maxScrollLeft = Math.max(html.scrollWidth - viewport.w, 0); // usually 0
};
exports.autoScroll = function(e){
// summary:
// a handler for mousemove and touchmove events, which scrolls the window, if
// necessary
// e: Event
// mousemove/touchmove event
// FIXME: needs more docs!
var v = viewport || winUtils.getBox(doc), // getBox() call for back-compat, in case autoScrollStart() wasn't called
html = win.body(doc).parentNode,
dx = 0, dy = 0;
if(e.clientX < exports.H_TRIGGER_AUTOSCROLL){
dx = -exports.H_AUTOSCROLL_VALUE;
}else if(e.clientX > v.w - exports.H_TRIGGER_AUTOSCROLL){
dx = Math.min(exports.H_AUTOSCROLL_VALUE, maxScrollLeft - html.scrollLeft); // don't scroll past edge of doc
}
if(e.clientY < exports.V_TRIGGER_AUTOSCROLL){
dy = -exports.V_AUTOSCROLL_VALUE;
}else if(e.clientY > v.h - exports.V_TRIGGER_AUTOSCROLL){
dy = Math.min(exports.V_AUTOSCROLL_VALUE, maxScrollTop - html.scrollTop); // don't scroll past edge of doc
}
window.scrollBy(dx, dy);
};
exports._validNodes = {"div": 1, "p": 1, "td": 1};
exports._validOverflow = {"auto": 1, "scroll": 1};
exports.autoScrollNodes = function(e){
// summary:
// a handler for mousemove and touchmove events, which scrolls the first available
// Dom element, it falls back to exports.autoScroll()
// e: Event
// mousemove/touchmove event
// FIXME: needs more docs!
var b, t, w, h, rx, ry, dx = 0, dy = 0, oldLeft, oldTop;
for(var n = e.target; n;){
if(n.nodeType == 1 && (n.tagName.toLowerCase() in exports._validNodes)){
var s = domStyle.getComputedStyle(n),
overflow = (s.overflow.toLowerCase() in exports._validOverflow),
overflowX = (s.overflowX.toLowerCase() in exports._validOverflow),
overflowY = (s.overflowY.toLowerCase() in exports._validOverflow);
if(overflow || overflowX || overflowY){
b = domGeom.getContentBox(n, s);
t = domGeom.position(n, true);
}
// overflow-x
if(overflow || overflowX){
w = Math.min(exports.H_TRIGGER_AUTOSCROLL, b.w / 2);
rx = e.pageX - t.x;
if(has("webkit") || has("opera")){
// FIXME: this code should not be here, it should be taken into account
// either by the event fixing code, or the domGeom.position()
// FIXME: this code doesn't work on Opera 9.5 Beta
rx += win.body().scrollLeft;
}
dx = 0;
if(rx > 0 && rx < b.w){
if(rx < w){
dx = -w;
}else if(rx > b.w - w){
dx = w;
}
oldLeft = n.scrollLeft;
n.scrollLeft = n.scrollLeft + dx;
}
}
// overflow-y
if(overflow || overflowY){
//console.log(b.l, b.t, t.x, t.y, n.scrollLeft, n.scrollTop);
h = Math.min(exports.V_TRIGGER_AUTOSCROLL, b.h / 2);
ry = e.pageY - t.y;
if(has("webkit") || has("opera")){
// FIXME: this code should not be here, it should be taken into account
// either by the event fixing code, or the domGeom.position()
// FIXME: this code doesn't work on Opera 9.5 Beta
ry += win.body().scrollTop;
}
dy = 0;
if(ry > 0 && ry < b.h){
if(ry < h){
dy = -h;
}else if(ry > b.h - h){
dy = h;
}
oldTop = n.scrollTop;
n.scrollTop = n.scrollTop + dy;
}
}
if(dx || dy){ return; }
}
try{
n = n.parentNode;
}catch(x){
n = null;
}
}
exports.autoScroll(e);
};
return exports;
});