< Day Day Up > |
Learn the subtle art of Greasemonkey debugging. The actual process of writing user scripts can be frustrating if you don't know how to debug them properly. Since JavaScript is an interpreted language, errors that would otherwise cause a compilation error (such as misspelled variables or function names) can only be caught when they occur at runtime. Furthermore, if something goes wrong, it's not immediately obvious how to figure out what happened, much less how to fix it. 1.11.1. Check Error MessagesIf your user script doesn't appear to be running properly, the first place to check is JavaScript Console, which lists all script-related errors, including those specific to user scripts. Select Tools JavaScript Console to open the JavaScript Console window. You will probably see a long list of all the script errors on all the pages youve visited since you opened Firefox. (You'd be surprised how many high-profile sites have scripts that crash regularly.) In the JavaScript Console window, click Clear to remove the old errors from the list. Now, refresh the page you're using to test your user script. If your user script is crashing or otherwise misbehaving, you will see the exception displayed in JavaScript Console.
If you don't see any errors printed in JavaScript Console, you might have a configuration problem. Go to Tools Manage User Scripts and double-check that your script is installed and enabled and that your current test page is listed in the Included Pages list. 1.11.2. Log ErrorsOK, so your script is definitely running, but it isn't working properly. What next? You can litter your script with alert calls, but that's annoying. Instead, Greasemonkey provides a logging function, GM_log, that allows you to write messages to JavaScript Console. Such messages should be taken out before release, but they are enormously helpful in debugging. Plus, watching the console pile up with log messages is much more satisfying than clicking OK over and over to dismiss multiple alerts. GM_log takes one argument, the string to be logged. After logging to JavaScript Console, the user script will continue executing normally. Save the following user script as testlog.user.js: // ==UserScript== // @name TestLog // @namespace http://example.com/ // ==/UserScript== if (/^http:\/\/www\.oreilly\.com\//.test(location.href)) { GM_log("running on O'Reilly site"); } else { GM_log('running elsewhere'); } GM_log('this line is always printed'); If you install this user script and visit http://www.oreilly.com, these two lines will appear in JavaScript Console: Greasemonkey: http://example.com//TestLog: running on O'Reilly site Greasemonkey: http://example.com//TestLog: this line is always printed Greasemonkey dumps the namespace and script name, taken from the user script's metadata section, then the message that was passed as an argument to GM_log. If you visit somewhere other than http://www.oreilly.com, these two lines will appear in JavaScript Console: Greasemonkey: http://example.com//TestLog: running elsewhere Greasemonkey: http://example.com//TestLog: this line is always printed Messages logged in Javascript Console are not limited to 255 characters. Plus, lines in JavaScript Console wrap properly, so you can always scroll down to see the rest of your log message. Go nuts with logging!
1.11.3. Find Page ElementsDOM Inspector allows you to explore the parsed Document Object Model (DOM) of any page. You can get details on each HTML element, attribute, and text node. You can see all the CSS rules from each page's stylesheets. You can explore all the scriptable properties of an object. It's extremely powerful. DOM Inspector is included with the Firefox installation program, but depending on your platform, it might not installed by default. If you don't see a DOM Inspector item in the Tools menu, you will need to reinstall Firefox and choose Custom Install, then select Developer Tools. (Don't worry; this will not affect your existing bookmarks, preferences, extensions, or user scripts.) A nice addition to DOM Inspector is the Inspect Element extension. It allows you to right-click on any element a link, a paragraph, even the page itself and open DOM Inspector with that element selected. From there, you can inspect its properties, or see exactly where it fits within the hierarchy of other elements on the page.
One last note: DOM Inspector does not follow you as you browse. If you open DOM Inspector and then navigate somewhere else in the original window, DOM Inspector will get confused. It's best to go where you want to go, inspect what you want to inspect, then close DOM Inspector before doing anything else. 1.11.4. Test JavaScript Code InteractivelyJavaScript Shell is a bookmarklet that allows you to evaluate arbitrary JavaScript expressions in the context of the current page. You install it simply by dragging it to your links toolbar. Then you can visit a web page you want to work on, and click the JavaScript Shell bookmarklet in your toolbar. The JavaScript Shell window will open in the background.
JavaScript Shell offers you the same power as DOM Inspector but in a free-form environment. Think of it as a command line for the DOM. You can enter any JavaScript expressions or commands, and you will see the output immediately. You can even make changes to the page, such as creating a new element document.createElement and adding to the page with document.body.appendChild. Your changes are reflected in the original page. One feature of JavaScript Shell that is worth special mention is the props function. Visit http://www.oreilly.com, open JavaScript Shell, and then type the following two lines: var link = document.getElementsByTagName('a')[0] props(link) JavaScript Shell spews out a long list of properties: Methods of prototype: blur, focus Fields of prototype: id, title, lang, dir, className, accessKey, charset, coords, href, hreflang, name, rel, rev, shape, tabIndex target, type, protocol, host, hostname, pathname, search, port, hash, text, offsetTop, offsetLeft, offsetWidth, offsetHeight, offsetParent, innerHTML, scrollTop, scrollLeft, scrollHeight, scrollWidth, clientHeight, clientWidth, style Methods of prototype of prototype of prototype: insertBefore, replaceChild, removeChild, appendChild, hasChildNodes, cloneNode, normalize, isSupported, hasAttributes, getAttribute, setAttribute, removeAttribute, getAttributeNode, setAttributeNode, removeAttributeNode, getElementsByTagName, getAttributeNS, setAttributeNS, removeAttributeNS, getAttributeNodeNS, setAttributeNodeNS, getElementsByTagNameNS, hasAttribute, hasAttributeNS, addEventListener, removeEventListener, dispatchEvent, compareDocumentPosition, isSameNode, lookupPrefix, isDefaultNamespace, lookupNamespaceURI, isEqualNode, getFeature, setUserData, getUserData Fields of prototype of prototype of prototype: tagName, nodeName, nodeValue, nodeType, parentNode, childNodes, firstChild, lastChild, previousSibling, nextSibling, attributes, ownerDocument, namespaceURI, prefix, localName, ELEMENT_NODE, ATTRIBUTE_NODE, TEXT_NODE, CDATA_SECTION_NODE, ENTITY_REFERENCE_NODE, ENTITY_NODE, PROCESSING_INSTRUCTION_NODE, COMMENT_NODE, DOCUMENT_NODE, DOCUMENT_TYPE_NODE, DOCUMENT_FRAGMENT_NODE, NOTATION_NODE, baseURI, textContent, DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_PRECEDING, DOCUMENT_POSITION_FOLLOWING, DOCUMENT_POSITION_CONTAINS, DOCUMENT_POSITION_CONTAINED_BY, DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC Methods of prototype of prototype of prototype of prototype of prototype: toString What's this all about? It's a list of all the properties and methods of that <a> element that are available to you in JavaScript, grouped by levels in the DOM object hierarchy. Methods and properties that are specific to link elements (such as the blur and focus methods, and the href and hreflang properties) are listed first, followed by methods and properties shared by all types of nodes (such as the insertBefore method). Again, this is the same information that is available in DOM Inspector but with more typing and experimenting, and less pointing and clicking.
|
< Day Day Up > |