mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-21 12:07:57 +01:00
Add (considerably evil) dactylIUtils.getScrollable. Deal with some quirky sites without scrollable elements. Closes issue #525.
This commit is contained in:
@@ -8,9 +8,12 @@
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
[scriptable, uuid(29d1c61f-5959-42b3-8a13-4b473b2b47bf)]
|
[scriptable, uuid(d8ef4492-8f4a-4f5d-8f19-1d71f7f895ed)]
|
||||||
interface dactylIUtils : nsISupports
|
interface dactylIUtils : nsISupports
|
||||||
{
|
{
|
||||||
|
const PRUint32 DIRECTION_HORIZONTAL = 1 << 0;
|
||||||
|
const PRUint32 DIRECTION_VERTICAL = 1 << 1;
|
||||||
|
|
||||||
[implicit_jscontext]
|
[implicit_jscontext]
|
||||||
jsval createGlobal();
|
jsval createGlobal();
|
||||||
|
|
||||||
@@ -25,6 +28,8 @@ interface dactylIUtils : nsISupports
|
|||||||
[implicit_jscontext]
|
[implicit_jscontext]
|
||||||
jsval getGlobalForObject(in jsval object);
|
jsval getGlobalForObject(in jsval object);
|
||||||
|
|
||||||
|
PRUint32 getScrollable(in nsIDOMElement element);
|
||||||
|
|
||||||
void loadSubScript (in wstring url
|
void loadSubScript (in wstring url
|
||||||
/* [optional] in jsval context, */
|
/* [optional] in jsval context, */
|
||||||
/* [optional] in wstring charset */);
|
/* [optional] in wstring charset */);
|
||||||
|
|||||||
@@ -40,6 +40,23 @@
|
|||||||
#include "jsdbgapi.h"
|
#include "jsdbgapi.h"
|
||||||
#include "jsobj.h"
|
#include "jsobj.h"
|
||||||
|
|
||||||
|
#include "nsStringAPI.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evil. Evil, evil, evil.
|
||||||
|
*/
|
||||||
|
#define MOZILLA_INTERNAL_API
|
||||||
|
# define nsAString_h___
|
||||||
|
# define nsString_h___
|
||||||
|
# define nsStringFwd_h___
|
||||||
|
# define nsStringGlue_h__
|
||||||
|
class nsAFlatCString;
|
||||||
|
typedef nsString nsSubstring;
|
||||||
|
# include "nsIScrollableFrame.h"
|
||||||
|
#undef MOZILLA_INTERNAL_API
|
||||||
|
#include "nsPresContext.h"
|
||||||
|
#include "nsQueryFrame.h"
|
||||||
|
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "nsIDOMXULElement.h"
|
#include "nsIDOMXULElement.h"
|
||||||
#include "nsIXULTemplateBuilder.h"
|
#include "nsIXULTemplateBuilder.h"
|
||||||
@@ -49,7 +66,6 @@
|
|||||||
|
|
||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsStringAPI.h"
|
|
||||||
|
|
||||||
|
|
||||||
class autoDropPrincipals {
|
class autoDropPrincipals {
|
||||||
@@ -322,4 +338,32 @@ dactylUtils::GetGlobalForObject(const jsval &aObject,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
dactylUtils::GetScrollable(nsIDOMElement *aElement, PRUint32 *rval)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
|
||||||
|
|
||||||
|
nsIFrame *frame = content->GetPrimaryFrame();
|
||||||
|
nsIScrollableFrame *scrollFrame = do_QueryFrame(frame);
|
||||||
|
|
||||||
|
*rval = 0;
|
||||||
|
if (scrollFrame) {
|
||||||
|
nsPresContext::ScrollbarStyles ss = scrollFrame->GetScrollbarStyles();
|
||||||
|
PRUint32 scrollbarVisibility = scrollFrame->GetScrollbarVisibility();
|
||||||
|
nsRect scrollRange = scrollFrame->GetScrollRange();
|
||||||
|
|
||||||
|
if (ss.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN &&
|
||||||
|
((scrollbarVisibility & nsIScrollableFrame::HORIZONTAL) ||
|
||||||
|
scrollRange.width > 0))
|
||||||
|
*rval |= dactylIUtils::DIRECTION_HORIZONTAL;
|
||||||
|
|
||||||
|
if (ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN &&
|
||||||
|
((scrollbarVisibility & nsIScrollableFrame::VERTICAL) ||
|
||||||
|
scrollRange.height > 0))
|
||||||
|
*rval |= dactylIUtils::DIRECTION_VERTICAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* vim:se sts=4 sw=4 et ft=cpp: */
|
/* vim:se sts=4 sw=4 et ft=cpp: */
|
||||||
|
|||||||
@@ -784,9 +784,29 @@ var Buffer = Module("buffer", {
|
|||||||
function find(elem) {
|
function find(elem) {
|
||||||
while (elem && !(elem instanceof Element) && elem.parentNode)
|
while (elem && !(elem instanceof Element) && elem.parentNode)
|
||||||
elem = elem.parentNode;
|
elem = elem.parentNode;
|
||||||
for (; elem && elem.parentNode instanceof Element; elem = elem.parentNode)
|
for (; elem instanceof Element; elem = elem.parentNode)
|
||||||
if (Buffer.isScrollable(elem, dir, horizontal))
|
if (Buffer.isScrollable(elem, dir, horizontal))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (!(elem instanceof Element))
|
||||||
|
return {
|
||||||
|
__proto__: elem.documentElement || elem.ownerDocument.documentElement,
|
||||||
|
|
||||||
|
win: elem.defaultView || elem.ownerDocument.defaultView,
|
||||||
|
|
||||||
|
get clientWidth() this.win.innerWidth,
|
||||||
|
get clientHeight() this.win.innerHeight,
|
||||||
|
|
||||||
|
get scrollWidth() this.win.scrollMaxX + this.win.innerWidth,
|
||||||
|
get scrollHeight() this.win.scrollMaxY + this.win.innerHeight,
|
||||||
|
|
||||||
|
get scrollLeft() this.win.scrollX,
|
||||||
|
set scrollLeft(val) { this.win.scrollTo(val, this.win.scrollY) },
|
||||||
|
|
||||||
|
get scrollTop() this.win.scrollY,
|
||||||
|
set scrollTop(val) { this.win.scrollTo(this.win.scrollX, val) }
|
||||||
|
};
|
||||||
|
|
||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1263,6 +1283,9 @@ var Buffer = Module("buffer", {
|
|||||||
findScrollable: deprecated("buffer.findScrollable", function findScrollable() buffer.findScrollable.apply(buffer, arguments)),
|
findScrollable: deprecated("buffer.findScrollable", function findScrollable() buffer.findScrollable.apply(buffer, arguments)),
|
||||||
|
|
||||||
isScrollable: function isScrollable(elem, dir, horizontal) {
|
isScrollable: function isScrollable(elem, dir, horizontal) {
|
||||||
|
if (!DOM(elem).isScrollable(horizontal ? "horizontal" : "vertical"))
|
||||||
|
return false;
|
||||||
|
|
||||||
let pos = "scrollTop", size = "clientHeight", max = "scrollHeight", layoutSize = "offsetHeight",
|
let pos = "scrollTop", size = "clientHeight", max = "scrollHeight", layoutSize = "offsetHeight",
|
||||||
overflow = "overflowX", border1 = "borderTopWidth", border2 = "borderBottomWidth";
|
overflow = "overflowX", border1 = "borderTopWidth", border2 = "borderBottomWidth";
|
||||||
if (horizontal)
|
if (horizontal)
|
||||||
@@ -1272,9 +1295,11 @@ var Buffer = Module("buffer", {
|
|||||||
let style = DOM(elem).style;
|
let style = DOM(elem).style;
|
||||||
let borderSize = Math.round(parseFloat(style[border1]) + parseFloat(style[border2]));
|
let borderSize = Math.round(parseFloat(style[border1]) + parseFloat(style[border2]));
|
||||||
let realSize = elem[size];
|
let realSize = elem[size];
|
||||||
|
|
||||||
// Stupid Gecko eccentricities. May fail for quirks mode documents.
|
// Stupid Gecko eccentricities. May fail for quirks mode documents.
|
||||||
if (elem[size] + borderSize == elem[max] || elem[size] == 0) // Stupid, fallible heuristic.
|
if (elem[size] + borderSize == elem[max] || elem[size] == 0) // Stupid, fallible heuristic.
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (style[overflow] == "hidden")
|
if (style[overflow] == "hidden")
|
||||||
realSize += borderSize;
|
realSize += borderSize;
|
||||||
return dir < 0 && elem[pos] > 0 || dir > 0 && elem[pos] + realSize < elem[max] || !dir && realSize < elem[max];
|
return dir < 0 && elem[pos] > 0 || dir > 0 && elem[pos] + realSize < elem[max] || !dir && realSize < elem[max];
|
||||||
|
|||||||
@@ -691,6 +691,9 @@ var DOM = Class("DOM", {
|
|||||||
createContents: function createContents()
|
createContents: function createContents()
|
||||||
this.each(DOM.createContents, this),
|
this.each(DOM.createContents, this),
|
||||||
|
|
||||||
|
isScrollable: function isScrollable(direction)
|
||||||
|
this.length && DOM.isScrollable(this[0], direction),
|
||||||
|
|
||||||
getSet: function getSet(args, get, set) {
|
getSet: function getSet(args, get, set) {
|
||||||
if (!args.length)
|
if (!args.length)
|
||||||
return this[0] && get.call(this, this[0]);
|
return this[0] && get.call(this, this[0]);
|
||||||
@@ -1246,6 +1249,10 @@ var DOM = Class("DOM", {
|
|||||||
createContents: Class.Memoize(function () services.has("dactyl") && services.dactyl.createContents
|
createContents: Class.Memoize(function () services.has("dactyl") && services.dactyl.createContents
|
||||||
|| function (elem) {}),
|
|| function (elem) {}),
|
||||||
|
|
||||||
|
isScrollable: Class.Memoize(function () services.has("dactyl") && services.dactyl.getScrollable
|
||||||
|
? function (elem, dir) services.dactyl.getScrollable(elem) & (dir ? services.dactyl["DIRECTION_" + dir.toUpperCase()] : ~0)
|
||||||
|
: function (elem, dir) true),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The set of input element type attribute values that mark the element as
|
* The set of input element type attribute values that mark the element as
|
||||||
* an editable field.
|
* an editable field.
|
||||||
|
|||||||
Reference in New Issue
Block a user