You are currently viewing a snapshot of www.mozilla.org taken on April 21, 2008. Most of this content is highly out of date (some pages haven't been updated since the project began in 1998) and exists for historical purposes only. If there are any pages on this archive site that you think should be added back to www.mozilla.org, please file a bug.



The Clipboard

Feature Owner
Mike Pinkerton

Overview

This document describes the Clipboard Service, used to transfer data with mozilla and other applications via the native OS clipboard and assumes the reader is familiar with the Transferable object discussed in the previous document. The meat of this API can be found in nsIClipboard.

Using The Clipboard

There are two key routines in the clipboard API, one for placing the data in a given transferable on the clipboard, the other for retreiving the data from the clipboard based on the flavors registered in the transferable:

/**
 * Given a transferable, set the data on the native clipboard
 *
 * @param  aTransferable The transferable
 * @param  anOwner The owner of the transferable
 * @result NS_Ok if no errors
 */

void setData ( in nsITransferable aTransferable, in nsIClipboardOwner anOwner) ;

/**
 * Given a transferable, get the clipboard data.
 *
 * @param  aTransferable The transferable
 * @result NS_Ok if no errors
 */

void getData ( in nsITransferable aTransferable ) ;

When calling getData(), only data corresponding to registered flavors will be copied from the native clipboard into the transferable. Any other data that may be on the native clipboard will be ignored.

Note that setData() may not actually place the data on the clipboard, but may place a "promise" which will be fulfilled when the data is actually requested. As a result, there is another API call to ensure that the data physically makes it to the clipboard:

/**
 * Some platforms support deferred notification for putting data on the clipboard
 * This method forces the data onto the clipboard in its various formats
 *
 * @result NS_OK if successful.
 */

void forceDataToClipboard ( ) ;

forceDataToClipboard() should be called before the application terminates, otherwise the promise can never be fulfilled and the clipboard will be empty after the application finishes shutting down. If there is nothing on the clipboard, this is a no-op and is harmless to call.

To round out the API, there is one more routine which can be used to determine if there is any applicable information on the clipboard, for example, to enable the "Paste" menu item only if there is data of the appropriate flavor on the clipboard.

/**
 * This provides a way to give correct UI feedback about, for instance, a paste
 * should be allowed. It does _NOT_ actually retreive the data and should be a very
 * inexpensive call. All it does is check if there is data on the clipboard matching
 * any of the flavors in the given list.
 *
 * @aFlavorList - nsISupportsString's in a nsISupportsArray (for JavaScript).
 * @outResult - if data is present matching one of
 * @result NS_OK if successful.
 */

boolean hasDataMatchingFlavors ( in nsISupportsArray aFlavorList )  ;

hasDataMatchingFlavors() should be an inexpensive call and does not actually transfer any data to or from the clipboard. As a result, it can be called whenever needed without too much worry about performance.

Example

Here's an example of how you get the data off the clipboard. Notice that this snippet can understand two distinct data flavors, and prefers HTML over plain text. When the data is copied

// 1. get the clipboard service
var clipboard = Components.classes["component://netscape/widget/clipboard"].getService();
if ( clipboard ) clipboard = clipboard.QueryInterface(Components.interfaces.nsIClipboard);

// 2. create the transferable
var trans = Components.classes["component://netscape/widget/transferable"].createInstance();
if ( trans )
  trans = trans.QueryInterface(Components.interfaces.nsITransferable);

if ( trans && clipboard ) {

  // 3. register the data flavors you want, highest fidelity first!
  trans.addDataFlavor("text/html");
  trans.addDataFlavor("text/unicode");

  // 4. get transferable from clipboard
  clipboard.getData ( trans );

  // 5. ask transferable for the best flavor. Need to create new JS
  //    objects for the out params.
  var dataObj = new Object();
  var bestFlavor = new Object();
  var len = new Object();
  trans.getAnyTransferData ( bestFlavor, dataObj, len );
  if ( bestFlavor.value == "text/html" ||
        bestFlavor.value == "text/unicode" ) {
    if ( dataObj )
      dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsWString);
    if ( dataObj ) {
      // ...do something with the data. remember len is in bytes, not chars
      var id = dataObj.data.substring(0, len.value / 2);
    }
  }
}