real.js
function Real(options) {
    options = options || {}
    var optimiseOpt = options.optimise || {}
    var precompile = optimiseOpt.precompile
    var compileCache = optimiseOpt.compileCache

    var vm = this
    var NS = conf.namespace
    var _ready = options.ready
    var _created = options.created
    var _destroy = options.destroy
    var _binding
    if (compileCache) {
        _binding = compileCache.hasBinding
    } else {
        _binding = util.hasOwn(options, 'binding') ? options.binding : true
        if (precompile) {
            precompile.hasBinding = _binding
        }
    }
    var _message
    if (!optimiseOpt.noMessage) {
        _message = this._message = new Message()
    }

    this.$id = _cid ++
    this.$name = options.name || ''
    this.$parent = options.parent || null
    this.$binding = !!_binding
    this.$shouldUpdate = options.shouldUpdate
    this.$directives = []
    this.$components = []
    this.$watchers = []
    this._$beforeDestroy = function () {
        _safelyCall(conf[CATCH_KEY], _destroy, vm)
    }


    var el = options.el
    var hasReplaceOption = util.hasOwn(options, 'replace') 
            ? options.replace
            : false
    /**
     *  Mounted element detect
     *  Convert selector to element
     */
    if (util.type(el) == 'string') {
        var sel = el
        if (supportQuerySelector) {
            el = document.querySelector(sel)
        } else if (/^\./.test(sel)) {
            el = _getElementsByClassName(sel.replace(/^\./, ''))
            el && (el = el[0])
        } else if (/^#/.test(sel)) {
            el = document.getElementById(sel.replace(/^#/, ''))
        } else {
            el = null
        }

        if (!el) return consoler.error('Can\'t resolve element by "' + sel + '"')
    }
    
    /**
     * Container element must be a element or has template option
     */
    var isHTMLElement = is.Element(el)
    var children
    if (isHTMLElement && options.template) {
        /**
         * If el is passed and has template option
         * if without "replace", it will render template to innerHTML,
         * otherwise template rendering to innerHTML and replace the component element with
         * root element of template.
         */
        if (util.hasAttribute(el, NS + 'notemplate') || options.notemplate) {
            // skip render template, using with SSR
        } else if (hasReplaceOption) {
            var child = _fragmentWrap(options.template)
            // for get first Element of the template as root element of the component
            children = _fragmentChildren(child)
            if (!children.length) 
                throw new Error('Component with \'replace\' must has a child element of template.', options.template)
            var nextEl = children[0]
            var parent = el.parentNode
            if (parent) {
                parent.replaceChild(nextEl, el)
            }
            _cloneAttributes(el, nextEl)
            el = nextEl
        } else {
            // el is given then set template as innerHTML for the component
            if (is.Fragment(el)){
                consoler.warn('Container element should\'nt a fragment node when "template" is given. Template:\n', options.template)
            } else {
                el.innerHTML = options.template
            }
        }
    } else if (!el && options.template) {
        if (hasReplaceOption) {
            var frag = _fragmentWrap(options.template)
            // for get first Element of the template as root element of the component
            el = _fragmentChildren(frag)[0]
            if (!el) 
                consoler.warn('Component\'s template should has a child element when using \'replace\' option.', options.template)
        }
        if (!el) {
            el = document.createElement('div')
            el.innerHTML = options.template
        }
    } else if (isHTMLElement) {
        if (hasReplaceOption) {
            children = is.Fragment(el) ? _fragmentChildren(el) : el.children
            var hasChildren = children && children.length
            !hasChildren && consoler.warn('Component\'s container element should has children when "replace" option given.')
            if (hasChildren) {
                var oldel = el
                el = children[0]
                if(oldel.parentNode) 
                    oldel.parentNode.replaceChild(el, oldel)
            }
        }
    } else {
        throw new Error('illegal "el" option.')
    }
    var componentDec = NS + 'component'
    var isReplaced
    var hasChildCompoent
    if (hasReplaceOption 
        && util.hasAttribute(el, componentDec) 
        && _getAttribute(el, componentDec) !== options.name) {
        // not same name policy, and make parentVM anonymous
        isReplaced = true
    } else {
        var cname = _getAttribute(el, componentDec)
        if (cname && cname === this.$name) {
            // prevent instance circularly
            _removeAttribute(el, componentDec)
        } else if (cname) {
            hasChildCompoent = true
        }
        // support multiple cid
        var cidKey = '_' + NS + 'cid'
        var cidValue = _getAttribute(el, cidKey) || ''
        if (cidValue) {
            cidValue += ','+this.$id
        } else {
            cidValue = this.$id
        }
        // expose cid to DOM for debug
        // _setAttribute(el, cidKey, cidValue)
    }

    this.$methods = {}
    this.$refs = {}
    
    // from options.data
    var data = _getData(options.data)
    // prop NS-props
    var props = hasChildCompoent ? null : this._$parseProps(el)
    // from DOM interface
    var _data = _getData(options._data)
    this.$data = util.extend(data, props, _data) 

    if (optimiseOpt.bindMethods === false) {
        this.$methods = options.methods
    } else {
        util.objEach(options.methods, function (key, m) {
            vm.$methods[key] = vm[key] = util.bind(m, vm)
        })
    }
    // created lifecycle
    _safelyCall(conf[CATCH_KEY], _created, vm)
    this.$el = el
    // binding watcher
    try {
        util.objEach(options.watch || {}, function (expr, handler) {
            vm.$watchers.push(new Watcher(vm, expr, handler))
        })
    } catch(e) {
        consoler.error('Watch catch error:', e)
    }
    try {
        var $compiledEl = this.$compile(el, null, precompile, compileCache)
        isReplaced && (this.$el = $compiledEl)
    } finally {

        // ready lifecycle
        try {
            _safelyCall(conf[CATCH_KEY], _ready, vm)
        } finally {
            _message && _message.emit('ready')
        }
    }
}
function Real(options) {
    options = options || {}
    var optimiseOpt = options.optimise || {}
    var precompile = optimiseOpt.precompile
    var compileCache = optimiseOpt.compileCache

    var vm = this
    var NS = conf.namespace
    var _ready = options.ready
    var _created = options.created
    var _destroy = options.destroy
    var _binding
    if (compileCache) {
        _binding = compileCache.hasBinding
    } else {
        _binding = util.hasOwn(options, 'binding') ? options.binding : true
        if (precompile) {
            precompile.hasBinding = _binding
        }
    }
    var _message
    if (!optimiseOpt.noMessage) {
        _message = this._message = new Message()
    }

    this.$id = _cid ++
    this.$name = options.name || ''
    this.$parent = options.parent || null
    this.$binding = !!_binding
    this.$shouldUpdate = options.shouldUpdate
    this.$directives = []
    this.$components = []
    this.$watchers = []
    this._$beforeDestroy = function () {
        _safelyCall(conf[CATCH_KEY], _destroy, vm)
    }


    var el = options.el
    var hasReplaceOption = util.hasOwn(options, 'replace') 
            ? options.replace
            : false
    /**
     *  Mounted element detect
     *  Convert selector to element
     */
    if (util.type(el) == 'string') {
        var sel = el
        if (supportQuerySelector) {
            el = document.querySelector(sel)
        } else if (/^\./.test(sel)) {
            el = _getElementsByClassName(sel.replace(/^\./, ''))
            el && (el = el[0])
        } else if (/^#/.test(sel)) {
            el = document.getElementById(sel.replace(/^#/, ''))
        } else {
            el = null
        }

        if (!el) return consoler.error('Can\'t resolve element by "' + sel + '"')
    }
    
    /**
     * Container element must be a element or has template option
     */
    var isHTMLElement = is.Element(el)
    var children
    if (isHTMLElement && options.template) {
        /**
         * If el is passed and has template option
         * if without "replace", it will render template to innerHTML,
         * otherwise template rendering to innerHTML and replace the component element with
         * root element of template.
         */
        if (util.hasAttribute(el, NS + 'notemplate') || options.notemplate) {
            // skip render template, using with SSR
        } else if (hasReplaceOption) {
            var child = _fragmentWrap(options.template)
            // for get first Element of the template as root element of the component
            children = _fragmentChildren(child)
            if (!children.length) 
                throw new Error('Component with \'replace\' must has a child element of template.', options.template)
            var nextEl = children[0]
            var parent = el.parentNode
            if (parent) {
                parent.replaceChild(nextEl, el)
            }
            _cloneAttributes(el, nextEl)
            el = nextEl
        } else {
            // el is given then set template as innerHTML for the component
            if (is.Fragment(el)){
                consoler.warn('Container element should\'nt a fragment node when "template" is given. Template:\n', options.template)
            } else {
                el.innerHTML = options.template
            }
        }
    } else if (!el && options.template) {
        if (hasReplaceOption) {
            var frag = _fragmentWrap(options.template)
            // for get first Element of the template as root element of the component
            el = _fragmentChildren(frag)[0]
            if (!el) 
                consoler.warn('Component\'s template should has a child element when using \'replace\' option.', options.template)
        }
        if (!el) {
            el = document.createElement('div')
            el.innerHTML = options.template
        }
    } else if (isHTMLElement) {
        if (hasReplaceOption) {
            children = is.Fragment(el) ? _fragmentChildren(el) : el.children
            var hasChildren = children && children.length
            !hasChildren && consoler.warn('Component\'s container element should has children when "replace" option given.')
            if (hasChildren) {
                var oldel = el
                el = children[0]
                if(oldel.parentNode) 
                    oldel.parentNode.replaceChild(el, oldel)
            }
        }
    } else {
        throw new Error('illegal "el" option.')
    }
    var componentDec = NS + 'component'
    var isReplaced
    var hasChildCompoent
    if (hasReplaceOption 
        && util.hasAttribute(el, componentDec) 
        && _getAttribute(el, componentDec) !== options.name) {
        // not same name policy, and make parentVM anonymous
        isReplaced = true
    } else {
        var cname = _getAttribute(el, componentDec)
        if (cname && cname === this.$name) {
            // prevent instance circularly
            _removeAttribute(el, componentDec)
        } else if (cname) {
            hasChildCompoent = true
        }
        // support multiple cid
        var cidKey = '_' + NS + 'cid'
        var cidValue = _getAttribute(el, cidKey) || ''
        if (cidValue) {
            cidValue += ','+this.$id
        } else {
            cidValue = this.$id
        }
        // expose cid to DOM for debug
        // _setAttribute(el, cidKey, cidValue)
    }

    this.$methods = {}
    this.$refs = {}
    
    // from options.data
    var data = _getData(options.data)
    // prop NS-props
    var props = hasChildCompoent ? null : this._$parseProps(el)
    // from DOM interface
    var _data = _getData(options._data)
    this.$data = util.extend(data, props, _data) 

    if (optimiseOpt.bindMethods === false) {
        this.$methods = options.methods
    } else {
        util.objEach(options.methods, function (key, m) {
            vm.$methods[key] = vm[key] = util.bind(m, vm)
        })
    }
    // created lifecycle
    _safelyCall(conf[CATCH_KEY], _created, vm)
    this.$el = el
    // binding watcher
    try {
        util.objEach(options.watch || {}, function (expr, handler) {
            vm.$watchers.push(new Watcher(vm, expr, handler))
        })
    } catch(e) {
        consoler.error('Watch catch error:', e)
    }
    try {
        var $compiledEl = this.$compile(el, null, precompile, compileCache)
        isReplaced && (this.$el = $compiledEl)
    } finally {

        // ready lifecycle
        try {
            _safelyCall(conf[CATCH_KEY], _ready, vm)
        } finally {
            _message && _message.emit('ready')
        }
    }
}
function Real ( options ) { options = options || { } var optimiseOpt = options . optimise || { } var precompile = optimiseOpt . precompile var compileCache = optimiseOpt . compileCache var vm = this var NS = conf . namespace var _ready = options . ready var _created = options . created var _destroy = options . destroy var _binding if ( compileCache ) { _binding = compileCache . hasBinding } else { _binding = util . hasOwn ( options , 'binding' ) ? options . binding : true if ( precompile ) { precompile . hasBinding = _binding } } var _message if ( ! optimiseOpt . noMessage ) { _message = this . _message = new Message ( ) } this . $id = _cid ++ this . $name = options . name || '' this . $parent = options . parent || null this . $binding = ! ! _binding this . $shouldUpdate = options . shouldUpdate this . $directives = [ ] this . $components = [ ] this . $watchers = [ ] this . _$beforeDestroy = function ( ) { _safelyCall ( conf [ CATCH_KEY ] , _destroy , vm ) } var el = options . el var hasReplaceOption = util . hasOwn ( options , 'replace' ) ? options . replace : false /**
     *  Mounted element detect
     *  Convert selector to element
     */ if ( util . type ( el ) == 'string' ) { var sel = el if ( supportQuerySelector ) { el = document . querySelector ( sel ) } else if ( / ^\. / . test ( sel ) ) { el = _getElementsByClassName ( sel . replace ( / ^\. / , '' ) ) el && ( el = el [ 0 ] ) } else if ( / ^# / . test ( sel ) ) { el = document . getElementById ( sel . replace ( / ^# / , '' ) ) } else { el = null } if ( ! el ) return consoler . error ( 'Can\'t resolve element by "' + sel + '"' ) } /**
     * Container element must be a element or has template option
     */ var isHTMLElement = is . Element ( el ) var children if ( isHTMLElement && options . template ) { /**
         * If el is passed and has template option
         * if without "replace", it will render template to innerHTML,
         * otherwise template rendering to innerHTML and replace the component element with
         * root element of template.
         */ if ( util . hasAttribute ( el , NS + 'notemplate' ) || options . notemplate ) { // skip render template, using with SSR } else if ( hasReplaceOption ) { var child = _fragmentWrap ( options . template ) // for get first Element of the template as root element of the component children = _fragmentChildren ( child ) if ( ! children . length ) throw new Error ( 'Component with \'replace\' must has a child element of template.' , options . template ) var nextEl = children [ 0 ] var parent = el . parentNode if ( parent ) { parent . replaceChild ( nextEl , el ) } _cloneAttributes ( el , nextEl ) el = nextEl } else { // el is given then set template as innerHTML for the component if ( is . Fragment ( el ) ) { consoler . warn ( 'Container element should\'nt a fragment node when "template" is given. Template:\n' , options . template ) } else { el . innerHTML = options . template } } } else if ( ! el && options . template ) { if ( hasReplaceOption ) { var frag = _fragmentWrap ( options . template ) // for get first Element of the template as root element of the component el = _fragmentChildren ( frag ) [ 0 ] if ( ! el ) consoler . warn ( 'Component\'s template should has a child element when using \'replace\' option.' , options . template ) } if ( ! el ) { el = document . createElement ( 'div' ) el . innerHTML = options . template } } else if ( isHTMLElement ) { if ( hasReplaceOption ) { children = is . Fragment ( el ) ? _fragmentChildren ( el ) : el . children var hasChildren = children && children . length ! hasChildren && consoler . warn ( 'Component\'s container element should has children when "replace" option given.' ) if ( hasChildren ) { var oldel = el el = children [ 0 ] if ( oldel . parentNode ) oldel . parentNode . replaceChild ( el , oldel ) } } } else { throw new Error ( 'illegal "el" option.' ) } var componentDec = NS + 'component' var isReplaced var hasChildCompoent if ( hasReplaceOption && util . hasAttribute ( el , componentDec ) && _getAttribute ( el , componentDec ) !== options . name ) { // not same name policy, and make parentVM anonymous isReplaced = true } else { var cname = _getAttribute ( el , componentDec ) if ( cname && cname === this . $name ) { // prevent instance circularly _removeAttribute ( el , componentDec ) } else if ( cname ) { hasChildCompoent = true } // support multiple cid var cidKey = '_' + NS + 'cid' var cidValue = _getAttribute ( el , cidKey ) || '' if ( cidValue ) { cidValue += ',' + this . $id } else { cidValue = this . $id } // expose cid to DOM for debug // _setAttribute(el, cidKey, cidValue) } this . $methods = { } this . $refs = { } // from options.data var data = _getData ( options . data ) // prop NS-props var props = hasChildCompoent ? null : this . _$parseProps ( el ) // from DOM interface var _data = _getData ( options . _data ) this . $data = util . extend ( data , props , _data ) if ( optimiseOpt . bindMethods === false ) { this . $methods = options . methods } else { util . objEach ( options . methods , function ( key , m ) { vm . $methods [ key ] = vm [ key ] = util . bind ( m , vm ) } ) } // created lifecycle _safelyCall ( conf [ CATCH_KEY ] , _created , vm ) this . $el = el // binding watcher try { util . objEach ( options . watch || { } , function ( expr , handler ) { vm . $watchers . push ( new Watcher ( vm , expr , handler ) ) } ) } catch ( e ) { consoler . error ( 'Watch catch error:' , e ) } try { var $compiledEl = this . $compile ( el , null , precompile , compileCache ) isReplaced && ( this . $el = $compiledEl ) } finally { // ready lifecycle try { _safelyCall ( conf [ CATCH_KEY ] , _ready , vm ) } finally { _message && _message . emit ( 'ready' ) } } }
Constructor Function and Class.
@param {Object} options Instance options
@return {Object} Real component instance
Constructor Function and Class .