<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SwiftLizard Interactive {Design, Development} &#187; javascript</title>
	<atom:link href="http://www.swift-lizard.com/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.swift-lizard.com</link>
	<description>all about a it - freelancers life</description>
	<lastBuildDate>Thu, 18 Mar 2010 09:10:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Developing a clock in Flash with AS3</title>
		<link>http://www.swift-lizard.com/2009/12/31/developing-a-clock-widget-in-flash-with-as3/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://www.swift-lizard.com/2009/12/31/developing-a-clock-widget-in-flash-with-as3/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 00:51:59 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[thoughts]]></category>
		<category><![CDATA[actionscript 3.0]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flashbuilder]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.swift-lizard.com/?p=254</guid>
		<description><![CDATA[Ok guys, this time we won´t do any php. This time it will all be about Flash and Actionscript 3.0. As I told you in some of the tutorials before I am working for a German ISP at the moment which is on it´s way to launch a new portal. This portal website will also [...]]]></description>
			<content:encoded><![CDATA[<p>Ok guys, this time we won´t do any php. This time it will all be about Flash and Actionscript 3.0. As I told you in some of the tutorials before I am working for a German ISP at the moment which is on it´s way to launch a new portal. This portal website will also hold some widgets that will provide the users with some basic functionality.</p>
<p>This tutorial will cover the alarm clock that comes with two layouts, analog and digital.  <span id="more-254"></span>To make it more fun the project manager covering this widget wanted to have the following options for configuration:</p>
<ol>
<li> The user should have the possibility to choose between the layouts on the fly.</li>
<li> There should be an option to set the date and the alarm time, as well as message displayed</li>
<li> The digital clock comes with 7 different themes of which the user can choose</li>
</ol>
<p>First thing I had to evaluate was if we can do this kind of thing in javascript, because this way it could have been displayed on mobile devices as well. To make a long story short, I found a way that worked in almost any browser, except our old friend the Internet Explorer up to 7 . Up to this version the Iex simply does not have the possibility to work with rotating canvas. With a share at the ISPs website of about 30% for this version downwards this was the deal breaker. So we had to go for flash.</p>
<p>Like almost every designer I have a little addiction to flash, but unlike most of my colleagues I also know how to code AS3. I have to admit that coming from another language, and coding that one oop style has made it a little easier, and knowing some Java was also a little help. But coming from php and knowing some Java also places some traps on my way to a running clock.swf. To code the widget I used the Flashbuilder 4, which I will definitely buy at its release. This incredible piece of software from Adobe has made my life  a lot  easier.</p>
<p>First question every good coder asks himself at the beginning of a project is what do I need:</p>
<ol>
<li> First of all I will need a controller class which will decide whether to display the digital or analog version of the clock, and also set the alarm</li>
<li> I will need a clock model that provides me with some basic functionality like getting the current time and drawing it</li>
<li> I will also need child models of that clock model for digital and analog clock</li>
<li> I will need an Alarm model that covers the basic functionality of an alarm</li>
<li> last I will need several different views for analog and digital clock as well as for the alarm message displayed</li>
</ol>
<p>So,&#8230; lets get started <img src='http://www.swift-lizard.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> .</p>
<p>First we need the basic clock model we want build our clock widget on.</p>
<pre name="code" class="actionscript" style="width: 550px; overflow:scroll;" >package com.clock
{
	import flash.display.MovieClip;
	import flash.events.TimerEvent;
	import flash.text.*;
	import flash.utils.Timer;
	import com.clock.events.AlarmEvent;

	public class clock extends MovieClip
	{	

		protected var clockLayout:String = ''; 

		public static const millisecondsPerMinute:int = 1000 * 60;
		public static const millisecondsPerHour:int   = 1000 * 60 * 60;
		public static const millisecondsPerDay:int    = 1000 * 60 * 60 * 24;

		public var clockTimer:Timer;

		public var alarmTimer:Timer;
		public var alarmTime:Date;
		public var alarmMessage:String;

		/**
		 * constructor
		 */
		public function clock():void
		{
			// set clock update Event to be called any second
			clockTimer = new Timer(1000);
			clockTimer.addEventListener(TimerEvent.TIMER, onTick);
			// init alarm function of the clock
			this.initAlarmClock();
		}

		/**
		 * start the clock
		 */
		public function startClock():void{
			clockTimer.start();
		}

		/**
		 * event handler that is called every second
		 *
		 * @param Event e, Timer event
		 */
		protected function onTick(e:TimerEvent):void
		{
			this.draw();
		}

		/**
		 * init for the alarm clock
		 */
		public function initAlarmClock():void
		{
			this.alarmTimer = new Timer(0, 1);
			this.alarmTimer.addEventListener(TimerEvent.TIMER, onAlarm);
		}

		/**
		 * Sets the time at which the alarm should go off.
		 * @param hour		The hour portion of the alarm time
		 * @param minutes	The minutes portion of the alarm time
		 * @param message	The message to display when the alarm goes off.
		 * @return The time at which the alarm will go off.
		 */
		public function setAlarm(hour:Number = 0, minutes:Number = 0, message:String = "Alarm!"):Date
		{
			this.alarmMessage = message;

			var now:Date = new Date();

			// create this time on today's date
			alarmTime = new Date(now.fullYear, now.month, now.date, hour, minutes);

			// determine if the specified time has already passed today
			if (alarmTime &lt;= now)
			{
				alarmTime.setTime(alarmTime.time + millisecondsPerDay);
			}

			// reset the alarm timer if it's currently set
			this.alarmTimer.reset();
			// calculate how many milliseconds should pass before the alarm should
			// go off (the difference between the alarm time and now) and set that
			// value as the delay for the alarm timer
			alarmTimer.delay = Math.max(1000, alarmTime.time - now.time);
			alarmTimer.start();

			return alarmTime;
		}

		/**
		 * Called when the Timer event is received
		 */
		public function onAlarm(event:TimerEvent):void
		{
			var alarm:AlarmEvent = new AlarmEvent(this.alarmMessage);
			this.dispatchEvent(alarm);
		}

		/**
		 * @retrun Date, Current time
		 */
		protected function getCurrentTime():Date
		{
			var time:Date = new Date();
			return time;
		}
		/**
		 * @return Number, current Minutes
		 */
		protected function getMinutes():Number
		{
			return this.getCurrentTime().getMinutes();
		}

		/**
		 * @return Number, current Hours
		 */
		protected function getHours():Number
		{
			return this.getCurrentTime().getHours();
		}

		/**
		 * @return Number, current Seconds
		 */
		protected function getSeconds():Number
		{
			return this.getCurrentTime().getSeconds();
		}

		/**
		 * draws current time
		 */
		protected function draw():void
		{

		}
	}
}
</pre>
<p>So what have we done here ? Basically we have set up a clock class that inherits MovieClip. The constructor has set a timer event that will call the method ontick every single second after the clock has been loaded. It also has initiated the alarm, and dispatched the alarm event. Afterwards you see a setter method for the alarm time, which checks if the alarm is in the future, and if so sets the time for the alarm to be displayed. Last, like I said, some very basic getters and setters for the time, and a empty draw method. This one is empty because it will be overwritten by the child classes anyways, it is there just to make sure there is a draw method in any case, otherwise we might get an fatal error at compiling.</p>
<p>Lets go on. Now that we have our basic clock model that will draw the clock each second, as well as fire the alarm, we need the models of the analog and the digital clock.<br />
Because it was the easier one lets start with the analog clock:</p>
<pre name="code" class="actionscript" style="width: 550px; overflow:scroll;">package com.clock.analog
{
	import com.clock.clock;

	public class AnalogClock extends clock
	{
		public var face:AnalogClockFace;

		/**
		 * constructor
		 *
		 * @param Number faceSize, Size of the clock
		 * @param Number correctionX, pixel position correction
		 * @param Number correctionY, pixel position correction
		 *
		 */
		public function AnalogClock(faceSize:Number,correctionX:Number, correctionY:Number):void
		{
			super();

			this.face = new AnalogClockFace(Math.max(20, faceSize),correctionX, correctionY);
			this.face.init();
			this.face.draw(this.getCurrentTime());
			addChild(this.face);
		}

		/**
		 * override function for parents draw method
		 */
		protected override function draw():void
		{
			this.face.draw(this.getCurrentTime());
		}
	}
}
</pre>
<p>As you can see for the analog clock we import the clock model since the analog clock inherits from this model. The fancy part is the constructor we are looking at. Normally you will have to import another class before you can create a instance of it, but in this case I decided to place the view for the analog clock in the same folder as the analog clock model. this way, thanks  to the flash API, the class is loaded automatically while i create the instance. Since we got only one view and one model for the analog clock to my mind it made perfectly sense to place &#8216;em in the same folder.</p>
<p>But lets take a closer look. What the constructor basically does is to create an instance of the view called AnalogClockFace, give the width of the analog clock, and since I got a fancy analog clock with a shadow and all that stuff I also needed the possibility to correct the starting point for the clock hands. Afterwards the view is initiated and its draw method called to get the clock rendered. Last but not least we add this child to the analog clock so that it is displayed.</p>
<p>You will notice that there is also the draw method that we already know from the parent clock model. Like in Java and unlike php, to override the parents method we have to declare this method with the param override, otherwise you will get a fatal error at compiling our clock. What it does is quite simple, it just calls the public draw method of the view over and over again each time it is called to redraw the clock so that the current time is shown.</p>
<p>Now lets take a look at the digital clock model. As you might imagine it is quite the same, but with some slight differences.</p>
<pre name="code" class="actionscript" style="width: 550px; overflow:scroll;">package com.clock.digital
{
	import com.clock.clock;

	import flash.text.*;

	public class DigitalClock extends clock
	{
		private var clock:DigitalClockFace;

		public function DigitalClock(theme:String)
		{
			super();
			this.clock = new DigitalClockFace(theme, 275);
			addChild(this.clock);
		}

		protected override function draw():void
		{
			this.clock.setTime(this.getCurrentTime());
		}
	}
}
</pre>
<p>We also got our constructor that creates a instance of the view (this time DigitalClockFace) and adds it to the parent class stage, and we also got our override draw method that will set the time for the digital clock. The only major difference is the param theme that is passed through. This is simply a string holding the name of the current clock theme, so that the view knows witch theme to apply.</p>
<p>By now we have all the basic models we need for the clock. Lets go on to the views so we get something displayed.<br />
First we will start with the analog clock again.</p>
<pre name="code" class="actionscript" style="width: 550px; overflow:scroll;">package com.clock.analog
{
    //impotant provides a method to set RegPoint
    import com.DynamicMovie.DynamicMovie;

    import flash.display.Loader;
    import flash.display.MovieClip;
    import flash.events.*;
    import flash.net.URLRequest;

    /**
     * Displays a round clock face with an hour hand, a minute hand, and a second hand.
     */
    public class AnalogClockFace extends MovieClip
    {
	/**
	 * The desired width of this component, as opposed to the .width
	 * property which represents tha actual width.
	 */
	public var w:uint = 256;

	/**
    	 * The radius from the center of the clock to the
    	 * outer edge of the circular face outline.
    	 */
        public var radius:uint;

        /**
         * The coordinates of the center of the face.
         */
        public var centerX:int;
        public var centerY:int;

	private var clockFace:DynamicMovie = new DynamicMovie();
	private var clockHandHour:DynamicMovie = new DynamicMovie();
	private var clockHandMinutes:DynamicMovie = new DynamicMovie();
	private var clockHandSeconds:DynamicMovie = new DynamicMovie();
	private var clockHandJoint:DynamicMovie = new DynamicMovie();

	private var clockParts:uint = 0;

        /**
         * Stores a snapshot of the current time, so it
         * doesn't change while in the middle of drawing the
         * three hands.
         */
        public var currentTime:Date;

        /**
         * Contructs a new clock face. The width and
         * height will be equal.
         */
        public function AnalogClockFace(w:uint, correctionX:Number, correctionY:Number):void
        {
			this.radius = Math.round(w / 2);
			this.centerX = this.radius + correctionX;
			this.centerY = this.radius + correctionY;
        }

        /**
         * Creates the outline, hour labels, and clock hands.
         */
        public function init():void
        {
			createClock();
        }

        /**
        * Creates hour, minute, and second hands using the 2D drawing API.
        */
        public function createClock():void
        {
			loadImage(this.clockFace,'img/analog_clock.png', 0,0, true);
			loadImage(this.clockHandSeconds,'img/sekunde.png');
			loadImage(this.clockHandMinutes,'img/minute.png');
			loadImage(this.clockHandHour,'img/stunde.png');
			loadImage(this.clockHandJoint, 'img/gelenk.png', -3, -3);
        }

	protected function loadImage(clockPart:DynamicMovie, clockPartUrl:String, correctionX:Number = 0, correctionY:Number = 0, isClockFace:Boolean = false):void
	{

		var imageLoader:Loader = new Loader();
		imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoad);
		imageLoader.load(new URLRequest(clockPartUrl));

		clockPart.addChild(imageLoader);
		if(!isClockFace)
		{
			clockPart.x = this.centerX + correctionX;
			clockPart.y = this.centerY + correctionY;
		}
	}

	private function onImageLoad(e:Event):void
	{
		var regPoint:Number = e.target.content.width / 2;
		e.target.content.parent.parent.setRegistration(2.5,2.5);
		this.registerClockPart();
	}

	private function registerClockPart():void
	{
		this.clockParts++;
	}

       /**
        * Called by the parent container when the display is being drawn.
        */
        public function draw(time:Date):void
        {
			if(this.clockParts == 5)
			{
				addChild(this.clockFace);
				addChild(this.clockHandSeconds);
				addChild(this.clockHandMinutes);
				addChild(this.clockHandHour);
				addChild(this.clockHandJoint);

				showTime(time);
			}
        }

        /**
         * Displays the given Date/Time in that good old analog clock style.
         */
        public function showTime(time:Date):void
        {
        	// Gets the time values
	        var seconds:uint = time.getSeconds();
	        var minutes:uint = time.getMinutes();
	        var hours:uint 	 = time.getHours();

		if(hours &gt; 12){
			hours -= 12;
		}

	        // Multiplies by 6 to get degrees
	        this.clockHandSeconds.rotation2 = 180 + (seconds * 6);
	        this.clockHandMinutes.rotation2 = 180 + (minutes * 6);

	        // Multiplies by 30 to get basic degrees, and then
	        this.clockHandHour.rotation2 = 180 + (hours * 30);
	}
    }
}
</pre>
<p>First thing you might notice is the import statement &#8220;import com.DynamicMovie.DynamicMovie;&#8221;, this was the first trap I ran into while coding the clock, and it took me quite a while to find the solution for that a uncle googles. I learned that it is impossible to set the registration point of a MovieClip object by actionscript, but we need the registration point to be set to let the clock hands move in a nice round circle. The DynamicMovie class is the solution to that problem, it is a simple workaround provided by Oscar Trelles you can download on his website.</p>
<p>All the other stuff is pretty basic coding. We create a clock, load its images, and let the clockhands rotate the amount that is needed to diplay the correct time. The only difference you might notice to basic AS3 code are two methods that are new here and where provided by the DynamicMovie class. First is setRegistration at the onImageLoad eventhandler which simply sets the registrationpoint x and y coordinates. The second method that is new is rotation2 which provides you with a rotation method that simply takes registrationpoint into count for the rotation to perfom.</p>
<p>Analog clock is done lets move on to the digital clock and all of its traps Actionscript has for us.</p>
<pre name="code" class="actionscript" style="width: 550px; overflow:scroll;">package com.clock.digital
{
	import com.clock.loader.ImageLoader;

	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.events.*;
	import flash.net.URLRequest;

	public class DigitalClockFace extends MovieClip
	{
		private var clockFace:MovieClip 			= new MovieClip();
		private var currentTimeDisplay:MovieClip 	= new MovieClip();

		private var digitContainer_0:DigitContainer = new DigitContainer();
		private var digitContainer_1:DigitContainer = new DigitContainer();
		private var digitContainer_2:DigitContainer = new DigitContainer();
		private var digitContainer_3:DigitContainer = new DigitContainer();
		private var digitsLoaded:Number			= 0;

		private var clockTheme:MovieClip			= new MovieClip();
		private var clockThemeName:String;
		private var clockWidth:Number;

		private var position:Number = 0;
		private var lastTimeDisplay:Array = new Array();

		private var imageLoader:ImageLoader  = new ImageLoader();

		/**
		 * constructor
		 *
		 * @param String theme, the name of the current theme
		 * @param Number width, the width of the digital clock
		 *
		 * @return void
		 */
		public function DigitalClockFace(theme:String, width:Number):void
		{
			this.clockWidth = width;
			this.clockThemeName = theme;
			this.createClockTheme();
		}

		/**
		 * loader for the clockTheme
		 *
		 * @return void
		 */
		protected function createClockTheme():void
		{
			var clockFaceThemeLoader:Loader = new Loader();
			clockFaceThemeLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onClockThemeImageLoad);
			clockFaceThemeLoader.load(new URLRequest('img/digital/theme/bg_theme_'+this.clockThemeName+'.png'));
		}

		/**
		 * event handler that is called the moment the theme image
		 * is loaded.
		 *
		 * Creates the background image
		 * loads the default dots on top
		 * loads the time display and sets its opacity to 0.4
		 * loads the clockFace with the refection
		 *
		 * param Event e, the event object
		 */
		protected function onClockThemeImageLoad(e:Event):void
		{
			// container Movie :e.target.content.parent.parent
			var i:Number = 0;
			trace(this.clockWidth);
			for(i = 0; i &lt; this.clockWidth; i++)
			{
				var image:Bitmap = new Bitmap(e.target.loader.contentLoaderInfo.content.bitmapData.clone());
				this.clockTheme.addChild(image);
				image.x = i;
			}
			addChild(this.clockTheme);

			this.loadDefaultDots();
			this.imageLoader.loadImage(this.currentTimeDisplay, 'img/digital/dot_doppelpunkt.png', 123);

			this.currentTimeDisplay.alpha  = 0.4;
			this.currentTimeDisplay.y = 2;
			addChild(this.currentTimeDisplay);

			this.imageLoader.loadImage(this.clockFace, 'img/digital/digitalClock_face.png');
			addChild(this.clockFace);

			this.loadDigitContainers();
		}

		/**
		 * helper method to load the default dots
		 */
		protected function loadDefaultDots():void
		{
			var dotsLoader:Loader = new Loader();
			dotsLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onDotsLoaderImageLoad);
			dotsLoader.load(new URLRequest('img/digital/dot_default.png'));

		}

		/**
		 * event handler for the default dots loader
		 * will attach the loaded image to the stage (3 times)
		 * and position them properly
		 *
		 * param Event e, the event object
		 */
		protected function onDotsLoaderImageLoad(e:Event):void
		{
			var i:Number = 0;
			for(i = 0; i &lt; 3; i++){
				var image:Bitmap = new Bitmap(e.target.loader.contentLoaderInfo.content.bitmapData.clone());
				this.currentTimeDisplay.addChild(image);
				switch(i)
				{
					case 1:
						image.x =  9;
						break;
					case 2:
						image.x = 255;
						break;
					case 0:
						image.x = -9;
						break;
				}
			}
		}

		/**
		 * Loads digitcontainers and add them to the stage
		 * on their position
		 */
		protected function loadDigitContainers():void
		{
			this.populateDigitContainers();

			this.currentTimeDisplay.addChild(this.digitContainer_0);
			this.currentTimeDisplay.addChild(this.digitContainer_1);
			this.currentTimeDisplay.addChild(this.digitContainer_2);
			this.currentTimeDisplay.addChild(this.digitContainer_3);

			this.digitContainer_0.x = 27;
			this.digitContainer_1.x = 75;
			this.digitContainer_2.x = 159;
			this.digitContainer_3.x = 207;
		}

		/**
		 * Helper function to add the number images to the digits containers
		 */
		protected function populateDigitContainers():void
		{
			var i:Number = 0;
			for(i=0; i &lt; 10; i++)
			{
				var clockFaceNumLoader:Loader = new Loader();
				clockFaceNumLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onClockFaceNumImageLoad);
				clockFaceNumLoader.load(new URLRequest('img/digital/dot_'+ i +'.png'));
			}
		}

		/**
		 * Event handler for populateDigitContainers
		 * will add the loaded image to an array inside the digitcontainer.
		 *
		 * if all images are loaded will add them to the clockFacNumContainers
		 * by calling loadImagesToContainers
		 *
		 * @param Event e, the image loaded event
		 */
		protected function onClockFaceNumImageLoad(e:Event):void
		{

			trace(e.target.loader.contentLoaderInfo.url);
			this.digitsLoaded ++;
			var i:Number = 0;
			for(i = 0; i &lt; 4; i++)
			{
				var image:Bitmap = new Bitmap(e.target.loader.contentLoaderInfo.content.bitmapData.clone());
				var url:String = e.target.loader.contentLoaderInfo.url;
				var pos:String = url.substr(-5, 1);
				this["digitContainer_"+i].pushImage(image, pos);
			}

			if(this.digitsLoaded == 10){
				this.digitContainer_0.loadImagesToContainers();
				this.digitContainer_1.loadImagesToContainers();
				this.digitContainer_2.loadImagesToContainers();
				this.digitContainer_3.loadImagesToContainers();
			}
		}

		/**
		 * helper method to set the current Time in Display
		 */
		public function setTime(time:Date):void
		{
			var currentMinutes:int	= time.getMinutes();
			var currentHours:int 	= time.getHours();

			this.addTimeToDisplay(currentHours);
			this.addTimeToDisplay(currentMinutes);

		}

		/**
		 * will add the current time to display
		 *
		 * @param int time, the two digits of hous __or__ minutes
		 */
		private function addTimeToDisplay(time:int):void
		{
			var firstDigit:String;
			var secondDigit:String;
			var timeString:String = time.toString();

			if(time &lt; 10) 			{ 				firstDigit  = "0"; 				secondDigit = timeString; 			}else{ 				firstDigit  = timeString.substr(0,1); 				secondDigit = timeString.substr(1,1); 			} 			 			this.removeLastDigits(); 			 			this.addDigit(firstDigit); 			this.addDigit(secondDigit); 			 			if(this.lastTimeDisplay.length == 4) 			{ 				this.lastTimeDisplay = new Array(); 			} 			 			this.lastTimeDisplay.push(firstDigit); 			this.lastTimeDisplay.push(secondDigit); 		} 		 		/** 		 * shows the current digit on the display 		 *  		 * param String digit, the current digit 		 */ 		private function addDigit(digit:String):void 		{ 			this["digitContainer_"+this.position].showNumber(digit); 			 			this.position++; 			if(this.position &gt; 3)
			{
				this.position = 0;
			}
		}

		/**
		 * will remove the previously shown digits
		 */
		private function removeLastDigits():void
		{
			if(this.lastTimeDisplay.length == 4){
				for(var i:Number = 0; i &lt; this.lastTimeDisplay.length; i++)
				{
					this.removeDigit(this.lastTimeDisplay[i], i);
				}
			}
		}

		/**
		 * helper method that call the removeNumber method on the digit container
		 */
		private function removeDigit(digit:String, container:Number):void
		{
			this["digitContainer_"+container].removeNumber(digit);
		}
	}
}
</pre>
<p>By reading this view class you might notice &#8220;import com.clock.loader.ImageLoader;&#8221; this is simply a imageloader method I created to avoid redoing the basic imageload method over and over again. The next new thing is far more interesting &#8220;&#8230; = new DigitContainer()&#8221;. This is the solution I came up with because of one of the most anoying &#8220;features&#8221; of Flash I ever came accross. It is simply impossible to assign the same instance of a DisplayObject to different parent DisplayObject, which means that you have to create n 100% equal instances of the same object if you want to use it n times in your flash movie. That´s why I had to come up with the helper class for the digits to put &#8216;em into a container that provides me with a way to show the digitis of the current time.</p>
<pre name="code" class="actionscript" style="width: 550px; overflow:scroll;">package com.clock.digital
{
	import com.clock.loader.ImageLoader;

	import flash.display.Bitmap;
	import flash.display.MovieClip;

	public class DigitContainer extends MovieClip
	{

		public var clockFaceNum_0:MovieClip = new MovieClip();
		public var clockFaceNum_1:MovieClip = new MovieClip();
		public var clockFaceNum_2:MovieClip = new MovieClip();
		public var clockFaceNum_3:MovieClip = new MovieClip();
		public var clockFaceNum_4:MovieClip = new MovieClip();
		public var clockFaceNum_5:MovieClip = new MovieClip();
		public var clockFaceNum_6:MovieClip = new MovieClip();
		public var clockFaceNum_7:MovieClip = new MovieClip();
		public var clockFaceNum_8:MovieClip = new MovieClip();
		public var clockFaceNum_9:MovieClip = new MovieClip();

		private var imageLoader:ImageLoader  = new ImageLoader();

		private var images:Array			 = new Array();

		/**
		 * constructor
		 */
		public function DigitContainer():void
		{
			super();
		}

		/**
		 * show the currentNumber on the stage
		 *
		 * @param String currentNumber
		 */
		public function showNumber(currentNumber:String):void
		{
			addChild(this["clockFaceNum_"+currentNumber]);
		}

		/**
		* remove the currentNumber from the stage
		*
		* @param String currentNumber
		*/
		public function removeNumber(currentNumber:String):void
		{
			removeChild(this["clockFaceNum_"+currentNumber]);
		}

		/**
		 * push image type Bitmap to images array on a specific position
		 *
		 * @param Bitmap image, the current Number image
		 * @param String pos, position in array
		 */
		public function pushImage(image:Bitmap, pos:String):void
		{
			this.images[pos] = image;
		}

		/**
		 * helper methods that loads the images in their order
		 * to their containers
		 */
		public function loadImagesToContainers():void
		{
			var i:Number = 0;
			for(i = 0; i &lt; this.images.length; i++)
			{
				this["clockFaceNum_"+i].addChild(this.images[i]);
			}
		}
	}
}
</pre>
<p>So here we go digital clock also ready to run. Last we have to build the model for the alarm as well as the view for the alarm that should be displayed. First we will need the alarm model to handle the alarm event.</p>
<pre name="code" class="actionscript" style="width: 550px; overflow:scroll;">package com.clock.events
{
	import flash.events.Event;

	/**
	 * This custom Event class adds a message property to a basic Event.
	 */
	public class AlarmEvent extends Event
	{
		/**
		 * The name of the new AlarmEvent type.
		 */
		public static const ALARM:String = "alarm";

		/**
		 * A text message that can be passed to an event handler
		 * with this event object.
		 */
		public var message:String;

		/**
		 *  Constructor.
		 *  @param message The text to display when the alarm goes off.
		 */
		public function AlarmEvent(message:String = "ALARM!")
		{
			super(ALARM);

			this.message = message;
		}

		/**
		 * Creates and returns a copy of the current instance.
		 * @return	A copy of the current instance.
		 */
		public override function clone():Event
		{
			return new AlarmEvent(message);
		}

		/**
		 * Returns a String containing all the properties of the current
		 * instance.
		 * @return A string representation of the current instance.
		 */
		public override function toString():String
		{
			return formatToString("AlarmEvent", "type", "bubbles", "cancelable", "eventPhase", "message");
		}
	}
}
</pre>
<p>The alarm model is basically a event so the alarm inherits from the event class. As you can see it is pretty basic stuff. The view model is a little bit more complicated. thought the alarms to display look a little bit different.</p>
<pre name="code" class="actionscript" style="width: 550px; overflow:scroll;">package com.clock.alarm
{
	import com.clock.events.AlarmEvent;
	import com.clock.fonts.Tahoma;
	import com.clock.loader.ImageLoader;
	import com.clock.sound.AlarmSound;

	import flash.display.MovieClip;
	import flash.events.*;
	import flash.external.ExternalInterface;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.text.Font;

	public class AlarmContainer extends MovieClip
	{

		private var AlarmSoundStorage:AlarmSound;
		private var AlarmMessage:TextField;
		private var AlarmButton:MovieClip  = new MovieClip();
		private var AlarmOverlay:MovieClip = new MovieClip();

		private var clockType:String;

		private var imageLoader:ImageLoader  = new ImageLoader();

		//private var Fontester:Tahoma = new Tahoma();

		/**
		 * constructor
		 */
		public function AlarmContainer():void
		{
			super();

			// load alarm sound
			this.AlarmSoundStorage = new AlarmSound('sound/alarm.mp3');
		}

		/**
		 * getter for the alarmtime
		 *
		 * @return Date
		 */
		public function getAlarmTime():Date
		{
			var alarmPropertyTime:String 	= ExternalInterface.call('getAlarmTime');

			var alarmTimeArray:Array 		= alarmPropertyTime.split(' ');
			var alarmDate:Array 			= alarmTimeArray[0].split('.');
			var alarmDateTime:Array 		= alarmTimeArray[1].split(':');

			var alarmTime:Date = new Date(alarmDate[2],alarmDate[1]-1,alarmDate[0],alarmDateTime[0],alarmDateTime[1]);
			return alarmTime;
		}

		/**
		 * eventhandler for the alarm
		 */
		public function onAlarm(e:AlarmEvent):void
		{
			trace('ALARM FIRED');
			this.AlarmSoundStorage.initSound();
			// configure Layout and position of alarm message
			this.configureAlarmMessage();
			// set the message
			this.AlarmMessage.text = e.message;
			// Load overlay
			this.loadAlarmOverlay();
			this.showOverlay();
		}

		/**
		 * setter for the clock Type
		 */
		public function setClockType(clockType:String):void
		{
			this.clockType = clockType;
		}

		/**
		 * config for the alarm to display
		 */
		private function configureAlarmMessage():void
		{
			var textFormat:TextFormat = new TextFormat();
			textFormat.font 	= "Arial";
			textFormat.size 	= 14;
			textFormat.color 	= 0xFFFFFF;

			this.AlarmMessage = new TextField();
			this.AlarmMessage.defaultTextFormat = textFormat;
			this.AlarmMessage.wordWrap = true;
			//this.AlarmMessage.embedFonts = true;

			switch(this.clockType)
			{
				case "analog":
					this.AlarmMessage.x = 130;
					this.AlarmMessage.y = 80;
					this.AlarmMessage.width = 65;
					this.AlarmMessage.height = 60;
					break;

				case "digital":
					this.AlarmMessage.x = 80;
					this.AlarmMessage.y = 10;
					this.AlarmMessage.width = 90;
					this.AlarmMessage.height = 50;
					break;
			}

		}

		/**
		 * shows the overlay on the Alarm event
		 */
		private function showOverlay():void
		{
			trace('overlay displayed');
			addChild(this.AlarmOverlay);
			addChild(this.AlarmButton);
			this.AlarmOverlay.addChild(this.AlarmMessage);

		}

		/**
		 * handles the event if the stop Button is clicked
		 */
		private function stopClicked(e:MouseEvent):void
		{
			trace ('Stop Button Clicked');

			this.AlarmSoundStorage.stopAlarmSound();
			removeChild(this.AlarmButton);
			removeChild(this.AlarmOverlay);
			this.AlarmOverlay.removeChild(this.AlarmMessage);
		}

		/**
		 * loads the alarm overlay depending on the current clock face
		 */
		private function loadAlarmOverlay():void
		{
			this.AlarmButton.addEventListener(MouseEvent.CLICK, stopClicked);
			trace('overlay loaded');
			switch(this.clockType)
			{
				case "analog":
					trace('overlay loaded analog');
					this.imageLoader.loadImage(this.AlarmOverlay, 'img/alarm/analog_alarm.png', 47, 40);
					this.imageLoader.loadImage(this.AlarmOverlay, 'img/alarm/alarm_clock.png', 57, 65);
					this.imageLoader.loadImage(this.AlarmButton, 'img/alarm/alarmbutton_close.png', 50, 50);
					break;
				case "digital":
					trace('overlay loaded digital');
					this.imageLoader.loadImage(this.AlarmOverlay, 'img/alarm/digital_alarm.png');
					this.imageLoader.loadImage(this.AlarmOverlay, 'img/alarm/alarm_clock.png');
					this.imageLoader.loadImage(this.AlarmButton, 'img/alarm/alarmbutton_close_digital.png');
					break;
			}
		}
	}
}
</pre>
<p>As you can see this is also pretty basic stuff, some imageloading and a sound that is loaded. A pretty anoying beep. And there is a little thing you might notice : &#8220;ExternalInterface.call(&#8216;getAlarmTime&#8217;);&#8221;. This is the nice way to communicate with the hosting html page. Basically what this does is to call a javascript function and get its<br />
return value. In this case the getAlarmTime method calls a json on the server to get the alarmtime out of the db via Java.</p>
<p>So here we are, we got the clock, the analog and the digital clock face as well as the alarm. Last thing missing is the start, the controller.<br />
Even this is easy if you know what you are doing:</p>
<pre name="code" class="actionscript" style="width: 550px; overflow:scroll;">package
{
	import com.clock.alarm.AlarmContainer;
	import com.clock.analog.AnalogClock;
	import com.clock.digital.DigitalClock;
	import com.clock.events.AlarmEvent;

	import flash.display.MovieClip;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.external.ExternalInterface;
	import flash.text.*;

	public class clockWidget extends MovieClip
	{
		private var digitalClock:DigitalClock;
		private var analogClock:AnalogClock;

		private var Alarm:AlarmContainer = new AlarmContainer();
		private var ClockLayout:String;

		/**
		 * constructor
		 */
		public function clockWidget()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align 	= StageAlign.TOP_LEFT;

			// set layout from js
			this.setClockLayout();

			// set alarmtime from js
			this.setAlarm();
		}

		/**
		 * setter for clocklayout
		 */
		protected function setClockLayout():void
		{
			this.ClockLayout = ExternalInterface.call('getClockLayout');
			this.Alarm.setClockType(this.ClockLayout);

			switch(this.ClockLayout)
			{
				case 'analog':
					this.initAnalogClock();
					break;

				case 'digital':
					this.initDigitalClock();
					break;
			}
			//var e:AlarmEvent = new AlarmEvent();
			//this.Alarm.onAlarm(e);
		}

		/**
		 * init for analog clock layout
		 */
		protected function initAnalogClock():void
		{
			// get LayoutVars form page
			var clockSize:Number 			= ExternalInterface.call('getClockLayoutWidth');
			var clockSizeXCorrection:Number = ExternalInterface.call('getClockLayoutXCorrection');
			var clockSizeYCorrection:Number = ExternalInterface.call('getClockLayoutYCorrection');

			this.analogClock = new AnalogClock(clockSize, clockSizeXCorrection, clockSizeYCorrection);
			this.analogClock.startClock();
			this.analogClock.x = 10;
			this.analogClock.y = 10;

			addChild(this.analogClock);
		}

		/**
		 * init for digital clock layout
		 */
		protected function initDigitalClock():void{
			var digitalClockTheme:String = ExternalInterface.call('getDigitalClockTheme');
			this.digitalClock = new DigitalClock(digitalClockTheme);
			this.digitalClock.startClock();

			addChild(this.digitalClock);
		}

		/**
		 * setter for the alarm
		 * will add an event handler
		 */
		private function setAlarm():void
		{
			var now:Date = new Date();
			var alarmLocalTime:Date = this.Alarm.getAlarmTime();
			var alarmMessage:String = ExternalInterface.call('getAlarmMessage');

			if(alarmLocalTime &gt;= now
			&amp;&amp; alarmLocalTime.getDay() == now.getDay()
			&amp;&amp; alarmLocalTime.getMonth() == now.getMonth()
			&amp;&amp; alarmLocalTime.getFullYear() == now.getFullYear())
			{
				switch(this.ClockLayout)
				{
					case 'analog':
						this.analogClock.setAlarm(alarmLocalTime.getHours(),alarmLocalTime.getMinutes(),alarmMessage);
						this.analogClock.addEventListener(AlarmEvent.ALARM, this.Alarm.onAlarm);
						break;
					case 'digital':
						this.digitalClock.setAlarm(alarmLocalTime.getHours(),alarmLocalTime.getMinutes(),alarmMessage);
						this.digitalClock.addEventListener(AlarmEvent.ALARM, this.Alarm.onAlarm);
						break;
				}
			}

			addChild(this.Alarm);
		}

	} // class end

} //package end
</pre>
<p>First we get the clocklayout, as well from the return of a js method within the hosting page, afterwards we get our selfs the alarmtime that was set by the user.<br />
Clock is up and running.</p>
<p>Although I can not provide you with the graphics due of my current contract and the copyright I am able to give you the code as a whole.<br />
<a href="http://www.swift-lizard.com/wp-content/uploads/2009/12/flash_clock_src.zip#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed">Here you can get the Flash clock sources.</a></p>
<p>Hope you enjoyed the show.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.swift-lizard.com/2009/12/31/developing-a-clock-widget-in-flash-with-as3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Javascript leashed with google Caja</title>
		<link>http://www.swift-lizard.com/2009/12/19/javascript-leashed-with-google-caja/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://www.swift-lizard.com/2009/12/19/javascript-leashed-with-google-caja/#comments</comments>
		<pubDate>Sat, 19 Dec 2009 00:16:50 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[caja]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://www.swift-lizard.com/?p=230</guid>
		<description><![CDATA[Like I wrote recently I am contracted at a German ISP at the moment to build a new Portal where one can put several different widgets on his or her personal web page. Similar to igoogle. My customer also wants to provide the possibility of own widgets to external developers, so to avoid security issues [...]]]></description>
			<content:encoded><![CDATA[<p>Like I wrote recently I am contracted at a German ISP at the moment to build a new Portal where one can put several different widgets on his or her personal web page. Similar to igoogle. My customer also wants to provide the possibility of own widgets to external developers, so to avoid security issues we will need to sandbox each of those widgets, but like we all know that can be a serious problem when it comes to the &#8220;evil unleashed monster&#8221; javascript. So in order to leash it inside a sandbox on a secure chain we came across <a title="Google Caja project page" href="http://code.google.com/p/google-caja/" target="_blank">google caja</a>.<span id="more-230"></span></p>
<p>Caja is a project started by google a few years ago to provide a way to safely embed third party DHTML code on your own web page, as well as rich communication interfaces between the embedding page and the embedded applications. Normally to embed third party code one would use iframes, but with the capability of javascript to communicate between frames this can be a serious security breach.</p>
<p>At this point google caja provides you with a neat solution. First of all you will not need any iframes to embed third party code on your web page safely, the java based cajoler will provide you with html and javascript that is sand-boxed and secure to embed once it is cajoled. Don&#8217;t get me wrong, Java will only be needed to compile possibly hazardous code once, into the cajoled secure  code one can use on his website. After that it is all done by the javascript libraries provided by the caja project.</p>
<p>But let me show you how the magic works.</p>
<p>First of all you will need to install some software:</p>
<ul>
<li><a rel="nofollow" href="http://java.sun.com/javase/downloads/index.jsp">JDK</a> 6</li>
<li>The <a rel="nofollow" href="http://subversion.tigris.org/project_packages.html">subversion</a> version manager</li>
<li>The <a rel="nofollow" href="http://ant.apache.org/manual/install.html">Apache Ant</a> build system.</li>
<li>The <a rel="nofollow" href="http://sourceforge.net/project/showfiles.php?group_id=15278&amp;package_id=12472">JUnit</a> testing framework.  Just drop junit.jar&lt;/tt&gt; in the $ANT_HOME/lib directory you set up for Ant.</li>
</ul>
<p>Then create some folders for your caja project, for this I assume you will use Linux or Mac OS:</p>
<pre name="code" class="java">

mkdir caja
cd caja
mkdir svn-changes
cd svn-changes
mkdir pristine
cd pristine
</pre>
<p>After you have done this you will need to check out caja from the SVN &#8211; Repository:</p>
<pre name="code" class="java">svn checkout http://google-caja.googlecode.com/svn/trunk/ google-caj</pre>
<p>Following the wiki of the caja project I assumed simply running &#8220;ant demos&#8221; on the console would provide me with some working demos. To make a long story of yelling and cursing short, no it didn`t. After long sessions of trail and error and a post on the discussion board where Jasvir Nagra pointed me in the right direction I found out why.</p>
<p>First of all several sources of the projects wiki as well as the sources compiled by ant will show you that you have to integrate the valija js the following way:</p>
<pre name="code" class="html">&lt;script src="valija.co.js" type="text/javascript"&gt;&lt;/script&gt;</pre>
<p>;<br />
What´s the problem with that ? There is simply no valija.co.js anywhere in the whole project !! But there is a &#8220;valija.out.js&#8221;. Simply use that file name and one of your setup problems will be gone. Yes right, one, there are several more traps I will show you.</p>
<p>Next thing you will notice, running firebug, is that cajoling source ,either via applet or via war (generated via ant playground), will not work but return a 500 Internal Server error.</p>
<p>Though I am a huge fan of software running out of the box I assumed that running either &#8220;ant playground&#8221; or &#8220;ant demos&#8221; ( / &#8220;ant testbed&#8221; for testbed only) would provide me with a running demo to play with. It didn´t. The reason why I found out after I had setup jetty Java server in debug mode, like Jasvir suggested. The log then showed me that some nu.validator.* library was missing in my jar file that was compiled by ant. Because I had been looking through all the project files and folders at my days of yelling and cursing I new where to find it. This Lib with all the needed classes is stored in &#8220;$cajaSourceFolder/third-party/java/htmlparser/src&#8221;. So there is a simply solution for that, simply copy the &#8220;nu&#8221; &#8211; folder to &#8220;$cajaSourceFolder/src&#8221; and run &#8220;ant testbed&#8221; or &#8220;ant playground&#8221; again.</p>
<p>Tada,&#8230; problem solved. Either you will get a working testbed by now or a working playground war.</p>
<p>To play at the playground I would suggest that you use jetty. The use of the server to my mind is quite easy. Simply download the src <a href="http://dist.codehaus.org/jetty/jetty-hightide-7.0.1/" target="_blank">here</a>, unpack it, switch to the folder and run:</p>
<pre name="code" class="java">
$cajaSourceFolder: ant playground
$jettyHomeDir/webapps:ln -s $cajaHomeDir/ant-war caja-playground
cd ..
$jettyHomeDir: java -jar start.jar etc/jetty-logging.xml etc/jetty.xml
</pre>
<p>By now you will have jetty running on port 8080 at localhost and caja-playground can be found at:</p>
<p>http://localhost:8080/caja-playground</p>
<p>But we don´t only want to play do we ? <img src='http://www.swift-lizard.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>So after playing around a little bit with either the playground or the testbed application I assume you would like to use what you have produced with either of those in a simple host page. Ten years of doing this job by now I thought the wiki might provide me with a simple solution for a host page that would be working right away. Hhmmm sorry nope. Wrong again. It does not.</p>
<p>Don`t get me wrong there is an example. It simply does not work with the code that you can download at the projects page. Simple as that. But this could not keep me from setting up one simple example, by braking down the playgrounds web page to the minimum needed to get it running.</p>
<p>Same procedure as every year Ms Sofia ? Same procedure as every year James. If nothing helps reverse engineering does it each and every time.</p>
<p>The nice guy I am I will save you some time and give you a step by step of what is needed to get the cajoled code running in a simple as can be host page.</p>
<p>First thing you will need to get the cajoled code running will be this inside the body tag of your page:</p>
<pre name="code" class="html">
&lt;!-- Load all needed scripts --&gt;
     &lt;script src="cajita.js" type="text/javascript"&gt;&lt;/script&gt;
     &lt;script src="unicode.js" type="text/javascript"&gt;&lt;/script&gt;
     &lt;script src="css-defs.js" type="text/javascript"&gt;&lt;/script&gt;
     &lt;script src="html4-defs.js" type="text/javascript"&gt;&lt;/script&gt;
     &lt;script src="html-sanitizer.js" type="text/javascript"&gt;&lt;/script&gt;
     &lt;script src="html-emitter.js" type="text/javascript"&gt;&lt;/script&gt;
     &lt;script src="setup-valija.js" type="text/javascript"&gt;&lt;/script&gt;
     &lt;script src="bridal.js" type="text/javascript"&gt;&lt;/script&gt;
     &lt;script src="domita.js" type="text/javascript"&gt;&lt;/script&gt;
     &lt;script src="valija.out.js" type="text/javascript"&gt;&lt;/script&gt;
</pre>
<p>The next step will be to provide a method that will assign the containers for your cajoled widget:</p>
<pre name="code" class="html">
&lt;script type="text/javascript"&gt;
  var imports = ___.copy(___.sharedImports);
  var gadgetRoot = "";
  imports.outers = imports;

  function setGadgetContainer(containerId){
    gadgetRoot = document.getElementById(containerId);
    imports.htmlEmitter___ = new HtmlEmitter(gadgetRoot);
    attachDocumentStub('-g___', {
      rewrite: function(){
        return null;
      }
    }, imports, gadgetRoot);
    imports.$v = valijaMaker.CALL___(imports.outers);
    ___.getNewModuleHandler().setImports(imports);
  }
&lt;/script&gt;
</pre>
<p>This code simply initiates the base for caja and assigns a container for the widget. But lets go on with the html you will need for your page:</p>
<pre name="code" class="html">
&lt;div id="cajoled-output" class="g___"&gt;
           {Here goes the html output of the cajoler}&lt;/div&gt;

&lt;!-- Load widget 1 --&gt;
&lt;script type="text/javascript"&gt;setGadgetContainer("cajoled-output");&lt;/script&gt;
&lt;!-- The Cajoled javascript output put in an external file --&gt;
&lt;script src="widgets/widget1.vo.js" type="text/javascript"&gt;&lt;/script&gt;
</pre>
<p>You might have recognized the &#8221; class=&#8217;g___&#8217; &#8221; that is also mentioned in the js method. This is nescessary for the html code rendered dynamicly by the caja libary to assign the content to the container.</p>
<p>This is it. If you followed the instructions you should have a working google caja playground, demo, webservice and jetty server by now as well as a working basic stand alone page witch will run you cajoled code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.swift-lizard.com/2009/12/19/javascript-leashed-with-google-caja/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>jQuery sortable with Iframes in FireFox</title>
		<link>http://www.swift-lizard.com/2009/11/15/jquery-sortable-with-iframes-in-firefox/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://www.swift-lizard.com/2009/11/15/jquery-sortable-with-iframes-in-firefox/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 22:33:32 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://swift-lizard.com/?p=98</guid>
		<description><![CDATA[I came across this problem a week ago when I tried to develop an interface between an Iframe, or in Detail it&#8217;s content, and the iframes parent page. Turns out that the following code wouldn´t work in FireFox although all other browsers, yes even our friend the Internet Explorer, would behave as expected.
   [...]]]></description>
			<content:encoded><![CDATA[<p>I came across this problem a week ago when I tried to develop an interface between an Iframe, or in Detail it&#8217;s content, and the iframes parent page. Turns out that the following code wouldn´t work in FireFox although all other browsers, yes even our friend the Internet Explorer, would behave as expected.<span id="more-98"></span></p>
<pre name="code" class="javascript">   function accessIframeJS(IframeName, methodName, methodParams)
   {
    var  IFrameObj  = window.frames[IframeName];
    var  methodCall = "IFrameObj."+methodName+"("+ methodParams +")";

    try{
       eval(methodCall);
    }catch(error){
       // some code here for error handling
    }
   }</pre>
<p>Traced on Firebug it turns out that FireFox loses the IFrameObj on Drag &amp; Drop while rewriting the DOM. Took me quite a while, and a long talk with uncle google until I took a look at bugzilla of mozzilla and the huge amount of iframe Bugs mentioned there. But I found the solution after reading alot of those posts,.. and yes as all ways it is an easy one, if you knew the solution.</p>
<pre name="code" class="javascript">function accessIframeJS(iframeId, methodName, methodParams)
 {
  var IFrameObj = document.getElementById(iframeId).contentWindow;
  var methodCall = "IFrameObj."+methodName+"("+ methodParams +")";

  try{
     eval(methodCall);
  }catch(error){
     // some code here for error handling
  }
 }</pre>
<p>Ta ta,&#8230; this works everywhere,&#8230; but it took me a long search, until I found the post in Bugzilla.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.swift-lizard.com/2009/11/15/jquery-sortable-with-iframes-in-firefox/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to develop a jQuery plugin</title>
		<link>http://www.swift-lizard.com/2009/11/15/how-to-develop-a-jquery-plugin/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://www.swift-lizard.com/2009/11/15/how-to-develop-a-jquery-plugin/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 14:15:47 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://swift-lizard.com/?p=51</guid>
		<description><![CDATA[Lately I started a new project at a German ISP where we (the team and me) have to develop several extensions to jQuery in order to build a framework to work with in this project. I am using jQuery for several years now but never had to develop my own extensions, because most of the [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I started a new project at a German ISP where we (the team and me) have to develop several extensions to jQuery in order to build a framework to work with in this project. I am using jQuery for several years now but never had to develop my own extensions, because most of the plugins available solved problems I came a cross. This time I have to do my own and started questioning uncle google about how to do it. No surprise there are several approaches to do a plugin for jQuery, but none of the tutorials I found answered all my Questions completely, so I decided to write this sum up of what I learned.</p>
<p><span id="more-51"></span></p>
<p>First of all you will need the basic wrapping:</p>
<pre name="code"  class="javascript">(function($){
   // your js code goes here
})(jQuery);</pre>
<p>This wrapping adds your code to the jQuery library if you add the js file to your page.<br />
Next thing you will have to do is add the basic functionality to your plugin.</p>
<pre name="code"  class="javascript">$.fn.yourPlugin = function(options){
}</pre>
<p>By adding those lines to your js file within the first code snippet you now can access your plugin by:</p>
<pre class="javascript">$('#yourDomElement').yourPlugin();</pre>
<p>Next you need to know the difference between private and public vars within the class you are developing. If you write something like:</p>
<pre name="code" class="javascript">   /**
     * default options for plugin
     * private
     * @var array defaultOptions
     */
    var defaultOptions = {
        action:       false,
        debug:        false
    }</pre>
<p>This would be a private var witch is only accessible within the class it self. If you need to have a var of your class to be public you have to write something like this:</p>
<pre name="code" class="javascript">   /**
     * default options for plugin
     * public
     * @var array defaultOptions
     */
    $.fn.yourPlugin.defaultOptions = {
        action:       false,
        debug:        false
    }</pre>
<p>One word has to be said by now, public variables can only be defined after the declaration of the constructor of your plugin, otherwise the compiler will throw a nice little javascript error because &#8220;yourPlugin&#8221; was not defined yet.<br />
Now that we have learned this we can go on with the possibility of configuration for the plugin. Like in every other language we will need to have some basic properties for the class that can be overwritten by your needs. To do something like that is quite simple:</p>
<pre name="code" class="javascript">   /**
     * yourPlugin base constructor
     *
     * @param [] options
     * @return void
     */
    $.fn.yourPlugin = function(options){
        // extend default options with overrides
        var opts = $.extend({}, defaultOptions, options);
    }</pre>
<p>So by now you can set the options you need by writing something like this:</p>
<pre name="code" class="javascript">   $('#yourDomElement').yourPlugin({
      action:       myAction
    });</pre>
<p>In this case you would have set opts.action from &#8220;false&#8221; to &#8220;myAction&#8221;.<br />
Next  we will go to private and public class methods. It is allmost the same as defining public and private member variables of your class.<br />
Something like this would be private:</p>
<pre name="code" class="javascript">   /**
     * private
     * method to do some vodoo
     */
    function yourPrivateClassMethod()
    {
        // the methods code
    }</pre>
<p>And something like this is a public method:</p>
<pre name="code" class="javascript">   /**
     * public
     * method to do some vodoo
     */
    $.fn.yourPlugin.yourPublicClassMethod = function()
    {
        // the methods code
    }</pre>
<p>Same rules like for the public member variables,&#8230; they have to be declared after your constructor, otherwise you will get an error. Another word of advise,.. as a developer I thought to access variables and methods within a class I can go by &#8220;this&#8221;,.. forget &#8220;this&#8221;,.. private methods and vars are accessed directly by their name, the public one you can access either by $(this).yourPlugin.yourPublicClassMethod() or $.fn.yourPlugin.yourPublicClassMethod().</p>
<p>So by now, if we put together the things we learned, we can do something like this:</p>
<pre name="code" class="javascript">(function($){
   /**
     * default options for plugin
     * private
     * @var array defaultOptions
     */
    var defaultOptions = {
        action:       false,
        debug:        false
    }

    /**
     * yourPlugin base constructor
     *
     * @param [] options
     * @return void
     */
    $.fn.yourPlugin = function(options){
        // extend default options with overrides
        var opts = $.extend({}, defaultOptions, options);

        switch(opts.action)
        {
        	case 'private':
        		yourPrivateClassMethod();
        		break;

        	case 'public':
        		$.fn.yourPlugin.yourPublicClassMethod();
        		break;
        }
    }

    /**
     * public
     * method to do some vodoo
     */
    $.fn.yourPlugin.yourPublicClassMethod = function()
    {
    	// should alert 'false', 'false',
    	//because the public vars where not set

        alert($.fn.yourPlugin.defaultOptions.action);
        alert($.fn.yourPlugin.defaultOptions.debug);
    }

    /**
     * default options for plugin
     * public
     * @var array defaultOptions
     */
    $.fn.yourPlugin.defaultOptions = {
        action:       false,
        debug:        false
    }

    /**
     * private
     * method to do some vodoo
     */
    function yourPrivateClassMethod()
    {
        alert('This method is private');
    }

})(jQuery);</pre>
<p>I hope this little summary helped a little in understanding how javascript classes and jQuery work.<br />
If you have any suggestion or did see some errors in this tutorial please let me know about it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.swift-lizard.com/2009/11/15/how-to-develop-a-jquery-plugin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

