mui-sass 0.2.10 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/mui/sass/version.rb +1 -1
- data/vendor/assets/javascripts/mui.js +982 -934
- data/vendor/assets/stylesheets/mui/_appbar.scss +20 -48
- data/vendor/assets/stylesheets/mui/_forms.scss +26 -11
- data/vendor/assets/stylesheets/mui/_grid.scss +5 -0
- data/vendor/assets/stylesheets/mui/_helpers.scss +54 -86
- data/vendor/assets/stylesheets/mui/_layout.scss +6 -3
- data/vendor/assets/stylesheets/mui/_variables.scss +30 -8
- data/vendor/assets/stylesheets/mui/mixins/_grid-framework.scss +0 -27
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f7ac0d12fc7dcc7819feba207f38ee95926e3cd
|
4
|
+
data.tar.gz: 3ad9ea39687180a74e2addccda24cdc0d6a6cbf8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc253ee837f1cd0b8b71b6f72b9f5dcb34f3584a38fec60b4d8188c83ec58a8ffda6ae183918f8c891781b79fb316742597d8865d66704d70bff99023ce27971
|
7
|
+
data.tar.gz: 816ddf101f9ff4b1ba08edf17c07ae23913443a4c73a210f7abcaf74626410a7e51951574f413e7c2062be64a1e1050b0c18573cbb9c4d51795dac62c742303a
|
data/CHANGELOG.md
CHANGED
data/lib/mui/sass/version.rb
CHANGED
@@ -1,4 +1,42 @@
|
|
1
|
-
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);
|
1
|
+
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
2
|
+
/**
|
3
|
+
* MUI CSS/JS main module
|
4
|
+
* @module main
|
5
|
+
*/
|
6
|
+
|
7
|
+
(function(win) {
|
8
|
+
'use strict';
|
9
|
+
|
10
|
+
// return if library has been loaded already
|
11
|
+
if (win._muiLoadedJS) return;
|
12
|
+
else win._muiLoadedJS = true;
|
13
|
+
|
14
|
+
// load dependencies
|
15
|
+
var jqLite = require('src/js/lib/jqLite'),
|
16
|
+
textfield = require('src/js/forms/textfield'),
|
17
|
+
select = require('src/js/forms/select'),
|
18
|
+
ripple = require('src/js/ripple'),
|
19
|
+
dropdowns = require('src/js/dropdowns'),
|
20
|
+
tabs = require('src/js/tabs'),
|
21
|
+
overlay = require('src/js/overlay');
|
22
|
+
|
23
|
+
// expose api
|
24
|
+
win.mui = {
|
25
|
+
overlay: overlay,
|
26
|
+
tabs: tabs.api
|
27
|
+
};
|
28
|
+
|
29
|
+
// init libraries
|
30
|
+
jqLite.ready(function() {
|
31
|
+
textfield.initListeners();
|
32
|
+
select.initListeners();
|
33
|
+
ripple.initListeners();
|
34
|
+
dropdowns.initListeners();
|
35
|
+
tabs.initListeners();
|
36
|
+
});
|
37
|
+
})(window);
|
38
|
+
|
39
|
+
},{"src/js/dropdowns":6,"src/js/forms/select":7,"src/js/forms/textfield":8,"src/js/lib/jqLite":9,"src/js/overlay":10,"src/js/ripple":11,"src/js/tabs":12}],2:[function(require,module,exports){
|
2
40
|
/**
|
3
41
|
* MUI config module
|
4
42
|
* @module config
|
@@ -10,1286 +48,1296 @@ module.exports = {
|
|
10
48
|
debug: true
|
11
49
|
};
|
12
50
|
|
13
|
-
},{}],
|
51
|
+
},{}],3:[function(require,module,exports){
|
14
52
|
/**
|
15
|
-
* MUI CSS/JS
|
16
|
-
* @module
|
53
|
+
* MUI CSS/JS form helpers module
|
54
|
+
* @module lib/forms.py
|
17
55
|
*/
|
18
56
|
|
19
57
|
'use strict';
|
20
58
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
attrSelector = '[data-mui-toggle="dropdown"]',
|
26
|
-
openClass = 'mui--is-open',
|
27
|
-
menuClass = 'mui-dropdown__menu';
|
59
|
+
var wrapperPadding = 15, // from CSS
|
60
|
+
inputHeight = 32, // from CSS
|
61
|
+
optionHeight = 42, // from CSS
|
62
|
+
menuPadding = 8; // from CSS
|
28
63
|
|
29
64
|
|
30
65
|
/**
|
31
|
-
*
|
32
|
-
* @
|
66
|
+
* Menu position/size/scroll helper
|
67
|
+
* @returns {Object} Object with keys 'height', 'top', 'scrollTop'
|
33
68
|
*/
|
34
|
-
function
|
35
|
-
|
36
|
-
if (toggleEl._muiDropdown === true) return;
|
37
|
-
else toggleEl._muiDropdown = true;
|
69
|
+
function getMenuPositionalCSSFn(wrapperEl, numOptions, currentIndex) {
|
70
|
+
var viewHeight = document.documentElement.clientHeight;
|
38
71
|
|
39
|
-
//
|
40
|
-
|
41
|
-
|
72
|
+
// determine 'height'
|
73
|
+
var h = numOptions * optionHeight + 2 * menuPadding,
|
74
|
+
height = Math.min(h, viewHeight);
|
42
75
|
|
76
|
+
// determine 'top'
|
77
|
+
var top, initTop, minTop, maxTop;
|
43
78
|
|
44
|
-
|
45
|
-
|
46
|
-
* @param {Event} ev - The DOM event
|
47
|
-
*/
|
48
|
-
function clickHandler(ev) {
|
49
|
-
// only left clicks
|
50
|
-
if (ev.button !== 0) return;
|
79
|
+
initTop = (menuPadding + optionHeight) - (wrapperPadding + inputHeight);
|
80
|
+
initTop -= currentIndex * optionHeight;
|
51
81
|
|
52
|
-
|
53
|
-
|
54
|
-
// exit if toggle button is disabled
|
55
|
-
if (toggleEl.getAttribute('disabled') !== null) return;
|
82
|
+
minTop = -1 * wrapperEl.getBoundingClientRect().top;
|
83
|
+
maxTop = (viewHeight - height) + minTop;
|
56
84
|
|
57
|
-
|
58
|
-
ev.preventDefault();
|
59
|
-
ev.stopPropagation();
|
85
|
+
top = Math.min(Math.max(initTop, minTop), maxTop);
|
60
86
|
|
61
|
-
//
|
62
|
-
|
87
|
+
// determine 'scrollTop'
|
88
|
+
var scrollTop = 0,
|
89
|
+
scrollIdeal,
|
90
|
+
scrollMax;
|
91
|
+
|
92
|
+
if (h > viewHeight) {
|
93
|
+
scrollIdeal = (menuPadding + (currentIndex + 1) * optionHeight) -
|
94
|
+
(-1 * top + wrapperPadding + inputHeight);
|
95
|
+
scrollMax = numOptions * optionHeight + 2 * menuPadding - height;
|
96
|
+
scrollTop = Math.min(scrollIdeal, scrollMax);
|
97
|
+
}
|
98
|
+
|
99
|
+
return {
|
100
|
+
'height': height + 'px',
|
101
|
+
'top': top + 'px',
|
102
|
+
'scrollTop': scrollTop
|
103
|
+
};
|
63
104
|
}
|
64
105
|
|
65
106
|
|
107
|
+
/** Define module API */
|
108
|
+
module.exports = {
|
109
|
+
getMenuPositionalCSS: getMenuPositionalCSSFn
|
110
|
+
};
|
111
|
+
|
112
|
+
},{}],4:[function(require,module,exports){
|
66
113
|
/**
|
67
|
-
*
|
68
|
-
* @
|
114
|
+
* MUI CSS/JS jqLite module
|
115
|
+
* @module lib/jqLite
|
69
116
|
*/
|
70
|
-
function toggleDropdown(toggleEl) {
|
71
|
-
var wrapperEl = toggleEl.parentNode,
|
72
|
-
menuEl = toggleEl.nextElementSibling,
|
73
|
-
doc = wrapperEl.ownerDocument;
|
74
|
-
|
75
|
-
// exit if no menu element
|
76
|
-
if (!menuEl || !jqLite.hasClass(menuEl, menuClass)) {
|
77
|
-
return util.raiseError('Dropdown menu element not found');
|
78
|
-
}
|
79
117
|
|
80
|
-
|
81
|
-
function closeDropdownFn() {
|
82
|
-
jqLite.removeClass(menuEl, openClass);
|
83
|
-
|
84
|
-
// remove event handlers
|
85
|
-
jqLite.off(doc, 'click', closeDropdownFn);
|
86
|
-
}
|
118
|
+
'use strict';
|
87
119
|
|
88
|
-
// method to open dropdown
|
89
|
-
function openDropdownFn() {
|
90
|
-
// position menu element below toggle button
|
91
|
-
var wrapperRect = wrapperEl.getBoundingClientRect(),
|
92
|
-
toggleRect = toggleEl.getBoundingClientRect();
|
93
120
|
|
94
|
-
|
95
|
-
|
121
|
+
/**
|
122
|
+
* Add a class to an element.
|
123
|
+
* @param {Element} element - The DOM element.
|
124
|
+
* @param {string} cssClasses - Space separated list of class names.
|
125
|
+
*/
|
126
|
+
function jqLiteAddClass(element, cssClasses) {
|
127
|
+
if (!cssClasses || !element.setAttribute) return;
|
96
128
|
|
97
|
-
|
98
|
-
|
129
|
+
var existingClasses = _getExistingClasses(element),
|
130
|
+
splitClasses = cssClasses.split(' '),
|
131
|
+
cssClass;
|
99
132
|
|
100
|
-
|
101
|
-
|
133
|
+
for (var i=0; i < splitClasses.length; i++) {
|
134
|
+
cssClass = splitClasses[i].trim();
|
135
|
+
if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) {
|
136
|
+
existingClasses += cssClass + ' ';
|
137
|
+
}
|
102
138
|
}
|
103
|
-
|
104
|
-
// toggle dropdown
|
105
|
-
if (jqLite.hasClass(menuEl, openClass)) closeDropdownFn();
|
106
|
-
else openDropdownFn();
|
107
|
-
}
|
108
|
-
|
109
139
|
|
110
|
-
|
111
|
-
|
112
|
-
/** Initialize module listeners */
|
113
|
-
initListeners: function() {
|
114
|
-
var doc = document;
|
115
|
-
|
116
|
-
// markup elements available when method is called
|
117
|
-
var elList = doc.querySelectorAll(attrSelector);
|
118
|
-
for (var i=elList.length - 1; i >= 0; i--) initialize(elList[i]);
|
140
|
+
element.setAttribute('class', existingClasses.trim());
|
141
|
+
}
|
119
142
|
|
120
|
-
// listen for new elements
|
121
|
-
util.onNodeInserted(function(el) {
|
122
|
-
if (el.getAttribute(attrKey) === 'dropdown') initialize(el);
|
123
|
-
});
|
124
|
-
}
|
125
|
-
};
|
126
143
|
|
127
|
-
},{"./lib/jqLite.js":5,"./lib/util.js":6}],3:[function(require,module,exports){
|
128
144
|
/**
|
129
|
-
*
|
130
|
-
* @
|
145
|
+
* Get or set CSS properties.
|
146
|
+
* @param {Element} element - The DOM element.
|
147
|
+
* @param {string} [name] - The property name.
|
148
|
+
* @param {string} [value] - The property value.
|
131
149
|
*/
|
150
|
+
function jqLiteCss(element, name, value) {
|
151
|
+
// Return full style object
|
152
|
+
if (name === undefined) {
|
153
|
+
return getComputedStyle(element);
|
154
|
+
}
|
132
155
|
|
133
|
-
|
156
|
+
var nameType = jqLiteType(name);
|
134
157
|
|
158
|
+
// Set multiple values
|
159
|
+
if (nameType === 'object') {
|
160
|
+
for (var key in name) element.style[_camelCase(key)] = name[key];
|
161
|
+
return;
|
162
|
+
}
|
135
163
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
menuClass = 'mui-select__menu',
|
141
|
-
wrapperPadding = 15, // from CSS
|
142
|
-
inputHeight = 32, // from CSS
|
143
|
-
optionHeight = 42, // from CSS
|
144
|
-
menuPadding = 8, // from CSS
|
145
|
-
doc = document,
|
146
|
-
win = window;
|
164
|
+
// Set a single value
|
165
|
+
if (nameType === 'string' && value !== undefined) {
|
166
|
+
element.style[_camelCase(name)] = value;
|
167
|
+
}
|
147
168
|
|
169
|
+
var styleObj = getComputedStyle(element),
|
170
|
+
isArray = (jqLiteType(name) === 'array');
|
148
171
|
|
149
|
-
|
150
|
-
|
151
|
-
* @param {Element} selectEl - The select element.
|
152
|
-
*/
|
153
|
-
function initialize(selectEl) {
|
154
|
-
// check flag
|
155
|
-
if (selectEl._muiSelect === true) return;
|
156
|
-
else selectEl._muiSelect = true;
|
172
|
+
// Read single value
|
173
|
+
if (!isArray) return _getCurrCssProp(element, name, styleObj);
|
157
174
|
|
158
|
-
//
|
159
|
-
|
175
|
+
// Read multiple values
|
176
|
+
var outObj = {},
|
177
|
+
key;
|
160
178
|
|
161
|
-
|
162
|
-
|
179
|
+
for (var i=0; i < name.length; i++) {
|
180
|
+
key = name[i];
|
181
|
+
outObj[key] = _getCurrCssProp(element, key, styleObj);
|
182
|
+
}
|
183
|
+
|
184
|
+
return outObj;
|
163
185
|
}
|
164
186
|
|
165
187
|
|
166
188
|
/**
|
167
|
-
*
|
168
|
-
* @
|
189
|
+
* Check if element has class.
|
190
|
+
* @param {Element} element - The DOM element.
|
191
|
+
* @param {string} cls - The class name string.
|
169
192
|
*/
|
170
|
-
function
|
171
|
-
|
172
|
-
|
173
|
-
this.wrapperEl = selectEl.parentNode;
|
174
|
-
this.useDefault = false; // currently unused but let's keep just in case
|
175
|
-
|
176
|
-
// attach event handlers
|
177
|
-
jqLite.on(selectEl, 'mousedown', util.callback(this, 'mousedownHandler'));
|
178
|
-
jqLite.on(selectEl, 'focus', util.callback(this, 'focusHandler'));
|
179
|
-
jqLite.on(selectEl, 'click', util.callback(this, 'clickHandler'));
|
180
|
-
|
181
|
-
// make wrapper focusable and fix firefox bug
|
182
|
-
this.wrapperEl.tabIndex = -1;
|
183
|
-
var callbackFn = util.callback(this, 'wrapperFocusHandler');
|
184
|
-
jqLite.on(this.wrapperEl, 'focus', callbackFn);
|
193
|
+
function jqLiteHasClass(element, cls) {
|
194
|
+
if (!cls || !element.getAttribute) return false;
|
195
|
+
return (_getExistingClasses(element).indexOf(' ' + cls + ' ') > -1);
|
185
196
|
}
|
186
197
|
|
187
198
|
|
188
199
|
/**
|
189
|
-
*
|
190
|
-
* @param {
|
200
|
+
* Return the type of a variable.
|
201
|
+
* @param {} somevar - The JavaScript variable.
|
191
202
|
*/
|
192
|
-
|
193
|
-
|
194
|
-
|
203
|
+
function jqLiteType(somevar) {
|
204
|
+
// handle undefined
|
205
|
+
if (somevar === undefined) return 'undefined';
|
206
|
+
|
207
|
+
// handle others (of type [object <Type>])
|
208
|
+
var typeStr = Object.prototype.toString.call(somevar);
|
209
|
+
if (typeStr.indexOf('[object ') === 0) {
|
210
|
+
return typeStr.slice(8, -1).toLowerCase();
|
211
|
+
} else {
|
212
|
+
throw new Error("MUI: Could not understand type: " + typeStr);
|
213
|
+
}
|
195
214
|
}
|
196
215
|
|
197
216
|
|
198
217
|
/**
|
199
|
-
*
|
200
|
-
* @param {
|
218
|
+
* Attach an event handler to a DOM element
|
219
|
+
* @param {Element} element - The DOM element.
|
220
|
+
* @param {string} type - The event type name.
|
221
|
+
* @param {Function} callback - The callback function.
|
222
|
+
* @param {Boolean} useCapture - Use capture flag.
|
201
223
|
*/
|
202
|
-
|
203
|
-
|
204
|
-
if (this.useDefault === true) return;
|
224
|
+
function jqLiteOn(element, type, callback, useCapture) {
|
225
|
+
useCapture = (useCapture === undefined) ? false : useCapture;
|
205
226
|
|
206
|
-
|
207
|
-
|
208
|
-
origIndex = selectEl.tabIndex,
|
209
|
-
keydownFn = util.callback(this, 'keydownHandler');
|
210
|
-
|
211
|
-
// attach keydown handler
|
212
|
-
jqLite.on(doc, 'keydown', keydownFn);
|
227
|
+
// add to DOM
|
228
|
+
element.addEventListener(type, callback, useCapture);
|
213
229
|
|
214
|
-
//
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
jqLite.off(doc, 'keydown', keydownFn);
|
219
|
-
});
|
220
|
-
|
221
|
-
// defer focus to parent
|
222
|
-
wrapperEl.focus();
|
230
|
+
// add to cache
|
231
|
+
var cache = element._muiEventCache = element._muiEventCache || {};
|
232
|
+
cache[type] = cache[type] || [];
|
233
|
+
cache[type].push([callback, useCapture]);
|
223
234
|
}
|
224
235
|
|
225
236
|
|
226
237
|
/**
|
227
|
-
*
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
if (this.selectEl.disabled !== true) this.renderMenu();
|
236
|
-
}
|
237
|
-
}
|
238
|
+
* Remove an event handler from a DOM element
|
239
|
+
* @param {Element} element - The DOM element.
|
240
|
+
* @param {string} type - The event type name.
|
241
|
+
* @param {Function} callback - The callback function.
|
242
|
+
* @param {Boolean} useCapture - Use capture flag.
|
243
|
+
*/
|
244
|
+
function jqLiteOff(element, type, callback, useCapture) {
|
245
|
+
useCapture = (useCapture === undefined) ? false : useCapture;
|
238
246
|
|
247
|
+
// remove from cache
|
248
|
+
var cache = element._muiEventCache = element._muiEventCache || {},
|
249
|
+
argsList = cache[type] || [],
|
250
|
+
args,
|
251
|
+
i;
|
239
252
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
Select.prototype.wrapperFocusHandler = function() {
|
244
|
-
// firefox bugfix
|
245
|
-
if (this.selectEl.disabled) return this.wrapperEl.blur();
|
246
|
-
}
|
253
|
+
i = argsList.length;
|
254
|
+
while (i--) {
|
255
|
+
args = argsList[i];
|
247
256
|
|
257
|
+
// remove all events if callback is undefined
|
258
|
+
if (callback === undefined ||
|
259
|
+
(args[0] === callback && args[1] === useCapture)) {
|
248
260
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
this.renderMenu();
|
261
|
+
// remove from cache
|
262
|
+
argsList.splice(i, 1);
|
263
|
+
|
264
|
+
// remove from DOM
|
265
|
+
element.removeEventListener(type, args[0], args[1]);
|
266
|
+
}
|
267
|
+
}
|
257
268
|
}
|
258
269
|
|
259
270
|
|
260
271
|
/**
|
261
|
-
*
|
272
|
+
* Attach an event hander which will only execute once
|
273
|
+
* @param {Element} element - The DOM element.
|
274
|
+
* @param {string} type - The event type name.
|
275
|
+
* @param {Function} callback - The callback function.
|
276
|
+
* @param {Boolean} useCapture - Use capture flag.
|
262
277
|
*/
|
263
|
-
|
264
|
-
|
265
|
-
|
278
|
+
function jqLiteOne(element, type, callback, useCapture) {
|
279
|
+
jqLiteOn(element, type, function onFn(ev) {
|
280
|
+
// execute callback
|
281
|
+
if (callback) callback.apply(this, arguments);
|
266
282
|
|
267
|
-
|
283
|
+
// remove wrapper
|
284
|
+
jqLiteOff(element, type, onFn);
|
285
|
+
}, useCapture);
|
268
286
|
}
|
269
287
|
|
270
288
|
|
271
289
|
/**
|
272
|
-
*
|
273
|
-
* @
|
290
|
+
* Get or set horizontal scroll position
|
291
|
+
* @param {Element} element - The DOM element
|
292
|
+
* @param {number} [value] - The scroll position
|
274
293
|
*/
|
275
|
-
function
|
276
|
-
|
277
|
-
util.enableScrollLock();
|
278
|
-
|
279
|
-
// instance variables
|
280
|
-
this.origIndex = null;
|
281
|
-
this.currentIndex = null;
|
282
|
-
this.selectEl = selectEl;
|
283
|
-
this.menuEl = this._createMenuEl(wrapperEl, selectEl);
|
284
|
-
this.clickCallbackFn = util.callback(this, 'clickHandler');
|
285
|
-
this.keydownCallbackFn = util.callback(this, 'keydownHandler');
|
286
|
-
this.destroyCallbackFn = util.callback(this, 'destroy');
|
287
|
-
|
288
|
-
// add to DOM
|
289
|
-
wrapperEl.appendChild(this.menuEl);
|
290
|
-
jqLite.scrollTop(this.menuEl, this.menuEl._muiScrollTop);
|
294
|
+
function jqLiteScrollLeft(element, value) {
|
295
|
+
var win = window;
|
291
296
|
|
292
|
-
//
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
+
// get
|
298
|
+
if (value === undefined) {
|
299
|
+
if (element === win) {
|
300
|
+
var docEl = document.documentElement;
|
301
|
+
return (win.pageXOffset || docEl.scrollLeft) - (docEl.clientLeft || 0);
|
302
|
+
} else {
|
303
|
+
return element.scrollLeft;
|
297
304
|
}
|
298
|
-
}
|
299
|
-
|
300
|
-
// attach event handlers
|
301
|
-
jqLite.on(this.menuEl, 'click', this.clickCallbackFn);
|
302
|
-
jqLite.on(doc, 'keydown', this.keydownCallbackFn);
|
303
|
-
jqLite.on(win, 'resize', this.destroyCallbackFn);
|
305
|
+
}
|
304
306
|
|
305
|
-
//
|
306
|
-
|
307
|
-
|
307
|
+
// set
|
308
|
+
if (element === win) win.scrollTo(value, jqLiteScrollTop(win));
|
309
|
+
else element.scrollLeft = value;
|
308
310
|
}
|
309
311
|
|
310
312
|
|
311
313
|
/**
|
312
|
-
*
|
313
|
-
* @param {Element}
|
314
|
+
* Get or set vertical scroll position
|
315
|
+
* @param {Element} element - The DOM element
|
316
|
+
* @param {number} value - The scroll position
|
314
317
|
*/
|
315
|
-
|
316
|
-
var
|
317
|
-
|
318
|
-
var menuEl = doc.createElement('div'),
|
319
|
-
optionList = selectEl.children,
|
320
|
-
m = optionList.length,
|
321
|
-
selectedPos = 0,
|
322
|
-
initTop = (menuPadding + optionHeight) - (wrapperPadding + inputHeight);
|
323
|
-
|
324
|
-
// create element
|
325
|
-
menuEl.className = menuClass;
|
326
|
-
|
327
|
-
// add options
|
328
|
-
for (i=0; i < m; i++) {
|
329
|
-
optionEl = optionList[i];
|
330
|
-
|
331
|
-
itemEl = doc.createElement('div');
|
332
|
-
itemEl.textContent = optionEl.textContent;
|
333
|
-
itemEl._muiPos = i;
|
334
|
-
|
335
|
-
if (optionEl.selected) selectedPos = i;
|
318
|
+
function jqLiteScrollTop(element, value) {
|
319
|
+
var win = window;
|
336
320
|
|
337
|
-
|
321
|
+
// get
|
322
|
+
if (value === undefined) {
|
323
|
+
if (element === win) {
|
324
|
+
var docEl = document.documentElement;
|
325
|
+
return (win.pageYOffset || docEl.scrollTop) - (docEl.clientTop || 0);
|
326
|
+
} else {
|
327
|
+
return element.scrollTop;
|
328
|
+
}
|
338
329
|
}
|
339
330
|
|
340
|
-
//
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
this.origIndex = selectedPos;
|
345
|
-
this.currentIndex = selectedPos;
|
346
|
-
|
347
|
-
var viewHeight = doc.documentElement.clientHeight;
|
348
|
-
|
349
|
-
// set height (use viewport as maximum height)
|
350
|
-
var height = m * optionHeight + 2 * menuPadding,
|
351
|
-
isOverflow = height > viewHeight;
|
352
|
-
|
353
|
-
height = Math.min(height, viewHeight);
|
354
|
-
jqLite.css(menuEl, 'height', height + 'px');
|
331
|
+
// set
|
332
|
+
if (element === win) win.scrollTo(jqLiteScrollLeft(win), value);
|
333
|
+
else element.scrollTop = value;
|
334
|
+
}
|
355
335
|
|
356
|
-
// ideal position
|
357
|
-
initTop -= selectedPos * optionHeight;
|
358
336
|
|
359
|
-
|
360
|
-
|
337
|
+
/**
|
338
|
+
* Return object representing top/left offset and element height/width.
|
339
|
+
* @param {Element} element - The DOM element.
|
340
|
+
*/
|
341
|
+
function jqLiteOffset(element) {
|
342
|
+
var win = window,
|
343
|
+
rect = element.getBoundingClientRect(),
|
344
|
+
scrollTop = jqLiteScrollTop(win),
|
345
|
+
scrollLeft = jqLiteScrollLeft(win);
|
361
346
|
|
362
|
-
|
363
|
-
|
347
|
+
return {
|
348
|
+
top: rect.top + scrollTop,
|
349
|
+
left: rect.left + scrollLeft,
|
350
|
+
height: rect.height,
|
351
|
+
width: rect.width
|
352
|
+
};
|
353
|
+
}
|
364
354
|
|
365
|
-
// prevent overflow-y
|
366
|
-
top = Math.max(initTop, minTop);
|
367
|
-
top = Math.min(top, maxTop);
|
368
355
|
|
369
|
-
|
356
|
+
/**
|
357
|
+
* Attach a callback to the DOM ready event listener
|
358
|
+
* @param {Function} fn - The callback function.
|
359
|
+
*/
|
360
|
+
function jqLiteReady(fn) {
|
361
|
+
var done = false,
|
362
|
+
top = true,
|
363
|
+
doc = document,
|
364
|
+
win = doc.defaultView,
|
365
|
+
root = doc.documentElement,
|
366
|
+
add = doc.addEventListener ? 'addEventListener' : 'attachEvent',
|
367
|
+
rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent',
|
368
|
+
pre = doc.addEventListener ? '' : 'on';
|
370
369
|
|
371
|
-
|
372
|
-
|
373
|
-
|
370
|
+
var init = function(e) {
|
371
|
+
if (e.type == 'readystatechange' && doc.readyState != 'complete') {
|
372
|
+
return;
|
373
|
+
}
|
374
374
|
|
375
|
-
|
376
|
-
|
375
|
+
(e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
|
376
|
+
if (!done && (done = true)) fn.call(win, e.type || e);
|
377
|
+
};
|
377
378
|
|
378
|
-
|
379
|
+
var poll = function() {
|
380
|
+
try { root.doScroll('left'); } catch(e) { setTimeout(poll, 50); return; }
|
381
|
+
init('poll');
|
382
|
+
};
|
379
383
|
|
380
|
-
|
381
|
-
|
384
|
+
if (doc.readyState == 'complete') {
|
385
|
+
fn.call(win, 'lazy');
|
382
386
|
} else {
|
383
|
-
|
384
|
-
|
387
|
+
if (doc.createEventObject && root.doScroll) {
|
388
|
+
try { top = !win.frameElement; } catch(e) { }
|
389
|
+
if (top) poll();
|
390
|
+
}
|
391
|
+
doc[add](pre + 'DOMContentLoaded', init, false);
|
392
|
+
doc[add](pre + 'readystatechange', init, false);
|
393
|
+
win[add](pre + 'load', init, false);
|
385
394
|
}
|
386
|
-
|
387
|
-
return menuEl;
|
388
395
|
}
|
389
396
|
|
390
397
|
|
391
398
|
/**
|
392
|
-
*
|
393
|
-
* @param {
|
399
|
+
* Remove classes from a DOM element
|
400
|
+
* @param {Element} element - The DOM element.
|
401
|
+
* @param {string} cssClasses - Space separated list of class names.
|
394
402
|
*/
|
395
|
-
|
396
|
-
|
403
|
+
function jqLiteRemoveClass(element, cssClasses) {
|
404
|
+
if (!cssClasses || !element.setAttribute) return;
|
397
405
|
|
398
|
-
|
399
|
-
|
406
|
+
var existingClasses = _getExistingClasses(element),
|
407
|
+
splitClasses = cssClasses.split(' '),
|
408
|
+
cssClass;
|
400
409
|
|
401
|
-
|
402
|
-
|
403
|
-
|
410
|
+
for (var i=0; i < splitClasses.length; i++) {
|
411
|
+
cssClass = splitClasses[i].trim();
|
412
|
+
while (existingClasses.indexOf(' ' + cssClass + ' ') >= 0) {
|
413
|
+
existingClasses = existingClasses.replace(' ' + cssClass + ' ', ' ');
|
414
|
+
}
|
404
415
|
}
|
405
416
|
|
406
|
-
|
407
|
-
this.destroy();
|
408
|
-
} else if (keyCode === 40) {
|
409
|
-
this.increment();
|
410
|
-
} else if (keyCode === 38) {
|
411
|
-
this.decrement();
|
412
|
-
} else if (keyCode === 13) {
|
413
|
-
this.selectCurrent();
|
414
|
-
this.destroy();
|
415
|
-
}
|
417
|
+
element.setAttribute('class', existingClasses.trim());
|
416
418
|
}
|
417
419
|
|
418
420
|
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
421
|
+
// ------------------------------
|
422
|
+
// Utilities
|
423
|
+
// ------------------------------
|
424
|
+
var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g,
|
425
|
+
MOZ_HACK_REGEXP = /^moz([A-Z])/,
|
426
|
+
ESCAPE_REGEXP = /([.*+?^=!:${}()|\[\]\/\\])/g,
|
427
|
+
BOOLEAN_ATTRS;
|
426
428
|
|
427
|
-
var pos = ev.target._muiPos;
|
428
429
|
|
429
|
-
|
430
|
-
|
430
|
+
BOOLEAN_ATTRS = {
|
431
|
+
multiple: true,
|
432
|
+
selected: true,
|
433
|
+
checked: true,
|
434
|
+
disabled: true,
|
435
|
+
readonly: true,
|
436
|
+
required: true,
|
437
|
+
open: true
|
438
|
+
}
|
431
439
|
|
432
|
-
// select option
|
433
|
-
this.currentIndex = pos;
|
434
|
-
this.selectCurrent();
|
435
440
|
|
436
|
-
|
437
|
-
|
441
|
+
function _getExistingClasses(element) {
|
442
|
+
var classes = (element.getAttribute('class') || '').replace(/[\n\t]/g, '');
|
443
|
+
return ' ' + classes + ' ';
|
438
444
|
}
|
439
445
|
|
440
446
|
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
this.menuEl.children[this.currentIndex].removeAttribute('selected');
|
448
|
-
this.currentIndex += 1;
|
449
|
-
this.menuEl.children[this.currentIndex].setAttribute('selected', true);
|
447
|
+
function _camelCase(name) {
|
448
|
+
return name.
|
449
|
+
replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
|
450
|
+
return offset ? letter.toUpperCase() : letter;
|
451
|
+
}).
|
452
|
+
replace(MOZ_HACK_REGEXP, 'Moz$1');
|
450
453
|
}
|
451
454
|
|
452
455
|
|
453
|
-
|
454
|
-
|
455
|
-
*/
|
456
|
-
Menu.prototype.decrement = function() {
|
457
|
-
if (this.currentIndex === 0) return;
|
458
|
-
|
459
|
-
this.menuEl.children[this.currentIndex].removeAttribute('selected');
|
460
|
-
this.currentIndex -= 1;
|
461
|
-
this.menuEl.children[this.currentIndex].setAttribute('selected', true);
|
456
|
+
function _escapeRegExp(string) {
|
457
|
+
return string.replace(ESCAPE_REGEXP, "\\$1");
|
462
458
|
}
|
463
459
|
|
464
460
|
|
465
|
-
|
466
|
-
|
467
|
-
*/
|
468
|
-
Menu.prototype.selectCurrent = function() {
|
469
|
-
if (this.currentIndex !== this.origIndex) {
|
470
|
-
this.selectEl.children[this.origIndex].selected = false;
|
471
|
-
this.selectEl.children[this.currentIndex].selected = true;
|
461
|
+
function _getCurrCssProp(elem, name, computed) {
|
462
|
+
var ret;
|
472
463
|
|
473
|
-
|
474
|
-
|
475
|
-
|
464
|
+
// try computed style
|
465
|
+
ret = computed.getPropertyValue(name);
|
466
|
+
|
467
|
+
// try style attribute (if element is not attached to document)
|
468
|
+
if (ret === '' && !elem.ownerDocument) ret = elem.style[_camelCase(name)];
|
469
|
+
|
470
|
+
return ret;
|
476
471
|
}
|
477
472
|
|
478
473
|
|
479
474
|
/**
|
480
|
-
*
|
475
|
+
* Module API
|
481
476
|
*/
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
this.selectEl.focus();
|
477
|
+
module.exports = {
|
478
|
+
/** Add classes */
|
479
|
+
addClass: jqLiteAddClass,
|
486
480
|
|
487
|
-
|
488
|
-
|
481
|
+
/** Get or set CSS properties */
|
482
|
+
css: jqLiteCss,
|
489
483
|
|
490
|
-
|
491
|
-
|
492
|
-
jqLite.off(doc, 'keydown', this.keydownCallbackFn);
|
493
|
-
jqLite.off(doc, 'click', this.destroyCallbackFn);
|
494
|
-
jqLite.off(win, 'resize', this.destroyCallbackFn);
|
495
|
-
}
|
484
|
+
/** Check for class */
|
485
|
+
hasClass: jqLiteHasClass,
|
496
486
|
|
487
|
+
/** Remove event handlers */
|
488
|
+
off: jqLiteOff,
|
497
489
|
|
498
|
-
/**
|
499
|
-
|
500
|
-
/** Initialize module listeners */
|
501
|
-
initListeners: function() {
|
502
|
-
// markup elements available when method is called
|
503
|
-
var elList = doc.querySelectorAll(cssSelector);
|
504
|
-
for (var i=elList.length - 1; i >= 0; i--) initialize(elList[i]);
|
490
|
+
/** Return offset values */
|
491
|
+
offset: jqLiteOffset,
|
505
492
|
|
506
|
-
|
507
|
-
|
508
|
-
if (el.tagName === 'SELECT' &&
|
509
|
-
jqLite.hasClass(el.parentNode, wrapperClass)) {
|
510
|
-
initialize(el);
|
511
|
-
}
|
512
|
-
});
|
513
|
-
}
|
514
|
-
};
|
493
|
+
/** Add event handlers */
|
494
|
+
on: jqLiteOn,
|
515
495
|
|
516
|
-
|
517
|
-
|
518
|
-
* MUI CSS/JS form-control module
|
519
|
-
* @module forms/form-control
|
520
|
-
*/
|
496
|
+
/** Add an execute-once event handler */
|
497
|
+
one: jqLiteOne,
|
521
498
|
|
522
|
-
|
499
|
+
/** DOM ready event handler */
|
500
|
+
ready: jqLiteReady,
|
501
|
+
|
502
|
+
/** Remove classes */
|
503
|
+
removeClass: jqLiteRemoveClass,
|
523
504
|
|
505
|
+
/** Check JavaScript variable instance type */
|
506
|
+
type: jqLiteType,
|
524
507
|
|
525
|
-
|
526
|
-
|
527
|
-
cssSelector = '.mui-textfield > input, .mui-textfield > textarea',
|
528
|
-
emptyClass = 'mui--is-empty',
|
529
|
-
notEmptyClass = 'mui--is-not-empty',
|
530
|
-
dirtyClass = 'mui--is-dirty',
|
531
|
-
floatingLabelClass = 'mui-textfield--float-label';
|
508
|
+
/** Get or set horizontal scroll position */
|
509
|
+
scrollLeft: jqLiteScrollLeft,
|
532
510
|
|
511
|
+
/** Get or set vertical scroll position */
|
512
|
+
scrollTop: jqLiteScrollTop
|
513
|
+
};
|
533
514
|
|
515
|
+
},{}],5:[function(require,module,exports){
|
534
516
|
/**
|
535
|
-
*
|
536
|
-
* @
|
517
|
+
* MUI CSS/JS utilities module
|
518
|
+
* @module lib/util
|
537
519
|
*/
|
538
|
-
function initialize(inputEl) {
|
539
|
-
// check flag
|
540
|
-
if (inputEl._muiTextfield === true) return;
|
541
|
-
else inputEl._muiTextfield = true;
|
542
520
|
|
543
|
-
|
544
|
-
else jqLite.addClass(inputEl, emptyClass);
|
521
|
+
'use strict';
|
545
522
|
|
546
|
-
jqLite.on(inputEl, 'input', inputHandler);
|
547
523
|
|
548
|
-
|
549
|
-
|
550
|
-
|
524
|
+
var config = require('../config'),
|
525
|
+
jqLite = require('./jqLite'),
|
526
|
+
nodeInsertedCallbacks = [],
|
527
|
+
scrollLock = 0,
|
528
|
+
scrollLockCls = 'mui-body--scroll-lock',
|
529
|
+
scrollLockPos,
|
530
|
+
_supportsPointerEvents;
|
551
531
|
|
552
532
|
|
553
533
|
/**
|
554
|
-
*
|
534
|
+
* Logging function
|
555
535
|
*/
|
556
|
-
function
|
557
|
-
var
|
536
|
+
function logFn() {
|
537
|
+
var win = window;
|
558
538
|
|
559
|
-
if (
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
539
|
+
if (config.debug && typeof win.console !== "undefined") {
|
540
|
+
try {
|
541
|
+
win.console.log.apply(win.console, arguments);
|
542
|
+
} catch (a) {
|
543
|
+
var e = Array.prototype.slice.call(arguments);
|
544
|
+
win.console.log(e.join("\n"));
|
545
|
+
}
|
565
546
|
}
|
566
|
-
|
567
|
-
jqLite.addClass(inputEl, dirtyClass);
|
568
547
|
}
|
569
548
|
|
570
549
|
|
571
|
-
/**
|
572
|
-
|
573
|
-
|
574
|
-
|
550
|
+
/**
|
551
|
+
* Load CSS text in new stylesheet
|
552
|
+
* @param {string} cssText - The css text.
|
553
|
+
*/
|
554
|
+
function loadStyleFn(cssText) {
|
555
|
+
var doc = document,
|
556
|
+
head;
|
557
|
+
|
558
|
+
// copied from jQuery
|
559
|
+
head = doc.head ||
|
560
|
+
doc.getElementsByTagName('head')[0] ||
|
561
|
+
doc.documentElement;
|
575
562
|
|
576
|
-
|
577
|
-
|
578
|
-
var doc = document;
|
563
|
+
var e = doc.createElement('style');
|
564
|
+
e.type = 'text/css';
|
579
565
|
|
580
|
-
|
581
|
-
|
582
|
-
|
566
|
+
if (e.styleSheet) e.styleSheet.cssText = cssText;
|
567
|
+
else e.appendChild(doc.createTextNode(cssText));
|
568
|
+
|
569
|
+
// add to document
|
570
|
+
head.insertBefore(e, head.firstChild);
|
583
571
|
|
584
|
-
|
585
|
-
|
586
|
-
if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') initialize(el);
|
587
|
-
});
|
572
|
+
return e;
|
573
|
+
}
|
588
574
|
|
589
|
-
// add transition css for floating labels
|
590
|
-
setTimeout(function() {
|
591
|
-
var css = '.mui-textfield.mui-textfield--float-label > label {' + [
|
592
|
-
'-webkit-transition',
|
593
|
-
'-moz-transition',
|
594
|
-
'-o-transition',
|
595
|
-
'transition',
|
596
|
-
''
|
597
|
-
].join(':all .15s ease-out;') + '}';
|
598
|
-
|
599
|
-
util.loadStyle(css);
|
600
|
-
}, 150);
|
601
575
|
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
576
|
+
/**
|
577
|
+
* Raise an error
|
578
|
+
* @param {string} msg - The error message.
|
579
|
+
*/
|
580
|
+
function raiseErrorFn(msg) {
|
581
|
+
throw new Error("MUI: " + msg);
|
582
|
+
}
|
606
583
|
|
607
|
-
if (targetEl.tagName === 'LABEL' &&
|
608
|
-
jqLite.hasClass(targetEl.parentNode, floatingLabelClass)) {
|
609
|
-
var inputEl = targetEl.previousElementSibling;
|
610
|
-
if (inputEl) inputEl.focus();
|
611
|
-
}
|
612
|
-
});
|
613
|
-
}
|
614
|
-
}
|
615
|
-
};
|
616
584
|
|
617
|
-
},{"../lib/jqLite.js":5,"../lib/util.js":6}],5:[function(require,module,exports){
|
618
585
|
/**
|
619
|
-
*
|
620
|
-
* @
|
586
|
+
* Register callbacks on muiNodeInserted event
|
587
|
+
* @param {function} callbackFn - The callback function.
|
621
588
|
*/
|
589
|
+
function onNodeInsertedFn(callbackFn) {
|
590
|
+
nodeInsertedCallbacks.push(callbackFn);
|
622
591
|
|
623
|
-
|
592
|
+
// initalize listeners
|
593
|
+
if (nodeInsertedCallbacks._initialized === undefined) {
|
594
|
+
var doc = document;
|
595
|
+
|
596
|
+
jqLite.on(doc, 'animationstart', animationHandlerFn);
|
597
|
+
jqLite.on(doc, 'mozAnimationStart', animationHandlerFn);
|
598
|
+
jqLite.on(doc, 'webkitAnimationStart', animationHandlerFn);
|
624
599
|
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
gWin = window;
|
600
|
+
nodeInsertedCallbacks._initialized = true;
|
601
|
+
}
|
602
|
+
}
|
629
603
|
|
630
604
|
|
631
605
|
/**
|
632
|
-
*
|
633
|
-
* @param {
|
634
|
-
* @param {string} cssClasses - Space separated list of class names.
|
606
|
+
* Execute muiNodeInserted callbacks
|
607
|
+
* @param {Event} ev - The DOM event.
|
635
608
|
*/
|
636
|
-
function
|
637
|
-
|
609
|
+
function animationHandlerFn(ev) {
|
610
|
+
// check animation name
|
611
|
+
if (ev.animationName !== 'mui-node-inserted') return;
|
638
612
|
|
639
|
-
var
|
640
|
-
splitClasses = cssClasses.split(' '),
|
641
|
-
cssClass;
|
613
|
+
var el = ev.target;
|
642
614
|
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
existingClasses += cssClass + ' ';
|
647
|
-
}
|
615
|
+
// iterate through callbacks
|
616
|
+
for (var i=nodeInsertedCallbacks.length - 1; i >= 0; i--) {
|
617
|
+
nodeInsertedCallbacks[i](el);
|
648
618
|
}
|
649
|
-
|
650
|
-
element.setAttribute('class', existingClasses.trim());
|
651
619
|
}
|
652
620
|
|
653
621
|
|
654
622
|
/**
|
655
|
-
*
|
656
|
-
*
|
657
|
-
* @param
|
658
|
-
* @
|
623
|
+
* Convert Classname object, with class as key and true/false as value, to an
|
624
|
+
* class string.
|
625
|
+
* @param {Object} classes The classes
|
626
|
+
* @return {String} class string
|
659
627
|
*/
|
660
|
-
function
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
}
|
665
|
-
|
666
|
-
var nameType = jqLiteType(name);
|
667
|
-
|
668
|
-
// Set multiple values
|
669
|
-
if (nameType === 'object') {
|
670
|
-
for (var key in name) element.style[_camelCase(key)] = name[key];
|
671
|
-
return;
|
672
|
-
}
|
673
|
-
|
674
|
-
// Set a single value
|
675
|
-
if (nameType === 'string' && value !== undefined) {
|
676
|
-
element.style[_camelCase(name)] = value;
|
677
|
-
}
|
678
|
-
|
679
|
-
var styleObj = getComputedStyle(element),
|
680
|
-
isArray = (jqLiteType(name) === 'array');
|
681
|
-
|
682
|
-
// Read single value
|
683
|
-
if (!isArray) return _getCurrCssProp(element, name, styleObj);
|
684
|
-
|
685
|
-
// Read multiple values
|
686
|
-
var outObj = {},
|
687
|
-
key;
|
688
|
-
|
689
|
-
for (var i=0; i < name.length; i++) {
|
690
|
-
key = name[i];
|
691
|
-
outObj[key] = _getCurrCssProp(element, key, styleObj);
|
628
|
+
function classNamesFn(classes) {
|
629
|
+
var cs = '';
|
630
|
+
for (var i in classes) {
|
631
|
+
cs += (classes[i]) ? i + ' ' : '';
|
692
632
|
}
|
693
|
-
|
694
|
-
return outObj;
|
633
|
+
return cs.trim();
|
695
634
|
}
|
696
635
|
|
697
636
|
|
698
637
|
/**
|
699
|
-
* Check if
|
700
|
-
* @param {Element} element - The DOM element.
|
701
|
-
* @param {string} cls - The class name string.
|
638
|
+
* Check if client supports pointer events.
|
702
639
|
*/
|
703
|
-
function
|
704
|
-
|
705
|
-
|
640
|
+
function supportsPointerEventsFn() {
|
641
|
+
// check cache
|
642
|
+
if (_supportsPointerEvents !== undefined) return _supportsPointerEvents;
|
643
|
+
|
644
|
+
var element = document.createElement('x');
|
645
|
+
element.style.cssText = 'pointer-events:auto';
|
646
|
+
_supportsPointerEvents = (element.style.pointerEvents === 'auto');
|
647
|
+
return _supportsPointerEvents;
|
706
648
|
}
|
707
649
|
|
708
650
|
|
709
651
|
/**
|
710
|
-
*
|
711
|
-
* @param {}
|
652
|
+
* Create callback closure.
|
653
|
+
* @param {Object} instance - The object instance.
|
654
|
+
* @param {String} funcName - The name of the callback function.
|
712
655
|
*/
|
713
|
-
function
|
714
|
-
|
715
|
-
if (somevar === undefined) return 'undefined';
|
716
|
-
|
717
|
-
// handle others (of type [object <Type>])
|
718
|
-
var typeStr = Object.prototype.toString.call(somevar);
|
719
|
-
if (typeStr.indexOf('[object ') === 0) {
|
720
|
-
return typeStr.slice(8, -1).toLowerCase();
|
721
|
-
} else {
|
722
|
-
throw new Error("MUI: Could not understand type: " + typeStr);
|
723
|
-
}
|
656
|
+
function callbackFn(instance, funcName) {
|
657
|
+
return function() {instance[funcName].apply(instance, arguments);};
|
724
658
|
}
|
725
659
|
|
726
660
|
|
727
661
|
/**
|
728
|
-
*
|
662
|
+
* Dispatch event.
|
729
663
|
* @param {Element} element - The DOM element.
|
730
|
-
* @param {
|
731
|
-
* @param {
|
732
|
-
* @param {Boolean}
|
664
|
+
* @param {String} eventType - The event type.
|
665
|
+
* @param {Boolean} bubbles=true - If true, event bubbles.
|
666
|
+
* @param {Boolean} cancelable=true = If true, event is cancelable
|
667
|
+
* @param {Object} [data] - Data to add to event object
|
733
668
|
*/
|
734
|
-
function
|
735
|
-
|
669
|
+
function dispatchEventFn(element, eventType, bubbles, cancelable, data) {
|
670
|
+
var ev = document.createEvent('HTMLEvents'),
|
671
|
+
bubbles = (bubbles !== undefined) ? bubbles : true,
|
672
|
+
cancelable = (cancelable !== undefined) ? cancelable : true,
|
673
|
+
k;
|
674
|
+
|
675
|
+
ev.initEvent(eventType, bubbles, cancelable);
|
736
676
|
|
737
|
-
// add to
|
738
|
-
|
677
|
+
// add data to event object
|
678
|
+
if (data) for (k in data) ev[k] = data[k];
|
739
679
|
|
740
|
-
//
|
741
|
-
|
742
|
-
|
743
|
-
|
680
|
+
// dispatch
|
681
|
+
if (element) element.dispatchEvent(ev);
|
682
|
+
|
683
|
+
return ev;
|
744
684
|
}
|
745
685
|
|
746
686
|
|
747
687
|
/**
|
748
|
-
*
|
749
|
-
* @param {Element} element - The DOM element.
|
750
|
-
* @param {string} type - The event type name.
|
751
|
-
* @param {Function} callback - The callback function.
|
752
|
-
* @param {Boolean} useCapture - Use capture flag.
|
688
|
+
* Turn on window scroll lock.
|
753
689
|
*/
|
754
|
-
function
|
755
|
-
|
756
|
-
|
757
|
-
// remove from cache
|
758
|
-
var cache = element._muiEventCache = element._muiEventCache || {},
|
759
|
-
argsList = cache[type] || [],
|
760
|
-
args,
|
761
|
-
i;
|
762
|
-
|
763
|
-
i = argsList.length;
|
764
|
-
while (i--) {
|
765
|
-
args = argsList[i];
|
690
|
+
function enableScrollLockFn() {
|
691
|
+
// increment counter
|
692
|
+
scrollLock += 1
|
766
693
|
|
767
|
-
|
768
|
-
|
769
|
-
|
694
|
+
// add lock
|
695
|
+
if (scrollLock === 1) {
|
696
|
+
var win = window,
|
697
|
+
doc = document;
|
770
698
|
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
// remove from DOM
|
775
|
-
element.removeEventListener(type, args[0], args[1]);
|
776
|
-
}
|
699
|
+
scrollLockPos = {left: jqLite.scrollLeft(win), top: jqLite.scrollTop(win)};
|
700
|
+
jqLite.addClass(doc.body, scrollLockCls);
|
701
|
+
win.scrollTo(scrollLockPos.left, scrollLockPos.top);
|
777
702
|
}
|
778
703
|
}
|
779
704
|
|
780
705
|
|
781
706
|
/**
|
782
|
-
*
|
783
|
-
* @param {Element} element - The DOM element.
|
784
|
-
* @param {string} type - The event type name.
|
785
|
-
* @param {Function} callback - The callback function.
|
786
|
-
* @param {Boolean} useCapture - Use capture flag.
|
707
|
+
* Turn off window scroll lock.
|
787
708
|
*/
|
788
|
-
function
|
789
|
-
|
790
|
-
|
791
|
-
if (callback) callback.apply(this, arguments);
|
709
|
+
function disableScrollLockFn() {
|
710
|
+
// ignore
|
711
|
+
if (scrollLock === 0) return;
|
792
712
|
|
793
|
-
|
794
|
-
|
795
|
-
}, useCapture);
|
796
|
-
}
|
713
|
+
// decrement counter
|
714
|
+
scrollLock -= 1
|
797
715
|
|
716
|
+
// remove lock
|
717
|
+
if (scrollLock === 0) {
|
718
|
+
var win = window,
|
719
|
+
doc = document;
|
798
720
|
|
799
|
-
|
800
|
-
|
801
|
-
* @param {Element} element - The DOM element
|
802
|
-
* @param {number} [value] - The scroll position
|
803
|
-
*/
|
804
|
-
function jqLiteScrollLeft(element, value) {
|
805
|
-
// get
|
806
|
-
if (value === undefined) {
|
807
|
-
if (element === gWin) {
|
808
|
-
var t = (gWin.pageXOffset || gDocEl.scrollLeft)
|
809
|
-
return t - (gDocEl.clientLeft || 0);
|
810
|
-
} else {
|
811
|
-
return element.scrollLeft;
|
812
|
-
}
|
721
|
+
jqLite.removeClass(doc.body, scrollLockCls);
|
722
|
+
win.scrollTo(scrollLockPos.left, scrollLockPos.top);
|
813
723
|
}
|
814
|
-
|
815
|
-
// set
|
816
|
-
if (element === gWin) gWin.scrollTo(value, jqLiteScrollTop(gWin));
|
817
|
-
else element.scrollLeft = value;
|
818
724
|
}
|
819
725
|
|
820
726
|
|
821
727
|
/**
|
822
|
-
*
|
823
|
-
* @param {Element} element - The DOM element
|
824
|
-
* @param {number} value - The scroll position
|
728
|
+
* Define the module API
|
825
729
|
*/
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
return element.scrollTop;
|
833
|
-
}
|
834
|
-
}
|
730
|
+
module.exports = {
|
731
|
+
/** Create callback closures */
|
732
|
+
callback: callbackFn,
|
733
|
+
|
734
|
+
/** Classnames object to string */
|
735
|
+
classNames: classNamesFn,
|
835
736
|
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
737
|
+
/** Disable scroll lock */
|
738
|
+
disableScrollLock: disableScrollLockFn,
|
739
|
+
|
740
|
+
/** Dispatch event */
|
741
|
+
dispatchEvent: dispatchEventFn,
|
742
|
+
|
743
|
+
/** Enable scroll lock */
|
744
|
+
enableScrollLock: enableScrollLockFn,
|
840
745
|
|
746
|
+
/** Log messages to the console when debug is turned on */
|
747
|
+
log: logFn,
|
841
748
|
|
842
|
-
/**
|
843
|
-
|
844
|
-
* @param {Element} element - The DOM element.
|
845
|
-
*/
|
846
|
-
function jqLiteOffset(element) {
|
847
|
-
var rect = element.getBoundingClientRect(),
|
848
|
-
scrollTop = jqLiteScrollTop(gWin),
|
849
|
-
scrollLeft = jqLiteScrollLeft(gWin);
|
749
|
+
/** Load CSS text as new stylesheet */
|
750
|
+
loadStyle: loadStyleFn,
|
850
751
|
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
};
|
857
|
-
}
|
752
|
+
/** Register muiNodeInserted handler */
|
753
|
+
onNodeInserted: onNodeInsertedFn,
|
754
|
+
|
755
|
+
/** Raise MUI error */
|
756
|
+
raiseError: raiseErrorFn,
|
858
757
|
|
758
|
+
/** Support Pointer Events check */
|
759
|
+
supportsPointerEvents: supportsPointerEventsFn
|
760
|
+
};
|
859
761
|
|
762
|
+
},{"../config":2,"./jqLite":4}],6:[function(require,module,exports){
|
860
763
|
/**
|
861
|
-
*
|
862
|
-
* @
|
863
|
-
*/
|
864
|
-
function jqLiteReady(fn) {
|
865
|
-
var done = false,
|
866
|
-
top = true,
|
867
|
-
doc = document,
|
868
|
-
win = doc.defaultView,
|
869
|
-
root = doc.documentElement,
|
870
|
-
add = doc.addEventListener ? 'addEventListener' : 'attachEvent',
|
871
|
-
rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent',
|
872
|
-
pre = doc.addEventListener ? '' : 'on';
|
764
|
+
* MUI CSS/JS dropdown module
|
765
|
+
* @module dropdowns
|
766
|
+
*/
|
873
767
|
|
874
|
-
|
875
|
-
if (e.type == 'readystatechange' && doc.readyState != 'complete') {
|
876
|
-
return;
|
877
|
-
}
|
768
|
+
'use strict';
|
878
769
|
|
879
|
-
(e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
|
880
|
-
if (!done && (done = true)) fn.call(win, e.type || e);
|
881
|
-
};
|
882
770
|
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
771
|
+
var jqLite = require('./lib/jqLite'),
|
772
|
+
util = require('./lib/util'),
|
773
|
+
attrKey = 'data-mui-toggle',
|
774
|
+
attrSelector = '[data-mui-toggle="dropdown"]',
|
775
|
+
openClass = 'mui--is-open',
|
776
|
+
menuClass = 'mui-dropdown__menu';
|
887
777
|
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
778
|
+
|
779
|
+
/**
|
780
|
+
* Initialize toggle element.
|
781
|
+
* @param {Element} toggleEl - The toggle element.
|
782
|
+
*/
|
783
|
+
function initialize(toggleEl) {
|
784
|
+
// check flag
|
785
|
+
if (toggleEl._muiDropdown === true) return;
|
786
|
+
else toggleEl._muiDropdown = true;
|
787
|
+
|
788
|
+
// attach click handler
|
789
|
+
jqLite.on(toggleEl, 'click', clickHandler);
|
899
790
|
}
|
900
791
|
|
901
792
|
|
902
793
|
/**
|
903
|
-
*
|
904
|
-
* @param {
|
905
|
-
* @param {string} cssClasses - Space separated list of class names.
|
794
|
+
* Handle click events on dropdown toggle element.
|
795
|
+
* @param {Event} ev - The DOM event
|
906
796
|
*/
|
907
|
-
function
|
908
|
-
|
797
|
+
function clickHandler(ev) {
|
798
|
+
// only left clicks
|
799
|
+
if (ev.button !== 0) return;
|
909
800
|
|
910
|
-
var
|
911
|
-
splitClasses = cssClasses.split(' '),
|
912
|
-
cssClass;
|
801
|
+
var toggleEl = this;
|
913
802
|
|
914
|
-
|
915
|
-
|
916
|
-
while (existingClasses.indexOf(' ' + cssClass + ' ') >= 0) {
|
917
|
-
existingClasses = existingClasses.replace(' ' + cssClass + ' ', ' ');
|
918
|
-
}
|
919
|
-
}
|
803
|
+
// exit if toggle button is disabled
|
804
|
+
if (toggleEl.getAttribute('disabled') !== null) return;
|
920
805
|
|
921
|
-
|
806
|
+
// prevent form submission
|
807
|
+
ev.preventDefault();
|
808
|
+
ev.stopPropagation();
|
809
|
+
|
810
|
+
// toggle dropdown
|
811
|
+
toggleDropdown(toggleEl);
|
922
812
|
}
|
923
813
|
|
924
814
|
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
815
|
+
/**
|
816
|
+
* Toggle the dropdown.
|
817
|
+
* @param {Element} toggleEl - The dropdown toggle element.
|
818
|
+
*/
|
819
|
+
function toggleDropdown(toggleEl) {
|
820
|
+
var wrapperEl = toggleEl.parentNode,
|
821
|
+
menuEl = toggleEl.nextElementSibling,
|
822
|
+
doc = wrapperEl.ownerDocument;
|
932
823
|
|
824
|
+
// exit if no menu element
|
825
|
+
if (!menuEl || !jqLite.hasClass(menuEl, menuClass)) {
|
826
|
+
return util.raiseError('Dropdown menu element not found');
|
827
|
+
}
|
933
828
|
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
open: true
|
942
|
-
}
|
829
|
+
// method to close dropdown
|
830
|
+
function closeDropdownFn() {
|
831
|
+
jqLite.removeClass(menuEl, openClass);
|
832
|
+
|
833
|
+
// remove event handlers
|
834
|
+
jqLite.off(doc, 'click', closeDropdownFn);
|
835
|
+
}
|
943
836
|
|
837
|
+
// method to open dropdown
|
838
|
+
function openDropdownFn() {
|
839
|
+
// position menu element below toggle button
|
840
|
+
var wrapperRect = wrapperEl.getBoundingClientRect(),
|
841
|
+
toggleRect = toggleEl.getBoundingClientRect();
|
944
842
|
|
945
|
-
|
946
|
-
|
947
|
-
return ' ' + classes + ' ';
|
948
|
-
}
|
843
|
+
var top = toggleRect.top - wrapperRect.top + toggleRect.height;
|
844
|
+
jqLite.css(menuEl, 'top', top + 'px');
|
949
845
|
|
846
|
+
// add open class to wrapper
|
847
|
+
jqLite.addClass(menuEl, openClass);
|
950
848
|
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
849
|
+
// close dropdown when user clicks outside of menu
|
850
|
+
jqLite.on(doc, 'click', closeDropdownFn);
|
851
|
+
}
|
852
|
+
|
853
|
+
// toggle dropdown
|
854
|
+
if (jqLite.hasClass(menuEl, openClass)) closeDropdownFn();
|
855
|
+
else openDropdownFn();
|
957
856
|
}
|
958
857
|
|
858
|
+
|
859
|
+
/** Define module API */
|
860
|
+
module.exports = {
|
861
|
+
/** Initialize module listeners */
|
862
|
+
initListeners: function() {
|
863
|
+
var doc = document;
|
959
864
|
|
960
|
-
|
961
|
-
|
962
|
-
|
865
|
+
// markup elements available when method is called
|
866
|
+
var elList = doc.querySelectorAll(attrSelector);
|
867
|
+
for (var i=elList.length - 1; i >= 0; i--) initialize(elList[i]);
|
963
868
|
|
869
|
+
// listen for new elements
|
870
|
+
util.onNodeInserted(function(el) {
|
871
|
+
if (el.getAttribute(attrKey) === 'dropdown') initialize(el);
|
872
|
+
});
|
873
|
+
}
|
874
|
+
};
|
964
875
|
|
965
|
-
function
|
966
|
-
|
876
|
+
},{"./lib/jqLite":4,"./lib/util":5}],7:[function(require,module,exports){
|
877
|
+
/**
|
878
|
+
* MUI CSS/JS select module
|
879
|
+
* @module forms/select
|
880
|
+
*/
|
967
881
|
|
968
|
-
|
969
|
-
ret = computed.getPropertyValue(name);
|
882
|
+
'use strict';
|
970
883
|
|
971
|
-
// try style attribute (if element is not attached to document)
|
972
|
-
if (ret === '' && !elem.ownerDocument) ret = elem.style[_camelCase(name)];
|
973
884
|
|
974
|
-
|
975
|
-
|
885
|
+
var jqLite = require('../lib/jqLite'),
|
886
|
+
util = require('../lib/util'),
|
887
|
+
formlib = require('../lib/forms'),
|
888
|
+
wrapperClass = 'mui-select',
|
889
|
+
cssSelector = '.mui-select > select',
|
890
|
+
menuClass = 'mui-select__menu',
|
891
|
+
selectedClass = 'mui--is-selected',
|
892
|
+
doc = document,
|
893
|
+
win = window;
|
976
894
|
|
977
895
|
|
978
896
|
/**
|
979
|
-
*
|
897
|
+
* Initialize select element.
|
898
|
+
* @param {Element} selectEl - The select element.
|
980
899
|
*/
|
981
|
-
|
982
|
-
|
983
|
-
|
900
|
+
function initialize(selectEl) {
|
901
|
+
// check flag
|
902
|
+
if (selectEl._muiSelect === true) return;
|
903
|
+
else selectEl._muiSelect = true;
|
984
904
|
|
985
|
-
|
986
|
-
|
905
|
+
// use default behavior on touch devices
|
906
|
+
if ('ontouchstart' in doc.documentElement) return;
|
987
907
|
|
988
|
-
|
989
|
-
|
908
|
+
// initialize element
|
909
|
+
new Select(selectEl);
|
910
|
+
}
|
990
911
|
|
991
|
-
/** Remove event handlers */
|
992
|
-
off: jqLiteOff,
|
993
912
|
|
994
|
-
|
995
|
-
|
913
|
+
/**
|
914
|
+
* Creates a new Select object
|
915
|
+
* @class
|
916
|
+
*/
|
917
|
+
function Select(selectEl) {
|
918
|
+
// instance variables
|
919
|
+
this.selectEl = selectEl;
|
920
|
+
this.wrapperEl = selectEl.parentNode;
|
921
|
+
this.useDefault = false; // currently unused but let's keep just in case
|
996
922
|
|
997
|
-
|
998
|
-
on
|
923
|
+
// attach event handlers
|
924
|
+
jqLite.on(selectEl, 'mousedown', util.callback(this, 'mousedownHandler'));
|
925
|
+
jqLite.on(selectEl, 'focus', util.callback(this, 'focusHandler'));
|
926
|
+
jqLite.on(selectEl, 'click', util.callback(this, 'clickHandler'));
|
927
|
+
|
928
|
+
// make wrapper focusable and fix firefox bug
|
929
|
+
this.wrapperEl.tabIndex = -1;
|
930
|
+
var callbackFn = util.callback(this, 'wrapperFocusHandler');
|
931
|
+
jqLite.on(this.wrapperEl, 'focus', callbackFn);
|
932
|
+
}
|
999
933
|
|
1000
|
-
/** Add an execute-once event handler */
|
1001
|
-
one: jqLiteOne,
|
1002
934
|
|
1003
|
-
|
1004
|
-
|
935
|
+
/**
|
936
|
+
* Disable default dropdown on mousedown.
|
937
|
+
* @param {Event} ev - The DOM event
|
938
|
+
*/
|
939
|
+
Select.prototype.mousedownHandler = function(ev) {
|
940
|
+
if (ev.button !== 0 || this.useDefault === true) return;
|
941
|
+
ev.preventDefault();
|
942
|
+
}
|
1005
943
|
|
1006
|
-
/** Remove classes */
|
1007
|
-
removeClass: jqLiteRemoveClass,
|
1008
944
|
|
1009
|
-
|
1010
|
-
|
945
|
+
/**
|
946
|
+
* Handle focus event on select element.
|
947
|
+
* @param {Event} ev - The DOM event
|
948
|
+
*/
|
949
|
+
Select.prototype.focusHandler = function(ev) {
|
950
|
+
// check flag
|
951
|
+
if (this.useDefault === true) return;
|
1011
952
|
|
1012
|
-
|
1013
|
-
|
953
|
+
var selectEl = this.selectEl,
|
954
|
+
wrapperEl = this.wrapperEl,
|
955
|
+
origIndex = selectEl.tabIndex,
|
956
|
+
keydownFn = util.callback(this, 'keydownHandler');
|
1014
957
|
|
1015
|
-
|
1016
|
-
|
1017
|
-
};
|
958
|
+
// attach keydown handler
|
959
|
+
jqLite.on(doc, 'keydown', keydownFn);
|
1018
960
|
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
961
|
+
// disable tabfocus once
|
962
|
+
selectEl.tabIndex = -1;
|
963
|
+
jqLite.one(wrapperEl, 'blur', function() {
|
964
|
+
selectEl.tabIndex = origIndex;
|
965
|
+
jqLite.off(doc, 'keydown', keydownFn);
|
966
|
+
});
|
967
|
+
|
968
|
+
// defer focus to parent
|
969
|
+
wrapperEl.focus();
|
970
|
+
}
|
1024
971
|
|
1025
|
-
'use strict';
|
1026
972
|
|
973
|
+
/**
|
974
|
+
* Handle keydown events on doc
|
975
|
+
**/
|
976
|
+
Select.prototype.keydownHandler = function(ev) {
|
977
|
+
// spacebar, down, up
|
978
|
+
if (ev.keyCode === 32 || ev.keyCode === 38 || ev.keyCode === 40) {
|
979
|
+
// prevent win scroll
|
980
|
+
ev.preventDefault();
|
981
|
+
|
982
|
+
if (this.selectEl.disabled !== true) this.renderMenu();
|
983
|
+
}
|
984
|
+
}
|
1027
985
|
|
1028
|
-
var config = require('../config.js'),
|
1029
|
-
jqLite = require('./jqLite.js'),
|
1030
|
-
win = window,
|
1031
|
-
doc = document,
|
1032
|
-
nodeInsertedCallbacks = [],
|
1033
|
-
scrollLock = 0,
|
1034
|
-
scrollLockCls = 'mui-body--scroll-lock',
|
1035
|
-
scrollLockPos,
|
1036
|
-
head,
|
1037
|
-
_supportsPointerEvents;
|
1038
986
|
|
1039
|
-
|
987
|
+
/**
|
988
|
+
* Handle focus event on wrapper element.
|
989
|
+
*/
|
990
|
+
Select.prototype.wrapperFocusHandler = function() {
|
991
|
+
// firefox bugfix
|
992
|
+
if (this.selectEl.disabled) return this.wrapperEl.blur();
|
993
|
+
}
|
1040
994
|
|
1041
995
|
|
1042
996
|
/**
|
1043
|
-
*
|
997
|
+
* Handle click events on select element.
|
998
|
+
* @param {Event} ev - The DOM event
|
1044
999
|
*/
|
1045
|
-
function
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
} catch (a) {
|
1050
|
-
var e = Array.prototype.slice.call(arguments);
|
1051
|
-
win.console.log(e.join("\n"));
|
1052
|
-
}
|
1053
|
-
}
|
1000
|
+
Select.prototype.clickHandler = function(ev) {
|
1001
|
+
// only left clicks
|
1002
|
+
if (ev.button !== 0) return;
|
1003
|
+
this.renderMenu();
|
1054
1004
|
}
|
1055
1005
|
|
1056
1006
|
|
1057
1007
|
/**
|
1058
|
-
*
|
1059
|
-
* @param {string} cssText - The css text.
|
1008
|
+
* Render options dropdown.
|
1060
1009
|
*/
|
1061
|
-
function
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
if (e.styleSheet) e.styleSheet.cssText = cssText;
|
1066
|
-
else e.appendChild(doc.createTextNode(cssText));
|
1067
|
-
|
1068
|
-
// add to document
|
1069
|
-
head.insertBefore(e, head.firstChild);
|
1010
|
+
Select.prototype.renderMenu = function() {
|
1011
|
+
// check and reset flag
|
1012
|
+
if (this.useDefault === true) return this.useDefault = false;
|
1070
1013
|
|
1071
|
-
|
1014
|
+
new Menu(this.wrapperEl, this.selectEl);
|
1072
1015
|
}
|
1073
1016
|
|
1074
1017
|
|
1075
1018
|
/**
|
1076
|
-
*
|
1077
|
-
* @
|
1019
|
+
* Creates a new Menu
|
1020
|
+
* @class
|
1078
1021
|
*/
|
1079
|
-
function
|
1080
|
-
|
1022
|
+
function Menu(wrapperEl, selectEl) {
|
1023
|
+
// add scroll lock
|
1024
|
+
util.enableScrollLock();
|
1025
|
+
|
1026
|
+
// instance variables
|
1027
|
+
this.origIndex = null;
|
1028
|
+
this.currentIndex = null;
|
1029
|
+
this.selectEl = selectEl;
|
1030
|
+
this.menuEl = this._createMenuEl(wrapperEl, selectEl);
|
1031
|
+
this.clickCallbackFn = util.callback(this, 'clickHandler');
|
1032
|
+
this.keydownCallbackFn = util.callback(this, 'keydownHandler');
|
1033
|
+
this.destroyCallbackFn = util.callback(this, 'destroy');
|
1034
|
+
|
1035
|
+
// add to DOM
|
1036
|
+
wrapperEl.appendChild(this.menuEl);
|
1037
|
+
jqLite.scrollTop(this.menuEl, this.menuEl._muiScrollTop);
|
1038
|
+
|
1039
|
+
// blur active element
|
1040
|
+
setTimeout(function() {
|
1041
|
+
// ie10 bugfix
|
1042
|
+
if (doc.activeElement.nodeName.toLowerCase() !== "body") {
|
1043
|
+
doc.activeElement.blur();
|
1044
|
+
}
|
1045
|
+
}, 0);
|
1046
|
+
|
1047
|
+
// attach event handlers
|
1048
|
+
jqLite.on(this.menuEl, 'click', this.clickCallbackFn);
|
1049
|
+
jqLite.on(doc, 'keydown', this.keydownCallbackFn);
|
1050
|
+
jqLite.on(win, 'resize', this.destroyCallbackFn);
|
1051
|
+
|
1052
|
+
// attach event handler after current event loop exits
|
1053
|
+
var fn = this.destroyCallbackFn;
|
1054
|
+
setTimeout(function() {jqLite.on(doc, 'click', fn);}, 0);
|
1081
1055
|
}
|
1082
1056
|
|
1083
1057
|
|
1084
1058
|
/**
|
1085
|
-
*
|
1086
|
-
* @param {
|
1059
|
+
* Create menu element
|
1060
|
+
* @param {Element} selectEl - The select element
|
1087
1061
|
*/
|
1088
|
-
function
|
1089
|
-
|
1062
|
+
Menu.prototype._createMenuEl = function(wrapperEl, selectEl) {
|
1063
|
+
var menuEl = doc.createElement('div'),
|
1064
|
+
optionEls = selectEl.children,
|
1065
|
+
numOptions = optionEls.length,
|
1066
|
+
selectedPos = 0,
|
1067
|
+
optionEl,
|
1068
|
+
itemEl,
|
1069
|
+
i;
|
1090
1070
|
|
1091
|
-
|
1092
|
-
if (nodeInsertedCallbacks._initialized === undefined) {
|
1093
|
-
jqLite.on(doc, 'animationstart', animationHandlerFn);
|
1094
|
-
jqLite.on(doc, 'mozAnimationStart', animationHandlerFn);
|
1095
|
-
jqLite.on(doc, 'webkitAnimationStart', animationHandlerFn);
|
1071
|
+
menuEl.className = menuClass;
|
1096
1072
|
|
1097
|
-
|
1073
|
+
// add options
|
1074
|
+
for (i=0; i < numOptions; i++) {
|
1075
|
+
optionEl = optionEls[i];
|
1076
|
+
|
1077
|
+
itemEl = doc.createElement('div');
|
1078
|
+
itemEl.textContent = optionEl.textContent;
|
1079
|
+
itemEl._muiPos = i;
|
1080
|
+
|
1081
|
+
if (optionEl.selected) {
|
1082
|
+
itemEl.setAttribute('class', selectedClass);
|
1083
|
+
selectedPos = i;
|
1084
|
+
}
|
1085
|
+
|
1086
|
+
menuEl.appendChild(itemEl);
|
1098
1087
|
}
|
1088
|
+
|
1089
|
+
// save indices
|
1090
|
+
this.origIndex = selectedPos;
|
1091
|
+
this.currentIndex = selectedPos;
|
1092
|
+
|
1093
|
+
// set position
|
1094
|
+
var props = formlib.getMenuPositionalCSS(
|
1095
|
+
wrapperEl,
|
1096
|
+
numOptions,
|
1097
|
+
selectedPos
|
1098
|
+
);
|
1099
|
+
|
1100
|
+
jqLite.css(menuEl, props);
|
1101
|
+
menuEl._muiScrollTop = props.scrollTop;
|
1102
|
+
|
1103
|
+
return menuEl;
|
1099
1104
|
}
|
1100
1105
|
|
1101
1106
|
|
1102
1107
|
/**
|
1103
|
-
*
|
1104
|
-
* @param {Event} ev - The DOM event
|
1108
|
+
* Handle keydown events on doc element.
|
1109
|
+
* @param {Event} ev - The DOM event
|
1105
1110
|
*/
|
1106
|
-
function
|
1107
|
-
|
1108
|
-
if (ev.animationName !== 'mui-node-inserted') return;
|
1111
|
+
Menu.prototype.keydownHandler = function(ev) {
|
1112
|
+
var keyCode = ev.keyCode;
|
1109
1113
|
|
1110
|
-
|
1114
|
+
// tab
|
1115
|
+
if (keyCode === 9) return this.destroy();
|
1116
|
+
|
1117
|
+
// escape | up | down | enter
|
1118
|
+
if (keyCode === 27 || keyCode === 40 || keyCode === 38 || keyCode === 13) {
|
1119
|
+
ev.preventDefault();
|
1120
|
+
}
|
1111
1121
|
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1122
|
+
if (keyCode === 27) {
|
1123
|
+
this.destroy();
|
1124
|
+
} else if (keyCode === 40) {
|
1125
|
+
this.increment();
|
1126
|
+
} else if (keyCode === 38) {
|
1127
|
+
this.decrement();
|
1128
|
+
} else if (keyCode === 13) {
|
1129
|
+
this.selectCurrent();
|
1130
|
+
this.destroy();
|
1115
1131
|
}
|
1116
1132
|
}
|
1117
1133
|
|
1118
1134
|
|
1119
1135
|
/**
|
1120
|
-
*
|
1121
|
-
*
|
1122
|
-
* @param {Object} classes The classes
|
1123
|
-
* @return {String} class string
|
1136
|
+
* Handle click events on menu element.
|
1137
|
+
* @param {Event} ev - The DOM event
|
1124
1138
|
*/
|
1125
|
-
function
|
1126
|
-
|
1127
|
-
|
1128
|
-
cs += (classes[i]) ? i + ' ' : '';
|
1129
|
-
}
|
1130
|
-
return cs.trim();
|
1131
|
-
}
|
1139
|
+
Menu.prototype.clickHandler = function(ev) {
|
1140
|
+
// don't allow events to bubble
|
1141
|
+
ev.stopPropagation();
|
1132
1142
|
|
1143
|
+
var pos = ev.target._muiPos;
|
1133
1144
|
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
_supportsPointerEvents = (element.style.pointerEvents === 'auto');
|
1144
|
-
return _supportsPointerEvents;
|
1145
|
+
// ignore clicks on non-items
|
1146
|
+
if (pos === undefined) return;
|
1147
|
+
|
1148
|
+
// select option
|
1149
|
+
this.currentIndex = pos;
|
1150
|
+
this.selectCurrent();
|
1151
|
+
|
1152
|
+
// destroy menu
|
1153
|
+
this.destroy();
|
1145
1154
|
}
|
1146
1155
|
|
1147
1156
|
|
1148
1157
|
/**
|
1149
|
-
*
|
1150
|
-
* @param {Object} instance - The object instance.
|
1151
|
-
* @param {String} funcName - The name of the callback function.
|
1158
|
+
* Increment selected item
|
1152
1159
|
*/
|
1153
|
-
function
|
1154
|
-
|
1160
|
+
Menu.prototype.increment = function() {
|
1161
|
+
if (this.currentIndex === this.menuEl.children.length - 1) return;
|
1162
|
+
|
1163
|
+
var optionEls = this.menuEl.children;
|
1164
|
+
|
1165
|
+
jqLite.removeClass(optionEls[this.currentIndex], selectedClass);
|
1166
|
+
this.currentIndex += 1;
|
1167
|
+
jqLite.addClass(optionEls[this.currentIndex], selectedClass);
|
1155
1168
|
}
|
1156
1169
|
|
1157
1170
|
|
1158
1171
|
/**
|
1159
|
-
*
|
1160
|
-
* @param {Element} element - The DOM element.
|
1161
|
-
* @param {String} eventType - The event type.
|
1162
|
-
* @param {Boolean} bubbles=true - If true, event bubbles.
|
1163
|
-
* @param {Boolean} cancelable=true = If true, event is cancelable
|
1164
|
-
* @param {Object} [data] - Data to add to event object
|
1172
|
+
* Decrement selected item
|
1165
1173
|
*/
|
1166
|
-
function
|
1167
|
-
|
1168
|
-
bubbles = (bubbles !== undefined) ? bubbles : true,
|
1169
|
-
cancelable = (cancelable !== undefined) ? cancelable : true,
|
1170
|
-
k;
|
1171
|
-
|
1172
|
-
ev.initEvent(eventType, bubbles, cancelable);
|
1173
|
-
|
1174
|
-
// add data to event object
|
1175
|
-
if (data) for (k in data) ev[k] = data[k];
|
1174
|
+
Menu.prototype.decrement = function() {
|
1175
|
+
if (this.currentIndex === 0) return;
|
1176
1176
|
|
1177
|
-
|
1178
|
-
if (element) element.dispatchEvent(ev);
|
1177
|
+
var optionEls = this.menuEl.children;
|
1179
1178
|
|
1180
|
-
|
1179
|
+
jqLite.removeClass(optionEls[this.currentIndex], selectedClass);
|
1180
|
+
this.currentIndex -= 1;
|
1181
|
+
jqLite.addClass(optionEls[this.currentIndex], selectedClass);
|
1181
1182
|
}
|
1182
1183
|
|
1183
1184
|
|
1184
1185
|
/**
|
1185
|
-
*
|
1186
|
+
* Select current item
|
1186
1187
|
*/
|
1187
|
-
function
|
1188
|
-
|
1189
|
-
|
1188
|
+
Menu.prototype.selectCurrent = function() {
|
1189
|
+
if (this.currentIndex !== this.origIndex) {
|
1190
|
+
var optionEls = this.selectEl.children;
|
1191
|
+
optionEls[this.origIndex].selected = false;
|
1192
|
+
optionEls[this.currentIndex].selected = true;
|
1190
1193
|
|
1191
|
-
|
1192
|
-
|
1193
|
-
scrollLockPos = {left: jqLite.scrollLeft(win), top: jqLite.scrollTop(win)};
|
1194
|
-
jqLite.addClass(doc.body, scrollLockCls);
|
1195
|
-
win.scrollTo(scrollLockPos.left, scrollLockPos.top);
|
1194
|
+
// trigger change event
|
1195
|
+
util.dispatchEvent(this.selectEl, 'change');
|
1196
1196
|
}
|
1197
1197
|
}
|
1198
1198
|
|
1199
1199
|
|
1200
1200
|
/**
|
1201
|
-
*
|
1201
|
+
* Destroy menu and detach event handlers
|
1202
1202
|
*/
|
1203
|
-
function
|
1204
|
-
//
|
1205
|
-
|
1203
|
+
Menu.prototype.destroy = function() {
|
1204
|
+
// remove element and focus element
|
1205
|
+
this.menuEl.parentNode.removeChild(this.menuEl);
|
1206
|
+
this.selectEl.focus();
|
1206
1207
|
|
1207
|
-
//
|
1208
|
-
|
1208
|
+
// remove scroll lock
|
1209
|
+
util.disableScrollLock();
|
1209
1210
|
|
1210
|
-
// remove
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1211
|
+
// remove event handlers
|
1212
|
+
jqLite.off(this.menuEl, 'click', this.clickCallbackFn);
|
1213
|
+
jqLite.off(doc, 'keydown', this.keydownCallbackFn);
|
1214
|
+
jqLite.off(doc, 'click', this.destroyCallbackFn);
|
1215
|
+
jqLite.off(win, 'resize', this.destroyCallbackFn);
|
1215
1216
|
}
|
1216
1217
|
|
1217
1218
|
|
1219
|
+
/** Define module API */
|
1220
|
+
module.exports = {
|
1221
|
+
/** Initialize module listeners */
|
1222
|
+
initListeners: function() {
|
1223
|
+
// markup elements available when method is called
|
1224
|
+
var elList = doc.querySelectorAll(cssSelector);
|
1225
|
+
for (var i=elList.length - 1; i >= 0; i--) initialize(elList[i]);
|
1226
|
+
|
1227
|
+
// listen for new elements
|
1228
|
+
util.onNodeInserted(function(el) {
|
1229
|
+
if (el.tagName === 'SELECT' &&
|
1230
|
+
jqLite.hasClass(el.parentNode, wrapperClass)) {
|
1231
|
+
initialize(el);
|
1232
|
+
}
|
1233
|
+
});
|
1234
|
+
}
|
1235
|
+
};
|
1236
|
+
|
1237
|
+
},{"../lib/forms":3,"../lib/jqLite":4,"../lib/util":5}],8:[function(require,module,exports){
|
1218
1238
|
/**
|
1219
|
-
*
|
1239
|
+
* MUI CSS/JS form-control module
|
1240
|
+
* @module forms/form-control
|
1220
1241
|
*/
|
1221
|
-
module.exports = {
|
1222
|
-
/** Create callback closures */
|
1223
|
-
callback: callbackFn,
|
1224
|
-
|
1225
|
-
/** Classnames object to string */
|
1226
|
-
classNames: classNamesFn,
|
1227
1242
|
|
1228
|
-
|
1229
|
-
disableScrollLock: disableScrollLockFn,
|
1243
|
+
'use strict';
|
1230
1244
|
|
1231
|
-
/** Dispatch event */
|
1232
|
-
dispatchEvent: dispatchEventFn,
|
1233
|
-
|
1234
|
-
/** Enable scroll lock */
|
1235
|
-
enableScrollLock: enableScrollLockFn,
|
1236
1245
|
|
1237
|
-
|
1238
|
-
|
1246
|
+
var jqLite = require('../lib/jqLite'),
|
1247
|
+
util = require('../lib/util'),
|
1248
|
+
cssSelector = '.mui-textfield > input, .mui-textfield > textarea',
|
1249
|
+
emptyClass = 'mui--is-empty',
|
1250
|
+
notEmptyClass = 'mui--is-not-empty',
|
1251
|
+
dirtyClass = 'mui--is-dirty',
|
1252
|
+
floatingLabelClass = 'mui-textfield--float-label';
|
1239
1253
|
|
1240
|
-
/** Load CSS text as new stylesheet */
|
1241
|
-
loadStyle: loadStyleFn,
|
1242
1254
|
|
1243
|
-
|
1244
|
-
|
1255
|
+
/**
|
1256
|
+
* Initialize input element.
|
1257
|
+
* @param {Element} inputEl - The input element.
|
1258
|
+
*/
|
1259
|
+
function initialize(inputEl) {
|
1260
|
+
// check flag
|
1261
|
+
if (inputEl._muiTextfield === true) return;
|
1262
|
+
else inputEl._muiTextfield = true;
|
1245
1263
|
|
1246
|
-
|
1247
|
-
|
1264
|
+
if (inputEl.value.length) jqLite.addClass(inputEl, notEmptyClass);
|
1265
|
+
else jqLite.addClass(inputEl, emptyClass);
|
1266
|
+
|
1267
|
+
jqLite.on(inputEl, 'input', inputHandler);
|
1268
|
+
|
1269
|
+
// add dirty class on focus
|
1270
|
+
jqLite.on(inputEl, 'focus', function(){jqLite.addClass(this, dirtyClass);});
|
1271
|
+
}
|
1248
1272
|
|
1249
|
-
/** Support Pointer Events check */
|
1250
|
-
supportsPointerEvents: supportsPointerEventsFn
|
1251
|
-
};
|
1252
1273
|
|
1253
|
-
},{"../config.js":1,"./jqLite.js":5}],7:[function(require,module,exports){
|
1254
1274
|
/**
|
1255
|
-
*
|
1256
|
-
* @module main
|
1275
|
+
* Handle input events.
|
1257
1276
|
*/
|
1277
|
+
function inputHandler() {
|
1278
|
+
var inputEl = this;
|
1258
1279
|
|
1259
|
-
(
|
1260
|
-
|
1280
|
+
if (inputEl.value.length) {
|
1281
|
+
jqLite.removeClass(inputEl, emptyClass);
|
1282
|
+
jqLite.addClass(inputEl, notEmptyClass);
|
1283
|
+
} else {
|
1284
|
+
jqLite.removeClass(inputEl, notEmptyClass);
|
1285
|
+
jqLite.addClass(inputEl, emptyClass)
|
1286
|
+
}
|
1261
1287
|
|
1262
|
-
|
1263
|
-
|
1264
|
-
else win._muiLoadedJS = true;
|
1265
|
-
|
1266
|
-
// load dependencies
|
1267
|
-
var jqLite = require('./lib/jqLite.js'),
|
1268
|
-
util = require('./lib/util.js'),
|
1269
|
-
textfield = require('./forms/textfield.js'),
|
1270
|
-
select = require('./forms/select.js'),
|
1271
|
-
ripple = require('./ripple.js'),
|
1272
|
-
dropdowns = require('./dropdowns.js'),
|
1273
|
-
tabs = require('./tabs.js'),
|
1274
|
-
overlay = require('./overlay.js');
|
1288
|
+
jqLite.addClass(inputEl, dirtyClass);
|
1289
|
+
}
|
1275
1290
|
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1291
|
+
|
1292
|
+
/** Define module API */
|
1293
|
+
module.exports = {
|
1294
|
+
/** Initialize input elements */
|
1295
|
+
initialize: initialize,
|
1281
1296
|
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1297
|
+
/** Initialize module listeners */
|
1298
|
+
initListeners: function() {
|
1299
|
+
var doc = document;
|
1300
|
+
|
1301
|
+
// markup elements available when method is called
|
1302
|
+
var elList = doc.querySelectorAll(cssSelector);
|
1303
|
+
for (var i=elList.length - 1; i >= 0; i--) initialize(elList[i]);
|
1304
|
+
|
1305
|
+
// listen for new elements
|
1306
|
+
util.onNodeInserted(function(el) {
|
1307
|
+
if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') initialize(el);
|
1308
|
+
});
|
1309
|
+
|
1310
|
+
// add transition css for floating labels
|
1311
|
+
setTimeout(function() {
|
1312
|
+
var css = '.mui-textfield.mui-textfield--float-label > label {' + [
|
1313
|
+
'-webkit-transition',
|
1314
|
+
'-moz-transition',
|
1315
|
+
'-o-transition',
|
1316
|
+
'transition',
|
1317
|
+
''
|
1318
|
+
].join(':all .15s ease-out;') + '}';
|
1319
|
+
|
1320
|
+
util.loadStyle(css);
|
1321
|
+
}, 150);
|
1322
|
+
|
1323
|
+
// pointer-events shim for floating labels
|
1324
|
+
if (util.supportsPointerEvents() === false) {
|
1325
|
+
jqLite.on(document, 'click', function(ev) {
|
1326
|
+
var targetEl = ev.target;
|
1327
|
+
|
1328
|
+
if (targetEl.tagName === 'LABEL' &&
|
1329
|
+
jqLite.hasClass(targetEl.parentNode, floatingLabelClass)) {
|
1330
|
+
var inputEl = targetEl.previousElementSibling;
|
1331
|
+
if (inputEl) inputEl.focus();
|
1332
|
+
}
|
1333
|
+
});
|
1334
|
+
}
|
1335
|
+
}
|
1336
|
+
};
|
1291
1337
|
|
1292
|
-
},{"
|
1338
|
+
},{"../lib/jqLite":4,"../lib/util":5}],9:[function(require,module,exports){
|
1339
|
+
module.exports=require(4)
|
1340
|
+
},{}],10:[function(require,module,exports){
|
1293
1341
|
/**
|
1294
1342
|
* MUI CSS/JS overlay module
|
1295
1343
|
* @module overlay
|
@@ -1298,8 +1346,8 @@ module.exports = {
|
|
1298
1346
|
'use strict';
|
1299
1347
|
|
1300
1348
|
|
1301
|
-
var util = require('./lib/util
|
1302
|
-
jqLite = require('./lib/jqLite
|
1349
|
+
var util = require('./lib/util'),
|
1350
|
+
jqLite = require('./lib/jqLite'),
|
1303
1351
|
overlayId = 'mui-overlay',
|
1304
1352
|
bodyClass = 'mui--overflow-hidden',
|
1305
1353
|
iosRegex = /(iPad|iPhone|iPod)/g;
|
@@ -1483,7 +1531,7 @@ function onClick(ev) {
|
|
1483
1531
|
/** Define module API */
|
1484
1532
|
module.exports = overlayFn;
|
1485
1533
|
|
1486
|
-
},{"./lib/jqLite
|
1534
|
+
},{"./lib/jqLite":4,"./lib/util":5}],11:[function(require,module,exports){
|
1487
1535
|
/**
|
1488
1536
|
* MUI CSS/JS ripple module
|
1489
1537
|
* @module ripple
|
@@ -1492,8 +1540,8 @@ module.exports = overlayFn;
|
|
1492
1540
|
'use strict';
|
1493
1541
|
|
1494
1542
|
|
1495
|
-
var jqLite = require('./lib/jqLite
|
1496
|
-
util = require('./lib/util
|
1543
|
+
var jqLite = require('./lib/jqLite'),
|
1544
|
+
util = require('./lib/util'),
|
1497
1545
|
btnClass = 'mui-btn',
|
1498
1546
|
btnFABClass = 'mui-btn--fab',
|
1499
1547
|
rippleClass = 'mui-ripple-effect',
|
@@ -1588,7 +1636,7 @@ module.exports = {
|
|
1588
1636
|
}
|
1589
1637
|
};
|
1590
1638
|
|
1591
|
-
},{"./lib/jqLite
|
1639
|
+
},{"./lib/jqLite":4,"./lib/util":5}],12:[function(require,module,exports){
|
1592
1640
|
/**
|
1593
1641
|
* MUI CSS/JS tabs module
|
1594
1642
|
* @module tabs
|
@@ -1597,8 +1645,8 @@ module.exports = {
|
|
1597
1645
|
'use strict';
|
1598
1646
|
|
1599
1647
|
|
1600
|
-
var jqLite = require('./lib/jqLite
|
1601
|
-
util = require('./lib/util
|
1648
|
+
var jqLite = require('./lib/jqLite'),
|
1649
|
+
util = require('./lib/util'),
|
1602
1650
|
attrKey = 'data-mui-toggle',
|
1603
1651
|
attrSelector = '[' + attrKey + '="tab"]',
|
1604
1652
|
controlsAttrKey = 'data-mui-controls',
|
@@ -1749,4 +1797,4 @@ module.exports = {
|
|
1749
1797
|
}
|
1750
1798
|
};
|
1751
1799
|
|
1752
|
-
},{"./lib/jqLite
|
1800
|
+
},{"./lib/jqLite":4,"./lib/util":5}]},{},[1])
|