Home > Buzzword, Flex, Uncategorized > Make FileReference.browse() work under Flash Player 10

Make FileReference.browse() work under Flash Player 10

June 25th, 2008

People are starting to use the recently released beta of Flash Player 10, which is full of new feature goodness.  It’s just a beta and not in wide circulation yet, but we figured we better make sure Buzzword at least works with it, if for no other reason than we wanted to avoid getting bug reports from a lot of Adobe employees.

Turns out the biggest breakage we encountered is that image and file uploads stopped working, because of a change to FileReference.browse(). This blog post isn’t rocket science but maybe it’ll save one or two people the trouble of tracking down this problem.

In Flash Player 9, it was permitted to call browse() at any time. But a new security measure in Flash Player 10 restricts the browse() call so that it only works if somewhere above it on the call stack is a user event handler, such as MouseEvent.MOUSE_UP.

As it turns out, our UI code for handling file and image uploads is centered around some TitleWindow subclasses, for example ImageUploadDlg, which has a static method run() that constructs a new ImageUploadDlg instance, then opens it via PopupWindow.createPopUp().  (Buzzword trivia: this is some of the very oldest code in the product!) The first thing the user sees is the OS file browse dialog, but the call to browse() was happening in the FlexEvent.CREATION_COMPLETE handler, not the static run() method.

Under Flash Player 9, this worked fine. Under Flash Player 10, the call to browse() was being ignored. The solution was to move the call to the private method that calls browse() into the static run() method, where it was still in the same call stack as the original MOUSE_UP handler.

Another interesting bit of AS3 trivia emerged: it wasn’t obvious to me that the compiler would let you make a call into a private method of an ImageUploadDlg class from code that was in a static method of ImageUploadDlg. But in fact, this call is perfectly legal, because a static method of a class is a method of that class from the perspective of namespace visibility.

Here’s a code sample that illustrates the fix. Look for the call to dlg.selectLocalFile() at the end of the static run() method. Disclaimer: All source code appearing on this site is provided “as-is,” and is not warranted by any party for any purpose. Some source code appearing on this site is identified as Copyright Adobe Systems Incorporated, and neither David Coletta nor Adobe Systems Incorporated grants to you a license to use the source code so identified for any purpose.

/*************************************************************************
*
*  Copyright © 2006-2008 Adobe Systems Incorporated
*  All Rights Reserved.
*
**************************************************************************/

/**
 * Create and run the dialog.
 * @param completionCallback Function called on completion; passed the ImageUploadDlg instance
 * 	as its only argument.
 * @param title Optional title for dialog
 * @return True if successful.
 */
static public function run(completionCallback:Function, documentID:String, title:String = null) : Boolean
{
	if (documentID == null)
	{
		Alert.show(ResourceManager.getInstance().getString("ImageUploadDlg", 'MUST_SAVE_FIRST'),
		           ResourceManager.getInstance().getString("Common", 'ERROR'));
		return false;
	}

	var dlg:ImageUploadDlg = PopUpManager.createPopUp(Application.application as DisplayObject, ImageUploadDlg, true) as ImageUploadDlg;
	if (title != null)
		dlg.title = title;

	dlg.completionCallback = completionCallback;
	dlg.documentID = documentID;
	dlg.visible = false;
	// browse for image file to upload
	dlg.selectLocalFile();
	return true;
}

/**
 * Open native browser dialog to select image file to upload
 */
public function selectLocalFile() : void
{
	_fileRef = new FileReference();
	_fileRef.addEventListener(Event.SELECT, onSelectLocalFile);
	_fileRef.addEventListener(Event.CANCEL, onCancelLocalFile);

	var filterExtensions:String = "*.gif;*.jpeg;*.jpg;*.png";
	// On Linux, file extensions are case-sensitive, so we need to include the
	// upper-case versions of all of these.  It seems to be important to specify
	// the upper-case versions at the beginning of the filter string rather than
	// at the end.
	if (Host.isLinux)
		filterExtensions = filterExtensions.toUpperCase() + ";" + filterExtensions;

	var fileFilter:FileFilter = new FileFilter(resourceManager.getString("ImageUploadDlg", "IMAGES"), filterExtensions);

	_fileRef.browse([ fileFilter ]);
}
Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • StumbleUpon
Author: David Coletta Categories: Buzzword, Flex, Uncategorized Tags:
  1. Aida
    August 20th, 2008 at 23:38 | #1

    How does selectLocalFile() relate to run?

  2. YosiDov
    March 17th, 2009 at 05:14 | #2

    Can I use the FileReference.browse() to open a file like in fscommand exec?

  1. July 1st, 2008 at 13:08 | #1