UNPKG

vquery

Version:

A simple, light-weight, vanilla JS wrapper for jQuery-like syntax.

907 lines (869 loc) 26.3 kB
'use strict'; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var V = function () { function V(selector) { var _this = this; var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { methodHistory: [], selectorHistory: [] }; _classCallCheck(this, V); if (!(this instanceof V)) { return new V(selector); } if (selector instanceof V) { return selector; } if (selector && selector.nodeName) { selector = [selector]; if (!this.selector) { this.selector = selector; } } this.version = '5.0.1'; this.methodHistory = context.methodHistory; if (context.selectorHistory.length === 0) { this.selectorHistory = []; this.selectorHistory.push(selector); } else { this.selectorHistory = context.selectorHistory; } // Utility functions this.error = function (msg, selector, method, parameters) { var errMsg = function errMsg(msg) { console.error('vQuery: ' + msg + '\nAcceptable parameters: v(' + selector + ').' + method + '(' + parameters + ')'); }; if (msg === 'undefinedNode') { errMsg('Selector is not a valid node.'); } else if (msg === 'notType') { errMsg('Parameter passed to the ' + method + ' method is not of the type \'' + parameters + '\'.'); } else { errMsg(msg); } }; this.isElement = function (element) { return element instanceof Element || element[0] instanceof Element; }; this.queryElement = function (element) { return _this.isElement(element) ? element : _this.query(document, element)[0]; }; this.queryParameter = function (param, checkNodes) { if (checkNodes) { return _this.nodes ? _this.nodes : _this.nonElement ? _this.nonElement : param; } else { return _this.nonElement ? _this.nonElement : param; } }; this.assignNodes = function (nodes) { _this.nodes = _this.slice(nodes); _this.node = _this.nodes.length > 0 ? _this.nodes[0] : null; }; this.handler = function (data, opts) { // If the selector is updated, start a new instance with the updated selector. var _selector = data ? data : _this.selector ? _this.selector : selector; _this.selectorHistory.push(_selector); _this.methodHistory.push(opts.method); return new V(_selector, { selectorHistory: _this.selectorHistory, methodHistory: _this.methodHistory }); }; this.slice = function (nodeList) { return Array.prototype.slice.call(nodeList); }; // Assign the selector by calling this.query if its an element, otherwise assign it to this.nodes directly. var isStringElement = null; if (selector) { if (this.typeOf(selector) === 'string') { try { isStringElement = selector.match(/<(.|\n)*?>/g)[0]; } catch (e) {} if (isStringElement) { this.nonElement = selector; this.assignNodes(this.parseHTML(selector)); } else { try { this.assignNodes(this.query(document, selector)); } catch (e) { this.nonElement = selector; } } if (!this.node) { this.nonElement = selector; } } else if (isStringElement) { this.nonElement = selector; this.assignNodes(this.parseHTML(selector)); } else { if (this.isElement(selector)) { this.assignNodes(selector); } else { this.nodes = selector; this.node = this.nodes[0]; } } this.length = this.nodes ? this.nodes.length : this.nonElement ? this.nonElement.length : 0; } } _createClass(V, [{ key: 'for', value: function _for(iterator, func) { if (iterator !== undefined) { for (var i = 0, len = iterator.length; i < len; i++) { func.apply(this, [iterator[i], i, arguments]); } } } }, { key: 'forIn', value: function forIn(props, func) { for (var y in props) { func.apply(this, [y, props, arguments]); } } }, { key: 'includes', value: function includes(string, match) { return string.indexOf(match) > -1; } }, { key: 'typeOf', value: function typeOf(input) { return Object.prototype.toString.call(input).replace(/^\[object (.+)\]$/, '$1').toLowerCase(); } }, { key: 'move', value: function move(fromIndex, toIndex) { try { this.nodes = this.nodes.splice(toIndex, 0, this.nodes.splice(fromIndex, 1)[0]); return this.handler(null, { method: 'move' }); } catch (e) { this.error('notType', '', 'move', 'array'); } } }, { key: 'uniq', value: function uniq(array) { var _array = array ? array : this.nonElement ? this.nonElement : this.nodes ? this.nodes : null; var uniq = Array.from(new Set(_array)); if (array) { return uniq; } else { this.selector = uniq; return this.handler(null, { method: 'uniq' }); } } // Turn the CSS selector into a node, pass an existing node to this.nodes, which is used by all methods. }, { key: 'query', value: function query(el, _selector) { return el.querySelectorAll(_selector); } }, { key: 'parseHTML', value: function parseHTML(string) { var tmp = document.implementation.createHTMLDocument(); tmp.body.innerHTML = this.nonElement ? this.nonElement : string; return tmp.body.children; } }, { key: 'mixin', value: function mixin(_mixin) { for (var prop in _mixin) { if (_mixin.hasOwnProperty(prop)) { V.prototype[prop] = _mixin[prop]; } return V.prototype[prop].apply(this, [this.nodes, arguments]); } } }, { key: 'ajax', value: function ajax(type, url, options) { var _this2 = this; var Promise = require('promise-polyfill'); var setAsap = require('setasap'); Promise._setImmediateFn(setAsap); return new Promise(function (resolve, reject) { var _resolve = function _resolve(data) { var _data = options && options.chain ? _this2.handler(data, { method: 'ajax' }) : data; if (typeof _data !== 'undefined' && _data) { resolve(_data); } }; var request = new XMLHttpRequest(); request.open(type, url, true); var data = void 0; if (type.toLowerCase() === 'post') { // Check if options.data is JSON, if not, send as application/x-www-form-urlencoded try { options.data = JSON.stringify(options.data); request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); } catch (e) { request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); } request.send(options.data); } request.onload = function () { if (request.status >= 200 && request.status < 400) { try { data = JSON.parse(request.responseText); } catch (e) { data = request.responseText; } _resolve(data); } else { reject(); } }; if (type.toLowerCase() === 'get') { request.send(); } request.onerror = function (err) { reject(err); }; }); } // v(selector).get(0) -> <div></div> }, { key: 'get', value: function get(i) { this.selector = this.nodes[i]; return this.handler(null, { method: 'get' }); } // Event methods }, { key: 'ready', value: function ready(func) { if (func && func !== undefined && typeof func === 'function') { document.addEventListener('DOMContentLoaded', func); } else { this.error('notType', '', 'ready', 'function'); } } }, { key: 'load', value: function load(func) { if (func && func !== undefined && typeof func === 'function') { document.addEventListener('load', func); } else { this.error('notType', '', 'load', 'function'); } } }, { key: 'on', value: function on(event, func) { this.for(this.nodes, function (i) { i.addEventListener(event, func); }); return this.handler(null, { method: 'on' }); } }, { key: 'off', value: function off(event, func) { this.for(this.nodes, function (i) { i.removeEventListener(event, func); }); return this.handler(null, { method: 'off' }); } }, { key: 'trigger', value: function trigger(event) { if (this.node.fireEvent) { this.node.fireEvent('on' + event); } else { var evObj = document.createEvent('Events'); evObj.initEvent(event, true, false); this.node.dispatchEvent(evObj); } return this.handler(null, { method: 'trigger' }); } }, { key: 'click', value: function click(func) { var _this3 = this; this.for(this.nodes, function (i) { if (func) { _this3.on('click', func); } else { _this3.trigger('click'); } }); return this.handler(null, { method: 'click' }); } // DOM traversal and manipulation methods }, { key: 'filter', value: function filter(func) { Array.prototype.filter.call(this.nodes, func); return this.handler(null, { method: 'filter' }); } }, { key: 'each', value: function each(func) { Array.prototype.forEach.call(this.nodes, func); return this.handler(null, { method: 'each' }); } }, { key: 'map', value: function map(func) { Array.prototype.map.call(this.nodes, func); return this.handler(null, { method: 'map' }); } }, { key: 'find', value: function find(_selector) { var _this4 = this; if (!this.isElement(_selector)) { if (this.includes(_selector, ',')) { (function () { var __selector = _selector.split(','); var newSelector = []; var subset = []; _this4.for(__selector, function (i) { subset = _this4.query(_this4.node, i); _this4.for(subset, function (y) { newSelector.push(y); }); }); _this4.selector = newSelector; })(); } else { this.selector = this.query(this.node, _selector); } } else { this.selector = _selector; } return this.handler(null, { method: 'find' }); } }, { key: 'end', value: function end() { this.selector = this.selectorHistory[0]; return this.handler(null, { method: 'end' }); } }, { key: 'hide', value: function hide() { this.for(this.nodes, function (i) { i.style.display = 'none'; }); return this.handler(null, { method: 'hide' }); } }, { key: 'show', value: function show() { this.for(this.nodes, function (i) { i.style.display = 'block'; }); return this.handler(null, { method: 'show' }); } }, { key: 'remove', value: function remove() { this.for(this.nodes, function (i) { i.parentNode.removeChild(i); }); return this.handler(null, { method: 'remove' }); } }, { key: 'empty', value: function empty() { this.for(this.nodes, function (i) { i.innerHTML = ''; }); return this.handler(null, { method: 'empty' }); } }, { key: 'clone', value: function clone() { var clone = this.node.cloneNode(true); this.selector = clone; return this.handler(null, { method: 'clone' }); } }, { key: 'wrap', value: function wrap(tag) { this.for(this.nodes, function (i) { i.outerHTML = '' + tag.match(/<(.|\n)*?>/g)[0] + i.outerHTML; }); return this.handler(null, { method: 'wrap' }); } }, { key: 'parent', value: function parent() { this.selector = this.node.parentNode; return this.handler(null, { method: 'parent' }); } }, { key: 'parents', value: function parents(el) { var _this5 = this; var parent = this.node.parentNode; var _parents = []; while (parent) { _parents.unshift(parent); parent = parent.parentNode; } if (el) { (function () { var __parents = []; var _parentsQuery = []; _this5.for(_parents, function (i) { __parents = _this5.slice(_this5.query(i, el)); _this5.for(__parents, function (y) { _parentsQuery.push(y); }); }); _this5.selector = _this5.uniq(_parentsQuery); })(); } else { this.selector = _parents; } return this.handler(null, { method: 'parents' }); } }, { key: 'children', value: function children(el) { var _this6 = this; var children = this.slice(this.nodes[0].children); if (el) { (function () { var _children = []; var arr = []; _this6.for(children, function (i) { _children = _this6.slice(_this6.query(i, el)); _this6.for(_children, function (y) { arr.push(_children[y]); }); }); _this6.selector = arr; })(); } else { this.selector = children; } return this.handler(null, { method: 'children' }); } }, { key: 'allChildren', value: function allChildren(_el) { var _this7 = this; var __el = _el ? this.slice(this.query(this.node, _el))[0] : this.node; var arr = []; var recurse = function recurse(el) { arr.push(el); if (el.childNodes.length > 0) { _this7.forIn(el.childNodes, function (child) { if (el.childNodes[child].nodeType == 1) { recurse(el.childNodes[child]); } }); } }; recurse(__el); this.selector = arr; return this.handler(null, { method: 'allChildren' }); } }, { key: 'isEmpty', value: function isEmpty() { return !this.node.hasChildNodes(); } }, { key: 'siblings', value: function siblings() { var _this8 = this; this.nodes = this.node.parentNode.children; return this.filter(function (child) { return child !== _this8.node; }); } }, { key: 'next', value: function next() { this.selector = this.node.nextElementSibling; return this.handler(null, { method: 'next' }); } }, { key: 'prev', value: function prev() { this.selector = this.node.previousElementSibling; return this.handler(null, { method: 'prev' }); } }, { key: 'addClass', value: function addClass(_class) { var _this9 = this; var classArr = _class.split(' '); this.for(this.nodes, function (i) { _this9.for(classArr, function (y) { i.classList.add(y); }); }); return this.handler(null, { method: 'addClass' }); } }, { key: 'removeClass', value: function removeClass(_class) { var _this10 = this; var classArr = _class.split(' '); this.for(this.nodes, function (i) { _this10.for(classArr, function (y) { i.classList.remove(y); }); }); return this.handler(null, { method: 'removeClass' }); } }, { key: 'toggleClass', value: function toggleClass(_class) { var _this11 = this; var classArr = _class.split(' '); this.for(this.nodes, function (i) { _this11.for(classArr, function (y) { i.classList.toggle(y); }); }); return this.handler(null, { method: 'toggleClass' }); } }, { key: 'hasClass', value: function hasClass(_class) { var bool = this.node.classList.contains(_class); return bool; } }, { key: 'removeAttr', value: function removeAttr(attr) { this.for(this.nodes, function (i) { i.removeAttribute(attr); }); return this.handler(null, { method: 'removeAttr' }); } // v(selector).attr() returns an object of camelized attribute keys. // v(selector).attr({dataId: '0'}) -> <div data-id="0"></div> }, { key: 'attr', value: function attr(props, props2) { var _this12 = this; var _return = null; this.for(this.nodes, function (i) { if (props) { if (props2 && _this12.typeOf(props2) === 'string') { i.setAttribute(_this12.decamelize(props), props2); _return = _this12.handler(null, { method: 'attr' }); } else { _this12.forIn(props, function (y) { if (_this12.typeOf(props) === 'string') { _return = i.attributes[props].value; } else { i.setAttribute(_this12.decamelize(y), props[y]); _return = _this12.handler(null, { method: 'attr' }); } }); } } else { var obj = {}; var name = null; var value = null; _this12.for(i.attributes, function (z) { name = _this12.camelize(z.name); value = z.value; obj[name] = value; }); _return = obj; } }); return _return; } // v(selector).css({backgroundColor: '#FFF'}) -> <div style="background-color:#FFF;"></div> }, { key: 'css', value: function css(props) { var _this13 = this; if (props) { this.for(this.nodes, function (i) { _this13.forIn(props, function (y) { i.style[y] = props[y]; }); }); return this.handler(null, { method: 'css' }); } else { if (this.isElement(this.node)) { return getComputedStyle(this.node); } else { return {}; } } } }, { key: 'val', value: function val(string) { if (string) { this.for(this.nodes, function (i) { i.value = string; }); return this.handler(null, { method: 'val' }); } else { return this.node.value; } } }, { key: 'rect', value: function rect() { return this.node.getBoundingClientRect(); } }, { key: 'offset', value: function offset() { var rect = this.rect(); var offset = { top: rect.top + document.body.scrollTop, left: rect.left + document.body.scrollLeft }; return offset; } }, { key: 'offsetParent', value: function offsetParent() { return this.node.offsetParent || this.node; } }, { key: 'height', value: function height(withMargin) { var height = this.node.offsetHeight; if (withMargin) { var style = this.css(); height += parseInt(style.marginTop) + parseInt(style.marginBottom); } return height; } }, { key: 'width', value: function width(withMargin) { var width = this.node.offsetWidth; if (withMargin) { var style = this.css(); width += parseInt(style.marginTop) + parseInt(style.marginBottom); } return width; } }, { key: 'position', value: function position(withMargin) { if (typeof this.node !== 'undefined') { return { left: this.node.offsetLeft, top: this.node.offsetTop }; } else { this.error('undefinedNode', 'node', 'position', 'withMargin'); } } }, { key: 'html', value: function html(contents) { var output = []; this.for(this.nodes, function (i) { if (!contents) { output.push(i.outerHTML); } else { i.innerHTML = contents; } }); return contents ? this.handler(null, { method: 'html' }) : output; } }, { key: 'json', value: function json(input) { var _input = this.nodes ? this.nodes : this.nonElement ? this.nonElement : input; try { return JSON.stringify(_input); } catch (e) { this.error(e, '', 'json', 'serializable input'); } } }, { key: 'parseJSON', value: function parseJSON(string) { string = this.nonElement ? this.nonElement : string; try { var output = JSON.parse(string); return output; } catch (e) { this.error(e, '', 'parseJSON', 'valid JSON'); } } }, { key: 'type', value: function type(input) { input = this.queryParameter(input, true); return this.nodes && this.isElement(this.nodes) ? 'node' : this.typeOf(input); } }, { key: 'replaceWith', value: function replaceWith(string) { var _this14 = this; this.for(this.nodes, function (i) { if (string && typeof string === 'string') { i.outerHTML = string; return _this14.handler(null, { method: 'replaceWith' }); } else { _this14.error('notType', '', 'replaceWith', 'string'); } }); } }, { key: 'text', value: function text(contents) { var output = []; this.for(this.nodes, function (i) { if (!contents) { output.push(i.textContent); } else { i.textContent = contents; } }); return contents ? this.handler(null, { method: 'text' }) : output; } }, { key: 'insertBefore', value: function insertBefore(el) { var _element = this.queryElement(el); this.for(this.nodes, function (i) { _element.parentNode.insertBefore(i, _element.parentNode.firstChild); }); return this.handler(null, { method: 'insertBefore' }); } }, { key: 'insertAfter', value: function insertAfter(el) { var _element = this.queryElement(el); this.for(this.nodes, function (i) { _element.parentNode.insertBefore(i, _element.parentNode.nextSibling); }); return this.handler(null, { method: 'insertAfter' }); } }, { key: 'prepend', value: function prepend(el) { var _element = this.queryElement(el); this.for(this.nodes, function (i) { i.insertBefore(_element, i.firstChild); }); return this.handler(null, { method: 'prepend' }); } }, { key: 'append', value: function append(el) { var _element = this.queryElement(el); this.for(this.nodes, function (i) { i.appendChild(_element); }); return this.handler(null, { method: 'append' }); } }, { key: 'after', value: function after(string) { this.for(this.nodes, function (i) { i.insertAdjacentHTML('afterend', string); }); return this.handler(null, { method: 'after' }); } }, { key: 'before', value: function before(string) { this.for(this.nodes, function (i) { i.insertAdjacentHTML('beforebegin', string); }); return this.handler(null, { method: 'before' }); } }, { key: 'contains', value: function contains(text) { var textContent = null; if (this.nonElement) { textContent = this.nonElement; } else { textContent = this.node.textContent; } var bool = this.includes(this.node.textContent, text); return bool; } }, { key: 'is', value: function is(el) { var _el = this.queryElement(el); return this.node === _el; } }, { key: 'inViewport', value: function inViewport() { var rect = this.rect(); return rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth); } }, { key: 'inIframe', value: function inIframe() { try { return window.self !== window.top; } catch (e) { return true; } } }, { key: 'trim', value: function trim(string) { string = this.queryParameter(string, true); return string.trim(); } // Used by attr method }, { key: 'camelize', value: function camelize(string) { string = this.queryParameter(string, false); return string.replace(/(?:^\w|[A-Z]|\b\w)/g, function (letter, index) { return index === 0 ? letter.toLowerCase() : letter.toUpperCase(); }).replace(/\s+/g, '').replace(/[-_]+/g, ''); } }, { key: 'decamelize', value: function decamelize(string) { string = this.queryParameter(string, false); return string.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/\b([A-Z]+)([A-Z])([a-z])/, '$1-$2$3').replace(/^./, function (str) { return str.toLowerCase(); }); } }, { key: 'noConflict', value: function noConflict() { var _v = v; window.v = window.oldV; return _v; } // Aliases }, { key: 'n', get: function get() { return this.node; } }, { key: 'ns', get: function get() { return this.nodes; } }, { key: 'ne', get: function get() { return this.nonElement; } }]); return V; }(); var v = function v(selector) { return new V(selector); }; window.v = v; if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { module.exports = v; } else { if (typeof define === 'function' && define.amd) { define([], function () { return v; }); } }