Note: Opera Dragonfly also features a Console, which is fully integrated with the debugger.
Any linked, inline and evaled scripts can be selected from the document selector in the Scripts toolbar. These are organized under their parent runtime. If there are multiple documents, such as iframes or linked SVG files, the scripts will be listed under the document in which they are defined. Injected scripts such as Browser.js and User.js are also listed under their respective headings. The list of scripts can be filtered to only show scripts whose filename or path matches a particular string.
If Opera Dragonfly is opened after the page was loaded it will have to be reloaded, either using the browser reload button or the reload button in the center of the Source panel for the scripts to be shown, as for performance reasons debugging information is not collected when Opera Dragonfly is inactive.
Once a script is selected, the syntax highlighted source is shown in the main panel. From this panel, breakpoints can be set to control the flow of the program by clicking on the line number in the gutter. Breakpoints are covered in more detail in the
Breakpoints section below.
injected checkbox will avoid searching in those scripts.
Source section of the
Scripts tab in the settings.
Pressing Ctrl+G (⌘+L) when the Source panel is active will open the Go to line window. Entering a number will scroll to the specified line. It will temporarily highlight to show which is the correct line.
Breakpoints define where the execution of the program halts. When a breakpoint is reached Opera Dragonfly switches to break mode. When you add breakpoints, you can then manage them using the Breakpoints sub-panel.
Opera Dragonfly supports a number of different kinds of breakpoints:
Line breakpoints break the execution when the specified line is reached. A line breakpoint can be set by clicking the line number in the left-hand gutter of the source view.
The breakpoint will show in the Breakpoints sub-panel, identified by the debugging context, the line number, and a snippet of code from that line.
An event breakpoint pauses execution when the specified type of event is fired. An event breakpoint can be set by checking the box next to the event name in the Breakpoints sub-panel. The events are organized under expandable headings corresponding to the event type. When an event is checked, the relevant event breakpoint will appear in the Breakpoints sub-panel, identified by the event name.
Custom Events heading and clicking the
A conditional breakpoint has an expression attached to it that is evaluated when the breakpoint is reached. If the evaluation returns true, the execution breaks; otherwise, it continues.
A regular line or event breakpoint can be changed to a conditional breakpoint by selecting
Add condition from the context menu of the appropriate breakpoint in the Breakpoints sub-panel, and entering a valid expression in the
condition field. The expression must return a boolean value. The breakpoint symbol in the source view gutter will change to indicate it has a condition attached.
For line breakpoints, it is also possible to right click on the breakpoint in the source view gutter and select
To remove a condition, delete the text inside the condition field and press Enter.
Examples of conditions include testing if: a variable equals a specific value (
foo == 10), a variable is greater than another variable (
foo > bar), a function returns
foo.bar(baz) === true), or, when an event breakpoint fires, if it is a specific element (
event.target.id == "foo").
Break on first statement of a new script pauses the execution each time a new script is loaded and the first statement is evaluated. This can be enabled in the Scripts toolbar.
An individual breakpoint can be disabled by unchecking the checkbox next to the name of the breakpoint in the Breakpoints sub-panel. The icon in the gutter will change to show it is disabled.
It is often useful to disable all breakpoints when debugging to see how the application runs normally without losing all the breakpoints. This can be achieved by clicking the
Disable all breakpoints button in the Breakpoints toolbar or by selecting
Disable all from the context menu inside the breakpoints list.
If a breakpoint is not needed anymore it can be deleted by selecting
Delete in the context menu of the breakpoint to be deleted in the breakpoint list. For line breakpoints, it is also possible to click on the breakpoint symbol in the gutter.
Deleting all breakpoints can be achieved in a similar way: by pressing the
Delete all breakpoints button, or selecting the
Delete all context menu item.
The program flow is controlled by setting breakpoints. Once the program hits a breakpoint, the execution will halt and will switch to the paused state. A paused execution indicator will be shown on the Scripts application toolbar button to indicate the program is currently at a break point. When Opera Dragonfly is in this state, the call stack and the variable object for the currently selected execution context are shown in the State sub-panel.
The breakpoint will be hit when the code it is defined on is evaluated, and any condition evaluates to true. For example, if a breakpoint is set on the first line of a function for handling what happens when a button is pressed, pressing that button will likely hit that breakpoint and pause execution. The document will have to be reloaded if the breakpoint is set on code that is only evaluated once when loading the page, and it has already been evaluated when the breakpoint is set.
Once a breakpoint is hit, it is possible to continue execution in a number of ways, using the buttons in the Scripts toolbar:
There are various ways to see and monitor variables and their state in Opera Dragonfly. When in the paused state, a full list of the properties in scope can be found in the Inspection section of the State sub-panel. Properties of interest can be watched in the Watches section of the State sub-panel.
When at a breakpoint, it is possible to inspect the variables, objects, and functions in the currently selected execution context. These can be found under the Inspection section of the State sub-panel. The currently active execution context is selected in the Call Stack section. It is possible to step back in the call stack to access previously active execution contexts.
All variables in scope for the execution context are listed along with their current value. Functions and objects can be further examined by clicking the expander icon next to its name. This will show all the properties and functions contained within.
As the number of properties can start to get unwieldy, it is possible to hide variables which have a default value of null or an empty string by deactivating the relevant button on the Inspection toolbar. It is also possible to hide non-enumerable properties.
It is also possible to filter by a search term using the Filter field in the toolbar. This will only match properties that are currently visible.
In addition to the State sub-panel, dynamic inspection tooltips offer the ability to observe values of properties, variables, objects and expressions.
Hovering over an object in the Script panel source view will open a filterable tooltip.
Pressing shift while hovering over a function invocation will also evaluate the function and show its return value in the tooltip. For example, pressing Shift while hovering over a call to
document.getElementsByClassName('frame') returns the
Selecting any amount of code and pressing Shift will evaluate it and display the result in the tooltip. This also works across multiple lines.
Object we show the according Class. If you now hover over the Class name of any
Exception, you will get a tooltip with a pretty-printed representation. This even works on top of another tooltip.
Watches section in the State sub-panel.
Examples of watches include individual variables or objects (
foo), the return value of a function (
foo.bar()), or manipulating variables (
bar + baz * superman). If the variables or functions are in scope the result will be returned.
It is also possible to add a watch from the context menu on variables in the Inspection section of the State sub-panel.
An existing watch can be edited by double clicking on the expression or selecting
Edit from the context menu.
A watch can be deleted by selecting
Delete from the context menu of the watch.
When debugging a program, it is often useful to know the value that was returned from the last function call. If the value is assigned to a variable, this can be done easily from the
Watches section. There are situations, though, where return values are not explicitly assigned, particularly if they formed part of a more complex expression.
As an example, let's take the following trivial function call:
mul(add(1, 2), add(3, 4));
If we set a breakpoint in our script at this point, and then "Step over" this call, we can see that the
Return values section lists all function calls and their respective return values, in the order in which they were executed (with the oldest call at the bottom, and the most recent call at the top). Clicking on the arrow next to the function name will jump to that particular function's definition, while the arrow next to the return value jumps directly to the
return statement inside the function.
When a function is called it is pushed onto the top of the call stack, and when it returns it is popped off the stack. The call stack contains a frame for each function that has not yet returned, with global scope at the base. The frames on the stack are listed in the Call Stack section of the State sub-panel.
Clicking on an entry in the stack will switch to that frame. From there it is possible to see all the variables in scope for that frame in the Inspection section, as described above. The source view will also switch to the function that the frame represents. The execution position will be at the line that contains the function call that created the frame above on the call stack.