Martin Ström
my-domain.se

Copying to clipboard with JavaScript in Flash 10

As you might know, we have a feature on CopyPasteCharacter to let the user copy a character to their clipboard by just clicking on the character. An invisible Flash movie would do the copying using the ActionScript function System.setClipboard.

In October, Adobe updated the Flash Player to version 10, which included some security changes, like: “Setting the Clipboard will now have to be invoked through a button, keyboard shortcut, or some other event initiated by the user.”. This broke CopyPasteCharacter (and many other sites) for people running Flash 10. I had some ideas on how to solve workaround this a pretty long time ago but too little time to implement it until now.

We’re now having a fully working version which, since I couldn’t find any other solutions online, I thought could be useful for others/Google to know about.

The workaround I came up with is to use a hidden Flash movie which will get resized and moved to overlay the element/character where the user’s mouse is. This way, when the user clicks on the character, the Flash movie will receive the mouse event and therefore be allowed to set the system’s clipboard.

  1. The mouse roll overs a character.
  2. A JavaScript will resize and move the invisible Flash movie to match the character’s size and position
  3. The flash movie receives the mouseover and mouseouts so JavaScript can set the element’s class name (like a faked :hover selector)
  4. When (if?) the user clicks on the character, the click event will get received by the invisible Flash movie and not the document itself.
  5. The Flash movie asks JavaScript for the characters to copy (Clipboard#textToCopy) since it differs a bit depending on which element was clicked. Also, Flash tells JS if the the alt/option key was pressed (so the copy-multiple-characters-at-once feature works).
  6. The same #textToCopy function highlights the clicked element using the same code as we had for the Flash 9 version.

Here’s the code for the Flash movie (highlighted version)

import flash.external.*;

var text:String;

button.onRelease = function() {
  text = String(ExternalInterface.call("Clipboard.textToCopy", Key.isDown(KEY.ALT))) || ' ';
  System.setClipboard(text);
  trace('copied [' + text + ']');
}

button.onRollOver = function() {
  ExternalInterface.call('Clipboard.onFlashButtonOver');
}

button.onRollOut = function() {
  ExternalInterface.call('Clipboard.onFlashButtonOut');
}

The Clipboard class can be found here if you’re interested. It should keep the old behaviour for Flash 9 players but we had some problems with it in some browsers on Windows so right now all players get the updated code.

Note: This post has been lurking in my “Drafts” folder for about a month and shortly after we deployed the new code for Flash 10 a few weeks ago, I found the Zero Clipboard project which seems to use a similar approach as we did but as a stand alone library. I haven’t looked at the code yet but it seems promising.

Updated Colhour website

Colhour website

Colhour is my and Peters system to visualize time using colors. We wanted to extend the previous web site a bit by adding more information about the system and link to projects that were using the system. Also, the former site didn’t set the “Right now” text in the current times color but black only. I decided to rewrite the flash content from scratch, mainly because I wanted to do it in ActionScript 2, and then use the new BitmapData class available in Flash 8. It was my first “real” AS2 project but I’ve done some Java before and a lot of reading about AS2 so there weren’t any problems to make it work. I used the BitmapData#getPixel to get the actual color from the flash movie from specified positions, instead of hard coding all available colors into an array and then update the text field with correct color from the current time. After spending too much time with some wierd coordinate error I got (and make a ASCII-generator from everything), I finally worked it out. After the first update, the update method won’t trigger if nothing has happend to the hand (year, month etc). Since most visitors of the site won’t wait so long that they’ll see any update in year, month, date or even hour, it was unnecessary waste of CPU to update all hands all the time.

Colhour


CSS is in progress