Web Inspector is an open source web development tool built into Safari that makes it easy to prototype, optimize, and debug your web content on iOS and OS X.

Note: As a web developer, you are encouraged to live on the bleeding edge. Download the latest WebKit Nightly, the developmental branch of Safari. It contains experimental, developer-facing features, so you can try out new WebKit functionality before it reaches wider audiences.

Get Oriented

Before you start using Web Inspector, familiarize yourself with its organization and interface.

Enabling Web Inspector

To start using Web Inspector, you must first enable the Develop menu. To do so, enable the “Show Develop menu in menu bar” setting found in Safari’s preferences under the Advanced pane, as shown in Figure 1-1.

Figure 1-1 The Advanced pane of Safari’s preferences

You can then access Web Inspector through the Develop menu that appears in the menubar, or by pressing Command-Option-I. You can also add the Web Inspector toolbar item to Safari’s toolbar by selecting View > Customize Toolbar.

Figure 1-2 The Web Inspector toolbar item

WebKit-based Apps

To enable the developer tools in a WebKit-based application other than Safari, enter the following into the Terminal:

defaults write com.bundle.identifier WebKitDeveloperExtras -bool true

Replace com.bundle.identifier with the bundle identifier of your app, and then launch your app. Web Inspector can now be accessed by a Control-click or right-click from within any web view. You must also enable contextual menus in your app.

Safari on iOS

You can use Web Inspector to debug web content on your device directly from your desktop.

Note: Web Inspector is available on iOS 6 and later.

To enable Web Inspector on iOS

Open the Settings app.

Tap Safari.

Scroll down and select Advanced.

Switch Web Inspector to ON.

After Web Inspector is enabled, connect your device to your desktop machine with a USB cable. The name of your device appears in the Develop menu of Safari alongside all open inspectable apps and webpages.

Alternately, you can use iOS Simulator to take advantage of Web Inspector’s debugging capabilities, which comes free with Xcode from the Mac App Store. Use the same instructions,“To enable Web Inspector on iOS,” from within the iOS Simulator’s Settings app.

If you have a development provisioning profile installed on your device, you can even inspect the web content of any UIWebViewobject in your app. The name of your app will appear as a submenu under the name of your device. When debugging web content in a web view, Web Inspector behaves in the same manner as debugging web content in Safari.

Navigating Web Inspector

The toolbar icons listed in Table 1-1 are in order as they appear in Web Inspector, from left to right.

Positioning Web Inspector

There are three positions that Web Inspector can take: docked to the bottom of the window, docked to the right of the window, or in its own window. When inspecting web content on OS X, Web Inspector is docked to the bottom of the window by default. You can detach Web Inspector into its own window by pressing the detach button (). This mode is especially advantageous when working on a computer with multiple displays.

Note: When inspecting web content on iOS, Web Inspector must be in its own window.

When in its own window, Web Inspector presents another button allowing you to dock Web Inspector to the right of the window. This is particularly useful for inspecting narrow web content on wide monitors. Press the Dock to Right button () to dock Web Inspector to the right side of the window.

Hold down the Option key to switch docking types.

Changing Toolbar Appearance

You can change the look and feel of the toolbar to better suit your liking. Depending on the size of your screen, you might want to adjust your toolbar to take up less space. Right-clicking anywhere on the toolbar invokes a contextual menu which allows you to change the layout and size of the toolbar icons.

Possible toolbar appearances are shown in Table 1-2. By default, toolbar icons are presented with icons and text positioned vertically.

Table 1-2 Toolbar variants

Para

Appearance

Icon and Text (Vertical)

Icon and Text (Horizontal)

Icon only

Text only

You also have the option to make the icons smaller by selecting Small Icons from the contextual menu.

Reading the Activity Viewer

The activity viewer is like a heads-up display for the loaded page. It shows an at-a-glance summary of key information about the current page, as shown in Figure 1-3. Each label in the activity viewer is a button that, when clicked, takes you to an area of Web Inspector.

Note: You need to load the webpage with Web Inspector open for values to appear in the activity viewer.

Inspect the DOM and Resources

At the heart of Web Inspector is the ability to inspect the Document Object Model (DOM). Web Inspector shows you the structure of your DOM as perceived by Safari’s rendering engine, WebKit. But the DOM isn’t all you can inspect. External resources and locally stored data—such as scripts, stylesheets, and offline storage—can be inspected, providing insight to the data available to your web content.

