Debugging Your Website

Safari's powerful Web Inspector tool can find and correct problems with your website. Syntactic and structural problems can be revealed by using the interactive console. Data transmitting over the network can be analyzed and dissected. Script execution can be paused and examined in the Debug navigator. Even the most complex problems can usually be resolved using Web Inspector.

Use Cases

Here are some common cases and the best ways to deal with them.

Debugging HTML and CSS Using Web Inspector

If your website doesn’t look or act as you expect, analyze your site using Web Inspector.

Choose Show Web Inspector from the Develop menu. This opens the Web Inspector window.

The left sidebar of Web Inspector is known as the Navigation sidebar. Here you’ll find the main sections of Web Inspector under each navigator icon. At the bottom of the Navigation sidebar is the Filter input field. Anything typed into this field will filter the results displayed within the currently selected navigator. For example, in the Resource navigator (Control-1), typing *.min.js will refine the results shown to only display files containing .min.js in their filepaths.

The center of Web Inspector, known as the content browser, contains the content view of the selected item in the Navigation sidebar. You can access the DOM of the current webpage as a collapsable and expandable structure of nested elements by clicking a source file in the Resource navigator. Click the disclosure triangle to expand or collapse the view of a given element and its contents. A breadcrumb path is added to the top bar, allowing you to see where you are in the DOM hierarchy. You can click a breadcrumb to move back up the hierarchy, as well as toggle between viewing the DOM and the source.

The DOM displayed is the symbolic structure of the webpage that Safari has constructed in memory. In a simple static webpage with no errors, the DOM is identical to the HTML source. In websites where the DOM changes interactively, the content browser gives you the current state of the DOM. If there are errors in the webpage, the content browser shows you the DOM that Safari has constructed, which may differ significantly from the source.

When you click an element in the DOM, the corresponding element is highlighted in the browser window. If you Control-click or right-click in the browser window, a contextual menu is displayed with an Inspect Element option. Choosing Inspect Element highlights the corresponding element in the DOM, making it easy to zoom in on a given element and find its location in the source, even in a complex web app.

The Details sidebar on the right side of Web Inspector displays the properties, styles, and metrics of the currently selected element, as well as information about the page itself, such as query parameters and HTTP headers.

Using the DOM view along with the styles, metrics, and properties, you can inspect and interactively modify any element on a webpage. More significantly, you can quickly grasp the inheritance structure that gives each element its appearance, placement, and behavior.

When debugging a webpage, it’s typically best to Control-click or right-click on the part of the page that looks wrong in Safari’s browser window, select Inspect Element, then look at the highlighted element in the DOM panel of Web Inspector to see how the element is defined. You can interactively modify the HTML parameters in Web Inspector to see how that changes the behavior in the browser window. If the HTML attributes seem correct, check the applied CSS styles by selectively disabling them or modifying them in Web Inspector. The effects are immediately visible in the browser window. If this solves the problem, copy the modified HTML or CSS and paste it into your source. If not, the problem may be caused by an errant script. See “Debugging JavaScript Using the Web Inspector.”

If you know the name of an element in the DOM that you want to inspect (for example, to find all instances of a particular class), use the Search navigator (Control-4) in the upper-left corner of the Inspector. The Search navigator conducts a plain-text search across all resources linked from the current page.

The following subsections show how to inspect and modify HTML and CSS using Web Inspector.

Inspecting and Editing DOM Attributes

The left pane shows the DOM attributes associated with the currently selected element. Double-click an element name, attribute name, or attribute value to edit it interactively, as shown in Figure 3-1.

Figure 3-1  Editing DOM attributes
Editing DOM attributes in Web Inspector.

Use the Tab key and Shift-Tab key combination to traverse the attributes.

You can edit values using the letter and number keys as you would expect. For numerical values, you can also use the arrow keys to increment or decrement the value by 1. Holding down the Option or Alt key increments or decrements the value by 0.1, while holding down the Shift key increments or decrements by 10.

