
/**
 * Adds the specified class to the matched element.
 * @param className
 * @returns {Q.Dom.Element}
 */
Q.Dom.Element.prototype.addClass = function (className) {
    this.getElement().classList.add(className);
    return this;
};

/**
 * Remove a class from the matched element.
 * @param className
 * @returns {Q.Dom.Element}
 */
Q.Dom.Element.prototype.removeClass = function (className) {
    this.getElement().classList.remove(className);
    return this;
};

/**
 * Add or remove a class from the matched element, depending on the class's presence.
 * @param className
 * @returns {Q.Dom.Element}
 */
Q.Dom.Element.prototype.toggleClass = function(className){
    this.getElement().classList.toggle(className);
    return this;
};

/**
 * add a class to the matched element and remove the same class from its siblings
 * @param className
 * @returns {Q.Dom.Element}
 */
Q.Dom.Element.prototype.radioClass = function(className){
    var elem = this.getElement();
    Array.prototype.forEach.call(elem.parentNode.children, function(child){
        if(child !== elem){
            child.classList.remove(className);
        }
    });
    elem.classList.add(className);
    return this;
};

/**
 * Determine whether the matched element is assigned the given class.
 * @param className
 * @returns {boolean}
 */
Q.Dom.Element.prototype.hasClass = function(className){
    return this.getElement().classList.contains(className);
};

/**
 * Get the value of an attribute for the matched element.
 * @param attrName
 * @returns {string}
 */
Q.Dom.Element.prototype.getAttr = function(attrName){
    return this.getElement().getAttribute(attrName);
};

/**
 * Set an attribute for the matched element.
 * @param attrName
 * @param attrValue
 * @returns {Q.Dom.Element}
 */
Q.Dom.Element.prototype.setAttr = function(attrName, attrValue){
    this.getElement().setAttribute(attrName, attrValue);
    return this;
};

/**
 * Remove an attribute from the matched element.
 * @param attrName
 * @returns {Q.Dom.Element}
 */
Q.Dom.Element.prototype.removeAttr = function(attrName){
    this.getElement().removeAttribute(attrName);
    return this;
};

/**
 * Check if the matched element has the given attribute
 * @param attrName
 * @returns {boolean}
 */
Q.Dom.Element.prototype.hasAttr = function(attrName){
    return this.getElement().hasAttribute(attrName);
};

/**
 * Get element's text node
 * @returns {string|*}
 */
Q.Dom.Element.prototype.getText = function(){
    return this.getElement().textContent;
};

/**
 * sets element's text node
 * @param t
 * @returns {Q.Dom.Element}
 */
Q.Dom.Element.prototype.setText = function(t){
    var elem = this.getElement(),
        index = 0;
    if (typeof t === 'function') {
        elem.textContent = t.apply(elem, [elem.textContent, index]);
    } else {
        elem.textContent = t;
    }
    return this;
};

/**
 * Insert content, specified by the parameter, before the element
 * @param htmlString
 * @returns {Q.Dom.Element}
 */
Q.Dom.Element.prototype.before = function(htmlString){
    var elem = this.getElement();
    elem.insertAdjacentHTML('beforebegin', htmlString);
    return this;
};

/**
 * Insert content, specified by the parameter, after the element
 * @param htmlString
 * @returns {Q.Dom.Element}
 */
Q.Dom.Element.prototype.after = function(htmlString){
    var elem = this.getElement();
    elem.insertAdjacentHTML('afterend', htmlString);
    return this;
};

/**
 * Insert content, specified by the parameter, to the beginning of the element
 * @param htmlString
 * @returns {Q.Dom.Element}
 */
Q.Dom.Element.prototype.prepend = function(htmlString){
    var elem = this.getElement();
    elem.insertAdjacentHTML('afterbegin', htmlString);
    return this;
};

/**
 * Insert content, specified by the parameter, to the end of the element
 * @param htmlString
 * @returns {Q.Dom.Element}
 */
Q.Dom.Element.prototype.append = function(htmlString){
    var elem = this.getElement();
    elem.insertAdjacentHTML('beforeend', htmlString);
    return this;
};
