NOTE: The current preferred location for bug reports is the GitHub issue tracker.
Bug 569 - Changed HTMLPropertyCollection to always return PropertyNodeLists when accessed by name. Make itemprop=about only work for RDF on the linking elements. vCard output support. Minor tweaks to microdata. Editorial fixes.
Changed HTMLPropertyCollection to always return PropertyNodeLists when access...
Status: RESOLVED INTENTIONAL
Product: Validator.nu
Classification: Unclassified
Component: General
HEAD
All All
: P2 normal
Assigned To: Henri Sivonen
http://svn.whatwg.org/webapps/source?...
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2009-05-27 14:36 CEST by Henri Sivonen
Modified: 2009-05-27 14:53 CEST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Henri Sivonen 2009-05-27 14:36:23 CEST
Index: source
===================================================================
--- source	(revision 3104)
+++ source	(revision 3105)
@@ -1162,6 +1162,11 @@
   those that have the Unicode property "White_Space". <a
   href="#refsUNICODE">[UNICODE]</a></p>
 
+  <p>The <dfn>alphanumeric ASCII characters</dfn> are those in the
+  ranges U+0030 DIGIT ZERO .. U+0039 DIGIT NINE, U+0041 LATIN CAPITAL
+  LETTER A .. U+005A LATIN CAPITAL LETTER Z, U+0061 LATIN SMALL LETTER
+  A .. U+007A LATIN SMALL LETTER Z.</p>
+
   <p>Some of the micro-parsers described below follow the pattern of
   having an <var title="">input</var> variable that holds the string
   being parsed, and having a <var title="">position</var> variable
@@ -6453,15 +6458,16 @@
   <pre class="idl">[Callable=<span title="dom-HTMLPropertyCollection-namedItem">namedItem</span>]
 interface <dfn>HTMLPropertyCollection</dfn> {
   readonly attribute unsigned long <span title="dom-HTMLPropertyCollection-length">length</span>;
-  readonly attribute <span>DOMStringList</span> <span title="dom-HTMLPropertyCollection-names">names</span>;
   [IndexGetter] <span>HTMLElement</span> <span title="dom-HTMLPropertyCollection-item">item</span>(in unsigned long index);
-  [NameGetter] Object <span title="dom-HTMLPropertyCollection-namedItem">namedItem</span>(in DOMString name);
+
+  readonly attribute <span>DOMStringList</span> <span title="dom-HTMLPropertyCollection-names">names</span>;
+  [NameGetter] <span>PropertyNodeList</span> <span title="dom-HTMLPropertyCollection-namedItem">namedItem</span>(in DOMString name);
 };
 
-typedef sequence&lt;DOMString> <dfn>DOMStringArray</dfn>;
+typedef sequence&lt;any> <dfn>PropertyValueArray</dfn>;
 
 interface <dfn>PropertyNodeList</dfn> : <span>NodeList</span> {
-          attribute <span>DOMStringArray</span> <span title="dom-PropertyNodeList-content">content</span>;
+          attribute <span>PropertyValueArray</span> <span title="dom-PropertyNodeList-content">content</span>;
 };</pre>
 
   <dl class="domintro">
@@ -6488,9 +6494,7 @@
    <dt><var title="">collection</var>[<var title="">name</var>]</dt>
    <dt><var title="">collection</var>(<var title="">name</var>)</dt>
    <dd>
-    <p>Returns the element with that adds the property named <var title="">name</var> from the collection.</p>
-    <p>If there are multiple matching elements, then a <code>PropertyNodeList</code> object containing all those elements is returned.</p>
-    <p>Returns null if no element adds the property named <var title="">name</var>.</p>
+    <p>Returns a <code>PropertyNodeList</code> object containing any elements that add a property named <var title="">name</var>.</p>
    </dd>
 
    <dt><var title="">propertyNodeList</var> . <var title="">content</var></dt>
@@ -6519,15 +6523,6 @@
   collection</span>.</p>
 
   <p>The <dfn
-  title="dom-HTMLPropertyCollection-names"><code>names</code></dfn>
-  attribute must return a live <code>DOMStringList</code> object
-  giving the <span>property names</span> of all the elements
-  <span>represented by the collection</span>, listed in <span>tree
-  order</span>, but with duplicates removed, leaving only the first
-  occurrence of each name. The same object must be returned each
-  time.</p>
-
-  <p>The <dfn
   title="dom-HTMLPropertyCollection-item"><code>item(<var
   title="">index</var>)</code></dfn> method must return the <var
   title="">index</var>th node in the collection. If there is no <var
@@ -6539,32 +6534,25 @@
   <span>represented by the collection</span>.</p>
 
   <p>The <dfn
-  title="dom-HTMLPropertyCollection-namedItem"><code>namedItem(<var
-  title="">name</var>)</code></dfn> method must act according to the
-  following algorithm:</p>
-
-  <ol>
-
-   <li>If, at the time the method is called, there is exactly one node
-   in the collection that has a <span title="property names">property
-   name</span> equal to <var title="">name</var>, then return that
-   node and stop the algorithm.</li>
-
-   <li>Otherwise, if there are no nodes in the collection that have a
-   <span title="property names">property name</span> equal to <var
-   title="">name</var>, then return null and stop the algorithm.</li>
-
-   <li>Otherwise, create a <code>PropertyNodeList</code> object
-   representing a live view of the <code>HTMLPropertyCollection</code>
-   object, further filtered so that the only nodes in the
-   <code>RadioNodeList</code> object are those that have a <span
-   title="property names">property name</span> equal to <var
-   title="">name</var>. The nodes in the <code>PropertyNodeList</code>
-   object must be sorted in <span>tree order</span>.</li>
-
-   <li>Return that <code>PropertyNodeList</code> object.</li>
+  title="dom-HTMLPropertyCollection-names"><code>names</code></dfn>
+  attribute must return a live <code>DOMStringList</code> object
+  giving the <span>property names</span> of all the elements
+  <span>represented by the collection</span>, listed in <span>tree
+  order</span>, but with duplicates removed, leaving only the first
+  occurrence of each name. The same object must be returned each
+  time.</p>
 