Double-click an element or attribute to edit it, or Control-click or right-click the element to bring up a contextual menu, as shown in Figure 3-2.

Figure 3-2  Nodal context menu
A contextual menu that is activated upon right-click of a node in the content browser.

You can add a new attribute to the element, edit the DOM as if it were an HTML file in a text editor, copy the HTML for the element and its children to the clipboard, of delete the element and all of its children.

Inspecting and Editing Styles

Click Style (Control-Shift-3) in the Details sidebar to see the CSS styles that are applied to the currently selected element, as shown in Figure 3-3.

Figure 3-3  Viewing styles in the Details sidebar of Web Inspector
Viewing CSS styles in the Details sidebar, the right side of Web Inspector.

The first section of text in the Style details sidebar shows the computed style for the selected element, which is the sum of all inherited and overridden styles specified for that element and its containers. This section is followed by the sections containing the CSS specifications that apply to the element, in hierarchical order. Select the “Show inherited” option to see the inherited default styles being applied as well.

Clicking an editable style brings up a series of checkboxes. Deselecting a checkbox disables the application of that style property. The results are immediately displayed in the browser window. The style is then displayed in strikethrough text, as shown in Figure 3-4. Reselecting the checkbox enables the style property again.

Figure 3-4  Editing style properties
Editing CSS styles in the Details sidebar of Web Inspector.

Double-clicking a style allows you to edit it on the fly and immediately see the difference in your browser window. You can edit properties in a few different ways:

  • Press Delete with the property selected to delete the property, if allowed.

  • Use the keyboard to change the property values.

  • Use the arrow keys to increment or decrement the value by 1 (for numerical values only). Holding down the Option or Alt key increments or decrements the value by 0.1, while holding down the Shift key increments or decrements by 10.

  • Add style attributes by clicking in the white space or tabbing past the last attribute, or by appending a semicolon to the end of a line and typing in new style attributes.

  • Edit a selector by double-clicking it.

  • Create a new rule by choosing New Style Rule from the gear menu.

  • Cycle through different color representations—white, #ffffff, or rgb(255,255,255), for example—by clicking on the color swatch beside a color value.

Because style properties are interactively editable, you can modify them until you have exactly the effect you want—before you change a line of source code.

Inspecting and Editing Metrics

Click Appearance to see the spatial metrics for a given element—its height and width, along with the height and width of any borders, margins, or padding. Double-click a metric value displayed on the right to edit it directly, as shown in Figure 3-5.

Figure 3-5  Editing metric attributes
Editing the position, margin, border, and padding in the Appearance inspector.

Inspecting and Editing HTML Properties

Click the disclosure triangle for HTMLElement under the Node navigator in the Details sidebar to view the highlighted element’s HTML properties. Double-click a property to edit its value, as illustrated in Figure 3-6.

Figure 3-6  Editing HTML properties
Editing HTML properties in the Node navigator.

In this image, you can see the properties of the element with an id of main. The hidden property is set to false. Double-clicking the property allows you to edit its value.

Inspecting Listener Functions

If any JavaScript functions have been added as event listeners, you can inspect them by clicking the HTML node of interest in the content browser, and then clicking the Event Listeners disclosure triangle in the Details sidebar, as shown in Figure 3-7.

Figure 3-7  Event Listeners
Viewing JavaScript event listeners in the Node inspector.

Clicking the go-to arrow to the right of the function name will take you to where the event handler is declared in the code.

Debugging JavaScript Using the Web Inspector

To start debugging JavaScript, open Web Inspector and click Breakpoint in the Navigation sidebar.

You can set a breakpoint in any script by clicking in the gutter by the line number. The script will pause at the breakpoint. The script name, line number, and text of the breakpoint appear in the Breakpoints section on the left of the Web Inspector window. Clicking a breakpoint on the left 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.

