| 'use strict'; | 
|   | 
| var values = require('object.values'); | 
| if (!Object.values) { | 
|     values.shim(); | 
| } | 
|   | 
|   | 
| var CSSClassList = function(node) { | 
|     this.parentNode = node; | 
|     this.classNames = new Set(); | 
|     this.classAttr = null; | 
|     //this.classValue = null; | 
| }; | 
|   | 
| /** | 
|  * Performs a deep clone of this object. | 
|  * | 
|  * @param parentNode the parentNode to assign to the cloned result | 
|  */ | 
| CSSClassList.prototype.clone = function(parentNode) { | 
|     var node = this; | 
|     var nodeData = {}; | 
|   | 
|     Object.keys(node).forEach(function(key) { | 
|         if (key !== 'parentNode') { | 
|             nodeData[key] = node[key]; | 
|         } | 
|     }); | 
|   | 
|     // Deep-clone node data. | 
|     nodeData = JSON.parse(JSON.stringify(nodeData)); | 
|   | 
|     var clone = new CSSClassList(parentNode); | 
|    Object.assign(clone, nodeData); | 
|     return clone; | 
| }; | 
|   | 
| CSSClassList.prototype.hasClass = function() { | 
|     this.classAttr = { // empty class attr | 
|         'name': 'class', | 
|         'value': null | 
|     }; | 
|   | 
|     this.addClassHandler(); | 
| }; | 
|   | 
|   | 
| // attr.class | 
|   | 
| CSSClassList.prototype.addClassHandler = function() { | 
|   | 
|     Object.defineProperty(this.parentNode.attrs, 'class', { | 
|         get: this.getClassAttr.bind(this), | 
|         set: this.setClassAttr.bind(this), | 
|         enumerable: true, | 
|         configurable: true | 
|     }); | 
|   | 
|     this.addClassValueHandler(); | 
| }; | 
|   | 
| // attr.class.value | 
|   | 
| CSSClassList.prototype.addClassValueHandler = function() { | 
|   | 
|     Object.defineProperty(this.classAttr, 'value', { | 
|         get: this.getClassValue.bind(this), | 
|         set: this.setClassValue.bind(this), | 
|         enumerable: true, | 
|         configurable: true | 
|     }); | 
| }; | 
|   | 
| CSSClassList.prototype.getClassAttr = function() { | 
|     return this.classAttr; | 
| }; | 
|   | 
| CSSClassList.prototype.setClassAttr = function(newClassAttr) { | 
|     this.setClassValue(newClassAttr.value); // must before applying value handler! | 
|   | 
|     this.classAttr = newClassAttr; | 
|     this.addClassValueHandler(); | 
| }; | 
|   | 
| CSSClassList.prototype.getClassValue = function() { | 
|     var arrClassNames = Array.from(this.classNames); | 
|     return arrClassNames.join(' '); | 
| }; | 
|   | 
| CSSClassList.prototype.setClassValue = function(newValue) { | 
|     if(typeof newValue === 'undefined') { | 
|       this.classNames.clear(); | 
|       return; | 
|     } | 
|     var arrClassNames = newValue.split(' '); | 
|     this.classNames = new Set(arrClassNames); | 
| }; | 
|   | 
|   | 
| CSSClassList.prototype.add = function(/* variadic */) { | 
|     this.hasClass(); | 
|     Object.values(arguments).forEach(this._addSingle.bind(this)); | 
| }; | 
|   | 
| CSSClassList.prototype._addSingle = function(className) { | 
|     this.classNames.add(className); | 
| }; | 
|   | 
|   | 
| CSSClassList.prototype.remove = function(/* variadic */) { | 
|     this.hasClass(); | 
|     Object.values(arguments).forEach(this._removeSingle.bind(this)); | 
| }; | 
|   | 
| CSSClassList.prototype._removeSingle = function(className) { | 
|     this.classNames.delete(className); | 
| }; | 
|   | 
|   | 
| CSSClassList.prototype.item = function(index) { | 
|     var arrClassNames = Array.from(this.classNames); | 
|     return arrClassNames[index]; | 
| }; | 
|   | 
| CSSClassList.prototype.toggle = function(className, force) { | 
|     if(this.contains(className) || force === false) { | 
|         this.classNames.delete(className); | 
|     } | 
|     this.classNames.add(className); | 
| }; | 
|   | 
| CSSClassList.prototype.contains = function(className) { | 
|     return this.classNames.has(className); | 
| }; | 
|   | 
|   | 
| module.exports = CSSClassList; |