API Docs for: 0.0.1
Show:

File: src/vdom/partials/extend-element.js

"use strict";

/**
 * Provides several methods that override native Element-methods to work with the vdom.
 *
 *
 * <i>Copyright (c) 2014 ITSA - https://github.com/itsa</i>
 * <br>
 * New BSD License - http://choosealicense.com/licenses/bsd-3-clause/
 *
 * @module vdom
 * @submodule extend-element
 * @class Element
 * @since 0.0.1
*/


require('../css/element.css');
require('js-ext/lib/object.js');
require('js-ext/lib/string.js');
require('js-ext/lib/promise.js');
require('polyfill');

var createHashMap = require('js-ext/extra/hashmap.js').createMap;

module.exports = function (window) {

    window._ITSAmodules || Object.protectedProp(window, '_ITSAmodules', createHashMap());

    if (window._ITSAmodules.ExtendElement) {
        return; // ExtendElement was already created
    }

    // prevent double definition:
    window._ITSAmodules.ExtendElement = true;

    var NAME = '[extend-element]: ',
        ElementArray = require('./element-array.js')(window),
        domNodeToVNode = require('./node-parser.js')(window),
        htmlToVNodes = require('./html-parser.js')(window),
        vNodeProto = require('./vnode.js')(window),
        RUNNING_ON_NODE = (typeof global !== 'undefined') && (global.window!==window),
        mutationsAreObserved = false,
        TRANSITION = 'transition',
        TRANSFORM = 'transform',
        BROWSERS_SUPPORT_PSEUDO_TRANS = false, // set true as soon as they do
        SUPPORTS_PSEUDO_TRANS = null, // is a life check --> is irrelevant as long BROWSERS_SUPPORT_PSEUDO_TRANS === false
        VENDOR_CSS = require('polyfill/extra/vendorCSS.js')(window),
        generateVendorCSSProp = VENDOR_CSS.generator,
        VENDOR_CSS_PROPERTIES = VENDOR_CSS.cssProps,
        VENDOR_TRANSFORM_PROPERTY = generateVendorCSSProp(TRANSFORM),
        VENDOR_TRANSITION_PROPERTY = require('polyfill/extra/transition.js')(window), // DO NOT use TRANSITION-variable here --> browserify cannot deal this
        EV_TRANSITION_END = require('polyfill/extra/transitionend.js')(window),
        _BEFORE = ':before',
        _AFTER = ':before',
        extractor = require('./attribute-extractor.js')(window),
        UTILS = require('utils'),
        later = UTILS.later,
        async = UTILS.async,
        idGenerator = UTILS.idGenerator,
        DOCUMENT = window.document,
        arrayIndexOf = Array.prototype.indexOf,
        POSITION = 'position',
        ITSA_ = 'itsa-',
        BLOCK = ITSA_+'block',
        BORDERBOX = ITSA_+'borderbox',
        NO_TRANS = ITSA_+'notrans',
        NO_TRANS2 = NO_TRANS+'2', // needed to prevent removal of NO_TRANS when still needed `notrans`
        ITSA_NODISPLAY = ITSA_+'nodisplay',
        INVISIBLE = ITSA_+'invisible',
        INVISIBLE_RELATIVE = INVISIBLE+'-relative',
        INVISIBLE_UNFOCUSABLE = INVISIBLE+'-unfocusable',
        HIDDEN = ITSA_+'hidden',
        LEFT = 'left',
        TOP = 'top',
        BORDER = 'border',
        WIDTH = 'width',
        HEIGHT = 'height',
        STRING = 'string',
        CLASS = 'class',
        STYLE = 'style',
        OVERFLOW = 'overflow',
        SCROLL = 'scroll',
        BORDER_LEFT_WIDTH = BORDER+'-left-'+WIDTH,
        BORDER_RIGHT_WIDTH = BORDER+'-right-'+WIDTH,
        BORDER_TOP_WIDTH = BORDER+'-top-'+WIDTH,
        BORDER_BOTTOM_WIDTH = BORDER+'-bottom-'+WIDTH,
        NUMBER = 'number',
        PX = 'px',
        SET = 'set',
        TOGGLE = 'toggle',
        REPLACE = 'replace',
        REMOVE = 'remove',
        _STARTSTYLE = '_startStyle',
        setupObserver,
        SIBLING_MATCH_CHARACTER = createHashMap({
            '+': true,
            '~': true
        }),
        NON_CLONABLE_STYLES = createHashMap({
            absolute: true,
            hidden: true,
            block: true
        }),
        // CSS_PROPS_TO_CALCULATE should not be a hashMap, but an object --> we need to iterate with .each
        CSS_PROPS_TO_CALCULATE = { // http://www.w3.org/TR/css3-transitions/#animatable-css
            backgroundColor: true,
            backgroundPositionX: true,
            backgroundPositionY: true,
            borderBottomColor: true,
            borderBottomWidth: true,
            borderLeftColor: true,
            borderLeftWidth: true,
            borderRightColor: true,
            borderRightWidth: true,
            borderTopColor: true,
            borderTopWidth: true,
            borderSpacing: true,
            bottom: true,
            clip: true,
            color: true,
            fontSize: true,
            fontWeight: true,
            height: true,
            left: true,
            letterSpacing: true,
            lineHeight: true,
            marginBottom: true,
            marginTop: true,
            marginLeft: true,
            marginRight: true,
            maxHeight: true,
            maxWidth: true,
            minHeight: true,
            minWidth: true,
            opacity: true,
            outlineColor: true,
            outlineWidth: true,
            paddingBottom: true,
            paddingTop: true,
            paddingLeft: true,
            paddingRight: true,
            right: true,
            textIndent: true,
            textShadow: true,
            verticalAlign: true,
            // visibility: true,  DO NOT use visibility!
            width: true,
            wordSpacing: true,
            zIndex: true
        },
        // CSS_PROPS_TO_CALCULATE.transform is set later on by the vendor specific transform-property
        htmlToVFragments = function(html, nameSpace, allowScripts) {
            var vnodes = htmlToVNodes(html, vNodeProto, nameSpace, null, null, allowScripts),
                len = vnodes.length,
                _cleanupStyle = false,
                vnode, i, bkpAttrs, bkpVChildNodes, scriptContent, _scripts, _scriptVNodes, scriptVNode;

            for (i=0; i<len; i++) {
                vnode = vnodes[i];
                if (vnode.nodeType===1) {
                    (vnode.tag==='STYLE') && (_cleanupStyle=true);
                    if (vnode.tag==='SCRIPT') {
                        scriptContent = (vnode.attrs && vnode.attrs.src) ? vnode.attrs.src : vnode.vChildNodes[0].text;
                        // check if the parent has this script set:
                        // parent didn't had the script set: we will process
                        // but we need to remove the node once it is set
                        // also: the script's content will be stored on is parent,
                        // so we know can compare future comparision.
                        _scripts || (_scripts=[]);
                        _scripts[_scripts.length] = scriptContent;
                        _scriptVNodes || (_scriptVNodes=[]);
                        _scriptVNodes[_scriptVNodes.length] = vnode;
                        // CREATE INNER TEXTNODE
                        scriptVNode = Object.create(vNodeProto);
                        scriptVNode.nodeType = 3;
                        scriptVNode.domNode = DOCUMENT.createTextNode(scriptContent);
                        // create circular reference:
                        scriptVNode.domNode._vnode = scriptVNode;
                        scriptVNode.text = scriptContent;
                        scriptVNode.vParent = vnode;
                        vnode.vChildNodes = [scriptVNode];
                    }
                    // same tag --> only update what is needed
                    bkpAttrs = vnode.attrs;
                    bkpVChildNodes = vnode.vChildNodes;

                    // reset, to force creation of inner domNodes:
                    vnode.attrs = {};
                    vnode.vChildNodes = [];

                    // next: sync the vnodes:
                    vnode._setAttrs(bkpAttrs);
                    vnode._setChildNodes(bkpVChildNodes);
                }
                else {
                    vnode.domNode.nodeValue = vnode.text;
                }
            }
            return {
                isFragment: true,
                vnodes: vnodes,
                _scripts: _scripts,
                _scriptVNodes: _scriptVNodes,
                _cleanupStyle: _cleanupStyle
            };
        },
        toCamelCase = function(input) {
            input || (input='');
            return input.replace(/-(.)/g, function(match, group) {
                return group.toUpperCase();
            });
        },
        fromCamelCase = function(input) {
            input || (input='');
            return input.replace(/[a-z]([A-Z])/g, function(match, group) {
                return match[0]+'-'+group.toLowerCase();
            });
        },
        getVendorCSS = function(cssProperties) {
            var uniqueProps = {},
                i, len, prop, safeProperty, uniqueSafeProperty;
            len = cssProperties.length;
            for (i=len-1; i>=0; i--) {
                // set the right property, but also dedupe when there are multiple same vendor-properties
                prop = cssProperties[i];
                safeProperty = prop.property;
                if (safeProperty) {
                    safeProperty = fromCamelCase(safeProperty);
                    uniqueSafeProperty = safeProperty+'#'+prop.pseudo;
                    VENDOR_CSS_PROPERTIES[safeProperty] || (safeProperty=generateVendorCSSProp(safeProperty));
                    if (uniqueProps[uniqueSafeProperty]) {
                        cssProperties.splice(i, 1);
                    }
                    else {
                        uniqueProps[uniqueSafeProperty] = true;
                        prop.property = safeProperty;
                    }
                }
            }
            return cssProperties;
        },
        vendorSupportsPseudoTrans = function() {
            // DO NOT CHANGE THIS FUNCTION!
            // it does exactly what it should do:
            // Sarari seems to support speudo transmisions, however it calculates css-properties wrong when they are 'undefined'
            // within a specific node, while the 'non-pseudo' is defined.
            // This would lead into a wrong calculation (too many) of the number of expected transitionend-events
            // Thus, this feature is disabled in some specific browsers
            if (SUPPORTS_PSEUDO_TRANS) {
                return SUPPORTS_PSEUDO_TRANS;
            }
            var cssnode, node, nodeParent;
            DOCUMENT.body.prepend('<style id="vendorSupportsPseudoTrans_css" type="text/css">#vendorSupportsPseudoTransParent {background-color:#F00;} #vendorSupportsPseudoTrans {background-color:#00F;}</style>');
            DOCUMENT.body.prepend('<div id="vendorSupportsPseudoTransParent"><div id="vendorSupportsPseudoTrans"></div></div>');
            node = DOCUMENT.getElement('#vendorSupportsPseudoTrans');
            nodeParent = DOCUMENT.getElement('#vendorSupportsPseudoTransParent');
            cssnode = DOCUMENT.getElement('#vendorSupportsPseudoTrans_css');
            SUPPORTS_PSEUDO_TRANS = node.getStyle('background-color')!==node.getStyle('background-color', ':before');
            cssnode.remove();
            nodeParent.remove();
            return SUPPORTS_PSEUDO_TRANS;
        },
        getTransPromise = function(node, hasTransitionedStyle, removalPromise, afterTransEventsNeeded, transitionProperties, maxtranstime) {
            var promise, fallback;
            afterTransEventsNeeded || (afterTransEventsNeeded=1);
            if (hasTransitionedStyle) {
                promise = new window.Promise(function(fulfill) {
                    var afterTrans = function(e) {
                        var finishedProperty = e.propertyName,
                            index;
                        if (finishedProperty) {
                            // some browsers support this feature: now we can exactly determine what promise to fulfill
                            delete transitionProperties[finishedProperty];
                            // in case of shorthand properties (such as padding) allmost all browsers
                            // fire multiple detailed events (http://www.smashingmagazine.com/2013/04/26/css3-transitions-thank-god-specification/).
                            // therefore, we also must delete the shortcut property when a detailed property gets fired:
                            index = finishedProperty.indexOf('-');
                            if (index!==-1) {
                                finishedProperty = finishedProperty.substr(0, index);
                                delete transitionProperties[finishedProperty];
                            }
                            // now fulfill when empty:
                            if (transitionProperties.isEmpty()) {
                                fallback.cancel();
                                console.log('Transition fulfilled');
                                node.removeEventListener(EV_TRANSITION_END, afterTrans, true);
                                fulfill();
                            }
                        }
                        else {
                            // in cae the browser doesn't support e.propertyName, we need to countdown:
                            if (--afterTransEventsNeeded<=0) {
                                fallback.cancel();
                                node.removeEventListener(EV_TRANSITION_END, afterTrans, true);
                                console.log('Transition fulfilled by counting nr. of endTransition events');
                                fulfill();
                            }
                        }
                    };
                    if (EV_TRANSITION_END===undefined) {
                        // no transition supported
                        console.log('No endTransition events supported: transition fulfilled');
                        fulfill();
                    }
                    else {
                        node.addEventListener(EV_TRANSITION_END, afterTrans, true);
                        fallback = later(function(){
                            console.log('Transition fulfilled by timer');
                            fulfill();
                        }, maxtranstime*1000+50); // extra 50 ms, after all, it is a fallback, we don't want it to take over the original end-transition-events
                    }
                });
                removalPromise && (promise=window.Promise.finishAll([promise, removalPromise]));
            }
            else {
                promise = removalPromise || window.Promise.resolve();
            }
            return promise;
        },
        getClassTransPromise = function(node, method, className, extraData1, extraData2) {
            // first. check if the final node has a transitioned property.
            // If not, then return as fulfilled. If so, then check for all the transitioned properties,
            // if there is any who changes its calculated value. If not, then return as fulfilled. If so, then setup
            // the evenlistener
            var resolvedPromise = window.Promise.resolve(),
                currentInlineCSS = [],
                finalInlineCSS = [],
                finalNode, getsTransitioned, originalCSS, finalCSS, transPropertiesElement, transPropertiesBefore, transPropertiesAfter, bkpFreezedData1, endIntermediate,
                promise, finalCSS_before, finalCSS_after, transpromise, manipulated, getCurrentProperties, currentProperties, bkpNodeData, bkpFreezed, cleanup,
                originalCSS_before, originalCSS_after, searchTrans, generateInlineCSS, finalStyle, unFreeze, freezedExtraData1, startStyle, unfreezePromise,
                transprops, transpropsBefore, transpropsAfter, time1, time2;

            time1 = Date.now();
            bkpNodeData = idGenerator('bkpNode');
            bkpFreezed = idGenerator('bkpFreezed');
            bkpFreezedData1 = idGenerator('bkpFreezedData1');
            if ((method===TOGGLE) && !extraData1) {
                // because -when toggling- the future current node-class might have been changed:
                freezedExtraData1 = !node.hasClass(className);
            }
            unFreeze = function(options) {
                var bkpFreezedStyle = node.getData(bkpFreezed),
                    finish = options && options.finish,
                    cancel = options && options.cancel,
                    transitioned = !finish;
                bkpFreezedData1 = node.getData(bkpFreezedData1);
                if (bkpFreezedStyle!==undefined) {
                    if (finish || cancel) {
                        node.setClass(NO_TRANS2);
                    }
                    else {
                        node.setData(_STARTSTYLE, bkpFreezedStyle);
                    }
                    if (!cancel) {
                        switch(method) {
                            case SET:
                                unfreezePromise = node.setClass(className, transitioned);
                            break;
                            case REPLACE:
                                unfreezePromise = node.replaceClass(extraData1, className, extraData2, transitioned);
                            break;
                            case REMOVE:
                                unfreezePromise = node.removeClass(className, transitioned);
                            break;
                            case TOGGLE:
                                unfreezePromise = node.toggleClass(className, (bkpFreezedData1===undefined) ? extraData1 : bkpFreezedData1, transitioned);
                            break;
                        }
                    }
                    else {
                        unfreezePromise = resolvedPromise;
                    }
                    async(function() {
                        node.removeData(bkpFreezed);
                        node.removeData(bkpFreezedData1);
                    });
                    if (finish || cancel) {
                        finalStyle = finalNode.getAttr(STYLE);
                        node.setAttr(STYLE, finalStyle);
                        later(function() { // not just async --> it seems we need more time
                            node.removeClass(NO_TRANS2);
                        }, 50);
                        unfreezePromise = resolvedPromise;
                    }
                    return unfreezePromise;
                }
                return promise;
            };

            resolvedPromise.cancel = function() { /* NOOP for compatibility */ };
            resolvedPromise.freeze = function() { return window.Promise.resolve(0); /* compatibility */ };
            resolvedPromise.unfreeze = unFreeze;
            resolvedPromise.finish = function() { /* NOOP for compatibility */ };
            if (EV_TRANSITION_END===undefined) {
                return resolvedPromise;
            }
            cleanup = function() {
                // we manipulate the classes as they should be, before returning the original inline style:
                // all without Promise-return!
                if (!promise.cancelled && !promise.frozen) {
                    switch(method) {
                        case SET:
                            node.setClass(className);
                        break;
                        case REPLACE:
                            node.replaceClass(extraData1, className, extraData2);
                        break;
                        case REMOVE:
                            node.removeClass(className);
                        break;
                        case TOGGLE:
                            node.toggleClass(className, extraData1);
                        break;
                    }
                }
                // last transitionrun: reset the inline css:
                finalStyle = finalNode.getAttr(STYLE);
                if (!promise.frozen) {
                    node.removeData(bkpFreezed);
                    node.removeData(bkpFreezedData1);
                    node.setClass(NO_TRANS2);
                    node.setAttr(STYLE, finalStyle);
                }
                else {
                    node.setData(bkpFreezed, finalStyle);
                }
                node.removeData(bkpNodeData);
                finalNode.remove();
                async(function() {
                    node.removeClass(NO_TRANS2);
                    promise.fulfill();
                });
            };
            endIntermediate = function(type) {
                if (!promise.isFulfilled) {
                    manipulated = true;
                    node.setData(bkpFreezedData1, freezedExtraData1);
                    currentProperties = getCurrentProperties(node, transprops);
                    node.setClass(NO_TRANS2);
                    node.setInlineStyles(currentProperties, false, true);
                    if (BROWSERS_SUPPORT_PSEUDO_TRANS) {
                        node.setInlineStyles(getCurrentProperties(node, transpropsBefore, ':before'), false, true);
                        node.setInlineStyles(getCurrentProperties(node, transpropsAfter, ':after'), false, true);
                    }
                    // also force to set the style on the node outside the vdom --> by forcing this
                    // we won't run into the situation where the vdom doesn't change the dom because the style didn';'t change:
                    node._setAttribute(STYLE, node.getAttr(STYLE));
                    Object.defineProperty(promise, 'isFulfilled', {
                        configurable: false,
                        enumerable: false,
                        writable: false,
                        value: true
                    });
                    Object.defineProperty(promise, type, {
                        configurable: false,
                        enumerable: false,
                        writable: false,
                        value: true
                    });
                    if (transpromise) {
                        transpromise.reject(); // prevent transitionpromise to set its own final values after finishing
                    }
                    else {
                        // in case `transpromise` wasn't setup yet:
                        async(function() {
                            transpromise.reject(); // prevent transitionpromise to set its own final values after finishing
                        });
                    }
                }
                time2 || (time2=Date.now());
                return new window.Promise(function(resolve) {
                    async(function() {
                        resolve(time2-time1);
                    });
                });
            };
            searchTrans = function(CSS1, CSS2, transProperties) {
                var allTrans = !!transProperties.all,
                    searchObject = allTrans ? CSS_PROPS_TO_CALCULATE : transProperties,
                    transprops = {};

                searchObject.each(function(transProp, key) {
                    // transProp will always be a vendor-specific property already
                    key = toCamelCase(key);
                    if (CSS1[key]!==CSS2[key]) {
                        transprops[key] = true;
                    }
                });
                return (transprops.size()>0) ? transprops : null;
            };
            generateInlineCSS = function(group, transProperties, CSS1, CSS2) {
                transProperties.each(function(value, key) {
                    var prop1 = {property: key, value: CSS1[key]},
                        prop2 = {property: key, value: CSS2[key]};
                    if (group) {
                        prop1.pseudo = group;
                        prop2.pseudo = group;
                    }
                    currentInlineCSS[currentInlineCSS.length] = prop1;
                    finalInlineCSS[finalInlineCSS.length] = prop2;
                });
            };

            getCurrentProperties = function(node, transProperties, group) {
                var props = [],
                    styles = window.getComputedStyle(node, group);
                transProperties.each(function(value, property) {
                    // if property is vendor-specific transition, or transform, than we reset it to the current vendor
                    props.push({
                        property: property,
                        value: styles[toCamelCase(property)],
                        pseudo: group
                    });
                });
                return props;
            };

            finalNode = node.cloneNode(true);
            finalNode.setClass(NO_TRANS2);
            finalNode.setClass(INVISIBLE_UNFOCUSABLE);
            node.setData(bkpNodeData, finalNode);

            startStyle = node.getData(_STARTSTYLE);
            if (startStyle!==undefined) {
                finalNode.setAttr(STYLE, startStyle);
                node.removeData(_STARTSTYLE);
            }

            switch(method) {
                case SET:
                    finalNode.setClass(className);
                break;
                case REPLACE:
                    finalNode.replaceClass(extraData1, className, extraData2);
                break;
                case REMOVE:
                    finalNode.removeClass(className);
                break;
                case TOGGLE:
                    finalNode.toggleClass(className, extraData1);
                break;
            }
            // insert in the dom, to make its style calculatable:
            DOCUMENT.body.append(finalNode);

            // check the css-property `transition`
            finalNode.removeClass(NO_TRANS2);
            transPropertiesElement = finalNode.getStyle(TRANSITION);
            transPropertiesBefore = finalNode.getStyle(TRANSITION, _BEFORE);
            transPropertiesAfter = finalNode.getStyle(TRANSITION, _AFTER);
            finalNode.setClass(NO_TRANS2);
            getsTransitioned = false;
            if (!RUNNING_ON_NODE && ((transPropertiesElement.size()>0) || (transPropertiesBefore.size()>0) || (transPropertiesAfter.size()>0))) {
                // when code comes here, there are one or more properties that can be transitioned
                // check if their values differ from the original node
                originalCSS = window.getComputedStyle(node);
                originalCSS_before = window.getComputedStyle(node, _BEFORE);
                originalCSS_after = window.getComputedStyle(node, _AFTER);
                finalCSS = window.getComputedStyle(finalNode);
                finalCSS_before = window.getComputedStyle(finalNode, _BEFORE);
                finalCSS_after = window.getComputedStyle(finalNode, _AFTER);
/*jshint boss:true */
                if (transprops=searchTrans(originalCSS, finalCSS, transPropertiesElement)) {
/*jshint boss:false */
                    getsTransitioned = true;
                    generateInlineCSS(null, transprops, originalCSS, finalCSS);
                }
                if (BROWSERS_SUPPORT_PSEUDO_TRANS && vendorSupportsPseudoTrans()) {
/*jshint boss:true */
                    if (transpropsBefore=searchTrans(originalCSS_before, finalCSS_before, transPropertiesBefore)) {
/*jshint boss:false */
                        getsTransitioned = true;
                        generateInlineCSS(_BEFORE, transpropsBefore, originalCSS_before, finalCSS_before);
                    }
/*jshint boss:true */
                    if (transpropsAfter=searchTrans(originalCSS_after, finalCSS_after, transPropertiesAfter)) {
/*jshint boss:false */
                        getsTransitioned = true;
                        generateInlineCSS(_AFTER, transpropsAfter, originalCSS_after, finalCSS_after);
                    }
                }
            }
            if (getsTransitioned) {
                // to force the transitioned items to work, we will set their calculated inline values for both at the start as well
                // as on the end of the transition.
                // set the original css inline:
                promise = window.Promise.manage();
                promise.finally(function() {
                    time2 || (time2=Date.now());
                });
                node.setClass(NO_TRANS2);
                node.setInlineStyles(currentInlineCSS, false, true);
                async(function() {
                    if (!manipulated) {
                        node.removeClass(NO_TRANS2);
                        transpromise = node.setInlineStyles(finalInlineCSS, true, true);
                        transpromise.finally(function() {
                            // async `setAttr` --> only fulfill when the DOM has been updated
                            async(function() {
                                cleanup();
                            });
                        });
                    }
                });

                promise.cancel = function() {
                    return endIntermediate('cancelled');
                };

                promise.freeze = function() {
                    return endIntermediate('frozen');
                };

                promise.finish = function() {
                    return endIntermediate('finished');
                };

                promise.unfreeze = unFreeze;

                return promise;
            }
            else {
                switch(method) {
                    case SET:
                        node.setClass(className);
                    break;
                    case REPLACE:
                        node.replaceClass(extraData1, className, extraData2);
                    break;
                    case REMOVE:
                        node.removeClass(className);
                    break;
                    case TOGGLE:
                        node.toggleClass(className, extraData1);
                    break;
                }
                node.removeData(bkpNodeData);
                finalNode.remove();
            }

            return resolvedPromise;
        },
        classListProto = {
            add: function(className) {
                // we do not use the property className, but setAttribute, because setAttribute can be hacked by other modules like `vdom`
                // note: `this` is the returned object which is NOT the Elementinstance
                var thisobject = this,
                    element = thisobject.element,
                    doSet = function(cl) {
                        var clName = element.vnode.attrs[CLASS] || '';
                        // we do not use the property className, but setAttribute, because setAttribute can be hacked by other modules like `vdom`
                        thisobject.contains(cl) || (element.setAttribute(CLASS, clName+((clName.length>0) ? ' ' : '') + cl));
                    };
                if (typeof className === STRING) {
                    doSet(className);
                }
                else if (Array.isArray(className)) {
                    className.forEach(doSet);
                }
            },
            remove: function(className) {
                var element = this.element,
                    doRemove = function(cl) {
                        var clName = element.vnode.attrs[CLASS] || '',
                            regexp = new RegExp('(?:^|\\s+)' + cl + '(?:\\s+|$)', 'g');
                        // we do not use the property className, but setAttribute, because setAttribute can be hacked by other modules like `vdom`
                        // note: `this` is the returned object which is NOT the Elementinstance
                        element.setAttribute(CLASS, clName.replace(regexp, ' ').trim());
                    };
                if (typeof className === STRING) {
                    doRemove(className);
                }
                else if (Array.isArray(className)) {
                    className.forEach(doRemove);
                }
                (element.vnode.attrs[CLASS]==='') && element.removeAttr(CLASS);
            },
            toggle: function(className, forceState) {
                // we do not use the property className, but setAttribute, because setAttribute can be hacked by other modules like `vdom`
                // note: `this` is the returned object which is NOT the Elementinstance
                var thisobject = this,
                    doToggle = function(cl) {
                        if (typeof forceState === 'boolean') {
                            forceState ? thisobject.add(cl) : thisobject.remove(cl);
                        }
                        else {
                            thisobject.contains(cl) ? thisobject.remove(cl) : thisobject.add(cl);
                        }
                    };
                if (typeof className === STRING) {
                    doToggle(className);
                }
                else if (Array.isArray(className)) {
                    className.forEach(doToggle);
                }
            },
            contains: function(className) {
                // we do not use the property className, but setAttribute, because setAttribute can be hacked by other modules like `vdom`
                // note: `this` is the returned object which is NOT the Elementinstance.
                // May be an Array of classNames, which all needs to be present.
                return this.element.vnode.hasClass(className);
            },
            item: function(index) {
                var items = this.element.vnode.attrs['class'].split(' ');
                return items[index];
            },
            _init: function(element) {
                this.element = element;
            }
        },
        treeWalkerProto = {
            _init: function(element, whatToShow, filter) {
                var instance = this;
                if (typeof filter !== 'function') {
                    // check if it is a NodeFilter-object
                    filter && filter.acceptNode && (filter=filter.acceptNode);
                }
                (typeof filter==='function') || (filter=null);
                instance.vNodePointer = element.vnode;
                instance._root = element;
                whatToShow || (whatToShow=-1); // -1 equals NodeFilter.SHOW_ALL
                (whatToShow===-1) && (whatToShow=133);
                instance._whatToShow = whatToShow; // making it accessable for the getter `whatToShow`
                instance._filter = filter; // making it accessable for the getter `filter`
            },
            _match: function(vnode, forcedVisible) {
                var whatToShow = this._whatToShow,
                    filter = this._filter,
                    showElement = ((whatToShow & 1)!==0),
                    showComment = ((whatToShow & 128)!==0),
                    showText = ((whatToShow & 4)!==0),
                    typeMatch = (showElement && (vnode.nodeType===1)) || (showComment && (vnode.nodeType===8)) || (showText && (vnode.nodeType===3)),
                    visibleMatch = !forcedVisible || (window.getComputedStyle(vnode.domNode).display!=='none'),
                    funcMatch = filter ? filter(vnode.domNode) : true;
                return typeMatch && visibleMatch && funcMatch;
            },
            firstChild: function() {
                var instance = this,
                    foundVNode = instance.vNodePointer.vFirstChild;
                while (foundVNode && !instance._match(foundVNode)) {
                    foundVNode = foundVNode.vNext;
                }
                foundVNode && (instance.vNodePointer=foundVNode);
                return foundVNode && foundVNode.domNode;
            },
            lastChild: function() {
                var instance = this,
                    foundVNode = instance.vNodePointer.vLastChild;
                while (foundVNode && !instance._match(foundVNode)) {
                    foundVNode = foundVNode.vPrevious;
                }
                foundVNode && (instance.vNodePointer=foundVNode);
                return foundVNode && foundVNode.domNode;
            },
            nextNode: function() {
                var instance = this,
                    foundVNode = instance.vNodePointer.vNext;
                while (foundVNode && !instance._match(foundVNode, true)) {
                    foundVNode = foundVNode.vNext;
                }
                foundVNode && (instance.vNodePointer=foundVNode);
                return foundVNode && foundVNode.domNode;
            },
            nextSibling: function() {
                var instance = this,
                    foundVNode = instance.vNodePointer.vNext;
                while (foundVNode && !instance._match(foundVNode)) {
                    foundVNode = foundVNode.vNext;
                }
                foundVNode && (instance.vNodePointer=foundVNode);
                return foundVNode && foundVNode.domNode;
            },
            parentNode: function() {
                var instance = this,
                    foundVNode = instance.vNodePointer.vParent;
                (foundVNode!==instance._root) && (instance.vNodePointer=foundVNode);
                return foundVNode && foundVNode.domNode;
            },
            previousNode: function() {
                var instance = this,
                    foundVNode = instance.vNodePointer.vPrevious;
                while (foundVNode && !instance._match(foundVNode, true)) {
                    foundVNode = foundVNode.vPrevious;
                }
                foundVNode && (instance.vNodePointer=foundVNode);
                return foundVNode && foundVNode.domNode;
            },
            previousSibling: function() {
                var instance = this,
                    foundVNode = instance.vNodePointer.vPrevious;
                while (foundVNode && !instance._match(foundVNode)) {
                    foundVNode = foundVNode.vPrevious;
                }
                foundVNode && (instance.vNodePointer=foundVNode);
                return foundVNode && foundVNode.domNode;
            }
        };

    require('window-ext')(window);

    Object.defineProperties(treeWalkerProto, {
        'currentNode': {
            get: function() {
                return this.vNodePointer.domNode;
            }
        },
        'filter': {
            get: function() {
                return this._filter;
            }
        },
        'root': {
            get: function() {
                return this._root;
            }
        },
        'whatToShow': {
            get: function() {
                return this._whatToShow;
            }
        }
    });

    // NOTE: `vnode` should be a property of Node, NOT Element
    /**
     * Reference to the vnode-object that represents the Node
     *
     * (will autogenerate a vnode, should it not exists)
     *
     * @for Node
     * @property vnode
     * @type vnode
     * @since 0.0.1
     */
    Object.defineProperty(window.Node.prototype, 'vnode', {
       get: function() {
            var instance = this,
                vnode = instance._vnode,
                parentNode, parentVNode, index;
            if (!vnode) {
                vnode = instance._vnode = domNodeToVNode(instance);
                parentNode = instance.parentNode;
                 // parentNode.vnode will be an existing vnode, because it runs through the same getter
                // it will only be `null` if `html` is not virtualised
                parentVNode = parentNode && parentNode.vnode;
                if (parentVNode) {
                    // set the vnode at the right position of its children:
                    index = arrayIndexOf.call(parentNode.childNodes, instance);
                    vnode._moveToParent(parentVNode, index);
                }
            }
            return vnode;
        },
        set: function() {} // NOOP but needs to be there, otherwise we could clone any domNodes
    });

    CSS_PROPS_TO_CALCULATE[VENDOR_TRANSFORM_PROPERTY] = true;
    CSS_PROPS_TO_CALCULATE[generateVendorCSSProp(TRANSFORM+'-origin')] = true;
    CSS_PROPS_TO_CALCULATE[generateVendorCSSProp('perspective')] = true;

    // backup native _contains --> mutationobserver needs it
    // cautious: IE has this property ONLY on HTMLElement (not on Element)
    window.HTMLElement.prototype._contains = window.HTMLElement.prototype.contains;

    (function(ElementPrototype) {

        /**
        * Determines the number of transitionend-events there will occur
        * @method _getEvtTransEndCount
        * @private
        * @since 0.0.1
        */
        ElementPrototype._getEvtTransEndCount = function(cssProperties) {
            var transitions = this.getStyle(TRANSITION),
                timing = {},
                duration, delay, time;
            transitions.each(function(transition) {
                if (!cssProperties || (cssProperties[transition.property])) {
                    duration = transition.duration || 0;
                    delay = transition.delay || 0;
                    time = (duration+delay);
                    timing[time] = true;
                }
            });
            return timing.size();
        };

        /**
        * Returns cascaded "transition" style of all transition-properties. `Cascaded` means: the actual present style,
        * the way it is visible (calculated through the DOM-tree).
        *
        * Note1: When "transition" is set inline, ONLY inline transtition is active!
        * Thus, if parentNode has "transition: width 2s" and inline has "transition: height 3s", then the transition
        * will be "transition: height 3s" --> returning "undefined" for transitionProperty=width.
        * Note2: in case of "transition: all" --> these values will be returned for every "transitionProperty" (even when querying "width")
        *
        * @method _getTransitionAll
        * @param transitionProperty {String} transform property that is queried, f.e. "width", or "all"
        * @param [pseudo] {String} to query pseudo-element, fe: `:before` or `:first-line`
        * @return {Object} the transition-object, with the properties:
        * <ul>
        *     <li>duration {Number}</li>
        *     <li>timingFunction {String}</li>
        *     <li>delay {Number}</li>
        * </ul>
        * @private
        * @since 0.0.1
        */
        ElementPrototype._getTransitionAll = function(pseudo) {
            var instance = this,
                transProperty, transDuration, transTimingFunction, transDelay, transPropertySplitted, property,
                transitions, transDurationSplitted, transTimingFunctionSplitted, transDelaySplitted, i, len, duration;
            // first look at inline transition:
            transitions = instance.getInlineTransition(null, pseudo);
            if (transitions) {
                return transitions;
            }
            // no inline transitions over here --> calculate using getStyle
            transitions = {};
            transProperty = instance.getStyle(VENDOR_TRANSITION_PROPERTY+'Property', pseudo);
            transDuration = instance.getStyle(VENDOR_TRANSITION_PROPERTY+'Duration', pseudo);
            transTimingFunction = instance.getStyle(VENDOR_TRANSITION_PROPERTY+'TimingFunction', pseudo);
            transDelay = instance.getStyle(VENDOR_TRANSITION_PROPERTY+'Delay', pseudo);
            if (transProperty) {
                transPropertySplitted = transProperty && transProperty.split(',');
                transDurationSplitted = transDuration.split(',');
                transTimingFunctionSplitted = transTimingFunction.split(',');
                transDelaySplitted = transDelay.split(',');
                len = transPropertySplitted.length;
                for (i=0; i<len; i++) {
                    property = transPropertySplitted[i];
                    duration = transTimingFunctionSplitted[i];
                    if ((property!=='none') && (duration!=='0s')) {
                        if (property!=='all') {
                            property = VENDOR_CSS_PROPERTIES[property] || generateVendorCSSProp(property);
                        }
                        transitions[property] = {
                            duration: parseFloat(transDurationSplitted[i]),
                            timingFunction: duration,
                            delay: parseFloat(transDelaySplitted[i])
                        };
                    }
                }
            }
            return transitions;
        };

        /**
         * Inserts a system-HTMLElement. These are child-Elements, just like other children, but they have a slightly different behaviour:
         *
         * <ul>
         *     <li>They get inserted as the first of the children</li>
         *     <li>They don't show up when querying</li>
         *     <li>They retain whenever new content is set for the parent-Element</li>
         * </ul>
         *
         * System-Elements are useful f.e. when you want to add special features to an Element, like scrolling or resizing. You can add `helper-elements`
         * (the system-elements) which keep hidden (protected) and retain whenever the Element changes his content.
         *
         * @method addSystemElement
         * @param content {Element|ElementArray|String} content to append
         * @param [escape] {Boolean} whether to insert `escaped` content, leading it into only text inserted
         * @param [silent=true] {Boolean} prevent node-mutation events by the Event-module to emit --> defaults TRUE
         * @return {Element} the created Element (or the last when multiple)
         */
        ElementPrototype.addSystemElement = function(content, escape, silent) {
            var instance = this,
                vChildNodes = instance.vnode.vChildNodes,
                len = vChildNodes.length,
                systemElement, refElement, i;
            (typeof silent === 'boolean') || (silent=true);
            for (i=0; (i<len) && !refElement; i++) {
                vChildNodes[i]._systemNode || (refElement=vChildNodes[i].domNode);
            }
            systemElement = refElement ? instance.prepend(content, escape, refElement, silent) : instance.append(content, escape, refElement, silent);
            systemElement.vnode._systemNode = true;
            systemElement.setAttr('is', 'system-node', true);
            return systemElement;
        };

       /**
        * Appends an Element or an Element's string-representation at the end of Element's innerHTML, or before the `refElement`.
        *
        * @for Element
        * @method append
        * @param content {Element|ElementArray|String} content to append
        * @param [escape] {Boolean} whether to insert `escaped` content, leading it into only text inserted
        * @param [refElement] {Element} reference Element where the content should be appended
        * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
        * @param [allowScripts=false] {Boolean} whether scripts are allowed --> these should be defined with `xscript` instead of `script`
        * @return {Element} the created Element (or the last when multiple)
        * @since 0.0.1
        */
        ElementPrototype.append = function(content, escape, refElement, silent, allowScripts) {
            var instance = this,
                vnode = instance.vnode,
                prevSuppress = DOCUMENT._suppressMutationEvents || false,
                i, len, item, createdElement, vnodes, vRefElement, _scripts, scriptcontent, hasDisplayNode,
            doAppend = function(oneItem) {
                escape && (oneItem.nodeType===1) && (oneItem=DOCUMENT.createTextNode(oneItem.getOuterHTML()));
                createdElement = refElement ? vnode._insertBefore(oneItem.vnode, refElement.vnode) : vnode._appendChild(oneItem.vnode);
            };
            // for optimum performance, we "disply: block" the parent node, so that repainting the dom only happens once (when displayed again)
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(true);
            vnode._noSync()._normalizable(false);
            if (refElement && (vnode.vChildNodes.indexOf(refElement.vnode)!==-1)) {
                vRefElement = refElement.vnode.vNext;
                refElement = vRefElement && vRefElement.domNode;
            }
            (typeof content===STRING) && (content=htmlToVFragments(content, vnode.ns, allowScripts));
            if (content.isFragment) {
                hasDisplayNode = instance.hasClass(ITSA_NODISPLAY);
                hasDisplayNode || instance.setClass(ITSA_NODISPLAY);
                vnodes = content.vnodes;
                len = vnodes.length;
                for (i=0; i<len; i++) {
                    doAppend(vnodes[i].domNode);
                }
/*jshint boss:true */
                if (_scripts=content._scripts) {
/*jshint boss:false */
                    len = _scripts.length;
                    vnode._scripts || (vnode._scripts=[]);
                    for (i=0; i<len; i++) {
                        scriptcontent = _scripts[i];
                        if (!vnode._scripts.contains(scriptcontent)) {
                            vnode._scripts[vnode._scripts.length] = scriptcontent;
                        }
                    }
                }
                // in case a style-tag was added, we need to cleanup double definitions:
                content._cleanupStyle && vnode._cleanupStyle();
                vnode._normalizable(true)._normalize();
                hasDisplayNode || instance.removeClass(ITSA_NODISPLAY);
            }
            else if (Array.isArray(content)) {
                hasDisplayNode = instance.hasClass(ITSA_NODISPLAY);
                hasDisplayNode || instance.setClass(ITSA_NODISPLAY);
                len = content.length;
                for (i=0; i<len; i++) {
                    item = content[i];
                    doAppend(item);
                }
                vnode._normalizable(true)._normalize();
                hasDisplayNode || instance.removeClass(ITSA_NODISPLAY);
            }
            else {
                doAppend(content);
                vnode._normalizable(true)._normalize();
            }
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(prevSuppress);
            return createdElement;
        };

        /**
         * Adds a node to the end of the list of childNodes of a specified parent node.
         *
         * @method appendChild
         * @param content {Element|ElementArray|String} content to append
         * @param [escape] {Boolean} whether to insert `escaped` content, leading it into only text inserted
         * @return {Element} the Element that was appended
         */
        ElementPrototype._appendChild = ElementPrototype.appendChild;
        ElementPrototype.appendChild = function(domNode, escape) {
            return this.append(domNode, escape);
        };

       /**
        * Returns a duplicate of the node. Use cloneNode(true) for a `deep` clone.
        *
        * @method cloneNode
        * @param [deep] {Boolean} whether to perform a `deep` clone: with all descendants
        * @return {Element} a clone of this Element
        * @since 0.0.1
        */
        ElementPrototype._cloneNode = ElementPrototype.cloneNode;
        ElementPrototype.cloneNode = function(deep) {
            var instance = this,
                vnode = instance.vnode,
                plugins = [],
                cloned = instance._cloneNode(deep),
                cloneData = function(srcVNode, targetVNode) {
                    if (srcVNode._data) {
                        Object.protectedProp(targetVNode, '_data', {});
                        targetVNode._data.merge(srcVNode._data);
                    }
                },
                updatePlugins = function(srcVNode, targetVNode) {
                    targetVNode && targetVNode.attrs && targetVNode.attrs.each(function(value, key) {
                        var pluginName;
                        if (key.substr(0, 7)==='plugin-') {
                            pluginName = key.substr(7);
                            // remove and reset the plugin with shallowcloned modeldata
                            // needs to be scheduled --> when deep cloned the full node needs t be build up first
                            // otherwise we could get doube rendered nodes.
                            plugins[plugins.length] = {
                                domNode: targetVNode.domNode,
                                pluginName: pluginName,
                                model: srcVNode.domNode._plugin[pluginName].model.shallowClone()
                            };
                        }
                    });
                },
                cloneDeepData = function(srcVNode, targetVNode) {
                    var srcVChildren, targetVChildren, len, i, childSrcVNode, childTargetVNode;
                    if (srcVNode && targetVNode) {
                        srcVChildren = srcVNode.vChildren;
                        targetVChildren = targetVNode.vChildren;
                        len = srcVChildren.length;
                        for (i=0; i<len; i++) {
                            childSrcVNode = srcVChildren[i];
                            childTargetVNode = targetVChildren[i];
                            cloneData(childSrcVNode, childTargetVNode);
                            updatePlugins(childSrcVNode, childTargetVNode);
                            childSrcVNode.hasVChildren() && cloneDeepData(childSrcVNode, childTargetVNode);
                        }
                    }
                },
                i, len, PluginClass, pluginDef;
            cloned.vnode = domNodeToVNode(cloned);
            cloneData(vnode, cloned.vnode);
            updatePlugins(vnode, cloned.vnode);
            // if deep, then we need to merge _data of all deeper nodes
            deep && vnode.hasVChildren() && cloneDeepData(vnode, cloned.vnode);
            len = plugins.length;
            for (i=0; i<len; i++) {
                pluginDef = plugins[i];
                PluginClass = window._ITSAPlugins[pluginDef.pluginName];
                pluginDef.domNode.unplug(PluginClass);
                pluginDef.domNode.plug(PluginClass, null, pluginDef.model);
            }
            return cloned;
        };

        /**
         * Compares the position of the current node against another node in any other document.
         *
         * Returnvalues are a composition of the following bitwise values:
         * <ul>
         *     <li>Node.DOCUMENT_POSITION_DISCONNECTED === 1 (one of the Elements is not part of the dom)</li>
         *     <li>Node.DOCUMENT_POSITION_PRECEDING === 2 (this Element comes before otherElement)</li>
         *     <li>Node.DOCUMENT_POSITION_FOLLOWING === 4 (this Element comes after otherElement)</li>
         *     <li>Node.DOCUMENT_POSITION_CONTAINS === 8 (otherElement trully contains -not equals- this Element)</li>
         *     <li>Node.DOCUMENT_POSITION_CONTAINED_BY === 16 (Element trully contains -not equals- otherElement)</li>
         * </ul>
         *
         * @method compareDocumentPosition
         * @param otherElement {Element}
         * @return {Number} A bitmask, use it this way: if (thisNode.compareDocumentPosition(otherNode) & Node.DOCUMENT_POSITION_FOLLOWING) {// otherNode is following thisNode}
         */
        ElementPrototype.compareDocumentPosition = function(otherElement) {
            // see http://ejohn.org/blog/comparing-document-position/
            var instance = this,
                parent, index1, index2, vChildNodes, vnode, otherVNode,
                i_instance, i_other, sameLevel, arrayInstance, arrayOther;
            if (instance===otherElement) {
                return 0;
            }
            if (!DOCUMENT.contains(instance, null, true) || !DOCUMENT.contains(otherElement, null, true)) {
                return 1;
            }
            else if (instance.contains(otherElement)) {
                return 20;
            }
            else if (otherElement.contains(instance)) {
                return 10;
            }
            parent = instance.getParent();
            vChildNodes = parent.vnode.vChildNodes;
            vnode = instance.vnode;
            otherVNode = otherElement.vnode;
            index1 = vChildNodes.indexOf(vnode);
            index2 = vChildNodes.indexOf(otherVNode);
            if ((index1!==-1) && (index2!==-1)) {
                if (index1<index2) {
                    return 4;
                }
                else {
                    return 2;
                }
            }
            // still not found, now we need to inspect the tree-structure of both elements
            // and determine at what point (up-down the tree) the elements are going to differ
            arrayInstance = [];
            arrayOther = [];
            arrayInstance[0] = vnode;
/*jshint boss:true */
            while (vnode=vnode.vParent) {
/*jshint boss:false */
                arrayInstance[arrayInstance.length] = vnode;
            }
            arrayOther[0] = otherVNode;
/*jshint boss:true */
            while (otherVNode=otherVNode.vParent) {
/*jshint boss:false */
                arrayOther[arrayOther.length] = otherVNode;
            }
            i_instance = arrayInstance.length - 1;
            i_other = arrayOther.length - 1;
            sameLevel = true;
            while (sameLevel && (i_instance>=0) && (i_other>=0)) {
                // starts with the most upper element
                vnode = arrayInstance[i_instance];
                otherVNode = arrayOther[i_other];
                sameLevel = (vnode===otherVNode);
                i_instance--;
                i_other--;
            }
            // now we are out and we should be able to compare `vnode` and `otherVNode` which lie at the same level though are different
            parent = vnode.vParent;
            vChildNodes = parent.vChildNodes;
            index1 = vChildNodes.indexOf(vnode);
            index2 = vChildNodes.indexOf(otherVNode);
            if (index1<index2) {
                return 4;
            }
            else {
                return 2;
            }
        };

        /**
         * Indicating whether this Element contains OR equals otherElement. If you need only to be sure the other Element lies inside,
         * but not equals itself, set `excludeItself` true.
         *
         * @method contains
         * @param otherElement {Element}
         * @param [excludeItself=false] {Boolean} to exclude itself as a hit
         * @param [inspectProtectedNodes=false] {Boolean} no deepsearch in protected Nodes or iTags --> by default, these elements should be hidden
         * @return {Boolean} whether this Element contains OR equals otherElement.
         */
        ElementPrototype.contains = function(otherElement, excludeItself, inspectProtectedNodes) {
            if (otherElement===this) {
                return !excludeItself;
            }
            return !!otherElement && this.vnode.contains(otherElement.vnode, !inspectProtectedNodes);
        };

        /**
         * Returns a newly created TreeWalker object with this Element as root.
         *
         * The TreeWalker is life presentation of the dom. It gets updated when the dom changes.
         *
         * @method createTreeWalker
         * @param root {Element} The root node at which to begin the NodeIterator's traversal.
         * @param [whatToShow] {Number} Filter specification constants from the NodeFilter DOM interface, indicating which nodes to iterate over.
         * You can use or sum one of the next properties:
         * <ul>
         *   <li>window.NodeFilter.SHOW_ALL === -1</li>
         *   <li>window.NodeFilter.SHOW_ELEMENT === 1</li>
         *   <li>window.NodeFilter.SHOW_COMMENT === 128</li>
         *   <li>window.NodeFilter.SHOW_TEXT === 4</li>
         * </ul>
         *
         * A treewalker has the next methods:
         * <ul>
         *   <li>treewalker.firstChild()</li>
         *   <li>treewalker.lastChild()</li>
         *   <li>treewalker.nextNode()</li>
         *   <li>treewalker.nextSibling()</li>
         *   <li>treewalker.parentNode()</li>
         *   <li>treewalker.previousNode()</li>
         *   <li>treewalker.previousSibling()</li>
         * </ul>
         *
         * A treewalker has the next properties:
         * <ul>
         *   <li>treewalker.currentNode</li>
         *   <li>treewalker.filter</li>
         *   <li>treewalker.root</li>
         *   <li>treewalker.whatToShow</li>
         * </ul>
         *
         * @param [filter] {NodeFilter|function} An object implementing the NodeFilter interface or a function. See https://developer.mozilla.org/en-US/docs/Web/API/NodeFilter
         * @return {TreeWalker}
         * @since 0.0.1
         */
        ElementPrototype.createTreeWalker = function(whatToShow, filter) {
            var treeWalker = Object.create(treeWalkerProto);
            treeWalker._init(this, whatToShow, filter);
            return treeWalker;
        };

       /**
        * Sets the inline-style of the Element exactly to the specified `value`, overruling previous values.
        * Making the Element's inline-style look like: style="value".
        *
        * This is meant for a quick one-time setup. For individually inline style-properties to be set, you can use `setInlineStyle()`.
        *
        * @method defineInlineStyle
        * @param value {String} the style string to be set
        * @chainable
        * @since 0.0.1
        */
        ElementPrototype.defineInlineStyle = function(value) {
            return this.setAttr(STYLE, value);
        };

       /**
        * Empties the content of the Element.
        * Alias for thisNode.vTextContent = '';
        *
        * @method empty
        * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
        * @param [full=false] {Boolean} whether system-nodes should be removed as well
        * @chainable
        * @since 0.0.1
        */
        ElementPrototype.empty = function(silent, full) {
            var prevSuppress = DOCUMENT._suppressMutationEvents || false;
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(true);
            this.vnode.empty(full);
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(prevSuppress);
        };

        /**
         * Reference to the first of sibbling vNode's, where the related dom-node is an Element(nodeType===1).
         *
         * @method first
         * @param [cssSelector] {String} to return the first Element that matches the css-selector
         * @param [container] {HTMLElement} the container-element to search within --> this lead into searching out of the same level
         * @return {Element}
         * @since 0.0.1
         */
        ElementPrototype.first = function(cssSelector, container) {
            var parent, firstV;
            if (container) {
                return container.querySelector(cssSelector);
            }
            parent = this.vnode.vParent;
            firstV = parent && parent.firstOfVChildren(cssSelector);
            return firstV && firstV.domNode;
        };

        /**
         * Reference to the first child-Element, where the related dom-node an Element (nodeType===1).
         *
         * @method firstOfChildren
         * @param [cssSelector] {String} to return the first Element that matches the css-selector
         * @return {Element}
         * @since 0.0.1
         */
        ElementPrototype.firstOfChildren = function(cssSelector) {
            var foundVNode = this.vnode.firstOfVChildren(cssSelector);
            return foundVNode && foundVNode.domNode;
        };

       /**
        * Forces the Element to be inside an ancestor-Element that has the `overfow="scroll" set.
        *
        * @method forceIntoNodeView
        * @param [ancestor] {Element} the Element where it should be forced into its view.
        *        Only use this when you know the ancestor and this ancestor has an `overflow="scroll"` property
        *        when not set, this method will seek through the doc-tree upwards for the first Element that does match this criteria.
        * @chainable
        * @since 0.0.1
        */
        ElementPrototype.forceIntoNodeView = function(ancestor) {
            // TODO: transitioned: http://wibblystuff.blogspot.nl/2014/04/in-page-smooth-scroll-using-css3.html
            console.log(NAME, 'forceIntoNodeView');
            var instance = this,
                parentOverflowNode = this.getParent(),
                match, left, width, right, height, top, bottom, scrollLeft, scrollTop, parentOverflowNodeX, parentOverflowNodeY,
                parentOverflowNodeStartTop, parentOverflowNodeStartLeft, parentOverflowNodeStopRight, parentOverflowNodeStopBottom, newX, newY;
            if (parentOverflowNode) {
                if (ancestor) {
                    parentOverflowNode = ancestor;
                }
                else {
                    while (parentOverflowNode && (parentOverflowNode!==DOCUMENT) && !(match=((parentOverflowNode.getStyle(OVERFLOW)===SCROLL) || (parentOverflowNode.getStyle(OVERFLOW+'-y')===SCROLL)))) {
                        parentOverflowNode = parentOverflowNode.getParent();
                    }
                }
                if (parentOverflowNode && (parentOverflowNode!==DOCUMENT)) {
                    left = instance.left;
                    width = instance.offsetWidth;
                    right = left + width;
                    height = instance.offsetHeight;
                    top = instance.top;
                    bottom = top + height;
                    scrollLeft = parentOverflowNode.scrollLeft;
                    scrollTop = parentOverflowNode.scrollTop;
                    parentOverflowNodeX = parentOverflowNode.left;
                    parentOverflowNodeY = parentOverflowNode.top;
                    parentOverflowNodeStartTop = parentOverflowNodeY+parseInt(parentOverflowNode.getStyle(BORDER_TOP_WIDTH), 10);
                    parentOverflowNodeStartLeft = parentOverflowNodeX+parseInt(parentOverflowNode.getStyle(BORDER_LEFT_WIDTH), 10);
                    parentOverflowNodeStopRight = parentOverflowNodeX+parentOverflowNode.offsetWidth-parseInt(parentOverflowNode.getStyle(BORDER_RIGHT_WIDTH), 10);
                    parentOverflowNodeStopBottom = parentOverflowNodeY+parentOverflowNode.offsetHeight-parseInt(parentOverflowNode.getStyle(BORDER_BOTTOM_WIDTH), 10);

                    if (left<parentOverflowNodeStartLeft) {
                        newX = Math.max(0, scrollLeft+left-parentOverflowNodeStartLeft);
                    }
                    else if (right>parentOverflowNodeStopRight) {
                        newX = scrollLeft + right - parentOverflowNodeStopRight;
                    }

                    if (top<parentOverflowNodeStartTop) {
                        newY = Math.max(0, scrollTop+top-parentOverflowNodeStartTop);
                    }
                    else if (bottom>parentOverflowNodeStopBottom) {
                        newY = scrollTop + bottom - parentOverflowNodeStopBottom;
                    }

                    if ((newX!==undefined) || (newY!==undefined)) {
                        parentOverflowNode.scrollTo((newX!==undefined) ? newX : scrollLeft,(newY!==undefined) ? newY : scrollTop);
                    }
                }
            }
            return instance;
        };

       /**
        * Forces the Element to be inside the window-view. Differs from `scrollIntoView()` in a way
        * that `forceIntoView()` doesn't change the position when it's inside the view, whereas
        * `scrollIntoView()` sets it on top of the view.
        *
        * @method forceIntoView
        * @param [notransition=false] {Boolean} set true if you are sure positioning is without transition.
        *        this isn't required, but it speeds up positioning. Only use when no transition is used:
        *        when there is a transition, setting this argument `true` would miscalculate the position.
        * @param [rectangle] {Object} Set this if you have already calculated the window-rectangle (used for preformance within drag-drop)
        * @param [rectangle.x] {Number} scrollLeft of window
        * @param [rectangle.y] {Number} scrollTop of window
        * @param [rectangle.w] {Number} width of window
        * @param [rectangle.h] {Number} height of window
        * @chainable
        * @since 0.0.2
        */
        ElementPrototype.forceIntoView = function(notransition, rectangle) {
            // TODO: 'notransition' can be calculated with this.getTransition(left) this.getTransition(left)
            // TODO: transitioned: http://wibblystuff.blogspot.nl/2014/04/in-page-smooth-scroll-using-css3.html
            console.log(NAME, 'forceIntoView');
            var instance = this,
                left = instance.left,
                width = instance.offsetWidth,
                right = left + width,
                height = instance.offsetHeight,
                top = instance.top,
                bottom = top + height,
                windowLeft, windowTop, windowRight, windowBottom, newX, newY;
            if (rectangle) {
                windowLeft = rectangle.x;
                windowTop = rectangle.y;
                windowRight = rectangle.w;
                windowBottom = rectangle.h;
            }
            else {
                windowLeft = window.getScrollLeft();
                windowTop = window.getScrollTop();
                windowRight = windowLeft + window.getWidth();
                windowBottom = windowTop + window.getHeight();
            }

            if (left<windowLeft) {
                newX = Math.max(0, left);
            }
            else if (right>windowRight) {
                newX = windowLeft + right - windowRight;
            }
            if (top<windowTop) {
                newY = Math.max(0, top);
            }
            else if (bottom>windowBottom) {
                newY = windowTop + bottom - windowBottom;
            }

            if ((newX!==undefined) || (newY!==undefined)) {
                window.scrollTo((newX!==undefined) ? newX : windowLeft, (newY!==undefined) ? newY : windowTop);
            }
            return instance;
        };

        /**
         * Gets an ElementArray of Elements that lie within this Element and match the css-selector.
         *
         * @method getAll
         * @param cssSelector {String} css-selector to match
         * @param [inspectProtectedNodes=false] {Boolean} no deepsearch in protected Nodes or iTags --> by default, these elements should be hidden
         * @return {ElementArray} ElementArray of Elements that match the css-selector
         * @since 0.0.1
         */
        ElementPrototype.getAll = function(cssSelector, inspectProtectedNodes) {
            return this.querySelectorAll(cssSelector, inspectProtectedNodes);
        };

       /**
        * Gets an attribute of the Element.
        *
        * Alias for getAttribute().
        *
        * @method getAttr
        * @param attributeName {String}
        * @return {String|null} value of the attribute
        * @since 0.0.1
        */
        ElementPrototype.getAttr = function(attributeName) {
            return this.vnode.attrs[attributeName] || null;
        };

        /**
         * Returns all attributes as defined as an key/value object.
         *
         * @method getAttrs
         * @param attributeName {String}
         * @return {Object} all attributes as on Object
         * @since 0.0.1
         */
        ElementPrototype.getAttrs = function() {
            return this.vnode.attrs;
        };

       /**
        * Gets an attribute of the Element.
        *
        * Same as getAttr().
        *
        * @method getAttribute
        * @param attributeName {String}
        * @return {String|null} value of the attribute
        * @since 0.0.1
        */
        ElementPrototype._getAttribute = ElementPrototype.getAttribute;
        ElementPrototype.getAttribute = function(attributeName) {
            return this.vnode.attrs[attributeName] || null;
        };

        /**
         * Returns a live collection of the Element-childNodes.
         *
         * @method getChildren
         * @return {ElementArray}
         * @since 0.0.1
         */
        ElementPrototype.getChildren = function() {
            var vChildren = this.vnode.vChildren,
                len = vChildren.length,
                children = ElementArray.createArray(),
                i;
            for (i=0; i<len; i++) {
                children[children.length] = vChildren[i].domNode;
            }
            return children;
        };

        /**
         * Returns a token list of the class attribute of the element.
         * See: https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList
         *
         * @method getClassList
         * @return DOMTokenList
         * @since 0.0.1
         */
        ElementPrototype.getClassList = function() {
            var instance = this,
                vnode = instance.vnode;
            if (!vnode._classList) {
                vnode._classList = Object.create(classListProto);
                vnode._classList._init(instance);
            }
            return vnode._classList;
        };

       /**
        * Returns data set specified by `key`. If not set, `undefined` will be returned.
        * The data is efficiently stored on the vnode.
        *
        * @method getData
        * @param key {string} name of the key
        * @return {Any|undefined} data set specified by `key`
        * @since 0.0.1
        */
        ElementPrototype.getData = function(key) {
            var vnode = this.vnode;
            return vnode._data && vnode._data[key];
        };

       /**
        * Gets one Element, specified by the css-selector. To retrieve a single element by id,
        * you need to prepend the id-name with a `#`. When multiple Element's match, the first is returned.
        *
        * @method getElement
        * @param cssSelector {String} css-selector to match
         * @param [inspectProtectedNodes=false] {Boolean} no deepsearch in protected Nodes or iTags --> by default, these elements should be hidden
        * @return {Element|null} the Element that was search for
        * @since 0.0.1
        */
        ElementPrototype.getElement = function(cssSelector, inspectProtectedNodes) {
            return this.querySelector(cssSelector, inspectProtectedNodes);
        };

        /**
         * Returns the Element matching the specified id, which should should be a descendant of this Element.
         *
         * @method getElementById
         * @param id {String} id of the Element
         * @param [inspectProtectedNodes=false] {Boolean} no deepsearch in protected Nodes or iTags --> by default, these elements should be hidden
         * @return {Element|null}
         *
         */
        ElementPrototype.getElementById = function(id, inspectProtectedNodes) {
            return this.getElement('#'+id, inspectProtectedNodes);
        };

        /**
         * Gets innerHTML of the dom-node.
         * Goes through the vdom, so it's superfast.
         *
         * Use this method instead of `innerHTML`
         *
         * @method getHTML
         * @param [exclude] {Array|HTMLElement} an array of HTMLElements - or just 1 - to be excluded
         * @param [includeSystemNodes=false] {Boolean} whether system-nodes and i-tag inner-content should be returned. By default, they stay hidden.
         * @return {String}
         * @since 0.0.1
         */
        ElementPrototype.getHTML = function(exclude, includeSystemNodes) {
            return this.vnode.getHTML(exclude, includeSystemNodes);
        };

       /**
        * Returns the Elments `id`
        *
        * @method getId
        * @return {String|undefined} Elements `id`
        * @since 0.0.1
        */
        ElementPrototype.getId = function() {
            return this.vnode.id;
        };

       /**
        * Returns inline style of the specified property. `Inline` means: what is set directly on the Element,
        * this doesn't mean necesairy how it is looked like: when no css is set inline, the Element might still have
        * an appearance because of other CSS-rules.
        *
        * In most cases, you would be interesting in using `getStyle()` instead.
        *
        * Note: no need to camelCase cssProperty: both `margin-left` as well as `marginLeft` are fine
        *
        * @method getInlineStyle
        * @param cssProperty {String} the css-property to look for
        * @param [pseudo] {String} to look inside a pseudo-style
        * @return {String|undefined} css-style
        * @since 0.0.1
        */
        ElementPrototype.getInlineStyle = function(cssProperty, pseudo) {
            var styles = this.vnode.styles,
                groupStyle = styles && styles[pseudo || 'element'],
                value;
            if (groupStyle) {
                value = groupStyle[fromCamelCase(cssProperty)];
                value && (cssProperty===VENDOR_TRANSITION_PROPERTY) && (value=extractor.serializeTransition(value));
            }
            return value;
        };

       /**
        * Returns inline transition-css-property. `Inline` means: what is set directly on the Element,
        * When `transition` is set inline, no `parent` transition-rules apply.
        *
        *
        * @method getInlineTransition
        * @param [transitionProperty] {String} the css-property to look for
        * @param [pseudo] {String} to look inside a pseudo-style
        * @return {Object} the transition-object, with the properties:
        * <ul>
        *     <li>duration {Number}</li>
        *     <li>timingFunction {String}</li>
        *     <li>delay {Number}</li>
        * </ul>
        * @since 0.0.1
        */
        ElementPrototype.getInlineTransition = function(transitionProperty, pseudo) {
            var styles = this.vnode.styles,
                groupStyle = styles && styles[pseudo || 'element'],
                transitionStyles = groupStyle && groupStyle[VENDOR_TRANSITION_PROPERTY];
            if (transitionStyles) {
                return transitionProperty ? transitionStyles[fromCamelCase(transitionProperty)] : transitionStyles;
            }
        };

        /**
         * Gets the outerHTML of the dom-node.
         * Goes through the vdom, so it's superfast.
         *
         * Use this method instead of `outerHTML`
         *
         * @method getOuterHTML
         * @param [exclude] {Array|HTMLElement} an array of HTMLElements - or just 1 - to be excluded
         * @param [includeSystemNodes=false] {Boolean} whether system-nodes and i-tag inner-content should be returned. By default, they stay hidden.
         * @return {String}
         * @since 0.0.1
         */
        ElementPrototype.getOuterHTML = function(exclude, includeSystemNodes) {
            return this.vnode.getOuterHTML(exclude, includeSystemNodes);
        };

        /**
         * Returns the Element's parent Element.
         *
         * @method getParent
         * @return {Element}
         */
        ElementPrototype.getParent = function() {
            var vParent = this.vnode.vParent;
            return vParent && vParent.domNode;
        };

       /**
        * Returns cascaded style of the specified property. `Cascaded` means: the actual present style,
        * the way it is visible (calculated through the DOM-tree).
        *
        * <ul>
        *     <li>Note1: values are absolute: percentages and points are converted to absolute values, sizes are in pixels, colors in rgb/rgba-format.</li>
        *     <li>Note2: you cannot query shotcut-properties: use `margin-left` instead of `margin`.</li>
        *     <li>Note3: no need to camelCase cssProperty: both `margin-left` as well as `marginLeft` are fine.</li>
        *     <li>Note4: you can query `transition`, `transform`, `perspective` and `transform-origin` instead of their vendor-specific properties.</li>
        *     <li>Note5: `transition` or `transform` return an Object instead of a String.</li>
        * </ul>
        *
        * @method getCascadeStyle
        * @param cssProperty {String} property that is queried
        * @param [pseudo] {String} to query pseudo-element, fe: `:before` or `:first-line`
        * @return {String|Object} value for the css-property: this is an Object for the properties `transition` or `transform`
        * @since 0.0.1
        */
        ElementPrototype.getStyle = function(cssProperty, pseudo) {
            // Cautious: when reading the property `transform`, getComputedStyle should
            // read the calculated value, but some browsers (webkit) only calculate the style on the current element
            // In those cases, we need a patch and look up the tree ourselves
            //  Also: we will return separate value, NOT matrices
            var instance = this;
            if (cssProperty===VENDOR_TRANSITION_PROPERTY) {
                return instance._getTransitionAll(pseudo);
            }
            VENDOR_CSS_PROPERTIES[cssProperty] || (cssProperty=generateVendorCSSProp(cssProperty));
            return window.getComputedStyle(instance, pseudo)[toCamelCase(cssProperty)];
        };

        /**
        * Returns cascaded "transition" style of the specified trandform-property. `Cascaded` means: the actual present style,
        * the way it is visible (calculated through the DOM-tree).
        *
        * Note1: When "transition" is set inline, ONLY inline transtition is active!
        * Thus, if parentNode has "transition: width 2s" and inline has "transition: height 3s", then the transition
        * will be "transition: height 3s" --> returning "undefined" for transitionProperty=width.
        * Note2: in case of "transition: all" --> these values will be returned for every "transitionProperty" (even when querying "width")
        *
        * @method getTransition
        * @param transitionProperty {String} transform property that is queried, f.e. "width", or "all"
        * @param [pseudo] {String} to query pseudo-element, fe: `:before` or `:first-line`
        * @return {Object} the transition-object, with the properties:
        * <ul>
        *     <li>duration {Number}</li>
        *     <li>timingFunction {String}</li>
        *     <li>delay {Number}</li>
        * </ul>
        * @since 0.0.1
        */
        ElementPrototype.getTransition = function(transitionProperty, pseudo) {
            var instance = this,
                transProperty, transDuration, transTimingFunction, transDelay, transPropertySplitted,
                transition, transDurationSplitted, transTimingFunctionSplitted, transDelaySplitted, index;
            if (instance.hasInlineStyle(VENDOR_TRANSITION_PROPERTY, pseudo)) {
                transition = instance.getInlineTransition(transitionProperty, pseudo);
                // if not found, then search for "all":
                transition || (transition=instance.getInlineTransition('all', pseudo));
                if (transition) {
                    // getTransition always returns all the properties:
                    transition.timingFunction || (transition.timingFunction='ease');
                    transition.delay || (transition.delay=0);
                }
                return transition;
            }
            transProperty = instance.getStyle(VENDOR_TRANSITION_PROPERTY+'Property', pseudo);
            transDuration = instance.getStyle(VENDOR_TRANSITION_PROPERTY+'Duration', pseudo);
            transTimingFunction = instance.getStyle(VENDOR_TRANSITION_PROPERTY+'TimingFunction', pseudo);
            transDelay = instance.getStyle(VENDOR_TRANSITION_PROPERTY+'Delay', pseudo);
            transPropertySplitted = transProperty && transProperty.split(',');
            if (transProperty) {
                if (transPropertySplitted.length>1) {
                    // multiple definitions
                    index = transPropertySplitted.indexOf(transitionProperty);
                    // the array is in a form like this: 'width, height, opacity' --> therefore, we might need to look at a whitespace
                    if (index===-1) {
                        index = transPropertySplitted.indexOf(' '+transitionProperty);
                        // if not found, then search for "all":
                        if (index===-1) {
                            index = transPropertySplitted.indexOf('all');
                            (index===-1) && (index=transPropertySplitted.indexOf(' '+'all'));
                        }
                    }
                    if (index!==-1) {
                        transDurationSplitted = transDuration.split(',');
                        transTimingFunctionSplitted = transTimingFunction.split(',');
                        transDelaySplitted = transDelay.split(',');
                        transition = {
                            duration: parseFloat(transDurationSplitted[index]),
                            timingFunction: transTimingFunctionSplitted[index].trimLeft(),
                            delay: parseFloat(transDelaySplitted)
                        };
                    }
                }
                else {
                    // one definition
                    if ((transProperty===transitionProperty) || (transProperty==='all')) {
                        transition = {
                            duration: parseFloat(transDuration),
                            timingFunction: transTimingFunction,
                            delay: parseFloat(transDelay)
                        };
                    }
                }
                transition && (transition.duration===0) && (transition=undefined);
                return transition;
            }
        };

       /**
        * Elements tag-name in uppercase (same as nodeName).
        *
        * @method getTagName
        * @return {String}
        * @since 0.0.1
        */
        ElementPrototype.getTagName = function() {
            return this.vnode.tag;
        };

        /**
         * Gets the innerContent of the Element as plain text.
         * Goes through the vdom, so it's superfast.
         *
         * Use this method instead of `textContent`
         *
         * @method getText
         * @return String
         * @since 0.0.1
         */
        ElementPrototype.getText = function() {
            return this.vnode.textContent;
        };

       /**
        * Gets the value of the following Elements:
        *
        * <ul>
        *     <li>input</li>
        *     <li>textarea</li>
        *     <li>select</li>
        *     <li>any container that is `contenteditable`</li>
        * </ul>
        *
        * @method getValue
        * @return {String}
        * @since 0.0.1
        */
        ElementPrototype.getValue = function() {
            // cautious: input and textarea must be accessed by their propertyname:
            // input.getAttribute('value') would return the default-value instead of actual
            // and textarea.getAttribute('value') doesn't exist
            var instance = this,
                contenteditable = instance.vnode.attrs.contenteditable,
                editable = contenteditable && (contenteditable!=='false');
            return editable ? instance.getHTML() : instance.value;
        };

       /**
        * Whether the Element has the attribute set.
        *
        * Alias for hasAttribute().
        *
        * @method hasAttr
        * @param attributeName {String}
        * @return {Boolean} Whether the Element has the attribute set.
        * @since 0.0.1
        */
        ElementPrototype.hasAttr = function(attributeName) {
            return !!this.vnode.attrs[attributeName];
        };

       /**
        * Whether the Element has the attribute set.
        *
        * Same as hasAttr().
        *
        * @method hasAttribute
        * @param attributeName {String}
        * @return {Boolean} Whether the Element has the attribute set.
        * @since 0.0.1
        */
        ElementPrototype.hasAttribute = function(attributeName) {
            return !!this.vnode.attrs[attributeName];
        };

        /**
         * Indicating if the current element has any attributes or not.
         *
         * @method hasAttributes
         * @return {Boolean} Whether the current element has any attributes or not.
         */
        ElementPrototype.hasAttributes = function() {
            var attrs = this.vnode.attrs;
            return attrs ? (attrs.size() > 0) : false;
        };

       /**
        * Indicating if the Element has any children (childNodes with nodeType of 1).
        *
        * @method hasChildren
        * @return {Boolean} whether the Element has children
        * @since 0.0.1
        */
        ElementPrototype.hasChildren = function() {
            return this.vnode.hasVChildren();
        };

       /**
        * Checks whether the className is present on the Element.
        *
        * @method hasClass
        * @param className {String|Array} the className to check for. May be an Array of classNames, which all needs to be present.
        * @return {Boolean} whether the className (or classNames) is present on the Element
        * @since 0.0.1
        */
        ElementPrototype.hasClass = function(className) {
            return this.getClassList().contains(className);
        };

       /**
        * If the Element has data set specified by `key`. The data could be set with `setData()`.
        *
        * @method hasData
        * @param key {string} name of the key
        * @return {Boolean}
        * @since 0.0.1
        */
        ElementPrototype.hasData = function(key) {
            var vnode = this.vnode;
            return !!(vnode._data && (vnode._data[key]!==undefined));
        };

       /**
        * Indicates whether Element currently has the focus.
        *
        * @method hasFocus
        * @param [inside] whether focus may also lie on a descendent inside
        * @return {Boolean}
        * @since 0.0.1
        */
        ElementPrototype.hasFocus = function(inside) {
            return (DOCUMENT.activeElement===this) || (inside ? this.contains(DOCUMENT.activeElement, true, true) : false);
        };

       /**
        * Indicates whether the current focussed Element lies inside this Element (on a descendant Element).
        *
        * @method hasFocusInside
        * @return {Boolean}
        * @since 0.0.1
        */
        ElementPrototype.hasFocusInside = function() {
            return this.contains(DOCUMENT.activeElement, true, true);
        };

       /**
        * Returns whether the inline style of the specified property is present. `Inline` means: what is set directly on the Element.
        *
        * Note: no need to camelCase cssProperty: both `margin-left` as well as `marginLeft` are fine
        *
        * @method hasInlineStyle
        * @param cssProperty {String} the css-property to look for
        * @param [pseudo] {String} to look inside a pseudo-style
        * @return {Boolean} whether the inlinestyle was present
        * @since 0.0.1
        */
        ElementPrototype.hasInlineStyle = function(cssProperty, pseudo) {
            return !!this.getInlineStyle(cssProperty, pseudo);
        };

       /**
        * Returns whether the specified inline transform-css-property is present. `Inline` means: what is set directly on the Element.
        *
        * See more about tranform-properties: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
        *
        * @method hasInlineTransition
        * @param transitionProperty {String} the css-property to look for
        * @param [pseudo] {String} to look inside a pseudo-style
        * @return {Boolean} whether the inline transform-css-property was present
        * @since 0.0.1
        */
        ElementPrototype.hasInlineTransition = function(transitionProperty, pseudo) {
            return !!this.getInlineTransition(transitionProperty, pseudo);
        };

        /**
        * Returns whether the specified transform-property is active.
        *
        * Note1: When "transition" is set inline, ONLY inline transtition is active!
        * Thus, if parentNode has "transition: width 2s" and inline has "transition: height 3s",
        * then hasTransition('width') will return false.
        * Note2: in case of "transition: all" --> hasTransition() will always `true` for every transitionProperty.
        *
        * @method hasTransition
        * @param transitionProperty {String} the css-property to look for
        * @param [pseudo] {String} to look inside a pseudo-style
        * @return {Boolean} whether the inlinestyle was present
        * @since 0.0.1
        */
        ElementPrototype.hasTransition = function(transitionProperty, pseudo) {
            return !!this.getTransition(transitionProperty, pseudo);
        };

       /**
        * Hides a node by making it floated and removing it out of the visible screen.
        * Hides immediately without `fade`, or will fade when fade is specified.
        *
        * @method hide
        * @param [fade] {Number} sec to fade (you may use `0.1`)
        * @return {this|Promise} fulfilled when the element is ready hiding, or rejected when showed up again (using node.show) before fully hided.
        * @since 0.0.1
        */
        ElementPrototype.hide = function(duration) {
            // when it doesn't have, it doesn;t harm to leave the transitionclass on: it would work anyway
            // nevertheless we will remove it with a timeout
            var instance = this,
                showPromise = instance.getData('_showNodeBusy'),
                hidePromise = instance.getData('_hideNodeBusy'),
                originalOpacity, hasOriginalOpacity, promise, freezedOpacity, fromOpacity;

            instance.setData('nodeShowed', false); // for any routine who wants to know
            originalOpacity = instance.getData('_showNodeOpacity');
            if (!originalOpacity && !showPromise && !hidePromise) {
                originalOpacity = parseFloat(instance.getInlineStyle('opacity'));
                instance.setData('_showNodeOpacity', originalOpacity);
            }
            hasOriginalOpacity = !!originalOpacity;

            showPromise && showPromise.freeze();
            if (showPromise) {
                showPromise.freeze();
                instance.removeData('_showNodeBusy');
            }
            hidePromise && hidePromise.freeze();

            if (duration) {
                if (showPromise || hidePromise) {
                    freezedOpacity = instance.getInlineStyle('opacity');
                    fromOpacity = originalOpacity || 1;
                    duration = (fromOpacity>0) ? Math.min(1, (freezedOpacity/fromOpacity))*duration : 0;
                }
                promise = instance.transition({property: 'opacity', value: 0, duration: duration});
                instance.setData('_hideNodeBusy', promise);
                promise.finally(
                    function() {
                        if (!promise.cancelled && !promise.frozen) {
                            instance.setClass(HIDDEN);
                            originalOpacity ? instance.setInlineStyle('opacity', originalOpacity) : instance.removeInlineStyle('opacity');
                        }
                        instance.removeData('_hideNodeBusy');
                    }
                );
                return promise;
            }
            else {
                async(function() {
                    instance.setClass(HIDDEN);
                    hasOriginalOpacity ? instance.setInlineStyle('opacity', originalOpacity) : instance.removeInlineStyle('opacity');
                });
                return instance;
            }
        };

       /**
        * Indicates whether the Element currently is part if the DOM.
        *
        * @method inDOM
        * @return {Boolean} whether the Element currently is part if the DOM.
        * @since 0.0.1
        */
        ElementPrototype.inDOM = function() {
            if (this.vnode.removedFromDOM) {
                return false;
            }
            return DOCUMENT.contains(this, false, true);
        };

       /**
         * Checks whether the Element lies within the specified selector (which can be a CSS-selector or a Element)
         *
         * @example
         * var divnode = childnode.inside('div.red');
         *
         * @example
         * var divnode = childnode.inside(containerNode);
         *
         * @method inside
         * @param selector {Element|String} the selector, specified by a Element or a css-selector
         * @return {Element|false} the nearest Element that matches the selector, or `false` when not found
         * @since 0.0.1
         */
        ElementPrototype.inside = function(selector) {
            var instance = this,
                vParent;
            if (typeof selector===STRING) {
                vParent = instance.vnode.vParent;
                while (vParent && !vParent.matchesSelector(selector)) {
                    vParent = vParent.vParent;
                }
                return vParent ? vParent.domNode : false;
            }
            else {
                // selector should be an Element
                return ((selector!==instance) && selector.contains(instance, false, true)) ? selector : false;
            }
        };

       /**
         * Checks whether a point specified with x,y is within the Element's region.
         *
         * @method insidePos
         * @param x {Number} x-value for new position (coordinates are page-based)
         * @param y {Number} y-value for new position (coordinates are page-based)
         * @return {Boolean} whether there is a match
         * @since 0.0.1
         */
        ElementPrototype.insidePos = function(x, y) {
            var instance = this,
                left = instance.left,
                top = instance.top,
                right = left + instance.offsetWidth,
                bottom = top + instance.offsetHeight;
            return (x>=left) && (x<=right) && (y>=top) && (y<=bottom);
        };

        /**
         * Inserts `domNode` before `refDomNode`.
         *
         * @method insertBefore
         * @param domNode {Node|Element|ElementArray|String} content to insert
         * @param refDomNode {Element} The Element before which newElement is inserted.
         * @param [escape] {Boolean} whether to insert `escaped` content, leading it into only text inserted
         * @return {Node} the Element being inserted (equals domNode)
         */
        ElementPrototype._insertBefore = ElementPrototype.insertBefore;
        ElementPrototype.insertBefore = function(domNode, refDomNode, escape) {
            return this.prepend(domNode, escape, refDomNode);
        };

        /**
         * Whether the element is an Itag-element
         *
         * @method isItag
         * @return {Boolean}
         * @since 0.0.1
         */
        ElementPrototype.isEmpty = function(inspectSystemNodes) {
            var vnode = this.vnode,
                vChildNodes = vnode.vChildNodes,
                i, len;
            if (!inspectSystemNodes) {
                if (vnode.isItag && vnode.domNode.contentHidden) {
                    return true;
                }
                // else:
                len = vChildNodes.length;
                for (i=0; i<len; i++) {
                    if (!vChildNodes[i]._systemNode) {
                        return false;
                    }
                }
                return true;
            }
            // else:
            return (vChildNodes.length===0);
        };

        /**
         * Whether the element is an Itag-element
         *
         * @method isItag
         * @return {Boolean}
         * @since 0.0.1
         */
        ElementPrototype.isItag = function() {
            return this.vnode.isItag;
        };

        /**
         * Reference to the last of sibbling vNode's, where the related dom-node is an Element(nodeType===1).
         *
         * @method last
         * @param [cssSelector] {String} to return the last Element that matches the css-selector
         * @param [container] {HTMLElement} the container-element to search within --> this lead into searching out of the same level
         * @return {Element}
         * @since 0.0.1
         */
        ElementPrototype.last = function(cssSelector, container) {
            var vParent, lastV, found;
            if (container) {
                found = container.querySelectorAll(cssSelector);
                return found[found.length-1];
            }
            vParent = this.vnode.vParent;
            lastV = vParent && vParent.lastOfVChildren(cssSelector);
            return lastV && lastV.domNode;
        };

        /**
         * Reference to the last child-Element, where the related dom-node an Element (nodeType===1).
         *
         * @method lastOfChildren
         * @param [cssSelector] {String} to return the last Element that matches the css-selector
         * @return {Element}
         * @since 0.0.1
         */
        ElementPrototype.lastOfChildren = function(cssSelector) {
            var foundVNode = this.vnode.lastOfVChildren(cssSelector);
            return foundVNode && foundVNode.domNode;
        };

        /**
         * Indicates if the element would be selected by the specified selector string.
         * Alias for matchesSelector()
         *
         * @method matches
         * @param [cssSelector] {String} the css-selector to check for
         * @return {Boolean}
         * @since 0.0.1
         */
        ElementPrototype.matches = function(selectors) {
            return this.vnode.matchesSelector(selectors);
        };

        /**
         * Indicates if the element would be selected by the specified selector string.
         * Alias for matches()
         *
         * @method matchesSelector
         * @param [cssSelector] {String} the css-selector to check for
         * @return {Boolean}
         * @since 0.0.1
         */
        ElementPrototype.matchesSelector = function(selectors) {
            return this.vnode.matchesSelector(selectors);
        };

        /**
         * Reference to the next of sibbling Element, where the related dom-node is an Element(nodeType===1).
         *
         * @method next
         * @param [cssSelector] {String} css-selector to be used as a filter
         * @param [container] {HTMLElement} the container-element to search within --> this lead into searching out of the same level
         * @return {Element|null}
         * @type Element
         * @since 0.0.1
         */
        ElementPrototype.next = function(cssSelector, container) {
            var vnode = this.vnode,
                found, vNextElement, firstCharacter, i, len;
            if (container) {
                return container.querySelector(cssSelector, false, this, 2) || null;
            }
            if (!cssSelector) {
                vNextElement = vnode.vNextElement;
                return vNextElement && vNextElement.domNode;
            }
            else {
                i = -1;
                len = cssSelector.length;
                while (!firstCharacter && (++i<len)) {
                    firstCharacter = cssSelector[i];
                    (firstCharacter===' ') && (firstCharacter=null);
                }
                if (firstCharacter==='>') {
                    return null;
                }
            }
            vNextElement = vnode;
            do {
                vNextElement = vNextElement.vNextElement;
                found = vNextElement && vNextElement.matchesSelector(cssSelector);
            } while(vNextElement && !found);
            return found ? vNextElement.domNode : null;
        };

       /**
        * Prepends a Element or text at the start of Element's innerHTML, or before the `refElement`.
        *
        * @method prepend
        * @param content {Element|Element|ElementArray|String} content to prepend
        * @param [escape] {Boolean} whether to insert `escaped` content, leading it into only text inserted
        * @param [refElement] {Element} reference Element where the content should be prepended
        * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
        * @param [allowScripts=false] {Boolean} whether scripts are allowed --> these should be defined with `xscript` instead of `script`
        * @return {Element} the created Element (or the last when multiple)
        * @since 0.0.1
        */
        ElementPrototype.prepend = function(content, escape, refElement, silent, allowScripts) {
            var instance = this,
                vnode = instance.vnode,
                prevSuppress = DOCUMENT._suppressMutationEvents || false,
                i, len, item, createdElement, vnodes, vChildNodes, _scripts, scriptcontent, hasDisplayNode,
            doPrepend = function(oneItem) {
                escape && (oneItem.nodeType===1) && (oneItem=DOCUMENT.createTextNode(oneItem.getOuterHTML()));
                createdElement = refElement ? vnode._insertBefore(oneItem.vnode, refElement.vnode) : vnode._appendChild(oneItem.vnode);
                // CAUTIOUS: when using TextNodes, they might get merged (vnode._normalize does this), which leads into disappearance of refElement:
                refElement = createdElement;
            };
            // for optimum performance, we "disply: block" the parent node, so that repainting the dom only happens once (when displayed again)
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(true);
            vnode._noSync()._normalizable(false);
            if (!refElement) {
                vChildNodes = vnode.vChildNodes;
                if (vChildNodes) {
                    len = vChildNodes.length;
                    for (i=0; (i<len) && !refElement; i++) {
                        vChildNodes[i]._systemNode || (refElement=vChildNodes[i].domNode);
                    }
                }
            }
            (typeof content===STRING) && (content=htmlToVFragments(content, vnode.ns, allowScripts));
            if (content.isFragment) {
                hasDisplayNode = instance.hasClass(ITSA_NODISPLAY);
                hasDisplayNode || instance.setClass(ITSA_NODISPLAY);
                vnodes = content.vnodes;
                len = vnodes.length;
                // to manage TextNodes which might get merged, we loop downwards:
                for (i=len-1; i>=0; i--) {
                    doPrepend(vnodes[i].domNode);
                }
/*jshint boss:true */
                if (_scripts=content._scripts) {
/*jshint boss:false */
                    len = _scripts.length;
                    vnode._scripts || (vnode._scripts=[]);
                    for (i=0; i<len; i++) {
                        scriptcontent = _scripts[i];
                        if (!vnode._scripts.contains(scriptcontent)) {
                            vnode._scripts[vnode._scripts.length] = scriptcontent;
                        }
                    }
                }
                // in case a style-tag was added, we need to cleanup double definitions:
                content._cleanupStyle && vnode._cleanupStyle();
                vnode._normalizable(true)._normalize();
                hasDisplayNode || instance.removeClass(ITSA_NODISPLAY);
            }
            else if (Array.isArray(content)) {
                hasDisplayNode = instance.hasClass(ITSA_NODISPLAY);
                hasDisplayNode || instance.setClass(ITSA_NODISPLAY);
                len = content.length;
                // to manage TextNodes which might get merged, we loop downwards:
                for (i=len-1; i>=0; i--) {
                    item = content[i];
                    doPrepend(item);
                }
                vnode._normalizable(true)._normalize();
                hasDisplayNode || instance.removeClass(ITSA_NODISPLAY);
            }
            else {
                doPrepend(content);
                vnode._normalizable(true)._normalize();
            }
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(prevSuppress);
            return createdElement;
        };

        /**
         * Reference to the previous of sibbling Element, where the related dom-node is an Element(nodeType===1).
         *
         * @method previous
         * @param [cssSelector] {String} css-selector to be used as a filter
         * @param [container] {HTMLElement} the container-element to search within --> this lead into searching out of the same level
         * @return {Element|null}
         * @type Element
         * @since 0.0.1
         */
        ElementPrototype.previous = function(cssSelector, container) {
            var vnode = this.vnode,
                found, vPreviousElement, firstCharacter, i, len;
            if (container) {
                found = container.querySelectorAll(cssSelector, false, this, 4);
                return (found.length>0) ? found[found.length-1] :  null;
            }
            if (!cssSelector) {
                vPreviousElement = vnode.vPreviousElement;
                return vPreviousElement && vPreviousElement.domNode;
            }
            else {
                i = -1;
                len = cssSelector.length;
                while (!firstCharacter && (++i<len)) {
                    firstCharacter = cssSelector[i];
                    (firstCharacter===' ') && (firstCharacter=null);
                }
                if (firstCharacter==='>') {
                    return null;
                }
            }
            vPreviousElement = vnode;
            do {
                vPreviousElement = vPreviousElement.vPreviousElement;
                found = vPreviousElement && vPreviousElement.matchesSelector(cssSelector);
            } while(vPreviousElement && !found);
            return found ? vPreviousElement.domNode : null;
        };

        /**
         * Returns the first Element within the Element, that matches the CSS-selectors. You can pass one, or multiple CSS-selectors. When passed multiple,
         * they need to be separated by a `comma`.
         *
         * @method querySelector
         * @param selectors {String} CSS-selector(s) that should match
         * @param [inspectProtectedNodes=false] {Boolean} no deepsearch in protected Nodes or iTags --> by default, these elements should be hidden
         * @param [refNode] {HTMLElement} reference-node where the found node should be `before` or `after`: specified by domPosition
         * @param [domPosition] {Number} The position to accept, compared to `refNode`. Should be either:
         * <ul>
         *     <li>Node.DOCUMENT_POSITION_PRECEDING === 2 (this Element comes before otherElement)</li>
         *     <li>Node.DOCUMENT_POSITION_FOLLOWING === 4 (this Element comes after otherElement)</li>
         * </ul>
         * @return {Element}
         */
        ElementPrototype.querySelector = function(selectors, inspectProtectedNodes, refNode, domPosition) {
            var found,
                i = -1,
                thisvnode = this.vnode,
                len, firstCharacter, startvnode, inspectChildren;
            selectors || (selectors='*');
            len = selectors.length;
            inspectChildren = function(vnode) {
                var vChildren = vnode.vChildren,
                    len2 = vChildren ? vChildren.length : 0,
                    j, vChildNode, noDeep;
                for (j=0; (j<len2) && !found; j++) {
                    vChildNode = vChildren[j];
                    if (vChildNode.matchesSelector(selectors, thisvnode) && (!refNode || ((vChildNode.domNode.compareDocumentPosition(refNode) & domPosition)!==0))) {
                        if (!vChildNode._systemNode || inspectProtectedNodes) {
                            found = vChildNode.domNode;
                        }
                    }
                    if (!found) {
                        if (!inspectProtectedNodes) {
                            if (vChildNode._systemNode || (vChildNode.isItag && vChildNode.domNode.contentHidden)) {
                                noDeep = true;
                            }
                            else {
                                noDeep = false;
                            }
                        }
                        else {
                            noDeep = false;
                        }
                        noDeep || inspectChildren(vChildNode);
                    }
                }
            };
            while (!firstCharacter && (++i<len)) {
                firstCharacter = selectors[i];
                (firstCharacter===' ') && (firstCharacter=null);
            }
            startvnode = SIBLING_MATCH_CHARACTER[firstCharacter] ? thisvnode.vParent : thisvnode;
            startvnode && inspectChildren(startvnode);
            return found;
        };

        /**
         * Returns an ElementArray of all Elements within the Element, that match the CSS-selectors. You can pass one, or multiple CSS-selectors. When passed multiple,
         * they need to be separated by a `comma`.
         *
         * querySelectorAll is a snapshot of the dom at the time this method was called. It is not updated when changes of the dom are made afterwards.
         *
         * @method querySelectorAll
         * @param selectors {String} CSS-selector(s) that should match
         * @param [inspectProtectedNodes=false] {Boolean} no deepsearch in protected Nodes or iTags --> by default, these elements should be hidden
         * @param [refNode] {HTMLElement} reference-node where the found nodes should be `before` or `after`: specified by domPosition
         * @param [domPosition] {Number} The position to accept, compared to `refNode`. Should be either:
         * <ul>
         *     <li>Node.DOCUMENT_POSITION_PRECEDING === 2 (this Element comes before otherElement)</li>
         *     <li>Node.DOCUMENT_POSITION_FOLLOWING === 4 (this Element comes after otherElement)</li>
         * </ul>
         * @return {ElementArray} non-life Array (snapshot) with Elements
         */
        ElementPrototype.querySelectorAll = function(selectors, inspectProtectedNodes, refNode, domPosition) {
            var found = ElementArray.createArray(),
                i = -1,
                thisvnode = this.vnode,
                len, firstCharacter, startvnode, inspectChildren;
            selectors || (selectors='*');
            len = selectors.length,
            inspectChildren = function(vnode) {
                var vChildren = vnode.vChildren,
                    len2 = vChildren ? vChildren.length : 0,
                    j, vChildNode, noDeep;
                for (j=0; j<len2; j++) {
                    vChildNode = vChildren[j];
                    if (vChildNode.matchesSelector(selectors, thisvnode) && (!refNode || ((vChildNode.domNode.compareDocumentPosition(refNode) & domPosition)!==0))) {
                        if (!vChildNode._systemNode || inspectProtectedNodes) {
                            found[found.length] = vChildNode.domNode;
                        }
                    }
                    if (!inspectProtectedNodes) {
                        if (vChildNode._systemNode || (vChildNode.isItag && vChildNode.domNode.contentHidden)) {
                            noDeep = true;
                        }
                        else {
                            noDeep = false;
                        }
                    }
                    else {
                        noDeep = false;
                    }
                    noDeep || inspectChildren(vChildNode);
                }
            };
            while (!firstCharacter && (++i<len)) {
                firstCharacter = selectors[i];
                (firstCharacter===' ') && (firstCharacter=null);
            }
            startvnode = SIBLING_MATCH_CHARACTER[firstCharacter] ? thisvnode.vParent : thisvnode;
            startvnode && inspectChildren(startvnode);
            return found;
        };

       /**
         * Checks whether the Element has its rectangle inside the outbound-Element.
         * This is no check of the DOM-tree, but purely based upon coordinates.
         *
         * @method rectangleInside
         * @param outboundElement {Element} the Element where this element should lie inside
         * @return {Boolean} whether the Element lies inside the outboundElement
         * @since 0.0.1
         */
        ElementPrototype.rectangleInside = function(outboundElement) {
            var instance = this,
                outerRect = outboundElement.getBoundingClientRect(),
                innerRect = instance.getBoundingClientRect();
            return (outerRect.left<=innerRect.left) &&
                   (outerRect.top<=innerRect.top) &&
                   ((outerRect.left+outboundElement.offsetWidth)>=(innerRect.left+instance.offsetWidth)) &&
                   ((outerRect.top+outboundElement.offsetHeight)>=(innerRect.top+instance.offsetHeight));
        };

       /**
        * Removes the Element from the DOM.
        * Alias for thisNode.parentNode.removeChild(thisNode);
        *
        * @method remove
        * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
        * @return {Node} the DOM-node that was removed. You could re-insert it at a later time.
        * @since 0.0.1
        */
        ElementPrototype.remove = function(silent) {
            var instance = this,
                vnode = instance.vnode,
                prevSuppress = DOCUMENT._suppressMutationEvents || false,
                vParent = vnode.vParent;
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(true);
            vParent && vParent._removeChild(vnode);
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(prevSuppress);
            return instance;
        };

       /**
        * Removes the attribute from the Element.
        *
        * Alias for removeAttribute() BUT is chainable instead (removeAttribute is not).
        *
        * @method removeAttr
        * @param attributeName {String}
        * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
        * @chainable
        * @since 0.0.1
        */
        ElementPrototype.removeAttr = function(attributeName, silent) {
            this.removeAttribute(attributeName, silent);
            return this;
        };

       /**
         * Removes multiple attributes on the Element.
         * The argument should be one ore more AttributeNames.
         *
         * @example
         * instance.removeAttrs(['tabIndex', 'style']);
         *
         * @method removeAttrs
         * @param attributeData {Array|String}
         * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
         * @chainable
         * @since 0.0.1
        */
        ElementPrototype.removeAttrs = function(attributeData, silent) {
            var instance = this;
            Array.isArray(attributeData) || (attributeData=[attributeData]);
            attributeData.forEach(function(item) {
                instance.removeAttribute(item, silent);
            });
            return instance;
        };

       /**
        * Removes the attribute from the Element.
        *
        * Use removeAttr() to be able to chain.
        *
        * @method removeAttr
        * @param attributeName {String}
        * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
        * @since 0.0.1
        */
        ElementPrototype._removeAttribute = ElementPrototype.removeAttribute;
        ElementPrototype.removeAttribute = function(attributeName, silent) {
            var prevSuppress = DOCUMENT._suppressMutationEvents || false;
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(true);
            this.vnode._removeAttr(attributeName);
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(prevSuppress);
        };

       /**
         * Removes the attribute of the Elementinside a specified namespace
         *
         * @method removeAttributeNS
         * @param nameSpace {String} the namespace where to attribuyte should be set in
         * @param attributeName {String}
         * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
        */
        ElementPrototype._removeAttributeNS = ElementPrototype.removeAttributeNS;
        ElementPrototype.removeAttributeNS = function(nameSpace, attributeName, silent) {
            this.removeAttribute((nameSpace ? nameSpace+':' : '')+attributeName, silent);
        };

        /**
        * Removes the Element's child-Node from the DOM.
        *
        * @method removeChild
        * @param domNode {Node} the child-Node to remove
        * @return {Node} the DOM-node that was removed. You could re-insert it at a later time.
        */
        ElementPrototype._removeChild = ElementPrototype.removeChild;
        ElementPrototype.removeChild = function(domNode) {
            var instance = this;
            instance.vnode._removeChild(domNode.vnode);
            return instance;
        };

       /**
        * Removes a className from the Element.
        *
        * @method removeClass
        * @param className {String|Array} the className that should be removed. May be an Array of classNames.
        * @param [returnPromise] {Boolean} whether to return a Promise instead of `this`, which might be useful in case of
        *        transition-properties. The promise will fullfil when the transition is ready, or immediately when no transitioned.
        * @param [transitionFix] set this to `true` if you experience transition-problems due to wrong calculated css (mostly because of the `auto` value)
        *        Setting this parameter, will calculate the true css of the transitioned properties and set this temporarely inline, to fix the issue.
        *        Don't use it when not needed, it has a slightly performancehit.
        *        No need to set when `returnPromise` is set --> returnPromise always handles the transitionFix.
        * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
        * @return {Promise|this} In case `returnPromise` is set, a Promise returns with the next handles:
        *        <ul>
        *            <li>cancel() {Promise}</li>
        *            <li>freeze() {Promise}</li>
        *            <li>unfreeze()</li>
        *            <li>finish() {Promise}</li>
        *        </ul>
        *        These handles resolve with the `elapsed-time` as first argument of the callbackFn
        * @since 0.0.1
        */
        ElementPrototype.removeClass = function(className, returnPromise, transitionFix, silent) {
            var instance = this,
                prevSuppress = DOCUMENT._suppressMutationEvents || false,
                transPromise, returnValue;
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(true);
            transPromise = (returnPromise || transitionFix) && getClassTransPromise(instance, REMOVE, className);
            returnValue = returnPromise ? transPromise : instance;
            transPromise || instance.getClassList().remove(className);
            if (silent && DOCUMENT.suppressMutationEvents) {
                if (returnValue===instance) {
                    DOCUMENT.suppressMutationEvents(prevSuppress);
                }
                else {
                    returnValue.finally(function() {
                        DOCUMENT.suppressMutationEvents(prevSuppress);
                    });
                }
            }
            return returnValue;
        };

       /**
        * Removes data specified by `key` that was set by using `setData()`.
        * When no arguments are passed, all node-data (key-value pairs) will be removed.
        *
        * @method removeData
        * @param [key] {string} name of the key, when not set, all data is removed
        * @param [deep] {Boolean} whether to set the data to all descendants recursively
        * @chainable
        * @since 0.0.1
        */
        ElementPrototype.removeData = function(key, deep) {
            var instance = this,
                vnode = instance.vnode;
            if (vnode._data) {
                if (key) {
                    delete vnode._data[key];
                }
                else {
                    // we cannot just redefine _data, for it is set as readonly
                    vnode._cleanData();
                    if (deep) {
                        instance.getChildren().forEach(function(element) {
                            element.removeData(key, true);
                        });
                    }
                }
            }
            return instance;
        };

       /**
        * Removes the Elment's `id`.
        *
        * @method removeId
        * @chainable
        * @since 0.0.1
        */
        ElementPrototype.removeId = function() {
            return this.removeAttr('id');
        };

       /**
        * Removes a css-property (inline) out of the Element.
        * No need to use camelCase.
        *
        * @method removeInlineStyle
        * @param cssProperty {String} the css-property to remove
        * @param [pseudo] {String} to look inside a pseudo-style
        * @param [returnPromise] {Boolean} whether to return a Promise instead of `this`, which might be useful in case of
        *        transition-properties. The promise will fullfil when the transition is ready, or immediately when no transitioned.
        * @chainable
        * @since 0.0.1
        */
        ElementPrototype.removeInlineStyle = function(cssProperty, pseudo, returnPromise) {
            return this.removeInlineStyles({property: cssProperty, pseudo: pseudo}, returnPromise);
        };

       /**
        * Removes multiple css-properties (inline) out of the Element. You need to supply an Array of Objects, with the properties:
        *        <ul>
        *            <li>property  {String}</li>
        *            <li>pseudo  {String}</li>
        *        <ul>
        * No need to use camelCase.
        *
        * @method removeInlineStyles
        * @param cssProperties {Array|Object} Array of objects, Strings (or 1 Object/String).
        *       When String, then speduo is considered as undefined. When `Objects`, they need the properties:
        *        <ul>
        *            <li>property  {String}</li>
        *            <li>pseudo  {String}</li>
        *        <ul>
        * @param [returnPromise] {Boolean} whether to return a Promise instead of `this`, which might be useful in case of
        *        transition-properties. The promise will fullfil when the transition is ready, or immediately when no transitioned.
        * @chainable
        * @since 0.0.1
        */
        ElementPrototype.removeInlineStyles = function(cssProperties, returnPromise) {
            // There will be 3 sets of styles:
            // `fromStyles` --> the current styles, only exactly calculated -without `auto`- (that is, for the transitioned properties)
            // `toStylesExact` --> the new styles, exactly calculated -without `auto`- (that is, for the transitioned properties)
            // `vnodeStyles` --> the new styles as how they should be in the end (f.i. with `auto`)
            var instance = this,
                vnode = instance.vnode,
                removed = [],
                transCount = 0,
                transitionProperties = {},
                maxtranstime = 0,
                needSync, prop, styles, i, len, item, hasTransitionedStyle, promise, vnodeStyles,
                pseudo, group, clonedElement, fromStyles, toStylesExact, value, transproperty, transtime;

            Array.isArray(cssProperties) || (cssProperties=[cssProperties]);
            cssProperties = getVendorCSS(cssProperties);
            len = cssProperties.length;
            vnodeStyles = vnode.styles;
            if (!vnodeStyles) {
                return;
            }
            for (i=0; i<len; i++) {
                item = cssProperties[i];
                if (typeof item==='string') {
                    item = cssProperties[i] = {
                        property: item
                    };
                }
                pseudo = item.pseudo;
                group = pseudo || 'element';
                styles = vnodeStyles[group];
                if (styles) {
                    prop = item.property;
                    // if property is vendor-specific transition, or transform, than we reset it to the current vendor
                    if (styles[prop]) {
                        fromStyles || (fromStyles=vnodeStyles.deepClone());
                        needSync = true;
                        if ((prop!==VENDOR_TRANSITION_PROPERTY) && instance.hasTransition(prop, pseudo)) {
                            // store the calculated value:
                            fromStyles[group] || (fromStyles[group]={});
                            (prop===VENDOR_TRANSFORM_PROPERTY) || (fromStyles[group][prop]=instance.getStyle(prop, group));
                            hasTransitionedStyle = true;
                            removed[removed.length] = {
                                group: group,
                                property: prop,
                                pseudo: pseudo
                            };
                        }
                        delete styles[prop];
                        (styles.size()===0) && (delete vnode.styles[pseudo || 'element']);
                    }
                }
            }

            RUNNING_ON_NODE && (hasTransitionedStyle=false);
            if (hasTransitionedStyle) {
                // fix the current style with what is actual calculated:
                vnode.styles = fromStyles; // exactly styles, so we can transition well
                instance.setClass(NO_TRANS);
                instance.setAttr(STYLE, vnode.serializeStyles());
                async(function() {
                    // needs to be done in the next eventcyle, otherwise webkit-browsers miscalculate the syle (with transition on)
                    instance.removeClass(NO_TRANS);
                });

                // now calculate the final value
                clonedElement = instance.cloneNode(true);
                toStylesExact = vnodeStyles.deepClone();
                clonedElement.vnode.styles = toStylesExact;
                clonedElement.setClass(INVISIBLE_UNFOCUSABLE);
                clonedElement.setAttr(STYLE, clonedElement.vnode.serializeStyles());
                DOCUMENT.body.append(clonedElement);
                // clonedElement has `vnodeStyles`, but we change them into `toStylesExact`

                len = removed.length;
                for (i=0; i<len; i++) {
                    item = removed[i];
                    prop = item.property;
                    group = item.pseudo || 'element';
                    if (!NON_CLONABLE_STYLES[prop]) {
                        value = (prop===VENDOR_TRANSFORM_PROPERTY) ? clonedElement.getInlineStyle(prop, item.pseudo) : clonedElement.getStyle(prop, item.pseudo);
                        if (value) {
                            toStylesExact[group] || (toStylesExact[group]={});
                            toStylesExact[group][prop] = value;
                        }
                    }
                    // look if we really have a change in the value:

                    if (toStylesExact[group] && (toStylesExact[group][prop]!==fromStyles[group][prop])) {
                        transproperty = instance.getTransition(prop, (group==='element') ? null : group);
                        if (transproperty) {
                        transtime = transproperty.delay+transproperty.duration;
                            maxtranstime = Math.max(maxtranstime, transtime);
                            if (transtime>0) {
                                transCount++;
                                // TODO: transitionProperties supposes that we DO NOT have pseudo transitions!
                                // as soon we do, we need to split this object for each 'group'
                                transitionProperties[prop] = true;
                            }
                        }
                    }
                }
                hasTransitionedStyle = (transCount>0);
                clonedElement.remove();
            }
            if (needSync) {
                if (returnPromise || hasTransitionedStyle) {
                    promise = window.Promise.manage();
                    // need to call `setAttr` in a next event-cycle, otherwise the eventlistener made
                    // by `getTransPromise gets blocked.
                    async(function() {
                        if (hasTransitionedStyle) {
                            // reset
                            vnode.styles = toStylesExact;
                            promise.then(function() {
                                vnode.styles = vnodeStyles; // finally values, not exactly calculated, but as is passed through
                                instance.setClass(NO_TRANS);
                                instance.setAttr(STYLE, vnode.serializeStyles());
                            }).finally(function() {
                                async(function() {
                                    instance.removeClass(NO_TRANS);
                                    // webkit browsers seems to need to recalculate their set width:
                                    instance.getBoundingClientRect();
                                });
                            });
                        }
                        else {
                            vnode.styles = vnodeStyles; // finally values, not exactly calculated, but as is passed through
                        }
                        getTransPromise(instance, hasTransitionedStyle, null, transCount, transitionProperties, maxtranstime).then(
                            promise.fulfill
                        ).catch(promise.reject);
                        instance.setAttr(STYLE, vnode.serializeStyles());
                    });
                }
                else {
                    vnode.styles = vnodeStyles; // finally values, not exactly calculated, but as is passed through
                    instance.setAttr(STYLE, vnode.serializeStyles());
                    // webkit browsers seems to need to recalculate their set width:
                    instance.getBoundingClientRect();
                }
            }
            // else
            return returnPromise ? (promise || window.Promise.resolve()) : instance;
        };

       /**
        * Removes a subtype `transform`-css-property of (inline) out of the Element.
        * This way you can sefely remove partial `transform`-properties while remaining the
        * other inline `transform` css=properties.
        *
        * See more about tranform-properties: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
        *
        * @method removeInlineTransition
        * @param transitionProperty {String} the css-transform property to remove
        * @param [pseudo] {String} to look inside a pseudo-style
        * @chainable
        * @since 0.0.1
        */
        ElementPrototype.removeInlineTransition = function(transitionProperty, pseudo) {
            return this.removeInlineTransitions({property: transitionProperty, pseudo: pseudo});
        };

       /**
        * Removes multiple subtype `transform`-css-property of (inline) out of the Element.
        * This way you can sefely remove partial `transform`-properties while remaining the
        * other inline `transform` css=properties.
        * You need to supply an Array of Objects, with the properties:
        *        <ul>
        *            <li>property  {String}</li>
        *            <li>pseudo  {String}</li>
        *        <ul>
        *
        * See more about tranform-properties: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
        *
        * @method removeInlineTransitions
        * @param transitionProperties {Array|Object} the css-transform properties to remove
        * @chainable
        * @since 0.0.1
        */
        ElementPrototype.removeInlineTransitions = function(transitionProperties) {
            var instance = this,
                vnode = instance.vnode,
                styles = vnode.styles,
                groupStyle, transitionStyles, i, len, item, needSync, transitionProperty, pseudo;

            if (styles) {
                Array.isArray(transitionProperties) || (transitionProperties=[transitionProperties]);
                transitionProperties = getVendorCSS(transitionProperties);
                len = transitionProperties.length;
                for (i=0; i<len; i++) {
                    item = transitionProperties[i];
                    pseudo = item.pseudo;
                    groupStyle = styles && styles[pseudo || 'element'];
                    transitionStyles = groupStyle && groupStyle[VENDOR_TRANSITION_PROPERTY];
                    if (transitionStyles) {
                        transitionProperty = item.property;
                        if (transitionStyles[transitionProperty]) {
                            delete transitionStyles[transitionProperty];
                            (transitionStyles.size()===0) && (delete groupStyle[VENDOR_TRANSITION_PROPERTY]);
                            (styles.size()===0) && (delete vnode.styles[pseudo || 'element']);
                            needSync = true;
                        }
                    }
                }
            }
            needSync && instance.setAttr(STYLE, vnode.serializeStyles());
            return instance;
        };

       /**
        * Replaces the Element with a new Element.
        *
        * @method replace
        * @param content {Element|Element|ElementArray|String} content to replace
        * @param [escape] {Boolean} whether to insert `escaped` content, leading it into only text inserted
        * @return {Element} the created Element (or the last when multiple)
        * @since 0.0.1
        */
        ElementPrototype.replace = function(newElement, escape) {
            var instance = this,
                vnode = instance.vnode,
                previousVNode = vnode.vPrevious,
                vParent = vnode.vParent,
                createdElement;
            createdElement = previousVNode ? vParent.domNode.append(newElement, escape, previousVNode.domNode) : vParent.domNode.prepend(newElement, escape);
            instance.setClass(HIDDEN);
            instance.remove();
            return createdElement;
        };

        /**
        * Replaces the Element's child-Element with a new Element.
        *
        * @method replaceChild
        * @param newElement {Element} the new Element
        * @param oldVChild {Element} the Element to be replaced
        * @param [escape] {Boolean} whether to insert `escaped` content, leading it into only text inserted
        * @return {Element} the Element that was removed (equals oldVChild)
        * @since 0.0.1
        */
        ElementPrototype._replaceChild = ElementPrototype.replaceChild;
        ElementPrototype.replaceChild = function(newDomNode, oldDomNode, escape) {
            return oldDomNode.replace(newDomNode, escape);
        };

       /**
        * Replaces the className of the Element with a new className.
        * If the previous className is not available, the new className is set nevertheless.
        *
        * @method replaceClass
        * @param prevClassName {String} the className to be replaced
        * @param newClassName {String} the className to be set
        * @param [force ] {Boolean} whether the new className should be set, even is the previous className isn't there
        * @param [returnPromise] {Boolean} whether to return a Promise instead of `this`, which might be useful in case of
        *        transition-properties. The promise will fullfil when the transition is ready, or immediately when no transitioned.
        * @param [transitionFix] set this to `true` if you experience transition-problems due to wrong calculated css (mostly because of the `auto` value)
        *        Setting this parameter, will calculate the true css of the transitioned properties and set this temporarely inline, to fix the issue.
        *        Don't use it when not needed, it has a slightly performancehit.
        *        No need to set when `returnPromise` is set --> returnPromise always handles the transitionFix.
        * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
        * @return {Promise|this} In case `returnPromise` is set, a Promise returns with the next handles:
        *        <ul>
        *            <li>cancel() {Promise}</li>
        *            <li>freeze() {Promise}</li>
        *            <li>unfreeze()</li>
        *            <li>finish() {Promise}</li>
        *        </ul>
        *        These handles resolve with the `elapsed-time` as first argument of the callbackFn
        * @since 0.0.1
        */
        ElementPrototype.replaceClass = function(prevClassName, newClassName, force, returnPromise, transitionFix, silent) {
            var instance = this,
                prevSuppress = DOCUMENT._suppressMutationEvents || false,
                transPromise, returnValue;
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(true);
            transPromise = (returnPromise || transitionFix) && getClassTransPromise(instance, REPLACE, newClassName, prevClassName, force);
            if (force || instance.hasClass(prevClassName)) {
                returnValue = returnPromise ? transPromise : instance;
                transPromise || instance.removeClass(prevClassName).setClass(newClassName);
                return returnValue;
            }
            if (silent && DOCUMENT.suppressMutationEvents) {
                if (returnValue===instance) {
                    DOCUMENT.suppressMutationEvents(prevSuppress);
                }
                else {
                    returnValue.finally(function() {
                        DOCUMENT.suppressMutationEvents(prevSuppress);
                    });
                }
            }
            return returnPromise ? window.Promise.resolve() : instance;
        };

        /**
         * Scrolls the content of the Element into the specified scrollposition.
         * Only available when the Element has overflow.
         *
         * @method scrollTo
         * @param x {Number} left-offset in pixels
         * @param y {Number} top-offset in pixels
         * @chainable
         * @since 0.0.1
        */
        ElementPrototype.scrollTo = function(x, y) {
            var instance = this;
            instance.scrollLeft = x;
            instance.scrollTop = y;
            return instance;
        };

       /**
         * Sets the attribute on the Element with the specified value.
         *
         * Alias for setAttribute(), BUT differs in a way that setAttr is chainable, setAttribute is not.
         *
         * @method setAttr
         * @param attributeName {String}
         * @param value {Any} the value that belongs to `key`
         * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
         * @chainable
         * @since 0.0.1
        */
        ElementPrototype.setAttr = function(attributeName, value, silent) {
            var instance = this;
            instance.setAttribute(attributeName, value, silent);
            return instance;
        };

       /**
         * Sets the attribute on the Element with the specified value.
         *
         * Alias for setAttr(), BUT differs in a way that setAttr is chainable, setAttribute is not.
         *
         * @method setAttribute
         * @param attributeName {String}
         * @param value {String} the value for the attributeName
         * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
        */
        ElementPrototype._setAttribute = ElementPrototype.setAttribute;
        ElementPrototype.setAttribute = function(attributeName, value, silent) {
            var instance = this,
                prevSuppress = DOCUMENT._suppressMutationEvents || false,
                vnode = instance.vnode;
            (value==='') && (value=null);
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(true);
            ((value!==null) && (value!==undefined)) ? vnode._setAttr(attributeName, value) : vnode._removeAttr(attributeName);
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(prevSuppress);
        };

       /**
         * Sets the attribute on the Element with the specified value inside a specified namespace
         *
         * @method setAttributeNS
         * @param nameSpace {String} the namespace where to attribuyte should be set in
         * @param attributeName {String}
         * @param value {String} the value for the attributeName
         * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
        */
        ElementPrototype._setAttributeNS = ElementPrototype.setAttributeNS;
        ElementPrototype.setAttributeNS = function(nameSpace, attributeName, value, silent) {
            this.setAttribute((nameSpace ? nameSpace+':' : '')+attributeName, value, silent);
        };

       /**
         * Sets multiple attributes on the Element with the specified value.
         * The argument should be one ore more Objects with the properties: `name` and `value`
         *
         * @example
         * instance.setAttrs([
         *                      {name: 'tabIndex', value: '0'},
         *                      {name: 'style', value: 'color: #000;'}
         *                  ]);
         *
         * @method setAttrs
         * @param attributeData {Array|Object}
         * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
         * @chainable
         * @since 0.0.1
        */
        ElementPrototype.setAttrs = function(attributeData, silent) {
            var instance = this;
            Array.isArray(attributeData) || (attributeData=[attributeData]);
            attributeData.forEach(function(item) {
                instance.setAttribute(item.name, item.value, silent);
            });
            return instance;
        };

       /**
        * Adds a class to the Element. If the class already exists it won't be duplicated.
        *
        * @method setClass
        * @param className {String|Array} className to be added, may be an array of classNames
        * @param [returnPromise] {Boolean} whether to return a Promise instead of `this`, which might be useful in case of
        *        transition-properties. The promise will fullfil when the transition is ready, or immediately when no transitioned.
        * @param [transitionFix] set this to `true` if you experience transition-problems due to wrong calculated css (mostly because of the `auto` value)
        *        Setting this parameter, will calculate the true css of the transitioned properties and set this temporarely inline, to fix the issue.
        *        Don't use it when not needed, it has a slightly performancehit.
        *        No need to set when `returnPromise` is set --> returnPromise always handles the transitionFix.
        * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
        * @return {Promise|this} In case `returnPromise` is set, a Promise returns with the next handles:
        *        <ul>
        *            <li>cancel() {Promise}</li>
        *            <li>freeze() {Promise}</li>
        *            <li>unfreeze()</li>
        *            <li>finish() {Promise}</li>
        *        </ul>
        *        These handles resolve with the `elapsed-time` as first argument of the callbackFn
        * @since 0.0.1
        */
        ElementPrototype.setClass = function(className, returnPromise, transitionFix, silent) {
            var instance = this,
                prevSuppress = DOCUMENT._suppressMutationEvents || false,
                transPromise, returnValue;
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(true);
            transPromise = (returnPromise || transitionFix) && getClassTransPromise(instance, SET, className);
            returnValue = returnPromise ? transPromise : instance;
            transPromise || instance.getClassList().add(className);
            if (silent && DOCUMENT.suppressMutationEvents) {
                if (returnValue===instance) {
                    DOCUMENT.suppressMutationEvents(prevSuppress);
                }
                else {
                    returnValue.finally(function() {
                        DOCUMENT.suppressMutationEvents(prevSuppress);
                    });
                }
            }
            return returnValue;
        };

        /**
         * Stores arbitary `data` at the Element (actually at vnode). This has nothing to do with node-attributes whatsoever,
         * it is just a way to bind any data to the specific Element so it can be retrieved later on with `getData()`.
         *
         * @method setData
         * @param key {string} name of the key
         * @param value {Any} the value that belongs to `key`
         * @param [deep] {Boolean} whether to set the data to all descendants recursively
         * @chainable
         * @since 0.0.1
        */
        ElementPrototype.setData = function(key, value, deep) {
            var instance = this,
                vnode = instance.vnode;
            if (value!==undefined) {
                vnode._data || Object.protectedProp(vnode, '_data', {});
                vnode._data[key] = value;
                if (deep) {
                    instance.getChildren().forEach(function(element) {
                        element.setData(key, value, true);
                    });
                }
            }
            return instance;
        };

        /**
         * Sets the innerHTML of both the vnode as well as the representing dom-node.
         * Goes through the vdom, so it's superfast.
         *
         * Use this method instead of `innerHTML`
         *
         * Syncs with the DOM.
         *
         * @method setHTML
         * @param val {String} the new value to be set
         * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
         * @param [allowScripts=false] {Boolean} whether scripts are allowed --> these should be defined with `xscript` instead of `script`
         * @chainable
         * @since 0.0.1
         */
        ElementPrototype.setHTML = function(val, silent, allowScripts) {
            var instance = this,
                prevSuppress = DOCUMENT._suppressMutationEvents || false;
            // DO NOT use "display: block" the parent node (as with append/prepend), for itags mostly re-setHTML without changes
            // that would lead to more delay when we want
            // hasDisplayNode || instance.setClass(ITSA_NODISPLAY);
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(true);
            instance.vnode.setHTML(val, null, allowScripts);
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(prevSuppress);
            return instance;
        };

       /**
        * Sets the Elments `id`
        *
        * @method setId
        * @param val {String} Elements new `id`
        * @chainable
        * @since 0.0.1
        */
        ElementPrototype.setId = function(val) {
            return this.setAttr('id', val);
        };

       /**
        * Sets a css-property (inline) for the Element.
        *
        * Note1: Do not use vendor-specific properties, but general (like `transform` instead of `-webkit-transform`)
        *        This method will use the appropriate css-property.
        * Note2: no need to camelCase cssProperty: both `margin-left` as well as `marginLeft` are fine
        *
        * @method setInlineStyle
        * @param cssProperty {String} the css-property to be set
        * @param value {String} the css-value
        * @param [pseudo] {String} to look inside a pseudo-style
        * @param [returnPromise] {Boolean} whether to return a Promise instead of `this`, which might be useful in case of
        *        transition-properties. The promise will fullfil when the transition is ready, or immediately when no transitioned.
        * @return {Promise|this}
        * @since 0.0.1
        */
        ElementPrototype.setInlineStyle = function(cssProperty, value, pseudo, returnPromise) {
            if (typeof pseudo==='boolean') {
                returnPromise = pseudo;
                pseudo = null;
            }
            return this.setInlineStyles([{property: cssProperty, value: value, pseudo: pseudo}], returnPromise);
        };

       /**
        * Sets multiple css-properties (inline) for the Element at once.
        *
        * Note1: Do not use vendor-specific properties, but general (like `transform` instead of `-webkit-transform`)
        *        This method will use the appropriate css-property.
        * Note2: no need to camelCase cssProperty: both `margin-left` as well as `marginLeft` are fine
        *
        * @method setInlineStyles
        * @param cssProperties {Array|Object} the css-properties to be set, specified as an Array of Objects, or 1 Object.
        *        The objects should have the next properties:
        *        <ul>
        *            <li>property  {String}</li>
        *            <li>value  {String}</li>
        *            <li>pseudo  {String} (optional) --> not: not supported yet in browsers</li>
        *        </ul>
        * @param [returnPromise] {Boolean} whether to return a Promise instead of `this`, which might be useful in case of
        *        transition-properties. The promise will fullfil when the transition is ready, or immediately when no transitioned.
        * @return {Promise|this}
        * @since 0.0.1
        */
        ElementPrototype.setInlineStyles = function(cssProperties, returnPromise) {
            // There will be 3 sets of styles:
            // `fromStyles` --> the current styles, only exactly calculated -without `auto`- (that is, for the transitioned properties)
            // `toStylesExact` --> the new styles, exactly calculated -without `auto`- (that is, for the transitioned properties)
            // `vnodeStyles` --> the new styles as how they should be in the end (f.i. with `auto`)
            var instance = this,
                vnode = instance.vnode,
                transitionedProps = [],
                transCount = 0,
                maxtranstime = 0,
                transitionProperties = {},
                // third argument is a hidden feature --> used by getClassTransPromise()
                avoidBackup = arguments[2],
                styles, group, i, len, item, promise, hasTransitionedStyle, property, hasChanged, transtime,
                pseudo, fromStyles, value, vnodeStyles, toStylesExact, clonedElement, transproperty;

            // if there is a class-transition going on (initiated by getClassTransPromise),
            // the we might need to update the internal bkpNode:
            if (!avoidBackup && vnode._data) {
                // there might be more bkpNodes, so we need to loop through the data:
                vnode._data.each(function(bkpNode, key) {
                    if (key.startsWith('bkpNode')) {
                        bkpNode.setInlineStyles(cssProperties, null, true);
                    }
                });
            }

            Array.isArray(cssProperties) || (cssProperties=[cssProperties]);
            cssProperties = getVendorCSS(cssProperties);
            len = cssProperties.length;
            vnode.styles || (vnode.styles={});
            vnodeStyles = vnode.styles;
            // Both `from` and `to` ALWAYS need to be set to their calculated value --> this makes transition
            // work with `auto`, or when the page isn't completely loaded
            // First: backup the actual style:
            fromStyles = vnodeStyles.deepClone();
            for (i=0; i<len; i++) {
                item = cssProperties[i];
                pseudo = item.pseudo;
                group = pseudo || 'element';
                vnodeStyles[group] || (vnodeStyles[group]={});
                styles = vnodeStyles[group];
                property = fromCamelCase(item.property);
                value = item.value;

                (property===VENDOR_TRANSITION_PROPERTY) && (value=extractor.toTransitionObject(value));
                if (value===undefined) {
                    delete styles[property];
                }
                else {
                    styles[property] = value;
                }
                if ((property!==VENDOR_TRANSITION_PROPERTY) && (instance.getStyle(property, pseudo)!==value) && instance.hasTransition(property, pseudo)) {
                    fromStyles[group] || (fromStyles[group]={});
                    (property===VENDOR_TRANSFORM_PROPERTY) || (fromStyles[group][property]=instance.getStyle(property, pseudo));
                    if (fromStyles[group][property]!==value) {
                        transproperty = instance.getTransition(property, (group==='element') ? null : group);
                        if (transproperty) {
                            transtime = transproperty.delay+transproperty.duration;
                            maxtranstime = Math.max(maxtranstime, transtime);
                            if (transtime>0) {
                                hasTransitionedStyle = true;
                                transCount++;
                                // TODO: transitionProperties supposes that we DO NOT have pseudo transitions!
                                // as soon we do, we need to split this object for each 'group'
                                transitionProperties[property] = true;
                                transitionedProps[transitionedProps.length] = {
                                    group: group,
                                    property: property,
                                    value: value,
                                    pseudo: pseudo
                                };
                            }
                        }
                    }
                }
            }
            RUNNING_ON_NODE && (hasTransitionedStyle=false);
            if (hasTransitionedStyle) {
                // we forced set the exact initial css inline --> this is the only way to make a right transition
                // under all circumstances
                toStylesExact = vnodeStyles.deepClone();
                clonedElement = instance.cloneNode(true); // cloned with `vnodeStyles`
                clonedElement.vnode.styles = toStylesExact;
                // fix the current style with what is actual calculated:
                vnode.styles = fromStyles; // exactly styles, so we can transition well
                instance.setClass(NO_TRANS);
                instance.setAttr(STYLE, vnode.serializeStyles());
                async(function() {
                    // needs to be done in the next eventcyle, otherwise webkit-browsers miscalculate the syle (with transition on)
                    instance.removeClass(NO_TRANS);
                });

                // clonedElement has `vnodeStyles`, but we change them into `toStylesExact`
                clonedElement.setClass(INVISIBLE_UNFOCUSABLE);
                clonedElement.setAttr(STYLE, clonedElement.vnode.serializeStyles());
                DOCUMENT.body.append(clonedElement);

                // now calculate the `transition` styles and store them in the css-property of `toStylesExact`:
                len = transitionedProps.length;
                hasChanged = false;
                for (i=0; i<len; i++) {
                    item = transitionedProps[i];
                    property = item.property;
                    group = item.pseudo || 'element';
                    if (!NON_CLONABLE_STYLES[property]) {
                        value = (property===VENDOR_TRANSFORM_PROPERTY) ? clonedElement.getInlineStyle(property, item.pseudo) : clonedElement.getStyle(property, item.pseudo);
                        if (value) {
                            toStylesExact[group] || (toStylesExact[group]={});
                            toStylesExact[group][property] = value;
                        }
                    }
                    // look if we really have a change in the value:
                    if (!hasChanged && toStylesExact[group]) {
                        hasChanged = (toStylesExact[group][property]!==fromStyles[group][property]);
                    }
                }
                clonedElement.remove();
                hasTransitionedStyle = hasChanged;
            }
            RUNNING_ON_NODE && (hasTransitionedStyle=false);
            if (returnPromise || hasTransitionedStyle) {
                promise = window.Promise.manage();
                // need to call `setAttr` in a next event-cycle, otherwise the eventlistener made
                // by `getTransPromise gets blocked.
                async(function() {
                    if (hasTransitionedStyle) {
                        // reset
                        vnode.styles = toStylesExact;
                        promise.then(function() {

                            vnode.styles = vnodeStyles; // finally values, not exactly calculated, but as is passed through
                            instance.setClass(NO_TRANS);
                            instance.setAttr(STYLE, vnode.serializeStyles());
                        }).finally(function() {
                            async(function() {
                                // needs to be done in the next eventcyle, otherwise webkit-browsers miscalculate the syle (with transition on)
                                instance.removeClass(NO_TRANS);
                                // webkit browsers seems to need to recalculate their set width:
                                instance.getBoundingClientRect();
                            });
                        });
                    }
                    else {
                        vnode.styles = vnodeStyles; // finally values, not exactly calculated, but as is passed through
                    }
                    getTransPromise(instance, hasTransitionedStyle, null, transCount, transitionProperties, maxtranstime).then(
                        function() {
                            promise.fulfill();
                        }
                    ).catch(promise.reject);
                    instance.setAttr(STYLE, vnode.serializeStyles());
                });
                return returnPromise ? promise : instance;
            }
            // else
            vnode.styles = vnodeStyles; // finally values, not exactly calculated, but as is passed through
            instance.setAttr(STYLE, vnode.serializeStyles());
            // webkit browsers seems to need to recalculate their set width:
            instance.getBoundingClientRect();
            return instance;
        };

       /**
        * Sets a transform-css-property (inline) for the Element.
        *
        * See more about transitions: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions
        *
        * @method setStyle
        * @param setInlineTransition {String} the css-property to be set, f.e. `translateX`
        * @param duration {Number} the duration in seconds (may be a broken number, like `0.5`)
        * @param [timingFunction] {String} See https://developer.mozilla.org/en-US/docs/Web/CSS/transition-timing-function
        * @param delay {Number} the delay in seconds (may be a broken number, like `0.5`)
        * @param [pseudo] {String} to look inside a pseudo-style
        * @chainable
        * @since 0.0.1
        */
        ElementPrototype.setInlineTransition = function(transitionProperty, duration, timingFunction, delay, pseudo) {
            // transition-example: transition: width 2s, height 2s, transform 2s;
            return this.setInlineTransitions({property: transitionProperty, duration: duration, timingFunction: timingFunction, delay: delay, pseudo: pseudo});
        };

       /**
        * Sets a transform-css-property (inline) for the Element.
        *
        * See more about transitions: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions
        *
        * @method setStyle
        * @param transitionProperties {Array} the css-transition-properties to be set, specified as an Array of Objects.
        *        The objects should have the next properties:
        *        <ul>
        *            <li>property  {String}</li>
        *            <li>duration  {Number}</li>
        *            <li>timingFunction  {String} (optional)</li>
        *            <li>delay  {Number} (optional)</li>
        *            <li>pseudo  {String} (optional)</li>
        *        </ul>
        * @param [pseudo] {String} to look inside a pseudo-style
        * @chainable
        * @since 0.0.1
        */
        ElementPrototype.setInlineTransitions = function(transitionProperties) {
            // transition-example: transition: width 2s, height 2s, transform 2s;
            var instance = this,
                vnode = instance.vnode,
                transitionStyles, transitionProperty, group, trans, i, len, item;
            Array.isArray(transitionProperties) || (transitionProperties=[transitionProperties]);
            transitionProperties = getVendorCSS(transitionProperties);
            len = transitionProperties.length;
            vnode.styles || (vnode.styles={});
            for (i=0; i<len; i++) {
                item = transitionProperties[i];
                if (item.property) {
                    group = item.pseudo || 'element';
                    vnode.styles[group] || (vnode.styles[group]={});
                    vnode.styles[group][VENDOR_TRANSITION_PROPERTY] || (vnode.styles[group][VENDOR_TRANSITION_PROPERTY]={});
                    transitionStyles = vnode.styles[group][VENDOR_TRANSITION_PROPERTY];
                    transitionProperty = fromCamelCase(item.property);
                    trans = transitionStyles[transitionProperty] = {
                        duration: item.duration
                    };
                    item.timingFunction && (trans.timingFunction=item.timingFunction);
                    item.delay && (trans.delay=item.delay);
                }
            }
            instance.setAttr(STYLE, vnode.serializeStyles());
            return instance;
        };

        /**
         * Gets or sets the outerHTML of both the Element as well as the representing dom-node.
         * Goes through the vdom, so it's superfast.
         *
         * Use this property instead of `outerHTML`
         *
         * Syncs with the DOM.
         *
         * @method setOuterHTML
         * @param val {String} the new value to be set
         * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
         * @chainable
         * @since 0.0.1
         */
        ElementPrototype.setOuterHTML = function(val, silent) {
            var instance = this,
                prevSuppress = DOCUMENT._suppressMutationEvents || false;
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(true);
            instance.vnode.outerHTML = val;
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(prevSuppress);
            return instance;
        };

        /**
         * Sets the innerContent of the Element as plain text.
         * Goes through the vdom, so it's superfast.
         *
         * Use this method instead of `textContent`
         *
         * Syncs with the DOM.
         *
         * @method setText
         * @param val {String} the textContent to be set
         * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
         * @chainable
         * @since 0.0.1
         */
        ElementPrototype.setText = function(val, silent) {
            var instance = this,
                prevSuppress = DOCUMENT._suppressMutationEvents || false;
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(true);
            instance.vnode.textContent = val;
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(prevSuppress);
            return instance;
        };

       /**
        * Sets the value of the following Elements:
        *
        * <ul>
        *     <li>input</li>
        *     <li>textarea</li>
        *     <li>select</li>
        *     <li>any container that is `contenteditable`</li>
        * </ul>
        *
        * Will emit a `valuechange`-event when a new value is set and ITSA's `event`-module is active.
        *
        * @method setValue
        * @param val {String} thenew value to be set
        * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit. Only appropriate for contenteditable nodes.
        * @chainable
        * @since 0.0.1
        */
        ElementPrototype.setValue = function(val, silent) {
            var instance = this,
                prevVal = instance.value,
                contenteditable = instance.vnode.attrs.contenteditable,
            // cautious: input and textarea must be accessed by their propertyname:
            // input.getAttribute('value') would return the defualt-value instead of actusl
            // and textarea.getAttribute('value') doesn't exist
                editable = contenteditable && (contenteditable!=='false'),
                tag, i, option, len, vChildren;
            if (editable) {
                // no need to compare with current html --> when vdom is working, only differences are set
                instance.setHTML(val, silent);
            }
            else {
                tag = instance.getTagName();
                if ((tag==='INPUT') || (tag==='TEXTAREA')) {
                    // don't update when not needed: we don't want to reposition the cursor
                    (instance.value!==val) && (instance.value=val);
                }
                else if (tag==='SELECT') {
                    vChildren = instance.vnode.vChildren;
                    len = vChildren.length;
                    for (i=0; i<len; i++) {
                        option = vChildren[i];
                        if (option.attrs.value === val) {
                            instance.selectedIndex = i;
                            break;
                        }
                    }
                }
            }
            // if `document._emitVC` is available, then invoke it to emit the `valuechange`-event
            /**
            * @event valuechange
            * @param e.value {String} new value
            * @param e.sourceTarget {Element} Element whare the valuechange occured
            */
            DOCUMENT._emitVC && (prevVal!==val) && DOCUMENT._emitVC(instance, val);
            return instance;
        };

       /**
         * Set the position of an html element in page coordinates.
         * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
         *
         * If the Element has the attribute `xy-constrian` set, then its position cannot exceed any matching container it lies within.
         *
         * @method setXY
         * @param x {Number} x-value for new position (coordinates are page-based)
         * @param y {Number} y-value for new position (coordinates are page-based)
         * @param [constrain] {'window', Element, Object, String}
         * <ul>
         *     <li><b>'window'</b> to constrain to the visible window</li>
         *     <li><b>Element</b> to constrain to a specified Element</li>
         *     <li><b>Object</b> to constrain to an object with the properties: {x, y, w, h} where x and y are absolute pixels of the document
         *            (like calculated with getX() and getY()).</li>
         *     <li><b>String</b> to constrain to a specified css-selector, which should be an ancestor</li>
         * </ul>
         * @param [notransition=false] {Boolean} set true if you are sure positioning is without transition.
         *        this isn't required, but it speeds up positioning. Only use when no transition is used:
         *        when there is a transition, setting this argument `true` would miscalculate the position.
         *        The return-value will be `this` in case `notransition`===true, making setXY to be chainable.
         * @return {Promise|this}
         * @since 0.0.1
         */
        ElementPrototype.setXY = function(x, y, constrain, notransition) {
            console.log(NAME, 'setXY '+x+','+y);
            var instance = this,
                dif, constrainNode, parent, clone, promise,
                containerTop, containerRight, containerLeft, containerBottom, requestedX, requestedY,
                transObject, xtrans, ytrans, inlinePosition, globalPosition, invisibleClass;

            // default position to relative: check first inlinestyle because this goes quicker
            inlinePosition = instance.getInlineStyle(POSITION);
            inlinePosition || (globalPosition=instance.getStyle(POSITION));
            if ((inlinePosition==='static') || (inlinePosition==='fixed') || (globalPosition==='static') || (globalPosition==='fixed')) {
                inlinePosition = 'relative';
                instance.setInlineStyle(POSITION, inlinePosition);
            }
            invisibleClass = (inlinePosition==='absolute') ? INVISIBLE : INVISIBLE_RELATIVE;
            // make sure it has sizes and can be positioned
            instance.setClass([invisibleClass, BORDERBOX]);
            (instance.getInlineStyle('display')==='none') && instance.setClass(BLOCK);
            constrain || (constrain=instance.getAttr('constrain-selector'));
            if (constrain) {
                if (constrain==='window') {
                    containerLeft = window.getScrollLeft();
                    containerTop = window.getScrollTop();
                    containerRight = containerLeft + window.getWidth();
                    containerBottom = containerTop + window.getHeight();
                }
                else {
                    if (typeof constrain === STRING) {
                        constrainNode = instance.inside(constrain);
                    }
                    if (constrain.matchesSelector) {
                        // Element --> we need to search the rectangle
                        containerLeft = constrain.left + parseInt(constrain.getStyle(BORDER_LEFT_WIDTH), 10);
                        containerTop = constrain.top + parseInt(constrain.getStyle(BORDER_TOP_WIDTH), 10);
                        containerRight = containerLeft + constrain.scrollWidth;
                        containerBottom = containerTop + constrain.scrollHeight;
                    }
                    else {
                        containerLeft = constrain.x;
                        containerTop = constrain.y;
                        containerRight = constrain.x + constrain.w;
                        containerBottom = constrain.y + constrain.h;
                    }
                }
                if (typeof containerLeft === NUMBER) {
                    // found constrain, always redefine x and y
                    x = requestedX = (typeof x===NUMBER) ? x : instance.left;
                    if (requestedX<containerLeft) {
                        x = containerLeft;
                    }
                    else {
                        if ((requestedX+instance.offsetWidth)>containerRight) {
                            x = requestedX = containerRight - instance.offsetWidth;
                        }
                        // now we might need to reset to the left again:
                        (requestedX<containerLeft) && (x=containerLeft);
                    }
                    y = requestedY = (typeof y===NUMBER) ? y : instance.top;
                    if (requestedY<containerTop) {
                        y = containerTop;
                    }
                    else {
                        if ((requestedY+instance.offsetHeight)>containerBottom) {
                            y = requestedY = containerBottom - instance.offsetHeight;
                        }
                        // now we might need to reset to the top again:
                        (requestedY<containerTop) && (y=containerTop);
                    }
                }
            }
            xtrans = (typeof x === NUMBER);
            ytrans = (typeof y === NUMBER);
            if (xtrans || ytrans) {
                // check if there is a transition:
                if (notransition) {
                    instance.setClass([NO_TRANS2, invisibleClass]);
                    transObject = [];
                    xtrans && (transObject[0]={property: LEFT, value: x + PX});
                    ytrans && (transObject[xtrans ? 1 : 0]={property: TOP, value: y + PX});
                    instance.setInlineStyles(transObject);
                    // reset transObject and maybe it will be filled when there is a difference
                    // between the set value and the true value (which could appear due to different `position` properties)
                    transObject = [];
                    if (xtrans) {
                        dif = (instance.left-x);
                        (dif!==0) && (transObject[0]={property: LEFT, value: (x - dif) + PX});
                    }
                    if (ytrans) {
                        dif = (instance.top-y);
                        (dif!==0) && (transObject[transObject.length]={property: TOP, value: (y - dif) + PX});
                    }
                    (transObject.length>0) && instance.setInlineStyles(transObject);
                    instance.removeClass([NO_TRANS2, invisibleClass]);
                }
                else {
                    // we will clone the node, make it invisible and without transitions and look what its correction should be
                    clone = instance.cloneNode();
                    clone.setClass([NO_TRANS2, invisibleClass]);
                    parent = instance.getParent() || DOCUMENT.body;
                    parent.prepend(clone, null, instance);

                    transObject = [];
                    xtrans && (transObject[0]={property: LEFT, value: x + PX});
                    ytrans && (transObject[xtrans ? 1 : 0]={property: TOP, value: y + PX});

                    clone.setInlineStyles(transObject);

                    // reset transObject and fill it with the final true values
                    transObject = [];
                    xtrans && (transObject[0]={property: LEFT, value: (2*x-clone.left) + PX});
                    ytrans && (transObject[xtrans ? 1 : 0]={property: TOP, value: (2*y-clone.top) + PX});
                    clone.remove();
                    promise = instance.setInlineStyles(transObject, true);
                }
            }
            else if (!notransition) {
                promise = window.Promise.resolve();
            }
            instance.removeClass([BLOCK, BORDERBOX, invisibleClass]);
            return promise || instance;
        };

       /**
        * Shows a previously hidden node.
        * Shows immediately without `fade`, or will fade-in when fade is specified.
        *
        * @method show
        * @param [fade] {Number} sec to fade-in (you may use `0.1`)
        * @return {this|Promise} fulfilled when the element is ready showing up, or rejected when hidden again (using node.hide) before fully showed.
        * @since 0.0.1
        */
        ElementPrototype.show = function(duration, forceFull) {
            var instance = this,
                showPromise = instance.getData('_showNodeBusy'),
                hidePromise = instance.getData('_hideNodeBusy'),
                originalOpacity, hasOriginalOpacity, promise, freezedOpacity, finalValue;

            instance.setData('nodeShowed', true); // for any routine who wants to know
            originalOpacity = instance.getData('_showNodeOpacity');
            if (!originalOpacity && !showPromise && !hidePromise) {
                originalOpacity = instance.getInlineStyle('opacity');
                instance.setData('_showNodeOpacity', originalOpacity);
            }
            hasOriginalOpacity = !!originalOpacity;

            showPromise && showPromise.freeze();
            if (hidePromise) {
                hidePromise.freeze();
                instance.removeData('_hideNodeBusy');
            }

            if (duration) {

                instance.setInlineStyle('opacity', (instance.hasClass(HIDDEN) ? 0 : instance.getStyle('opacity')));
                instance.removeClass(HIDDEN);

                finalValue = (forceFull || !hasOriginalOpacity) ? 1 : originalOpacity;
                if (showPromise || hidePromise) {
                    freezedOpacity = instance.getInlineStyle('opacity');
                    duration = (finalValue>0) ? Math.min(1, ((finalValue-freezedOpacity)/finalValue))*duration : 0;
                }
                promise = instance.transition({property: 'opacity', value: finalValue, duration: duration});
                instance.setData('_showNodeBusy', promise);

                promise.finally(function() {
                    if (!promise.cancelled && !promise.frozen) {
                        hasOriginalOpacity || instance.removeInlineStyle('opacity');
                        if (!forceFull || !hasOriginalOpacity) {
                            instance.removeData('_showNodeOpacity');
                        }
                    }
                    instance.removeData('_showNodeBusy');
                });
                return promise;
            }
            else {
                async(function() {
                    (hasOriginalOpacity && !forceFull) ? instance.setInlineStyle('opacity', originalOpacity) : instance.removeInlineStyle('opacity');
                    instance.removeClass(HIDDEN);
                });
                return instance;
            }
        };

       /**
        * Transitions one ore more properties of the Element.
        *
        * @method toggleClass
        * @param to {Array} the css-properties to be set, specified as an Array of Objects.
        *        The objects should have the next properties:
        *        <ul>
        *            <li>property  {String}</li>
        *            <li>value  {String}</li>
        *            <li>duration  {Number} (optional)</li>
        *            <li>timingFunction  {String} (optional)</li>
        *            <li>delay  {String} (optional)</li>
        *            <li>pseudo  {String} (optional) --> not: not supported yet in browsers</li>
        *        </ul>
        * @param [from] {Array} starting the css-properties to be set, specified as an Array of Objects.
        *        If disguarded, then the current style is used as startingpoint. You may specify a subset of the `to`-properties.
        *        The objects should have the next properties:
        *        <ul>
        *            <li>property  {String}</li>
        *            <li>value  {String}</li>
        *            <li>duration  {Number} (optional)</li>
        *            <li>timingFunction  {String} (optional)</li>
        *            <li>delay  {String} (optional)</li>
        *            <li>pseudo  {String} (optional) --> not: not supported yet in browsers</li>
        *        </ul>
        * @return {Promise} The promise has the handles:
        *        <ul>
        *            <li>cancel() {Promise}</li>
        *            <li>freeze() {Promise}</li>
        *            <li>finish() {Promise}</li>
        *        </ul>
        *        These handles resolve with the `elapsed-time` as first argument of the callbackFn
        * @since 0.0.1
        */
        ElementPrototype.transition = function(to, from) {
            var instance = this,
                currentInlineTransition, transitions, transitionRun, transitionError, promise, resolveHandle, initialStyle, time1, intermediateInvoked,
                initialProperties, cleanup, getCurrentProperties, manipulated, getNoTransProp, transpromise, endIntermediate, time2;

            to || (to={});
            Array.isArray(to) || (to=[to]);
            to = getVendorCSS(to);
            transitions = Array.isArray(to) ? to.deepClone() : [to.shallowClone()];
            time1 = Date.now();
            // transitions = Array.isArray(to) ? to.deepClone() : [to.shallowClone()];
            cleanup = function() {
                currentInlineTransition = instance.getData('_bkpTransition');
                currentInlineTransition ? instance.setInlineStyle(TRANSITION, currentInlineTransition) : instance.removeInlineStyle(TRANSITION);
                instance.removeData('_bkpTransition');
                instance.removeData('_readyOnRun');
                Object.defineProperty(promise, 'isFulfilled', {
                    configurable: false,
                    enumerable: false,
                    writable: false,
                    value: true
                });
            };
            getCurrentProperties = function() {
                var props = [],
                    currentStyle = window.getComputedStyle(instance),
                    currentStyleBefore = window.getComputedStyle(instance, ':before'),
                    currentStyleAfter = window.getComputedStyle(instance, ':after');
                to.each(function(value) {
                    var styles = (value.pseudo===':before') ? currentStyleBefore : ((value.pseudo===':after') ? currentStyleAfter : currentStyle),
                        property = value.property;
                    // if property is vendor-specific transition, or transform, than we reset it to the current vendor
                    props.push({
                        property: property,
                        value: styles[toCamelCase(property)]
                    });
                });
                return props;
            };
            getNoTransProp = function() {
                var props = [];
                transitions.forEach(function(item) {
                    props.push({
                        property: item.property,
                        duration: 0,
                        delay: 0
                    });
                });
                return props;
            };
            endIntermediate = function(type) {
                intermediateInvoked = true;
                if (!promise.isFulfilled) {
                    manipulated = true;
                    instance.setInlineTransitions(getNoTransProp());
                    instance.setInlineStyles((type==='cancelled') ? initialProperties : getCurrentProperties());
                    // also force to set the style on the node outside the vdom --> by forcing this
                    // we won't run into the situation where the vdom doesn't change the dom because the style didn';'t change:
                    instance._setAttribute(STYLE, instance.getAttr(STYLE));
                    switch (type) {
                        case 'cancelled':
                            // now cleanup inline style that wasn't there initially,
                            async(function() {
                                instance.setClass(NO_TRANS2);
                                instance.setAttr(STYLE, initialStyle);
                                instance.removeClass(NO_TRANS2);
                            });
                            cleanup();
                        break;
                        case 'frozen':
                            async(function() {
                                cleanup();
                            });
                        break;
                        case 'finished':
                            instance.setInlineStyles(to);
                            async(function() {
                                cleanup();
                            });
                        break;
                    }
                    Object.defineProperty(promise, type, {
                        configurable: false,
                        enumerable: false,
                        writable: false,
                        value: true
                    });
                    // prevent transitionpromise to set its own final values after finishing
                    // but only if it is already available:
                    transpromise && transpromise.reject();
                    resolveHandle && resolveHandle();
                }
                time2 || (time2=Date.now());
                return new window.Promise(function(resolve) {
                    async(function() {
                        resolve(time2-time1);
                    });
                });
            };
            promise = new window.Promise(function(resolve, reject) {
                async(function() {
                    if (intermediateInvoked) {
                        reject();
                        return;
                    }
                    resolveHandle = resolve;
                    transitionRun = idGenerator('nodeTransition');
                    // only make ready on the last run
                    instance.setData('_readyOnRun', transitionRun);

                    if (from) {
                        instance.setClass(NO_TRANS2);
                        instance.setInlineStyles(from);
                        instance.removeClass(NO_TRANS2);
                    }
                    initialProperties = getCurrentProperties();
                    initialStyle = instance.getAttr(STYLE);

                    currentInlineTransition = instance.getData('_bkpTransition');
                    if (currentInlineTransition===undefined) {
                        currentInlineTransition = instance.getInlineStyle(TRANSITION) || null;
                        // `null` can be set as node-data, `undefined` connot
                        instance.setData('_bkpTransition', currentInlineTransition);
                    }

                    // we could use the `to` object and pass into `setInlineTransitions` directly,
                    // however, in case `duration` is not specified, we will define them to 1 sec.

                    // CAUTIOUS: the sum of `duration`+`delay` determines when the transition will be ready.
                    // This leads into separate transitions, we must prevent the promise to fulfill on the
                    // first tranition to be ready.
                    // Thus: we need to split every (`duration`+`delay`) group and give them each a separate setInlineStyle()-promise!
                    transitions.forEach(function(item) {
                        item.duration || (item.duration=1);
                        item.delay || (item.delay=0);
                    });

                    instance.setInlineTransitions(transitions);
                    transpromise = instance.setInlineStyles(to, true);
                    transpromise.catch(
                        function(err) {
                            transitionError = err;
                            return true; // fulfill the chain
                        }
                    ).finally(
                        function() {
                            // to prevent `transitionend` events biting each other when chaining `transition`,
                            // and reset the inline transition in time,
                            // we need to resolve the Promise after the eventstack:
                            async(function() {
                                if (!manipulated && (instance.getData('_readyOnRun')===transitionRun)) {
                                    cleanup();
                                    // because cleanup does an async action (setInlineStyles), we will append the eventstack:
                                    async(function() {
                                        if (transitionError) {
                                            reject(transitionError);
                                        }
                                        else {
                                            time2 || (time2=Date.now());
                                            resolve(time2-time1);
                                        }
                                    });
                                }
                            });
                        }
                    );
                });
            });

            promise.cancel = function() {
                return endIntermediate('cancelled');
            };

            promise.freeze = function() {
                return endIntermediate('frozen');
            };

            promise.finish = function() {
                return endIntermediate('finished');
            };

            return promise;
        };

       /**
         * Toggles the attribute on the Element with the specified value (giving it the value, or removes the attribute)
         *
         * @method toggleAttr
         * @param attributeName {String}
         * @param value {Any} the value that belongs to `key`
         * @param forceState {Boolean} to force toggling into this specific state
         * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
         * @chainable
         * @since 0.0.1
        */
        ElementPrototype.toggleAttr = function(attributeName, value, forceState, silent) {
            var instance = this,
                condition = (typeof forceState==='boolean') ? forceState : !instance.hasAttr(attributeName);
            if (condition) {
                return instance.setAttr(attributeName, value, silent);
            }
            else {
                return instance.removeAttr(attributeName, silent);
            }
        };

       /**
        * Toggles the className of the Element.
        *
        * @method toggleClass
        * @param className {String|Array} className that should be toggled, may be an array of classNames
        * @param forceState {Boolean} to force toggling into this specific state
        * @param [returnPromise] {Boolean} whether to return a Promise instead of `this`, which might be useful in case of
        *        transition-properties. The promise will fullfil when the transition is ready, or immediately when no transitioned.
        * @param [transitionFix] set this to `true` if you experience transition-problems due to wrong calculated css (mostly because of the `auto` value)
        *        Setting this parameter, will calculate the true css of the transitioned properties and set this temporarely inline, to fix the issue.
        *        Don't use it when not needed, it has a slightly performancehit.
        *        No need to set when `returnPromise` is set --> returnPromise always handles the transitionFix.
        * @param [silent=false] {Boolean} prevent node-mutation events by the Event-module to emit
        * @return {Promise|this} In case `returnPromise` is set, a Promise returns with the next handles:
        *        <ul>
        *            <li>cancel() {Promise}</li>
        *            <li>freeze() {Promise}</li>
        *            <li>unfreeze()</li>
        *            <li>finish() {Promise}</li>
        *        </ul>
        *        These handles resolve with the `elapsed-time` as first argument of the callbackFn
        * @since 0.0.1
        */
        ElementPrototype.toggleClass = function(className, forceState, returnPromise, transitionFix, silent) {
            var instance = this,
                prevSuppress = DOCUMENT._suppressMutationEvents || false,
                transPromise, returnValue;
            silent && DOCUMENT.suppressMutationEvents && DOCUMENT.suppressMutationEvents(true);
            transPromise = (returnPromise || transitionFix) && getClassTransPromise(instance, TOGGLE, className, forceState);
            returnValue = returnPromise ? transPromise : instance;
            transPromise || instance.getClassList().toggle(className, forceState);
            if (silent && DOCUMENT.suppressMutationEvents) {
                if (returnValue===instance) {
                    DOCUMENT.suppressMutationEvents(prevSuppress);
                }
                else {
                    returnValue.finally(function() {
                        DOCUMENT.suppressMutationEvents(prevSuppress);
                    });
                }
            }
            return returnValue;
        };

        Object.defineProperties(ElementPrototype, {

           /**
            * Gets the bottom y-position (in the DOCUMENT) of the element in pixels.
            * DOCUMENT-related: regardless of the window's scroll-position.
            *
            * @property bottom
            * @since 0.0.1
            */
            bottom: {
                get: function() {
                    return this.top + this.height;
                },
                set: function(pixelsBottom) {
                    this.top = pixelsBottom - this.height;
                }
            },

           /**
            * Gets or set the height of the element in pixels. Included are padding and border, not any margins.
            *
            * The getter is calculating through `offsetHeight`, the setter will set inline css-style for the height.
            *
            * Values are numbers without unity.
            *
            * @property height
            * @type {Number}
            * @since 0.0.1
            */
            height: {
                get: function() {
                    return this.offsetHeight;
                },
                set: function(val) {
                    var instance = this,
                        dif;
                    instance.setClass(INVISIBLE);
                    instance.setInlineStyle(HEIGHT, val + PX);
                    dif = (instance.offsetHeight-val);
                    (dif!==0) && (instance.setInlineStyle(HEIGHT, (val - dif) + PX));
                    instance.removeClass(INVISIBLE);
                }
            },

           /**
            * Gets or set the innerHeight of the element in pixels. Excluded the borders.
            * Included are padding.
            *
            * The getter is calculating through `offsetHeight`, the setter will set inline css-style for the height.
            *
            * Values are numbers without unity.
            *
            * @property innerHeight
            * @type {Number}
            * @since 0.0.1
            */
            innerHeight: {
                get: function() {
                    var instance = this,
                        borderTop = parseInt(instance.getStyle('border-top-width'), 10) || 0,
                        borderBottom = parseInt(instance.getStyle('border-bottom-width'), 10) || 0;
                    return instance.height - borderTop - borderBottom;
                },
                set: function(val) {
                    var instance = this,
                        borderTop = parseInt(instance.getStyle('border-top-width'), 10) || 0,
                        borderBottom = parseInt(instance.getStyle('border-bottom-width'), 10) || 0;
                    instance.height = val + borderTop + borderBottom;
                }
            },

           /**
            * Gets or set the innerHeight of the element in pixels. Excluded the borders.
            * Included are padding.
            *
            * The getter is calculating through `offsetHeight`, the setter will set inline css-style for the height.
            *
            * Values are numbers without unity.
            *
            * @property innerWidth
            * @type {Number}
            * @since 0.0.1
            */
            innerWidth: {
                get: function() {
                    var instance = this,
                        borderLeft = parseInt(instance.getStyle('border-left-width'), 10) || 0,
                        borderRight = parseInt(instance.getStyle('border-right-width'), 10) || 0;
                    return instance.width - borderLeft - borderRight;
                },
                set: function(val) {
                    var instance = this,
                        borderLeft = parseInt(instance.getStyle('border-left-width'), 10) || 0,
                        borderRight = parseInt(instance.getStyle('border-right-width'), 10) || 0;
                    instance.width = val + borderLeft + borderRight;
                }
            },

           /**
            * Gets the x-position (in the DOCUMENT) of the element in pixels.
            * DOCUMENT-related: regardless of the window's scroll-position.
            *
            * @property left
            * @since 0.0.1
            */
            left: {
                get: function() {
                    return Math.round(this.getBoundingClientRect().left + window.getScrollLeft());
                },
                set: function(pixelsLeft) {
                    this.setXY(pixelsLeft, null, null, true);
                }
            },

           /**
            * Gets the right-position (in the DOCUMENT) of the element in pixels.
            * DOCUMENT-related: regardless of the window's scroll-position.
            *
            * @property right
            * @since 0.0.1
            */
            right: {
                get: function() {
                    return this.left + this.width;
                },
                set: function(pixelsRight) {
                    this.left = pixelsRight - this.width;
                }
            },

           /**
            * Gets the y-position (in the DOCUMENT) of the element in pixels.
            * DOCUMENT-related: regardless of the window's scroll-position.
            *
            * @property top
            * @since 0.0.1
            */
            top: {
                get: function() {
                    return Math.round(this.getBoundingClientRect().top + window.getScrollTop());
                },
                set: function(pixelsTop) {
                    this.setXY(null, pixelsTop, null, true);
                }
            },

           /**
            * Gets or set the width of the element in pixels. Included are padding and border, not any margins.
            *
            * The getter is calculating through `offsetHeight`, the setter will set inline css-style for the width.
            *
            * Values are numbers without unity.
            *
            * @property width
            * @type {Number}
            * @since 0.0.1
            */
            width: {
                get: function() {
                    return this.offsetWidth;
                },
                set: function(val) {
                    var instance = this,
                        dif;
                    instance.setClass(INVISIBLE);
                    instance.setInlineStyle(WIDTH, val + PX);
                    dif = (instance.offsetWidth-val);
                    (dif!==0) && (instance.setInlineStyle(WIDTH, (val - dif) + PX));
                    instance.removeClass(INVISIBLE);
                }
            }

        });

    }(window.Element.prototype));


    (function(HTMLButtonElementPrototype) {
        /**
         * Disables the button
         *
         * @for HTMLButtonElement
         * @method disable
         * @chainable
        */
        HTMLButtonElementPrototype.disable = function() {
            var instance = this;
            instance.setAttr('disabled', 'true');
            return instance;
        };

        /**
         * Enables the button
         *
         * @method enable
         * @chainable
        */
        HTMLButtonElementPrototype.enable = function() {
            var instance = this;
            instance.removeAttr('disabled');
            return instance;
        };

        /**
         * Toggles the `disabled`-state of the button
         *
         * @method toggle
         * @param [forcedState] {boolean} to force a specific state
         * @chainable
        */
        HTMLButtonElementPrototype.toggle = function(forcedState) {
            var instance = this;
            instance.toggleAttr('disabled', 'true', forcedState);
            return instance;
        };
    }(window.HTMLButtonElement.prototype));


    (function(HTMLInputElementPrototype) {
        /**
         * Shows the pop-up of an `input` element of the type `file`.
         *
         * @for HTMLInputElement
         * @method showFileSelect
         * @chainable
        */
        HTMLInputElementPrototype.showFileSelect = function() {
            var instance = this,
                type = instance.getAttr('type');
            type && (type.toLowerCase()==='file') && instance.click();
            return instance;
        };

        /**
         * Hides the pop-up and empties the files-list of an `input` element of the type `file`.
         *
         * @method resetFileSelect
         * @chainable
        */
        HTMLInputElementPrototype.resetFileSelect = function() {
            var instance = this,
                type = instance.getAttr('type');
            if (type && (type.toLowerCase()==='file')) {
                // force the fileselector-popup up to disappear and become empty:
                instance.setAttr('type', 'text');
                instance.value = '';
                instance.setAttr('type', 'file');
            }
            return instance;
        };
    }(window.HTMLInputElement.prototype));


    // Modify SVGElement:
    (function(SVGlementPrototype) {

        Object.defineProperties(SVGlementPrototype, {

           /**
            * Gets or set the height of the element in pixels. Included are padding and border, not any margins.
            *
            * The getter is calculating through `offsetHeight`, the setter will set inline css-style for the height.
            *
            * Values are numbers without unity.
            *
            * @property svgHeight
            * @for SVGElement
            * @type {Number}
            * @since 0.0.1
            */
            svgHeight: {
                get: function() {
                    return parseInt(this.getStyle('height'), 10) || 0;
                },
                set: function(val) {
                    var instance = this,
                        dif;
                    instance.setClass(INVISIBLE);
                    instance.setInlineStyle(HEIGHT, val + PX);
                    dif = (instance.svgHeight-val);
                    (dif!==0) && (instance.setInlineStyle(HEIGHT, (val - dif) + PX));
                    instance.removeClass(INVISIBLE);
                }
            },

           /**
            * Gets or set the innerHeight of the element in pixels. Excluded the borders.
            * Included are padding.
            *
            * The getter is calculating through `offsetHeight`, the setter will set inline css-style for the height.
            *
            * Values are numbers without unity.
            *
            * @property innerHeight
            * @type {Number}
            * @since 0.0.1
            */
            innerHeight: {
                get: function() {
                    var instance = this,
                        borderTop = parseInt(instance.getStyle('border-top-width'), 10) || 0,
                        borderBottom = parseInt(instance.getStyle('border-bottom-width'), 10) || 0;
                    return instance.svgHeight - borderTop - borderBottom;
                },
                set: function(val) {
                    var instance = this,
                        borderTop = parseInt(instance.getStyle('border-top-width'), 10) || 0,
                        borderBottom = parseInt(instance.getStyle('border-bottom-width'), 10) || 0;
                    instance.svgHeight = val + borderTop + borderBottom;
                }
            },

           /**
            * Gets or set the innerHeight of the element in pixels. Excluded the borders.
            * Included are padding.
            *
            * The getter is calculating through `offsetHeight`, the setter will set inline css-style for the height.
            *
            * Values are numbers without unity.
            *
            * @property innerWidth
            * @type {Number}
            * @since 0.0.1
            */
            innerWidth: {
                get: function() {
                    var instance = this,
                        borderLeft = parseInt(instance.getStyle('border-left-width'), 10) || 0,
                        borderRight = parseInt(instance.getStyle('border-right-width'), 10) || 0;
                    return instance.svgWidth - borderLeft - borderRight;
                },
                set: function(val) {
                    var instance = this,
                        borderLeft = parseInt(instance.getStyle('border-left-width'), 10) || 0,
                        borderRight = parseInt(instance.getStyle('border-right-width'), 10) || 0;
                    instance.svgWidth = val + borderLeft + borderRight;
                }
            },

           /**
            * Gets or set the width of the element in pixels. Included are padding and border, not any margins.
            *
            * The getter is calculating through `offsetHeight`, the setter will set inline css-style for the width.
            *
            * Values are numbers without unity.
            *
            * @property svgWidth
            * @type {Number}
            * @since 0.0.1
            */
            svgWidth: {
                get: function() {
                    return parseInt(this.getStyle('width'), 10) || 0;
                },
                set: function(val) {
                    var instance = this,
                        dif;
                    instance.setClass(INVISIBLE);
                    instance.setInlineStyle(WIDTH, val + PX);
                    dif = (instance.svgWidth-val);
                    (dif!==0) && (instance.setInlineStyle(WIDTH, (val - dif) + PX));
                    instance.removeClass(INVISIBLE);
                }
            }

        });

    }(window.SVGElement.prototype));

    setupObserver = function() {
        // configuration of the observer:
        var observerConfig = {
                attributes: true,
                subtree: true,
                characterData: true,
                childList : true
            };
        if (mutationsAreObserved) {
            return;
        }
        (new window.MutationObserver(function(mutations) {
            mutations.forEach(function(mutation) {
                var node = mutation.target,
                    vnode = node.vnode,
                    type = mutation.type,
                    attribute = mutation.attributeName,
                    addedChildNodes = mutation.addedNodes,
                    removedChildNodes = mutation.removedNodes,
                    i, len, childDomNode, childVNode, index, vchildnode;
                if (vnode && !vnode._nosync) {
                    if (type==='attributes') {
                        vnode.reloadAttr(attribute);
                    }
                    else if (type==='characterData') {
                        vnode.text = node.nodeValue;
                    }
                    else {
                        // remove the childNodes that are no longer there,
                        // but ONLY when they are not in the dom --> nodes might get
                        // replaced inside other nodes, which leads into 'remove'-observer,
                        // yet we still need them
                        len = removedChildNodes.length;
                        for (i=len-1; i>=0; i--) {
                            childDomNode = removedChildNodes[i];
                            childVNode = childDomNode.vnode;
                            // need to cheack with native `_contains` --> the vdom its `contains` won't work for it isn't updated yet:
                            childVNode && !DOCUMENT.documentElement._contains(childDomNode) && childVNode._destroy();
                        }
                        // add the new childNodes:
                        len = addedChildNodes.length;
                        for (i=0; i<len; i++) {
                            childDomNode = addedChildNodes[i];
                            // find its index in the true DOM:
                            index = node.childNodes.indexOf(childDomNode);
                            // create the vnode:
                            vchildnode = domNodeToVNode(childDomNode);
                            // add the vnode:
                            vchildnode._moveToParent(vnode, index);
                        }
                    }
                }
            });
        })).observe(DOCUMENT, observerConfig);
        mutationsAreObserved = true;
    };


    // Decided NOT to use MutationObserver by default. It would lead to undeeded ballast.
    // It would be needed when developers manipulate the dom other than through this module,
    // but because it is strongly advisable not to

    /**
     * Activates MutationObserver: only needed when manipulating dom-elements by other means than through
     * this framework. It causes the vdom to be correctly being updated.
     *
     * Only works for modern browsers and >IE10
     *
     * @method setupMutationObserver
     * @for document
     * @since 0.0.5
     */
    window.document.setupMutationObserver = function() {
        // only if mutationobserver exists natively, we use it
        // 'setupObserver' is only needed to register domchanges that are not done through the library
        // any IE-polyfill will fail, because IE9 has a bug to register childnodes for the first time
        // and polyfills that use polling will interfer wrongly with the library's MVC (plugins and itags)
        // So.... IE9 and IE10 are doomed again. But not when dom-manipulation is done by this library.
        window.MutationObserver && setupObserver();
    };

};

