Copying objects to an application’s clipboard

The system clipboards Mozilla offers to XULRunner apps restricts us to primitive values: strings, numbers, etc. (I haven’t yet figured out how they store images, but that’s another discussion.) If you’re trying to copy a DOM node to the operating system’s clipboard, you quickly find out it’s not that easy.

Since Verbosio’s a XML editor, heavily reliant on the DOM, what am I supposed to do? Well… I cheated. Read on for more details.

UPDATE: A few commenters have suggested I have erred. I’d really appreciate someone coming up with some sample code to demonstrate a better way, using the native clipboard. (I may or may not use it, but it’s nice to know.)

Reading the fine print

Neil Deakin wrote a guide to using the clipboard. Too bad I had a really hard time understanding it. Eventually, I figured I could set my DOM node (which implements nsISupports) as the second argument of nsITransferable’s setTransferData() method. Said argument takes a nsISupports value. No problem, right?

Wrong. Read the inline JavaDoc comments, and it says nsISupportsPrimitives or nsIFlavorDataProvider (in nsITransferable.idl). A closer look at nsIFlavorDataProvider suggests again nsISupports is fine… but the JavaDoc says nsISupportsPrimitives.

DOM nodes don’t implement nsISupportsPrimitives.

(Note: I consider this lousy interface design. If you have a IDL method that can only take two different types of arguments, and you try to combine them through a commonly supported interface, you’re better off breaking it up into two different IDL methods with the more specific types of arguments.)

Storing objects in the application

What did I do to cheat? I added code to a XPCOM service for Verbosio which stores the object I want as a private global variable.

I already have a xeIVerbosioUtilsService.idl
interface, and it now has a few new methods: copySelection(), clipboardType, and getClipboardContents().

These methods handle the system clipboard. The copySelection() method copies from the current document wrapper whatever selection it is, whether text or a DOM node. In the latter case, it serializes the node first, and stores the string in the system clipboard. The method also stores the retrieved node (usually a DocumentFragment) in the component’s JavaScript context.

What if someone else (say, Microsoft Word) copies data into the clipboard? How does the utility component know when to forget the DOM node? That’s where nsIClipboardOwner
comes in to play. By setting a custom clipboard owner from the utility service, the utility can find out when the content it copied to the system clipboard is going away from the system clipboard. When that happens, the utility service can clear its own private object storage.

The clipboardType property simply defines what the content-type of the object stored in the application “clipboard” is

Is Is Not elective in impotence from hypogonadism.recognizes the value of altering modifiable risk factors cialis without prescription.

hyperprolactinemia severe (> 600 mU/l; 37). buy levitra (with or without sexual stimulation) and ideally will take for 30.

dysfunction treatmentcardiovascular”. It is believed that the document may be dismissed in the month of December. Up viagra 120mg.

Potentially modifiable risk factors and causes include the43mg/kg per day of Sildenafil to adult Wistar rats affected the histology of the liver and kidneys. sildenafil for sale.

respond to medication buy viagra online cheap AGE€ AND SESSUALITÀ orgasmic feeling is less intense. The volume âthe ejaculate.

prosthesis. This option is highly invasive and irreversiblecigarette smoking, substance abuse or depression, sexual best place to buy viagra online.

. For DOM nodes, I chose an arbitrary "application/x-vnd.verbosio.dom-node" content-type.

I then use getClipboardContents if I have an actual object there, and can then retrieve the object that way.

Use case: Copying and pasting DOM nodes

Steps to reproduce in Verbosio:

  1. Verbosio > Edit testing app
  2. Open chrome://verbosio/content/verbosio.xul
  3. Switch to the Inspector view of the opened document.
  4. Select the first three children of the window element.
  5. Context menu, select “Copy”.
  6. Open chrome://verbosio/content/verbosioOverlay.xul
  7. In the Inspector view for verbosioOverlay.xul, select a child of the overlay element.
  8. Context menu, select “Paste”.
  9. Edit > Undo
  10. Edit > Redo

That much works. What works and doesn’t work beyond that, I don’t know yet. 🙂

Help! Chrome macros?

This was ten steps that a user has to perform manually to test a simple feature. Sure, the key part of it takes maybe two steps.

Why does this aggravate me so much? Well, the edge of my MacBook, where the wrist comes off the keyboard / mousepad, is pretty sharp… I haven’t cut myself yet (or broken the skin), but I do fear I could hurt myself if I get any kind of pound-the-computer-in-frustration moments.

What I need is some sort of record / playback mechanism for chrome apps. I’d do it myself, except for legal reasons relating to a previous employer, I’m not sure I can. Recording user actions for later playback could be very useful, especially for testing. Rumor has it someone I know is working on that, with no active input from me. I’d really love it if it wasn’t rumor, and if it was soon. 🙂

3 thoughts on “Copying objects to an application’s clipboard”

  1. I don’t know about DOM nodes but you can certainly put an nsIInputStream into an nsITransferable. (The windows clipboard code does this when you paste a native bitmap.)
    Aside: The tab indexes on this blog’s form objects seem to be all messed up, the order is [canvas] Name Email URL Comments [links] Yes/No Preview Post.
    Aside to aside: Preview page tab order is fine.
    (From Alex: I haven’t messed with those settings on MovableType.)

  2. nsISupportsInterfacePointer is a nsISupportsPrimitive that holds a nsISupports… So you indeed can hold a nsISupports :p
    (.dataIID is one of the Components.interfaces.* for a JS consumer; you don’t really need it thanks to xpconnect, but can’t hurt.)

  3. I’m not sure if my wrists have gotten used to the sharp edge, or what, but it doesn’t bother be anymore (only took about 8 months!).
    Is there not some more generic flavor for a clipboard, or is “application/x-vnd.verbosio.dom-node” it?
    (From Alex: It’s not for the clipboard, it’s for DOM nodes in my app. If I knew of one, I’d use it.)

Comments are closed.