﻿/*! 
* jQuery nodesContainingText plugin 
* 
* Version: 1.1.2
* 
* http://code.google.com/p/jquery-translate/
* 
* Copyright (c) 2009 Balazs Endresz (balazs.endresz@gmail.com)
* Dual licensed under the MIT and GPL licenses.
* 
*/

; (function ($) {

	function Nct() { }

	Nct.prototype = {
		init: function (jq, o) {
			this.textArray = [];
			this.elements = [];
			this.options = o;
			this.jquery = jq;
			this.n = -1;
			if (o.async === true)
				o.async = 2;

			if (o.not) {
				jq = jq.not(o.not);
				jq = jq.add(jq.find("*").not(o.not)).not($(o.not).find("*"));
			} else
				jq = jq.add(jq.find("*"));

			this.jq = jq;
			this.jql = this.jq.length;
			return this.process();

		},

		process: function () {
			this.n++;
			var that = this, o = this.options, text = "", hasTextNode = false,
			hasChildNode = false, el = this.jq[this.n], e, c, ret;

			if (this.n === this.jql) {
				ret = this.jquery.pushStack(this.elements, "nodesContainingText");
				o.complete.call(ret, ret, this.textArray);

				if (o.returnAll === false && o.walk === false)
					return this.jquery;
				return ret;
			}

			if (!el)
				return this.process();
			e = $(el);

			var nodeName = el.nodeName.toUpperCase(),
			type = nodeName === "INPUT" && $.attr(el, "type").toLowerCase();

			if (({ SCRIPT: 1, NOSCRIPT: 1, STYLE: 1, OBJECT: 1, IFRAME: 1 })[nodeName])
				return this.process();

			if (typeof o.subject === "string") {
				text = e.attr(o.subject);
			} else {
				if (o.altAndVal && (nodeName === "IMG" || type === "image"))
					text = e.attr("alt");
				else if (o.altAndVal && ({ text: 1, button: 1, submit: 1 })[type])
					text = e.val();
				else if (nodeName === "TEXTAREA")
					text = e.val();
				else {
					//check childNodes:
					c = el.firstChild;
					if (o.walk !== true)
						hasChildNode = true;
					else {
						while (c) {
							if (c.nodeType == 1) {
								hasChildNode = true;
								break;
							}
							c = c.nextSibling;
						}
					}

					if (!hasChildNode)
						text = e.text();
					else {//check textNodes:
						if (o.walk !== true)
							hasTextNode = true;

						c = el.firstChild;
						while (c) {
							if (c.nodeType == 3 && c.nodeValue.match(/\S/) !== null) {//textnodes with text
								/*jslint skipLines*/
								if (c.nodeValue.match(/<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)>/) !== null) {
									if (c.nodeValue.match(/(\S+(?=.*<))|(>(?=.*\S+))/) !== null) {
										hasTextNode = true;
										break;
									}
								} else {
									hasTextNode = true;
									break;
								}
								/*jslint skipLinesEnd*/
							}
							c = c.nextSibling;
						}

						if (hasTextNode) {//remove child nodes from jq
							//remove scripts:
							text = e.html();
							/*jslint skipLines*/
							text = o.stripScripts ? text.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, "") : text;
							/*jslint skipLinesEnd*/
							this.jq = this.jq.not(e.find("*"));
						}
					}
				}
			}

			if (!text)
				return this.process();
			this.elements.push(el);
			this.textArray.push(text);

			o.each.call(el, this.elements.length - 1, el, text);

			if (o.async) {
				setTimeout(function () { that.process(); }, o.async);
				return this.jquery;
			} else
				return this.process();

		}
	};

	var defaults = {
		not: "",
		async: false,
		each: function () { },
		complete: function () { },
		comments: false,
		returnAll: true,
		walk: true,
		altAndVal: false,
		subject: true,
		stripScripts: true
	};

	$.fn.nodesContainingText = function (o) {
		o = $.extend({}, defaults, $.fn.nodesContainingText.defaults, o);
		return new Nct().init(this, o);
	};

	$.fn.nodesContainingText.defaults = defaults;

})(jQuery);