//--- definition API of unmodified `Element`-methods ------

/**
 * Returns the specified attribute of the specified element, as an Attr node.
 *
 * @method getAttributeNode
 * @return {attributeNode}
 */

/**
 * Returns a text rectangle object that encloses a group of text rectangles. The returned value is
 * a TextRectangle object which is the union of the rectangles returned by getClientRects() for the element,
 * i.e., the CSS border-boxes associated with the element.
 *
 * The returned value is a TextRectangle object, which contains read-only left, top, right and bottom properties
 * describing the border-box in pixels. top and left are relative to the top-left of the viewport.
 *
 * @method getBoundingClientRect
 * @return {attributeNode} Therectangle object that encloses a group of text rectangles.
 */

/**
 * Returns a collection of rectangles that indicate the bounding rectangles for each box in a client.
 *
 * The returned value is a collection of ClientRect objects, one for each CSS border box associated with the element.
 * Each ClientRect object contains read-only left, top, right and bottom properties describing the border box, in pixels,
 * with the top-left relative to the top-left of the viewport. For tables with captions,
 * the caption is included even though it's outside the border box of the table.
 *
 * @method getClientRects
 * @return {Collection}
 */

/**
 * Returns a new NodeIterator object with this Element as root.
 *
 * The NodeIterator is a snapshot of the dom at the time this method was called. It is not updated when changes of the dom are made afterwards.
 *
 * @method createNodeIterator
 * @param [whatToShow] {Number} Filter specification constants from the NodeFilter DOM interface, indicating which nodes to iterate over.
 * You can use or sum one of the next properties:
 * <ul>
 *   <li>window.NodeFilter.SHOW_ELEMENT</li>
 *   <li>window.NodeFilter.SHOW_COMMENT</li>
 *   <li>window.NodeFilter.SHOW_TEXT</li>
 * </ul>
 * @param [filter] {NodeFilter|function} An object implementing the NodeFilter interface or a function. See https://developer.mozilla.org/en-US/docs/Web/API/NodeFilter
 * @return {NodeIterator}
 * @since 0.0.1
*/

