Commits

msssk committed 2e88437

a bunch of refactoring

Comments (0)

Files changed (1)

  * @version 1.0.1
  */
 
-/*global jQuery, init, clikkitHandler, shrink, expand, close, logError, TRACE, imgOnLoad, imgOnClick, imgSetSize, addLink, closeLink, closeImageFrame, setState */
+/*global jQuery, init, setDimensions, triggerEvent, addUIToDOM, linkClickHandler, deactivate, activate, close, logError, trace, getImageDimensions, toggleImageSize, setImageSize, addLink, closeLink, closeImageFrame, setState */
 
  
 ( function($) {
 
-var $container,
-	$contentPane,
-	links = [],
-	shrinkOffset = 400,
-	clikkitWidth,
-	noFrameDomains = [ 'flickr.com', 'facebook.com', 'facebook.net', 'fbcdn.net', 'twitter.com' ];
+var container;
+var contentPane;
+var links = [];
+var inactiveOffset = 400;
+var activeWidth;
+var noFrameDomains = [ 'flickr.com', 'facebook.com', 'facebook.net', 'fbcdn.net', 'twitter.com', 'plus.google.com' ];
+
+var STATE = {
+	ACTIVE: 'Active',
+	INACTIVE: 'Inactive',
+	CLOSED: 'Closed',
+	ACTIVATING: 'Activating',
+	DEACTIVATING: 'Deactivating'
+};
+
+var EVENT = {
+	ACTIVE: 'Activated',
+	INACTIVE: 'Deactivated',
+	CLOSED: 'Closed',
+	ACTIVATING: 'Activating',
+	DEACTIVATING: 'Deactivating'
+};
 
 /**
  * @private
  * jQuery object that clikkit is invoked on, and applied to the elements within it that are matched by 'selector'. <br>
  * clikkit is designed for use with HTMLLinkElements, but should work with any element with href and text properties
  * @param {Object} userConfig clikkit configuration
- * @param {Number|String} [userConfig.expandedWidth=75%] The width of the clikkit pane
- * @param {Number|String} [userConfig.shrunkenWidth=50%] The width of the clikkit pane when contracted
- * @param {Number} [userConfig.shrunkenOpacity=0.6] The opacity of the clikkit pane when contracted - a value between 0 and 1
+ * @param {Number|String} [userConfig.activeWidth=75%] The width of the clikkit pane
+ * @param {Number|String} [userConfig.inactiveWidth=50%] The width of the clikkit pane when inactive
+ * @param {Number} [userConfig.inactiveOpacity=0.6] The opacity of the clikkit pane when contracted - a value between 0 and 1
  * @param {Number} [userConfig.closeBarColor=hsl(345, 64%, 35%)] The background color of the Close bar
  * @param {Number} [userConfig.zIndex=100] The z-index of the clikkit pane
  * @param {Boolean} [userConfig.enableHotkeys=true] If true, hotkeys will be enabled: <br>
  *     Escape or numpad minus:  close the currently displayed link <br>
- *     Left arrow or numpad plus:  expand the clikkit pane (if it's currently contracted)
+ *     Left arrow or numpad plus:  activate the clikkit pane (if it's currently contracted)
  */
 $.fn.clikkit = function( selector, userConfig ) {
 	if ( !this.length ) {
 	}
 
 	var config = {
-		expandedWidth: '75%',
-		shrunkenWidth: '50%',
-		shrunkenOpacity: 0.6,
+		activeWidth: '75%',
+		inactiveWidth: '50%',
+		inactiveOpacity: 0.6,
 		closeBarColor: 'hsl(345, 64%, 35%)',
 		zIndex: 100,
 		enableHotkeys: true
 		$.clikkit.settings = config;
 
 		if( selector ) {
-			this.delegate( selector, 'click', clikkitHandler );
+			this.delegate( selector, 'click', linkClickHandler );
 
 			if( $.fn.hoverIntent ) {
 				this.hoverIntent({
 					delegateSelector: selector,
-					over: shrink,
+					over: deactivate,
 					out: $.noop
 				});
 			}
 			else {
-				this.delegate( selector, 'mouseover', shrink );
+				this.delegate( selector, 'mouseover', deactivate );
 			}
 		}
 		else {
-			this.click( clikkitHandler );
+			this.click( linkClickHandler );
 
 			if( $.fn.hoverIntent ) {
-				this.hoverIntent( shrink, $.noop );
+				this.hoverIntent( deactivate, $.noop );
 			}
 			else {
-				this.mouseover( shrink );
+				this.mouseover( deactivate );
 			}
 		}
 	}
 };
 
 
-function clikkitHandler( clickEvent ) {
+function linkClickHandler( clickEvent ) {
 	// allow normal action for middle-click and ctrl+click
 	// shift+click is a special clikkit modifier - disable clikkit just for that click
 	if( clickEvent.button === 1 || clickEvent.ctrlKey || clickEvent.shiftKey ) {
 
 		case 37: // left arrow
 		case 107: // numpad plus (+)
-			if( $.clikkit.state === 'shrink' ) {
-				expand();
-			}
+			activate();
+			break;
+
+		case 39: // right arrow
+			deactivate();
 			break;
 	}
 }
 
 function init() {
 	if( $.clikkit.isInitialized ) {
-TRACE( 'WARNING:  init() called, already initialized.' );
+		trace( 'WARNING:  init() called, already initialized.' );
 		return;
 	}
 
-	var $row,
-		$borderCell,
-		$border,
-		$edgeCell,
-		$closeText,
-		clikkitStyles,
-		winResizeTimer;
+	var winResizeTimer;
 
 	$(window).resize( function() {
 		clearTimeout( winResizeTimer );
 		noFrameDomains = noFrameDomains.concat( $.clikkit.settings.noFrameDomains );
 	}
 
+	addUIToDOM();
+
+	$.clikkit.state = STATE.CLOSED;
+	setDimensions();
+
+	$.clikkit.isInitialized = true;
+}
+
+
+function setDimensions() {
+	var viewportWidth = $(window).width(),
+		viewportHeight = $(window).height();
+
+	if( typeof $.clikkit.settings.activeWidth === 'string' && $.clikkit.settings.activeWidth.charAt($.clikkit.settings.activeWidth.length - 1) === '%' ) {
+		activeWidth = parseInt( $.clikkit.settings.activeWidth, 10 );
+		activeWidth = parseInt( ( viewportWidth * activeWidth ) / 100, 10 );
+	}
+	else {
+		activeWidth = parseInt( $.clikkit.settings.activeWidth, 10 );
+	}
+
+	if( typeof $.clikkit.settings.inactiveWidth === 'string' && $.clikkit.settings.inactiveWidth.charAt($.clikkit.settings.inactiveWidth.length - 1) === '%' ) {
+		inactiveOffset = parseInt( $.clikkit.settings.inactiveWidth, 10 );
+		inactiveOffset = activeWidth - parseInt( ( viewportWidth * inactiveOffset ) / 100, 10 );
+	}
+	else {
+		inactiveOffset = activeWidth - parseInt( $.clikkit.settings.inactiveWidth, 10 );
+	}
+
+	container.width( activeWidth );
+	container.height( viewportHeight );
+
+	if( $.clikkit.state === STATE.CLOSED ) {
+		container.css( 'right', -activeWidth );
+	}
+}
+
+
+function addUIToDOM() {
+	var row;
+	var borderCell;
+	var border;
+	var edgeCell;
+	var closeText;
+	var clikkitStyles;
+
+	// Since the CSS required is fairly light, in-line it to provide the plug-in with
+	// only a single file dependency
 	clikkitStyles = '.clikkitLocationBar {';
 	clikkitStyles += ' font: small verdana, arial, helvetica, sans-serif;';
 	clikkitStyles += ' text-decoration: none;';
 	// 1. div-inside-div:  inner div inherits translucence of outer div
 	// 2. div-next-to-div:  alignment is hell, pixels are all wrong!
 	// 3. table - it works!
-	$container = $( '<table id="clikkit"></table>' );
-	$container.css({
+	container = $( '<table id="clikkit"></table>' );
+	container.css({
 		borderCollapse: 'collapse',
 		borderSpacing: 0,
 		opacity: 0,
 		zIndex: $.clikkit.settings.zIndex
 	});
 
-	$row = $( '<tr></tr>' );
-	$row.css( {
+	row = $( '<tr></tr>' );
+	row.css( {
 		margin: 0,
 		padding: 0
 	} );
-	$container.append( $row );
+	container.append( row );
 
-	$borderCell = $( '<td id="clikkitBorder"></td>' );
-	$borderCell.css( {
+	borderCell = $( '<td id="clikkitBorder"></td>' );
+	borderCell.css( {
 		border: 'none',
 		padding: 0,
 		opacity: 0.42,
 		boxShadow: '-3px 0 5px #424242'
 	} );
-	$row.append( $borderCell );
+	row.append( borderCell );
 
-	$border = $( '<div></div>' );
-	$border.css( {
+	border = $( '<div></div>' );
+	border.css( {
 		borderLeft: '1px solid hsl(0, 0%, 96%)',
 		borderRight: '1px solid hsl(0, 0%, 96%)',
 		margin: 0,
 		width: '4px',
 		height: '100%'
 	} );
-	$borderCell.append( $border );
+	borderCell.append( border );
 
-	$edgeCell = $( '<td id="clikkitEdge"></td>' );
-	$edgeCell.css( {
+	edgeCell = $( '<td id="clikkitEdge"></td>' );
+	edgeCell.css( {
 		opacity: 0.88,
 		fontFamily: 'verdana, arial, helvetica, sans-serif',
 		fontSize: 'small',
 		cursor: 'pointer',
 		verticalAlign: 'middle'
 	} );
-	$edgeCell.click( closeLink );
-	$row.append( $edgeCell );
+	edgeCell.click( closeLink );
+	row.append( edgeCell );
 
-	$closeText = $( '<p id="clikkitCloseText">CLOSE</p>' );
-	$closeText.css( {
+	closeText = $( '<p id="clikkitCloseText">CLOSE</p>' );
+	closeText.css( {
 		writingMode: 'tb-rl',
 		WebkitTransform: 'rotate(270deg)',
 		MozTransform: 'rotate(270deg)',
 		width: '14px'
 	} );
-	$edgeCell.append( $closeText );
+	edgeCell.append( closeText );
 
-	$contentPane = $( '<td id="clikkitContent"></td>' );
-	$contentPane.css( {
+	contentPane = $( '<td id="clikkitContent"></td>' );
+	contentPane.css( {
 		width: '100%',
 		height: '100%',
 		background: '#E3E3E3',
 		verticalAlign: 'top'
 	} );
-	$contentPane.mouseenter( function() {
-		if( $.clikkit.state === 'shrink' && links.length ) {
-			expand();
+	contentPane.mouseenter( function() {
+		if( links.length ) {
+			activate();
 		}
 	} );
-	$row.append( $contentPane );
+	row.append( contentPane );
 
 	// put a dummy value in the div so that when it is first rendered, it has its normal height
-	$contentPane.URL = $( '<div>Tj</div>' );
-	$contentPane.URL.css( {
+	contentPane.URL = $( '<div>Tj</div>' );
+	contentPane.URL.css( {
 		color: 'black',
 		backgroundColor: '#F5F5F5',
 		padding: '2px 2px 2px 3px',
 		borderRadius: '4px',
 		margin: '2px 2px 1px 2px'
 	} );
-	$contentPane.append( $contentPane.URL );
+	contentPane.append( contentPane.URL );
 
-	$contentPane.FrameCount = $( '<div>0</div>' );
-	$contentPane.FrameCount.css( {
+	contentPane.FrameCount = $( '<div>0</div>' );
+	contentPane.FrameCount.css( {
 		display: 'block',
 		"float": 'left',
 		marginTop: '1px',
 			}
 		}())
 	} );
-	$contentPane.append( $contentPane.FrameCount );
+	contentPane.append( contentPane.FrameCount );
 
-	$contentPane.Title = $( '<div>Tj</div>' );
-	$contentPane.Title.css( {
+	contentPane.Title = $( '<div>Tj</div>' );
+	contentPane.Title.css( {
 		fontFamily: 'verdana, arial, helvetica, sans-serif',
 		fontSize: 'medium',
 		color: '#222222',
 		padding: '2px 2px 2px 4px',
 		marginBottom: '1px'
 	} );
-	$contentPane.append( $contentPane.Title );
+	contentPane.append( contentPane.Title );
 
-	$contentPane.ImageFrame = $( '<div id="clikkitImagePane"></div>' );
-	$contentPane.ImageFrame.css( {
+	contentPane.ImageFrame = $( '<div id="clikkitImagePane"></div>' );
+	contentPane.ImageFrame.css( {
 		overflow: 'auto',
 		width: '100%',
 		height: 600,
 		borderTop: '1px solid #8B8B8B'
 	} );
-	$contentPane.ImageFrame.Image = $( new Image() );
-	$contentPane.ImageFrame.Image.click( imgOnClick );
-	$contentPane.ImageFrame.Image.load( imgOnLoad );
-	$contentPane.ImageFrame.append( $contentPane.ImageFrame.Image );
-	$contentPane.append( $contentPane.ImageFrame );
+	contentPane.ImageFrame.Image = $( new Image() );
+	contentPane.ImageFrame.Image.click( toggleImageSize );
+	contentPane.ImageFrame.Image.load( getImageDimensions );
+	contentPane.ImageFrame.append( contentPane.ImageFrame.Image );
+	contentPane.append( contentPane.ImageFrame );
 
-	$(document.body).append( $container );
-	$contentPane.ImageFrame.hide();
-TRACE( 'container.height: ' + $container.height() + '; c.outer: ' + $container.outerHeight() + '; win: ' + $(window).height() );
-
-	$.clikkit.state = 'close';
-	setDimensions();
-
-	$.clikkit.isInitialized = true;
-}
-
-
-function setDimensions() {
-	var viewportWidth = $(window).width(),
-		viewportHeight = $(window).height();
-
-	if( typeof $.clikkit.settings.expandedWidth === 'string' && $.clikkit.settings.expandedWidth.charAt($.clikkit.settings.expandedWidth.length - 1) === '%' ) {
-		clikkitWidth = parseInt( $.clikkit.settings.expandedWidth );
-		clikkitWidth = parseInt( ( viewportWidth * clikkitWidth ) / 100 );
-	}
-	else {
-		clikkitWidth = parseInt( $.clikkit.settings.expandedWidth );
-	}
-
-	if( typeof $.clikkit.settings.shrunkenWidth === 'string' && $.clikkit.settings.shrunkenWidth.charAt($.clikkit.settings.shrunkenWidth.length - 1) === '%' ) {
-		shrinkOffset = parseInt( $.clikkit.settings.shrunkenWidth );
-		shrinkOffset = clikkitWidth - parseInt( ( viewportWidth * shrinkOffset ) / 100 );
-	}
-	else {
-		shrinkOffset = clikkitWidth - parseInt( $.clikkit.settings.shrunkenWidth );
-	}
-
-	$container.width( clikkitWidth );
-	$container.height( viewportHeight );
-
-	if( $.clikkit.state === 'close' ) {
-		$container.css( 'right', -clikkitWidth );
-	}
+	$(document.body).append( container );
+	contentPane.ImageFrame.hide();
+	trace( 'container.height: ' + container.height() + '; c.outer: ' + container.outerHeight() + '; win: ' + $(window).height() );
 }
 
 
  * @param {Object} link The clikkit link {domNode: <HTMLLinkElement>, $iframe: <$HTMLIFrameElement>} to display
  */
 function showLink( link ) {
-	var eventResult,
-		frameHREF,
-		linkText,
-		dotIndex,
-		hrefEnd,
-		$linkNode = $(link.domNode),
-		showLinkEvent;
+	var eventResult;
+	var frameHREF;
+	var linkText;
+	var dotIndex;
+	var hrefEnd;
+	var $linkNode = $(link.domNode);
+	var showLinkEvent;
 
 	/**
 	 * @name clikkitShowLink
 	 * @description Fires on an HTMLLinkElement before clikkit displays the link <br>
 	 * If an event handler returns a falsy value other than undefined, the link will not be displayed.
 	 * @example
-	 * $( 'a' ).bind( 'clikkitShowLink', myFunction )
+	 * $( 'a' ).bind( 'clikkitShowLink', myHandler )
 	 */
-	showLinkEvent = $.Event( 'clikkitShowLink' );
-	$linkNode.trigger( showLinkEvent );
-	eventResult = showLinkEvent.result;
-	if( showLinkEvent.isDefaultPrevented() || (!eventResult && eventResult !== undefined) ) {
+	if( !triggerEvent( 'clikkitShowLink', $linkNode ) ) {
 		return false;
 	}
 
 	frameHREF = $linkNode.data( 'clikkithref' );
 	linkText = $linkNode.data( 'clikkittext' );
 
-	$contentPane.URL.html( '<a href="' + frameHREF + '" target="_blank" class="clikkitLocationBar">' + frameHREF + '</a>' );
-	$contentPane.FrameCount.text( links.length );
-	$contentPane.Title.text( linkText );
-	$contentPane.Frame = link.$iframe;
+	contentPane.URL.html( '<a href="' + frameHREF + '" target="_blank" class="clikkitLocationBar">' + frameHREF + '</a>' );
+	contentPane.FrameCount.text( links.length );
+	contentPane.Title.text( linkText );
+	contentPane.Frame = link.$iframe;
 
 	dotIndex = frameHREF.lastIndexOf( '.' );
 	if( dotIndex !== -1 ) {
 		hrefEnd = frameHREF.substring( dotIndex + 1 ).toLowerCase();
 		if( hrefEnd === 'jpeg' || hrefEnd === 'jpg' || hrefEnd === 'png' || hrefEnd === 'gif' ) {
-			$contentPane.ImageFrame.height( $contentPane.Frame.innerHeight() - 1 ); // -1 to allow for 1px border at top
-			if( $contentPane.ImageFrame.outerHeight() > $contentPane.Frame.height() ) {
-				$contentPane.ImageFrame.height( $contentPane.ImageFrame.height() - ($contentPane.ImageFrame.outerHeight() - $contentPane.Frame.height()) );
-			}
-			$contentPane.ImageFrame.Image.attr( 'src', frameHREF );
-			$contentPane.ImageFrame.isActive = true;
-			$contentPane.ImageFrame.show();
-
-			// if the image is loaded and ready, set the size
-			if( $contentPane.ImageFrame.Image[0].complete && $contentPane.ImageFrame.Image[0].width > 0 ) {
-				if( $.clikkit.state === 'expand' ) {
-					imgSetSize.apply( $contentPane.ImageFrame.Image[0] );
-				}
-				else {
-					$container.one( 'clikkitexpand', function() { imgSetSize.apply( $contentPane.ImageFrame.Image[0] ); } );
-				}
-			}
+			showImage( frameHREF );
 
 			// exit the function so we don't make the normal iframe visible
 			return;
 		}
 	}
 
-	$contentPane.append( link.$iframe );
-	$contentPane.Frame.css( 'position', 'relative' );
-	$contentPane.Frame.css( 'left', 0 );
+	contentPane.append( link.$iframe );
+	contentPane.Frame.css( 'position', 'relative' );
+	contentPane.Frame.css( 'left', 0 );
 }
 
 
+function showImage( imageURL ) {
+	contentPane.ImageFrame.height( contentPane.Frame.innerHeight() - 1 ); // -1 to allow for 1px border at top
+	if( contentPane.ImageFrame.outerHeight() > contentPane.Frame.height() ) {
+		contentPane.ImageFrame.height( contentPane.ImageFrame.height() - (contentPane.ImageFrame.outerHeight() - contentPane.Frame.height()) );
+	}
+	contentPane.ImageFrame.Image.attr( 'src', imageURL );
+	contentPane.ImageFrame.isActive = true;
+	contentPane.ImageFrame.show();
+
+	// if the image is loaded and ready, set the size
+	if( contentPane.ImageFrame.Image[0].complete && contentPane.ImageFrame.Image[0].width > 0 ) {
+		if( $.clikkit.state === STATE.ACTIVE ) {
+			setImageSize.apply( contentPane.ImageFrame.Image[0] );
+		}
+		else {
+			container.one( 'clikkitActivated', function() { setImageSize.apply( contentPane.ImageFrame.Image[0] ); } );
+		}
+	}
+}
+
+
 function closeLink( event ) {
-	if( $.clikkit.state === 'close' ) {
-		return;
-	}
-
-	var currentLink,
-		eventResult,
-		$linkNode,
-		closeLinkEvent;
+	var currentLink;
+	var eventResult;
+	var $linkNode;
+	var closeLinkEvent;
 
 	try {
 		if( links.length ) {
 			 * @description Fires on an HTMLLinkElement before clikkit closes the link <br>
 			 * If an event handler returns a falsy value other than undefined, the link will not be closed.
 			 * @example
-			 * $( 'a' ).bind( 'clikkitCloseLink', myFunction )
+			 * $( 'a' ).bind( 'clikkitCloseLink', myHandler )
 			 */
-			closeLinkEvent = $.Event( 'clikkitCloseLink' );
-			$linkNode.trigger( closeLinkEvent );
-			eventResult = closeLinkEvent.result;
-			if( closeLinkEvent.isDefaultPrevented() || (!eventResult && eventResult !== undefined) ) {
+			if( !triggerEvent( 'clikkitCloseLink', $linkNode ) ) {
 				return false;
 			}
 
 			delete currentLink.domNode;
 			delete currentLink.$iframe;
 
-			$contentPane.URL.html( 'Tj' );
-			$contentPane.Title.html( 'Tj' );
+			contentPane.URL.html( 'Tj' );
+			contentPane.Title.html( 'Tj' );
 		}
 
-		if( $contentPane.ImageFrame.isActive ) {
+		if( contentPane.ImageFrame.isActive ) {
 			closeImageFrame();
 		}
 
-		$contentPane.Frame.remove();
-		$contentPane.Frame = null;
+		contentPane.Frame.remove();
+		contentPane.Frame = null;
 	}
 	catch( e ) {
 		logError( e, 'closeLink' );
  * @param {HTMLLinkElement} link The link to enqueue
  */
 function addLink( link ) {
+	var jqLink;
+	var eventResult;
+	// if the frame height calculations are off, a correction value may be needed
+	var frameHeightCorrection = 0;
+	var frameCountHeight;
+	var titleHeight;
+	var frameHeight;
+	var frameHREF;
+	var addLinkEvent;
+	var i;
+
 	try {
-		var $link = $(link),
-			eventResult,
-			// if the frame height calculations are off, a correction value may be needed
-			frameHeightCorrection = 0,
-			frameCountHeight,
-			titleHeight,
-			frameHeight,
-			frameHREF,
-			addLinkEvent,
-			i;
+		jqLink = $(link);
 
 		/**
 		 * @name clikkitAddLink
 		 * that link will be enqueued instead of the original. This can be useful, for example, to change a
 		 * normal Youtube link to its embed equivalent.
 		 * @example
-		 * $( 'a' ).bind( 'clikkitAddLink', myFunction )
+		 * $( 'a' ).bind( 'clikkitAddLink', myHandler )
 		 */
-		addLinkEvent = $.Event( 'clikkitAddLink' );
-		$link.trigger( addLinkEvent );
-		eventResult = addLinkEvent.result;
-		if( addLinkEvent.isDefaultPrevented() || (!eventResult && eventResult !== undefined) ) {
+		if( !triggerEvent( 'clikkitAddLink', jqLink ) ) {
 			return false;
 		}
 
 		frameHREF = link.href;
-		$link.data( 'clikkithref', link.href );
-		$link.data( 'clikkittext', link.text );
+		jqLink.data( 'clikkithref', link.href );
+		jqLink.data( 'clikkittext', link.text );
 
 		if( eventResult ) {
 			if( eventResult.href ) {
-				$link.data( 'clikkithref', eventResult.href );
+				jqLink.data( 'clikkithref', eventResult.href );
 				frameHREF = eventResult.href;
 			}
 
 			if( eventResult.text ) {
-				$link.data( 'clikkittext', eventResult.text );
+				jqLink.data( 'clikkittext', eventResult.text );
 			}
 		}
 
 			}
 		}
 
-		frameCountHeight = $contentPane.FrameCount.outerHeight();
-		titleHeight = $contentPane.Title.outerHeight();
+		frameCountHeight = contentPane.FrameCount.outerHeight();
+		titleHeight = contentPane.Title.outerHeight();
 		if( frameCountHeight > titleHeight ) {
 			titleHeight = frameCountHeight;
 		}
-		frameHeight = $contentPane.innerHeight() - $contentPane.URL.outerHeight() - titleHeight + frameHeightCorrection;
-TRACE( 'frameHeight = ' + frameHeight + '[' + $contentPane.innerHeight() + ' - ' + $contentPane.URL.outerHeight() + ' - ' + titleHeight + ' + ' + frameHeightCorrection + ']' );
+		frameHeight = contentPane.innerHeight() - contentPane.URL.outerHeight() - titleHeight + frameHeightCorrection;
+		trace( 'frameHeight = ' + frameHeight + '[' + contentPane.innerHeight() + ' - ' + contentPane.URL.outerHeight() + ' - ' + titleHeight + ' + ' + frameHeightCorrection + ']' );
 
 		// store the originally clicked link's href value, even if an event handler for 'clikkitAddLink' changed it
 		// since this is primarily for tracing purposes to see what the last link clicked was
 		// if nothing is already being displayed, display current link
 		if( links.length === 1 ) {
 			showLink( links[0] );
-			expand();
+			activate();
 		}
 		// otherwise, update link count display
 		else {
-			$contentPane.FrameCount.text( links.length );
+			contentPane.FrameCount.text( links.length );
 		}
 	}
 	catch( e )
 		window.open( link.href );
 	}
 	finally {
-		$link = null;
+		jqLink = null;
 		addLinkEvent = null;
 	}
 }
 
 
 function closeImageFrame() {
-	$contentPane.ImageFrame.Image.attr( 'src', '' );
-	$contentPane.ImageFrame.Image[0].width = 320;
-	$contentPane.ImageFrame.Image[0].height = 240;
-	$contentPane.ImageFrame.Image[0].retryCount = 0;
-	$contentPane.ImageFrame.isActive = false;
-	$contentPane.ImageFrame.hide();
+	contentPane.ImageFrame.Image.attr( 'src', '' );
+	contentPane.ImageFrame.Image[0].width = 320;
+	contentPane.ImageFrame.Image[0].height = 240;
+	contentPane.ImageFrame.Image[0].retryCount = 0;
+	contentPane.ImageFrame.isActive = false;
+	contentPane.ImageFrame.hide();
 }
 
 
+function triggerEvent( eventName, jqNode ) {
+	var clikkitEvent;
+	var eventResult;
+
+	clikkitEvent = $.Event( eventName );
+	jqNode.trigger( clikkitEvent );
+	eventResult = clikkitEvent.result;
+
+	if( clikkitEvent.isDefaultPrevented() || (!eventResult && eventResult !== undefined) ) {
+		return false;
+	}
+
+	return true;
+}
+
+
 /**
- * @name clikkitexpanding
+ * @name clikkitActivating
  * @event
- * @description Fires on the clikkit pane, which has 'clikkit' as its ID, when it starts expanding <br>
+ * @description Fires on the clikkit pane, which has 'clikkit' as its ID, when it starts activating <br>
  * This is a non-bubbling event.
  * @example
- * $( '#clikkit' ).bind( 'clikkitexpanding', myFunction )
+ * $( '#clikkit' ).bind( 'clikkitActivating', myHandler )
  */
 
 /**
- * @name clikkitexpand
+ * @name clikkitActivated
  * @event
- * @description Fires on the clikkit pane, which has 'clikkit' as its ID, when it finishes expanding <br>
+ * @description Fires on the clikkit pane, which has 'clikkit' as its ID, when it finishes activating <br>
  * This is a non-bubbling event.
  * @example
- * $( '#clikkit' ).bind( 'clikkitexpand', myFunction )
+ * $( '#clikkit' ).bind( 'clikkitActivated', myHandler )
  */
 
 /**
- * Expand the clikkit pane and make it visible
+ * Activate the clikkit pane and make it visible
  */
-function expand() {
-	// only expand if current state is not 'expand'
-	if( $.clikkit.state !== 'expand' ) {
-		setState( 'expanding' );
-		$container.animate( { right: 0, opacity: 1 }, 200, function() {
-			setState( 'expand' );
+function activate() {
+	// only activate if current state is not 'expand'
+	if( $.clikkit.state !== STATE.ACTIVE && $.clikkit.state !== STATE.ACTIVATING ) {
+		setState( STATE.ACTIVATING );
+		container.animate( { right: 0, opacity: 1 }, 200, function() {
+			setState( STATE.ACTIVE );
 		});
 	}
 }
 
 
 /**
- * @name clikkitshrinking
+ * @name clikkitDeactivating
  * @event
- * @description Fires on the clikkit pane, which has 'clikkit' as its ID, when it starts shrinking <br>
+ * @description Fires on the clikkit pane, which has 'clikkit' as its ID, when it starts deactivating <br>
  * This is a non-bubbling event.
  * @example
- * $( '#clikkit' ).bind( 'clikkitshrinking', myFunction )
+ * $( '#clikkit' ).bind( 'clikkitDeactivating', myHandler )
  */
 
 /**
- * @name clikkitshrink
+ * @name clikkitDeactivated
  * @event
- * @description Fires on the clikkit pane, which has 'clikkit' as its ID, when it finishes shrinking <br>
+ * @description Fires on the clikkit pane, which has 'clikkit' as its ID, when it finishes deactivating <br>
  * This is a non-bubbling event.
  * @example
- * $( '#clikkit' ).bind( 'clikkitshrink', myFunction )
+ * $( '#clikkit' ).bind( 'clikkitDeactivated', myHandler )
  */
 
 /**
  * Shrink the clikkit pane and reduce its visibility
  */
-function shrink() {
-	// only shrink if current state is 'expand'
-	if( $.clikkit.state === 'expand' ) {
-		setState( 'shrinking' );
-		$container.animate( { right: -shrinkOffset, opacity: $.clikkit.settings.shrunkenOpacity }, 275, function() {
-			setState( 'shrink' );
+function deactivate() {
+	if( !links.length ) {
+		close();
+		return;
+	}
+
+	// only deactivate if current state is 'expand'
+	if( $.clikkit.state === STATE.ACTIVE || $.clikkit.state === STATE.ACTIVATING ) {
+		setState( STATE.DEACTIVATING );
+		container.animate( { right: -inactiveOffset, opacity: $.clikkit.settings.inactiveOpacity }, 275, function() {
+			setState( STATE.INACTIVE );
 		});
 	}
 }
  * @description Fires on the clikkit pane, which has 'clikkit' as its ID, when it is closed <br>
  * This is a non-bubbling event.
  * @example
- * $( '#clikkit' ).bind( 'clikkitclose', myFunction )
+ * $( '#clikkit' ).bind( 'clikkitclose', myHandler )
  */
 
 /**
  * Close and hide the clikkit pane
  */
 function close() {
-	$container.animate( {right: -clikkitWidth}, 175, function() {
-		setState( 'close' );
-	});
+	if( $.clikkit.state !== STATE.CLOSED && $.clikkit.state !== STATE.CLOSING ) {
+		setState( STATE.CLOSING );
+		container.animate( {right: -activeWidth}, 175, function() {
+			setState( STATE.CLOSED );
+		});
+	}
 }
 
 
 function setState( state ) {
-TRACE( 'state:  ' + state );
+	trace( 'state:  ' + state );
 	$.clikkit.state = state;
-	$container.triggerHandler( 'clikkit' + state );
+	container.triggerHandler( 'clikkit' + EVENT[state] );
 }
 
 
-function imgOnClick() {
+function toggleImageSize() {
 	if( this.width === this.naturalWidth ) {
 		this.width = this.fitWidth ;
 		this.height = this.fitHeight;
 }
 
 
-function imgOnLoad() {
+function getImageDimensions() {
+	var self = this;
+
 	// seems like sometimes the onLoad fires before the image is really ready?
 	// if we can't get the dimensions, wait a bit and try again, if we still can't get them, open image in new window
 	if( this.width === 0 || this.height === 0 ) {
 		this.retryCount = this.retryCount === undefined ? 1 : this.retryCount + 1;
 		if( this.retryCount === 10 ) {
 			// can't get image dimensions, open in new window
+			debugger;
+			closeLink();
 			window.open( this.src );
+/*
 			this.src = '';
 			this.width = 320;
 			this.height = 240;
 			this.retryCount = 0;
+*/
 			return;
 		}
 
-		setTimeout( imgOnLoad.apply( this ), 250 );
+		setTimeout( getImageDimensions.apply( this ), 250 );
 		return;
 	}
 
 	if( this.naturalHeight === undefined ) {
 		this.naturalHeight = this.height;
 	}
-TRACE( 'img loaded:  ' + this.src + '; w=' + this.width + '; h=' + this.height );
+	trace( 'img loaded:  ' + this.src + '; w=' + this.width + '; h=' + this.height );
 
-	// showLink() sets '$contentPane.ImageFrame.isActive=true', then calls imgSetSize if the image is ready
+	// showLink() sets 'contentPane.ImageFrame.isActive=true', then calls setImageSize if the image is ready
 	// If isActive is already true during onLoad, that means the image frame was activated before the image
-	// finished loading and imgSetSize was not called, so call it now
-	if( $contentPane.ImageFrame.isActive && $contentPane.ImageFrame.Image[0] === this ) {
-TRACE( 'imgOnLoad->imgSetSize' );
-		if( $.clikkit.state === 'expand' ) {
-			imgSetSize.apply( this );
+	// finished loading and setImageSize was not called, so call it now
+	if( contentPane.ImageFrame.isActive && contentPane.ImageFrame.Image[0] === this ) {
+		trace( 'getImageDimensions->setImageSize' );
+		if( $.clikkit.state === STATE.ACTIVE ) {
+			setImageSize.apply( this );
 		}
 		else {
-			var image = this;
-			$container.one( 'clikkitexpand', function() { imgSetSize.apply( image ); } );
+			container.one( 'clikkitActivated', function() { setImageSize.apply( self ); } );
 		}
 	}
 }
 
 
-function imgSetSize() {
-	var frameWidth,
-		frameHeight,
-		ratio;
+function setImageSize() {
+	var frameWidth;
+	var frameHeight;
+	var ratio;
 
-	frameWidth = $contentPane.ImageFrame.innerWidth();
+	frameWidth = contentPane.ImageFrame.innerWidth();
 	this.fitWidth = frameWidth;
 
 	ratio = this.fitWidth / this.naturalWidth;
 	this.fitHeight = parseInt( this.naturalHeight * ratio, 10 );
 
-	frameHeight = $contentPane.ImageFrame.innerHeight();
+	frameHeight = contentPane.ImageFrame.innerHeight();
 	if( this.fitHeight > frameHeight ) {
 		ratio = frameHeight / this.naturalHeight;
 		this.fitWidth = parseInt( this.naturalWidth * ratio, 10 );
 	if( this.fitHeight < 10 ) {
 		this.fitHeight = 240;
 	}
-TRACE( 'imgSetSize:  calculated fitWidth = ' + this.fitWidth + '; fitHeight = ' + this.fitHeight );
+	trace( 'setImageSize:  calculated fitWidth = ' + this.fitWidth + '; fitHeight = ' + this.fitHeight );
 
 	// if the width or height is larger than the frame, then resize to fit
 	if( this.naturalWidth > frameWidth || this.naturalHeight > frameHeight ) {
 			this.width = this.fitWidth;
 			this.height = this.fitHeight;
 		}
-TRACE( 'imgSetSize:  w:' + this.naturalWidth + '->' + this.fitWidth + '; h:' + this.naturalHeight + '->' + this.fitHeight );
+		trace( 'setImageSize:  w:' + this.naturalWidth + '->' + this.fitWidth + '; h:' + this.naturalHeight + '->' + this.fitHeight );
 	}
 	else {
 		// we have to explicitly set the image to the size of the newly loaded image because it is re-using
 }
 
 
-function TRACE( msg ) {
+function trace( msg ) {
 	if( $.clikkit.settings.DEBUG && console ) {
-		console.log( '(clikkit)' + msg );
+		console.log( '(clikkit)', msg );
 	}
 }