You can add breakpoints to your code by selecting a JavaScript file in the Resource navigator. Clicking in the gutter will add blue breakpoints. You also have the option to break on all exceptions or all uncaught exceptions in the Breakpoint navigator, as shown in Figure 3-8.

Figure 3-8  The Breakpoint navigator
Setting breakpoints in a JavaScript's file. You can break on all exceptions, all uncaught exceptions, or at a line number of you choosing.

When the source of the script is a JavaScript file, the filename is listed. If the source is in-line JavaScript in an HTML file, the URL of the HTML is listed. If the JavaScript is the result of a string passed through eval() or another anonymous source, the resource is listed as Anonymous Script.

The pause button in the Quick Console at the bottom causes the debugger to pause JavaScript execution. While paused, all JavaScript calls are blocked, and you are presented with additional controls to help you understand your code:

Web Inspector has a unique feature regarding in-scope variables: It shows closures, “with” statements, and event-related scope objects separately. This gives you a clearer picture of where your variables are coming from and why things might be breaking (or even working correctly by accident).

You can also use the console to assist in debugging JavaScript.

Using the Console to Debug JavaScript

Click the Log navigator to open the Current Log. You can also press the Esc key anywhere in Web Inspector to move focus to the Quick Console in the bottom bar.

You can use the console to debug JavaScript in two distinct ways:

Entering JavaScript Interactively

You can enter JavaScript in the console interactively to help debug your script. For example, you can call functions defined in the script and see the results; you can evaluate expressions that include variables or functions declared in your script; and you can query the values of variables directly.

This is particularly helpful when used in combination with breakpoints in your code, allowing you to pause and inspect the script interactively at any point.

The console also has auto-completion support. As you type, JavaScript variables, properties, and function names are suggested in a pop-up selection menu. Pressing Tab or the Right Arrow key accepts the current suggestion. If multiple selections begin with the same prefix, you can cycle through suggestions by pressing the Up and Down Arrow keys.

Typing a variable name and pressing Enter displays the variable’s current value.

Any changes you make to the DOM using JavaScript from the console are immediately displayed in the content browser, as well as in the browser window.

The Command-Line API

In addition to the usual JavaScript methods, and the functions and variables defined in your script, you can enter some Firebug command-line APIs interactively at the console. The following commands are supported:

  • $0-$4

    Variables that contain the current and previous three selected nodes in Web Inspector.

  • $(id)

    Returns the element with the specified ID. Similar to getElementById().

  • $$(selector)

    Returns the array of elements that match the given CSS selector. Similar to querySelectorAll.

  • $x(xpath)

    Returns the array of elements that match the given XPath expression.

  • clear()

    Clears the console.

  • dir(object)

    Prints an interactive listing of all properties of the object. Similar to the popover from hovering over an object when a script is paused.

  • dirxml(node)

    Prints the XML source tree of an HTML or XML element. This looks identical to the view that you would see in the content browser of Web Inspector. You can click on any node to inspect it.

  • inspect(),

    Takes an element, database, or storage area as an argument and automatically jumps to the appropriate panel to display the relevant information.

  • keys(object)

    Returns an array containing the names of all properties of the object. (Properties are key-value pairs; the name of a property is the key.)

  • monitor(functionName)

    Turns on logging for all calls to a function.

  • monitorEvents(object[, types])

    Turns on logging for all events dispatched to an object. The optional argument types may specify a specific family of events to log. The most commonly used values for types are mouse and key.

    The full list of available types includes composition, contextmenu, drag, focus, form, key, load, mouse, mutation, paint, scroll, text, ui, and xul.

  • profile([title])

    Turns on the JavaScript profiler. The optional title is a label for the profile.

  • profileEnd()

    Stops a running profile.

  • unmonitor(functionName)

    Stops logging calls to a function.

  • unmonitorEvents(object[, types])

    Stops logging events, optionally events of a particular type, that are dispatched to an object.

  • values(object)

    Returns an array containing the values of all properties of the object. The values are returned in the same order as the keys in keys(object).