/**
 * Returns an HTMLCollection of all Elements within this Element, that match their classes with the supplied `classNames` argument.
 * To match multiple different classes, separate them with a `comma`.
 *
 * getElementsByClassName is life presentation of the dom. The returned HTMLCollection gets updated when the dom changes.
 *
 * NOTE: it is highly recomended to use `document.getAll` because that method takes advantage of the vdom.
 *
 * @method getElementsByClassName
 * @param classNames {String} the classes to search for
 * @return {HTMLCollection} life Array with Elements
 */

/**
 * Returns an HTMLCollection of all Elements within this Element, that match their `name`-attribute with the supplied `name` argument.
 *
 * getElementsByName is life presentation of the dom. The returned HTMLCollection gets updated when the dom changes.
 *
 * NOTE: it is highly recomended to use `document.getAll` because that method takes advantage of the vdom.
 *
 * @method getElementsByName
 * @param name {String} the property of name-attribute to search for
 * @return {HTMLCollection} life Array with Elements
 */


/**
 * Returns an HTMLCollection of all Elements within this Element, that match their `name`-attribute with the supplied `name` argument.
 *
 * getElementsByTagName is life presentation of the dom. The returned HTMLCollection gets updated when the dom changes.
 *
 * NOTE: it is highly recomended to use `document.getAll` because that method takes advantage of the vdom.
 *
 * @method getElementsByTagName
 * @param tagNames {String} the tags to search for
 * @return {HTMLCollection} life Array with Elements
 */

