;(function(g){
	var D = document,
		  _tag = function(tag,p){
		    return p.getElementsByTagName(tag || "*");
	    };
  var _queryMethod = {
		"#":function(q,p){
       var bits = q.split("#"),
	         tagName = bits[0],
	         id = bits[1],
	         element = document.getElementById(id);
       return tagName && element.tagName.toLowerCase() != tagName ? [] : [element];
    },
		".":function(q,p){
			var bits = q.split("."),
				  tagName = bits[0],
				  cn=bits[1],
				  elems = null,
				  returnEl = [],
				  index = 0,
				  reg = new RegExp("\\b"+cn+"\\b");
		  for(var i=0,l = p.length;i<l;i++){
				elems = _tag(tagName,p[i]);
				var tmp = null;
				for(var j =0,m = elems.length;j<m;j++){
					if(!/\S/.test((tmp = elems[j]).nodeValue)) continue;
					if(reg.test(tmp.className)){
						returnEl[index++] = tmp;
					}
				}
			}
			return returnEl;
		},
		"_tag_":function(q,p){
			var found,returnEl = [],index=0;
			for(var i=0,l=p.length;i<l;i++){
				found = _tag(q,p[i]);
				for(var j =0,m=found.length;j<m;j++){
					returnEl[index++] = found[j];
				}
			}
			return returnEl;
		},
    "]":function(q,p){
			q.match(/^(.*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/);
			var returnEl = [],
				  index=fIndex=0,
				  op=RegExp.$3,
				  tag=RegExp.$1,
				  attr=RegExp.$2,
				  attrvalue=RegExp.$4,
			    found = query(tag,p);

			var checkFn = {
				'=':function(e) { return (e.getAttribute(attr) == attrValue); },
		    '~':function(e) { return (e.getAttribute(attr).match(new RegExp('\\b'+attrValue+'\\b'))); },
		    '|':function(e) { return (e.getAttribute(attr).match(new RegExp('^'+attrValue+'-?'))); },
		    '^':function(e) { return (e.getAttribute(attr).indexOf(attrValue) == 0); },
		    '$':function(e) { return (e.getAttribute(attr).lastIndexOf(attrValue) == e.getAttribute(attr).length - attrValue.length); },
		    '*':function(e) { return (e.getAttribute(attr).indexOf(attrValue) > -1); }
			}[op] || function(e) { return e.getAttribute(attr);};

			for(var i=0,l=found.length;i<l;i++){
				if(checkFn(found[i])){
					returnEl[fIndex++] = found[i];
				}
			}
			return returnEl;
		}
  }

	g.query = function(q,p){
		var elems = p || [D],reg=new RegExp(g.query.config.reg);
		var tokens = q.split(' '),token,m;
		for(var i=0,l=tokens.length;i<l;i++){
			token = tokens[i];
			m=token.match(reg);
			elems = _queryMethod[(m&&m[0]) || "_tag_"](token,elems);
		}
		return elems;
	}
	g.query.config={
		reg:"(\\])|(\\.)|(#)",
		addSelector:function(mark,fn){
			if(!mark || !fn){return;}
			_queryMethod[mark]=fn;
			mark = mark.replace(/(\.|\||\[|\]|\^|\\|\$|\?|\*|\+|\{|\}|\(|\))/g,"\\\\$1");
			this.reg += this.reg.indexOf(mark)!=-1? "" : "|("+mark+")";
		},
		queryMethod:_queryMethod
	}
})(this);
