You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by bi...@apache.org on 2012/07/16 09:53:00 UTC

svn commit: r1361928 - in /incubator/flex/utilities/InstallApacheFlex/badge: ./ AIRInstallBadge.as AIRInstallBadge.fla AIRInstallBadge.swf AIRInstallBadgeCS4.fla expressinstall.swf install.html snippet.txt swfobject.js

Author: bigosmallm
Date: Mon Jul 16 07:52:59 2012
New Revision: 1361928

URL: http://svn.apache.org/viewvc?rev=1361928&view=rev
Log:
Added source code for the badge installer.  

Added:
    incubator/flex/utilities/InstallApacheFlex/badge/
    incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadge.as
    incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadge.fla   (with props)
    incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadge.swf   (with props)
    incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadgeCS4.fla   (with props)
    incubator/flex/utilities/InstallApacheFlex/badge/expressinstall.swf   (with props)
    incubator/flex/utilities/InstallApacheFlex/badge/install.html
    incubator/flex/utilities/InstallApacheFlex/badge/snippet.txt
    incubator/flex/utilities/InstallApacheFlex/badge/swfobject.js

Added: incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadge.as
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadge.as?rev=1361928&view=auto
==============================================================================
--- incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadge.as (added)
+++ incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadge.as Mon Jul 16 07:52:59 2012
@@ -0,0 +1 @@
+/*
ADOBE SYSTEMS INCORPORATED
Copyright © 2008 Adobe Systems Incorporated. All Rights Reserved.
 
NOTICE:  This software code file is provided by Adobe as a Sample
under the terms of the Adobe AIR SDK license agreement.  Adobe permits
you to use, modify, and distribute this file only in accordance with
the terms of that agreement.  You may have received this file from a
source other than Adobe.  Nonetheless, you may use, modify, and/or
distribute this file only in accordance with the Adobe AIR SDK license
agreement. 
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/

package  {
	
	import flash.display.SimpleButton;
	import flash.display.MovieClip;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLRequest;
import flash.net.navigateToURL;
import flash.system.LoaderContext;
	import flash.system.ApplicationDomain;
	import flash.text.TextField;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
import flash.text.TextFormat;
import flash.utils.Dictionary;
import flash.utils.Timer;
	import adobe.utils.ProductManager;
	import flash.system.Capabilities;
import flash.utils.getDefinitionByName;

public class AIRInstallBadge extends MovieClip {
		
	// Constants:
		public static const AIR_SWF_URL:String = "http://airdownload.adobe.com/air/browserapi/air.swf";
		public static const VALID_PROTOCOLS:Array = ["http","https"];
		
	// Public Properties:
		// ui:
		public var dialog:MovieClip;
		public var light:MovieClip;
		public var actionBtn:SimpleButton;
		public var actionFld:TextField;
		public var sdkVersionClip:MovieClip;
		public var ideFld:TextField;
		public var helpBtn:SimpleButton;
	
	// Private Properties:
		// parameters:
		protected var mode:String;
		protected var airVersion:String;
		protected var appInstallArg:Array;
		protected var appLaunchArg:Array;
		protected var appID:String;
		protected var appName:String;
		protected var appURL:String;
		protected var appVersion:String;
		protected var sdkVersion:String;
		protected var ide:String;
		protected var helpURL:String;
		protected var hideHelp:Boolean;
		protected var pubID:String;
		protected var locale:Dictionary;
		//
		protected var installedAIRVersion:String;
		protected var airSWFLoader:Loader;
		protected var airSWF:Object;
		protected var action:String;
		protected var prevAction:String;
		protected var timer:Timer;
		protected var productManager:ProductManager;
	
	// Initialization:
		public function AIRInstallBadge() {
			configUI();

			// read params (except strings) from FlashVars:
			var params:Object = loaderInfo.parameters;
			mode = validateString(params.mode);
			airVersion = validateString(params.airversion);
			appInstallArg = (validateString(params.appinstallarg)==null) ? null : [params.appinstallarg];
			appLaunchArg = (validateString(params.applauncharg)==null) ? null : [params.applauncharg];
			appID = validateString(params.appid);
			appName = validateString(params.appname);
			appURL = validateURL(params.appurl);
			appVersion = validateString(params.appversion);
			sdkVersion = validateString(params.sdkversion);
            ide =  validateString(params.ide);
			helpURL = validateURL(params.helpurl);
			hideHelp = (params.hidehelp != null && params.hidehelp.toLowerCase() == "true");
			pubID = validateString(params.pubid);
			dialog.titleFld.textColor = (params.titlecolor != null) ? parseInt(params.titlecolor.replace(/[^0-9A-F]*/ig,""),16) : 0xff0000;
			actionFld.textColor = (params.buttonlabelcolor != null) ? parseInt(params.buttonlabelcolor.replace(/[^0-9A-F]*/ig,""),16) : 0xffffff;
			
			// verify all required params are accounted for:
			if (!verifyParams()) {
				showDialog(getText("error"),getText("err_params"));
				actionFld.text = "";
				return;
			}

            // set up the timer that will be used to check for installation progress:
            if(mode == "install")  {
                timer = new Timer(10000,0);
                timer.addEventListener(TimerEvent.TIMER,handleTimer);

                // set up a product manager for AIR:
                productManager = new ProductManager('airappinstaller' );
            }

			// strip tags out of the appName:
			appName = appName.replace(/(<.*?>|<)/g,"");

            var versionText:MovieClip = getVersionText(sdkVersion);
            versionText.x = 88;
            versionText.y = 11;
            sdkVersionClip.addChild(versionText);

            ideFld.text = ide;
            if(mode == "install")  {
                // load the AIR proxy swf:
                airSWFLoader = new Loader();
                airSWFLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,handleAIRSWFError);
                airSWFLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleAIRSWFInit);
                try {
                    airSWFLoader.load(new URLRequest(AIR_SWF_URL));//, loaderContext);
                } catch (e:*) {
                    handleAIRSWFError(null);
                }
            } else if(mode == "download") {
                enableAction("download");
                helpBtn.visible = !hideHelp;
            }
		}
	
	// Public Methods:
	// Protected Methods:

		// called when there is an error loading the airSWF
		protected function handleAIRSWFError(evt:IOErrorEvent):void {
			showDialog(getText("error"),getText("err_airswf"));
			actionFld.text = "";
		}
		
		// called when the airSWF loads and inits
		protected function handleAIRSWFInit(evt:Event):void {
			airSWF = airSWFLoader.content;
			if (airSWF.getStatus() == "unavailable") {
				showDialog(getText("error"),getText("err_airunavailable"));
				return;
			}
			var version:String = null;
			if (appID && pubID) {
				// check if the application is already installed:
				try {
					airSWF.getApplicationVersion(appID, pubID, appVersionCallback);
					return;
				} catch (e:*) {}
			}
			enableAction("install");
			helpBtn.visible = !hideHelp;
		}
		
		// callback from the airSWF when requesting application version
		protected function appVersionCallback(version:String):void {
			if (version == null) {
				// application is not installed
				enableAction("install");
			} else if (appVersion && (checkVersion(appVersion,version)==1)) {
				// old version is installed
				enableAction("upgrade");
			} else {
				// current version is probably installed
				enableAction("launch");
			}
			helpBtn.visible = !hideHelp;
		}
		
		// handles clicks on the action button
		protected function handleActionClick(evt:MouseEvent):void {
			if (action == "close") {
				hideDialog();
				enableAction(prevAction);
			} else if (action == "install" || action == "upgrade" || action == "tryagain") {
				showDialog(getText("installing"),getText("installingtext"));
				disableAction();
				// check if it's installed every 5 seconds:
				timer.reset();
				timer.start();
				airSWF.installApplication(appURL, airVersion, appInstallArg);
			} else if (action == "download") {
                disableAction();
                var request:URLRequest = new URLRequest(appURL);
                try {
                    navigateToURL(request, '_blank');
                } catch (e:Error) {
                    showDialog(getText("error"),getText("err_params"));
                    trace("Error occurred!");
                }
            } else if (action == "launch") {
				airSWF.launchApplication(appID, pubID, appLaunchArg);
				showDialog(getText("launching"),getText("launchingtext"));
				enableAction("close");
			}
		}
		
		// triggered  every 5 seconds after installing or upgrading.
		// checks to see if the expected version of the application was successfully installed.
		protected function handleTimer(evt:TimerEvent):void {
			try {
				airSWF.getApplicationVersion(appID, pubID, tryAgainVersionCallback);
			} catch (e:*) {
				enableAction("tryagain");
			}
		}
		
		// call back from version check in handleTimer
		// verifies that version is appVersion, and provides option to launch the app if it is.
		protected function tryAgainVersionCallback(version:String):void {
			if (version != null && (appVersion == null || !(checkVersion(appVersion,version)==1))) {
				// current version is probably installed
				timer.stop();
				enableAction("launch");
			} else {
				enableAction("tryagain");
			}
		}
		
		// show help
		protected function handleHelpClick(evt:MouseEvent):void {
			showDialog(getText("help"),getText("helptext"));
			enableAction("close");
		}
		
		// enables the action button with the appropriate label, and sets the action property
		protected function enableAction(action:String):void {
			if (action == null) {
				disableAction();
				actionFld.text = getText("loading");
				prevAction = null;
			} else {
				if (this.action != "close") { prevAction = this.action; }
				actionBtn.addEventListener(MouseEvent.CLICK,handleActionClick);
				actionBtn.enabled = true;
				actionFld.alpha = 1;
				actionFld.text = getText(action);
			}
			this.action = action;
		}
		
		// disables the action button
		protected function disableAction():void {
			actionBtn.removeEventListener(MouseEvent.CLICK,handleActionClick);
			actionBtn.enabled = false;
			actionFld.alpha = 0.2;
		}
		
		// shows the dialog, and hides the help button
		protected function showDialog(title:String,content:String):void {
			dialog.titleFld.text = title;
			dialog.contentFld.htmlText = content;
			dialog.visible = true;
			helpBtn.visible = false;
		}
		
		// hides the dialog, and shows the help button
		protected function hideDialog():void {
			dialog.visible = false;
			helpBtn.visible = !hideHelp;
		}
		
		// return if all required parameters are present, false if not:
		protected function verifyParams():Boolean {
			return !(appName == null || appURL == null || airVersion == null || !(mode == "download" || mode == "install"));
		}
		
		// return null if not a valid URL, only allow HTTP, HTTPS scheme or relative path
		protected function validateURL(url:String):String {
			if (url == null) { return null; }
			var markerIndex:int = url.search(/:|%3a/i);
			if (markerIndex > 0) {
				var scheme:String = url.substr(0, markerIndex).toLowerCase();
				if (VALID_PROTOCOLS.indexOf(scheme) == -1) { return null; }
			}
			if (url.indexOf("<") >= 0 || url.indexOf(">") >= 0) {
				return null;
			}
			return url;
		}
		
		// returns null if the string is empty or null.
		protected function validateString(str:String):String {
			return (str == null || str.length < 1 || str.indexOf("<") >= 0 || str.indexOf(">") >= 0) ? null : str;
		}
		
		// returns the specified string from FlashVars (passed as "str_strcode") if available, or the default string if not.
		protected function getText(strCode:String):String {
			var str:String = loaderInfo.parameters["str_"+strCode];
			if (str != null && str.length > 1) {
				return str;
			}
			switch (strCode) {
				case "error": return "Error!";
				case "err_params": return "Invalid installer parameters.";
				case "err_airunavailable": return "Adobe® AIR™ is not available for your system.";
				case "err_airswf": return "Unable to load the Adobe® AIR™ Browser API swf.";
				case "loading": return "Loading...";
				case "install": return "INSTALL";
				case "download": return "DOWNLOAD";
				case "launch": return "Launch Now";
				case "upgrade": return "Upgrade Now";
				case "close": return "CLOSE";
				case "launching": return "Launching Application";
				case "launchingtext": return "Please wait while the application launches.";
				case "installing": return "Installing Application";
				case "installingtext": return "Please wait while the application installs.";
				case "tryagain": return "Try Again";
				case "help": return "Help";
				case "helptext": return getHelpText();
			}
			return "";
		}
		
		// assembles help text based on the current badge state.
		// ex. Click the 'Install Now' button to install My Fun Application. The Adobe® AIR™ runtime will be installed automatically.
		protected function getHelpText():String {
			var helpText:String = "Click the '"+getText(action)+"' button to "+action+" "+appName;
			if (action == "upgrade") { helpText += " to version "+appVersion; }
			else if (action == "install") { helpText += ". The Adobe® AIR™ Runtime will be installed automatically if needed"; }
			helpText += ".";
			if (helpURL != null) { helpText += "\n<a href='"+helpURL+"'><font color='#2288FF'>Click here for additional help</font></a>"; }
			return helpText;
		}
		
		// returns true if the first version number is greater than the second, or false if it is lesser or indeterminate:
		// works with most common versions strings: ex. 1.0.2.27 < 1.0.3.2, 1.0b3 < 1.0b5, 1.0a12 < 1.0b7, 1.0b3 < 1.0
		protected function checkVersion(v1:String,v2:String):int {
			var arr1:Array = v1.replace(/^v/i,"").match(/\d+|[^\.,\d\s]+/ig);
			var arr2:Array = v2.replace(/^v/i,"").match(/\d+|[^\.,\d\s]+/ig);
			var l:uint = Math.max(arr1.length,arr2.length);
			for (var i:uint=0; i<l; i++) {
				var sub:int = checkSubVersion(arr1[i],arr2[i])
				if (sub == 0) { continue; }
				return sub;
			}
			return 0;
		}
		
		// return 1 if the sub version element v1 is greater than v2, -1 if v2 is greater than v1, and 0 if they are equal
		protected function checkSubVersion(v1:String,v2:String):int {
			v1 = (v1 == null) ? "" : v1.toUpperCase();
			v2 = (v2 == null) ? "" : v2.toUpperCase();
			
			if (v1 == v2) { return 0; }
			var num1:Number = parseInt(v1);
			var num2:Number = parseInt(v2);
			if (isNaN(num2) && isNaN(num1)) {
				return (v1 == "") ? 1 : (v2 == "") ? -1 : (v1 > v2) ? 1 : -1;
			}
			else if (isNaN(num2)) { return 1; }
			else if (isNaN(num1)) { return -1; }
			else { return (num1 > num2) ? 1 : -1; }
		}

		// returns an array of objects describing the parameters supported by this badge.
		// parameters will be displayed in the configurator in the same order they are in the array.
		// If you add a toolTip paramater, that value will be used as the paramaters label toolTip, otherwise the label will be used.
		// supported parameter types and associated properties:
		// - string (name, label, default, maxChars, toolTip)
		// - boolean (name, label, default, toolTip)
		// - color (name, label, default, toolTip)
		// - number (name, label, default, required, minValue, maxValue, toolTip)
		// - image (name, label, default, toolTip) - Creates an image browse field. Types are restricted to png, gif, and jpeg
		// - heading (label) – displays a heading above a parameter group
		public function getParams():Array {
			var params:Array = [
								{name:"helpurl",label:"help url",type:"string",maxChars:200,def:"help.html"},
								{name:"hidehelp",label:"hide help?",type:"boolean",def:false},
								{name:"skiptransition",label:"skip transition?",type:"boolean",def:false},
								{name:"titlecolor",label:"title color",type:"color",def:"FF0000"},
								{name:"buttonlabelcolor",label:"button label color",type:"color",def:"FFFFFF"},
								
								{label:"Strings",type:"heading"},
								{name:"str_error",label:"error title",type:"string",def:getText("error")},
								{name:"str_err_params",label:"invalid params error",type:"string",def:getText("err_params")},
								{name:"str_err_airunavailable",label:"AIR unavailable error",type:"string",def:getText("err_airunavailable")},
								{name:"str_err_airswf",label:"loading AIR swf failed error",type:"string",def:getText("err_airswf")},
								{name:"str_loading",label:"loading label",type:"string",def:getText("loading")},
								{name:"str_install",label:"install button label",type:"string",def:getText("install")},
								{name:"str_launch",label:"launch button label",type:"string",def:getText("launch")},
								{name:"str_upgrade",label:"upgrade button label",type:"string",def:getText("upgrade")},
								{name:"str_close",label:"close button label",type:"string",def:getText("close")},
								{name:"str_tryagain",label:"try again button label",type:"string",def:getText("tryagain")},
								{name:"str_launching",label:"launching title",type:"string",def:getText("launching")},
								{name:"str_launchingtext",label:"launching text",type:"string",def:getText("launchingtext")},
								{name:"str_installing",label:"installing title",type:"string",def:getText("installing")},
								{name:"str_installingtext",label:"installing text",type:"string",def:getText("installingtext")},
								{name:"str_help",label:"help title",type:"string",def:getText("help")},
								{name:"str_helptext",label:"help text",type:"string",def:""},
								];
			return params;
		}
		
		// handles initial UI setup.
		protected function configUI():void {
			actionFld.text = getText("loading");
			actionFld.mouseEnabled = false;
			disableAction();
			hideDialog();
			helpBtn.addEventListener(MouseEvent.CLICK,handleHelpClick);
			
			// allow clicks to pass through the light overlay:
			light.mouseEnabled = false;
			
			// hide the help button until the air proxy swf is loaded:
			helpBtn.visible = false;
		}

        protected function getVersionText(version:String):MovieClip{
            var versionText:MovieClip = new MovieClip();
            var character:MovieClip;
            var characterString:String;
            var charaters:Array = version.split("");
            var i:int, xPos:Number = 0, len:int = charaters.length;
            for(i = 0; i < len; i ++){
                characterString = charaters[i];
                if(characterString == "."){
                    character = createMovieClip("dot") as MovieClip;
                    character.y = 17.7;
                }else{
                    character = createMovieClip("_" + characterString) as MovieClip;
                }
                character.x = xPos;
                versionText.addChild(character);
                xPos = character.x + character.width + 1;
            }

            return versionText;
        }

        private function createMovieClip(classname:String):MovieClip {
            //trace(classname);
            var c:Class;
            try {
                c = Class(getDefinitionByName(classname));
            } catch (error:Error) {
                trace(error.errorID+' || '+error.name+' || '+error.message, c);
                //let error fail silently
                //throw new Error("#1065: Flash Library Error. || Variable " + classname + " is not defined in ApplicationDomain/MovieClip", $error.errorID);
            }
            if(c)
                return new c() as MovieClip;
            else
                return new MovieClip();

        }

	}
}
\ No newline at end of file