/**
* Parses the specified text as HTML and inserts the resulting nodes into the DOM tree at a specified position.
*
* @method insertAdjacentHTML
* @param position {String}
* <ul>
*     <li>'beforebegin' Before the element itself</li>
*     <li>'afterbegin' Just inside the element, before its first child</li>
*     <li>'beforeend' Just inside the element, after its last child</li>
*     <li>'afterend' After the element itself</li>
* <ul>
* @param element {Element}
*/

/**
* Removes the attribute specified by an attributeNode from the Element.
*
* @method removeAttributeNode
* @param attributeNode {attributeNode}
* @since 0.0.1
*/

/**
 * Scrolls the element into view.
 *
 * @method scrollIntoView
 */

/**
 * Sets the attribute on the Element specified by `attributeNode`
 *
 * @method setAttributeNode
 * @param attributeNode {attributeNode}
*/

//------ events --------

/**
 * Fired when a static `script` element  finishes executing its script. Does not fire if the element is added dynamically, eg with appendChild().
 *
 * @event afterscriptexecute
 */


/**
 * Fired when the code in a `script` element declared in an HTML document is about to start executing. Does not fire if the element is added dynamically, eg with appendChild().
 *
 * @event beforescriptexecute
 */

//------- properties --------

/**
 * sets or returns an accesskey for an element. An accesskey specifies a shortcut key to activate/focus an element.
 * Note: The way of accessing the shortcut key is varying in different browsers: http://www.w3schools.com/jsref/prop_html_accesskey.asp
 *
 * @property accessKey
 * @type String
 */