Resources and the DOM

The Document Object Model (DOM) is the API between your JavaScript and HTML. Each HTML element is rendered as a node in the DOM tree.

Inspecting the DOM

At the heart of Web Inspector is the ability to inspect, or locate within the DOM tree, a specific element on the page. After the specific element is selected in the DOM tree, details about the element become available, such as the element’s styles and event listeners.

Click the Inspect button, and start moving your mouse along the page. Notice that the elements you hover over becomes highlighted in a set of colors, and a tooltip appears, indicating the element’s tag and total dimensions. The colors that appear upon hover represent the element’s margin, border, padding, and dimensions, as illustrated in Figure 2-1.

Figure 2-1 Spacing properties are color-coded

With the Inspect button selected, click on this sentence. You can also right-click on this sentence and select Inspect Element in the contextual menu. Notice that the corresponding node becomes selected in the content browser.

Source versus DOM

The notions between a page’s source and a page’s DOM are similar, but different. The source is the raw HTML that is unadulterated by any client-side scripts. It is the direct response of the HTTP request to the server. The DOM, on the other hand, is the same HTML structure that has been modified by JavaScript.

Source Code reads the page’s HTML as if you opened it in a text editor. The source code reflects your HTML structure before any JavaScript is loaded. While the contents can’t be edited, it’s useful to see the HTML Safari receives from the server.

Figure 2-2 Viewing the source code

The DOM tree is fully editable. Of course, your edits are temporary, so any changes you make are lost in a browser refresh. To save changes you make to the DOM tree, select the root html node and press Command-C, which copies the DOM structure to you clipboard as HTML.

Figure 2-3 Viewing the DOM tree

You can switch between the page’s DOM tree and source code in the Navigation bar.

The Shadow DOM

WebKit automatically inserts HTML in certain elements. For example, the placeholder of text inputs is actually another HTML element that is hidden within the input itself. These hidden elements are known as the Shadow DOM. You can enable viewing shadow nodes in the content browser by clicking on the Shadow DOM button ().

Editing Nodes

To edit the markup of an element, double-click an element name, attribute name, or attribute value. Alternately, you can press the Enter key to input a new attribute. You can also use the Tab key and Shift-Tab key combination to cycle through attributes.

For example, inspect this paragraph and press the Enter key. You’ll see a text field appear within the highlighted node. Type inclass="notebox" and press Enter. A blue border appears surrounding the paragraph. That’s because the notebox class is already defined in the stylesheets included in this page. Deleting the class attribute or its value restores it to its original appearance.

Rearrange nodes with a simple drag and drop. Delete nodes by pressing the delete key. Try editing a couple nodes on this page—inspect this paragraph, then drag it above or below other nodes in the DOM tree. You’ll see the order of paragraphs change in the page to reflect the changed order in the DOM tree. All of your changes are local and won’t persist across pageloads. If you want to undo a change without losing other modifications you’ve made to the DOM, go to Edit > Undo (Command-Z) to undo your change.

Style

The Style details sidebar shows all of the CSS styles that pertain to the selected element. It also contains a series of checkboxes representing the element’s active, focus, hover, and visited pseudo-state. You can select these checkboxes to enable the pseudo-state without interacting with the element directly. For example, selecting the Hover checkbox will change the appearance of the element as if the mouse cursor is hovering over it.

Computed

The computed styles show all CSS styles associated with the selected element. It shows properties set to this specific element, as well as properties inherited from other selectors.

Figure 2-4 The Computed tab in the Style details sidebar

The styles displayed in the Computed tab are read-only. To edit an element’s styles, go to the “Rules” tab.

Next to every color in the Style sidebar is a color swatch. Clicking on the square swatch cycles through different formats of expressing that color. You can cycle through Hex, RGB, RGBA, HSL, HSLA, and named color values, depending on the color in context—for example, colors without alpha channels won’t cycle through RGBA or HSLA; colors that don’t represent an exact named color won’t cycle through the named color.

To see every CSS property, click on the Show All checkbox. This shows properties and their default values.

Rules

The Rules tab lists CSS rules that pertain to the selected element. The rules are collected from inline styles, attached stylesheets, and User Agent stylesheets. User Agent stylesheets are styles that Safari itself applies, such as a default margin.

