jsbeans

jsbeans  1.0.0

jsbeans > jsbeans > Navbar.js (source view)
Search:
 
Filters
/*!
 * Copyright (c) 2009 Francesco Mele jsbeans@francescomele.com
 *
 * This Software is licenced under the LGPL Licence (GNU Lesser General 
 * Public License).
 * In addition to the LGPL Licence the Software is subject to the 
 * following conditions:
 * 
 * 	i	every modification must be public and comunicated to the Author
 * 	ii	every "jsbean" added to this library must be self consistent 
 * 		except for the dependence from jsbeans-x.x.x.js
 * 	iii	copyright notice and this permission notice shall be included 
 * 		in all copies or substantial portions of the Software
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */ 
/**
 * A navigation bar starting from a pseudo-xml descriptor of the site.
 * @namespace jsbeans
 * @class Navbar
 * @static
 */
jsbeans.Navbar = {
	/**
	 * @property options
	 * @type JSON
	 * @static
	 * <pre>
	 * parameter: String, // the name of the request parameter indicating the actual page
	 * separator: String, // separator of each element of navigation bar, default " &gt; "
	 * target: String, // the id of the container of the navigation bar, default "navbar"
	 * descriptor: String, // the id of the container of the descriptor, usually an hidden div
	 * linkable: boolean, // if any voice of the navigation bar must have a link to the corresponding page, default true
	 * home: String, // the context path, default "/"
	 * replace: Array // replacer for rendered links
	 * </pre>
	 * */
	options: {
		parameter: null,
		separator: " &gt; ",
		target: "navbar",
		descriptor: "navbardescriptor",
		linkable: true,
		home: "/",
		replace: null
	},
	/**
	 * Renders the UI
	 * @method render
	 * @param [options] {JSON} override of defaults
	 * @static
	 * */
	render: function() {
		this._init(arguments[0] || {});
		var descriptor = document.getElementById("" + this.options.descriptor);
		if (descriptor == null || typeof(descriptor) == "undefined") {
			return;
		}
		descriptor.style.display = "none";
		descriptor.style.visibility = "hidden";
		descriptor.style.position = "absolute";
		descriptor.style.top = "-10000px";
		var currentPage = null;
		// use parameter
		if (this.options.parameter != null) {
			if (this._isFun(this.options.parameter)) {
				var parVal = this.options.parameter();
			}
			else {
				var parVal = this.getParameterValue();
			}
			if (this.options.replace != null && parVal != null) {
				parVal = parVal.split(this.options.replace[0]).join(this.options.replace[1]);
			}
			currentPage = document.getElementById(parVal);
		} 
		// use url
		else { 
			var currentLocation = location.href;
			// cut from protocol to first ? (http://www.francescomele.com/index.php?parName=parValue => www.francescomele.com/index.php)
			currentLocation = currentLocation.substring(currentLocation.indexOf("://") + 3, currentLocation.length);
			if (currentLocation.indexOf("?") != -1) {
				currentLocation = currentLocation.substring(0, currentLocation.indexOf("?"));
			}
			// cut this.options.home if != "/"
			if (this.options.home != "/" && currentLocation.indexOf(this.options.home) != -1) {
				currentLocation = currentLocation.substring(currentLocation.indexOf(this.options.home) + this.options.home.length);
			}
			currentPage = document.getElementById(currentLocation);
		}
		if (currentPage == null || typeof(currentPage) == "undefined") {
			return;
		}
		this._navbar = new Array();
		this._buildNavigation(currentPage);
		this._navbar.reverse();
		var nv = document.getElementById(this.options.target);
		nv.innerHTML = "";
		var a, cur;
		for (var i = 0; i < this._navbar.length; i++) {
			cur = this._navbar[i];
			a = document.createElement("a");
			if (this.options.linkable && (i != this._navbar.length - 1)) {
				// use parameter
				if (this.options.parameter != null) {
					if (this._isFun(this.options.parameter)) {
						a.href = "?" + this.options.parameter(cur);
					}
					else {
						a.href = "?" + this.options.parameter + "=" + this._getHref(cur);
					}
				} 
				// use url
				else { 
					a.href = this._getHref(cur);
				}
			}
			a.title = this._getAlt(cur);
			a.innerHTML = this._getLabel(cur);
			nv.innerHTML = nv.innerHTML + " " + this.options.separator;
			nv.appendChild(a);
		}
	},
	/**
	 * Returns the value of the request parameter as that of <code class="prop">jsbeans.Navbar.options.parameter</code>
	 * @method getParameterValue
	 * @return {String} the request parameter value
	 * @static
	 * */
	getParameterValue: function() {
		var qs = location.search.substring(1, location.search.length).replace(/\+/g, ' ');
		var items = qs.split('&');
		for (var i = 0, item; item = items[i]; i++) {
			var p = item.split('=');
			var n = decodeURIComponent(p[0]);
			if (this.options.parameter == n) {
				return (p.length == 2) ? decodeURIComponent(p[1]) : null;
			}
		}
		return null;
	},
	/**
	 * @method _init
	 * @param options {JSON}
	 * @private
	 * @static
	 * */
	_init: function(/*JSON*/options) {
		this.options.parameter = typeof(options.parameter) != "undefined" ? options.parameter : this.options.parameter;
		this.options.separator = typeof(options.separator) != "undefined" ? options.separator : this.options.separator;
		this.options.target = typeof(options.target) != "undefined" ? options.target : this.options.target;
		this.options.descriptor = typeof(options.descriptor) != "undefined" ? options.descriptor : this.options.descriptor;
		this.options.linkable = typeof(options.linkable) != "undefined" ? options.linkable : this.options.linkable;
		this.options.home = typeof(options.home) != "undefined" ? options.home : this.options.home;
		this.options.replace = typeof(options.replace) != "undefined" ? options.replace : this.options.replace;
	},
	/**
	 * @property _navbar
	 * @type Array
	 * @private
	 * @static
	 * */
	_navbar: new Array(),
	/**
	 * @method _buildNavigation
	 * @param node {DOM}
	 * @return {Array}
	 * @private
	 * @static
	 * */
	_buildNavigation: function(node) {
		if (node.id != this.options.descriptor) {
			this._navbar.push(node);
			this._buildNavigation(node.parentNode);
		} 
		else {
			return this._navbar;
		}
	},
	/**
	 * @method _getHref
	 * @param node {DOM}
	 * @return {String}
	 * @private
	 * @static
	 * */
	_getHref: function(obj) {
		var res = this._getAttribute(obj, "id");
		if (this.options.replace != null) {
			res = res.split(this.options.replace[1]).join(this.options.replace[0]);
		}
		return res;
	},
	/**
	 * @method _getLabel
	 * @param node {DOM}
	 * @return {String}
	 * @private
	 * @static
	 * */
	_getLabel: function(obj) {
		return this._getAttribute(obj, "class");
	},
	/**
	 * @method _getAlt
	 * @param node {DOM}
	 * @return {String}
	 * @private
	 * @static
	 * */
	_getAlt: function(obj) {
		return this._getAttribute(obj, "title");
	},
	/**
	 * @method _getAttribute
	 * @param node {DOM}
	 * @param attributeName {String}
	 * @return {String}
	 * @private
	 * @static
	 * */
	_getAttribute: function(obj, attrName) {
		return obj == null || !obj.getAttribute ? null : obj.getAttribute(attrName);
	},
	/**
	 * Cheks if fn is a Function
	 * @method _isFun
	 * @param func {Object}
	 * @return {boolean} true if <code class="param">func</code> is a <code>Function</code>
	 * @private
	 * @static
	 * */
	_isFun: function(fn) {
		return !!fn && typeof fn != "string" && !fn.nodeName && 
		fn.constructor != Array && /function/i.test( fn + "" );
	}
};

Copyright © 2016 Francesco Mele. All rights reserved.