/**
 * Returns a live collection of all attribute nodes registered to the specified node.
 * It is a NamedNodeMap, not an Array, so it has no Array methods and the Attr nodes' indexes may differ among browsers.
 * To be more specific, attributes is a key/value pair of strings that represents any information regarding that attribute.
 *
 * Prefer to use `getAttrs()` which is much quicker, but doesn't return a life-list.
 *
 * @property attributes
 * @type NamedNodeMap
 */

/**
 * The absolute base URL of a node.
 *
 * @property baseURI
 * @type String
 * @readOnly
 */

/**
 * Returns the number of children (child Elements)
 *
 * @property childElementCount
 * @type Number
 * @readOnly
 */

/**
 * Returns a live collection of childNodes of the given element, either Element, TextNode or CommentNode
 *
 * @property childNodes
 * @type NodeList
 * @readOnly
 */

/**
 * Returns a live collection of child Element's of the given element.
 *
 * @property children
 * @type NodeList
 * @readOnly
 */

/**
 * Gets and sets the value of the class attribute of the specified element.
 *
 * @property className
 * @type String
 */

/**
 * Returns the inner height of an element in pixels, including padding but not the horizontal scrollbar height, border, or margin.
 *
 * @property clientHeight
 * @type Number
 * @readOnly
 */