Here, you can edit your styles as you would in a text editor. As you begin typing, notice that CSS properties auto-complete. As soon as your rule is valid, the style is automatically applied to the page. You can uncheck the checkbox that appears next to rules on hover to disable them, or press the Delete key to remove them entirely.

Figure 2-5 The Rules tab in the Style details sidebar

Inspect this paragraph, then click on New Rule. Web Inspector creates a rule with a selector that matches the selected element. In this case, the element is a paragraph, so Web Inspector chose the generic p tag. Type color: red; underneath the p selector, and notice that this entire paragraph instantly turns red.

Metrics

The Box Model provides an easy way to visualize the dimensions of an element at a glance. From the center out, it shows the width and height, padding, border, and margin of the selected node. All of the values are editable; double-click and type in a value to see the change update immediately. As in the Rules tab, you can hold the Option key while pressing the up- or down-arrow keys to increment or decrement the current value.

Figure 2-6 The Metrics tab in the Style details sidebar

Inspect this sentence, and then click the Metrics tab. As you move your mouse over areas of the box model, you’ll see the corresponding areas on the page flash with color. Give the padding-bottom a value by double-clicking the hyphen directly underneath the dimensions. Type in a number (50, for example) and press Enter. You’ll notice the padding underneath this paragraph expand by 50 pixels. You do not need to supply a unit in the box model—all values are in pixels.

Adding values in the Metrics tab affects only the selected element. The values are applied as an inline style; look back in the content browser and notice that the selected node now has a style attribute. If you’d like the style applied to multiple elements, you’ll need to create a rule in the “Rules” tab that matches a certain selector.

Layers

The Layer details sidebar provides information about what is composited as a layer. Elements that have a 3D transform, a fixed position, or overlap other composited elements are rendered in their own layer so that its movement during animations or scrolling can be hardware-accelerated for maximum performance.

However, each layer increases the memory footprint of your webpage (significantly for layers covering a large area). You should avoid having elements in their own layer unless absolutely necessary. If your page has poor scrolling or resizing performance, check to see if any nodes are being repainted on every scroll or resize event.

To see which elements on your page are rendered in their own layer, select the root html node in the content browser. Any elements composited in a layer appear here, as shown in “Layers.” Clicking on the row in this table causes a popover to appear, explaining the reasons for compositing. When possible, minimize the number of layers present by eliminating the element’s need for compositing. Clicking the arrow that appears on hover jumps to the node’s location in the content browser.

Figure 2-7 The Layer details sidebar

The number of element repaints is displayed next to the node name. A repaint occurs when the rendering engine assesses that a portion of the page’s visual presentation needs updating—for example, when a hovered link becomes underlined, or when a window resizes. Repaints are expensive operations that can negatively affect the responsiveness of your webpage as well as impact the user’s battery life.

To visualize the page’s layers and their repaints, click the Composite Borders button () in the Navigation bar. Clicking this button outlines each layer with a colored border. Large layers are divided into tiles, which also become outlined. Whenever a tile repaints, the counter in the tile’s upper-left corner increments.

The amount of memory the element consumes is also displayed in the Layer details sidebar. The amount of memory an element consumes is determined by multiplying the product of the element’s dimensions by 4 bytes (1 byte for each red, green, blue, and alpha channel).

Node

The Attributes section lists the names and values of HTML attributes of the selected node. These values are read-only; to edit an element’s attributes, double-click the node in the content browser.

The Properties section lists all available methods and properties available to the selected element, including methods and properties inherited from its parent objects.

The Event Listeners section lists all JavaScript events attached to this node and its ancestors. It presents the type of event, such as click or mouseover, as well as the name of the function it calls. If your JavaScript events aren’t firing as expected, check here to confirm that the element is indeed listening for the intended event and function.

Resource

The Resource sidebar shows information about the selected resource. You can view the full URL of the resource, as well as the server request and response headers that were sent with this resource, as shown in Figure 2-9.

Figure 2-9 The Resource details sidebar

Resources and Storage

Resources are grouped implicitly. If there are over a certain number of resources on a page, then images, scripts, stylesheets, fonts, frames, and XHRs (XMLHttpRequests) coalesce into groups. These groups are represented by a folder. Groups do not reflect directory structure; that is to say, the organization of resources in the sidebar does not represent the path of the resource.

JavaScript and CSS