-  </ol>
+  <p>The <dfn
+  title="dom-HTMLPropertyCollection-namedItem"><code>namedItem(<var
+  title="">name</var>)</code></dfn> method must return a
+  <code>PropertyNodeList</code> object representing a live view of the
+  <code>HTMLPropertyCollection</code> object, further filtered so that
+  the only nodes in the <code>RadioNodeList</code> object are those
+  that have a <span title="property names">property name</span> equal
+  to <var title="">name</var>. The nodes in the
+  <code>PropertyNodeList</code> object must be sorted in <span>tree
+  order</span>, and the same object must be returned each time a
+  particular <var title="">name</var> is queried.</p>
 
   <hr>
 
@@ -46188,7 +46176,8 @@
   attribute returns an <code>HTMLPropertyCollection</code>, which can
   be enumerated to go through each element that adds one or more
   properties to the item. It can also be indexed by name, which will
-  return the property with that name (if there is just one).</p>
+  return an object with a list of the elements that add properties
+  with that name.</p>
 
   <p>Each element that adds a property also has a <code
   title="dom-content">content</code> DOM attribute that returns its
@@ -46201,40 +46190,35 @@
    "net.example.name" property from that item.</p>
 
    <pre>var user = getItems('net.example.user')[0];
-alert('Hello ' + user.properties['net.example.name'].content + '!');</pre>
+alert('Hello ' + user.properties['net.example.name'][0].content + '!');</pre>
 
   </div>
 
-  <p>When an item has multiple properties with the same name, the
-  <code>HTMLPropertyCollection</code> returns a
-  <code>PropertyNodeList</code> object with all those properties
-  instead of returning just one. The <code>PropertyNodeList</code>
-  object can be used to obtained all the values at once using
-  <em>its</em> <code
+  <p>The <code>HTMLPropertyCollection</code> object, when indexed by
+  name in this way, actually returns a <code>PropertyNodeList</code>
+  object with all the matching properties. The
+  <code>PropertyNodeList</code> object can be used to obtained all the
+  values at once using <em>its</em> <code
   title="dom-PropertyNodeList-content">content</code> attribute, which
   returns an array of all the values.</p>
 
   <div class="example">
 
    <p>In an earlier example, a "com.example.feline" item had two
-   "com.example.color" values. This script looks up such items and
-   then lists all their values. Because it doesn't know ahead of time
-   if the item has zero, one, or more colors, it checks whether the
-   value returned from the <code>HTMLPropertyCollection</code> is a
-   <code>PropertyNodeList</code> (multiple colors), just a regular
-   element (one color), or null (no colors) before using it.</p>
+   "com.example.color" values. This script looks up the first such
+   item and then lists all its values.</p>
 
    <pre>var cat = getItems('com.example.feline')[0];
-var colors = cat.properties['com.example.color'];
+var colors = cat.properties['com.example.color'].content;
 var result;