/**
 * The width of the left border of an element in pixels. It includes the width of the vertical scrollbar if the text direction of the element is right–to–left
 * and if there is an overflow causing a left vertical scrollbar to be rendered. clientLeft does not include the left margin or the left padding.
 *
 * @property clientLeft
 * @type Number
 * @readOnly
 */

/**
 * The width of the top border of an element in pixels. It does not include the top margin or padding.
 *
 * @property clientTop
 * @type Number
 * @readOnly
 */

/**
 * Returns the inner width of an element in pixels, including padding but not the vertical scrollbar height, border, or margin.
 *
 * @property clientWidth
 * @type Number
 * @readOnly
 */

/**
 * Reference to the first childNode, where the related dom-node is either an Element, TextNode or CommentNode (nodeType===1, 3 or 8).
 *
 * Better work with Elements only:  use `firstElementChild` instead, which returns the first Element-child.
 *
 * @property firstChild
 * @type Node
 * @readOnly
 * @deprecated
 */

/**
 * Reference to the first Element-child, which is an Element (nodeType===1).
 *
 * @property firstElementChild
 * @type Element
 * @readOnly
 */

/**
 * Gets or sets the element's attribute `href`. Only applies for the `a`-element.
 *
 * @property href
 * @type String
 */

/**
 * Gets or sets the element's identifier (attribute id).
 *
 * @property id
 * @type String
 */

