Microsummaries: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
(remove references to feeds, which the microsummary service will now leave up to the livemark service; definition -> generator; no more generator ID attribute, and misc other changes)
Line 5: Line 5:
Microsummaries are better than page titles at labeling bookmarks because they give users quicker access to the most interesting information behind a bookmark and provide sites with a way to notify users of updates and entice them to revisit the site.
Microsummaries are better than page titles at labeling bookmarks because they give users quicker access to the most interesting information behind a bookmark and provide sites with a way to notify users of updates and entice them to revisit the site.


For an overview of microsummaries and their integration into Firefox, see [http://www.melez.com/mozilla/microsummaries/walkthrough.html this walkthrough] with screenshots showing major elements.  For detailed information, read the rest of this document.
For a quick overview of microsummaries and their proposed integration into Firefox, see [http://www.melez.com/mozilla/microsummaries/walkthrough.html this walkthrough] with screenshots showing major elements.  For detailed information, read the rest of this document.
 


== Examples ==
== Examples ==
Line 22: Line 21:
* '''insert your bright idea here'''.
* '''insert your bright idea here'''.


== Microsummary Generators ==


== Microsummary Definitions ==
Microsummaries can either be provided by the page being summarized or generated by processing an XSLT stylesheet against the page.  In the latter case, the XSLT stylesheet and the page(s) to which it applies are provided by a microsummary generator.


Microsummaries can either be extracted from an RSS/Atom feed or generated by processing an XSLT stylesheet against the page being summarizedIn the latter case, the XSLT stylesheet and the pages to which it applies are provided by a microsummary definition.
A microsummary generator is a set of instructions for generating microsummaries.  Generators are expressed via an XML dialect with the namespace '''http://www.mozilla.org/microsummaries/0.1'''A generator consists of a <generator> tag containing the following attributes and child elements:


A microsummary definition is a set of instructions for generating microsummaries.  Definitions are expressed via an XML dialect with the namespace '''http://www.mozilla.org/microsummaries/0.1'''.  A definition consists of a <definition> tag containing the following attributes and child elements:
* a '''name''' attribute that identifies the generator to users, f.e. '''Latest BBC Headline''';
 
* a '''<pages>''' child element with one or more <include>/<exclude> child elements containing regular expressions that identify the URIs to which the generator applies; URIs are excluded by default and must be explicitly included for a generator to apply to them;
* an '''id''' attribute that uniquely identifies the definition; the recommended format for the attribute is @[author]/[site]/[name], where [author] identifies the developer of the definition, [site] identifies the site to which the definition applies, and [name] describes the definition, for example: '''@mozilla.org/bbc.co.uk/latest-headline''';
* a '''name''' attribute that identifies the definition to users, f.e. '''Latest BBC Headline''';
* a '''<pages>''' child element with one or more <include>/<exclude> child elements containing regular expressions that identify the URIs to which the definition applies; URIs are excluded by default and must be explicitly included for a definition to apply to them;
* a '''<template>''' element containing an XSLT stylesheet which generates a microsummary from a page.  The stylesheet can generate not only text but also HTML, graphics, and other rich content.
* a '''<template>''' element containing an XSLT stylesheet which generates a microsummary from a page.  The stylesheet can generate not only text but also HTML, graphics, and other rich content.


[Should a definition also contain an update interval or timeout specifying how often to update microsummaries or when to update them next?  How should this interval/timeout be specified?  Is it worth enabling complex specifications like "update every five minutes from 9:30am-4pm EST and not at all otherwise" for an NYSE stock quote?]
[Should a generator also contain an update interval or timeout specifying how often to update microsummaries or when to update them next?  How should this interval/timeout be specified?  Is it worth enabling complex specifications like "update every five minutes from 9:30am-4pm EST and not at all otherwise" for an NYSE stock quote?]


Here is an example microsummary definition:
Here is an example microsummary generator:


   <definition xmlns="http://www.mozilla.org/microsummaries/0.1"
   <?xml version="1.0" encoding="UTF-8"?>
              id="@mozilla.org/bbc.co.uk/latest-headline;1"
  <generator xmlns="http://www.mozilla.org/microsummaries/0.1" name="Yahoo! Finance Stock Quote">
              name="Latest BBC Headline">
 
     <pages>
     <pages>
 
       <include>http://finance.yahoo.com/q\?.*s=[a-zA-Z]+</include>
       <include>^http://(www\.)?bbc\.co\.uk/$</include>
 
     </pages>
     </pages>
 
     <template>
     <template>
 
       <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
       <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    version="1.0">
 
         <xsl:output method="text"/>
         <xsl:output method="text"/>
 
         <xsl:template match="/">
         <xsl:template match="/">
           <xsl:text>BBC: </xsl:text>
          <xsl:value-of select="substring-before(substring-after(string(id('yfncsubtit')/tbody/tr/td[1]/b), '('), ')')"/>
           <xsl:value-of select="normalize-space(id('rightColTable')/div/table[1]/tbody/tr/td[2]/table[2]/tbody/tr/td[3]/div[1]/a)"/>
           <xsl:text>: </xsl:text>
           <xsl:value-of select="id('yfncsumtab')/tbody/tr/td/table[3]/tbody/tr[2]/td[1]/table/tbody/tr/td/table/tbody/tr[1]/td[2]/big/b"/>
         </xsl:template>
         </xsl:template>
 
       </xsl:transform>
       </xsl:transform>
 
     </template>
     </template>
 
   </generator>
   </definition>


== Specifying Microsummaries ==
== Specifying Microsummaries ==
Line 72: Line 58:
=== Firefox ===
=== Firefox ===


Firefox should be able to specify microsummaries via bundled microsummary definitions for popular sites.
Firefox should be able to specify microsummaries via bundled microsummary generators for popular sites.


=== Users ===
=== Users ===


Users should be able to specify microsummaries via a microsummary builder feature in Firefox that lets users extract text snippets from a rendered page via simple methods like drag-and-drop and string them together along with arbitrary text into a microsummary.  Implementation of a microsummary builder is deferred to the future.
Users should be able to specify microsummaries via a microsummary builder feature in Firefox that lets users extract text snippets from a rendered page via simple methods like drag-and-drop and string them together along with arbitrary text into a microsummary.  Implementation of a microsummary builder is currently deferred to the future.


=== Sites ===
=== Sites ===


Sites should be able to specify microsummaries by embedding metadata referencing microsummary definitions or RSS/Atom feeds into pages.  For example, a site might embed one of the following two <link> elements into an HTML page:
Sites should be able to specify microsummaries by embedding metadata referencing microsummary generators into pages.  For example, a site might embed the following <link> element into an HTML page:


   <link rel="microsummary" type="application/x.microsummary+xml" href="/index-microsummary.xml">
   <link rel="microsummary" type="application/x.microsummary+xml" href="/index-microsummary.xml">
  <link rel="microsummary" type="application/x.atom+xml" href="/index-microsummary.xml">


Or it might embed one of the following two XML processing instructions into an XML document:
Or it might embed the following two XML processing instruction into an XML document:


   <?microsummary type="application/x.microsummary+xml" href="/index-microsummary.xml"?>
   <?microsummary type="application/x.microsummary+xml" href="/index-microsummary.xml"?>
  <?microsummary type="application/x.atom+xml" href="/index-microsummary.xml"?>


For RSS/Atom feed-based microsummaries, Firefox will use profiles of the RSS and Atom specifications to extract microsummaries via the following rules:
[If a page points to a microsummary generator whose <pages> list does not include the page, should the microsummary service ignore the <pages> list and apply the generator to the page anyway?]
 
* if the rss:channel/atom:feed element contains no items/entries, the microsummary is the value of the rss:description/atom:subtitle element;
* if the rss:channel/atom:feed element contains one item/entry, the microsummary is the value of the item's/entry's rss:description/atom:summary element;
* if the rss:channel/atom:feed element contains more than one item/entry:
** if the items/entries are dated via rss:pubDate/atom:published/atom:updated elements, the microsummary is the value of the rss:description/atom:summary element of the most recent item/entry;
** if the items/entries are not dated, the microsummary is the value of the rss:description/atom:summary element of the first item/entry.
 
[If a page points to a microsummary definition whose <pages> list does not include the page, should the microsummary service ignore the <pages> list and apply the definition to the page anyway?]


=== Independent Developers ===
=== Independent Developers ===


Independent developers should be able to specify microsummaries by packaging microsummary definitions into addons that users can acquire from a directory of such addons similar to the extensions/themes directory at addons.mozilla.org.  Microsummary definitions packaged in this way are called microsummary support packs.  Developers should be able to package multiple definitions into a single pack.  Packs should be automatically updatable.
Independent developers should be able to specify microsummaries by distributing generators that users can acquire from a directory similar to the search engines directory at addons.mozilla.org.  Generators should have simple search engine-like installation and management UI and update themselves automatically.
 
[Should packs use the extensions model, i.e. packaged as XPIs and subject to origin restrictions, or should they use the search engines model, i.e. no origin restrictions?
 
If packs use the extensions model, the XPIs might contain a definitions.xml file, a directory of such files, or both, i.e.:
 
  XPI
    install.rdf
    [definitions.xml]
    [definitions/
      *.xml]
 
]
 


== Back-end Implementation ==
== Back-end Implementation ==
Line 121: Line 84:
The microsummary service updates microsummaries when they expire and provides an API for front-end code to access microsummaries and be notified when they get updated.
The microsummary service updates microsummaries when they expire and provides an API for front-end code to access microsummaries and be notified when they get updated.


Like the livemarks service, the microsummary service checks every 15 seconds for microsummaries that need updating.  If a microsummary needs updating, the service downloads the necessary content (i.e. the page or its feed), processes it to generate an updated microsummary, and stores the updated microsummary in the datastore.
Like the livemarks service, the microsummary service checks every 15 seconds for microsummaries that need updating.  If a microsummary needs updating, the service downloads the necessary content (i.e. the page, the generator), processes it to generate an updated microsummary, and stores the updated microsummary in the datastore.


=== nsIMicrosummaryService ===
=== nsIMicrosummaryService ===
Line 129: Line 92:
   {
   {
       /**
       /**
       * Retrieves a list of available microsummaries for a given URI.
       * Install the microsummary generator from the resource at the supplied URI.
       * The aDoc argument is optional.  If present, this method will use it
      * Callable by content via the addMicrosummaryGenerator() sidebar method.
       * to generate the microsummaries. Otherwise, microsummary content
      *
       * may not be available, in which case this method will return microsummary
      * @param  generatorURI
       * objects without content.  Callers who receive such objects should use
      *          the URI of the resource providing the generator
       * the microsummary definition name in lieu of microsummary content.
      *
      */
      void addGenerator(in nsIURI generatorURI);
 
      /**
      * Get the set of microsummaries available for a given page. The set
       * might change after this method returns, since this method will trigger
      * an asynchronous load of the page in question (if it isn't already loaded)
       * to see if it references any page-specific microsummaries.
      *
      * If the caller passes a bookmark ID, and one of the microsummaries
       * is the current one for the bookmark, this method will retrieve content
      * from the datastore for that microsummary, which is useful when callers
       * want to display a list of microsummaries for a page that isn't loaded,
       * and they want to display the actual content of the selected microsummary
      * immediately (rather than after the content is asynchronously loaded).
      *
      * @param  pageURI
      *          the URI of the page for which to retrieve available microsummaries
      *
      * @param  bookmarkID (optional)
      *          the ID of the bookmark for which this method is being called
      *
      * @returns an nsIMicrosummarySet of nsIMicrosummaries for the given page
       *
       *
      * @param aURI  the URI of the microsummarized page
      * @param aDoc  the document to which the URI refers
      * @returns an enumerator of nsIMicrosummary objects
       */
       */
       nsISimpleEnumerator getMicrosummaries(in nsIURI aURI, in nsIDOMNode aDoc);
       nsIMicrosummarySet getMicrosummaries(in nsIURI pageURI,
                                          in nsISupports bookmarkID);
    
    
       /**
       /**
       * Manually updates the microsummary for a given URI.  The aDoc argument
       * Get the current microsummary for the given bookmark.
      * is optional.  If present, this method will use it to update the microsummary
      * Otherwise it will download the document asynchronously.
       *
       *
       * @param aURI  the URI of the microsummarized page
       * @param   bookmarkID
       * @param aDoc  the document to which the URI refers
      *          the bookmark for which to get the current microsummary
      *
       * @returns the current microsummary for the bookmark, or null
      *          if the bookmark does not have a current microsummary
       *
       *
       */
       */
       void updateMicrosummary(in nsIURI aURI, in nsIDOMNode aDoc);
       nsIMicrosummary getMicrosummary(in nsISupports bookmarkID);
    
    
       /**
       /**
       * Sets the microsummary for a given URI.
       * Set the current microsummary for the given bookmark.
      *
      * @param  bookmarkID
      *          the bookmark for which to set the current microsummary
       *
       *
       * @param aURI          the URI of the microsummarized page
       * @param   microsummary
       * @param aMicrosummary  the microsummary to set
       *         the microsummary to set as the current one
       *
       *
       */
       */
       void setMicrosummary(in nsIURI aURI, in nsIMicrosummary aMicrosummary);
       void setMicrosummary(in nsISupports bookmarkID,
                          in nsIMicrosummary microsummary);
    
    
       /**
       /**
       * Removes the microsummary for a given URI.
       * Remove the current microsummary for the given bookmark.
       *
       *
       * @param aURI          the URI of the microsummarized page
       * @param   bookmarkID
      *          the bookmark for which to remove the current microsummary
       *
       *
       */
       */
       void removeMicrosummary(in nsIURI aURI);
       void removeMicrosummary(in nsISupports bookmarkID);
    
    
       /**
       /**
       * Adds a microsummary observer.
       * Whether or not the given bookmark has a current microsummary.
      *
      * @param  bookmarkID
      *          the bookmark for which to set the current microsummary
      *
      * @returns a boolean representing whether or not the given bookmark
      *          has a current microsummary
       *
       *
       */
       */
       void addObserver(in nsIAnnotationObserver aObserver);
       boolean hasMicrosummary(in nsISupports bookmarkID);
    
    
       /**
       /**
       * Removes a microsummary observer previously registered by addObserver.
       * Whether or not the given microsummary is the current microsummary
      * for the given bookmark.
      *
      * @param  bookmarkID
      *          the bookmark to check
      *
      * @param  microsummary
      *          the microsummary to check
      *
      * @returns whether or not the microsummary is the current one
      *          for the bookmark
       *
       *
       */
       */
       void removeObserver(in nsIAnnotationObserver aObserver);
       boolean isMicrosummary(in nsISupports bookmarkID,
                            in nsIMicrosummary microsummary);
   };
   };


=== nsIMicrosummaryObserver ===
=== nsIMicrosummaryObserver ===


   [scriptable, uuid(de8ac63a-3867-4dad-a631-ba1d8869d733)]
   [scriptable, uuid(cb284a83-1ca5-4000-9841-ce345ce84915)]
   interface nsIMicrosummaryObserver : nsISupports
   interface nsIMicrosummaryObserver : nsISupports
   {
   {
       /**
       /**
       * Called when the microsummary service starts updating a microsummary.
       * Called when an observed microsummary updates its content.
      * Since an observer might watch multiple microsummaries at the same time,
      * the microsummary whose content has been updated gets passed
      * to this handler.
      * XXX Should this be onContentUpdated?
       *
       *
       * @param aURI  the URI of the microsummarized page
       * @param microsummary
      *        the microsummary whose content has just been updated
       *
       *
       */
       */
       void onStartUpdate(in nsIURI aURI);
       void onContentLoaded(in nsIMicrosummary microsummary);
    
    
       /**
       /**
       * Called when the microsummary service stops updating a microsummary.
       * Called when an element is appended to a microsummary set.
      * XXX Should this be in a separate nsICollectionObserver interface?
       *
       *
       * @param aURI  the URI of the microsummarized page
       * @param microsummary
      *        the microsummary that has just been appended to the set
       *
       *
       */
       */
       void onStopUpdate(in nsIURI aURI);
       void onElementAppended(in nsIMicrosummary microsummary);
   };
   };


Line 210: Line 224:
   interface nsIMicrosummary : nsISupports
   interface nsIMicrosummary : nsISupports
   {
   {
       // for microsummaries specified via a bundled or installed definition,
       // the URI of the page being summarized
      // the nsIMicrosummaryDefinition for this microsummary
       readonly attribute nsIURI pageURI;
       readonly attribute nsIMicrosummaryDefinition definition;
    
    
       // for microsummaries specified via a <link> element pointing to
       // The URI of the generator that generates this microsummary.
       // a microsummary definition or RSS/Atom feed, the URI of the resource
      readonly attribute nsIURI generatorURI;
       readonly attribute nsIURI uri;
 
      // The generator that generates this microsummary.
      // Since generators can be remote resources, this may not always be available.
      attribute nsIMicrosummaryGenerator generator;
 
      // The content of the microsummary.
      // Since generators and pages can be remote resources, and we need them
      // to generate the content, this may not always be available.
      readonly attribute AString content;
 
      /**
      * Add a microsummary observer to this microsummary.
      *
      * @param observer
      *        the microsummary observer to add
      *
      */
       void addObserver(in nsIMicrosummaryObserver observer);
 
      /**
      * Remove a microsummary observer from this microsummary.
      *
      * @param observer
      *        the microsummary observer to remove
      *
      */
      void removeObserver(in nsIMicrosummaryObserver observer);
 
      /**
      * Update the microsummary, first loading its generator and page content
      * as necessary.  If you want know when a microsummary finishes updating,
      * add an observer before calling this method.
      *
      */
      void update();
  };
 
=== nsIMicrosummarySet ===
 
  [scriptable, uuid(7111e88d-fecd-4b17-b7a9-1fa74e23153f)]
  interface nsIMicrosummarySet : nsISupports
  {
      /**
      * Add a microsummary observer to this microsummary set.  Adding an observer
      * to a set is the equivalent of adding it to each constituent microsummary.
      *
      * @param observer
      *        the microsummary observer to add
      *
      */
       void addObserver(in nsIMicrosummaryObserver observer);
    
    
       // the URI of the page being summarized
       /**
      // XXX Should this be the ID of the page in the history datastore?
      * Remove a microsummary observer from this microsummary.
       readonly attribute nsIURI page;
      *
      * @param observer
      *        the microsummary observer to remove
      *
      */
       void removeObserver(in nsIMicrosummaryObserver observer);
    
    
       // the content of the microsummary
       /**
       readonly attribute nsIDOMNode content;
      * Retrieve a enumerator of microsummaries in the set.
      *
      * @returns an enumerator of nsIMicrosummary objects
      *
      */
       nsISimpleEnumerator Enumerate();
   };
   };


=== nsIMicrosummaryDefinition ===
=== nsIMicrosummaryGenerator ===


   [scriptable, uuid(ff3eba15-81de-4c24-bfcf-c8180dc3c00a)]
   [scriptable, uuid(ff3eba15-81de-4c24-bfcf-c8180dc3c00a)]
   interface nsIMicrosummaryDefinition : nsISupports
   interface nsIMicrosummaryGenerator : nsISupports
   {
   {
       // the unique identifier for this microsummary definition;
       // An arbitrary descriptive name for this microsummary generator.
      // corresponds to the 'id' attribute of the <definition> element
       readonly attribute AUTF8String name;
       readonly attribute string id;
    
    
       // the user-friendly name for this microsummary definition;
       // The canonical location and unique identifier of the generator.
       // corresponds to the 'name' attribute of the <definition> element
      // It tells us where the generator comes from and where to go for updates.
       readonly attribute string name;
      // For generators referenced by web pages via <link> tags, this URI
      // is the one specified by the tag.  For generators installed by users,
      // this URI is the remote location from which we installed the generator.
      // For generators bundled with the browser, this URI is a reference
       // to the latest version of this generator available on Mozilla Add-ons.
       readonly attribute nsIURI uri;
    
    
       // the XSLT stysheet by which we generate the microsummary;
       // Whether or not this generator needs page content to generate
       // corresponds to the <template> child of the <definition> element
      // a microsummary. Microsummaries generated by XSLT templates need page
       readonly attribute nsIDOMNode template;
      // content, while those which represent the actual microsummary content
      // do not.
      readonly attribute boolean needsPageContent;
 
       /**
      * Generate a microsummary by processing the generator template
      * against the page content.  If a generator doesn't need content,
      * pass null as the parameter to this method.
      *
      * XXX In the future, this should support returning rich text content,
      * so perhaps we should make it return a DOM node now and have the caller
      * convert that to text if it doesn't support rich content.
      *
      * @param  pageContent
      *          the content of the page being summarized
      * @returns the text result of processing the template
      *
      */
       AString generateMicrosummary(in nsIDOMNode aPageContent);
   };
   };


=== Datastore ===
=== Datastore ===


The microsummary service stores microsummaries and their meta-data as annotations in the annotations datastore via the annotation service.  Microsummary annotations include:
In Firefox 2 the microsummary service stores microsummaries and their meta-data as properties of the RDF resources that represent bookmarks in the bookmarks data source.  In Firefox 3 the service stores the same date as annotations in the annotations datastore via the annotation service.  Microsummary data includes:


* microsummary/content: the microsummary content (i.e. what Firefox displays to users);
* bookmarks/generatedTitle: the content of the microsummary (i.e. what Firefox displays to users);
* microsummary/id: for microsummaries specified by bundled or installed definitions, the unique identifier of the microsummary definition;
* microsummary/generatorURI: the canonical source of the generator;
* microsummary/uri: for microsummaries specified by <link rel="microsummary"> elements embedded in page headers, the URI of the resource identified by the <link> element.
* microsummary/expiration: the time in microseconds since the epoch at which the microsummary will expire.
* microsummary/expiration: the time in microseconds since the epoch at which the microsummary will expire.


Line 261: Line 355:
=== Bookmark Properties Dialog ===
=== Bookmark Properties Dialog ===


The bookmark properties dialog lets the user choose to display a microsummary for the bookmark.  If multiple microsummaries are available, the dialog lets users choose between them.  The dialog retrieves microsummaries via nsIMicrosummaryService.getMicrosummariesForURI() and updates the datastore per the user's selection via nsIMicrosummaryService.setMicrosummary() and nsIMicrosummaryService.removeMicrosummary().
The bookmark properties dialog lets the user choose to display a microsummary for the bookmark.  If multiple microsummaries are available, the dialog lets users choose between them.  The dialog retrieves microsummaries via nsIMicrosummaryService.getMicrosummaries() and updates the datastore per the user's selection via nsIMicrosummaryService.setMicrosummary() and nsIMicrosummaryService.removeMicrosummary().


=== Bookmarks Toolbar ===
=== Bookmarks Toolbar ===


When a microsummary is set for a bookmarked URI, the bookmarks toolbar displays the microsummary instead of the page title as the label of the bookmark.  When the microsummary service updates the microsummary, the bookmarks toolbar updates the label.  While the microsummary service is in the process of updating the microsummary, the bookmarks toolbar displays some UI indicating that an update is underway (f.e. it replaces the favicon with a throbber for the duration of the update).
When a microsummary is set for a bookmarked URI, the bookmarks toolbar displays the microsummary instead of the page title as the label of the bookmark.  When the microsummary service updates the microsummary, the bookmarks toolbar updates the label.  Once the microsummary service has updated the microsummary, the bookmarks toolbar may display some UI indicating that an update is underway (f.e. it may replace the favicon with a throbber for the duration of the update).


The toolbar displays microsummaries via a template rule that applies only to bookmarks with microsummaries.  The toolbar controller registers itself with the microsummary service as a microsummary observer in order to be notified when a microsummary gets updated.
The toolbar displays microsummaries via a template rule that applies only to bookmarks with microsummaries.  The toolbar controller registers itself with the microsummary service as a microsummary observer in order to be notified when a microsummary gets updated.
[Is the annotation observer interface sufficient for this task?  I.e. is it sufficient for the toolbar controller to merely register itself as an annotation observer of the microsummary/content annotation?  Probably not, since the annotation observer doesn't let you observe that an update to the annotation is underway.]


[The mechanism by which the bookmarks controller identifies and observes microsummary bookmarks should be extensible (i.e. a generic "metadata observer") so that future code (both native and extensions) can register additional bookmark types with metadata whose observation triggers activity.]
[The mechanism by which the bookmarks controller identifies and observes microsummary bookmarks should be extensible (i.e. a generic "metadata observer") so that future code (both native and extensions) can register additional bookmark types with metadata whose observation triggers activity.]


Additional integration points may be defined in the future (f.e. microsummaries might be displayed as tab labels).
Additional integration points may be defined in the future (f.e. microsummaries might be displayed as tab labels).


== Standardization ==
== Standardization ==


The microsummary definition dialect and the use of the <link rel> element to specify microsummaries should be standardized by appropriate bodies.  Appropriate bodies for standardization may include the [http://microformats.org/wiki/Main_Page microformats group] and the WHATWG.
The microsummary generator dialect and the use of the <link rel> element to specify microsummaries should be standardized by appropriate bodies.  Appropriate bodies for standardization may include the [http://microformats.org/wiki/Main_Page microformats group] and the WHATWG.

Revision as of 10:07, 1 May 2006

Introduction

Microsummaries are regularly-updated succinct compilations of the most important information on web pages. They are compact enough to fit in the space available to a bookmark label, provide more useful information about pages than static page titles, and are regularly updated as new information becomes available.

Microsummaries are better than page titles at labeling bookmarks because they give users quicker access to the most interesting information behind a bookmark and provide sites with a way to notify users of updates and entice them to revisit the site.

For a quick overview of microsummaries and their proposed integration into Firefox, see this walkthrough with screenshots showing major elements. For detailed information, read the rest of this document.

Examples

Examples of pages for which microsummaries are useful include:

  • auction items: the item name, the current highest bid, and the time remaining, f.e. Honda Accord - $5000 - 1 minute left;
  • products for sale: the product name, the current price, and whether or not the product is in stock, f.e. Linksys WRT54G - $60 - in stock;
  • news sites: the latest headline, f.e. BBC: Chirac to sign France's job law;
  • "[thing] of the day" pages: today's [thing], f.e. (for Merriam-Webster's word of the day page) flat-hat;
  • stock quotes: the current price of the stock and its movement in the market, f.e. TWX 16.94 + .30;
  • stock portfolios: your current net worth, f.e. net worth: $30k; +$500 today;
  • weather pages: the current forecast, f.e. SF: showers likely;
  • tinderbox: the status of the tree, f.e. 3 tbxn burning;
  • insert your bright idea here.

Microsummary Generators

Microsummaries can either be provided by the page being summarized or generated by processing an XSLT stylesheet against the page. In the latter case, the XSLT stylesheet and the page(s) to which it applies are provided by a microsummary generator.

A microsummary generator is a set of instructions for generating microsummaries. Generators are expressed via an XML dialect with the namespace http://www.mozilla.org/microsummaries/0.1. A generator consists of a <generator> tag containing the following attributes and child elements:

  • a name attribute that identifies the generator to users, f.e. Latest BBC Headline;
  • a <pages> child element with one or more <include>/<exclude> child elements containing regular expressions that identify the URIs to which the generator applies; URIs are excluded by default and must be explicitly included for a generator to apply to them;
  • a <template> element containing an XSLT stylesheet which generates a microsummary from a page. The stylesheet can generate not only text but also HTML, graphics, and other rich content.

[Should a generator also contain an update interval or timeout specifying how often to update microsummaries or when to update them next? How should this interval/timeout be specified? Is it worth enabling complex specifications like "update every five minutes from 9:30am-4pm EST and not at all otherwise" for an NYSE stock quote?]

Here is an example microsummary generator:

 <?xml version="1.0" encoding="UTF-8"?>
 <generator xmlns="http://www.mozilla.org/microsummaries/0.1" name="Yahoo! Finance Stock Quote">
   <pages>
     <include>http://finance.yahoo.com/q\?.*s=[a-zA-Z]+</include>
   </pages>
   <template>
     <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
       <xsl:output method="text"/>
       <xsl:template match="/">
         <xsl:value-of select="substring-before(substring-after(string(id('yfncsubtit')/tbody/tr/td[1]/b), '('), ')')"/>
         <xsl:text>: </xsl:text>
         <xsl:value-of select="id('yfncsumtab')/tbody/tr/td/table[3]/tbody/tr[2]/td[1]/table/tbody/tr/td/table/tbody/tr[1]/td[2]/big/b"/>
       </xsl:template>
     </xsl:transform>
   </template>
 </generator>

Specifying Microsummaries

Firefox, its users, the web sites they visit, and independent developers should all be able to specify microsummaries for pages.

Firefox

Firefox should be able to specify microsummaries via bundled microsummary generators for popular sites.

Users

Users should be able to specify microsummaries via a microsummary builder feature in Firefox that lets users extract text snippets from a rendered page via simple methods like drag-and-drop and string them together along with arbitrary text into a microsummary. Implementation of a microsummary builder is currently deferred to the future.

Sites

Sites should be able to specify microsummaries by embedding metadata referencing microsummary generators into pages. For example, a site might embed the following <link> element into an HTML page:

 <link rel="microsummary" type="application/x.microsummary+xml" href="/index-microsummary.xml">

Or it might embed the following two XML processing instruction into an XML document:

 <?microsummary type="application/x.microsummary+xml" href="/index-microsummary.xml"?>

[If a page points to a microsummary generator whose <pages> list does not include the page, should the microsummary service ignore the <pages> list and apply the generator to the page anyway?]

Independent Developers

Independent developers should be able to specify microsummaries by distributing generators that users can acquire from a directory similar to the search engines directory at addons.mozilla.org. Generators should have simple search engine-like installation and management UI and update themselves automatically.

Back-end Implementation

The microsummary service updates microsummaries when they expire and provides an API for front-end code to access microsummaries and be notified when they get updated.

Like the livemarks service, the microsummary service checks every 15 seconds for microsummaries that need updating. If a microsummary needs updating, the service downloads the necessary content (i.e. the page, the generator), processes it to generate an updated microsummary, and stores the updated microsummary in the datastore.

nsIMicrosummaryService

 [scriptable, uuid(c5e9c390-beb0-4eb4-90ab-529efc817632)]
 interface nsIMicrosummaryService : nsISupports
 {
     /**
      * Install the microsummary generator from the resource at the supplied URI.
      * Callable by content via the addMicrosummaryGenerator() sidebar method.
      *
      * @param   generatorURI
      *          the URI of the resource providing the generator
      *
      */
     void addGenerator(in nsIURI generatorURI);
 
     /**
      * Get the set of microsummaries available for a given page.  The set
      * might change after this method returns, since this method will trigger
      * an asynchronous load of the page in question (if it isn't already loaded)
      * to see if it references any page-specific microsummaries.
      *
      * If the caller passes a bookmark ID, and one of the microsummaries
      * is the current one for the bookmark, this method will retrieve content
      * from the datastore for that microsummary, which is useful when callers
      * want to display a list of microsummaries for a page that isn't loaded,
      * and they want to display the actual content of the selected microsummary
      * immediately (rather than after the content is asynchronously loaded).
      *
      * @param   pageURI
      *          the URI of the page for which to retrieve available microsummaries
      *
      * @param   bookmarkID (optional)
      *          the ID of the bookmark for which this method is being called
      *
      * @returns an nsIMicrosummarySet of nsIMicrosummaries for the given page
      *
      */
     nsIMicrosummarySet getMicrosummaries(in nsIURI pageURI,
                                          in nsISupports bookmarkID);
 
     /**
      * Get the current microsummary for the given bookmark.
      *
      * @param   bookmarkID
      *          the bookmark for which to get the current microsummary
      *
      * @returns the current microsummary for the bookmark, or null
      *          if the bookmark does not have a current microsummary
      *
      */
     nsIMicrosummary getMicrosummary(in nsISupports bookmarkID);
 
     /**
      * Set the current microsummary for the given bookmark.
      *
      * @param   bookmarkID
      *          the bookmark for which to set the current microsummary
      *
      * @param   microsummary
      *          the microsummary to set as the current one
      *
      */
     void setMicrosummary(in nsISupports bookmarkID,
                          in nsIMicrosummary microsummary);
 
     /**
      * Remove the current microsummary for the given bookmark.
      *
      * @param   bookmarkID
      *          the bookmark for which to remove the current microsummary
      *
      */
     void removeMicrosummary(in nsISupports bookmarkID);
 
     /**
      * Whether or not the given bookmark has a current microsummary.
      *
      * @param   bookmarkID
      *          the bookmark for which to set the current microsummary
      *
      * @returns a boolean representing whether or not the given bookmark
      *          has a current microsummary
      *
      */
     boolean hasMicrosummary(in nsISupports bookmarkID);
 
     /**
      * Whether or not the given microsummary is the current microsummary
      * for the given bookmark.
      *
      * @param   bookmarkID
      *          the bookmark to check
      *
      * @param   microsummary
      *          the microsummary to check
      *
      * @returns whether or not the microsummary is the current one
      *          for the bookmark
      *
      */
     boolean isMicrosummary(in nsISupports bookmarkID,
                            in nsIMicrosummary microsummary);
 };

nsIMicrosummaryObserver

 [scriptable, uuid(cb284a83-1ca5-4000-9841-ce345ce84915)]
 interface nsIMicrosummaryObserver : nsISupports
 {
     /**
      * Called when an observed microsummary updates its content.
      * Since an observer might watch multiple microsummaries at the same time,
      * the microsummary whose content has been updated gets passed
      * to this handler.
      * XXX Should this be onContentUpdated?
      *
      * @param microsummary
      *        the microsummary whose content has just been updated
      *
      */
     void onContentLoaded(in nsIMicrosummary microsummary);
 
     /**
      * Called when an element is appended to a microsummary set.
      * XXX Should this be in a separate nsICollectionObserver interface?
      *
      * @param microsummary
      *        the microsummary that has just been appended to the set
      *
      */
     void onElementAppended(in nsIMicrosummary microsummary);
 };

nsIMicrosummary

 [scriptable, uuid(f9d1a73c-e147-46f3-ba61-4f0bd33f5d47)]
 interface nsIMicrosummary : nsISupports
 {
     // the URI of the page being summarized
     readonly attribute nsIURI pageURI;
 
     // The URI of the generator that generates this microsummary.
     readonly attribute nsIURI generatorURI;
 
     // The generator that generates this microsummary.
     // Since generators can be remote resources, this may not always be available.
     attribute nsIMicrosummaryGenerator generator;
 
     // The content of the microsummary.
     // Since generators and pages can be remote resources, and we need them
     // to generate the content, this may not always be available.
     readonly attribute AString content;
 
     /**
      * Add a microsummary observer to this microsummary.
      *
      * @param observer
      *        the microsummary observer to add
      *
      */
     void addObserver(in nsIMicrosummaryObserver observer);
 
     /**
      * Remove a microsummary observer from this microsummary.
      *
      * @param observer
      *        the microsummary observer to remove
      *
      */
     void removeObserver(in nsIMicrosummaryObserver observer);
 
     /**
      * Update the microsummary, first loading its generator and page content
      * as necessary.  If you want know when a microsummary finishes updating,
      * add an observer before calling this method.
      *
      */
     void update();
 };

nsIMicrosummarySet

 [scriptable, uuid(7111e88d-fecd-4b17-b7a9-1fa74e23153f)]
 interface nsIMicrosummarySet : nsISupports
 {
     /**
      * Add a microsummary observer to this microsummary set.  Adding an observer
      * to a set is the equivalent of adding it to each constituent microsummary.
      *
      * @param observer
      *        the microsummary observer to add
      *
      */
     void addObserver(in nsIMicrosummaryObserver observer);
 
     /**
      * Remove a microsummary observer from this microsummary.
      *
      * @param observer
      *        the microsummary observer to remove
      *
      */
     void removeObserver(in nsIMicrosummaryObserver observer);
 
     /**
      * Retrieve a enumerator of microsummaries in the set.
      *
      * @returns an enumerator of nsIMicrosummary objects
      *
      */
     nsISimpleEnumerator Enumerate();
 };

nsIMicrosummaryGenerator

 [scriptable, uuid(ff3eba15-81de-4c24-bfcf-c8180dc3c00a)]
 interface nsIMicrosummaryGenerator : nsISupports
 {
     // An arbitrary descriptive name for this microsummary generator.
     readonly attribute AUTF8String name;
 
     // The canonical location and unique identifier of the generator.
     // It tells us where the generator comes from and where to go for updates.
     // For generators referenced by web pages via <link> tags, this URI
     // is the one specified by the tag.  For generators installed by users,
     // this URI is the remote location from which we installed the generator.
     // For generators bundled with the browser, this URI is a reference
     // to the latest version of this generator available on Mozilla Add-ons.
     readonly attribute nsIURI uri;
 
     // Whether or not this generator needs page content to generate
     // a microsummary. Microsummaries generated by XSLT templates need page
     // content, while those which represent the actual microsummary content
     // do not.
     readonly attribute boolean needsPageContent;
 
     /**
      * Generate a microsummary by processing the generator template
      * against the page content.  If a generator doesn't need content,
      * pass null as the parameter to this method.
      *
      * XXX In the future, this should support returning rich text content,
      * so perhaps we should make it return a DOM node now and have the caller
      * convert that to text if it doesn't support rich content.
      *
      * @param   pageContent
      *          the content of the page being summarized
      * @returns the text result of processing the template
      *
      */
     AString generateMicrosummary(in nsIDOMNode aPageContent);
 };

Datastore

In Firefox 2 the microsummary service stores microsummaries and their meta-data as properties of the RDF resources that represent bookmarks in the bookmarks data source. In Firefox 3 the service stores the same date as annotations in the annotations datastore via the annotation service. Microsummary data includes:

  • bookmarks/generatedTitle: the content of the microsummary (i.e. what Firefox displays to users);
  • microsummary/generatorURI: the canonical source of the generator;
  • microsummary/expiration: the time in microseconds since the epoch at which the microsummary will expire.

Front-end Implementation

The initial integration points are the bookmark properties dialog and the bookmarks toolbar.

Since microsummaries can contain HTML and other unsafe content, they should be inserted into the UI inside untrusted iframes wherever they appear.

Bookmark Properties Dialog

The bookmark properties dialog lets the user choose to display a microsummary for the bookmark. If multiple microsummaries are available, the dialog lets users choose between them. The dialog retrieves microsummaries via nsIMicrosummaryService.getMicrosummaries() and updates the datastore per the user's selection via nsIMicrosummaryService.setMicrosummary() and nsIMicrosummaryService.removeMicrosummary().

Bookmarks Toolbar

When a microsummary is set for a bookmarked URI, the bookmarks toolbar displays the microsummary instead of the page title as the label of the bookmark. When the microsummary service updates the microsummary, the bookmarks toolbar updates the label. Once the microsummary service has updated the microsummary, the bookmarks toolbar may display some UI indicating that an update is underway (f.e. it may replace the favicon with a throbber for the duration of the update).

The toolbar displays microsummaries via a template rule that applies only to bookmarks with microsummaries. The toolbar controller registers itself with the microsummary service as a microsummary observer in order to be notified when a microsummary gets updated.

[The mechanism by which the bookmarks controller identifies and observes microsummary bookmarks should be extensible (i.e. a generic "metadata observer") so that future code (both native and extensions) can register additional bookmark types with metadata whose observation triggers activity.]

Additional integration points may be defined in the future (f.e. microsummaries might be displayed as tab labels).

Standardization

The microsummary generator dialect and the use of the <link rel> element to specify microsummaries should be standardized by appropriate bodies. Appropriate bodies for standardization may include the microformats group and the WHATWG.