-if (!colors) {
+if (colors.length == 0) {
   result = 'Color unknown.';
-} else if (colors instanceof PropertyNodeList) {
-  result = 'Colors:';
-  for (var i = 0; i &lt; colors.content.length; i += 1)
-    result += ' ' + colors.content[i];
+} else if (colors.length == 1) {
+  result = 'Color: ' + colors[0];
 } else {
-  result = 'Color: ' + colors.content;
+  result = 'Colors:';
+  for (var i = 0; i &lt; colors.length; i += 1)
+    result += ' ' + colors[i];
 }</pre>
 
   </div>
@@ -46551,12 +46535,16 @@
 
   </dl>
 
+  <p>The <dfn>URL property elements</dfn> are the <code>a</code>,
+  <code>area</code>, <code>audio</code>, <code>embed</code>,
+  <code>iframe</code>, <code>img</code>, <code>link</code>,
+  <code>object</code>, <code>source</code>, and <code>video</code>
+  elements.</p>
+
   <p>If a property's <span title="concept-property-value">value</span>
   is an <span>absolute URL</span>, the property must be specified
-  using an <code>a</code>, <code>area</code>, <code>audio</code>,
-  <code>embed</code>, <code>iframe</code>, <code>img</code>,
-  <code>link</code>, <code>object</code>, <code>source</code>, or
-  <code>video</code> element.</p>
+  using an <span title="URL property elements">URL property
+  element</span>.</p>
 
 
 
@@ -46802,54 +46790,6 @@
 
       </ul>
 
-      <p>User agents must run the following steps to convert the <code
-      title="md-vcard-fn">fn</code> property's <span
-      title="concept-property-value">value</span> into an implied
-      <code title="md-vcard-n-family-name">family-name</code>/<code
-      title="md-vcard-n-given-name">given-name</code> pair:</p>
-
-      <ol>
-
-       <li><p>Let <var title="">value</var> be the <code
-       title="md-vcard-fn">fn</code> property's <span
-       title="concept-property-value">value</span>.</p></li>
-
-       <li><p><span title="split a string on spaces">Split <var
-       title="">value</var> on spaces</span>, and let <var
-       title="">part one</var> be the first resulting token, and <var
-       title="">part two</var> be the second.</p></li>
-
-       <li><p>If the last character of <var title="">part one</var> is
-       a U+002C COMMA character (,), then remove that character from
-       <var title="">part one</var> and let the implied <code
-       title="md-vcard-n-family-name">family-name</code> be <var
-       title="">part one</var> and the implied <code
-       title="md-vcard-n-given-name">given-name</code> be <var
-       title="">part two</var>.</p></li>
-
-       <li><p>Otherwise, if <var title="">part two</var> is two
-       Unicode code-points long and its second character is a U+002E
-       FULL STOP character (.), then let the implied <code
-       title="md-vcard-n-family-name">family-name</code> be <var
-       title="">part one</var> and the implied <code
-       title="md-vcard-n-given-name">given-name</code> be the first
-       character of <var title="">part two</var>.</p></li>
-
-       <li><p>Otherwise, if <var title="">part two</var> is one
-       Unicode code-point long, then let the implied <code
-       title="md-vcard-n-family-name">family-name</code> be <var
-       title="">part one</var> and the implied <code
-       title="md-vcard-n-given-name">given-name</code> be <var
-       title="">part two</var>.</p></li>
-
-       <li><p>Otherwise, let the implied <code
-       title="md-vcard-n-family-name">family-name</code> be <var
-       title="">part two</var> and the implied <code
-       title="md-vcard-n-given-name">given-name</code> be <var
-       title="">part one</var>.</p></li>
-
-      </ol>
-
      </dd>
 
     </dl>
@@ -48044,7 +47984,7 @@
   (&lt;span itemprop="organization-unit">Los Angeles Division&lt;/span>)
  &lt;/p>
  &lt;p>
-  &lt;span class="adr" item>
+  &lt;span itempror="adr" item>
    &lt;span itemprop="street-address">10201 W. Pico Blvd.&lt;/span>&lt;br>
    &lt;span itemprop="locality">Los Angeles&lt;/span>,
    &lt;span itemprop="region">CA&lt;/span>
@@ -48128,7 +48068,7 @@
   <dl>
 
 
-   <dt><dfn title="md-vcevent-attach"><code>attach</code></dfn></dt>
+   <dt><dfn title="md-vevent-attach"><code>attach</code></dfn></dt>
 
    <dd>
 
@@ -48138,7 +48078,7 @@
     an <span>absolute URL</span>.</p>
 
     <p>Any number of properties with the name <code
-    title="md-vcard-attach">attach</code> may be present within each
+    title="md-vevent-attach">attach</code> may be present within each
     <span title="concept-item">item</span> with the type <code
     title="md-vevent">vevent</code>.</p>
 
@@ -48787,9 +48727,8 @@
     }
     for (var nameIndex = 0; nameIndex &lt; prop.itemprop.length; nameIndex += 1) {
       var name = prop.itemprop[nameIndex];
-      if (!name.match(':') && !name.match('.')) {
+      if (!name.match(':') && !name.match('.'))
         calendar += name.toUpperCase() + parameters + ':' + value + '\r\n';
-      }
     }
   }
   calendar += 'END:VEVENT\r\nEND:VCALENDAR\r\n';
@@ -49710,6 +49649,10 @@
 
   <h3>Converting HTML to other formats</h3>
 
+  <p>In all these algorithms, unless otherwise stated, operations that
+  iterate over a series of elements (whether items, properties, or
+  otherwise) must do so in <span>tree order</span>.</p>
+
 
   <h4>JSON</h4>
 
@@ -50004,12 +49947,12 @@
    title="concept-item-corresponding">corresponding item</span> is
    <var title="">item</var>, exactly one has a <span title="property
    names">property name</span> equal to the string "<code
-   title="">about</code>", and the <span
-   title="concept-property-value">property value</span> of that
-   element is an <span>absolute URL</span>, let <var
-   title="">subject</var> be that <span>absolute
-   URL</span>. Otherwise, let <var title="">subject</var> be a new
-   blank node.</p></li>
+   title="">about</code>", and that element is a <span title="URL
+   property elements">URL property element</span>, let <var
+   title="">subject</var> be the <span
+   title="concept-property-value">value</span> of that
+   property. Otherwise, let <var title="">subject</var> be a new blank
+   node.</p></li>
 
    <li>
 
@@ -50064,14 +50007,11 @@
      reserialise it, check if the <time> was valid, check if it had a
      .date, a .time, a .timezone, etc. -->
 
-     <li><p>Otherwise, if <var title="">element</var> is not an
-     <code>a</code>, <code>area</code>, <code>audio</code>,
-     <code>embed</code>, <code>iframe</code>, <code>img</code>,
-     <code>link</code>, <code>object</code>, <code>source</code>, or
-     <code>video</code> element, let <var title="">value</var> be a
-     plain literal, with the language information set from the
-     <span>language</span> of the element, if it is not
-     unknown.</p></li>
+     <li><p>Otherwise, if <var title="">element</var> is not one of
+     the <span>URL property elements</span>, let <var
+     title="">value</var> be a plain literal, with the language
+     information set from the <span>language</span> of the element, if
+     it is not unknown.</p></li>
 
      <li>
 