/**
 * Reference to the last childNode, where the related dom-node is either an Element, TextNode or CommentNode (nodeType===1, 3 or 8).
 *
 * Better use `lastElementChild` instead, which returns the last Element-child.
 *
 * @property lastChild
 * @type Node
 * @readOnly
 * @deprecated
 */

/**
 * Reference to the last Element-child, where the related dom-node is an Element (nodeType===1).
 *
 * @property lastElementChild
 * @type Element
 * @readOnly
 */

/**
 * Gets or sets the `name` property of a Element; it only applies to the following elements:
 * `a`, `applet`, `button`, `form`, `frame`, `iframe`, `img`, `input`, `map`, `meta`, `object`, `param`, `select`, and `textarea`.
 *
 * @property name
 * @type String
 */

/**
 * Returns the Element immediately following the specified one in its parent's childNodes list, or null if the specified node is the last node in that list.
 * Is an Element (nodeType===1).
 *
 * @property nextElementSibling
 * @type Element
 * @readOnly
 */

/**
 * Returns the Element immediately following the specified one in its parent's childNodes list, or null if the specified node is the last node in that list.
 * Is either an Element, TextNode or CommentNode (nodeType===1, 3 or 8).
 *
 * Do not use this, but use `lastElementChild` instead, which returns the next Element-child.
 *
 * @property nextElementSibling
 * @type Node
 * @deprecated
 * @readOnly
 */