Added: incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadge.fla
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadge.fla?rev=1361928&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadge.fla
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadge.swf
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadge.swf?rev=1361928&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadge.swf
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadgeCS4.fla
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadgeCS4.fla?rev=1361928&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/flex/utilities/InstallApacheFlex/badge/AIRInstallBadgeCS4.fla
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/flex/utilities/InstallApacheFlex/badge/expressinstall.swf
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/badge/expressinstall.swf?rev=1361928&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/flex/utilities/InstallApacheFlex/badge/expressinstall.swf
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/flex/utilities/InstallApacheFlex/badge/install.html
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/badge/install.html?rev=1361928&view=auto
==============================================================================
--- incubator/flex/utilities/InstallApacheFlex/badge/install.html (added)
+++ incubator/flex/utilities/InstallApacheFlex/badge/install.html Mon Jul 16 07:52:59 2012
@@ -0,0 +1,73 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<!-- SWFObject embed by Geoff Stearns geoff@deconcept.com http://blog.deconcept.com/swfobject/ -->
+	<script type="text/javascript" src="swfobject.js"></script>
+</head>
+<body color="#FFFFFF">
+	
+	<div id="flashcontent" style="width:300px; height:300px;">
+		<strong>Please upgrade your Flash Player</strong>
+		This is the content that would be shown if the user does not have Flash Player 6.0.65 or higher installed.
+	</div>
+
+	<script type="text/javascript">
+		
+		// version 9.0.115 or greater is required for launching AIR apps.
+		var so = new SWFObject("AIRInstallBadge.swf", "Badge", "300", "300", "9.0.115", "#e5e5e5");
+        //so.addParam("wmode", "transparent");
+        so.addParam("bgcolor", "#FFFFFF");
+        so.useExpressInstall('expressinstall.swf');
+
+		// these parameters are required for badge install:
+		//so.addVariable("mode", "install"); // badge mode install
+		so.addVariable("mode", "download"); // badge mode download
+		so.addVariable("airversion", "1.0"); // version of AIR runtime required
+		so.addVariable("appname", "InstallApacheFlex"); // application name to display to the user
+		var extension = "";
+		if (navigator.appVersion.indexOf("Win")!=-1)
+		{
+			extension = "exe";
+		}
+		else if (navigator.appVersion.indexOf("Mac")!=-1)
+		{
+			extension = "dmg";
+		}
+		else
+		{
+			alert("Unsupported operating system");
+		}
+		so.addVariable("appurl", "http://people.apache.org/~bigosmallm/installapacheflex/InstallApacheFlex." + extension); // absolute URL (beginning with http or https) of the application ".exe" or ".dmg" file
+		// these parameters are required to support launching apps from the badge (but optional for install):
+		so.addVariable("appid", "org.apache.flex.installapacheflex"); // the qualified application ID (ex. com.gskinner.air.MyApplication)
+		so.addVariable("pubid", "apache.org"); // publisher id
+		
+		// this parameter is required in addition to the above to support upgrading from the badge:
+		so.addVariable("appversion", ""); // AIR application version
+        so.addVariable("sdkversion", "4.8.0"); // AIR application version
+        so.addVariable("ide", "for Adobe Flash Builder"); // AIR application version
+
+		// these parameters are optional:
+		so.addVariable("appinstallarg", "installed from web"); // passed to the application when it is installed from the badge
+		so.addVariable("applauncharg", "launched from web"); // passed to the application when it is launched from the badge
+		so.addVariable("helpurl", "help.html"); // optional url to a page containing additional help, displayed in the badge's help screen
+		so.addVariable("hidehelp", "false"); // hides the help icon if "true"
+		so.addVariable("titlecolor", "#00AAFF"); // changes the color of titles
+		so.addVariable("buttonlabelcolor", "#FFFFFF"); // changes the color of the button label
+		so.addVariable("appnamecolor", "#00AAFF"); // changes the color of the application name if the image is not specified or loaded
+
+		// these parameters allow you to override the default text in the badge (i.e. for localization purpose):
+		// supported strings: str_error, str_err_params, str_err_airunavailable, str_err_airswf, str_loading, str_install, str_launch, str_upgrade, str_close, str_launching, str_launchingtext, str_installing, str_installingtext, str_tryagain, str_beta3, str_beta3text, str_help, str_helptext
+        //so.addVariable("str_install", "DOWNLOAD");
+        so.addVariable("str_err_airswf", "<u>Running locally?</u><br/><br/>The AIR proxy swf won't load properly when this demo is run from the local file system."); // overrides the error text when the AIR proxy swf fails to load
+		so.write("flashcontent");
+		
+		// ]]>
+	</script>
+
+<!-- END EMBED CODE -->
+
+	
+</body>
+</html>

