You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
3.2 KiB
138 lines
3.2 KiB
|
3 years ago
|
'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;
|