/**
 * Elements tag-name
 *
 * @property nodeName
 * @type String
 * @readOnly
 */

/**
 * Elements nodetype: 1==Element, 3==TextNode, 8===CommentNode
 *
 * @property nodeType
 * @type String
 * @readOnly
 */

/**
 * Value/text for non-Element Nodes
 *
 * @property nodeValue
 * @type String
 * @since 0.0.1
 */

/**
 * The exact width of the Element on the screen.
 * Included borders and padding (no margin).
 *
 * Returns a number without unity.
 *
 * Better use `width` --> it's an alias, but has a setter as well
 *
 * @property offsetWidth
 * @type Number
 * @readOnly
 * @since 0.0.1
 */

/**
 * The exact height of the Element on the screen.
 * Included borders and padding (no margin).
 *
 * Returns a number without unity.
 *
 * Better use `height` --> it's an alias, but has a setter as well
 *
 * @property offsetHeight
 * @type Number
 * @since 0.0.1
 */

/**
 * Returns the Element's parent Element.
 *
 * Same as `parentNode`
 *
 * @property parentElement
 * @type Element
 */

/**
 * Returns the Element's parent Element.
 *
 * Same as `parentElement`
 *
 * @property parentNode
 * @type Element
 */

/**
 * Returns the Element immediately preceding the specified one in its parent's childNodes list, or null if the specified node is the last node in that list.
 * Is an Element (nodeType===1).
 *
 * @property previousElementSibling
 * @type Element
 * @readOnly
 */

/**
 * Returns the Element immediately preceding the specified one in its parent's childNodes list, or null if the specified node is the last node in that list.
 * Is either an Element, TextNode or CommentNode (nodeType===1, 3 or 8).
 *
 * Do not use this, but use `previousElementSibling` instead, which returns the previous Element-child.
 *
 * @property previousSibling
 * @deprecated
 * @type Node
 * @readOnly
 */


/**
 * A measurement of the height of an element's content, including content not visible on the screen due to overflow.
 * The scrollHeight value is equal to the minimum clientHeight the element would require in order to fit all the content in the viewpoint
 * without using a vertical scrollbar. It includes the element padding but not its margin.
 *
 * Returns a number without unity.
 *
 * @property scrollHeight
 * @type Number
 * @readOnly
 */

/**
 * Gets or sets the number of pixels that an element's content is scrolled to the left.
 *
 * @property scrollLeft
 * @type Number
 */

/**
 * Gets or sets the number of pixels that the content of an element is scrolled upward. An element's scrollTop is a measurement
 * of the distance of an element's top to its topmost visible content. When an element content does not generate a vertical scrollbar,
 * then its scrollTop value defaults to 0.
 *
 * @property scrollTop
 * @type Number
 */

/**
 * Returns either the width in pixels of the content of an element or the width of the element itself, whichever is greater.
 * If the element is wider than its content area (for example, if there are scroll bars for scrolling through the content),
 * the scrollWidth is larger than the clientWidth.
 *
 * Returns a number without unity.
 *
 * @property scrollWidth
 * @type Number
 * @readOnly
 */

/**
 * Gets or sets the element's attribute `type`. Only applies for the `script`, `img` and `style`-elements.
 *
 * @property src
 * @type String
 */

/**
 * Gets or sets the element's attribute `style`.
 *
 * @property style
 * @type String
 */

/**
 * Gets or sets the element's attribute `type`. Only applies for the `input`-element.
 *
 * @property type
 * @type String
 */

/**
* Gets or sets the value of an input or select Element.
*
* Note it is highly preferable to use getValue() and setValue().
*
* @property value
* @type String
* @since 0.0.1
*/