var _ = require('../util') var transition = require('../transition') /** * Append instance to target * * @param {Node} target * @param {Function} [cb] * @param {Boolean} [withTransition] - defaults to true */ exports.$appendTo = function (target, cb, withTransition) { return insert( this, target, cb, withTransition, append, transition.append ) } /** * Prepend instance to target * * @param {Node} target * @param {Function} [cb] * @param {Boolean} [withTransition] - defaults to true */ exports.$prependTo = function (target, cb, withTransition) { target = query(target) if (target.hasChildNodes()) { this.$before(target.firstChild, cb, withTransition) } else { this.$appendTo(target, cb, withTransition) } return this } /** * Insert instance before target * * @param {Node} target * @param {Function} [cb] * @param {Boolean} [withTransition] - defaults to true */ exports.$before = function (target, cb, withTransition) { return insert( this, target, cb, withTransition, before, transition.before ) } /** * Insert instance after target * * @param {Node} target * @param {Function} [cb] * @param {Boolean} [withTransition] - defaults to true */ exports.$after = function (target, cb, withTransition) { target = query(target) if (target.nextSibling) { this.$before(target.nextSibling, cb, withTransition) } else { this.$appendTo(target.parentNode, cb, withTransition) } return this } /** * Remove instance from DOM * * @param {Function} [cb] * @param {Boolean} [withTransition] - defaults to true */ exports.$remove = function (cb, withTransition) { var inDoc = this._isAttached && _.inDoc(this.$el) // if we are not in document, no need to check // for transitions if (!inDoc) withTransition = false var op var self = this var realCb = function () { if (inDoc) self._callHook('detached') if (cb) cb() } if ( this._isBlock && !this._blockFragment.hasChildNodes() ) { op = withTransition === false ? append : transition.removeThenAppend blockOp(this, this._blockFragment, op, realCb) } else { op = withTransition === false ? remove : transition.remove op(this.$el, this, realCb) } return this } /** * Shared DOM insertion function. * * @param {Vue} vm * @param {Element} target * @param {Function} [cb] * @param {Boolean} [withTransition] * @param {Function} op1 - op for non-transition insert * @param {Function} op2 - op for transition insert * @return vm */ function insert (vm, target, cb, withTransition, op1, op2) { target = query(target) var targetIsDetached = !_.inDoc(target) var op = withTransition === false || targetIsDetached ? op1 : op2 var shouldCallHook = !targetIsDetached && !vm._isAttached && !_.inDoc(vm.$el) if (vm._isBlock) { blockOp(vm, target, op, cb) } else { op(vm.$el, target, vm, cb) } if (shouldCallHook) { vm._callHook('attached') } return vm } /** * Execute a transition operation on a block instance, * iterating through all its block nodes. * * @param {Vue} vm * @param {Node} target * @param {Function} op * @param {Function} cb */ function blockOp (vm, target, op, cb) { var current = vm._blockStart var end = vm._blockEnd var next while (next !== end) { next = current.nextSibling op(current, target, vm) current = next } op(end, target, vm, cb) } /** * Check for selectors * * @param {String|Element} el */ function query (el) { return typeof el === 'string' ? document.querySelector(el) : el } /** * Append operation that takes a callback. * * @param {Node} el * @param {Node} target * @param {Vue} vm - unused * @param {Function} [cb] */ function append (el, target, vm, cb) { target.appendChild(el) if (cb) cb() } /** * InsertBefore operation that takes a callback. * * @param {Node} el * @param {Node} target * @param {Vue} vm - unused * @param {Function} [cb] */ function before (el, target, vm, cb) { _.before(el, target) if (cb) cb() } /** * Remove operation that takes a callback. * * @param {Node} el * @param {Vue} vm - unused * @param {Function} [cb] */ function remove (el, vm, cb) { _.remove(el) if (cb) cb() }