Added: incubator/flex/utilities/InstallApacheFlex/badge/snippet.txt
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/badge/snippet.txt?rev=1361928&view=auto
==============================================================================
--- incubator/flex/utilities/InstallApacheFlex/badge/snippet.txt (added)
+++ incubator/flex/utilities/InstallApacheFlex/badge/snippet.txt Mon Jul 16 07:52:59 2012
@@ -0,0 +1 @@
+<iframe width="310" height="310" frameborder=0 scrolling="no" src="http://people.apache.org/~bigosmallm/installapacheflex/install.html"></iframe>
\ No newline at end of file

Added: incubator/flex/utilities/InstallApacheFlex/badge/swfobject.js
URL: http://svn.apache.org/viewvc/incubator/flex/utilities/InstallApacheFlex/badge/swfobject.js?rev=1361928&view=auto
==============================================================================
--- incubator/flex/utilities/InstallApacheFlex/badge/swfobject.js (added)
+++ incubator/flex/utilities/InstallApacheFlex/badge/swfobject.js Mon Jul 16 07:52:59 2012
@@ -0,0 +1,8 @@
+/**
+ * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
+ *
+ * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ */
+if(typeof deconcept=="undefined"){var deconcept=new Object();}if(typeof deconcept.util=="undefined"){deconcept.util=new Object();}if(typeof deconcept.SWFObjectUtil=="undefined"){deconcept.SWFObjectUtil=new Object();}deconcept.SWFObject=function(_1,id,w,h,_5,c,_7,_8,_9,_a){if(!document.getElementById){return;}this.DETECT_KEY=_a?_a:"detectflash";this.skipDetect=deconcept.util.getRequestParameter(this.DETECT_KEY);this.params=new Object();this.variables=new Object();this.attributes=new Array();if(_1){this.setAttribute("swf",_1);}if(id){this.setAttribute("id",id);}if(w){this.setAttribute("width",w);}if(h){this.setAttribute("height",h);}if(_5){this.setAttribute("version",new deconcept.PlayerVersion(_5.toString().split(".")));}this.installedVer=deconcept.SWFObjectUtil.getPlayerVersion();if(!window.opera&&document.all&&this.installedVer.major>7){deconcept.SWFObject.doPrepUnload=true;}if(c){this.addParam("bgcolor",c);}var q=_7?_7:"high";this.addParam("quality",q);this.setAttribute("u
 seExpressInstall",false);this.setAttribute("doExpressInstall",false);var _c=(_8)?_8:window.location;this.setAttribute("xiRedirectUrl",_c);this.setAttribute("redirectUrl","");if(_9){this.setAttribute("redirectUrl",_9);}};deconcept.SWFObject.prototype={useExpressInstall:function(_d){this.xiSWFPath=!_d?"expressinstall.swf":_d;this.setAttribute("useExpressInstall",true);},setAttribute:function(_e,_f){this.attributes[_e]=_f;},getAttribute:function(_10){return this.attributes[_10];},addParam:function(_11,_12){this.params[_11]=_12;},getParams:function(){return this.params;},addVariable:function(_13,_14){this.variables[_13]=_14;},getVariable:function(_15){return this.variables[_15];},getVariables:function(){return this.variables;},getVariablePairs:function(){var _16=new Array();var key;var _18=this.getVariables();for(key in _18){_16[_16.length]=key+"="+_18[key];}return _16;},getSWFHTML:function(){var _19="";if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){if(th
 is.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","PlugIn");this.setAttribute("swf",this.xiSWFPath);}_19="<embed type=\"application/x-shockwave-flash\" src=\""+this.getAttribute("swf")+"\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\"";_19+=" id=\""+this.getAttribute("id")+"\" name=\""+this.getAttribute("id")+"\" ";var _1a=this.getParams();for(var key in _1a){_19+=[key]+"=\""+_1a[key]+"\" ";}var _1c=this.getVariablePairs().join("&");if(_1c.length>0){_19+="flashvars=\""+_1c+"\"";}_19+="/>";}else{if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");this.setAttribute("swf",this.xiSWFPath);}_19="<object id=\""+this.getAttribute("id")+"\" classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\">";_19+="<param name=\"movie\" value=\
 ""+this.getAttribute("swf")+"\" />";var _1d=this.getParams();for(var key in _1d){_19+="<param name=\""+key+"\" value=\""+_1d[key]+"\" />";}var _1f=this.getVariablePairs().join("&");if(_1f.length>0){_19+="<param name=\"flashvars\" value=\""+_1f+"\" />";}_19+="</object>";}return _19;},write:function(_20){if(this.getAttribute("useExpressInstall")){var _21=new deconcept.PlayerVersion([6,0,65]);if(this.installedVer.versionIsValid(_21)&&!this.installedVer.versionIsValid(this.getAttribute("version"))){this.setAttribute("doExpressInstall",true);this.addVariable("MMredirectURL",escape(this.getAttribute("xiRedirectUrl")));document.title=document.title.slice(0,47)+" - Flash Player Installation";this.addVariable("MMdoctitle",document.title);}}if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){var n=(typeof _20=="string")?document.getElementById(_20):_20;n.innerHTML=this.getSWFHTML();return true;}else{if(this.getAttr
 ibute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}return false;}};deconcept.SWFObjectUtil.getPlayerVersion=function(){var _23=new deconcept.PlayerVersion([0,0,0]);if(navigator.plugins&&navigator.mimeTypes.length){var x=navigator.plugins["Shockwave Flash"];if(x&&x.description){_23=new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));}}else{if(navigator.userAgent&&navigator.userAgent.indexOf("Windows CE")>=0){var axo=1;var _26=3;while(axo){try{_26++;axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+_26);_23=new deconcept.PlayerVersion([_26,0,0]);}catch(e){axo=null;}}}else{try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");_23=new deconcept.PlayerVersion([6,0,21]);axo.AllowScriptAccess="always";}catch(e){if(_23.major==6){return _23;}}try{axo=new ActiveXObject("ShockwaveFlash.ShockwaveFl
 ash");}catch(e){}}if(axo!=null){_23=new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));}}}return _23;};deconcept.PlayerVersion=function(_29){this.major=_29[0]!=null?parseInt(_29[0]):0;this.minor=_29[1]!=null?parseInt(_29[1]):0;this.rev=_29[2]!=null?parseInt(_29[2]):0;};deconcept.PlayerVersion.prototype.versionIsValid=function(fv){if(this.major<fv.major){return false;}if(this.major>fv.major){return true;}if(this.minor<fv.minor){return false;}if(this.minor>fv.minor){return true;}if(this.rev<fv.rev){return false;}return true;};deconcept.util={getRequestParameter:function(_2b){var q=document.location.search||document.location.hash;if(_2b==null){return q;}if(q){var _2d=q.substring(1).split("&");for(var i=0;i<_2d.length;i++){if(_2d[i].substring(0,_2d[i].indexOf("="))==_2b){return _2d[i].substring((_2d[i].indexOf("=")+1));}}}return "";}};deconcept.SWFObjectUtil.cleanupSWFs=function(){var _2f=document.getElementsByTagName("OBJECT");for(var i=_2f.length
 -1;i>=0;i--){_2f[i].style.display="none";for(var x in _2f[i]){if(typeof _2f[i][x]=="function"){_2f[i][x]=function(){};}}}};if(deconcept.SWFObject.doPrepUnload){if(!deconcept.unloadSet){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);};window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);deconcept.unloadSet=true;}}if(!document.getElementById&&document.all){document.getElementById=function(id){return document.all[id];};}var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject;
\ No newline at end of file