﻿/*! 
* jQuery nodesContainingText plugin 
* 
* Version: 1.1.0
* 
* http://code.google.com/p/jquery-translate/
* 
* Copyright (c) 2009 Balazs Endresz (balazs.endresz@gmail.com)
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
* and GPL (http://www.opensource.org/licenses/gpl-license.php) 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
                                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;
                                }
                            }
                            c = c.nextSibling;
                        }

                        if (hasTextNode) {//remove child nodes from jq
                            //remove scripts:
                            text = e.html().replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, "");
                            this.jq = this.jq.not(e.find("*"));
                        }
                    }
                }
            }

            if (!text)
                return this.process();
            this.elements.push(el);
            if (o.comments === false)
                text = this.stripComments(text);
            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();

        },

        stripComments: function(t) { return t.replace(/<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)>/g, ""); }

    }

    $.fn.nodesContainingText = function(o) {
        o = $.extend({}, defaults, $.fn.nodesContainingText.defaults, o);
        return new Nct().init(this, o);
    }

    var defaults = {
        not: "",
        async: false,
        each: function() { },
        complete: function() { },
        comments: false,
        returnAll: true,
        walk: true,
        altAndVal: false,
        subject: true
    }

    $.fn.nodesContainingText.defaults = defaults;

})(jQuery);

