Clipboard Copying in Flash 10

One of the things I noticed about the DevFormatter plugin I’m using was that the clipboard copying code was no longer working. This apparently is because of the new security upgrades in Flash 10 which now have additional user-initiated action (UIA) requirements for various functions, including System.setClipboard().

While inconvenient, especially since it’s somewhat commonly used, it was a necessary change due to some high-profile clickjacking attacks, and well, a good idea regardless, when you think about it.

Surprisingly, months after Flash 10’s release, it seems that neither the WP plugins I looked at, nor the most popular general syntax highlighter script seem to have fixed their clipboard functionality, as the workaround isn’t too onerous. Instead of the having a JS triggered Flash copy, just reverse it with a Flash button calling a JS function – not quite as elegant since you’ll need as many Flash buttons as you want copy triggers, but not too onerous. It’s been a while since I’ve done any Flash work, but luckily, it didn’t take very long at all.

Since this might prove useful to others, I’ve done this in AS 2.0 for more compatibility and made the package available here under a GPLv3 license: clipboard_copy.

Of course, if you want to create your own unencumbered version, the code is easy enough to create yourself. The JS call looks something like:

function clipboard_copy(id) {
return document.getElementById(id).innerHTML;
// or instead of innerHTML, you can get plain text:
// [((document.all)? "innerText" : "textContent")]
}

Note, you can have the clipboard JS function act on a selection if you’d like, but for my purposes (integration w/ code blocks, getting the text was better).

The Flash is similarly simple. Here’s the AS 2.0 event attachment and ExternalInterface:

// AS 2.0 Event
copyButton.addEventListener("click",click);
function click(event:Object):Void {
var item = "testid";
var jsFunction:String = "clipboard_copy";
var returnValue:String = ExternalInterface.call(jsFunction, item).toString();
System.setClipboard(returnValue);
}

Easy peezy.

A couple of notes:

  • If you’re testing, you’ll want to run from a web server, not the file system, otherwise you’ll get sandbox errors
  • Regular cross-domain rules also apply of course
  • I used the Button Component for my version, which is admittedly a bit fugly. You could in theory have a text-only Flash link that you subsequently styled w/ JS (i.e., to match font-family and font-size), but I’ll leave that as an exercise for the reader