API Docs for: 1.4.4
Show:

File: scriptasaurus\ukeGeeks.overlapFixer.js

/**
 * Singleton to correct overlapping chord names/diagrams in songs rendered by UGS
 * @class overlapFixer
 * @namespace ukeGeeks
 * @project UkeGeeks' Scriptasaurus
 * @singleton
 */
ukeGeeks.overlapFixer = (function() {

	// private
	// ---------------------------
	var _public = {};

	/**
	 * returns TRUE if Box A overlaps Box B. Detailed horizontal check, we "cheat" the
	 * vertical check by assuming that tops must be equal to collide (a simplification
	 * over a full height check.)
	 * @method checkOverlap
	 * @param  {object} "a" box
	 * @param  {object} "b" box
	 * @return {boolean}
	 */
	var checkOverlap = function(a, b) {
		// "cheat" vertical check
		if (a.top != b.top) {
			return false;
		}

		if ((b.left > a.right) || (b.right < a.left)) {
			//overlap not possible
			return false;
		}
		if ((b.left > a.left) && (b.left < a.right)) {
			return true;
		}
		if ((b.right > a.left) && (b.right < a.right)) {
			return true;
		}
		return false;
	};


	/**
	 * returns object with width and left & right offsets
	 * @method getBox
	 * @param  {DOM_element} element to be measured
	 * @return {object}
	 */
	var getBox = function(ele) {
		var box = getOffsets(ele);
		box.width = getWidth(ele);

		// due to how CSS & HTML is defined it's possible that the <em> wrapping the
		// chord name is actually wider than the <strong>, let's check.
		// BTW: this will happen on the "mini-chord diagram" option
		var em = ele.getElementsByTagName('em')[0];
		if (em) {
			var emWidth = getWidth(em);
			if (emWidth > box.width) {
				//console.log('box strong.width: ' + box.width + 'px, em.width: ' + emWidth +'px');
				box.width = emWidth + 2;
			}
		}

		box.right = box.left + box.width;
		return box;
	};

	/**
	 * source: http://www.cjboco.com/blog.cfm/post/determining-an-elements-width-and-height-using-javascript/
	 * @method getWidth
	 * @param  {DOM_element} element to be measured
	 * @return {int}
	 */
	var getWidth = function(ele) {
		if (typeof ele.clip !== "undefined") {
			return ele.clip.width;
		}

		return (ele.style.pixelWidth) ? ele.style.pixelWidth : ele.offsetWidth;
	};

	/**
	 * Returns JSON with left, right, top, and width properties. ONLY left and top are calculate,
	 * width & right need to be added later.
	 * source: http://stackoverflow.com/questions/442404/dynamically-retrieve-the-position-x-y-of-an-html-element
	 * @method getOffsets
	 * @param  {DOM_element} element to be measured
	 * @return {JSON}
	 */
	var getOffsets = function(ele) {
		var box = {
			top: 0,
			left: 0,
			right: 0,
			width: 0
		};

		while (ele && !isNaN(ele.offsetLeft) && !isNaN(ele.offsetTop)) {
			box.left += ele.offsetLeft - ele.scrollLeft;
			box.top += ele.offsetTop - ele.scrollTop;
			ele = ele.offsetParent;
		}

		return box;
	};


	/**
	 * checks (and fixes if problem is presetn) two code tags
	 * @method checkChords
	 * @param  {[DOM_element]} codeA [description]
	 * @param  {[DOM_element]} codeB [description]
	 * @return {void}
	 */
	var checkChords = function(codeA, codeB) {
		var strongA = codeA.getElementsByTagName('strong')[0];
		var strongB = codeB.getElementsByTagName('strong')[0];

		if (!strongA || !strongB) {
			return;
		}

		var boxA = getBox(strongA);
		var boxB = getBox(strongB);

		if (checkOverlap(boxA, boxB)) {
			var width = boxA.right - boxB.left + 1;
			codeA.style.paddingRight = (width < 1 ? 1 : width) + 'px';
		}
	};

	/**
	 * Runs through the element looking for UkeGeek chords (based on HTML) and
	 * adjust the horizontal spacing if any of the chords overlap.
	 * @method Fix
	 * @param  {DOM_element} element containing the UGS HTML song
	 */
	_public.Fix = function(ele) {
		var i,
			elements = ele.getElementsByTagName('code');

		for (i = 0; i < elements.length; i++) {
			elements[i].style.paddingRight = '0px';
		}

		for (i = 0; i < (elements.length - 1); i++) {
			checkChords(elements[i], elements[i + 1]);
		}
	};

	return _public;
})();