A user account is required in order to edit this wiki, but we've had to disable public user registrations due to spam.

To request an account, ask an autoconfirmed user on IRC (such as one of these permanent autoconfirmed members).

Difference between revisions of "Specs/howto"

From WHATWG Wiki
Jump to: navigation, search
(add some notes on the format)
m (GPHemsley moved page Howto spec to Specs/howto: Using subpages for easier navigation.)
 
(48 intermediate revisions by 5 users not shown)
Line 1: Line 1:
author: [mailto:josiew@google.com Josie Wernecke]
+
== About this document ==
  
status: DRAFT (25 June 2009)
+
This document explains basic guidelines for writing a specification for the web platform. [http://www.whatwg.org/C HTML] and [http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html DOM] among others follow these guidelines. You are encouraged to study those specifications and follow the patterns and style they establish.
  
== About This Document ==
+
See also [[Advice for people writing specs]].
 
 
This document explains basic guidelines for writing a specification and is based on information provided by Ian Hickson, editor of the [http://www.whatwg.org/specs/web-apps/current-work/multipage/ HTML5 Specification].
 
  
 
== Audience ==
 
== Audience ==
Line 13: Line 11:
 
== Organization ==
 
== Organization ==
  
Organize the specification by classes. This is a reference document, not a teaching document, so the order should reflect the class hierarchy, with functional groupings of classes where appropriate.
+
Each specification includes these top-level sections:
 +
 
 +
* '''Introduction''' — Gives an overview of the technology defined.
 +
* '''Conformance''' — References [http://tools.ietf.org/html/rfc2119 RFC 2119] and/or explains how conformance is determined in this specification. Lists the conformance classes that apply to this specification. See http://www.w3.org/TR/qaframe-spec/
 +
* '''Terminology''' — Defines where the terms in the specification originate from and sometimes provides a few novel definitions that do not fit within the main prose of the specification.
 +
* … content …
 +
* '''References'''
 +
* '''Acknowledgments'''
 +
 
 +
See e.g. [http://dev.w3.org/2006/webapi/progress/ Progress Events] and [http://dev.w3.org/2006/webapi/XMLHttpRequest-2/ XMLHttpRequest].
  
 
== Content ==
 
== Content ==
  
Content in a specification falls into two general categories: ''normative'' and ''informative''. ''Normative'' content includes the requirements and definitions and uses verbs such as ''must'', ''should'', and ''may''. If a normative statement uses the verb ''must'', the browser implementor should be able to write a test case for it. (If it is not possible to write a test case for the statement, do not use the word ''must''.) ''Informative'' content is everything that is not normative. Informative (non-normative) content includes diagrams and code examples—very useful content, but supportive in nature to the actual browser requirements.
+
Content in a specification falls into two general categories: ''normative'' and ''informative''. ''Normative'' content includes the requirements and definitions and uses verbs such as ''must'', ''should'', and ''may''. Refer to [http://tools.ietf.org/html/rfc2119 RFC 2119]  for their definitions. If a normative statement uses the verb ''must'' (and applies to UAs), the browser implementor should be able to write a test case for it. (If it is not possible to write a test case for the statement, do not use the word ''must''.) The verb "may" merely grants permission and is used rarely. Do not use "may not". Normal lowercase is preferred for readability.
 +
 
 +
''Informative'' content is everything that is not normative. Informative (non-normative) content includes diagrams and code examples—very useful content, but supportive in nature to the actual browser requirements. Informative content must not include RFC 2119 keywords (use words like "can" or "is" instead).
  
 
See also Hixie's blog post on the subject: http://ln.hixie.ch/?start=1140242962&count=1
 
See also Hixie's blog post on the subject: http://ln.hixie.ch/?start=1140242962&count=1
  
Suggestions for marking up terms can be found at http://krijnhoetmer.nl/irc-logs/whatwg/20100204#l-529
+
=== Definitions ===
 +
 
 +
Elements, attributes, members of an object, algorithms, are all marked up using the <code>dfn</code> element. The <code>title</code> attribute of the element or its contents if there is no such attribute represents the name used for cross references. These are the conventions:
 +
 
 +
* '''Interfaces:''' InterfaceName; e.g. <code>interface <dfn>Document</dfn> { &hellip;</code>
 +
* '''Interface members:''' dom-InterfaceName-attributeOrMethodName; e.g. the <code><dfn title=dom-Document-URL><code>URL&lt;/code></dfn></code> attribute must &hellip;
 +
* '''Events:''' event-eventname
 +
* '''Elements:''' elementname
 +
* '''Attributes:''' attr-elementname-attributename
 +
* '''Concepts:''' concept-word; e.g. <code>&lt;dfn title=concept-node>node&lt;/dfn></code>
 +
 
 +
You reference a definition using either the <code>span</code> or <code>code</code> element. [[Anolis]] takes care of linking back to the definition.
 +
 
 +
=== IDL ===
 +
 
 +
The structure of an API is defined using [http://dev.w3.org/2006/webapi/WebIDL/ Web IDL]. An interface can be defined as follows:
 +
 
 +
&lt;pre class=idl>interface &lt;dfn>ProcessingInstruction&lt;/dfn> : &lt;span>Node&lt;/span> {
 +
  readonly attribute DOMString &lt;span title=dom-ProcessingInstruction-target>target&lt;/span>;
 +
            attribute DOMString &lt;span title=dom-ProcessingInstruction-data>data&lt;/span>;
 +
};&lt;/pre>
 +
 
 +
(See also [http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#processinginstruction <code>ProcessingInstruction</code>] in DOM Core.)
 +
 
 +
The interface members are described both in a non-normative and a normative way. Non-normatively using a <code>&lt;dl class=domintro></code> construct. Normatively as described in the following sections.
 +
 
 +
===Defining an attribute===
 +
 
 +
A readonly attribute is defined as follows:
 +
 
 +
The &lt;dfn>&lt;code>novel&lt;/code>&lt;/dfn> attribute must return "&lt;code>Hear the Wind Sing&lt;/code>".
 +
 
 +
An attribute whose value can be set is typically defined as two distinct definitions:
 +
 
 +
The &lt;dfn>&lt;code>pinball&lt;/code>&lt;/dfn> attribute must return its value. Initially its value must be null.
 +
 
 +
Setting the &lt;code>pinball&lt;/code> attribute must set its value to the given value.
 +
 
 +
Sometimes it gets a little bit more complicated and you need to use steps:
 +
 
 +
&lt;p>Setting the &lt;code>pinball&lt;/code> attribute must run these steps:
 +
&lt;ol>
 +
  &lt;li>&lt;p>If the &lt;span>readonly flag&lt;/span> is set, terminate these steps.
 +
  &lt;li>&lt;p>Set the attribute to the given value.
 +
&lt;/ol>
 +
 
 +
Keep this in mind:
 +
 
 +
* Include requirements for setting the attribute to ''any'' value, not just to valid values. For example, an attribute that requires a float value must also prescribe what the browser does when the value is set to values of Infinity, zero, or NaN (not a number), unless that is already defined by IDL.
 +
 
 +
* You can omit the "must" statement here for each step (as in the example above) if your conformance section says it is implied. The HTML spec, for example, says in its conformance section that "Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm".
 +
 
 +
* Attributes that return objects should always return the same object. Having an attribute that returns a new object each time it is accessed can make seemingly innocuous scripts perform a lot of expensive operations — for example, if such an attribute is used in a loop, every single iteration of the loop would involve allocating and initialising a new object.
 +
 
 +
===Defining a method===
 +
 
 +
Defining a simple method can be done as follows:
 +
 
 +
The &lt;dfn>&lt;code>timesTwo(&lt;var>num&lt;/var>)&lt;/code>&lt;/dfn> method must return &lt;var>num&lt;/var> &times; 2.
  
=== IDL Section ===
+
If the method is more complicated (or you feel like being more verbose) a list of steps can be used instead:
  
The IDL section (a gray box in the HTML5 Specification) provides the complete definition of all attributes, methods, and parameters for a given class. Use the IDL format defined in [http://dev.w3.org/2006/webapi/WebIDL/ Web IDL].
+
&lt;p>The &lt;dfn>&lt;code>add(&lt;var>num1&lt;/var>, &lt;var>num2&lt;/var>)&lt;/code>&lt;/dfn> method must run these steps:
 +
&lt;ol>
 +
  &lt;li>&lt;p>Let &lt;var>result&lt;/var> be &lt;var>num1&lt;/var> + &lt;var>num2&lt;/var>.
 +
  &lt;li>&lt;p>Return &lt;var>result&lt;/var>.
 +
&lt;/ol>
  
=== Attributes ===
+
Using steps helps implementors and QA making sure they have covered all the requirements.
  
For each attribute, include the following content:
+
===Dealing with exceptions===
  
* Purpose or general use of the attribute. Use the &lt;dfn&gt; tag for the definition.
+
Sometimes a method needs to throw an exception:
* What the browser must do when it retrieves the attribute ("on getting"). This is normative content.
 
* What the browser must do when it writes a value to the attribute ("on setting"). This is normative content. This content must include requirements for setting the attribute to ''any'' value, not just to valid values. For example, the on setting description for an attribute that requires a float value must also prescribe what the browser does when the value is set to values of infinity, to zero, or to NaN (not a number), unless that is already defined in the IDL section.
 
  
=== Methods ===
+
&lt;p>The &lt;dfn>&lt;code>isCuteAnimal(&lt;var>animal&lt;/var>)&lt;/code>&lt;/dfn> method must run these steps:
 +
&lt;ol>
 +
  &lt;li>&lt;p>If &lt;var>animal&lt;/var> is not "&lt;code>cat&lt;/code>",
 +
  &lt;span data-anolis-spec=dom title=concept-throw>throw&lt;/span> an "&lt;code>UnknownAnimalError&lt;/code>" exception
 +
  and terminate these steps.
  
For each method, include the following content:
+
It is important to state whether the algorithm should be terminate when the exception is thrown or not; in some cases, an algorithm will continue even after an exception is thrown (e.g. to do some cleanup).
  
* Purpose or general use of the method. Use the <code>dfn</code> element for the definition.
+
===Events===
* What happens when the method is called. Include a list of numbered steps that describe what happens when the method is invoked. Be sure to cover every case. This list of steps helps the browser implementor ensure that every steps is covered and tested.
 
  
Use the <code>var</code> element for parameters and <code>code</code> element for method names.
+
Just dispatching an event is rather trivial:
  
== Format ==
+
&lt;li>&lt;p>&lt;span data-anolis-spec=dom>Fire an event&lt;/span> named &lt;code>tralala&lt;/code>
 +
at the &lt;span data-anolis-spec=dom title=concept-document>document&lt;/span>.
  
Specifications are written in HTML. To simplify editing various parts of the document are generated by script, such as the Table of Contents. [https://bitbucket.org/ms2ger/anolis Anolis] can be used for this purpose.
+
However, often the situation is more complicated. Events may need to be dispatched from within a [http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#concept-task task] (see asynchronous below), listeners for the event can change the environment, events may need their own event object (to expose certain attributes), etc.
  
=== Conventions for definitions ===
+
====Asynchronous events====
  
Elements, attributes, members of an object, algorithms, are all marked up using the <code>dfn</code> element. The <code>title</code> attribute of the element or its contents if there is no such attribute represents the name used for cross references. These are the conventions:
+
In certain circumstances the method returns "early", but the algorithm keeps going. This is done to ensure that the user interface does not lock up while running potentially expensive operations:
 +
 
 +
&lt;li>&lt;p>Return, but continue running these steps asynchronouusly.
 +
&lt;li>&lt;p>Let &lt;var>visible&lt;/var> be the number of cute animals in the user's surroundings.
 +
&lt;li>&lt;p>If &lt;var>visible&lt;/var> is zero, terminate these steps.
 +
&lt;li>&lt;p>&lt;span data-anolis-spec=html>Queue&lt;/span> a &lt;span data-anolis-spec=html>task&lt;/span>
 +
to &lt;span data-anolis-spec=dom>fire an event&lt;/span> named &lt;code>spotted&lt;/code> at the
 +
&lt;span>context object&lt;/span>.
 +
 
 +
To still let the developer know of the effects of the method an event has to be dispatched. This is done using the "fire an event" concept from the DOM. As it cannot be dispatched synchronously since it happens in an operation running asynchronously from JavaScript's perspective, the event loop has to be used (queuing a task).
 +
 
 +
===="Cancelable" events====
 +
 
 +
Certain events are dispatched as part of an operation and allow the developer to choose whether to continue running the operation. These are often referred to as "cancelable events" (although actually the operation is cancelable). You can integrate these as follows:
 +
 
 +
&lt;li>&lt;p>&lt;span data-anolis-spec=dom>Fire an event&lt;/span> named &lt;code>hanginthere&lt;/code>  
 +
at the &lt;span>context object&lt;/span>.
 +
&lt;li>&lt;p>If the event's &lt;span>canceled flag&lt;/span> is set, terminate these steps.
 +
&lt;li>&lt;p>&hellip; eat all the things &hellip;
 +
 
 +
====Events implementing their own interface====
 +
 
 +
Often events are not just about notification, but also carry additional information. To make that work you will need to define your own event interface.
 +
 
 +
&lt;pre class=idl>[Constructor(DOMString &lt;var>type&lt;/var>, optional &lt;span>PonyEventInit&lt;/span> &lt;var>eventInitDict&lt;/var>)]
 +
interface &lt;dfn>PonyEvent&lt;/dfn> : &lt;span data-anolis-spec=dom>Event&lt;/span> {
 +
  readonly attribute DOMString &lt;span title=dom-PonyEvent-hairColor>hairColor&lt;/span>;
 +
};
 +
 +
dictionary &lt;dfn>PonyEventInit&lt;/dfn> {
 +
  DOMString hairColor;
 +
};&lt;/pre>
 +
 +
&lt;p>The &lt;dfn title=dom-PonyEvent-hairColor>&lt;code>hairColor&lt;/code>&lt;/dfn> attribute must
 +
return the value it was initialized to. When an
 +
&lt;span data-anolis-spec=dom title=concept-event>event&lt;/span> is created it must be
 +
initialized to "&lt;code>rainbow&lt;/code>".
 +
 
 +
Defining the constructor is "magically" taken care of by the [http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#constructing-events constructing events] chapter of DOM. Dispatching an event implementing its own interface requires a bit more wording as well. See the [http://dvcs.w3.org/hg/progress/raw-file/tip/Overview.html#concept-event-fire-progress "fire a progress event named e"] for an example.
 +
 
 +
====Event handler attributes====
 +
 
 +
HTML defines [http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#events event handlers]. Introducing these on objects upon which events are dispatched is common practice. Excluding markup, the IDL for adding a "colorchange" event's handler would be:
 +
 
 +
  attribute EventHandler oncolorchange;
 +
 
 +
In prose you use the following language (replacing "Pony" with the name of the interface and "colorchange" with the name of the event):
 +
 
 +
&lt;p>The following are the &lt;span data-anolis-spec=html>event handlers&lt;/span> (and their corresponding
 +
&lt;span data-anolis-spec=html title="event handler event type">event handler event types&lt;/span>) that must
 +
be supported on objects implementing the &lt;code>Pony&lt;/code> interface:
 +
 +
&lt;table>
 +
  &lt;thead>
 +
  &lt;tr>
 +
    &lt;th>&lt;span data-anolis-spec=html title="event handler">event handler&lt;/span>
 +
    &lt;th>&lt;span data-anolis-spec=html>event handler event type&lt;/span>
 +
  &lt;tbody>
 +
  &lt;tr>
 +
    &lt;td>&lt;dfn title="event-colorchange">&lt;code>oncolorchange&lt;/code>&lt;/dfn>
 +
    &lt;td>&lt;code>colorchange&lt;/code>
 +
&hellip;
 +
 
 +
===Callbacks===
  
* '''Interfaces:''' interface; e.g. <code>interface <dfn>Document</dfn> { &hellip;</code>
+
&lt;p>The &lt;dfn>&lt;code>getInspiration(&lt;var>callback&lt;/var>)&lt;/code>&lt;/dfn> method must run these steps:
* '''Interface member:''' dom-interface-member; e.g. the <code><dfn title=dom-Document-URL><code>URL&lt;/code></dfn></code> attribute must &hellip;
+
&lt;ol>
 +
  &lt;li>&lt;p>Return, but continue running these steps asynchronously.
 +
  &lt;li>&lt;p>Let &lt;var>result&lt;/var> be the result of running &lt;span>magic&lt;/span>.
 +
  &lt;li>&lt;p>&lt;span data-anolis-spec=html>Queue&lt;/span> a &lt;span data-anolis-spec=html>task&lt;/span>
 +
  to invoke &lt;var>callback&lt;/var> with &lt;var>result&lt;/var> as argument and &lt;span>context object&lt;/span>
 +
  as &lt;span>callback this value&lt;/span>.
  
== Language ==
+
Note that here we define the object the method was invoked upon as the [http://dev.w3.org/2006/webapi/WebIDL/#dfn-callback-this-value callback this value]. If you want the callback object itself to the this value you do not have to specify it, as that is the default.
  
Refer to the [http://www.ietf.org/rfc/rfc2119.txt RFC2119] for the definitive use of verbs such as ''must'', ''should'', and ''may''. If you use the verb ''must'', the implementor must be able to write a test case for this requirement. The verb ''may'' merely grants permission and is used rarely. Do not use "may not."
+
When dealing with the event loop (task queuing) the task source also needs to be clear. See &lt;canvas>'s [http://www.whatwg.org/C#dom-canvas-toblob toBlob()] method for an example.
  
 
== References ==
 
== References ==
Line 65: Line 206:
 
* '''Language and terminology:''' [http://www.ietf.org/rfc/rfc2119.txt RFC2119]. This document explains when and why to use those spec'y verbs like ''must'', ''may'', and ''should''.
 
* '''Language and terminology:''' [http://www.ietf.org/rfc/rfc2119.txt RFC2119]. This document explains when and why to use those spec'y verbs like ''must'', ''may'', and ''should''.
 
* '''Interface definitions:''' [http://dev.w3.org/2006/webapi/WebIDL/ Web IDL]. This document defines an interface definition language (IDL) that is useful for describing interfaces intended to be implemented in web browsers. It defines how to write the IDL blocks, how to overload methods, and the basics of common JavaScript bindings. This standard format helps to streamline the definitions for common script objects and allows the spec to focus on defining the unique aspects of the requirements.
 
* '''Interface definitions:''' [http://dev.w3.org/2006/webapi/WebIDL/ Web IDL]. This document defines an interface definition language (IDL) that is useful for describing interfaces intended to be implemented in web browsers. It defines how to write the IDL blocks, how to overload methods, and the basics of common JavaScript bindings. This standard format helps to streamline the definitions for common script objects and allows the spec to focus on defining the unique aspects of the requirements.
* '''Formatting tool: '''[http://pimpmyspec.net/ Pimp My Spec]. This irreverently named tool defines special markup elements that are processed by a Python script that adds the proper spec numbering, cross references, and table of contents. It's magic! [http://hg.gsnedders.com/anolis/raw-file/tip/example.src.html This page] demonstrates use of the prescribed markup elements.
+
* '''Formatting tool: '''[[Anolis]]. This irreverently named tool defines special markup elements that are processed by a Python script that adds the proper spec numbering, cross references, and table of contents. It's magic! [http://hg.gsnedders.com/anolis/raw-file/tip/example.src.html This page] demonstrates use of the prescribed markup elements.
 
* '''Also useful:''' [http://www.w3.org/TR/html-design-principles/ HTML Design Principles]. It's always good to keep the Big Picture in mind.
 
* '''Also useful:''' [http://www.w3.org/TR/html-design-principles/ HTML Design Principles]. It's always good to keep the Big Picture in mind.
 +
 +
== More ==
 +
 +
Here are some links to sources that might be helpful in expanding the above:
 +
 +
* http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-July/032361.html
 +
 +
== Legacy DOM-style ==
 +
 +
The old DOM specifications had a particular style of defining methods and attributes that is strongly discouraged (the separation of method definition from arguments, exceptions, and return value). Unfortunately ReSpec.js uses this style by default (consider using [[Anolis]]). E.g. the [http://www.w3.org/TR/DOM-Level-3-Core/core.html#Document3-adoptNode <code>adoptNode()</code> method] in DOM Level 3 Core does not define which exception would be thrown first and more importantently it is not clear at all what the processing model is as you have to piece it together from various independent pieces of information. Therefore please follow the patterns outlined above as demonstrated by the [http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-adoptnode <code>adoptNode()</code> method] in DOM.
 +
 +
[[Category:Specification editing]]

Latest revision as of 14:50, 6 November 2013

About this document

This document explains basic guidelines for writing a specification for the web platform. HTML and DOM among others follow these guidelines. You are encouraged to study those specifications and follow the patterns and style they establish.

See also Advice for people writing specs.

Audience

This document focuses primarily on specifications aimed at browser implementors. The content of these specifications focuses on API calls that browsers implement and the required browser behavior under all possible cases. Specifications for user interface design and for authored content are not addressed here.

Organization

Each specification includes these top-level sections:

  • Introduction — Gives an overview of the technology defined.
  • Conformance — References RFC 2119 and/or explains how conformance is determined in this specification. Lists the conformance classes that apply to this specification. See http://www.w3.org/TR/qaframe-spec/
  • Terminology — Defines where the terms in the specification originate from and sometimes provides a few novel definitions that do not fit within the main prose of the specification.
  • … content …
  • References
  • Acknowledgments

See e.g. Progress Events and XMLHttpRequest.

Content

Content in a specification falls into two general categories: normative and informative. Normative content includes the requirements and definitions and uses verbs such as must, should, and may. Refer to RFC 2119 for their definitions. If a normative statement uses the verb must (and applies to UAs), the browser implementor should be able to write a test case for it. (If it is not possible to write a test case for the statement, do not use the word must.) The verb "may" merely grants permission and is used rarely. Do not use "may not". Normal lowercase is preferred for readability.

Informative content is everything that is not normative. Informative (non-normative) content includes diagrams and code examples—very useful content, but supportive in nature to the actual browser requirements. Informative content must not include RFC 2119 keywords (use words like "can" or "is" instead).

See also Hixie's blog post on the subject: http://ln.hixie.ch/?start=1140242962&count=1

Definitions

Elements, attributes, members of an object, algorithms, are all marked up using the dfn element. The title attribute of the element or its contents if there is no such attribute represents the name used for cross references. These are the conventions:

  • Interfaces: InterfaceName; e.g. interface Document { …
  • Interface members: dom-InterfaceName-attributeOrMethodName; e.g. the URL</code> attribute must …
  • Events: event-eventname
  • Elements: elementname
  • Attributes: attr-elementname-attributename
  • Concepts: concept-word; e.g. <dfn title=concept-node>node</dfn>

You reference a definition using either the span or code element. Anolis takes care of linking back to the definition.

IDL

The structure of an API is defined using Web IDL. An interface can be defined as follows:

<pre class=idl>interface <dfn>ProcessingInstruction</dfn> : <span>Node</span> {
  readonly attribute DOMString <span title=dom-ProcessingInstruction-target>target</span>;
           attribute DOMString <span title=dom-ProcessingInstruction-data>data</span>;
};</pre>

(See also ProcessingInstruction in DOM Core.)

The interface members are described both in a non-normative and a normative way. Non-normatively using a <dl class=domintro> construct. Normatively as described in the following sections.

Defining an attribute

A readonly attribute is defined as follows:

The <dfn><code>novel</code></dfn> attribute must return "<code>Hear the Wind Sing</code>".

An attribute whose value can be set is typically defined as two distinct definitions:

The <dfn><code>pinball</code></dfn> attribute must return its value. Initially its value must be null.
Setting the <code>pinball</code> attribute must set its value to the given value.

Sometimes it gets a little bit more complicated and you need to use steps:

<p>Setting the <code>pinball</code> attribute must run these steps:
<ol>
 <li><p>If the <span>readonly flag</span> is set, terminate these steps.
 <li><p>Set the attribute to the given value.
</ol>

Keep this in mind:

  • Include requirements for setting the attribute to any value, not just to valid values. For example, an attribute that requires a float value must also prescribe what the browser does when the value is set to values of Infinity, zero, or NaN (not a number), unless that is already defined by IDL.
  • You can omit the "must" statement here for each step (as in the example above) if your conformance section says it is implied. The HTML spec, for example, says in its conformance section that "Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm".
  • Attributes that return objects should always return the same object. Having an attribute that returns a new object each time it is accessed can make seemingly innocuous scripts perform a lot of expensive operations — for example, if such an attribute is used in a loop, every single iteration of the loop would involve allocating and initialising a new object.

Defining a method

Defining a simple method can be done as follows:

The <dfn><code>timesTwo(<var>num</var>)</code></dfn> method must return <var>num</var> × 2.

If the method is more complicated (or you feel like being more verbose) a list of steps can be used instead:

<p>The <dfn><code>add(<var>num1</var>, <var>num2</var>)</code></dfn> method must run these steps:
<ol>
 <li><p>Let <var>result</var> be <var>num1</var> + <var>num2</var>.
 <li><p>Return <var>result</var>.
</ol>

Using steps helps implementors and QA making sure they have covered all the requirements.

Dealing with exceptions

Sometimes a method needs to throw an exception:

<p>The <dfn><code>isCuteAnimal(<var>animal</var>)</code></dfn> method must run these steps:
<ol>
 <li><p>If <var>animal</var> is not "<code>cat</code>",
 <span data-anolis-spec=dom title=concept-throw>throw</span> an "<code>UnknownAnimalError</code>" exception
 and terminate these steps.

It is important to state whether the algorithm should be terminate when the exception is thrown or not; in some cases, an algorithm will continue even after an exception is thrown (e.g. to do some cleanup).

Events

Just dispatching an event is rather trivial:

<li><p><span data-anolis-spec=dom>Fire an event</span> named <code>tralala</code>
at the <span data-anolis-spec=dom title=concept-document>document</span>.

However, often the situation is more complicated. Events may need to be dispatched from within a task (see asynchronous below), listeners for the event can change the environment, events may need their own event object (to expose certain attributes), etc.

Asynchronous events

In certain circumstances the method returns "early", but the algorithm keeps going. This is done to ensure that the user interface does not lock up while running potentially expensive operations:

<li><p>Return, but continue running these steps asynchronouusly.
<li><p>Let <var>visible</var> be the number of cute animals in the user's surroundings.
<li><p>If <var>visible</var> is zero, terminate these steps.
<li><p><span data-anolis-spec=html>Queue</span> a <span data-anolis-spec=html>task</span>
to <span data-anolis-spec=dom>fire an event</span> named <code>spotted</code> at the
<span>context object</span>.

To still let the developer know of the effects of the method an event has to be dispatched. This is done using the "fire an event" concept from the DOM. As it cannot be dispatched synchronously since it happens in an operation running asynchronously from JavaScript's perspective, the event loop has to be used (queuing a task).

"Cancelable" events

Certain events are dispatched as part of an operation and allow the developer to choose whether to continue running the operation. These are often referred to as "cancelable events" (although actually the operation is cancelable). You can integrate these as follows:

<li><p><span data-anolis-spec=dom>Fire an event</span> named <code>hanginthere</code> 
at the <span>context object</span>.
<li><p>If the event's <span>canceled flag</span> is set, terminate these steps.
<li><p>… eat all the things …

Events implementing their own interface

Often events are not just about notification, but also carry additional information. To make that work you will need to define your own event interface.

<pre class=idl>[Constructor(DOMString <var>type</var>, optional <span>PonyEventInit</span> <var>eventInitDict</var>)]
interface <dfn>PonyEvent</dfn> : <span data-anolis-spec=dom>Event</span> {
  readonly attribute DOMString <span title=dom-PonyEvent-hairColor>hairColor</span>;
};

dictionary <dfn>PonyEventInit</dfn> {
  DOMString hairColor;
};</pre>

<p>The <dfn title=dom-PonyEvent-hairColor><code>hairColor</code></dfn> attribute must
return the value it was initialized to. When an 
<span data-anolis-spec=dom title=concept-event>event</span> is created it must be
initialized to "<code>rainbow</code>".

Defining the constructor is "magically" taken care of by the constructing events chapter of DOM. Dispatching an event implementing its own interface requires a bit more wording as well. See the "fire a progress event named e" for an example.

Event handler attributes

HTML defines event handlers. Introducing these on objects upon which events are dispatched is common practice. Excluding markup, the IDL for adding a "colorchange" event's handler would be:

  attribute EventHandler oncolorchange;

In prose you use the following language (replacing "Pony" with the name of the interface and "colorchange" with the name of the event):

<p>The following are the <span data-anolis-spec=html>event handlers</span> (and their corresponding 
<span data-anolis-spec=html title="event handler event type">event handler event types</span>) that must 
be supported on objects implementing the <code>Pony</code> interface:

<table>
 <thead>
  <tr>
   <th><span data-anolis-spec=html title="event handler">event handler</span>
   <th><span data-anolis-spec=html>event handler event type</span>
 <tbody>
  <tr>
   <td><dfn title="event-colorchange"><code>oncolorchange</code></dfn>
   <td><code>colorchange</code>
…

Callbacks

<p>The <dfn><code>getInspiration(<var>callback</var>)</code></dfn> method must run these steps:
<ol>
 <li><p>Return, but continue running these steps asynchronously.
 <li><p>Let <var>result</var> be the result of running <span>magic</span>.
 <li><p><span data-anolis-spec=html>Queue</span> a <span data-anolis-spec=html>task</span>
 to invoke <var>callback</var> with <var>result</var> as argument and <span>context object</span>
 as <span>callback this value</span>.

Note that here we define the object the method was invoked upon as the callback this value. If you want the callback object itself to the this value you do not have to specify it, as that is the default.

When dealing with the event loop (task queuing) the task source also needs to be clear. See <canvas>'s toBlob() method for an example.

References

The following references provide useful information about specification writing and tools to aid the process of writing and producing a specification.

  • Language and terminology: RFC2119. This document explains when and why to use those spec'y verbs like must, may, and should.
  • Interface definitions: Web IDL. This document defines an interface definition language (IDL) that is useful for describing interfaces intended to be implemented in web browsers. It defines how to write the IDL blocks, how to overload methods, and the basics of common JavaScript bindings. This standard format helps to streamline the definitions for common script objects and allows the spec to focus on defining the unique aspects of the requirements.
  • Formatting tool: Anolis. This irreverently named tool defines special markup elements that are processed by a Python script that adds the proper spec numbering, cross references, and table of contents. It's magic! This page demonstrates use of the prescribed markup elements.
  • Also useful: HTML Design Principles. It's always good to keep the Big Picture in mind.

More

Here are some links to sources that might be helpful in expanding the above:

Legacy DOM-style

The old DOM specifications had a particular style of defining methods and attributes that is strongly discouraged (the separation of method definition from arguments, exceptions, and return value). Unfortunately ReSpec.js uses this style by default (consider using Anolis). E.g. the adoptNode() method in DOM Level 3 Core does not define which exception would be thrown first and more importantently it is not clear at all what the processing model is as you have to piece it together from various independent pieces of information. Therefore please follow the patterns outlined above as demonstrated by the adoptNode() method in DOM.