var _ = require('./index') var config = require('../config') /** * Query an element selector if it's not an element already. * * @param {String|Element} el * @return {Element} */ exports.query = function (el) { if (typeof el === 'string') { var selector = el el = document.querySelector(el) if (!el) { process.env.NODE_ENV !== 'production' && _.warn( 'Cannot find element: ' + selector ) } } return el } /** * Check if a node is in the document. * Note: document.documentElement.contains should work here * but always returns false for comment nodes in phantomjs, * making unit tests difficult. This is fixed byy doing the * contains() check on the node's parentNode instead of * the node itself. * * @param {Node} node * @return {Boolean} */ exports.inDoc = function (node) { var doc = document.documentElement var parent = node && node.parentNode return doc === node || doc === parent || !!(parent && parent.nodeType === 1 && (doc.contains(parent))) } /** * Extract an attribute from a node. * * @param {Node} node * @param {String} attr */ exports.attr = function (node, attr) { attr = config.prefix + attr var val = node.getAttribute(attr) if (val !== null) { node.removeAttribute(attr) } return val } /** * Insert el before target * * @param {Element} el * @param {Element} target */ exports.before = function (el, target) { target.parentNode.insertBefore(el, target) } /** * Insert el after target * * @param {Element} el * @param {Element} target */ exports.after = function (el, target) { if (target.nextSibling) { exports.before(el, target.nextSibling) } else { target.parentNode.appendChild(el) } } /** * Remove el from DOM * * @param {Element} el */ exports.remove = function (el) { el.parentNode.removeChild(el) } /** * Prepend el to target * * @param {Element} el * @param {Element} target */ exports.prepend = function (el, target) { if (target.firstChild) { exports.before(el, target.firstChild) } else { target.appendChild(el) } } /** * Replace target with el * * @param {Element} target * @param {Element} el */ exports.replace = function (target, el) { var parent = target.parentNode if (parent) { parent.replaceChild(el, target) } } /** * Add event listener shorthand. * * @param {Element} el * @param {String} event * @param {Function} cb */ exports.on = function (el, event, cb) { el.addEventListener(event, cb) } /** * Remove event listener shorthand. * * @param {Element} el * @param {String} event * @param {Function} cb */ exports.off = function (el, event, cb) { el.removeEventListener(event, cb) } /** * Add class with compatibility for IE & SVG * * @param {Element} el * @param {Strong} cls */ exports.addClass = function (el, cls) { if (el.classList) { el.classList.add(cls) } else { var cur = ' ' + (el.getAttribute('class') || '') + ' ' if (cur.indexOf(' ' + cls + ' ') < 0) { el.setAttribute('class', (cur + cls).trim()) } } } /** * Remove class with compatibility for IE & SVG * * @param {Element} el * @param {Strong} cls */ exports.removeClass = function (el, cls) { if (el.classList) { el.classList.remove(cls) } else { var cur = ' ' + (el.getAttribute('class') || '') + ' ' var tar = ' ' + cls + ' ' while (cur.indexOf(tar) >= 0) { cur = cur.replace(tar, ' ') } el.setAttribute('class', cur.trim()) } } /** * Extract raw content inside an element into a temporary * container div * * @param {Element} el * @param {Boolean} asFragment * @return {Element} */ exports.extractContent = function (el, asFragment) { var child var rawContent /* istanbul ignore if */ if ( exports.isTemplate(el) && el.content instanceof DocumentFragment ) { el = el.content } if (el.hasChildNodes()) { trim(el, el.firstChild) trim(el, el.lastChild) rawContent = asFragment ? document.createDocumentFragment() : document.createElement('div') /* eslint-disable no-cond-assign */ while (child = el.firstChild) { /* eslint-enable no-cond-assign */ rawContent.appendChild(child) } } return rawContent } function trim (content, node) { if (node && node.nodeType === 3 && !node.data.trim()) { content.removeChild(node) } } /** * Check if an element is a template tag. * Note if the template appears inside an SVG its tagName * will be in lowercase. * * @param {Element} el */ exports.isTemplate = function (el) { return el.tagName && el.tagName.toLowerCase() === 'template' } /** * Create an "anchor" for performing dom insertion/removals. * This is used in a number of scenarios: * - fragment instance * - v-html * - v-if * - component * - repeat * * @param {String} content * @param {Boolean} persist - IE trashes empty textNodes on * cloneNode(true), so in certain * cases the anchor needs to be * non-empty to be persisted in * templates. * @return {Comment|Text} */ exports.createAnchor = function (content, persist) { return config.debug ? document.createComment(content) : document.createTextNode(persist ? ' ' : '') }