1 // keep the global scope clean
6 var continueBtn
= null;
8 var getElementPosY = function(obj
) {
10 while (obj
.offsetParent
) {
12 obj
= obj
.offsetParent
;
17 // ugh, find scroll position in 3 possible ways
18 var getScrollY = function() {
19 return self
.pageYOffset
|| document
.body
.scrollTop
|| document
.documentElement
.scrollTop
;
22 var initScroll = function(obj
) {
23 // if we scroll to the warning div itself the sql that caused the warning will be off the top of the page
24 // so we can look through the page for a preceeding div and base the scroll position on that
25 var prevDiv
= findPreviousSibling(obj
, 'div');
26 // if the warning div doesn't have a previous sibling div scroll to the top of the page instead
27 var y
= (prevDiv
) ? getElementPosY(prevDiv
) + prevDiv
.offsetHeight
: 0;
33 // scroll with a little bit of easing, I guess it's a matter of personal taste whether it would be
34 // better to scroll the page directly to the point using window.scrollTo(0, y). But I think easing
35 // makes it a little clearer to the user that they're scrolling through the page :-)
36 id
= setInterval(function() {
37 var ys
= getScrollY();
38 // the stuff on arguments.callee is a check to stop scrolling if we've reached the end of the page
39 // and can't scroll any further
40 if ((arguments
.callee
.oldPos
&& arguments
.callee
.oldPos
== ys
) || Math
.abs(y
- ys
) < 5) {
41 arguments
.callee
.oldPos
= null;
42 window
.scrollTo(0, y
);
46 window
.scrollTo(0, Math
.round(ys
+ ((y
- ys
) / 2)));
48 arguments
.callee
.oldPos
= ys
;
52 // return nodes with a class name that matches regexp - if individual is set we're only looking
54 var filterNodesByClassName = function(nodes
, regexp
, individual
) {
57 for (var i
= 0; i
< n
; ++i
) {
58 if (nodes
[i
].className
&& nodes
[i
].className
.match(regexp
)) {
62 filtered
.push(nodes
[i
]);
68 // look through the previous siblings of an element and find the first one with a given node name
69 var findPreviousSibling = function(obj
, nodeName
) {
70 while (obj
= obj
.previousSibling
) {
71 if (obj
.nodeName
.toLowerCase() == nodeName
) {
78 // create the links to scroll around the page. warningIndex is used to look up the element in the
79 // warnings array that should be scrolled to
80 var createWarningSkipLink = function(linkText
, warningIndex
, style
) {
81 var link
= document
.createElement('a');
82 link
.href
= 'javascript:;';
83 link
.warningIndex
= warningIndex
;
84 link
.appendChild(document
.createTextNode(linkText
));
85 link
.onclick = function() {
86 initScroll(warnings
[this.warningIndex
]);
90 for (var x
in style
) {
91 link
.style
[x
] = style
[x
];
98 var checkWarnings = function() {
99 // look for div tags with the class name notifyproblem
100 warnings
= filterNodesByClassName(document
.getElementsByTagName('div'), /(^|\b)notifyproblem(\b|$)/);
101 // and find the continue button
102 continueBtn
= filterNodesByClassName(document
.getElementsByTagName('div'), /(^|\b)continuebutton(\b|$)/, true);
104 var n
= warnings
.length
; // find how many warnings
105 warnings
[warnings
.length
] = continueBtn
; // then add the continue button to the array
108 var statusOk
= false;
109 for (var i
= 0; i
< n
; ++i
) {
110 // add a "next" link to all warnings except the last one on the page
112 link
= createWarningSkipLink('Scroll to next warning', i
+ 1, {paddingLeft
: '1em'});
114 // on the last link add a link to go to the continue button
115 link
= createWarningSkipLink('Scroll to continue button', i
+ 1, {paddingLeft
: '1em'});
117 warnings
[i
].appendChild(link
);
118 // and add a "previous" link to all except the first
120 link
= createWarningSkipLink('Scroll to previous warning', i
- 1, {paddingRight
: '1em'});
121 warnings
[i
].insertBefore(link
, warnings
[i
].firstChild
);
126 var contentDiv
= document
.getElementById('content');
128 // create a message to display at the top of the page, with a link to the first warning
129 // or to the continue button if there were no warnings on the page
130 var p
= document
.createElement('p');
132 var warningText
= (n
== 1) ? 'warning' : 'warnings';
133 link
= createWarningSkipLink('Scroll to the first warning', 0);
134 p
.appendChild(document
.createTextNode('This script generated ' + n
+ ' ' + warningText
+ ' - '));
135 p
.className
= 'notifyproblem';
137 link
= createWarningSkipLink('Scroll to the continue button', 0);
138 p
.appendChild(document
.createTextNode('No warnings - '));
139 p
.className
= 'notifysuccess';
143 contentDiv
.insertBefore(p
, contentDiv
.firstChild
);
146 // automatically scroll to the first warning or continue button
147 initScroll(warnings
[0]);
148 if (statusOk
&& installautopilot
) {//global JS variable
149 document
.forms
[0].submit();//auto submit
153 // load should be a document event, but most browsers use window
154 if (window
.addEventListener
) {
155 window
.addEventListener('load', checkWarnings
, false);
156 } else if (document
.addEventListener
) {
157 document
.addEventListener('load', checkWarnings
, false);
158 } else if (window
.attachEvent
) {
159 // sometimes IE doesn't report scrollTop correctly (it might be a quirk of this specific page, I don't know)
160 // but using scrollTo once to begin makes sure things work
161 window
.scrollTo(0, 1);
162 window
.attachEvent('onload', checkWarnings
);