External JavaScript and CSS files are expanded by default. You might have minified some resources to reduce file size—a common practice on the web. Web Inspector automatically expands, or pretty-prints, your minified code in order to be easier to read. To toggle between pretty-print and original formatting, click the code formatting button ().

If source maps are present, Web Inspector splits production JavaScript and CSS into its original source files. Concatenated resources—for example, ones created by a CSS preprocessor or a build script—appear as a group, and the source files are listed as children. The names of source-mapped files appear throughout Web Inspector in italics; click the file name to jump to the position in the concatenated file, and Command-click the file name to jump to the position in the original source file.

JavaScript files allow you to set breakpoints in the left margin. To learn more about setting breakpoints, read “Breakpoints.”

While it’s quicker to change an element’s CSS rules in the Figure 2-11 sidebar, you can also live-edit the stylesheet directly in the content browser. Select a CSS resource and begin typing, just as you would in a text editor.

Note: You must view the CSS file in its original formatting (not pretty-printed) in order to live-edit a stylesheet.

Changes you make to JavaScript or CSS files can easily be saved onto disk by pressing Command-S. Saving external resources with Web Inspector allows you to rapidly prototype without the need to switch back to your text editor.

Storage

Cookies

If your website uses cookies, they appear as an offline resource in the Resources navigation sidebar. As shown in Figure 2-10, cookies are displayed in a table that lists each cookie’s name, value, domain, path, expiration date, and size.

Figure 2-10 Cookies

Entries in this table are read-only; if you want to edit a cookie’s value, you need to do so with the document.cookie object in JavaScript (you can use the Quick Console at the bottom of the content browser to modify the cookie and see the results update in real time). Pressing the Delete key while a cookie is selected deletes the cookie.

Local and Session Storage

If your web app uses HTML5 Web Storage, keys and values you set in your code appear in the Local Storage offline resource, as shown in Figure 2-11. Local storage is displayed as an editable data grid of key-value pairs. Double-click an empty row to create a new entry, and double-click an existing entry to edit its value. Pressing the Delete key on a selected entry removes the key-value pair. Local storage provides a database of up to 5 MB per domain that persists even after Safari is quit.

Figure 2-11 The Local Storage resource

Session storage is also displayed as an editable data grid of key-value pairs. Unlike local storage, session storage persists for as long as the window or tab remains open.

SQL Databases

If your webpage uses Web SQL Databases, they appear as an offline resource under Databases in the Resources navigation sidebar. Click the Databases disclose triangle to see a list of open databases and their tables. Selecting a database table displays a data grid containing all the columns and rows for that table.

In addition to inspecting HTML5 databases, you can interact with them by issuing SQL queries against any of the displayed databases. Select a database in the sidebar to see an interactive console for evaluating SQL queries.

The input to this console has auto-completion and tab-completion for table names in the database, as well as common SQL keywords.

Application Cache

Websites that provide a manifest file can have items stored in Safari’s offline application cache. On subsequent visits to the website, Safari loads these items from the cache instead of loading them from the website again. This provides a mechanism for websites to offer features such as canvas-based games that users can play, even when their device’s browser has no Internet connection.

You can inspect all the current contents of the application cache by clicking Application Cache. Safari shows a list of domains that have cached files. Select a domain to see the files in that domain’s cache, showing the URL from which they were loaded, the type of entry the resource was specified as (explicit, manifest, master, or fallback), and the file size.

When the Application Cache is selected, the Storage details sidebar is also shown. It reports if the target device is online or not, and its current status.

Extension Scripts

Any scripts that have loaded from an installed Safari extension appear in a group labeled Extension Scripts. For more information about Safari Extensions, read Safari Extensions Development Guide.

Measure and Improve Page Performance

Web Inspector provides a suite of tools you can use to quantify the speed of your webpages. You can monitor network requests as they download, observe page layout calculations performed by the WebKit rendering engine, and profile the efficiency of your JavaScript functions and CSS selectors.

Timelines

Web Inspector features a visual download analyzer and a JavaScript profiler to help you make your website load and your scripts run as quickly and responsively as possible.

Recording Timelines

Timelines are a graphical representation of activity that occurs during the lifetime of the open page. Timelines show network requests, CSS rendering, and JavaScript events.

All timelines record simultaneously. You can start recording timelines two ways:

Clicking the Start Recording button. This shows all activity that happens since the record button is clicked. While recording, you can interact with the page to trigger XHR loads, style recalculation, page layout and painting, and JavaScript events.

