UNPKG

bootstrap-vue

Version:

BootstrapVue provides one of the most comprehensive implementations of Bootstrap 4 components and grid system for Vue.js and with extensive and automated WAI-ARIA accessibility markup.

219 lines (193 loc) 6.91 kB
import { from as arrayFrom } from './array'; // Determine if an element is an HTML Element export var isElement = function isElement(el) { return el && el.nodeType === Node.ELEMENT_NODE; }; // Determine if an HTML element is visible - Faster than CSS check export var isVisible = function isVisible(el) { return isElement(el) && document.body.contains(el) && el.getBoundingClientRect().height > 0 && el.getBoundingClientRect().width > 0; }; // Determine if an element is disabled export var isDisabled = function isDisabled(el) { return !isElement(el) || el.disabled || el.classList.contains('disabled') || Boolean(el.getAttribute('disabled')); }; // Cause/wait-for an element to reflow it's content (adjusting it's height/width) export var reflow = function reflow(el) { // requsting an elements offsetHight will trigger a reflow of the element content return isElement(el) && el.offsetHeight; }; // Select all elements matching selector. Returns [] if none found export var selectAll = function selectAll(selector, root) { if (!isElement(root)) { root = document; } return arrayFrom(root.querySelectorAll(selector)); }; // Select a single element, returns null if not found export var select = function select(selector, root) { if (!isElement(root)) { root = document; } return root.querySelector(selector) || null; }; // Determine if an element matches a selector export var matches = function matches(el, selector) { if (!isElement(el)) { return false; } // https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill // Prefer native implementations over polyfill function var proto = Element.prototype; var Matches = proto.matches || proto.matchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector || proto.webkitMatchesSelector || /* istanbul ignore next */ function (sel) { var element = this; var m = selectAll(sel, element.document || element.ownerDocument); var i = m.length; // eslint-disable-next-line no-empty while (--i >= 0 && m.item(i) !== element) {} return i > -1; }; return Matches.call(el, selector); }; // Finds closest element matching selector. Returns null if not found export var closest = function closest(selector, root) { if (!isElement(root)) { return null; } // https://developer.mozilla.org/en-US/docs/Web/API/Element/closest // Since we dont support IE < 10, we can use the "Matches" version of the polyfill for speed // Prefer native implementation over polyfill function var Closest = Element.prototype.closest || /* istanbul ignore next */ function (sel) { var element = this; if (!document.documentElement.contains(element)) { return null; } do { // Use our "patched" matches function if (matches(element, sel)) { return element; } element = element.parentElement; } while (element !== null); return null; }; var el = Closest.call(root, selector); // Emulate jQuery closest and return null if match is the passed in element (root) return el === root ? null : el; }; // Get an element given an ID export var getById = function getById(id) { return document.getElementById(/^#/.test(id) ? id.slice(1) : id) || null; }; // Add a class to an element export var addClass = function addClass(el, className) { if (className && isElement(el)) { el.classList.add(className); } }; // Remove a class from an element export var removeClass = function removeClass(el, className) { if (className && isElement(el)) { el.classList.remove(className); } }; // Test if an element has a class export var hasClass = function hasClass(el, className) { if (className && isElement(el)) { return el.classList.contains(className); } return false; }; // Set an attribute on an element export var setAttr = function setAttr(el, attr, value) { if (attr && isElement(el)) { el.setAttribute(attr, value); } }; // Remove an attribute from an element export var removeAttr = function removeAttr(el, attr) { if (attr && isElement(el)) { el.removeAttribute(attr); } }; // Get an attribute value from an element (returns null if not found) export var getAttr = function getAttr(el, attr) { if (attr && isElement(el)) { return el.getAttribute(attr); } return null; }; // Determine if an attribute exists on an element (returns true or false, or null if element not found) export var hasAttr = function hasAttr(el, attr) { if (attr && isElement(el)) { return el.hasAttribute(attr); } return null; }; // Return the Bounding Client Rec of an element. Retruns null if not an element export var getBCR = function getBCR(el) { return isElement(el) ? el.getBoundingClientRect() : null; }; // Get computed style object for an element export var getCS = function getCS(el) { return isElement(el) ? window.getComputedStyle(el) : {}; }; // Return an element's offset wrt document element // https://j11y.io/jquery/#v=git&fn=jQuery.fn.offset export var offset = function offset(el) { if (isElement(el)) { if (!el.getClientRects().length) { return { top: 0, left: 0 }; } var bcr = getBCR(el); var win = el.ownerDocument.defaultView; return { top: bcr.top + win.pageYOffset, left: bcr.left + win.pageXOffset }; } }; // Return an element's offset wrt to it's offsetParent // https://j11y.io/jquery/#v=git&fn=jQuery.fn.position export var position = function position(el) { if (!isElement(el)) { return; } var parentOffset = { top: 0, left: 0 }; var offsetSelf = void 0; var offsetParent = void 0; if (getCS(el).position === 'fixed') { offsetSelf = getBCR(el); } else { offsetSelf = offset(el); var doc = el.ownerDocument; offsetParent = el.offsetParent || doc.documentElement; while (offsetParent && (offsetParent === doc.body || offsetParent === doc.documentElement) && getCS(offsetParent).position === 'static') { offsetParent = offsetParent.parentNode; } if (offsetParent && offsetParent !== el && offsetParent.nodeType === Node.ELEMENT_NODE) { parentOffset = offset(offsetParent); parentOffset.top += parseFloat(getCS(offsetParent).borderTopWidth); parentOffset.left += parseFloat(getCS(offsetParent).borderLeftWidth); } } return { top: offsetSelf.top - parentOffset.top - parseFloat(getCS(el).marginTop), left: offsetSelf.left - parentOffset.left - parseFloat(getCS(el).marginLeft) }; }; // Attach an event listener to an element export var eventOn = function eventOn(el, evtName, handler) { if (el && el.addEventListener) { el.addEventListener(evtName, handler); } }; // Remove an event listener from an element export var eventOff = function eventOff(el, evtName, handler) { if (el && el.removeEventListener) { el.removeEventListener(evtName, handler); } };