Category Archives: CS5

Flash Private Browsing Fixed – Not Good Enough

I was going to congrat Adobe for their fix to the private browsing in Flash, this was my original text:

I’m glad to say that Adobe has fixed the minor issue they had with the new Flash Player 10.1 private browsing. I’ve written before on how a developer can tell the user’s browsing mode.

The Flash Player that is installed with CS5 is 10.1.52.14 which still suffer from this bug. If you surf the web using private browsing mode you should update the Flash Player to the latest, currently, 10.1.53.38 (RC4). Actually you should update it anyway.

But, when I went to see what have they changed in order to fix it. I saw that both modes, now, have the same limit of 100KB, but it’s still differ. While trying to save more than 100KB in normal browsing mode the status is “pending” while in private browsing mode it immediately fails.

Making this demo functional again required changing 1 line of code. Using any Flash Player, from 10.1_beta2 till latest 10.1.53.38(RC4) should show you if you’re in private mode or not.

So, please, again, normal and private browsing modes should behave exactly the same from a developer standpoint. Making local storage limit the same 100KB was a step in the right direction, but, it’s not enough. Let any Flash content ask for more storage even if it’s in private mode and allow the user to accept it, just remember to delete the user’s choice along with the local storage.

BTW, it might be possible to trick the browsers to tell you the user’s browsing mode, using HTML5 localStorage for example, and without using Flash.

The updated source code is below:

package {
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.NetStatusEvent;
	import flash.net.SharedObject;
	import flash.net.SharedObjectFlushStatus;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.utils.getTimer;
	import flash.utils.setTimeout;

	/**
	 * This class will tell the current browsing mode of the user
	 * Tested with Flash Player 10.1 beta 2 - 10.1.53.38 (RC4)
	 * for more info go to:
	 * http://blog.guya.net
	 */

	[SWF(backgroundColor="#FFFFFF", width="400", height="35")]
	public class KissAndTell extends Sprite
	{
		private var _tf:TextField;

		public function KissAndTell()
		{
			initStage();
			createTF();
			setTimeout(saveData, 300);
		}

		private function initStage():void
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
		}

		//try to save 140kb into the local storage
		private function saveData():void
		{
			var kissSO:SharedObject = SharedObject.getLocal("kissAndTell");
			kissSO.data.value = getDataString(140);

			var status:String;

			try
			{
				status = kissSO.flush();
				kissSO.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
			}
			catch(ex:Error)
			{
				trace("Save failed - private browsing mode");
				setPrivateText();
			}

			if(status && status == SharedObjectFlushStatus.PENDING)
			{
				trace("Pending status - normal browsing mode");
			}

			/***  Changed in the newer versions of the Flash Player 10.1 beta ***/
			//If we can save more than 100kb then we're in Private Mode
			else if(status && status == SharedObjectFlushStatus.FLUSHED)
			{
				setPrivateText();
            }
		}

		//Listening to this event just to prevent exception on debug players
		private function netStatusHandler(event:NetStatusEvent):void
		{
			trace("event.info.code: " + event.info.code);
		}

		private function setPrivateText():void
		{
			_tf.text = "Private Browsing Mode";
			_tf.backgroundColor = 0xAA2222;
		}

		private function createTF():void
		{
			_tf = new TextField();
			_tf.autoSize = TextFieldAutoSize.LEFT;
			_tf.defaultTextFormat = new TextFormat("Arial, Verdana", 20, 0xFFFFFF, true, null, null, null, null, null, 10, 10);
			_tf.text = "Normal Browsing Mode"
			_tf.backgroundColor = 0x22AA22;
			_tf.background = true;
			addChild(_tf);
		}

		private function getDataString(kb:int):String
		{
			var t:int = getTimer();
			var word:String = "GUYA.NET_GUYA.NET_GUYA.NET_GUYA.NET_GUYA.NET_GUYA.NET_GUYA.NET_GUYA.NET_GUYA.NET_GUYA.NET_GUYA.NET_";
			var count:int;
			var a:Array = new Array();
			var lenNeeded:int = kb * 1024;
			while(count * word.length < lenNeeded)
			{
				a.push(word);
				count++;
			}

			var ret:String = a.join("");
			trace("time for generating " + kb + "kb: " + String(getTimer() - t) + " ml");
			return ret;
		}

	}
}