Reloading the webpage while Web Inspector is open. This shows all activity as it happens during page load.

To stop recording, click the Stop Recording button. The content browser shows various details depending on the selected timeline.

Network Requests

Figure 3-1 shows recorded network requests as blue horizontal bars.

Figure 3-1 Network requests in the Timelines navigation sidebar

When the Network Requests timeline is selected, the bottom portion of the content browser displays each individual file requested from the webpage. The horizontal bar graph shows you when each resource was requested, the latency of the server, and the download time for each resource. Hover over any bar to see additional details in a tooltip.

The vertical dashed blue line indicates when the DOM becomes available to Safari, and is equivalent to the DOMContentLoadedJavaScript event. The red line indicates when all resources have finished loading, and is equivalent to the load JavaScript event.

Layout and Rendering

Just as you can see great detail about every resource that has loaded, you can see great detail about how Safari’s rendering engine, WebKit, renders the page. Click on Layout & Rendering in the Timelines pane to display a table of each paint that has been rendered, as shown in Figure 3-2. Each layout calculation and paint rendering is represented by a purple horizontal bar.

JavaScript and Events

JavaScript executed during a recording session is represented as a yellow horizontal bar in the timeline. Evaluated scripts, dispatched events, animation frames, and timers are listed in the table in the content browser, as shown in Figure 3-3.

Figure 3-3 JavaScript events in the Timelines navigation sidebar

Timing Profiles

Underneath the Timelines pane in the Timelines navigation sidebar is the Profiles pane. This pane allows you to see where execution time is being spent in your JavaScript and CSS. Use the Profiles pane to find bottlenecks in your scripts and inefficiency in your CSS selectors to optimize their performance.

JavaScript Profiling

Profiling JavaScript exposes the bulk of your code’s execution time. To use the Profiles pane, you must start profiling, either manually or by including a console.profile() call in your script. To start profiling manually, click the record button () in the top right of the Profiles pane, and select Start JavaScript Profile in the resulting menu. The record button turns red (). To stop the profile, click the record button again. No profile is displayed until you stop profiling, either manually or through a call toconsole.profileEnd(). Each time you begin and end profiling, another profile is captured.

Once you have captured one or more profiles, they are listed on the left side of Web Inspector. Manual profiles are named sequentially (JavaScript Profile 1, JavaScript Profile 2, and so on). Profiles created by calls to console.profile() are named with the title of the profile provided as an optional argument. If multiple profiles are captured under the same name, a disclosure triangle reveals multiple runs within the profile.

The time spent in each function executed during the profile is displayed, as well as the number of times each function is called, as shown in Figure 3-4. The time is displayed as a percentage of total time by default, but you can view the time in seconds by clicking the percentage icon ().

Figure 3-4 Profiling JavaScript

The time spent is grouped into three categories: Self, the total time spent in the function itself; Total, the total time spent in the function and any subordinate functions it calls in turn; and Average, the average time spent in the function itself during each call (the Self time divided by the number of calls).

If a function is declared with a name, the function name is displayed. If a function is created programmatically by an eval()statement or inline <script> </script> tagset, it is labeled (program) in the profile. Other unnamed functions, for example, a function defined within a variable declaration, are labeled (anonymous function). To be less vague, you can rename anonymous functions in a profile by assigning a string value to the displayName property of the function.

Where applicable, the source URL and line number of the function declaration is shown in gray to the right of the function name. The source URL is a link. Clicking it opens the source in the content browser, scrolled to the line number where the function is declared.

CSS Selector Profiling

Just as you can profile JavaScript, you can profile CSS selectors to measure their efficiency. The more general a selector (such as a selector on a tag), the more time it takes to find all matches. More specific classes (such as an ID or class) match fewer elements, and are faster for WebKit to find.

Figure 3-5 Profiling CSS

Debug JavaScript

Turn to Web Inspector when your front-end logic goes awry. Web Inspector offers a debugging environment that lets you pause script execution and observe the values of your variables as they are defined.

Debugger

If you are getting JavaScript errors on your webpage, you can use the Debugger navigation sidebar to assist you in finding the cause of the problem. By setting breakpoints throughout your code, you can inspect the values of your variables and observe the call stack during runtime.