@@ -50117,7 +50057,735 @@
 
   <h4>vCard</h4>
 
-  <p class="XXX">...</p>
+  <p>Given a node <var title="">node</var> in a <code>Document</code>,
+  a user agent must run the following algorithm to <dfn
+  title="extracting a vCard">extract any <code
+  title="md-vcard">vcard</code> data represented by that
+  node</dfn>:</p>
+
+  <ol>
+
+   <li>
+
+    <p>If <var title="">node</var> is not an element that is an <span
+    title="concept-item">item</span> with the type <code
+    title="md-vcard">vcard</code>, then run these substeps:</p>
+
+    <ol>
+
+     <li><p>If <var title="">node</var> has no parent, then there is
+     no vCard. Abort the algorithm, returning nothing.</p></li>
+
+     <li><p>Let <var title="">node</var> be <var title="">node</var>'s
+     parent.</p></li>
+
+     <li><p>Restart the entire algorithm with the new value of <var
+     title="">node</var>.</p></li>
+
+    </ol>
+
+   </li>
+
+   <li><p>Let <var title="">output</var> be an empty string.</p></li>
+
+   <li><p><span>Add a vCard line</span> with the type "<code
+   title="">BEGIN</code>" and the value "<code title="">VCARD</code>"
+   to <var title="">output</var>.</p></li>
+
+   <li><p><span>Add a vCard line</span> with the type "<code
+   title="">PROFILE</code>" and the value "<code title="">VCARD</code>"
+   to <var title="">output</var>.</p></li>
+
+   <li><p><span>Add a vCard line</span> with the type "<code
+   title="">VERSION</code>" and the value "<code title="">3.0</code>"
+   to <var title="">output</var>.</p></li>
+
+   <li><p><span>Add a vCard line</span> with the type "<code
+   title="">SOURCE</code>" and <span>the document's current
+   address</span> as the value to <var title="">output</var>.</p></li>
+
+   <li><p>If <span>the <code>title</code> element</span> is not null,
+   <span>add a vCard line</span> with the type "<code
+   title="">NAME</code>" and the <code>textContent</code> of <span>the
+   <code>title</code> element</span> as the value to <var
+   title="">output</var>.</p></li>
+
+   <li>
+
+    <p>For each element <var title="">element</var> that has one or
+    more <span>property names</span> and whose <span
+    title="concept-item-corresponding">corresponding item</span> is
+    <var title="">node</var>: for each name <var title="">name</var>
+    in <var title="">element</var>'s <span>property names</span>, run
+    the following substeps:</p>
+
+    <ol>
+
+     <li><p>If <var title="">name</var> is equal to the string
+     "<code title="">about</code>", skip this name.</p></li>
+
+     <li><p>Let <var title="">parameters</var> be an empty set of
+     name-value pairs.</p></li>
+
+     <li>
+
+      <p>Run the appropriate set of substeps from the following
+      list. The steps will set a variable <var title="">value</var>,
+      which is used in the next step.</p>
+
+      <dl>
+
+       <dt>If the property's <span
+       title="concept-property-value">value</span> is an <span
+       title="concept-item">item</span> <var title="">subitem</var>
+       and <var title="">name</var> is <code
+       title="md-vcard-n">n</code></dt>
+
+       <dd>
+
+        <ol>
+
+         <li><p>Let <var title="">n1</var> be the <span
+         title="concept-property-value">value</span> of the first
+         property named <code
+         title="md-vcard-n-family-name">family-name</code> in <var
+         title="">subitem</var>, or the empty string if there is no
+         such property or the property's value is itself an <span
+         title="concept-item">item</span>.</p></li>
+
+         <li><p>Let <var title="">n2</var> be the <span
+         title="concept-property-value">value</span> of the first
+         property named <code
+         title="md-vcard-n-given-name">given-name</code> in <var
+         title="">subitem</var>, or the empty string if there is no
+         such property or the property's value is itself an <span
+         title="concept-item">item</span>.</p></li>
+
+         <li><p>Let <var title="">n3</var> be the <span
+         title="concept-property-value">value</span> of the first
+         property named <code
+         title="md-vcard-n-additional-name">additional-name</code> in
+         <var title="">subitem</var>, or the empty string if there is
+         no such property or the property's value is itself an <span
+         title="concept-item">item</span>.</p></li>
+
+         <li><p>Let <var title="">n4</var> be the <span
+         title="concept-property-value">value</span> of the first
+         property named <code
+         title="md-vcard-n-honorific-prefix">honorific-prefix</code>
+         in <var title="">subitem</var>, or the empty string if there
+         is no such property or the property's value is itself an
+         <span title="concept-item">item</span>.</p></li>
+
+         <li><p>Let <var title="">n5</var> be the <span
+         title="concept-property-value">value</span> of the first
+         property named <code
+         title="md-vcard-n-honorific-suffix">honorific-suffix</code>
+         in <var title="">subitem</var>, or the empty string if there
+         is no such property or the property's value is itself an
+         <span title="concept-item">item</span>.</p></li>
+
+         <li>
+
+          <p>Let <var title="">value</var> be the concatenation of the
+          following, in this order:</p>
+
+          <ol class="brief">
+           <li>The result of <span>escaping the vCard text string</span> <var title="">n1</var></li>
+           <li>A U+003B SEMICOLON character (;)</li>
+           <li>The result of <span>escaping the vCard text string</span> <var title="">n2</var></li>
+           <li>A U+003B SEMICOLON character (;)</li>
+           <li>The result of <span>escaping the vCard text string</span> <var title="">n3</var></li>
+           <li>A U+003B SEMICOLON character (;)</li>
+           <li>The result of <span>escaping the vCard text string</span> <var title="">n4</var></li>
+           <li>A U+003B SEMICOLON character (;)</li>
+           <li>The result of <span>escaping the vCard text string</span> <var title="">n5</var></li>
+          </ol>
+
+         </li>
+
+        </ol>
+
+       </dd>
+
+       <dt>If the property's <span
+       title="concept-property-value">value</span> is an <span
+       title="concept-item">item</span> <var title="">subitem</var>
+       and <var title="">name</var> is <code
+       title="md-vcard-adr">adr</code></dt>
+
+       <dd>
+
+        <ol>
+
+         <li><p>Let <var title="">value</var> be the empty
+         string.</p></li>
+
+         <li><p>Append to <var title="">value</var> the result of
+         <span>collecting vCard subproperties</span> named <code
+         title="md-vcard-adr-post-office-box">post-office-box</code>
+         in <var title="">subitem</var>.</p>
+
+         <li>Append a U+003B SEMICOLON character (;) to <var
+         title="">value</var>.</li>
+
+         <li><p>Append to <var title="">value</var> the result of
+         <span>collecting vCard subproperties</span> named <code
+         title="md-vcard-adr-extended-address">extended-address</code>
+         in <var title="">subitem</var>.</p>
+
+         <li>Append a U+003B SEMICOLON character (;) to <var
+         title="">value</var>.</li>
+
+         <li><p>Append to <var title="">value</var> the result of
+         <span>collecting vCard subproperties</span> named <code
+         title="md-vcard-adr-street-address">street-address</code> in
+         <var title="">subitem</var>.</p>
+
+         <li>Append a U+003B SEMICOLON character (;) to <var
+         title="">value</var>.</li>
+
+         <li><p>Append to <var title="">value</var> the result of
+         <span>collecting the first vCard subproperty</span> named
+         <code title="md-vcard-adr-locality">locality</code> in <var
+         title="">subitem</var>.</p>
+
+         <li>Append a U+003B SEMICOLON character (;) to <var
+         title="">value</var>.</li>
+
+         <li><p>Append to <var title="">value</var> the result of
+         <span>collecting the first vCard subproperty</span> named
+         <code title="md-vcard-adr-region">region</code> in <var
+         title="">subitem</var>.</p>
+
+         <li>Append a U+003B SEMICOLON character (;) to <var
+         title="">value</var>.</li>
+
+         <li><p>Append to <var title="">value</var> the result of
+         <span>collecting the first vCard subproperty</span> named
+         <code title="md-vcard-adr-postal-code">postal-code</code> in
+         <var title="">subitem</var>.</p>
+
+         <li>Append a U+003B SEMICOLON character (;) to <var
+         title="">value</var>.</li>
+
+         <li><p>Append to <var title="">value</var> the result of
+         <span>collecting the first vCard subproperty</span> named
+         <code title="md-vcard-adr-country-name">country-name</code>
+         in <var title="">subitem</var>.</p>
+
+         <li><p>If there is a property named <code
+         title="md-vcard-adr-type">type</code> in <var
+         title="">subitem</var>, and the first such property has a
+         <span title="concept-property-value">value</span> that is not
+         an <span title="concept-item">item</span> and whose value
+         consists only of <span>alphanumeric ASCII characters</span>,
+         then add a parameter named "<code title="">TYPE</code>" whose
+         value is the <span
+         title="concept-property-value">value</span> of that property
+         to <var title="">parameters</var>.</p></li>
+
+        </ol>
+
+       </dd>
+
+       <dt>If the property's <span
+       title="concept-property-value">value</span> is an <span
+       title="concept-item">item</span> <var title="">subitem</var>
+       and <var title="">name</var> is <code
+       title="md-vcard-org">org</code></dt>
+
+       <dd>
+
+        <ol>
+
+         <li><p>Let <var title="">value</var> be the empty
+         string.</p></li>
+
+         <li><p>Append to <var title="">value</var> the result of
+         <span>collecting the first vCard subproperty</span> named
+         <code
+         title="md-vcard-org-organization-name">organization-name</code>
+         in <var title="">subitem</var>.</p>
+
+         <li>
+
+          <p>For each property named <code
+          title="md-vcard-org-organization-unit">organization-unit</code>
+          in <var title="">subitem</var>, run the following steps:</p>
+
+          <ol>
+
+           <li><p>If the <span
+           title="concept-property-value">value</span> of the property
+           is an <span title="concept-item">item</span>, then skip
+           this property.</p></li>
+
+           <li><p>Append a U+003B SEMICOLON character (;) to <var
+           title="">value</var>.</p></li>
+
+           <li><p>Append the result of <span>escaping the vCard text
+           string</span> given by the <span
+           title="concept-property-value">value</span> of the property
+           to <var title="">value</var>.</p></li>
+
+          </ol>
+
+         </li>
+
+        </ol>
+
+       </dd>
+
+       <dt>If the property's <span
+       title="concept-property-value">value</span> is an <span
+       title="concept-item">item</span> <var title="">subitem</var>
+       with the type <code title="md-vcard">vcard</code> and <var
+       title="">name</var> is <code
+       title="md-vcard-agent">agent</code></dt>
+
+       <dd>
+
+        <ol>
+
+         <li><p>Let <var title="">value</var> be the result of
+         <span>escaping the vCard text string</span> obtained from
+         <span>extracting a vCard</span> from the element that
+         represents <var title="">subitem</var>.</p></li>
+
+         <li><p>Add a parameter named "<code title="">VALUE</code>"
+         whose value is "<code title="">VCARD</code>" to <var
+         title="">parameters</var>.</p></li>
+
+        </ol>
+
+       </dd>
+
+       <dt>If the property's <span
+       title="concept-property-value">value</span> is an <span
+       title="concept-item">item</span> and <var title="">name</var>
+       is none of the above</dt>
+
+       <dd>
+
+        <ol>
+
+         <li><p>Let <var title="">value</var> the result of
+         <span>collecting the first vCard subproperty</span> named
+         <code title="">value</code> in <var
+         title="">subitem</var>.</p>
+
+         <li><p>If there is a property named <code
+         title="">type</code> in <var title="">subitem</var>, and the
+         first such property has a <span
+         title="concept-property-value">value</span> that is not an
+         <span title="concept-item">item</span> and whose value
+         consists only of <span>alphanumeric ASCII characters</span>,
+         then add a parameter named "<code title="">TYPE</code>" whose
+         value is the <span
+         title="concept-property-value">value</span> of that property
+         to <var title="">parameters</var>.</p></li>
+
+        </ol>
+
+       </dd>
+
+       <dt>Otherwise (the property's <span
+       title="concept-property-value">value</span> is not an <span
+       title="concept-item">item</span>)</dt>
+
+       <dd>
+
+        <ol>
+
+         <li><p>Let <var title="">value</var> be the property's <span
+         title="concept-property-value">value</span>.</p></li>
+
+         <li><p>If <var title="">element</var> is one of the <span>URL
+         property elements</span>, add a parameter with the name "<code
+         title="">VALUE</code>" and the value "<code
+         title="">URI</code>" to <var
+         title="">parameters</var>.</p></li>
+
+         <li><p>Otherwise, if <var title="">element</var> is a
+         <code>time</code> element and the <var title="">value</var> is
+         a <span>valid date string</span>, add a parameter with the name
+         "<code title="">VALUE</code>" and the value "<code
+         title="">DATE</code>" to <var
+         title="">parameters</var>.</p></li>
+
+         <li><p>Otherwise, if <var title="">element</var> is a
+         <code>time</code> element and the <var title="">value</var> is
+         a <span>valid global date and time string</span>, add a
+         parameter with the name "<code title="">VALUE</code>" and the
+         value "<code title="">DATE-TIME</code>" to <var
+         title="">parameters</var>.</p></li>
+
+         <li><p>Prefix every U+005C REVERSE SOLIDUS character (\) in
+         <var title="">value</var> with another U+005C REVERSE SOLIDUS
+         character (\).</p></li>
+
+         <li><p>Prefix every U+002C COMMA character (,) in <var
+         title="">value</var> with a U+005C REVERSE SOLIDUS character
+         (\).</p></li>
+
+         <li><p>Unless <var title="">name</var> is <code
+         title="md-vcard-geo">geo</code>, prefix every U+003B SEMICOLON
+         character (;) in <var title="">value</var> with a U+005C
+         REVERSE SOLIDUS character (\).</p></li>
+
+         <li><p>Replace every U+000D CARRIAGE RETURN U+000A LINE FEED
+         character pair (CRLF) in <var title="">value</var> with a U+005C REVERSE
+         SOLIDUS character (\) followed by a U+006E LATIN SMALL LETTER
+         N.</p></li>
+
+         <li><p>Replace every remaining U+000D CARRIAGE RETURN (CR) or
+         U+000A LINE FEED (LF) character in <var title="">value</var>
+         with a U+005C REVERSE SOLIDUS character (\) followed by a U+006E
+         LATIN SMALL LETTER N.</p></li>
+
+        </ol>
+
+       </dd>
+
+      </dl>
+
+     </li>
+
+     <li>
+
+      <p><span>Add a vCard line</span> with the type <var
+      title="">name</var>, the parameters <var
+      title="">parameters</var>, and the value <var
+      title="">value</var> to <var title="">output</var>.</p>
+
+     </li>
+
+    </ol>
+
+   </li>
+
+   <li>
+
+    <p>If there is no property named <code title="md-vcard-n">n</code>
+    whose <span title="concept-item-corresponding">corresponding
+    item</span> is <var title="">node</var>, then run the following
+    substeps:</p>
+
+    <ol>
+
+     <li><p>If there is no property named <code
+     title="md-vcard-fn">fn</code> whose <span
+     title="concept-item-corresponding">corresponding item</span> is
+     <var title="">node</var>, then skip the remainder of these
+     substeps.</p></li>
+
+     <li><p>If the first property named <code
+     title="md-vcard-fn">fn</code> whose <span
+     title="concept-item-corresponding">corresponding item</span> is
+     <var title="">node</var> has a <span
+     title="concept-property-value">value</span> that is an <span
+     title="concept-item">item</span>, then skip the remainder of
+     these substeps.</p></li>
+
+     <li><p>Let <var title="">fn</var> be the <span
+     title="concept-property-value">value</span> of the first property
+     named <code title="md-vcard-fn">fn</code> whose <span
+     title="concept-item-corresponding">corresponding item</span> is
+     <var title="">node</var>.</p></li>
+
+     <li><p>If there is a property named <code
+     title="md-vcard-org">org</code> whose <span
+     title="concept-item-corresponding">corresponding item</span> is
+     <var title="">node</var>, and the <span
+     title="concept-property-value">value</span> of the first such
+     property is equal to <var title="">fn</var> (and is not an <span
+     title="concept-item">item</span>), then <span>add a vCard
+     line</span> with the type "<code title="">N</code>" whose value
+     is four U+003B SEMICOLON characters ("<code
+     title="">;;;;</code>") to <var title="">output</var>. Then, skip
+     the remainder of these substeps.</p></li>
+
+     <li><p>If the <span title="space character">space
+     characters</span> in <var title="">fn</var>, if any, are not all
+     contiguous, then skip the remainder of these substeps.</p></li>
+
+     <li><p><span title="split a string on spaces">Split <var
+     title="">fn</var> on spaces</span>, and let <var title="">part
+     one</var> be the first resulting token, and <var title="">part
+     two</var> be the second, if any, or the empty string if there is
+     no second token. (There cannot be three, given the previous
+     step.)</p></li>
+
+     <li>
+
+      <p>If the last character of <var title="">part one</var> is a
+      U+002C COMMA character (,), then remove that character from <var
+      title="">part one</var> and <span>add a vCard line</span> with
+      the type "<code title="">N</code>" whose value is the
+      concatenation of the following strings:</p>
+
+      <ol class="brief">
+       <li>The result of <span>escaping the vCard text string</span> <var title="">part one</var></li>
+       <li>A U+003B SEMICOLON character (;)</li>
+       <li>The result of <span>escaping the vCard text string</span> <var title="">part two</var></li>
+       <li>Three U+003B SEMICOLON characters (;)</li>
+      </ol>
+
+      <p>Then, skip the remainder of these substeps.</p>
+
+     </li>
+
+     <li>
+
+      <p>If <var title="">part two</var> is two Unicode code-points
+      long and its second character is a U+002E FULL STOP character
+      (.), then <span>add a vCard line</span> with the type "<code
+      title="">N</code>" whose value is the concatenation of the
+      following strings:</p>
+
+      <ol class="brief">
+       <li>The result of <span>escaping the vCard text string</span> <var title="">part one</var></li>
+       <li>A U+003B SEMICOLON character (;)</li>
+       <li>The result of <span>escaping the vCard text string</span> consisting of the first character of <var title="">part two</var></li>
+       <li>Three U+003B SEMICOLON characters (;)</li>
+      </ol>
+
+      <p>Then, skip the remainder of these substeps.</p>
+
+     </li>
+
+     <li>
+
+      <p>If <var title="">part two</var> is one Unicode code-point
+      long, then <span>add a vCard line</span> with the type "<code
+      title="">N</code>" whose value is the concatenation of the
+      following strings:</p>
+
+      <ol class="brief">
+       <li>The result of <span>escaping the vCard text string</span> <var title="">part one</var></li>
+       <li>A U+003B SEMICOLON character (;)</li>
+       <li>The result of <span>escaping the vCard text string</span> <var title="">part two</var></li>
+       <li>Three U+003B SEMICOLON characters (;)</li>
+      </ol>
+
+      <p>Then, skip the remainder of these substeps.</p>
+
+     </li>
+
+     <li>
+
+      <p><span>Add a vCard line</span> with the type "<code
+      title="">N</code>" whose value is the concatenation of the
+      following strings:</p>
+
+      <ol class="brief">
+       <li>The result of <span>escaping the vCard text string</span> <var title="">part two</var></li>
+       <li>A U+003B SEMICOLON character (;)</li>
+       <li>The result of <span>escaping the vCard text string</span> <var title="">part one</var></li>
+       <li>Three U+003B SEMICOLON characters (;)</li>
+      </ol>
+
+     </li>
+
+    </ol>
+
+   </li>
+
+   <li><p><span>Add a vCard line</span> with the type "<code
+   title="">END</code>" and the value "<code title="">VCARD</code>"
+   to <var title="">output</var>.</p></li>
+
+  </ol>
+
+  <p>When the above algorithm says that the user agent is to <dfn>add
+  a vCard line</dfn> consisting of a type <var title="">type</var>,
+  optionally some parameters, and a value <var title="">value</var> to
+  a string <var title="">output</var>, it must run the following
+  steps:</p>
+
+  <ol>
+
+   <li><p>Let <var title="">line</var> be an empty string.
+
+   <li><p>Append <var title="">type</var>, <span>converted to
+   uppercase</span>, to <var title="">line</var>.</p></li>
+
+   <li>
+
+    <p>If there are any parameters, then for each parameter, in the
+    order that they were added, run these substeps:</p>
+
+    <ol>
+
+     <li><p>Append a U+003B SEMICOLON character (;) to <var
+     title="">line</var>.</p></li>
+
+     <li><p>Append the parameter's name to <var
+     title="">line</var>.</p></li>
+
+     <li><p>Append a U+003D EQUALS SIGN character (=) to <var
+     title="">line</var>.</p></li>
+
+     <li><p>Append the parameter's value to <var
+     title="">line</var>.</p></li>
+
+    </ol>
+
+   </li>
+
+   <li><p>Append a U+003A COLON character (:) to <var
+   title="">line</var>.</p></li>
+
+   <li><p>Append <var title="">value</var> to <var
+   title="">line</var>.</p></li>
+
+   <li><p>Let <var title="">maximum length</var> be 75.</p></li>
+
+   <li>
+
+    <p>If and while <var title="">line</var> is longer than <var
+    title="">maximum length</var> Unicode code points long, run the
+    following substeps:</p>
+
+    <ol>
+
+     <li><p>Append the first <var title="">maximum length</var>
+     Unicode code points of <var title="">line</var> to <var
+     title="">output</var>.</p></li>
+
+     <li><p>Remove the first <var title="">maximum length</var>
+     Unicode code points from <var title="">line</var>.</p></li>
+
+     <li><p>Append a U+000D CARRIAGE RETURN character (CR) to <var
+     title="">output</var>.</p></li>
+
+     <li><p>Append a U+000A LINE FEED character (LF) to <var
+     title="">output</var>.</p></li>
+
+     <li><p>Append a U+0020 SPACE character to <var
+     title="">output</var>.</p></li>
+
+     <li><p>Let <var title="">maximum length</var> be 74.</p></li>
+
+    </ol>
+
+   </li>
+
+   <li><p>Append (what remains of) <var title="">line</var> to <var
+   title="">output</var>.</p></li>
+
+   <li><p>Append a U+000D CARRIAGE RETURN character (CR) to <var
+   title="">output</var>.</p></li>
+
+   <li><p>Append a U+000A LINE FEED character (LF) to <var
+   title="">output</var>.</p></li>
+
+  </ol>
+
+  <p>When the steps above require the user agent to obtain the result
+  of <dfn>collecting vCard subproperties</dfn> named <var
+  title="">subname</var> in <var title="">subitem</var>, the user
+  agent must run the following steps:</p>
+
+  <ol>
+
+   <li><p>Let <var title="">value</var> be the empty string.</p></li>
+
+   <li>
+
+    <p>For each property named <var title="">subname</var> in the item
+    <var title="">subitem</var>, run the following substeps:</p>
+
+    <ol>
+
+     <li><p>If the <span title="concept-property-value">value</span>
+     of the property is itself an <span
+     title="concept-item">item</span>, then skip this
+     property.</p></li>
+
+     <li><p>If this is not the first property named <var
+     title="">subname</var> in <var title="">subitem</var> (ignoring
+     any that were skipped by the previous step), then append a U+002C
+     COMMA character (,) to <var title="">value</var>.</p></li>
+
+     <li><p>Append the result of <span>escaping the vCard text
+     string</span> given by the <span
+     title="concept-property-value">value</span> of the property to
+     <var title="">value</var>.</p></li>
+
+    </ol>
+
+   </li>
+
+   <li><p>Return <var title="">value</var>.</p></li>
+
+  </ol>
+
+  <p>When the steps above require the user agent to obtain the result
+  of <dfn>collecting the first vCard subproperty</dfn> named <var
+  title="">subname</var> in <var title="">subitem</var>, the user
+  agent must run the following steps:</p>
+
+  <ol>
+
+   <li><p>If there are no properties named <var title="">subname</var>
+   in <var title="">subitem</var>, then abort these substeps,
+   returning the empty string.</p></li>
+
+   <li><p>If the <span title="concept-property-value">value</span> of
+   the first property named <var title="">subname</var> in <var
+   title="">subitem</var> is an <span
+   title="concept-item">item</span>, then abort these substeps,
+   returning the empty string.</p></li>
+
+   <li><p>Return the result of <span>escaping the vCard text
+   string</span> given by the <span
+   title="concept-property-value">value</span> of the first property
+   named <var title="">subname</var> in <var
+   title="">subitem</var>.</p></li>
+
+  </ol>
+
+  <p>When the above algorithms say the user agent is to <dfn
+  title="escaping the vCard text string">escape the vCard text
+  string</dfn> <var title="">value</var>, the user agent must use the
+  following steps:</p>
+
+  <ol>
+
+   <li><p>Prefix every U+005C REVERSE SOLIDUS character (\) in <var
+   title="">value</var> with another U+005C REVERSE SOLIDUS character
+   (\).</p></li>
+
+   <li><p>Prefix every U+002C COMMA character (,) in <var
+   title="">value</var> with a U+005C REVERSE SOLIDUS character
+   (\).</p></li>
+
+   <li><p>Prefix every U+003B SEMICOLON character (;) in <var
+   title="">value</var> with a U+005C REVERSE SOLIDUS character
+   (\).</p></li>
+
+   <li><p>Replace every U+000D CARRIAGE RETURN U+000A LINE FEED
+   character pair (CRLF) in <var title="">value</var> with a U+005C
+   REVERSE SOLIDUS character (\) followed by a U+006E LATIN SMALL
+   LETTER N.</p></li>
+
+   <li><p>Replace every remaining U+000D CARRIAGE RETURN (CR) or
+   U+000A LINE FEED (LF) character in <var title="">value</var> with a
+   U+005C REVERSE SOLIDUS character (\) followed by a U+006E LATIN
+   SMALL LETTER N.</p></li>
+
+   <li><p>Return the mutated <var title="">value</var>.</p></li>
+
+  </ol>
+
+  <p class="note">This algorithm can generate invalid vCard output, if
+  the input does not conform to the rules described for the <code
+  title="md-vcard">vcard</code> <span>predefined type</span> and <span
+  title="predefined property name">predefined property
+  names</span>.</p> <!-- of course since vcard doesn't define error
+  handling, this is somewhat problematic. -->
 
 
   <h4>iCalendar</h4>