|
- /**
- * Module dependencies.
- */
-
- try {
- var index = require('indexof');
- } catch (err) {
- var index = require('component-indexof');
- }
-
- /**
- * Whitespace regexp.
- */
-
- var re = /\s+/;
-
- /**
- * toString reference.
- */
-
- var toString = Object.prototype.toString;
-
- /**
- * Wrap `el` in a `ClassList`.
- *
- * @param {Element} el
- * @return {ClassList}
- * @api public
- */
-
- module.exports = function(el){
- return new ClassList(el);
- };
-
- /**
- * Initialize a new ClassList for `el`.
- *
- * @param {Element} el
- * @api private
- */
-
- function ClassList(el) {
- if (!el || !el.nodeType) {
- throw new Error('A DOM element reference is required');
- }
- this.el = el;
- this.list = el.classList;
- }
-
- /**
- * Add class `name` if not already present.
- *
- * @param {String} name
- * @return {ClassList}
- * @api public
- */
-
- ClassList.prototype.add = function(name){
- // classList
- if (this.list) {
- this.list.add(name);
- return this;
- }
-
- // fallback
- var arr = this.array();
- var i = index(arr, name);
- if (!~i) arr.push(name);
- this.el.className = arr.join(' ');
- return this;
- };
-
- /**
- * Remove class `name` when present, or
- * pass a regular expression to remove
- * any which match.
- *
- * @param {String|RegExp} name
- * @return {ClassList}
- * @api public
- */
-
- ClassList.prototype.remove = function(name){
- if ('[object RegExp]' == toString.call(name)) {
- return this.removeMatching(name);
- }
-
- // classList
- if (this.list) {
- this.list.remove(name);
- return this;
- }
-
- // fallback
- var arr = this.array();
- var i = index(arr, name);
- if (~i) arr.splice(i, 1);
- this.el.className = arr.join(' ');
- return this;
- };
-
- /**
- * Remove all classes matching `re`.
- *
- * @param {RegExp} re
- * @return {ClassList}
- * @api private
- */
-
- ClassList.prototype.removeMatching = function(re){
- var arr = this.array();
- for (var i = 0; i < arr.length; i++) {
- if (re.test(arr[i])) {
- this.remove(arr[i]);
- }
- }
- return this;
- };
-
- /**
- * Toggle class `name`, can force state via `force`.
- *
- * For browsers that support classList, but do not support `force` yet,
- * the mistake will be detected and corrected.
- *
- * @param {String} name
- * @param {Boolean} force
- * @return {ClassList}
- * @api public
- */
-
- ClassList.prototype.toggle = function(name, force){
- // classList
- if (this.list) {
- if ("undefined" !== typeof force) {
- if (force !== this.list.toggle(name, force)) {
- this.list.toggle(name); // toggle again to correct
- }
- } else {
- this.list.toggle(name);
- }
- return this;
- }
-
- // fallback
- if ("undefined" !== typeof force) {
- if (!force) {
- this.remove(name);
- } else {
- this.add(name);
- }
- } else {
- if (this.has(name)) {
- this.remove(name);
- } else {
- this.add(name);
- }
- }
-
- return this;
- };
-
- /**
- * Return an array of classes.
- *
- * @return {Array}
- * @api public
- */
-
- ClassList.prototype.array = function(){
- var className = this.el.getAttribute('class') || '';
- var str = className.replace(/^\s+|\s+$/g, '');
- var arr = str.split(re);
- if ('' === arr[0]) arr.shift();
- return arr;
- };
-
- /**
- * Check if class `name` is present.
- *
- * @param {String} name
- * @return {ClassList}
- * @api public
- */
-
- ClassList.prototype.has =
- ClassList.prototype.contains = function(name){
- return this.list
- ? this.list.contains(name)
- : !! ~index(this.array(), name);
- };
|