Even if your JavaScript is minified, Web Inspector pretty-prints—or expands—all of your scripts, allowing you to set breakpoints on minified content.

Breakpoints

Breakpoints are markers you set on JavaScript resources to indicate a pause in script execution. You may already be familiar with breakpoints if you have experience with compiled programming languages.

To add a breakpoint, select a JavaScript resource in the Resources navigation sidebar, and click a line number in the gutter of the content browser. A blue marker is set, indicating that script execution will pause here the next time this line runs. When a breakpoint is set, you can click it again to deactivate it, as shown in Figure 4-1.

Figure 4-1 An active breakpoint on line 17 and an inactive breakpoint on line 19

Important: Setting a breakpoint on a blank line does nothing. The line that you break on must contain code, otherwise script execution won’t pause at that line.

After one or more breakpoints are set, reload your page. Breakpoints retain their position across page loads, so your breakpoints won’t be lost. As soon as Safari’s JavaScript interpreter reaches a line of code that has a breakpoint on it, JavaScript execution halts, and the Scope Chain details sidebar appears. The Scope Chain contains a snapshot of variables available to the scope of the paused line, as well as their current values. For further information about the Scope Chain details sidebar, continue to “Scope Chain.”

Every breakpoint you set across all your scripts appears under Breakpoints in the navigation sidebar, as shown in Figure 4-2. Clicking the line jumps the text in the content browser to the line with the breakpoint. The breakpoint icon to the right of the line number allows you to enable and disable the breakpoint without removing it.

Figure 4-2 All breakpoints are listed in the navigation sidebar

By clicking the breakpoint icon in the Breakpoints pane, you disable all breakpoints. The breakpoint locations are still saved, but JavaScript runs as if no breakpoints are set. Disabled breakpoints have a grayed-out appearance, as shown in Figure 4-3.

Figure 4-3 An active and inactive breakpoint when breakpoints are disabled

You can also set a breakpoint within <script> tags on HTML resources.

Delete a breakpoint by selecting it in the Breakpoints pane and pressing the Delete key. You can also drag the breakpoint out of the gutter to remove it.

You can set a breakpoint programmatically by calling the debugger keyword in your scripts. Don’t ship this code to your customers, though, because it will break the execution of your scripts at that point. It is meant for development purposes only.

When a script is paused, you can hover over objects in your script to reveal a token popover containing the object’s methods and properties and their values at the current time, as shown in Figure 4-4.

Figure 4-4 Hovering over a variable inspects the object

Conditional Breakpoints

You can set breakpoints that are only active when a certain condition evaluates to be true. To do so, Right-click the breakpoint in the Debugger details sidebar and select Edit Breakpoint, as shown in Figure 4-5.

Figure 4-5 Editing a breakpoint

A popover appears, prompting you to enter a condition, as shown in Figure 4-6.

Figure 4-6 Setting a conditional breakpoint

The condition is scoped to the current context; any variables within current scope are available to use in this expression. If the condition evaluates to be true, the script pauses at the breakpoint; otherwise, the script continues.

Call Stack

The call stack lists the functions that have been called and have not yet finished returning. The most recently called functions are displayed at the top of the stack, as shown in Figure 4-7. Use this to view the order in which functions are called.

Figure 4-7 The call stack

When a script is paused, the call stack shows the chain of functions called to arrive at the paused line. Selecting an item in the stack jumps to where the line is declared in your scripts.

Debugger Controls

Use the buttons above the call stack to have line-by-line control of where the debugger pauses execution next. The buttons have the following behavior:

Continue—continues execution until the next breakpoint.

Step over—steps to the next line, without descending into any functions called on the current line.

Step into—steps to the next line, descending into any functions called on the current line first. If there are no function calls on the current line, this button behaves like the step over button.

Step out—steps to the preceding frame in the call stack.

Scope Chain

The Scope Chain details sidebar displays all the variables set on the page and their values at the moment in time the script is paused. Variables are organized by their scope.

Note: You can only access the Scope Chain details sidebar when a script is paused.

Local Variables

This includes all of the local variables available in the current function’s scope. All variables defined within the current function have their names printed here. Their values appear if they have been set at this point; otherwise, the value is undefined.

Figure 4-8 Variables defined within the scope of the immediate function

There are two variables that appear in the local variables section that you don’t declare explicitly: arguments and this. Thearguments variable contains the values of the arguments that were passed into this function, including the implicitly availableevent object. this refers to the object this function is a member of (either the object that this method is attached to, orwindow).

