<public:component>
<public:attach event="onpropertychange" onevent="verticalAlignMiddle()" />
<script type="text/javascript">
	function verticalAlignMiddle() {
		var total, children = [], i, len, child;

		function getStyle(element, property) {
			if (typeof window.getComputedStyle === 'function') {
				var style = window.getComputedStyle(element);
				return parseInt(style.getPropertyValue(property), 10);
			} else {
				property = property.toLowerCase().replace(/-(.)/g, function(match, letter) {
					return letter.toUpperCase();
				});
				return parseInt(element.currentStyle[property], 10);
			}
		};

		function getHeight(el) {
			var height         = parseInt(el.offsetHeight, 10);
			var borderTopWidth = getStyle(el, 'border-top-width') || 0;
			var paddingTop     = getStyle(el, 'padding-top'     ) || 0;

			el.setAttribute('data-height', height);
			el.setAttribute('data-offset-top', paddingTop + borderTopWidth);

			return parseInt(el.getAttribute('data-height'), 10);
		};

		function getWidth(el) {
			var width            = parseInt(el.offsetWidth, 10);
			var marginLeft       = getStyle(el, 'margin-left')        || 0;
			var marginRight      = getStyle(el, 'margin-right')       || 0;
			var borderLeftWidth  = getStyle(el, 'border-left-width')  || 0;
			var borderRightWidth = getStyle(el, 'border-right-width') || 0;
			var paddingLeft      = getStyle(el, 'padding-left')       || 0;
			var paddingRight     = getStyle(el, 'padding-right')      || 0;

			el.setAttribute('data-outer-width', width + marginLeft + marginRight);
			el.setAttribute('data-width', width);
			el.setAttribute('data-inner-width', width - borderLeftWidth - borderRightWidth - paddingLeft - paddingRight);

			return parseInt(el.getAttribute('data-inner-width'), 10);
		};

		function getRemainingWidth(children, total) {
			var i, len, child;
			for (i = 0, len = children.length; i < len; i += 1) {
				child = children[i];
				if (!child.className.match('middled')) {
					total = total - child.getAttribute('data-outer-width');
				}
			}
			return (total - 1); // minus 1 for browser calculation errors
		};

		if (element.getAttribute('data-middled') !== 'true') {
			element.style.zoom = '1';

			for (i = 0, len = element.children.length; i < len; i += 1) {
				child = element.children[i];
				if (child.tagName) {
					getWidth(child);
					children.push(child);

					child = children[i];
					child.style.cssFloat = children[i].className.match('right') ? 'right' : 'left';
					child.style.position = 'relative';
					child.style.zIndex = '1';
					child.style.zoom = '1';
					child.style.display = 'inline';
				}
			}

			total = getWidth(element);
			for (i = 0, len = children.length; i < len; i += 1) {
				child = children[i];
				if (child.className.match('middled')) {
					getWidth(child);
					child.style.width = getRemainingWidth(children, total) - (child.getAttribute('data-outer-width') - child.getAttribute('data-inner-width')) + 'px';
				}
			}

			getHeight(element);
			for (i = 0, len = children.length; i < len; i += 1) {
				child = children[i];
				getHeight(child);
				child.style.marginTop = ((element.getAttribute('data-height') - child.getAttribute('data-height')) / 2) - element.getAttribute('data-offset-top') - child.getAttribute('data-offset-top') + 'px';
			}

			element.setAttribute('data-middled', 'true');
		}
	}
	verticalAlignMiddle();
</script>
</public:component>
