mirror of
https://git.tt-rss.org/git/tt-rss.git
synced 2025-12-15 00:35:57 +00:00
build custom layer of Dojo to speed up loading of tt-rss (refs #293)
This commit is contained in:
@@ -5,85 +5,181 @@
|
||||
*/
|
||||
|
||||
|
||||
if(!dojo._hasResource["dojo.robot"]){
|
||||
dojo._hasResource["dojo.robot"]=true;
|
||||
if(!dojo._hasResource["dojo.robot"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dojo.robot"] = true;
|
||||
dojo.provide("dojo.robot");
|
||||
dojo.experimental("dojo.robot");
|
||||
dojo.require("doh.robot");
|
||||
dojo.require("dojo.window");
|
||||
|
||||
(function(){
|
||||
dojo.mixin(doh.robot,{_resolveNode:function(n){
|
||||
if(typeof n=="function"){
|
||||
n=n();
|
||||
}
|
||||
return n?dojo.byId(n):null;
|
||||
},_scrollIntoView:function(n){
|
||||
var d=dojo,dr=doh.robot,p=null;
|
||||
d.forEach(dr._getWindowChain(n),function(w){
|
||||
d.withGlobal(w,function(){
|
||||
var p2=d.position(n,false),b=d._getPadBorderExtents(n),_1=null;
|
||||
if(!p){
|
||||
p=p2;
|
||||
}else{
|
||||
_1=p;
|
||||
p={x:p.x+p2.x+b.l,y:p.y+p2.y+b.t,w:p.w,h:p.h};
|
||||
}
|
||||
dojo.window.scrollIntoView(n,p);
|
||||
p2=d.position(n,false);
|
||||
if(!_1){
|
||||
p=p2;
|
||||
}else{
|
||||
p={x:_1.x+p2.x+b.l,y:_1.y+p2.y+b.t,w:p.w,h:p.h};
|
||||
}
|
||||
n=w.frameElement;
|
||||
// users who use doh+dojo get the added convenience of dojo.mouseMoveAt,
|
||||
// instead of computing the absolute coordinates of their elements themselves
|
||||
dojo.mixin(doh.robot,{
|
||||
|
||||
_resolveNode: function(/*String||DOMNode||Function*/ n){
|
||||
if(typeof n == "function"){
|
||||
// if the user passed a function returning a node, evaluate it
|
||||
n = n();
|
||||
}
|
||||
return n? dojo.byId(n) : null;
|
||||
},
|
||||
|
||||
_scrollIntoView: function(/*Node*/ n){
|
||||
// scrolls the passed node into view, scrolling all ancester frames/windows as well.
|
||||
// Assumes parent iframes can be made fully visible given the current browser window size
|
||||
var d = dojo,
|
||||
dr = doh.robot,
|
||||
p = null;
|
||||
d.forEach(dr._getWindowChain(n), function(w){
|
||||
d.withGlobal(w, function(){
|
||||
// get the position of the node wrt its parent window
|
||||
// if it is a parent frame, its padding and border extents will get added in
|
||||
var p2 = d.position(n, false),
|
||||
b = d._getPadBorderExtents(n),
|
||||
oldp = null;
|
||||
// if p2 is the position of the original passed node, store the position away as p
|
||||
// otherwise, node is actually an iframe. in this case, add the iframe's position wrt its parent window and also the iframe's padding and border extents
|
||||
if(!p){
|
||||
p = p2;
|
||||
}else{
|
||||
oldp = p;
|
||||
p = {x: p.x+p2.x+b.l,
|
||||
y: p.y+p2.y+b.t,
|
||||
w: p.w,
|
||||
h: p.h};
|
||||
|
||||
}
|
||||
// scroll the parent window so that the node translated into the parent window's coordinate space is in view
|
||||
dojo.window.scrollIntoView(n,p);
|
||||
// adjust position for the new scroll offsets
|
||||
p2 = d.position(n, false);
|
||||
if(!oldp){
|
||||
p = p2;
|
||||
}else{
|
||||
p = {x: oldp.x+p2.x+b.l,
|
||||
y: oldp.y+p2.y+b.t,
|
||||
w: p.w,
|
||||
h: p.h};
|
||||
}
|
||||
// get the parent iframe so it can be scrolled too
|
||||
n = w.frameElement;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_position: function(/*Node*/ n){
|
||||
// Returns the dojo.position of the passed node wrt the passed window's viewport,
|
||||
// following any parent iframes containing the node and clipping the node to each iframe.
|
||||
// precondition: _scrollIntoView already called
|
||||
var d = dojo, p = null, M = Math.max, m = Math.min;
|
||||
// p: the returned position of the node
|
||||
d.forEach(doh.robot._getWindowChain(n), function(w){
|
||||
d.withGlobal(w, function(){
|
||||
// get the position of the node wrt its parent window
|
||||
// if it is a parent frame, its padding and border extents will get added in
|
||||
var p2 = d.position(n, false), b = d._getPadBorderExtents(n);
|
||||
// if p2 is the position of the original passed node, store the position away as p
|
||||
// otherwise, node is actually an iframe. in this case, add the iframe's position wrt its parent window and also the iframe's padding and border extents
|
||||
if(!p){
|
||||
p = p2;
|
||||
}else{
|
||||
var view;
|
||||
d.withGlobal(n.contentWindow,function(){
|
||||
view=dojo.window.getBox();
|
||||
});
|
||||
p2.r = p2.x+view.w;
|
||||
p2.b = p2.y+view.h;
|
||||
p = {x: M(p.x+p2.x,p2.x)+b.l, // clip left edge of node wrt the iframe
|
||||
y: M(p.y+p2.y,p2.y)+b.t, // top edge
|
||||
r: m(p.x+p2.x+p.w,p2.r)+b.l, // right edge (to compute width)
|
||||
b: m(p.y+p2.y+p.h,p2.b)+b.t}; // bottom edge (to compute height)
|
||||
// save a few bytes by computing width and height from r and b
|
||||
p.w = p.r-p.x;
|
||||
p.h = p.b-p.y;
|
||||
}
|
||||
// the new node is now the old node's parent iframe
|
||||
n=w.frameElement;
|
||||
});
|
||||
});
|
||||
return p;
|
||||
},
|
||||
|
||||
_getWindowChain : function(/*Node*/ n){
|
||||
// Returns an array of windows starting from the passed node's parent window and ending at dojo's window
|
||||
var cW = dojo.window.get(n.ownerDocument);
|
||||
var arr=[cW];
|
||||
var f = cW.frameElement;
|
||||
return (cW == dojo.global || f == null)? arr : arr.concat(doh.robot._getWindowChain(f));
|
||||
},
|
||||
|
||||
scrollIntoView : function(/*String||DOMNode||Function*/ node, /*Number, optional*/ delay){
|
||||
// summary:
|
||||
// Scroll the passed node into view, if it is not.
|
||||
//
|
||||
// node:
|
||||
// The id of the node, or the node itself, to move the mouse to.
|
||||
// If you pass an id or a function that returns a node, the node will not be evaluated until the movement executes.
|
||||
// This is useful if you need to move the mouse to an node that is not yet present.
|
||||
//
|
||||
// delay:
|
||||
// Delay, in milliseconds, to wait before firing.
|
||||
// The delay is a delta with respect to the previous automation call.
|
||||
//
|
||||
doh.robot.sequence(function(){
|
||||
doh.robot._scrollIntoView(doh.robot._resolveNode(node));
|
||||
}, delay);
|
||||
},
|
||||
|
||||
mouseMoveAt : function(/*String||DOMNode||Function*/ node, /*Integer, optional*/ delay, /*Integer, optional*/ duration, /*Number, optional*/ offsetX, /*Number, optional*/ offsetY){
|
||||
// summary:
|
||||
// Moves the mouse over the specified node at the specified relative x,y offset.
|
||||
//
|
||||
// description:
|
||||
// Moves the mouse over the specified node at the specified relative x,y offset.
|
||||
// If you do not specify an offset, mouseMove will default to move to the middle of the node.
|
||||
// Example: to move the mouse over a ComboBox's down arrow node, call doh.mouseMoveAt(dijit.byId('setvaluetest').downArrowNode);
|
||||
//
|
||||
// node:
|
||||
// The id of the node, or the node itself, to move the mouse to.
|
||||
// If you pass an id or a function that returns a node, the node will not be evaluated until the movement executes.
|
||||
// This is useful if you need to move the mouse to an node that is not yet present.
|
||||
//
|
||||
// delay:
|
||||
// Delay, in milliseconds, to wait before firing.
|
||||
// The delay is a delta with respect to the previous automation call.
|
||||
// For example, the following code ends after 600ms:
|
||||
// doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
|
||||
// doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
|
||||
//
|
||||
// duration:
|
||||
// Approximate time Robot will spend moving the mouse
|
||||
// The default is 100ms.
|
||||
//
|
||||
// offsetX:
|
||||
// x offset relative to the node, in pixels, to move the mouse. The default is half the node's width.
|
||||
//
|
||||
// offsetY:
|
||||
// y offset relative to the node, in pixels, to move the mouse. The default is half the node's height.
|
||||
//
|
||||
|
||||
doh.robot._assertRobot();
|
||||
duration = duration||100;
|
||||
this.sequence(function(){
|
||||
node=doh.robot._resolveNode(node);
|
||||
doh.robot._scrollIntoView(node);
|
||||
var pos = doh.robot._position(node);
|
||||
if(offsetY === undefined){
|
||||
offsetX=pos.w/2;
|
||||
offsetY=pos.h/2;
|
||||
}
|
||||
var x = pos.x+offsetX;
|
||||
var y = pos.y+offsetY;
|
||||
doh.robot._mouseMove(x, y, false, duration);
|
||||
}, delay, duration);
|
||||
}
|
||||
});
|
||||
});
|
||||
},_position:function(n){
|
||||
var d=dojo,p=null,M=Math.max,m=Math.min;
|
||||
d.forEach(doh.robot._getWindowChain(n),function(w){
|
||||
d.withGlobal(w,function(){
|
||||
var p2=d.position(n,false),b=d._getPadBorderExtents(n);
|
||||
if(!p){
|
||||
p=p2;
|
||||
}else{
|
||||
var _2;
|
||||
d.withGlobal(n.contentWindow,function(){
|
||||
_2=dojo.window.getBox();
|
||||
});
|
||||
p2.r=p2.x+_2.w;
|
||||
p2.b=p2.y+_2.h;
|
||||
p={x:M(p.x+p2.x,p2.x)+b.l,y:M(p.y+p2.y,p2.y)+b.t,r:m(p.x+p2.x+p.w,p2.r)+b.l,b:m(p.y+p2.y+p.h,p2.b)+b.t};
|
||||
p.w=p.r-p.x;
|
||||
p.h=p.b-p.y;
|
||||
}
|
||||
n=w.frameElement;
|
||||
});
|
||||
});
|
||||
return p;
|
||||
},_getWindowChain:function(n){
|
||||
var cW=dojo.window.get(n.ownerDocument);
|
||||
var _3=[cW];
|
||||
var f=cW.frameElement;
|
||||
return (cW==dojo.global||f==null)?_3:_3.concat(doh.robot._getWindowChain(f));
|
||||
},scrollIntoView:function(_4,_5){
|
||||
doh.robot.sequence(function(){
|
||||
doh.robot._scrollIntoView(doh.robot._resolveNode(_4));
|
||||
},_5);
|
||||
},mouseMoveAt:function(_6,_7,_8,_9,_a){
|
||||
doh.robot._assertRobot();
|
||||
_8=_8||100;
|
||||
this.sequence(function(){
|
||||
_6=doh.robot._resolveNode(_6);
|
||||
doh.robot._scrollIntoView(_6);
|
||||
var _b=doh.robot._position(_6);
|
||||
if(_a===undefined){
|
||||
_9=_b.w/2;
|
||||
_a=_b.h/2;
|
||||
}
|
||||
var x=_b.x+_9;
|
||||
var y=_b.y+_a;
|
||||
doh.robot._mouseMove(x,y,false,_8);
|
||||
},_7,_8);
|
||||
}});
|
||||
|
||||
})();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user