Important: Variables set without the var keyword fall out of local scope. If you don’t declare a variable with var, it appears under Global Variables instead of Local Variables. Doing so pollutes the global namespace, so you should always declare local variables with var.

Closure Variables

If you set a breakpoint within a closure, or anonymous function, you see variables appear in the Closure Variables section, as shown in Figure 4-9. Closures have privileged access to the scope of the outer function that calls them.

Figure 4-9 Variables available to the current scope outside the immediate function

Global Variables

Variables attached to the global object window appear under the Global Variables section, as shown in Figure 4-10. This includes global variables you define in your scripts, global variables defined in installed extensions, and methods and properties ofwindow.

Figure 4-10 Variables in the global scope

Interact with the Console

Lift up the hood of your webpages and interact directly with your web content in the console.

The Console

The console offers a way to inspect and debug your webpages. Think of it as the Terminal of your web content. The console has access to the DOM and JavaScript of the open page. Use the console as a tool to modify your web content via interactive commands and as a teaching aid to expand your knowledge of JavaScript. Because an object’s methods and properties autocomplete as you type, you can see all available functions that are valid in Safari.

For example, open the console and type $$(‘p’)[1]. ($$ is shorthand for document.querySelectorAll—see more shorthand commands in Table 5-1.) Because this paragraph is the second instance of the p element on this page ([1] in a 0-based index), the node represents this paragraph. As you hover over the node, its position on the page is visibly highlighted. You can expand the node to see its contents, and even press Command-C to copy it to your clipboard.

Command-Line API

You can inspect HTML nodes and JavaScript objects in more detail by using the console commands listed in Table 5-1. Type the command-line APIs interactively within the console.

If your scripts share the same function name as a Command-Line API function, the function in your scripts takes precedence.

Starts logging all events dispatched to the given object. The optional argument types defines specific events or event types to log, such as “click”.

unmonitorEvents(object[, types])

Stops logging for all events dispatched to the given object. The optional argument typesdefines specific events or event types to stop logging, such as “click”.

inspect(object)

Inspects the given object; this is the same as clicking the Inspect button.

copy(object)

Copies the given object to the clipboard.

clear()

Clears the console.

The functions listed in Table 5-1 are regular JavaScript functions that are part of the Web Inspector environment. That means you can use them as you would any JavaScript function. For example, you can assign a chain of Console API commands to a variable to create a useful shorthand. Listing 5-1 shows how you can quickly see all event types attached to the selected node.

Listing 5-1 Find the events attached to this element

var evs = function () {

return keys(getEventListeners($0));

};

After defining this function, inspect the magnifying glass in the top-right corner of this webpage, and type evs() in the console. An array containing the string “click” is returned, because there is a click event listener attached to that element.

Of course, these functions shouldn’t be included in your website’s JavaScript files because they are not available in the browser environment. Only use these functions in the Web Inspector console. Console functions you can include in your scripts are described in “Console API.”

Console API

You can output messages to the console, add markers to the timeline, and control the debugger directly from your scripts by using the commands listed in Table 5-2.

Important: These functions exist to aid development and should not be included in any of your production JavaScript.

Table 5-2 JavaScript functions available in the Console API

Function

Description

console.assert(expression, object)

Asserts whether the given expression is true. If the assertion fails, prints the error and increments the number of errors in the activity viewer. If the assertion succeeds, prints nothing.

console.clear()

Clears the console.

console.count([title])

Prints the number of times this line has been called.

console.debug(object)

Alias of console.log().

console.dir(object)

Prints the properties and values of the object.

console.dirxml(node)

Prints the DOM tree of an HTML or XML node.

console.error(object)

Prints a message to the console with the error icon. Increments the number of errors shown in the activity viewer.

console.group([title])

Prints subsequent logs under a disclosure of the given title.

console.groupEnd()

Ends the previously declared console grouping.

console.info(object)

Alias of console.log().

console.log(object)

Prints the object to the console with the log icon. Increments the number of logs shown in the activity viewer.

console.markTimeline(label)

Marks the Timeline with a green vertical dashed line that indicates when this line of code was called. See “Recording Timelines.”

console.profile([title])

Starts the JavaScript profiler. The optional argument title contains the string to be printed in the header of the profile report. See “JavaScript Profiling.”