I am writing a simple Greasemonkey script for Java SE API reference doc [http://docs.oracle.com/javase/8/docs/api/ ]. It goes as:
// ==UserScript==
// @id Test
// @grant none
// @include http://docs.oracle.com/javase/8/docs/api/*
// @version 1
// @run-at docuitment-end
// ==UserScript==
var classNamesFrame = null;
var classNamesDoc = null;
var classNamesATags = null;
var classNames = null;
function printClassNames()
{
classNamesATags = classNamesDoc.getElementsByTagName('a');
classNames = new Array();
var i;
for (i = 0; i < classNamesATags.length; i++) {
classNames.push(classNamesATags[i].textContent);
}
console.log(classNames);
console.log(classNamesDoc.URL);
console.log('Total number of classes: ' + classNamesATags.length);
alert("printClassNames called");
}
classNamesFrame = document.getElementsByName('packageFrame') [0];
classNamesDoc = classNamesFrame.contentDocument;
classNamesFrame.onload = printClassNames;
//classNamesFrame.addEventListener("DOMContentLoaded", printClassNames, false);
Function printClassNames() prints names of all classes it finds in the frame where all classes are listed. I should do so when the frame has finished loading. But the onload even is called before HTML document for the frame is loaded.
I have tried using DOMContentLoaded event but it is not even called.
What can I do so that printClassNames is called after the frame has finished loading completely?
That script has a variety of errors (list below), but the main one is that it's grabbing the wrong
contentDocument.This is because Firefox returns
<about:blank>for frame contents until it is replaced by the actual page contents. TheclassNamesDocvariable remains pointed at the blank value. (Note that Chrome handles frames slightly differently and updatesclassNamesDocfor you.)So, move
classNamesDoc = classNamesFrame.contentDocument;to insideprintClassNames()and the most obvious problem is solved.Other problems, "worstest firstest":
Badly malformed metadata block. Incorrect
// ==/UserScript==line. This causes the script to run (and crash) for every page and (i)frame you browse!Script silently crashes (on Firefox, Chrome reports these errors) for every page/frame but one small subset. You need to check the value of
classNamesFramebefore using it.For example, on the
docs.oracle.com/javase/8/docs/api/pages, this script is running 4 times and silently crashing on three of those.Missing
@namedirective. This can cause scoping, updating, and maintenance problems -- as well as hamper uploading and sharing the script.Syntax error. It should be:
@run-at document-end, except that you probably do not need this directive at all, in this case.Putting it all together, your script would be:
-- which works on Both Firefox and Chrome (and probably others).