To make working with these APIs easier, they are included in the Console’s auto-completion capability.

Safari JavaScript Console API

Safari supports several JavaScript console functions for debugging. As an alternative to setting breakpoints, you can log branches in your code path, print variable values, and so on, using console functions. Safari supports many of the same console functions used in the Firebug API.

Many console functions take a message-object as a parameter. This message-object is logged to the error console. When Safari logs a message-object, it appends a hyperlink to the line in the source code where the logging console function appears. A message-object can contain a string, one or more variables, or a combination. You can use printf-style string substitution using numeric or string variable values. If variables are included, but not used for string substitution, the variable values are logged, space delimited.

Examples of valid message-objects:

"It got this far..."

"Item and count:", item, count

"Item: %s Count: %d", item, count

"Item: %s Count:", item, count

count

The following console functions are supported in Safari:

  • console.assert(expression, message-object)

    Logs the message, if expression evaluates false.

  • console.count([title])

    Logs the number of times this line of code has executed, and an optional title.

  • console.debug([message-object])

    Logs the message object.

  • console.dir(object)

    Logs the current properties of the object.

  • console.dirxml(node)

    Logs the DOM tree of an HTML or XML element.

  • console.error(message-object)

    Logs an “error” icon followed by a color-coded message object.

  • console.group(message-object)

    Logs the message-object and begins an indented block for further log entries.

  • console.groupEnd()

    Ends an indented block of log entries.

  • console.info(message-object)

    Logs the message-object.

  • console.log(message-object)

    Logs the message-object.

  • console.profile([title])

    Begins profiling JavaScript—tracking the number of times each function is called, the time spent in that function, and the time spent in nested groups of functions. If a title is provided, the profile is named. See “Optimizing JavaScript.”

  • console.profileEnd([title])

    Ends one or more JavaScript profiles. If a title is provided and a running profile has a matching title, only the current run of that profile is ended. Otherwise, the current run of all profiles is ended.

  • console.time(name)

    Starts a timer and gives it a name.

  • console.markTimeline("string")

    Adds a label to the timeline view marking the point when the method was called.

  • console.trace()

    Logs a JavaScript stack trace at the moment the function is called. The stack trace lists the functions on the call stack (functions that have been called and have not yet finished executing and returned), and the values of any arguments passed to those functions.

  • console.warn(message-object)

    Logs a “warning” icon followed by a color-coded message-object.

Analyzing Client-Side Storage, Databases, and Cookies

You can use Web Inspector’s Storage navigator to inspect HTML5 client-side databases, local storage, session storage, cookies, and the application cache.

Local storage and session storage are displayed as an editable data grid of key-value pairs. As shown in Figure 3-9, cookies are displayed in a table that lists each cookie’s name, value, domain, path, expiration date, and size. Pressing the Delete key while a cookie is selected deletes the cookie.

Figure 3-9  Inspecting cookies
A list of all the cookies coming from the current domain. Columns include Name, Value, Domain, Path, Expiration date, and Size.A list of all the cookies coming from the current domain. Columns include Name, Value, Domain, Path, Expiration date, and Size.

If a webpage uses HTML5 databases, they will display in the Storage navigator. 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, as shown in Figure 3-10.

Figure 3-10  Inspecting databases
A table of HTML5 databases set from the current domain.

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, as illustrated in Figure 3-11.

Figure 3-11  An SQL query
Querying the HTML5 database with SQL.

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

Inspecting the Offline 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 opening the Storage navigator of the Web Inspector and clicking the Application Cache disclosure triangle. 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, as shown in Figure 3-12.

Figure 3-12  Application cache
A table of data saved with HTML5 localStorage. Columns include Resource, Type, and Size.A table of data saved with HTML5 localStorage. Columns include Resource, Type, and Size.

Did this document help you? Yes It's good, but... Not helpful...