forked from ruiramos/ampersand-dom
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ampersand-dom.js
138 lines (131 loc) · 4.07 KB
/
ampersand-dom.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*$AMPERSAND_VERSION*/
var dom = module.exports = {
text: function (el, val) {
el.textContent = getString(val);
},
// optimize if we have classList
addClass: function (el, cls) {
cls = getString(cls);
if (!cls) return;
if (Array.isArray(cls)) {
cls.forEach(function(c) {
dom.addClass(el, c);
});
} else if (el.classList) {
el.classList.add(cls);
} else {
if (!hasClass(el, cls)) {
if (el.classList) {
el.classList.add(cls);
} else {
el.className += ' ' + cls;
}
}
}
},
removeClass: function (el, cls) {
if (Array.isArray(cls)) {
cls.forEach(function(c) {
dom.removeClass(el, c);
});
} else if (el.classList) {
cls = getString(cls);
if (cls) el.classList.remove(cls);
} else {
// gets class or classes separated by spaces
var clsFinder = new RegExp('(^|\\b)' + cls.split(' ').join('|') + '(\\b|$)', 'gi');
if(typeof el.className === 'object'){
// node is an SVG
var currentClasses = el.getAttribute('class') || '';
el.setAttribute('class', currentClasses.replace(clsFinder, ' '));
} else {
// may be faster to not edit unless we know we have it?
el.className = el.className.replace(clsFinder, ' ');
}
}
},
hasClass: hasClass,
switchClass: function (el, prevCls, newCls) {
if (prevCls) this.removeClass(el, prevCls);
this.addClass(el, newCls);
},
// makes sure attribute (with no content) is added
// if exists it will be cleared of content
addAttribute: function (el, attr) {
// setting to empty string does same
el.setAttribute(attr, '');
// Some browsers won't update UI for boolean attributes unless you
// set it directly. So we do both
if (hasBooleanProperty(el, attr)) el[attr] = true;
},
// completely removes attribute
removeAttribute: function (el, attr) {
el.removeAttribute(attr);
if (hasBooleanProperty(el, attr)) el[attr] = false;
},
// sets attribute to string value given, clearing any current value
setAttribute: function (el, attr, value) {
el.setAttribute(attr, getString(value));
},
getAttribute: function (el, attr) {
return el.getAttribute(attr);
},
hasAttribute: function (el, attr) {
return el.hasAttribute(attr);
},
hide: function (el, mode) {
if (!mode) mode = 'display';
if (!isHidden(el)) {
storeDisplayStyle(el, mode);
hide(el, mode);
}
},
// show element
show: function (el, mode) {
if (!mode) mode = 'display';
show(el, mode);
},
toggle: function (el, mode) {
if (!isHidden(el)) {
dom.hide(el, mode);
} else {
dom.show(el, mode);
}
},
html: function (el, content) {
el.innerHTML = content;
}
};
// helpers
function getString(val) {
if (!val && val !== 0) {
return '';
} else {
return val;
}
}
function hasClass(el, cls) {
if (el.classList) {
return el.classList.contains(cls);
} else {
return new RegExp('(^| )' + cls + '( |$)', 'gi').test(el.className);
}
}
function hasBooleanProperty(el, prop) {
var val = el[prop];
return prop in el && (val === true || val === false);
}
function isHidden (el) {
return dom.getAttribute(el, 'data-anddom-hidden') === 'true';
}
function storeDisplayStyle (el, mode) {
dom.setAttribute(el, 'data-anddom-' + mode, el.style[mode]);
}
function show (el, mode) {
el.style[mode] = dom.getAttribute(el, 'data-anddom-' + mode) || '';
dom.removeAttribute(el, 'data-anddom-hidden');
}
function hide (el, mode) {
dom.setAttribute(el, 'data-anddom-hidden', 'true');
el.style[mode] = (mode === 'visibility' ? 'hidden' : 'none');
}