chui-rails 0.0.1
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 +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/chui-rails.gemspec +23 -0
- data/lib/chui/rails.rb +7 -0
- data/lib/chui/rails/version.rb +5 -0
- data/vendor/assets/images/app-icons/app.png +0 -0
- data/vendor/assets/images/app-icons/browser.png +0 -0
- data/vendor/assets/images/app-icons/mail.png +0 -0
- data/vendor/assets/images/app-icons/music.png +0 -0
- data/vendor/assets/images/app-icons/weather.png +0 -0
- data/vendor/assets/images/icons/Camera.svg +55 -0
- data/vendor/assets/images/icons/Documents.svg +71 -0
- data/vendor/assets/images/icons/Download.svg +8 -0
- data/vendor/assets/images/icons/Favorite.svg +25 -0
- data/vendor/assets/images/icons/Head_phones.svg +32 -0
- data/vendor/assets/images/icons/android.svg +15 -0
- data/vendor/assets/images/icons/arrow_down.svg +6 -0
- data/vendor/assets/images/icons/arrow_left.svg +6 -0
- data/vendor/assets/images/icons/arrow_right.svg +6 -0
- data/vendor/assets/images/icons/arrow_up.svg +6 -0
- data/vendor/assets/images/icons/down.svg +13 -0
- data/vendor/assets/images/icons/left.svg +13 -0
- data/vendor/assets/images/icons/right.svg +13 -0
- data/vendor/assets/images/icons/up.svg +13 -0
- Harm.jpg +0 -0
- data/vendor/assets/images/music/Imagine Dragons.jpg +0 -0
- data/vendor/assets/images/music/Kiss.jpg +0 -0
- data/vendor/assets/images/music/Permanent.jpg +0 -0
- data/vendor/assets/images/music/The Olms.jpg +0 -0
- data/vendor/assets/images/music/Willy Moon.jpg +0 -0
- data/vendor/assets/javascripts/chui-3.7.0.js +2796 -0
- data/vendor/assets/javascripts/chui-3.7.0.min.js +9 -0
- data/vendor/assets/stylesheets/chui-android-3.7.0.css +2970 -0
- data/vendor/assets/stylesheets/chui-android-3.7.0.min.css +8 -0
- data/vendor/assets/stylesheets/chui-ios-3.7.0.css +2614 -0
- data/vendor/assets/stylesheets/chui-ios-3.7.0.min.css +8 -0
- data/vendor/assets/stylesheets/chui-win-3.7.0.css +2375 -0
- data/vendor/assets/stylesheets/chui-win-3.7.0.min.css +8 -0
- metadata +113 -0
Harm.jpg
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,2796 @@
|
|
1
|
+
/*
|
2
|
+
pO\
|
3
|
+
6 /\
|
4
|
+
/OO\
|
5
|
+
/OOOO\
|
6
|
+
/OOOOOO\
|
7
|
+
(OOOOOOOO)
|
8
|
+
\:~==~:/
|
9
|
+
|
10
|
+
ChocolateChip-UI
|
11
|
+
ChUI.js
|
12
|
+
Copyright 2014 Sourcebits www.sourcebits.com
|
13
|
+
License: MIT
|
14
|
+
Version: 3.7.0
|
15
|
+
*/
|
16
|
+
window.CHUIJSLIB;
|
17
|
+
if(window.jQuery) {
|
18
|
+
window.CHUIJSLIB = window.jQuery;
|
19
|
+
} else if (window.$chocolatechipjs) {
|
20
|
+
window.CHUIJSLIB = window.$chocolatechipjs;
|
21
|
+
}
|
22
|
+
(function($) {
|
23
|
+
|
24
|
+
$.extend({
|
25
|
+
///////////////
|
26
|
+
// Create Uuid:
|
27
|
+
///////////////
|
28
|
+
UuidBit : 1,
|
29
|
+
|
30
|
+
Uuid : function() {
|
31
|
+
this.UuidBit++;
|
32
|
+
return Date.now().toString(36) + this.UuidBit;
|
33
|
+
},
|
34
|
+
|
35
|
+
///////////////////////////
|
36
|
+
// Concat array of strings:
|
37
|
+
///////////////////////////
|
38
|
+
concat : function ( args ) {
|
39
|
+
return (args instanceof Array) ? args.join('') : [].slice.apply(arguments).join('');
|
40
|
+
},
|
41
|
+
////////////////////////////
|
42
|
+
// Version of each that uses
|
43
|
+
// regular parameter order:
|
44
|
+
////////////////////////////
|
45
|
+
forEach : function ( obj, callback, args ) {
|
46
|
+
function isArraylike( obj ) {
|
47
|
+
var length = obj.length,
|
48
|
+
type = typeof obj;
|
49
|
+
if ( type === "function" || obj === window ) {
|
50
|
+
return false;
|
51
|
+
}
|
52
|
+
if ( obj.nodeType === 1 && length ) {
|
53
|
+
return true;
|
54
|
+
}
|
55
|
+
return type === "array" || length === 0 ||
|
56
|
+
typeof length === "number" && length > 0 && ( length - 1 ) in obj;
|
57
|
+
}
|
58
|
+
var value,
|
59
|
+
i = 0,
|
60
|
+
length = obj.length,
|
61
|
+
isArray = isArraylike( obj );
|
62
|
+
if ( args ) {
|
63
|
+
if ( isArray ) {
|
64
|
+
for ( ; i < length; i++ ) {
|
65
|
+
value = callback.apply( obj[ i ], args );
|
66
|
+
if ( value === false ) {
|
67
|
+
break;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
} else {
|
71
|
+
for ( i in obj ) {
|
72
|
+
value = callback.apply( obj[ i ], args );
|
73
|
+
if ( value === false ) {
|
74
|
+
break;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
// A special, fast, case for the most common use of each
|
79
|
+
} else {
|
80
|
+
if ( isArray ) {
|
81
|
+
for ( ; i < length; i++ ) {
|
82
|
+
value = callback.call( obj[ i ], obj[ i ], i );
|
83
|
+
if ( value === false ) {
|
84
|
+
break;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
} else {
|
88
|
+
for ( i in obj ) {
|
89
|
+
value = callback.call( obj[ i ], obj[ i ], i );
|
90
|
+
if ( value === false ) {
|
91
|
+
break;
|
92
|
+
}
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
96
|
+
}
|
97
|
+
});
|
98
|
+
|
99
|
+
$.fn.extend({
|
100
|
+
|
101
|
+
///////////////////////////////////
|
102
|
+
// forEach method for jQuery to
|
103
|
+
// preserve normal parameter order.
|
104
|
+
///////////////////////////////////
|
105
|
+
forEach : function( callback, args ) {
|
106
|
+
var $this = this;
|
107
|
+
return $.forEach( $this, callback, args );
|
108
|
+
},
|
109
|
+
|
110
|
+
//////////////////////
|
111
|
+
// Return element that
|
112
|
+
// matches selector:
|
113
|
+
//////////////////////
|
114
|
+
iz : function ( selector ) {
|
115
|
+
if (window.jQuery) {
|
116
|
+
var ret = $();
|
117
|
+
this.forEach(function(ctx) {
|
118
|
+
if ($(ctx).is(selector)) {
|
119
|
+
ret.push(ctx);
|
120
|
+
}
|
121
|
+
});
|
122
|
+
return ret;
|
123
|
+
|
124
|
+
} else if (window.$chocolatechipjs) {
|
125
|
+
return this.is(selector);
|
126
|
+
}
|
127
|
+
},
|
128
|
+
//////////////////////////////
|
129
|
+
// Return element that doesn't
|
130
|
+
// match selector:
|
131
|
+
//////////////////////////////
|
132
|
+
iznt : function ( selector ) {
|
133
|
+
if (window.jQuery) {
|
134
|
+
return this.not(selector);
|
135
|
+
} else if (window.$chocolatechipjs) {
|
136
|
+
return this.isnt(selector);
|
137
|
+
}
|
138
|
+
},
|
139
|
+
|
140
|
+
///////////////////////////////////
|
141
|
+
// Return element whose descendants
|
142
|
+
// match selector:
|
143
|
+
///////////////////////////////////
|
144
|
+
haz : function ( selector ) {
|
145
|
+
return this.has(selector);
|
146
|
+
},
|
147
|
+
|
148
|
+
///////////////////////////////////
|
149
|
+
// Return element whose descendants
|
150
|
+
// don't match selector:
|
151
|
+
///////////////////////////////////
|
152
|
+
haznt : function ( selector ) {
|
153
|
+
if (window.jQuery) {
|
154
|
+
var ret = $();
|
155
|
+
this.forEach(function(ctx) {
|
156
|
+
if (!$(ctx).has(selector)[0]) {
|
157
|
+
ret.push(ctx);
|
158
|
+
}
|
159
|
+
});
|
160
|
+
return ret;
|
161
|
+
} else if (window.$chocolatechipjs) {
|
162
|
+
return this.hasnt(selector);
|
163
|
+
}
|
164
|
+
},
|
165
|
+
//////////////////////////////////////
|
166
|
+
// Return element that has class name:
|
167
|
+
//////////////////////////////////////
|
168
|
+
hazClass : function ( className ) {
|
169
|
+
if (window.jQuery) {
|
170
|
+
var ret = $();
|
171
|
+
this.forEach(function(ctx) {
|
172
|
+
if ($(ctx).hasClass(className)) {
|
173
|
+
ret.push(ctx);
|
174
|
+
}
|
175
|
+
});
|
176
|
+
return ret;
|
177
|
+
} else if(window.$chocolatechipjs) {
|
178
|
+
return this.hasClass(className);
|
179
|
+
}
|
180
|
+
},
|
181
|
+
//////////////////////////////
|
182
|
+
// Return element that doesn't
|
183
|
+
// have class name:
|
184
|
+
//////////////////////////////
|
185
|
+
hazntClass : function ( className ) {
|
186
|
+
if (window.jQuery) {
|
187
|
+
var ret = $();
|
188
|
+
this.forEach(function(ctx) {
|
189
|
+
if (!$(ctx).hasClass(className)) {
|
190
|
+
ret.push(ctx);
|
191
|
+
}
|
192
|
+
});
|
193
|
+
return ret;
|
194
|
+
} else if (window.$chocolatechipjs) {
|
195
|
+
var ret = [];
|
196
|
+
this.forEach(function(ctx) {
|
197
|
+
if (ctx.classList.contains(className)) {
|
198
|
+
ret.push(ctx);
|
199
|
+
}
|
200
|
+
});
|
201
|
+
return ret;
|
202
|
+
}
|
203
|
+
},
|
204
|
+
/////////////////////////////////////
|
205
|
+
// Return element that has attribute:
|
206
|
+
/////////////////////////////////////
|
207
|
+
hazAttr : function ( property ) {
|
208
|
+
if (window.jQuery) {
|
209
|
+
var ret = $();
|
210
|
+
this.forEach(function(ctx){
|
211
|
+
if ($(ctx).attr(property)) {
|
212
|
+
ret.push(ctx);
|
213
|
+
}
|
214
|
+
});
|
215
|
+
return ret;
|
216
|
+
} else if (window.$chocolatechipjs) {
|
217
|
+
var ret = [];
|
218
|
+
|
219
|
+
return ret;
|
220
|
+
}
|
221
|
+
},
|
222
|
+
//////////////////////////
|
223
|
+
// Return element that
|
224
|
+
// doesn't have attribute:
|
225
|
+
//////////////////////////
|
226
|
+
hazntAttr : function ( property ) {
|
227
|
+
if (window.jQuery) {
|
228
|
+
var ret = $();
|
229
|
+
this.forEach(function(ctx){
|
230
|
+
if (!$(ctx).attr(property)) {
|
231
|
+
ret.push(ctx);
|
232
|
+
}
|
233
|
+
});
|
234
|
+
return ret;
|
235
|
+
} else if (window.$chocolatechipjs) {
|
236
|
+
var ret = [];
|
237
|
+
if (!ctx.hasAttribute(property)){
|
238
|
+
ret.push(ctx);
|
239
|
+
}
|
240
|
+
return ret;
|
241
|
+
}
|
242
|
+
}
|
243
|
+
});
|
244
|
+
|
245
|
+
|
246
|
+
$.extend({
|
247
|
+
eventStart : null,
|
248
|
+
eventEnd : null,
|
249
|
+
eventMove : null,
|
250
|
+
eventCancel : null,
|
251
|
+
// Define min-length for gesture detection:
|
252
|
+
gestureLength : 30
|
253
|
+
});
|
254
|
+
|
255
|
+
$(function() {
|
256
|
+
//////////////////////////
|
257
|
+
// Setup Event Variables:
|
258
|
+
//////////////////////////
|
259
|
+
// Pointer events for IE10 and WP8:
|
260
|
+
if (window.navigator.pointerEnabled) {
|
261
|
+
$.eventStart = 'pointerdown';
|
262
|
+
$.eventEnd = 'pointerup';
|
263
|
+
$.eventMove = 'pointermove';
|
264
|
+
$.eventCancel = 'pointercancel';
|
265
|
+
// Pointer events for IE10 and WP8:
|
266
|
+
} else if (window.navigator.msPointerEnabled) {
|
267
|
+
$.eventStart = 'MSPointerDown';
|
268
|
+
$.eventEnd = 'MSPointerUp';
|
269
|
+
$.eventMove = 'MSPointerMove';
|
270
|
+
$.eventCancel = 'MSPointerCancel';
|
271
|
+
// Touch events for iOS & Android:
|
272
|
+
} else if ('ontouchstart' in window) {
|
273
|
+
$.eventStart = 'touchstart';
|
274
|
+
$.eventEnd = 'touchend';
|
275
|
+
$.eventMove = 'touchmove';
|
276
|
+
$.eventCancel = 'touchcancel';
|
277
|
+
// Mouse events for desktop:
|
278
|
+
} else {
|
279
|
+
$.eventStart = 'mousedown';
|
280
|
+
$.eventEnd = 'click';
|
281
|
+
$.eventMove = 'mousemove';
|
282
|
+
$.eventCancel = 'mouseout';
|
283
|
+
}
|
284
|
+
});
|
285
|
+
|
286
|
+
|
287
|
+
$.extend({
|
288
|
+
isiPhone : /iphone/img.test(navigator.userAgent),
|
289
|
+
isiPad : /ipad/img.test(navigator.userAgent),
|
290
|
+
isiPod : /ipod/img.test(navigator.userAgent),
|
291
|
+
isiOS : /ip(hone|od|ad)/img.test(navigator.userAgent),
|
292
|
+
isAndroid : (/android/img.test(navigator.userAgent) && !/trident/img.test(navigator.userAgent)),
|
293
|
+
isWebOS : /webos/img.test(navigator.userAgent),
|
294
|
+
isBlackberry : /blackberry/img.test(navigator.userAgent),
|
295
|
+
isTouchEnabled : ('createTouch' in document),
|
296
|
+
isOnline : navigator.onLine,
|
297
|
+
isStandalone : navigator.standalone,
|
298
|
+
isiOS6 : navigator.userAgent.match(/OS 6/i),
|
299
|
+
isiOS7 : navigator.userAgent.match(/OS 7/i),
|
300
|
+
isWin : /trident/img.test(navigator.userAgent),
|
301
|
+
isWinPhone : (/trident/img.test(navigator.userAgent) && /mobile/img.test(navigator.userAgent)),
|
302
|
+
isIE10 : navigator.userAgent.match(/msie 10/i),
|
303
|
+
isIE11 : navigator.userAgent.match(/msie 11/i),
|
304
|
+
isWebkit : navigator.userAgent.match(/webkit/),
|
305
|
+
isMobile : /mobile/img.test(navigator.userAgent),
|
306
|
+
isDesktop : !(/mobile/img.test(navigator.userAgent)),
|
307
|
+
isSafari : (!/Chrome/img.test(navigator.userAgent) && /Safari/img.test(navigator.userAgent) && !/android/img.test(navigator.userAgent)),
|
308
|
+
isChrome : /Chrome/img.test(navigator.userAgent),
|
309
|
+
isNativeAndroid : (/android/i.test(navigator.userAgent) && /webkit/i.test(navigator.userAgent) && !/chrome/i.test(navigator.userAgent))
|
310
|
+
});
|
311
|
+
|
312
|
+
|
313
|
+
|
314
|
+
/////////////////////////////
|
315
|
+
// Determine browser version:
|
316
|
+
/////////////////////////////
|
317
|
+
$.extend({
|
318
|
+
browserVersion : function ( ) {
|
319
|
+
var n = navigator.appName;
|
320
|
+
var ua = navigator.userAgent;
|
321
|
+
var temp;
|
322
|
+
var m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
|
323
|
+
if (m && (temp = ua.match(/version\/([\.\d]+)/i))!== null) m[2]= temp[1];
|
324
|
+
m = m ? [m[1], m[2]]: [n, navigator.appVersion, '-?'];
|
325
|
+
return m[1];
|
326
|
+
}
|
327
|
+
});
|
328
|
+
|
329
|
+
$(function() {
|
330
|
+
////////////////////////////////
|
331
|
+
// Added classes for client side
|
332
|
+
// os-specific styles:
|
333
|
+
////////////////////////////////
|
334
|
+
$.body = $('body');
|
335
|
+
|
336
|
+
if ((/android/img.test(navigator.userAgent)) && (/webkit/img.test(navigator.userAgent) ) && (!/Chrome/img.test(navigator.userAgent))) {
|
337
|
+
$.body.addClass('isNativeAndroidBrowser');
|
338
|
+
}
|
339
|
+
if ($.isWin) {
|
340
|
+
$.body.addClass('isWindows');
|
341
|
+
} else if ($.isiOS) {
|
342
|
+
$.body.addClass('isiOS');
|
343
|
+
} else if ($.isAndroid) {
|
344
|
+
$.body.addClass('isAndroid');
|
345
|
+
}
|
346
|
+
if ($.isSafari && parseInt($.browserVersion(), 10) === 6) {
|
347
|
+
$.body.addClass('isSafari6');
|
348
|
+
}
|
349
|
+
if ($.isNativeAndroid) {
|
350
|
+
$.body.addClass('isNativeAndroidBrowser');
|
351
|
+
}
|
352
|
+
});
|
353
|
+
|
354
|
+
|
355
|
+
//////////////////////////////////////////////////////
|
356
|
+
// Swipe Gestures for ChocolateChip-UI.
|
357
|
+
// Includes mouse gestures for desktop compatibility.
|
358
|
+
//////////////////////////////////////////////////////
|
359
|
+
var touch = {};
|
360
|
+
var touchTimeout;
|
361
|
+
var swipeTimeout;
|
362
|
+
var tapTimeout;
|
363
|
+
var longTapDelay = 750;
|
364
|
+
var singleTapDelay = 150;
|
365
|
+
var longTapTimeout;
|
366
|
+
function parentIfText(node) {
|
367
|
+
return 'tagName' in node ? node : node.parentNode;
|
368
|
+
}
|
369
|
+
function swipeDirection(x1, x2, y1, y2) {
|
370
|
+
return Math.abs(x1 - x2) >=
|
371
|
+
Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'left' : 'right') : (y1 - y2 > 0 ? 'up' : 'down');
|
372
|
+
}
|
373
|
+
function longTap() {
|
374
|
+
longTapTimeout = null;
|
375
|
+
if (touch.last) {
|
376
|
+
try {
|
377
|
+
if (touch && touch.el) {
|
378
|
+
touch.el.trigger('longtap');
|
379
|
+
touch = {};
|
380
|
+
}
|
381
|
+
} catch(err) { }
|
382
|
+
}
|
383
|
+
}
|
384
|
+
function cancelLongTap() {
|
385
|
+
if (longTapTimeout) clearTimeout(longTapTimeout);
|
386
|
+
longTapTimeout = null;
|
387
|
+
}
|
388
|
+
function cancelAll() {
|
389
|
+
if (touchTimeout) clearTimeout(touchTimeout);
|
390
|
+
if (tapTimeout) clearTimeout(tapTimeout);
|
391
|
+
if (swipeTimeout) clearTimeout(swipeTimeout);
|
392
|
+
if (longTapTimeout) clearTimeout(longTapTimeout);
|
393
|
+
touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null;
|
394
|
+
touch = {};
|
395
|
+
}
|
396
|
+
$(function(){
|
397
|
+
var now;
|
398
|
+
var delta;
|
399
|
+
var body = $(document.body);
|
400
|
+
var twoTouches = false;
|
401
|
+
body.on($.eventStart, function(e) {
|
402
|
+
now = Date.now();
|
403
|
+
delta = now - (touch.last || now);
|
404
|
+
if (e.originalEvent) e = e.originalEvent;
|
405
|
+
|
406
|
+
// Handle MSPointer Events:
|
407
|
+
if (window.navigator.msPointerEnabled || window.navigator.pointerEnabled) {
|
408
|
+
if (window && window.jQuery && $ === window.jQuery) {
|
409
|
+
if (e.originalEvent && !e.originalEvent.isPrimary) return;
|
410
|
+
} else {
|
411
|
+
if (!e.isPrimary) return;
|
412
|
+
}
|
413
|
+
e = e.originalEvent ? e.originalEvent : e;
|
414
|
+
body.on('MSHoldVisual', function (e) {
|
415
|
+
e.preventDefault();
|
416
|
+
});
|
417
|
+
touch.el = $(parentIfText(e.target));
|
418
|
+
touchTimeout && clearTimeout(touchTimeout);
|
419
|
+
touch.x1 = e.pageX;
|
420
|
+
touch.y1 = e.pageY;
|
421
|
+
twoTouches = false;
|
422
|
+
} else {
|
423
|
+
if ($.eventStart === 'mousedown') {
|
424
|
+
touch.el = $(parentIfText(e.target));
|
425
|
+
touchTimeout && clearTimeout(touchTimeout);
|
426
|
+
touch.x1 = e.pageX;
|
427
|
+
touch.y1 = e.pageY;
|
428
|
+
twoTouches = false;
|
429
|
+
} else {
|
430
|
+
// User to detect two or more finger gestures:
|
431
|
+
if (e.touches.length === 1) {
|
432
|
+
touch.el = $(parentIfText(e.touches[0].target));
|
433
|
+
touchTimeout && clearTimeout(touchTimeout);
|
434
|
+
touch.x1 = e.touches[0].pageX;
|
435
|
+
touch.y1 = e.touches[0].pageY;
|
436
|
+
if (e.targetTouches.length === 2) {
|
437
|
+
twoTouches = true;
|
438
|
+
} else {
|
439
|
+
twoTouches = false;
|
440
|
+
}
|
441
|
+
}
|
442
|
+
}
|
443
|
+
}
|
444
|
+
if (delta > 0 && delta <= 250) {
|
445
|
+
touch.isDoubleTap = true;
|
446
|
+
}
|
447
|
+
touch.last = now;
|
448
|
+
longTapTimeout = setTimeout(longTap, longTapDelay);
|
449
|
+
});
|
450
|
+
body.on($.eventMove, function(e) {
|
451
|
+
if (e.originalEvent) e = e.originalEvent;
|
452
|
+
if (window.navigator.msPointerEnabled) {
|
453
|
+
if (window && window.jQuery && $ === window.jQuery) {
|
454
|
+
if (e.originalEvent && !e.originalEvent.isPrimary) return;
|
455
|
+
} else {
|
456
|
+
if (!e.isPrimary) return;
|
457
|
+
}
|
458
|
+
e = e.originalEvent ? e.originalEvent : e;
|
459
|
+
cancelLongTap();
|
460
|
+
touch.x2 = e.pageX;
|
461
|
+
touch.y2 = e.pageY;
|
462
|
+
} else {
|
463
|
+
cancelLongTap();
|
464
|
+
if ($.eventMove === 'mousemove') {
|
465
|
+
touch.x2 = e.pageX;
|
466
|
+
touch.y2 = e.pageY;
|
467
|
+
} else {
|
468
|
+
// One finger gesture:
|
469
|
+
if (e.touches.length === 1) {
|
470
|
+
touch.x2 = e.touches[0].pageX;
|
471
|
+
touch.y2 = e.touches[0].pageY;
|
472
|
+
}
|
473
|
+
}
|
474
|
+
}
|
475
|
+
if ($.isAndroid) {
|
476
|
+
$.gestureLength = 10;
|
477
|
+
if (!!touch.el) {
|
478
|
+
// Swipe detection:
|
479
|
+
if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > $.gestureLength) ||
|
480
|
+
(touch.y2 && Math.abs(touch.y1 - touch.y2) > $.gestureLength)) {
|
481
|
+
swipeTimeout = setTimeout(function() {
|
482
|
+
e.preventDefault();
|
483
|
+
if (touch && touch.el) {
|
484
|
+
touch.el.trigger('swipe');
|
485
|
+
touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)));
|
486
|
+
touch = {};
|
487
|
+
}
|
488
|
+
}, 0);
|
489
|
+
// Normal tap:
|
490
|
+
} else if ('last' in touch) {
|
491
|
+
// Delay by one tick so we can cancel the 'tap' event if 'scroll' fires:
|
492
|
+
tapTimeout = setTimeout(function() {
|
493
|
+
// Trigger universal 'tap' with the option to cancelTouch():
|
494
|
+
if (touch && touch.el) {
|
495
|
+
touch.el.trigger('tap');
|
496
|
+
}
|
497
|
+
// Trigger double tap immediately:
|
498
|
+
if (touch && touch.isDoubleTap) {
|
499
|
+
if (touch && touch.el) {
|
500
|
+
touch.el.trigger('doubletap');
|
501
|
+
touch = {};
|
502
|
+
}
|
503
|
+
} else {
|
504
|
+
// Trigger single tap after singleTapDelay:
|
505
|
+
touchTimeout = setTimeout(function(){
|
506
|
+
touchTimeout = null;
|
507
|
+
if (touch && touch.el) {
|
508
|
+
touch.el.trigger('singletap');
|
509
|
+
touch = {};
|
510
|
+
return false;
|
511
|
+
}
|
512
|
+
}, singleTapDelay);
|
513
|
+
}
|
514
|
+
}, 0);
|
515
|
+
}
|
516
|
+
} else { return; }
|
517
|
+
}
|
518
|
+
});
|
519
|
+
body.on($.eventEnd, function(e) {
|
520
|
+
if (window.navigator.msPointerEnabled) {
|
521
|
+
if (window && window.jQuery && $ === window.jQuery) {
|
522
|
+
if (e.originalEvent && !e.originalEvent.isPrimary) return;
|
523
|
+
} else {
|
524
|
+
if (!e.isPrimary) return;
|
525
|
+
}
|
526
|
+
}
|
527
|
+
cancelLongTap();
|
528
|
+
if (!!touch.el) {
|
529
|
+
// Swipe detection:
|
530
|
+
if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > $.gestureLength) ||
|
531
|
+
(touch.y2 && Math.abs(touch.y1 - touch.y2) > $.gestureLength)) {
|
532
|
+
swipeTimeout = setTimeout(function() {
|
533
|
+
if (touch && touch.el) {
|
534
|
+
touch.el.trigger('swipe');
|
535
|
+
touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)));
|
536
|
+
touch = {};
|
537
|
+
}
|
538
|
+
}, 0);
|
539
|
+
// Normal tap:
|
540
|
+
} else if ('last' in touch) {
|
541
|
+
// Delay by one tick so we can cancel the 'tap' event if 'scroll' fires:
|
542
|
+
tapTimeout = setTimeout(function() {
|
543
|
+
// Trigger universal 'tap' with the option to cancelTouch():
|
544
|
+
if (touch && touch.el) {
|
545
|
+
touch.el.trigger('tap');
|
546
|
+
}
|
547
|
+
// Trigger double tap immediately:
|
548
|
+
if (touch && touch.isDoubleTap) {
|
549
|
+
if (touch && touch.el) {
|
550
|
+
touch.el.trigger('doubletap');
|
551
|
+
touch = {};
|
552
|
+
}
|
553
|
+
} else {
|
554
|
+
// Trigger single tap after singleTapDelay:
|
555
|
+
touchTimeout = setTimeout(function(){
|
556
|
+
touchTimeout = null;
|
557
|
+
if (touch && touch.el) {
|
558
|
+
touch.el.trigger('singletap');
|
559
|
+
touch = {};
|
560
|
+
return false;
|
561
|
+
}
|
562
|
+
}, singleTapDelay);
|
563
|
+
}
|
564
|
+
}, 0);
|
565
|
+
}
|
566
|
+
} else { return; }
|
567
|
+
});
|
568
|
+
body.on('touchcancel', cancelAll);
|
569
|
+
});
|
570
|
+
['swipe', 'swipeleft', 'swiperight', 'swipeup', 'swipedown', 'doubletap', 'tap', 'singletap', 'longtap'].forEach(function(method){
|
571
|
+
// Add gesture events to ChocolateChipJS:
|
572
|
+
$.fn.extend({
|
573
|
+
method : function(callback){
|
574
|
+
return this.on(method, callback);
|
575
|
+
}
|
576
|
+
});
|
577
|
+
});
|
578
|
+
|
579
|
+
|
580
|
+
/////////////////////////////////////////
|
581
|
+
// Set classes for desktop compatibility:
|
582
|
+
/////////////////////////////////////////
|
583
|
+
$.extend({
|
584
|
+
UIDesktopCompat : function ( ) {
|
585
|
+
if ($.isDesktop && $.isSafari) {
|
586
|
+
$('body').addClass('isiOS').addClass('isDesktopSafari isDesktop');
|
587
|
+
} else if ($.isDesktop && $.isChrome) {
|
588
|
+
$('body').addClass('isAndroid').addClass('isDesktopChrome isDesktop');
|
589
|
+
}
|
590
|
+
}
|
591
|
+
});
|
592
|
+
$(function() {
|
593
|
+
$.UIDesktopCompat();
|
594
|
+
});
|
595
|
+
|
596
|
+
|
597
|
+
$(function() {
|
598
|
+
$.body = $('body');
|
599
|
+
|
600
|
+
//////////////////////
|
601
|
+
// Add the global nav:
|
602
|
+
//////////////////////
|
603
|
+
if (!$.body[0].classList.contains('splitlayout')) {
|
604
|
+
$('body').prepend("<nav id='global-nav'></nav>");
|
605
|
+
}
|
606
|
+
|
607
|
+
/////////////////////////////////////////////////
|
608
|
+
// Fix Split Layout to display properly on phone:
|
609
|
+
/////////////////////////////////////////////////
|
610
|
+
if ($.body[0].classList.contains('splitlayout')) {
|
611
|
+
if (window.innerWidth < 768) {
|
612
|
+
$('meta[name=viewport]').attr('content','width=device-width, initial-scale=0.45, maximum-scale=2, user-scalable=yes');
|
613
|
+
}
|
614
|
+
}
|
615
|
+
|
616
|
+
/////////////////////////////////////////////////////////
|
617
|
+
// Add class to nav when button on right.
|
618
|
+
// This allows us to adjust the nav h1 for small screens.
|
619
|
+
/////////////////////////////////////////////////////////
|
620
|
+
$('h1').each(function(idx, ctx) {
|
621
|
+
if (ctx.nextElementSibling && ctx.nextElementSibling.nodeName === 'A') {
|
622
|
+
ctx.classList.add('buttonOnRight');
|
623
|
+
}
|
624
|
+
});
|
625
|
+
|
626
|
+
//////////////////////////////////////////
|
627
|
+
// Get any toolbars and adjust the bottom
|
628
|
+
// of their corresponding articles:
|
629
|
+
//////////////////////////////////////////
|
630
|
+
$('.toolbar').prev('article').addClass('has-toolbar');
|
631
|
+
|
632
|
+
if ($.isiOS && $.isStandalone) {
|
633
|
+
$.body[0].classList.add('isStandalone');
|
634
|
+
}
|
635
|
+
});
|
636
|
+
|
637
|
+
|
638
|
+
/////////////////////////
|
639
|
+
// Hide and show navbars:
|
640
|
+
/////////////////////////
|
641
|
+
$.extend({
|
642
|
+
UIHideNavBar : function () {
|
643
|
+
$('nav').hide();
|
644
|
+
$.body.addClass('hide-navbars');
|
645
|
+
},
|
646
|
+
|
647
|
+
UIShowNavBar : function () {
|
648
|
+
$('nav').show();
|
649
|
+
$.body.removeClass('hide-navbars');
|
650
|
+
}
|
651
|
+
});
|
652
|
+
|
653
|
+
|
654
|
+
$.extend({
|
655
|
+
subscriptions : {},
|
656
|
+
|
657
|
+
// Topic: string defining topic: /some/topic
|
658
|
+
// Data: a string, number, array or object.
|
659
|
+
subscribe : function (topic, callback) {
|
660
|
+
if (!$.subscriptions[topic]) {
|
661
|
+
$.subscriptions[topic] = [];
|
662
|
+
}
|
663
|
+
var token = ($.Uuid());
|
664
|
+
$.subscriptions[topic].push({
|
665
|
+
token: token,
|
666
|
+
callback: callback
|
667
|
+
});
|
668
|
+
return token;
|
669
|
+
},
|
670
|
+
|
671
|
+
unsubscribe : function ( token ) {
|
672
|
+
setTimeout(function() {
|
673
|
+
for (var m in $.subscriptions) {
|
674
|
+
if ($.subscriptions[m]) {
|
675
|
+
for (var i = 0, len = $.subscriptions[m].length; i < len; i++) {
|
676
|
+
if ($.subscriptions[m][i].token === token) {
|
677
|
+
$.subscriptions[m].splice(i, 1);
|
678
|
+
return token;
|
679
|
+
}
|
680
|
+
}
|
681
|
+
}
|
682
|
+
}
|
683
|
+
return false;
|
684
|
+
});
|
685
|
+
},
|
686
|
+
|
687
|
+
publish : function ( topic, args ) {
|
688
|
+
if (!$.subscriptions[topic]) {
|
689
|
+
return false;
|
690
|
+
}
|
691
|
+
setTimeout(function () {
|
692
|
+
var len = $.subscriptions[topic] ? $.subscriptions[topic].length : 0;
|
693
|
+
while (len--) {
|
694
|
+
$.subscriptions[topic][len].callback(topic, args);
|
695
|
+
}
|
696
|
+
return true;
|
697
|
+
});
|
698
|
+
return true;
|
699
|
+
}
|
700
|
+
});
|
701
|
+
|
702
|
+
|
703
|
+
////////////////////////////////////
|
704
|
+
// Create custom navigationend event
|
705
|
+
////////////////////////////////////
|
706
|
+
function triggerNavigationEvent(target) {
|
707
|
+
var transition;
|
708
|
+
var tansitionDuration;
|
709
|
+
if ('transition' in document.body.style) {
|
710
|
+
transition = 'transition-duration';
|
711
|
+
} else if ('-webkit-transition' in document.body.style){
|
712
|
+
transition = '-webkit-transition-duration';
|
713
|
+
}
|
714
|
+
function determineDurationType (duration) {
|
715
|
+
if (/m/.test(duration)) {
|
716
|
+
return parseFloat(duration);
|
717
|
+
} else if (/s/.test(duration)) {
|
718
|
+
return parseFloat(duration) * 100;
|
719
|
+
}
|
720
|
+
}
|
721
|
+
tansitionDuration = determineDurationType($('article').eq(0).css(transition));
|
722
|
+
|
723
|
+
setTimeout(function() {
|
724
|
+
$(target).trigger({type: 'navigationend'});
|
725
|
+
}, tansitionDuration);
|
726
|
+
}
|
727
|
+
$.extend({
|
728
|
+
////////////////////////////////////////////////
|
729
|
+
// Manage location.hash for client side routing:
|
730
|
+
////////////////////////////////////////////////
|
731
|
+
UITrackHashNavigation : function ( url, delimiter ) {
|
732
|
+
url = url || true;
|
733
|
+
$.UISetHashOnUrl($.UINavigationHistory[$.UINavigationHistory.length-1], delimiter);
|
734
|
+
},
|
735
|
+
/////////////////////////////////////////////////////
|
736
|
+
// Set the hash according to where the user is going:
|
737
|
+
/////////////////////////////////////////////////////
|
738
|
+
UISetHashOnUrl : function ( url, delimiter ) {
|
739
|
+
delimiter = delimiter || '#/';
|
740
|
+
var hash;
|
741
|
+
if (/^#/.test(url)) {
|
742
|
+
hash = delimiter + (url.split('#')[1]);
|
743
|
+
} else {
|
744
|
+
hash = delimiter + url;
|
745
|
+
}
|
746
|
+
if ($.isAndroid) {
|
747
|
+
if (/#/.test(url)) {
|
748
|
+
url = url.split('#')[1];
|
749
|
+
}
|
750
|
+
if (/\//.test(url)) {
|
751
|
+
url = url.split('/')[1];
|
752
|
+
}
|
753
|
+
window.location.hash = '#/' + url;
|
754
|
+
} else {
|
755
|
+
window.history.replaceState('Object', 'Title', hash);
|
756
|
+
}
|
757
|
+
},
|
758
|
+
//////////////////////////////////////
|
759
|
+
// Navigate Back to Non-linear Article
|
760
|
+
//////////////////////////////////////
|
761
|
+
UIGoBackToArticle : function ( articleID ) {
|
762
|
+
var historyIndex = $.UINavigationHistory.indexOf(articleID);
|
763
|
+
var currentArticle = $('article.current');
|
764
|
+
var destination = $(articleID);
|
765
|
+
var currentToolbar;
|
766
|
+
var destinationToolbar;
|
767
|
+
if ($.UINavigationHistory.length === 0) {
|
768
|
+
destination = $('article:first-of-type');
|
769
|
+
$.UINavigationHistory.push('#' + destination[0].id);
|
770
|
+
}
|
771
|
+
var prevArticles;
|
772
|
+
if ($.UINavigationHistory.length > 1) {
|
773
|
+
prevArticles = $.UINavigationHistory.splice(historyIndex+1);
|
774
|
+
} else {
|
775
|
+
prevArticles = $('article.previous');
|
776
|
+
}
|
777
|
+
$.publish('chui/navigateBack/leave', currentArticle[0].id);
|
778
|
+
$.publish('chui/navigateBack/enter', destination[0].id);
|
779
|
+
currentArticle[0].scrollTop = 0;
|
780
|
+
destination[0].scrollTop = 0;
|
781
|
+
if (prevArticles.length) {
|
782
|
+
$.forEach(prevArticles, function(ctx) {
|
783
|
+
$(ctx).removeClass('previous').addClass('next');
|
784
|
+
$(ctx).prev().removeClass('previous').addClass('next');
|
785
|
+
});
|
786
|
+
}
|
787
|
+
currentToolbar = currentArticle.next().hazClass('toolbar');
|
788
|
+
destinationToolbar = destination.next().hazClass('toolbar');
|
789
|
+
destination.removeClass('previous next').addClass('current');
|
790
|
+
destination.prev().removeClass('previous next').addClass('current');
|
791
|
+
destinationToolbar.removeClass('previous next').addClass('current');
|
792
|
+
currentArticle.removeClass('current').addClass('next');
|
793
|
+
currentArticle.prev().removeClass('current').addClass('next');
|
794
|
+
currentToolbar.removeClass('current').addClass('next');
|
795
|
+
$('.toolbar.previous').removeClass('previous').addClass('next');
|
796
|
+
$.UISetHashOnUrl($.UINavigationHistory[$.UINavigationHistory.length-1]);
|
797
|
+
triggerNavigationEvent(destination);
|
798
|
+
},
|
799
|
+
////////////////////////////////////
|
800
|
+
// Navigate Back to Previous Article
|
801
|
+
////////////////////////////////////
|
802
|
+
UIGoBack : function () {
|
803
|
+
var histLen = $.UINavigationHistory.length;
|
804
|
+
var currentArticle = $('article.current');
|
805
|
+
var destination = $($.UINavigationHistory[histLen-2]);
|
806
|
+
var currentToolbar;
|
807
|
+
var destinationToolbar;
|
808
|
+
if (histLen === 0) {
|
809
|
+
destination = $('article:first-of-type');
|
810
|
+
$.UINavigationHistory.push('#' + destination[0].id);
|
811
|
+
}
|
812
|
+
$.publish('chui/navigateBack/leave', currentArticle[0].id);
|
813
|
+
$.publish('chui/navigateBack/enter', destination[0].id);
|
814
|
+
currentArticle[0].scrollTop = 0;
|
815
|
+
destination[0].scrollTop = 0;
|
816
|
+
currentToolbar = currentArticle.next().hazClass('toolbar');
|
817
|
+
destinationToolbar = destination.next().hazClass('toolbar');
|
818
|
+
destination.removeClass('previous').addClass('current');
|
819
|
+
destination.prev().removeClass('previous').addClass('current');
|
820
|
+
destinationToolbar.removeClass('previous').addClass('current');
|
821
|
+
currentArticle.removeClass('current').addClass('next');
|
822
|
+
currentArticle.prev().removeClass('current').addClass('next');
|
823
|
+
currentToolbar.removeClass('current').addClass('next');
|
824
|
+
$.UISetHashOnUrl($.UINavigationHistory[histLen-2]);
|
825
|
+
if ($.UINavigationHistory.length === 1) return;
|
826
|
+
$.UINavigationHistory.pop();
|
827
|
+
triggerNavigationEvent(destination);
|
828
|
+
},
|
829
|
+
isNavigating : false,
|
830
|
+
|
831
|
+
///////////////////////////////
|
832
|
+
// Navigate to Specific Article
|
833
|
+
///////////////////////////////
|
834
|
+
UIGoToArticle : function ( destination ) {
|
835
|
+
if ($.isNavigating) return;
|
836
|
+
$.isNavigating = true;
|
837
|
+
var current = $('article.current');
|
838
|
+
var currentNav = current.prev();
|
839
|
+
destination = $(destination);
|
840
|
+
var destinationID = '#' + destination[0].id;
|
841
|
+
var destinationNav = destination.prev();
|
842
|
+
var currentToolbar;
|
843
|
+
var destinationToolbar;
|
844
|
+
var navigationClass = 'next previous';
|
845
|
+
$.publish('chui/navigate/leave', current[0].id);
|
846
|
+
$.UINavigationHistory.push(destinationID);
|
847
|
+
$.publish('chui/navigate/enter', destination[0].id);
|
848
|
+
current[0].scrollTop = 0;
|
849
|
+
destination[0].scrollTop = 0;
|
850
|
+
currentToolbar = current.next().hazClass('toolbar');
|
851
|
+
destinationToolbar = destination.next().hazClass('toolbar');
|
852
|
+
current.removeClass('current').addClass('previous');
|
853
|
+
currentNav.removeClass('current').addClass('previous');
|
854
|
+
currentToolbar.removeClass('current').addClass('previous');
|
855
|
+
destination.removeClass(navigationClass).addClass('current');
|
856
|
+
destinationNav.removeClass(navigationClass).addClass('current');
|
857
|
+
destinationToolbar.removeClass(navigationClass).addClass('current');
|
858
|
+
|
859
|
+
$.UISetHashOnUrl(destination[0].id);
|
860
|
+
setTimeout(function() {
|
861
|
+
$.isNavigating = false;
|
862
|
+
}, 500);
|
863
|
+
triggerNavigationEvent(destination);
|
864
|
+
}
|
865
|
+
});
|
866
|
+
///////////////////
|
867
|
+
// Init navigation:
|
868
|
+
///////////////////
|
869
|
+
$(function() {
|
870
|
+
//////////////////////////////////////////
|
871
|
+
// Set first value for navigation history:
|
872
|
+
//////////////////////////////////////////
|
873
|
+
$.extend({
|
874
|
+
UINavigationHistory : ["#" + $('article').eq(0).attr('id')]
|
875
|
+
});
|
876
|
+
///////////////////////////////////////////////////////////
|
877
|
+
// Make sure that navs and articles have navigation states:
|
878
|
+
///////////////////////////////////////////////////////////
|
879
|
+
$('nav:not(#global-nav)').forEach(function(ctx, idx) {
|
880
|
+
// Prevent if splitlayout for tablets:
|
881
|
+
if ($('body')[0].classList.contains('splitlayout')) return;
|
882
|
+
if (idx === 0) {
|
883
|
+
ctx.classList.add('current');
|
884
|
+
} else {
|
885
|
+
ctx.classList.add('next');
|
886
|
+
}
|
887
|
+
});
|
888
|
+
|
889
|
+
$('article').forEach(function(ctx, idx) {
|
890
|
+
// Prevent if splitlayout for tablets:
|
891
|
+
if ($('body')[0].classList.contains('splitlayout')) return;
|
892
|
+
if ($('body')[0].classList.contains('slide-out-app')) return;
|
893
|
+
if (idx === 0) {
|
894
|
+
ctx.classList.add('current');
|
895
|
+
} else {
|
896
|
+
ctx.classList.add('next');
|
897
|
+
}
|
898
|
+
});
|
899
|
+
///////////////////////////
|
900
|
+
// Initialize Back Buttons:
|
901
|
+
///////////////////////////
|
902
|
+
$('body').on('singletap', 'a.back', function() {
|
903
|
+
if (this.classList.contains('back')) {
|
904
|
+
$.UIGoBack();
|
905
|
+
}
|
906
|
+
});
|
907
|
+
|
908
|
+
////////////////////////////////
|
909
|
+
// Handle navigation list items:
|
910
|
+
////////////////////////////////
|
911
|
+
$('body').on('singletap doubletap', 'li', function() {
|
912
|
+
var $this = $(this);
|
913
|
+
if ($.isNavigating) return;
|
914
|
+
if (!this.hasAttribute('data-goto')) return;
|
915
|
+
if (!this.getAttribute('data-goto')) return;
|
916
|
+
if (!document.getElementById(this.getAttribute('data-goto'))) return;
|
917
|
+
if ($(this).parent()[0].classList.contains('deletable')) return;
|
918
|
+
$this.addClass('selected');
|
919
|
+
var destinationHref = '#' + this.getAttribute('data-goto');
|
920
|
+
$(destinationHref).addClass('navigable');
|
921
|
+
setTimeout(function() {
|
922
|
+
$this.removeClass('selected');
|
923
|
+
}, 500);
|
924
|
+
var destination = $(destinationHref);
|
925
|
+
$.UIGoToArticle(destination);
|
926
|
+
});
|
927
|
+
$('li[data-goto]').forEach(function(ctx) {
|
928
|
+
$(ctx).closest('article').addClass('navigable');
|
929
|
+
var navigable = '#' + ctx.getAttribute('data-goto');
|
930
|
+
$(navigable).addClass('navigable');
|
931
|
+
});
|
932
|
+
|
933
|
+
/////////////////////////////////////
|
934
|
+
// Init navigation url hash tracking:
|
935
|
+
/////////////////////////////////////
|
936
|
+
// If there's more than one article:
|
937
|
+
if ($('article').eq(1)[0]) {
|
938
|
+
$.UISetHashOnUrl($('article').eq(0)[0].id);
|
939
|
+
}
|
940
|
+
/////////////////////////////////////////////////////////
|
941
|
+
// Stop rubber banding when dragging down on nav:
|
942
|
+
/////////////////////////////////////////////////////////
|
943
|
+
$('nav').on($.eventStart, function(e) {
|
944
|
+
e.preventDefault();
|
945
|
+
});
|
946
|
+
});
|
947
|
+
|
948
|
+
|
949
|
+
$(function() {
|
950
|
+
///////////////////////////////////
|
951
|
+
// Initialize singletap on buttons:
|
952
|
+
///////////////////////////////////
|
953
|
+
$('body').on('singletap', '.button', function() {
|
954
|
+
var $this = $(this);
|
955
|
+
if ($this.parent('.segmented')[0]) return;
|
956
|
+
if ($this.parent('.tabbar')[0]) return;
|
957
|
+
if ($.isDesktop) return;
|
958
|
+
$this.addClass('selected');
|
959
|
+
setTimeout(function() {
|
960
|
+
$this.removeClass('selected');
|
961
|
+
}, 500);
|
962
|
+
});
|
963
|
+
});
|
964
|
+
|
965
|
+
|
966
|
+
$.fn.extend({
|
967
|
+
/////////////////////////
|
968
|
+
// Block Screen with Mask
|
969
|
+
/////////////////////////
|
970
|
+
UIBlock : function ( opacity ) {
|
971
|
+
opacity = opacity ? " style='opacity:" + opacity + "'" : " style='opacity: .5;'";
|
972
|
+
$(this).before("<div class='mask'" + opacity + "></div>");
|
973
|
+
$('article.current').attr('aria-hidden',true);
|
974
|
+
return this;
|
975
|
+
},
|
976
|
+
|
977
|
+
//////////////////////////
|
978
|
+
// Remove Mask from Screen
|
979
|
+
//////////////////////////
|
980
|
+
UIUnblock : function ( ) {
|
981
|
+
$('.mask').remove();
|
982
|
+
$('article.current').removeAttr('aria-hidden');
|
983
|
+
return this;
|
984
|
+
}
|
985
|
+
});
|
986
|
+
|
987
|
+
|
988
|
+
$.fn.extend({
|
989
|
+
//////////////////////////////
|
990
|
+
// Center an Element on Screen
|
991
|
+
//////////////////////////////
|
992
|
+
UICenter : function ( position ) {
|
993
|
+
var position = position;
|
994
|
+
if (!this[0]) return;
|
995
|
+
var $this = $(this);
|
996
|
+
var parent = $this.parent();
|
997
|
+
if (position) {
|
998
|
+
$(this.css('position', position));
|
999
|
+
} else if ($this.css('position') === 'absolute') {
|
1000
|
+
position = 'absolute';
|
1001
|
+
} else {
|
1002
|
+
position = 'relative';
|
1003
|
+
}
|
1004
|
+
var height, width, parentHeight, parentWidth;
|
1005
|
+
if (position === 'absolute') {
|
1006
|
+
height = $this[0].clientHeight;
|
1007
|
+
width = $this[0].clientWidth;
|
1008
|
+
parentHeight = parent[0].clientHeight;
|
1009
|
+
parentWidth = parent[0].clientWidth;
|
1010
|
+
} else {
|
1011
|
+
height = parseInt($this.css('height'),10);
|
1012
|
+
width = parseInt($this.css('width'),10);
|
1013
|
+
parentHeight = parseInt(parent.css('height'),10);
|
1014
|
+
parentWidth = parseInt(parent.css('width'),10);
|
1015
|
+
$(this).css({'margin-left': 'auto', 'margin-right': 'auto'});
|
1016
|
+
}
|
1017
|
+
var tmpTop, tmpLeft;
|
1018
|
+
if (parent[0].nodeName === 'body') {
|
1019
|
+
tmpTop = ((window.innerHeight /2) + window.pageYOffset) - height /2 + 'px';
|
1020
|
+
tmpLeft = ((window.innerWidth / 2) - (width / 2) + 'px');
|
1021
|
+
} else {
|
1022
|
+
tmpTop = (parentHeight /2) - (height /2) + 'px';
|
1023
|
+
tmpLeft = (parentWidth / 2) - (width / 2) + 'px';
|
1024
|
+
}
|
1025
|
+
if (position !== 'absolute') tmpLeft = 0;
|
1026
|
+
// if (parseInt(tmpLeft,10) <= 0) tmpLeft = '10px';
|
1027
|
+
$this.css({left: tmpLeft, top: tmpTop});
|
1028
|
+
}
|
1029
|
+
});
|
1030
|
+
|
1031
|
+
|
1032
|
+
$.fn.extend({
|
1033
|
+
////////////////////////
|
1034
|
+
// Create Busy indicator
|
1035
|
+
////////////////////////
|
1036
|
+
/*
|
1037
|
+
var options = {
|
1038
|
+
color: 'red',
|
1039
|
+
size: '80px',
|
1040
|
+
position: 'right'
|
1041
|
+
}
|
1042
|
+
*/
|
1043
|
+
UIBusy : function ( options ) {
|
1044
|
+
var count = 1;
|
1045
|
+
options = options || {};
|
1046
|
+
var settings = {
|
1047
|
+
size: 43,
|
1048
|
+
color: '#000',
|
1049
|
+
position: false,
|
1050
|
+
duration: '2s'
|
1051
|
+
};
|
1052
|
+
$.extend(settings, options);
|
1053
|
+
var $this = this;
|
1054
|
+
var spinner;
|
1055
|
+
// For iOS:
|
1056
|
+
var iOSBusy = function() {
|
1057
|
+
var webkitAnim = {'-webkit-animation-duration': settings.duration};
|
1058
|
+
spinner = $('<span class="busy"></span>');
|
1059
|
+
$(spinner).css({'background-color': settings.color, 'height': settings.size, 'width': settings.size});
|
1060
|
+
$(spinner).css(webkitAnim);
|
1061
|
+
$(spinner).attr('role','progressbar');
|
1062
|
+
if (settings.position) $(spinner).addClass(settings.position);
|
1063
|
+
$this.append(spinner);
|
1064
|
+
return this;
|
1065
|
+
};
|
1066
|
+
// For Android:
|
1067
|
+
var androidBusy = function() {
|
1068
|
+
settings.id = $.Uuid();
|
1069
|
+
var androidActivityIndicator = null;
|
1070
|
+
var position = settings.position ? (' ' + settings.position) : '';
|
1071
|
+
if ($.isNativeAndroid) {
|
1072
|
+
androidActivityIndicator = '<svg class="busy' + position + '" version="1.1" id="' + settings.id + '" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve"><g><path fill="none" stroke="' + settings.color + '" stroke-width="10" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M74.2,65c2.7-4.4,4.3-9.5,4.3-15c0-15.7-12.8-28.5-28.5-28.5S21.5,34.3,21.5,50c0,5.5,1.6,10.6,4.3,15"/></g><polyline fill="none" stroke="' + settings.color + '" stroke-width="10" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="89.4,56.1 74.3,65 65.4,49.9 "/></svg>';
|
1073
|
+
|
1074
|
+
$this.append(androidActivityIndicator);
|
1075
|
+
return;
|
1076
|
+
} else {
|
1077
|
+
androidActivityIndicator = '<svg id="'+ settings.id +'" class="busy' + position + '" x="0px" y="0px" viewBox="0 0 100 100"><circle stroke="url(#SVGID_1_)" cx="50" cy="50" r="28.5"/></svg>';
|
1078
|
+
$this.append(androidActivityIndicator);
|
1079
|
+
$this.addClass('hasActivityIndicator');
|
1080
|
+
if (settings.position) {
|
1081
|
+
$('#' + settings.id).addClass(settings.position);
|
1082
|
+
}
|
1083
|
+
if (options.color) {
|
1084
|
+
$('#' + settings.id).find('circle').css('stroke', options.color);
|
1085
|
+
}
|
1086
|
+
$('#' + settings.id).css({'height': settings.size + 'px', 'width': settings.size + 'px'});
|
1087
|
+
}
|
1088
|
+
return $('#' + settings.id);
|
1089
|
+
};
|
1090
|
+
// For Windows 8/WP8:
|
1091
|
+
var winBusy = function() {
|
1092
|
+
spinner = $('<progress class="busy"></progress>');
|
1093
|
+
$(spinner).css({ 'color': settings.color });
|
1094
|
+
$(spinner).attr('role','progressbar');
|
1095
|
+
$(spinner).addClass('win-ring');
|
1096
|
+
if (settings.position) $(spinner).addClass(settings.position);
|
1097
|
+
$this.append(spinner);
|
1098
|
+
return this;
|
1099
|
+
};
|
1100
|
+
// Create Busy control for appropriate OS:
|
1101
|
+
if ($.isWin) {
|
1102
|
+
winBusy(options);
|
1103
|
+
} else if ($.isAndroid || $.isChrome) {
|
1104
|
+
androidBusy(options);
|
1105
|
+
} else if ($.isiOS || $.isSafari) {
|
1106
|
+
iOSBusy(options);
|
1107
|
+
}
|
1108
|
+
}
|
1109
|
+
});
|
1110
|
+
|
1111
|
+
|
1112
|
+
$.extend({
|
1113
|
+
///////////////
|
1114
|
+
// Create Popup
|
1115
|
+
///////////////
|
1116
|
+
UIPopup : function( options ) {
|
1117
|
+
/*
|
1118
|
+
options {
|
1119
|
+
id: 'alertID',
|
1120
|
+
title: 'Alert',
|
1121
|
+
message: 'This is a message from me to you.',
|
1122
|
+
cancelButton: 'Cancel',
|
1123
|
+
continueButton: 'Go Ahead',
|
1124
|
+
callback: function() { // do nothing }
|
1125
|
+
}
|
1126
|
+
*/
|
1127
|
+
if (!options) return;
|
1128
|
+
var id = options.id || $.Uuid();
|
1129
|
+
var title = options.title ? '<header><h1>' + options.title + '</h1></header>' : '';
|
1130
|
+
var message = options.message ? '<p role="note">' + options.message + '</p>' : '';
|
1131
|
+
var cancelButton = options.cancelButton ? '<a href="javascript:void(null)" class="button cancel" role="button">' + options.cancelButton + '</a>' : '';
|
1132
|
+
var continueButton = options.continueButton ? '<a href="javascript:void(null)" class="button continue" role="button">' + options.continueButton + '</a>' : '';
|
1133
|
+
var callback = options.callback || $.noop;
|
1134
|
+
var padding = options.empty ? ' noTitle' : '';
|
1135
|
+
var panelOpen, panelClose;
|
1136
|
+
var popup = $.concat('<div class="popup closed', padding, '" role="alertdialog" id="', id, '"><div class="panel">', title, message, '</div><footer>', cancelButton, continueButton, '</footer>', panelClose, '</div>');
|
1137
|
+
|
1138
|
+
$('body').append(popup);
|
1139
|
+
if (callback && continueButton) {
|
1140
|
+
$('.popup').find('.continue').on($.eventStart, function() {
|
1141
|
+
$('.popup').UIPopupClose();
|
1142
|
+
callback.call(callback);
|
1143
|
+
});
|
1144
|
+
}
|
1145
|
+
|
1146
|
+
$.UICenterPopup();
|
1147
|
+
setTimeout(function() {
|
1148
|
+
$('body').find('.popup').removeClass('closed');
|
1149
|
+
}, 200);
|
1150
|
+
$('body').find('.popup').UIBlock('0.5');
|
1151
|
+
var events = $.eventStart + ' singletap ' + $.eventEnd;
|
1152
|
+
$('.mask').on(events, function(e) {
|
1153
|
+
e.stopPropagation();
|
1154
|
+
});
|
1155
|
+
},
|
1156
|
+
|
1157
|
+
//////////////////////////////////////////
|
1158
|
+
// Center Popups When Orientation Changes:
|
1159
|
+
//////////////////////////////////////////
|
1160
|
+
UICenterPopup : function ( ) {
|
1161
|
+
var popup = $('.popup');
|
1162
|
+
if (!popup[0]) return;
|
1163
|
+
var tmpTop = ((window.innerHeight /2) + window.pageYOffset) - (popup[0].clientHeight /2) + 'px';
|
1164
|
+
var tmpLeft;
|
1165
|
+
if (window.innerWidth === 320) {
|
1166
|
+
tmpLeft = '10px';
|
1167
|
+
} else {
|
1168
|
+
tmpLeft = Math.floor((window.innerWidth - 318) /2) + 'px';
|
1169
|
+
}
|
1170
|
+
if ($.isWin) {
|
1171
|
+
popup.css({top: tmpTop});
|
1172
|
+
} else {
|
1173
|
+
popup.css({left: tmpLeft, top: tmpTop});
|
1174
|
+
}
|
1175
|
+
}
|
1176
|
+
});
|
1177
|
+
$.fn.extend({
|
1178
|
+
//////////////
|
1179
|
+
// Close Popup
|
1180
|
+
//////////////
|
1181
|
+
UIPopupClose : function ( ) {
|
1182
|
+
if (!this && !this.classList.contains('popup')) return;
|
1183
|
+
$(this).UIUnblock();
|
1184
|
+
$(this).remove();
|
1185
|
+
}
|
1186
|
+
});
|
1187
|
+
$(function() {
|
1188
|
+
//////////////////////////
|
1189
|
+
// Handle Closing Popups:
|
1190
|
+
//////////////////////////
|
1191
|
+
$('body').on($.eventStart, '.cancel', function() {
|
1192
|
+
if ($(this).closest('.popup')[0]) {
|
1193
|
+
$(this).closest('.popup').UIPopupClose();
|
1194
|
+
}
|
1195
|
+
});
|
1196
|
+
/////////////////////////////////////////////////
|
1197
|
+
// Reposition popups on window resize:
|
1198
|
+
/////////////////////////////////////////////////
|
1199
|
+
$(window).on('resize', function() {
|
1200
|
+
$.UICenterPopup();
|
1201
|
+
});
|
1202
|
+
});
|
1203
|
+
|
1204
|
+
|
1205
|
+
$.extend({
|
1206
|
+
/////////////////
|
1207
|
+
// Create Popover
|
1208
|
+
/////////////////
|
1209
|
+
/*
|
1210
|
+
id: myUniqueID,
|
1211
|
+
title: 'Great',
|
1212
|
+
callback: myCallback,
|
1213
|
+
*/
|
1214
|
+
UIPopover : function ( options ) {
|
1215
|
+
options = options || {};
|
1216
|
+
var settings = {
|
1217
|
+
id: $.Uuid(),
|
1218
|
+
callback: $.noop,
|
1219
|
+
title: '',
|
1220
|
+
};
|
1221
|
+
$.extend(settings, options);
|
1222
|
+
if (options && options.content) {
|
1223
|
+
settings.content = options.content;
|
1224
|
+
} else {
|
1225
|
+
settings.content = '';
|
1226
|
+
}
|
1227
|
+
var header = '<header><h1>' + settings.title + '</h1></header>';
|
1228
|
+
var popover = '<div class="popover" id="' + settings.id + '">' + header + '<section></section></div>';
|
1229
|
+
var popoverID = '#' + settings.id;
|
1230
|
+
|
1231
|
+
// Calculate position of popover relative to the button that opened it:
|
1232
|
+
var _calcPopPos = function (element) {
|
1233
|
+
var offset = $(element).offset();
|
1234
|
+
var left = offset.left;
|
1235
|
+
var calcLeft;
|
1236
|
+
var calcTop;
|
1237
|
+
var popover = $(popoverID);
|
1238
|
+
var popoverOffset = popover.offset();
|
1239
|
+
calcLeft = popoverOffset.left;
|
1240
|
+
calcTop = offset.top + $(element)[0].clientHeight;
|
1241
|
+
if ((popover.width() + offset.left) > window.innerWidth) {
|
1242
|
+
popover.css({
|
1243
|
+
'left': ((window.innerWidth - popover.width())-20) + 'px',
|
1244
|
+
'top': (calcTop + 20) + 'px'
|
1245
|
+
});
|
1246
|
+
} else {
|
1247
|
+
popover.css({'left': left + 'px', 'top': (calcTop + 20) + 'px'});
|
1248
|
+
}
|
1249
|
+
};
|
1250
|
+
|
1251
|
+
if ($('.mask')[0]) {
|
1252
|
+
$.UIPopoverClose();
|
1253
|
+
$('body').UIUnblock();
|
1254
|
+
return;
|
1255
|
+
}
|
1256
|
+
$('body').append(popover);
|
1257
|
+
if ($.isWin) {
|
1258
|
+
$(popoverID).addClass('open');
|
1259
|
+
}
|
1260
|
+
$(popoverID).data('triggerEl', settings.trigger);
|
1261
|
+
$(popoverID).find('section').append(settings.content);
|
1262
|
+
settings.callback.call(settings.callback, settings.trigger);
|
1263
|
+
_calcPopPos(settings.trigger);
|
1264
|
+
$('.popover').UIBlock('.5');
|
1265
|
+
|
1266
|
+
}
|
1267
|
+
});
|
1268
|
+
$.extend({
|
1269
|
+
///////////////////////////////////////
|
1270
|
+
// Align the Popover Before Showing it:
|
1271
|
+
///////////////////////////////////////
|
1272
|
+
UIAlignPopover : function () {
|
1273
|
+
var popover = $('.popover');
|
1274
|
+
if (!popover.length) return;
|
1275
|
+
var triggerID = popover.data('triggerEl');
|
1276
|
+
var offset = $(triggerID).offset();
|
1277
|
+
var left = offset.left;
|
1278
|
+
if (($(popover).width() + offset.left) > window.innerWidth) {
|
1279
|
+
popover.css({
|
1280
|
+
'left': ((window.innerWidth - $(popover).width())-20) + 'px'
|
1281
|
+
});
|
1282
|
+
} else {
|
1283
|
+
popover.css({'left': left + 'px'});
|
1284
|
+
}
|
1285
|
+
}
|
1286
|
+
});
|
1287
|
+
$.extend({
|
1288
|
+
UIPopoverClose : function ( ) {
|
1289
|
+
$('body').UIUnblock();
|
1290
|
+
$('.popover').css('visibility','hidden');
|
1291
|
+
setTimeout(function() {
|
1292
|
+
$('.popover').remove();
|
1293
|
+
},10);
|
1294
|
+
}
|
1295
|
+
});
|
1296
|
+
$(function() {
|
1297
|
+
/////////////////////////////////////////////////
|
1298
|
+
// Reposition popovers on window resize:
|
1299
|
+
/////////////////////////////////////////////////
|
1300
|
+
$(window).on('resize', function() {
|
1301
|
+
$.UIAlignPopover();
|
1302
|
+
});
|
1303
|
+
var events = $.eventStart + ' singletap ' + $.eventEnd;
|
1304
|
+
$('body').on(events, '.mask', function(e) {
|
1305
|
+
if (!$('.popover')[0]) {
|
1306
|
+
if (e && e.nodeType === 1) return;
|
1307
|
+
e.stopPropogation();
|
1308
|
+
} else {
|
1309
|
+
$.UIPopoverClose();
|
1310
|
+
}
|
1311
|
+
});
|
1312
|
+
});
|
1313
|
+
|
1314
|
+
|
1315
|
+
$.fn.extend({
|
1316
|
+
///////////////////////////////
|
1317
|
+
// Initialize Segmented Control
|
1318
|
+
///////////////////////////////
|
1319
|
+
UISegmented : function ( options ) {
|
1320
|
+
/*
|
1321
|
+
var options = {
|
1322
|
+
selected: 0,
|
1323
|
+
callback: function() { alert('Boring!'); }
|
1324
|
+
}
|
1325
|
+
*/
|
1326
|
+
if ($(this).hazClass('paging').length) return;
|
1327
|
+
var callback = (options && options.callback) ? options.callback : $.noop;
|
1328
|
+
var selected = (options && options.selected > 0) ? options.selected : 0;
|
1329
|
+
this.find('a').forEach(function(ctx, idx) {
|
1330
|
+
$(ctx).find('a').attr('role','radio');
|
1331
|
+
if (idx === selected) {
|
1332
|
+
ctx.setAttribute('aria-checked', 'true');
|
1333
|
+
ctx.classList.add('selected');
|
1334
|
+
}
|
1335
|
+
});
|
1336
|
+
this.on('singletap', '.button', function(e) {
|
1337
|
+
var $this = $(this);
|
1338
|
+
if (this.parentNode.classList.contains('paging')) return;
|
1339
|
+
$this.siblings('a').removeClass('selected');
|
1340
|
+
$this.siblings('a').removeAttr('aria-checked');
|
1341
|
+
$this.addClass('selected');
|
1342
|
+
$this.attr('aria-checked', true);
|
1343
|
+
callback.call(this, e);
|
1344
|
+
});
|
1345
|
+
}
|
1346
|
+
});
|
1347
|
+
$.extend({
|
1348
|
+
///////////////////////////
|
1349
|
+
// Create Segmented Control
|
1350
|
+
///////////////////////////
|
1351
|
+
UICreateSegmented : function ( options ) {
|
1352
|
+
/*
|
1353
|
+
options = {
|
1354
|
+
id : '#myId',
|
1355
|
+
className : 'special' || '',
|
1356
|
+
labels : ['first','second','third'],
|
1357
|
+
selected: 0
|
1358
|
+
}
|
1359
|
+
*/
|
1360
|
+
var segmented;
|
1361
|
+
var id = (options && options.id) ? options.id : $.Uuid();
|
1362
|
+
var className = (options && options.className) ? options.className : '';
|
1363
|
+
var labels = (options && options.labels) ? options.labels : [];
|
1364
|
+
var selected = (options && options.selected) ? options.selected : 0;
|
1365
|
+
var _segmented = ['<div class="segmented'];
|
1366
|
+
if (className) _segmented.push(' ' + className);
|
1367
|
+
_segmented.push('">');
|
1368
|
+
labels.forEach(function(ctx, idx) {
|
1369
|
+
_segmented.push('<a role="radio" class="button');
|
1370
|
+
_segmented.push('"');
|
1371
|
+
_segmented.push('>');
|
1372
|
+
_segmented.push(ctx);
|
1373
|
+
_segmented.push('</a>');
|
1374
|
+
});
|
1375
|
+
_segmented.push('</div>');
|
1376
|
+
segmented = $(_segmented.join(''));
|
1377
|
+
segmented.attr('id', id);
|
1378
|
+
return segmented;
|
1379
|
+
}
|
1380
|
+
});
|
1381
|
+
|
1382
|
+
|
1383
|
+
$.fn.extend({
|
1384
|
+
////////////////////////////////////////////
|
1385
|
+
// Allow Segmented Control to toggle panels
|
1386
|
+
////////////////////////////////////////////
|
1387
|
+
UIPanelToggle : function ( panel, callback ) {
|
1388
|
+
var panels;
|
1389
|
+
var selected = 0;
|
1390
|
+
selected = this.children().hazClass('selected').index() || 0;
|
1391
|
+
if (panel instanceof Array) {
|
1392
|
+
panels = panel.children('div');
|
1393
|
+
} else if (typeof panel === 'string') {
|
1394
|
+
panels = $(panel).children('div');
|
1395
|
+
}
|
1396
|
+
panels.eq(selected).siblings().css({display: 'none'});
|
1397
|
+
if (callback) callback.apply(this, arguments);
|
1398
|
+
this.on($.eventEnd, 'a', function() {
|
1399
|
+
panels.eq($(this).index()).css({display:'block'})
|
1400
|
+
.siblings().css('display','none');
|
1401
|
+
});
|
1402
|
+
|
1403
|
+
this.on('singletap', '.button', function() {
|
1404
|
+
var $this = $(this);
|
1405
|
+
if (this.parentNode.classList.contains('paging')) return;
|
1406
|
+
$this.siblings('a').removeClass('selected');
|
1407
|
+
$this.siblings('a').removeAttr('aria-checked');
|
1408
|
+
$this.addClass('selected');
|
1409
|
+
$this.attr('aria-checked', true);
|
1410
|
+
});
|
1411
|
+
}
|
1412
|
+
});
|
1413
|
+
|
1414
|
+
|
1415
|
+
$.extend({
|
1416
|
+
///////////////////////
|
1417
|
+
// Setup Paging Control
|
1418
|
+
///////////////////////
|
1419
|
+
UIPaging : function ( ) {
|
1420
|
+
var currentArticle = $('.segmented.paging').closest('nav').next();
|
1421
|
+
if ($('.segmented.paging').hazClass('horizontal').length) {
|
1422
|
+
currentArticle.addClass('horizontal');
|
1423
|
+
} else if ($('.segmented.paging').hazClass('vertical').length) {
|
1424
|
+
currentArticle.addClass('vertical');
|
1425
|
+
}
|
1426
|
+
|
1427
|
+
currentArticle.children().eq(0).addClass('current');
|
1428
|
+
currentArticle.children().eq(0).siblings().addClass('next');
|
1429
|
+
var sections = function() {
|
1430
|
+
return currentArticle.children().length;
|
1431
|
+
};
|
1432
|
+
var pageBack = function($this) {
|
1433
|
+
if (sections() === 1) return;
|
1434
|
+
$this.next().removeClass('selected');
|
1435
|
+
$this.addClass('selected');
|
1436
|
+
var currentSection;
|
1437
|
+
currentSection = $('section.current');
|
1438
|
+
if (currentSection.index() === 0) {
|
1439
|
+
currentSection.removeClass('current');
|
1440
|
+
currentArticle.children().eq(sections() - 1).addClass('current').removeClass('next');
|
1441
|
+
currentArticle.children().eq(sections() - 1).siblings().removeClass('next').addClass('previous');
|
1442
|
+
} else {
|
1443
|
+
currentSection.removeClass('current').addClass('next');
|
1444
|
+
currentSection.prev().removeClass('previous').addClass('current');
|
1445
|
+
}
|
1446
|
+
setTimeout(function() {
|
1447
|
+
$this.removeClass('selected');
|
1448
|
+
}, 250);
|
1449
|
+
};
|
1450
|
+
var pageForward = function ($this) {
|
1451
|
+
if (sections() === 1) return;
|
1452
|
+
$this.prev().removeClass('selected');
|
1453
|
+
$this.addClass('selected');
|
1454
|
+
var currentSection;
|
1455
|
+
if ($this[0].classList.contains('disabled')) return;
|
1456
|
+
currentSection = $('section.current');
|
1457
|
+
if (currentSection.index() === sections() - 1) {
|
1458
|
+
// start again!
|
1459
|
+
currentSection.removeClass('current');
|
1460
|
+
currentArticle.children().eq(0).addClass('current').removeClass('previous');
|
1461
|
+
currentArticle.children().eq(0).siblings().removeClass('previous').addClass('next');
|
1462
|
+
} else {
|
1463
|
+
currentSection.removeClass('current').addClass('previous');
|
1464
|
+
currentSection.next().removeClass('next').addClass('current');
|
1465
|
+
}
|
1466
|
+
setTimeout(function() {
|
1467
|
+
$this.removeClass('selected');
|
1468
|
+
}, 250);
|
1469
|
+
};
|
1470
|
+
$('.segmented.paging').on($.eventStart, '.button:first-of-type', function() {
|
1471
|
+
pageBack($(this));
|
1472
|
+
});
|
1473
|
+
$('.segmented.paging').on($.eventStart, '.button:last-of-type', function() {
|
1474
|
+
pageForward($(this));
|
1475
|
+
});
|
1476
|
+
// Handle swipe gestures for paging:
|
1477
|
+
if ($('article.paging.horizontal')[0]) {
|
1478
|
+
$('article.paging').on('swiperight', function() {
|
1479
|
+
pageBack($('.button:first-of-type'));
|
1480
|
+
});
|
1481
|
+
$('article.paging').on('swipeleft', function() {
|
1482
|
+
pageForward($('.button:last-of-type'));
|
1483
|
+
});
|
1484
|
+
}
|
1485
|
+
if ($('article.paging.vertical')[0]) {
|
1486
|
+
$('article.paging').on('swipeup', function() {
|
1487
|
+
pageBack($('.button:first-of-type'));
|
1488
|
+
});
|
1489
|
+
$('article.paging').on('swipeudown', function() {
|
1490
|
+
pageForward($('.button:last-of-type'));
|
1491
|
+
});
|
1492
|
+
}
|
1493
|
+
}
|
1494
|
+
});
|
1495
|
+
|
1496
|
+
|
1497
|
+
$.fn.extend({
|
1498
|
+
////////////////////////////
|
1499
|
+
// Initialize Editable List,
|
1500
|
+
// allows moving items and
|
1501
|
+
// deleting them.
|
1502
|
+
////////////////////////////
|
1503
|
+
UIEditList : function ( options ) {
|
1504
|
+
/*
|
1505
|
+
options = {
|
1506
|
+
editLabel : labelName,
|
1507
|
+
doneLabel : labelName,
|
1508
|
+
deleteLabel : labelName,
|
1509
|
+
callback : callback (Tapping "Done" fires this),
|
1510
|
+
deletable: false (no deletables),
|
1511
|
+
movable: false (no movables)
|
1512
|
+
}
|
1513
|
+
*/
|
1514
|
+
var settings = {
|
1515
|
+
editLabel : 'Edit',
|
1516
|
+
doneLabel : 'Done',
|
1517
|
+
deleteLabel : 'Delete',
|
1518
|
+
callback : $.noop,
|
1519
|
+
deletable: true,
|
1520
|
+
movable: true
|
1521
|
+
};
|
1522
|
+
if (!options) {
|
1523
|
+
return;
|
1524
|
+
}
|
1525
|
+
$.extend(settings, options);
|
1526
|
+
|
1527
|
+
if (!settings.deletable && !settings.movable) {
|
1528
|
+
return;
|
1529
|
+
}
|
1530
|
+
|
1531
|
+
var editLabel = settings.editLabel;
|
1532
|
+
var doneLabel = settings.doneLabel;
|
1533
|
+
var deleteLabel = settings.deleteLabel;
|
1534
|
+
var placement = settings.placement;
|
1535
|
+
var callback = settings.callback;
|
1536
|
+
|
1537
|
+
var deleteButton;
|
1538
|
+
var editButton;
|
1539
|
+
var deletionIndicator;
|
1540
|
+
var button;
|
1541
|
+
var dispelDeletable = 'swiperight';
|
1542
|
+
var enableDeletable = 'swipeleft';
|
1543
|
+
var moveUpIndicator;
|
1544
|
+
var moveDownIndicator;
|
1545
|
+
var dir = $('html').attr('dir');
|
1546
|
+
dir = dir ? dir.toLowerCase() : '';
|
1547
|
+
if (dir === 'rtl') {
|
1548
|
+
dispelDeletable = 'swipeleft';
|
1549
|
+
enableDeletable = 'swiperight';
|
1550
|
+
}
|
1551
|
+
// Windows uses an icon for the delete button:
|
1552
|
+
if ($.isWin) deleteLabel = '';
|
1553
|
+
var height = $('li').eq(0)[0].clientHeight;
|
1554
|
+
|
1555
|
+
if (settings.deletable) {
|
1556
|
+
deleteButton = $.concat('<a href="javascript:void(null)" class="button delete">', deleteLabel, '</a>');
|
1557
|
+
deletionIndicator = '<span class="deletion-indicator"></span>';
|
1558
|
+
$(this).addClass('deletable');
|
1559
|
+
}
|
1560
|
+
if (settings.movable) {
|
1561
|
+
var moveUpIndicator = "<span class='move-up'></span>";
|
1562
|
+
var moveDownIndicator = "<span class='move-down'></span>";
|
1563
|
+
$(this).addClass('editable');
|
1564
|
+
}
|
1565
|
+
editButton = $.concat('<a href="javascript:void(null)" class="button edit">', editLabel, '</a>');
|
1566
|
+
if (!$(this).closest('article').prev().find('.edit')[0] && !$(this).closest('article').prev().find('.done')[0]) {
|
1567
|
+
$(this).closest('article').prev().append(editButton);
|
1568
|
+
}
|
1569
|
+
|
1570
|
+
button = $(this).closest('article').prev().find('.edit');
|
1571
|
+
$(this).find('li').forEach(function(ctx) {
|
1572
|
+
if (!$(ctx).has('.deletion-indicator').length) {
|
1573
|
+
if (settings.deletable) {
|
1574
|
+
$(ctx).prepend(deletionIndicator);
|
1575
|
+
}
|
1576
|
+
if (settings.movable) {
|
1577
|
+
$(ctx).append(moveUpIndicator);
|
1578
|
+
$(ctx).append(moveDownIndicator);
|
1579
|
+
}
|
1580
|
+
if (settings.deletable) {
|
1581
|
+
$(ctx).append(deleteButton);
|
1582
|
+
}
|
1583
|
+
}
|
1584
|
+
});
|
1585
|
+
|
1586
|
+
var listData = [];
|
1587
|
+
this.find('li').each(function(_, ctx) {
|
1588
|
+
listData.push($(ctx).attr('data-ui-value'));
|
1589
|
+
});
|
1590
|
+
|
1591
|
+
// Callback to setup indicator interactions:
|
1592
|
+
var setupDeletability = function(callback, list, button) {
|
1593
|
+
$(function() {
|
1594
|
+
button.on('singletap', function() {
|
1595
|
+
var $this = this;
|
1596
|
+
|
1597
|
+
// When button is in "Edit" state:
|
1598
|
+
if (this.classList.contains('edit')) {
|
1599
|
+
setTimeout(function() {
|
1600
|
+
$this.classList.remove('edit');
|
1601
|
+
$this.classList.add('done');
|
1602
|
+
$($this).text(settings.doneLabel);
|
1603
|
+
$(list).addClass('showIndicators');
|
1604
|
+
});
|
1605
|
+
|
1606
|
+
// When button is in "Done" state:
|
1607
|
+
} else if (this.classList.contains('done')) {
|
1608
|
+
// Execute callback if edit was performed:
|
1609
|
+
//========================================
|
1610
|
+
if ($(list).data('list-edit')) {
|
1611
|
+
callback.call(callback, $this);
|
1612
|
+
}
|
1613
|
+
setTimeout(function() {
|
1614
|
+
$this.classList.remove('done');
|
1615
|
+
$this.classList.add('edit');
|
1616
|
+
$($this).text(settings.editLabel);
|
1617
|
+
$(list).removeClass('showIndicators');
|
1618
|
+
$(list).find('li').removeClass('selected');
|
1619
|
+
});
|
1620
|
+
}
|
1621
|
+
});
|
1622
|
+
|
1623
|
+
// Handle deletion indicators:
|
1624
|
+
$(list).off('singletap', '.deletion-indicator');
|
1625
|
+
$(list).on('singletap', '.deletion-indicator', function() {
|
1626
|
+
if ($(this).parent('li').hazClass('selected').length) {
|
1627
|
+
$(this).parent('li').removeClass('selected');
|
1628
|
+
return;
|
1629
|
+
} else {
|
1630
|
+
$(this).parent('li').addClass('selected');
|
1631
|
+
}
|
1632
|
+
});
|
1633
|
+
|
1634
|
+
// Handle swipe gestures:
|
1635
|
+
$(list).on(dispelDeletable, 'li', function() {
|
1636
|
+
// If no deletables, disable swipes:
|
1637
|
+
if (!settings.deletable) return;
|
1638
|
+
// Else reveal delete button:
|
1639
|
+
$(this).removeClass('selected');
|
1640
|
+
});
|
1641
|
+
|
1642
|
+
$(list).on(enableDeletable, 'li', function() {
|
1643
|
+
// If no deletables, disable swipes:
|
1644
|
+
if (!settings.deletable) return;
|
1645
|
+
// Else reveal delete button:
|
1646
|
+
$(this).addClass('selected');
|
1647
|
+
});
|
1648
|
+
|
1649
|
+
// Move list item up:
|
1650
|
+
$(list).on('singletap', '.move-up', function(e) {
|
1651
|
+
var item = $(this).closest('li');
|
1652
|
+
if (item.is('li:first-child')) {
|
1653
|
+
return;
|
1654
|
+
} else {
|
1655
|
+
// Mark list as edited:
|
1656
|
+
$(list).data('list-edit', true);
|
1657
|
+
var clone = $(this).closest('li').clone();
|
1658
|
+
item.prev().before(clone);
|
1659
|
+
item.remove();
|
1660
|
+
}
|
1661
|
+
});
|
1662
|
+
|
1663
|
+
// Move list item down:
|
1664
|
+
$(list).on('singletap', '.move-down', function(e) {
|
1665
|
+
var item = $(this).closest('li');
|
1666
|
+
if (item.is('li:last-child')) {
|
1667
|
+
return;
|
1668
|
+
} else {
|
1669
|
+
// Mark list as edited:
|
1670
|
+
$(list).data('list-edit', true);
|
1671
|
+
var clone = $(this).closest('li').clone();
|
1672
|
+
item.next().after(clone);
|
1673
|
+
item.remove();
|
1674
|
+
}
|
1675
|
+
});
|
1676
|
+
|
1677
|
+
// Handle deletion of list item:
|
1678
|
+
$(list).on('singletap', '.delete', function() {
|
1679
|
+
var $this = this;
|
1680
|
+
// Mark list as edited:
|
1681
|
+
$(list).data('list-edit', true);
|
1682
|
+
var direction = '-1000%';
|
1683
|
+
if ($('html').attr('dir') === 'rtl') direction = '1000%';
|
1684
|
+
$(this).siblings().css({'-webkit-transform': 'translate3d(' + direction + ',0,0)', '-webkit-transition': 'all 1s ease-out'});
|
1685
|
+
setTimeout(function() {
|
1686
|
+
$($this).parent().remove();
|
1687
|
+
}, 500);
|
1688
|
+
});
|
1689
|
+
});
|
1690
|
+
};
|
1691
|
+
// Initialize the editable list:
|
1692
|
+
return setupDeletability(settings.callback, $(this), button);
|
1693
|
+
}
|
1694
|
+
|
1695
|
+
});
|
1696
|
+
|
1697
|
+
|
1698
|
+
$.fn.extend({
|
1699
|
+
/////////////////////////
|
1700
|
+
// Initialize Select List
|
1701
|
+
/////////////////////////
|
1702
|
+
/*
|
1703
|
+
// For default selection use zero-based integer:
|
1704
|
+
options = {
|
1705
|
+
name : name // used on radio buttons as group name, defaults to uuid.
|
1706
|
+
selected : integer,
|
1707
|
+
callback : callback
|
1708
|
+
// callback example:
|
1709
|
+
function () {
|
1710
|
+
// this is the selected list item:
|
1711
|
+
console.log($(this).text());
|
1712
|
+
}
|
1713
|
+
}
|
1714
|
+
*/
|
1715
|
+
UISelectList : function (options) {
|
1716
|
+
var name = (options && options.name) ? options.name : $.Uuid();
|
1717
|
+
var list = this[0];
|
1718
|
+
list.classList.add('select');
|
1719
|
+
$(list).find('li').forEach(function(ctx, idx) {
|
1720
|
+
var value = ctx.getAttribute("data-select-value") !== null ? ctx.getAttribute("data-select-value") : "";
|
1721
|
+
ctx.setAttribute('role', 'radio');
|
1722
|
+
$(ctx).removeClass('selected').find('input').removeAttr('checked');
|
1723
|
+
if (options && options.selected === idx) {
|
1724
|
+
ctx.setAttribute('aria-checked', 'true');
|
1725
|
+
ctx.classList.add('selected');
|
1726
|
+
if (!$(ctx).find('input')[0]) {
|
1727
|
+
$(ctx).append('<input type="radio" checked="checked" name="' + name + '" value="' + value +'">');
|
1728
|
+
} else {
|
1729
|
+
$(ctx).find('input').prop('checked',true).attr('value', value);
|
1730
|
+
}
|
1731
|
+
} else {
|
1732
|
+
if (!$(ctx).find('input')[0]) {
|
1733
|
+
$(ctx).append('<input type="radio" name="' + name + '" value="' + value +'">');
|
1734
|
+
}
|
1735
|
+
}
|
1736
|
+
});
|
1737
|
+
$(list).on('singletap', 'li', function() {
|
1738
|
+
var item = this;
|
1739
|
+
$(item).siblings('li').removeClass('selected');
|
1740
|
+
$(item).siblings('li').removeAttr('aria-checked');
|
1741
|
+
$(item).siblings('li').find('input').removeAttr('checked');
|
1742
|
+
$(item).addClass('selected');
|
1743
|
+
item.setAttribute('aria-checked', true);
|
1744
|
+
$(item).find('input').prop('checked',true);
|
1745
|
+
if (options && options.callback) {
|
1746
|
+
options.callback.apply(this, arguments);
|
1747
|
+
}
|
1748
|
+
});
|
1749
|
+
}
|
1750
|
+
});
|
1751
|
+
|
1752
|
+
|
1753
|
+
$.extend({
|
1754
|
+
///////////////////////////////////////////////
|
1755
|
+
// UISheet: Create an Overlay for Buttons, etc.
|
1756
|
+
///////////////////////////////////////////////
|
1757
|
+
/*
|
1758
|
+
var options {
|
1759
|
+
id : 'starTrek',
|
1760
|
+
listClass :'enterprise',
|
1761
|
+
background: 'transparent',
|
1762
|
+
}
|
1763
|
+
*/
|
1764
|
+
UISheet : function ( options ) {
|
1765
|
+
var id = $.Uuid();
|
1766
|
+
var listClass = '';
|
1767
|
+
var background = '';
|
1768
|
+
if (options) {
|
1769
|
+
id = options.id ? options.id : id;
|
1770
|
+
listClass = options.listClass ? ' ' + options.listClass : '';
|
1771
|
+
background = ' style="background-color:' + options.background + ';" ' || '';
|
1772
|
+
}
|
1773
|
+
var sheet = '<div id="' + id + '" class="sheet' + listClass + '"><div class="handle"></div><section class="scroller-vertical"></section></div>';
|
1774
|
+
$('body').append(sheet);
|
1775
|
+
$('.sheet .handle').on($.eventStart, function() {
|
1776
|
+
$.UIHideSheet();
|
1777
|
+
});
|
1778
|
+
},
|
1779
|
+
UIShowSheet : function ( ) {
|
1780
|
+
$('article.current').addClass('blurred');
|
1781
|
+
if ($.isAndroid || $.isChrome) {
|
1782
|
+
$('.sheet').css('display','block');
|
1783
|
+
setTimeout(function() {
|
1784
|
+
$('.sheet').addClass('opened');
|
1785
|
+
}, 20);
|
1786
|
+
} else {
|
1787
|
+
$('.sheet').addClass('opened');
|
1788
|
+
}
|
1789
|
+
},
|
1790
|
+
UIHideSheet : function ( ) {
|
1791
|
+
$('.sheet').removeClass('opened');
|
1792
|
+
$('article.current').addClass('removeBlurSlow');
|
1793
|
+
setTimeout(function() {
|
1794
|
+
$('article').removeClass('blurred');
|
1795
|
+
$('article').removeClass('removeBlurSlow');
|
1796
|
+
},500);
|
1797
|
+
}
|
1798
|
+
});
|
1799
|
+
|
1800
|
+
|
1801
|
+
$.extend({
|
1802
|
+
////////////////////////////////////////////////
|
1803
|
+
// Create Slideout with toggle button.
|
1804
|
+
// Use $.UISlideout.populate to polate slideout.
|
1805
|
+
// See widget-factor.js for details.
|
1806
|
+
////////////////////////////////////////////////
|
1807
|
+
/*
|
1808
|
+
var options = {
|
1809
|
+
position: position,
|
1810
|
+
dynamic: false,
|
1811
|
+
callback: $.noop
|
1812
|
+
};
|
1813
|
+
*/
|
1814
|
+
UISlideout : function ( options ) {
|
1815
|
+
var position, dynamic, callback = $.noop;
|
1816
|
+
if (options && options.position) {
|
1817
|
+
position = options.position;
|
1818
|
+
} else {
|
1819
|
+
position = 'left';
|
1820
|
+
}
|
1821
|
+
if (options && options.dynamic) {
|
1822
|
+
dynamic = options.dynamic;
|
1823
|
+
} else {
|
1824
|
+
dynamic = false;
|
1825
|
+
}
|
1826
|
+
if (options && options.callback) {
|
1827
|
+
callback = options.callback;
|
1828
|
+
}
|
1829
|
+
var slideoutButton = $("<a class='button slide-out-button' href='javascript:void(null)'></a>");
|
1830
|
+
var slideOut = '<div class="slide-out"><section></section></div>';
|
1831
|
+
$('article').removeClass('next');
|
1832
|
+
$('article').removeClass('current');
|
1833
|
+
$('article').prev().removeClass('next');
|
1834
|
+
$('article').prev().removeClass('current');
|
1835
|
+
$('body').append(slideOut);
|
1836
|
+
$('body').addClass('slide-out-app');
|
1837
|
+
$('article:first-of-type').addClass('show');
|
1838
|
+
$('article:first-of-type').prev().addClass('show');
|
1839
|
+
$('#global-nav').append(slideoutButton);
|
1840
|
+
$('.slide-out-button').on($.eventStart, function() {
|
1841
|
+
$('.slide-out').toggleClass('open');
|
1842
|
+
});
|
1843
|
+
if (!dynamic) {
|
1844
|
+
$('.slide-out').on('singletap', 'li', function() {
|
1845
|
+
var whichArticle = '#' + $(this).attr('data-show-article');
|
1846
|
+
$.UINavigationHistory[0] = whichArticle;
|
1847
|
+
$.UISetHashOnUrl(whichArticle);
|
1848
|
+
$.publish('chui/navigate/leave', $('article.show')[0].id);
|
1849
|
+
$.publish('chui/navigate/enter', whichArticle);
|
1850
|
+
$('.slide-out').removeClass('open');
|
1851
|
+
$('article').removeClass('show');
|
1852
|
+
$('article').prev().removeClass('show');
|
1853
|
+
$(whichArticle).addClass('show');
|
1854
|
+
$(whichArticle).prev().addClass('show');
|
1855
|
+
});
|
1856
|
+
} else {
|
1857
|
+
$('.slide-out').on('singletap', 'li', function() {
|
1858
|
+
callback(this);
|
1859
|
+
});
|
1860
|
+
}
|
1861
|
+
}
|
1862
|
+
});
|
1863
|
+
$.extend($.UISlideout, {
|
1864
|
+
/////////////////////////////////////////////////////////////////
|
1865
|
+
// Method to populate a slideout with actionable items.
|
1866
|
+
// The argument is an array of objects consisting of a key/value.
|
1867
|
+
// The key will be the id of the article to be shown.
|
1868
|
+
// The value is the title for the list item.
|
1869
|
+
// [{music:'Music'},{docs:'Documents'},{recipes:'Recipes'}]
|
1870
|
+
/////////////////////////////////////////////////////////////////
|
1871
|
+
populate: function( args ) {
|
1872
|
+
var slideout = $('.slide-out');
|
1873
|
+
if (!slideout[0]) return;
|
1874
|
+
if (!$.isArray(args)) {
|
1875
|
+
return;
|
1876
|
+
} else {
|
1877
|
+
slideout.find('section').append('<ul class="list"></ul>');
|
1878
|
+
var list = slideout.find('ul');
|
1879
|
+
args.forEach(function(ctx) {
|
1880
|
+
for (var key in ctx) {
|
1881
|
+
if (key === 'header') {
|
1882
|
+
list.append('<li class="slideout-header"><h2>'+ctx[key]+'</h2></li>');
|
1883
|
+
} else {
|
1884
|
+
list.append('<li data-show-article="' + key + '"><h3>' + ctx[key] + '</h3></li>');
|
1885
|
+
}
|
1886
|
+
}
|
1887
|
+
});
|
1888
|
+
}
|
1889
|
+
}
|
1890
|
+
});
|
1891
|
+
|
1892
|
+
|
1893
|
+
$.fn.extend({
|
1894
|
+
/////////////////
|
1895
|
+
// Create stepper
|
1896
|
+
/////////////////
|
1897
|
+
/*
|
1898
|
+
var options = {
|
1899
|
+
start: 0,
|
1900
|
+
end: 10,
|
1901
|
+
defaultValue: 3
|
1902
|
+
}
|
1903
|
+
*/
|
1904
|
+
UIStepper : function (options) {
|
1905
|
+
if (!options) return [];
|
1906
|
+
if (!options.start) return [];
|
1907
|
+
if (!options.end) return [];
|
1908
|
+
var stepper = $(this);
|
1909
|
+
var start = options.start;
|
1910
|
+
var end = options.end;
|
1911
|
+
var defaultValue = options.defaultValue ? options.defaultValue : options.start;
|
1912
|
+
var increaseSymbol = '+';
|
1913
|
+
var decreaseSymbol = '-';
|
1914
|
+
if ($.isWin) {
|
1915
|
+
increaseSymbol = '';
|
1916
|
+
decreaseSymbol = '';
|
1917
|
+
}
|
1918
|
+
var decreaseButton = '<a href="javascript:void(null)" class="button decrease">' + decreaseSymbol + '</a>';
|
1919
|
+
var label = '<label>' + defaultValue + '</label><input type="text" value="' + defaultValue + '">';
|
1920
|
+
var increaseButton = '<a href="javascript:void(null)" class="button increase">' + increaseSymbol + '</a>';
|
1921
|
+
stepper.append(decreaseButton + label + increaseButton);
|
1922
|
+
stepper.data('ui-value', {start: start, end: end, defaultValue: defaultValue});
|
1923
|
+
|
1924
|
+
var decreaseStepperValue = function() {
|
1925
|
+
var currentValue = stepper.find('input').val();
|
1926
|
+
var value = stepper.data('ui-value');
|
1927
|
+
var start = value.start;
|
1928
|
+
var newValue;
|
1929
|
+
if (currentValue <= start) {
|
1930
|
+
$(this).addClass('disabled');
|
1931
|
+
} else {
|
1932
|
+
newValue = Number(currentValue) - 1;
|
1933
|
+
stepper.find('.button:last-of-type').removeClass('disabled');
|
1934
|
+
stepper.find('label').text(newValue);
|
1935
|
+
stepper.find('input')[0].value = newValue;
|
1936
|
+
if (currentValue === start) {
|
1937
|
+
$(this).addClass('disabled');
|
1938
|
+
}
|
1939
|
+
}
|
1940
|
+
};
|
1941
|
+
|
1942
|
+
var increaseStepperValue = function() {
|
1943
|
+
var currentValue = stepper.find('input').val();
|
1944
|
+
var value = stepper.data('ui-value');
|
1945
|
+
var end = value.end;
|
1946
|
+
var newValue;
|
1947
|
+
if (currentValue >= end) {
|
1948
|
+
$(this).addClass('disabled');
|
1949
|
+
} else {
|
1950
|
+
newValue = Number(currentValue) + 1;
|
1951
|
+
stepper.find('.button:first-of-type').removeClass('disabled');
|
1952
|
+
stepper.find('label').text(newValue);
|
1953
|
+
stepper.find('input')[0].value = newValue;
|
1954
|
+
if (currentValue === end) {
|
1955
|
+
$(this).addClass('disabled');
|
1956
|
+
}
|
1957
|
+
}
|
1958
|
+
};
|
1959
|
+
stepper.find('.button:first-of-type').on('singletap', function() {
|
1960
|
+
decreaseStepperValue.call(this, stepper);
|
1961
|
+
});
|
1962
|
+
stepper.find('.button:last-of-type').on('singletap', function() {
|
1963
|
+
increaseStepperValue.call(this, stepper);
|
1964
|
+
});
|
1965
|
+
}
|
1966
|
+
});
|
1967
|
+
$.extend({
|
1968
|
+
///////////////////////////////////////////
|
1969
|
+
// Pass the id of the stepper to reset.
|
1970
|
+
// It's value will be reset to the default.
|
1971
|
+
///////////////////////////////////////////
|
1972
|
+
// Pass it the id of the stepper:
|
1973
|
+
UIResetStepper : function ( stepper ) {
|
1974
|
+
var defaultValue = stepper.data('ui-value').defaultValue;
|
1975
|
+
stepper.find('label').html(defaultValue);
|
1976
|
+
stepper.find('input')[0].value = defaultValue;
|
1977
|
+
}
|
1978
|
+
});
|
1979
|
+
|
1980
|
+
|
1981
|
+
$.fn.extend({
|
1982
|
+
////////////////////////////
|
1983
|
+
// Initialize Switch Control
|
1984
|
+
////////////////////////////
|
1985
|
+
UISwitch : function ( ) {
|
1986
|
+
var hasThumb = false;
|
1987
|
+
this.forEach(function(ctx, idx) {
|
1988
|
+
ctx.setAttribute('role','checkbox');
|
1989
|
+
if ($(ctx).data('ui-setup') === true) return;
|
1990
|
+
if (!ctx.querySelector('input')) {
|
1991
|
+
ctx.insertAdjacentHTML('afterBegin', '<input type="checkbox">');
|
1992
|
+
}
|
1993
|
+
if (ctx.classList.contains('on')) {
|
1994
|
+
ctx.querySelector('input').setAttribute('checked', 'checked');
|
1995
|
+
}
|
1996
|
+
if (ctx.querySelector('em')) hasThumb = true;
|
1997
|
+
if (!hasThumb) {
|
1998
|
+
ctx.insertAdjacentHTML('afterBegin', '<em></em>');
|
1999
|
+
}
|
2000
|
+
$(ctx).on('singletap', function() {
|
2001
|
+
var checkbox = ctx.querySelector('input');
|
2002
|
+
if (ctx.classList.contains('on')) {
|
2003
|
+
ctx.classList.remove('on');
|
2004
|
+
ctx.removeAttribute('aria-checked');
|
2005
|
+
checkbox.removeAttribute('checked');
|
2006
|
+
} else {
|
2007
|
+
ctx.classList.add('on');
|
2008
|
+
checkbox.setAttribute('checked', 'checked');
|
2009
|
+
ctx.setAttribute('aria-checked', true);
|
2010
|
+
}
|
2011
|
+
});
|
2012
|
+
$(ctx).on('swipeleft', function() {
|
2013
|
+
var checkbox = ctx.querySelector('input');
|
2014
|
+
if (ctx.classList.contains('on')) {
|
2015
|
+
ctx.classList.remove('on');
|
2016
|
+
ctx.removeAttribute('aria-checked');
|
2017
|
+
checkbox.removeAttribute('checked');
|
2018
|
+
}
|
2019
|
+
});
|
2020
|
+
$(ctx).on('swiperight', function() {
|
2021
|
+
var checkbox = ctx.querySelector('input');
|
2022
|
+
if (!ctx.classList.contains('on')) {
|
2023
|
+
ctx.classList.add('on');
|
2024
|
+
checkbox.setAttribute('checked', 'checked');
|
2025
|
+
ctx.setAttribute('aria-checked', true);
|
2026
|
+
}
|
2027
|
+
});
|
2028
|
+
$(ctx).data('ui-setup', true);
|
2029
|
+
});
|
2030
|
+
}
|
2031
|
+
});
|
2032
|
+
$.extend({
|
2033
|
+
////////////////////////
|
2034
|
+
// Create Switch Control
|
2035
|
+
////////////////////////
|
2036
|
+
UICreateSwitch : function ( options ) {
|
2037
|
+
/* options = {
|
2038
|
+
id : '#myId',
|
2039
|
+
name: 'fruit.mango'
|
2040
|
+
state : 'on' || 'off' //(off is default),
|
2041
|
+
value : 'Mango' || '',
|
2042
|
+
callback : callback
|
2043
|
+
}
|
2044
|
+
*/
|
2045
|
+
var id = options ? options.id : $.Uuid();
|
2046
|
+
var name = options && options.name ? (' name="' + options.name + '"') : '';
|
2047
|
+
var value= options && options.value ? (' value="' + options.value + '"') : '';
|
2048
|
+
var state = (options && options.state === 'on') ? (' ' + options.state) : '';
|
2049
|
+
var checked = (options && options.state === 'on') ? ' checked="checked"' : '';
|
2050
|
+
var _switch = $.concat('<span class="switch', state,
|
2051
|
+
'" id="', id, '"><em></em>','<input type="checkbox"',
|
2052
|
+
name, checked, value, '></span>');
|
2053
|
+
return $(_switch);
|
2054
|
+
}
|
2055
|
+
});
|
2056
|
+
$(function() {
|
2057
|
+
//////////////////////////
|
2058
|
+
// Handle Existing Switches:
|
2059
|
+
//////////////////////////
|
2060
|
+
$('.switch').UISwitch();
|
2061
|
+
});
|
2062
|
+
|
2063
|
+
|
2064
|
+
document.addEventListener('touchstart', function (e) {
|
2065
|
+
var parent = e.target,
|
2066
|
+
i = 0;
|
2067
|
+
|
2068
|
+
for (i = 0; i < 10; i += 1) {
|
2069
|
+
if (parent !== null) {
|
2070
|
+
if (parent.className !== undefined) {
|
2071
|
+
if (parent.className.match('navigable')) {
|
2072
|
+
if (parent.scrollTop === 0) {
|
2073
|
+
parent.scrollTop = 1;
|
2074
|
+
} else if ((parent.scrollTop + parent.offsetHeight) === parent.scrollHeight) {
|
2075
|
+
parent.scrollTop = parent.scrollTop - 1;
|
2076
|
+
}
|
2077
|
+
}
|
2078
|
+
}
|
2079
|
+
parent = parent.parentNode;
|
2080
|
+
}
|
2081
|
+
}
|
2082
|
+
});
|
2083
|
+
|
2084
|
+
|
2085
|
+
$.extend({
|
2086
|
+
///////////////////////////////////////////
|
2087
|
+
// Creates a Tab Bar for Toggling Articles:
|
2088
|
+
///////////////////////////////////////////
|
2089
|
+
UITabbar : function ( options ) {
|
2090
|
+
/*
|
2091
|
+
var options = {
|
2092
|
+
id: 'mySpecialTabbar',
|
2093
|
+
tabs: 4,
|
2094
|
+
labels: ["Refresh", "Add", "Info", "Downloads", "Favorite"],
|
2095
|
+
icons: ["refresh", "add", "info", "downloads", "favorite"],
|
2096
|
+
selected: 2
|
2097
|
+
}
|
2098
|
+
*/
|
2099
|
+
if (!options) return;
|
2100
|
+
var settings = {
|
2101
|
+
id : $.Uuid(),
|
2102
|
+
selected : 0
|
2103
|
+
};
|
2104
|
+
$.extend(settings, options);
|
2105
|
+
$('body').addClass('hasTabBar');
|
2106
|
+
if ($.isiOS6) $('body').addClass('isiOS6');
|
2107
|
+
var tabbar = '<div class="tabbar" id="' + settings.id + '">';
|
2108
|
+
var icon = ($.isiOS || $.isSafari) ? '<span class="icon"></span>' : '';
|
2109
|
+
var articles = $('article');
|
2110
|
+
for (var i = 0; i < settings.tabs; i++) {
|
2111
|
+
tabbar += '<a class="button ' + settings.icons[i];
|
2112
|
+
if (settings.selected === i+1) {
|
2113
|
+
tabbar += ' selected';
|
2114
|
+
}
|
2115
|
+
tabbar += '">' + icon + '<label>' + settings.labels[i] + '</label></a>';
|
2116
|
+
}
|
2117
|
+
tabbar += '</div>';
|
2118
|
+
$('body').append(tabbar);
|
2119
|
+
|
2120
|
+
//////////////////////////////////////////////////////
|
2121
|
+
// Add article id as history data attribute to button:
|
2122
|
+
//////////////////////////////////////////////////////
|
2123
|
+
$('#' + settings.id).find('.button').each(function(idx, ctx){
|
2124
|
+
$(ctx).data('history', ['#' + articles.eq(idx)[0].id]);
|
2125
|
+
});
|
2126
|
+
$('nav').removeClass('current').addClass('next');
|
2127
|
+
$('#global-nav').removeClass('next');
|
2128
|
+
$('nav').eq(settings.selected).removeClass('next').addClass('current');
|
2129
|
+
$('article').removeClass('current').addClass('next');
|
2130
|
+
$('article').eq(settings.selected-1).removeClass('next').addClass('current');
|
2131
|
+
|
2132
|
+
// Setup events on tabs:
|
2133
|
+
$('.tabbar').on('singletap', '.button', function() {
|
2134
|
+
var $this = this;
|
2135
|
+
var index;
|
2136
|
+
var id;
|
2137
|
+
$.publish('chui/navigate/leave', $('article.current')[0].id);
|
2138
|
+
|
2139
|
+
//////////////////////////////////////////////////
|
2140
|
+
// Set the data attribute for the current history:
|
2141
|
+
//////////////////////////////////////////////////
|
2142
|
+
$(this).siblings('.selected').data('history', $.UINavigationHistory);
|
2143
|
+
|
2144
|
+
$this.classList.add('selected');
|
2145
|
+
$($this).siblings('a').removeClass('selected');
|
2146
|
+
index = $(this).index();
|
2147
|
+
$('article.previous').removeClass('previous').addClass('next');
|
2148
|
+
$('nav.previous').removeClass('previous').addClass('next');
|
2149
|
+
|
2150
|
+
/////////////////////////////////////////////////////////////////
|
2151
|
+
// Update the history array with the current tabs stored history:
|
2152
|
+
/////////////////////////////////////////////////////////////////
|
2153
|
+
var history = $(this).data('history');
|
2154
|
+
|
2155
|
+
///////////////////////////////////////////////
|
2156
|
+
// If the history array has more than one item,
|
2157
|
+
// we know that it is a navigation link.
|
2158
|
+
///////////////////////////////////////////////
|
2159
|
+
if (history.length > 1) {
|
2160
|
+
$('article.current').removeClass('current').addClass('next');
|
2161
|
+
$('nav.current').removeClass('current').addClass('next');
|
2162
|
+
|
2163
|
+
/////////////////////////////////////////////////
|
2164
|
+
// Set saved state of navigation list to current:
|
2165
|
+
/////////////////////////////////////////////////
|
2166
|
+
$(history[history.length-1]).removeClass('next').addClass('current');
|
2167
|
+
$(history[history.length-1]).prev().removeClass('next').addClass('current');
|
2168
|
+
|
2169
|
+
////////////////////////////////////////////////////
|
2170
|
+
// Set state for earlier screens of navigation list:
|
2171
|
+
////////////////////////////////////////////////////
|
2172
|
+
var prevScreens = history.length-1;
|
2173
|
+
for (var i = 0; i < prevScreens; i++) {
|
2174
|
+
$(history[i]).removeClass('next').addClass('previous');
|
2175
|
+
$(history[i]).prev().removeClass('next').addClass('previous');
|
2176
|
+
}
|
2177
|
+
|
2178
|
+
////////////////////////////////////////////////
|
2179
|
+
// Otherwise, since the array has only one item,
|
2180
|
+
// we are dealing with a single tabbar panel.
|
2181
|
+
////////////////////////////////////////////////
|
2182
|
+
} else {
|
2183
|
+
$('article.current').removeClass('current').addClass('next');
|
2184
|
+
$('nav.current').removeClass('current').addClass('next');
|
2185
|
+
$('article').eq(index).removeClass('next').addClass('current');
|
2186
|
+
$('nav').eq(index+1).removeClass('next').addClass('current');
|
2187
|
+
}
|
2188
|
+
|
2189
|
+
id = $('article').eq(index)[0].id;
|
2190
|
+
$.publish('chui/navigate/enter', id);
|
2191
|
+
|
2192
|
+
// Set the chosen tab article's scroll to top:
|
2193
|
+
//============================================
|
2194
|
+
$('article').forEach(function(ctx) {
|
2195
|
+
if (window.jQuery) {
|
2196
|
+
$(ctx).scrollTop(0);
|
2197
|
+
} else if (window.$chocolatechipjs) {
|
2198
|
+
ctx.scrollTop = 0;
|
2199
|
+
}
|
2200
|
+
});
|
2201
|
+
$.UISetHashOnUrl('#'+id);
|
2202
|
+
$.UINavigationHistory = $(this).data('history');
|
2203
|
+
});
|
2204
|
+
}
|
2205
|
+
});
|
2206
|
+
|
2207
|
+
|
2208
|
+
$.extend({
|
2209
|
+
/////////////////////////////
|
2210
|
+
// Templating:
|
2211
|
+
/////////////////////////////
|
2212
|
+
templates : {},
|
2213
|
+
|
2214
|
+
template : function ( tmpl, variable ) {
|
2215
|
+
var regex;
|
2216
|
+
variable = variable || 'data';
|
2217
|
+
regex = /\[\[=([\s\S]+?)\]\]/g;
|
2218
|
+
var template = new Function(variable,
|
2219
|
+
"var p=[];" + "p.push('" + tmpl
|
2220
|
+
.replace(/[\r\t\n]/g, " ")
|
2221
|
+
.split("'").join("\\'")
|
2222
|
+
.replace(regex,"',$1,'")
|
2223
|
+
.split('[[').join("');")
|
2224
|
+
.split(']]').join("p.push('") + "');" +
|
2225
|
+
"return p.join('');");
|
2226
|
+
return template;
|
2227
|
+
}
|
2228
|
+
});
|
2229
|
+
|
2230
|
+
|
2231
|
+
/////////////////////////
|
2232
|
+
// Create a search input:
|
2233
|
+
/////////////////////////
|
2234
|
+
/*
|
2235
|
+
$.UISearch({
|
2236
|
+
articleId: '#products',
|
2237
|
+
id: 'productSearch',
|
2238
|
+
placeholder: 'Find a product',
|
2239
|
+
results: 5
|
2240
|
+
})
|
2241
|
+
*/
|
2242
|
+
$.extend({
|
2243
|
+
UISearch : function(options) {
|
2244
|
+
var article = options && options.articleId || $('article').eq(0);
|
2245
|
+
var searchID = options && options.id || $.Uuid();
|
2246
|
+
var placeholder = options && options.placeholder || 'search';
|
2247
|
+
var results = options && options.results || 1;
|
2248
|
+
var widget = '<div class="searchBar"><input placeholder="' + placeholder +'" type="search" results="' + results + '" id="'+ searchID + '"></div>';
|
2249
|
+
$(article).find('section').prepend(widget);
|
2250
|
+
if ($.isWin) {
|
2251
|
+
$(article).prev().append(widget);
|
2252
|
+
$('#' + searchID).parent().append('<span class="searchGlyph"></span>');
|
2253
|
+
}
|
2254
|
+
}
|
2255
|
+
});
|
2256
|
+
|
2257
|
+
|
2258
|
+
//////////////////////////////////
|
2259
|
+
// Initialize a swipeable carousel:
|
2260
|
+
//////////////////////////////////
|
2261
|
+
$(function() {
|
2262
|
+
var UICarousel = (function () {
|
2263
|
+
var discoverVendorStyle = document.createElement('div').style,
|
2264
|
+
vendor = (function () {
|
2265
|
+
var vendors = 't,webkitT'.split(',');
|
2266
|
+
var l = vendors.length;
|
2267
|
+
var t;
|
2268
|
+
for ( var i = 0 ; i < l; i++ ) {
|
2269
|
+
t = vendors[i] + 'ransform';
|
2270
|
+
if ( t in discoverVendorStyle ) {
|
2271
|
+
return vendors[i].substr(0, vendors[i].length - 1);
|
2272
|
+
}
|
2273
|
+
}
|
2274
|
+
return false;
|
2275
|
+
})(),
|
2276
|
+
cssVendor = vendor ? '-' + vendor.toLowerCase() + '-' : '',
|
2277
|
+
transform = prefixStyle('transform'),
|
2278
|
+
transitionDuration = prefixStyle('transitionDuration'),
|
2279
|
+
hasTouch = 'ontouchstart' in window;
|
2280
|
+
var startEvent = $.eventStart;
|
2281
|
+
var moveEvent = $.eventMove;
|
2282
|
+
var endEvent = $.eventEnd;
|
2283
|
+
var cancelEvent = $.eventCancel;
|
2284
|
+
var transitionEndEvent = (function () {
|
2285
|
+
if ( vendor === false ) return false;
|
2286
|
+
var transitionEnd = {
|
2287
|
+
'': 'transitionend',
|
2288
|
+
'webkit': 'webkitTransitionEnd'
|
2289
|
+
};
|
2290
|
+
return transitionEnd[vendor];
|
2291
|
+
})(),
|
2292
|
+
|
2293
|
+
UICarousel = function ( options ) {
|
2294
|
+
if (!options) return;
|
2295
|
+
var ul, li, className;
|
2296
|
+
this.carouselContainer = typeof options.target === 'string' ? document.querySelector(options.target) : options.target;
|
2297
|
+
this.options = {
|
2298
|
+
panels: options.panels || 3,
|
2299
|
+
snapThreshold: null,
|
2300
|
+
loop: options.loop || true
|
2301
|
+
};
|
2302
|
+
// Adjustment for RTL carousels:
|
2303
|
+
if ($.isRTL) {
|
2304
|
+
options.loop = true;
|
2305
|
+
}
|
2306
|
+
// Include user's options:
|
2307
|
+
for (var i in options) this.options[i] = options[i];
|
2308
|
+
this.carouselContainer.style.overflow = 'hidden';
|
2309
|
+
this.carouselContainer.style.position = 'relative';
|
2310
|
+
this.carouselPanels = [];
|
2311
|
+
ul = document.createElement('ul');
|
2312
|
+
ul.className = 'carousel-track';
|
2313
|
+
ul.style.cssText = 'position:relative;top:0;height:100%;width:100%;' + cssVendor + 'transition-duration:0;' + cssVendor + 'transform:translateZ(0);' + cssVendor + 'transition-timing-function:ease-out';
|
2314
|
+
this.carouselContainer.appendChild(ul);
|
2315
|
+
this.track = ul;
|
2316
|
+
this.refreshSize();
|
2317
|
+
var whichPanelIndex;
|
2318
|
+
for (var j = -1; j < 2; j++) {
|
2319
|
+
li = document.createElement('li');
|
2320
|
+
li.id = 'carousel-panel-' + (j + 1);
|
2321
|
+
li.style.cssText = cssVendor + 'transform:translateZ(0);position:absolute;top:0;height:100%;width:100%;left:' + j * 100 + '%';
|
2322
|
+
whichPanelIndex = j === -1 ? this.options.panels - 1 : j;
|
2323
|
+
$(li).data('upcomingPanelIndex', whichPanelIndex);
|
2324
|
+
if (!this.options.loop && j === -1) li.style.visibility = 'hidden';
|
2325
|
+
this.track.appendChild(li);
|
2326
|
+
this.carouselPanels.push(li);
|
2327
|
+
}
|
2328
|
+
className = this.carouselPanels[1].className;
|
2329
|
+
this.carouselPanels[1].className = !className ? 'carousel-panel-active' : className + ' carousel-panel-active';
|
2330
|
+
this.carouselContainer.addEventListener(startEvent, this, false);
|
2331
|
+
this.carouselContainer.addEventListener(moveEvent, this, false);
|
2332
|
+
this.carouselContainer.addEventListener(endEvent, this, false);
|
2333
|
+
this.track.addEventListener(transitionEndEvent, this, false);
|
2334
|
+
var pagination;
|
2335
|
+
if (options.pagination) {
|
2336
|
+
pagination = document.createElement('ul');
|
2337
|
+
pagination.className = 'pagination';
|
2338
|
+
for (var k = 0; k < this.options.panels.length; k++) {
|
2339
|
+
li = document.createElement('li');
|
2340
|
+
if (k === 0) {
|
2341
|
+
li.className = 'selected';
|
2342
|
+
}
|
2343
|
+
pagination.appendChild(li);
|
2344
|
+
}
|
2345
|
+
if (window.$chocolatechipjs) {
|
2346
|
+
this.carouselContainer.insertAdjacentElement('afterEnd', pagination);
|
2347
|
+
} else {
|
2348
|
+
$(this.carouselContainer).after(pagination);
|
2349
|
+
}
|
2350
|
+
}
|
2351
|
+
};
|
2352
|
+
UICarousel.prototype = {
|
2353
|
+
currentPanel: 1,
|
2354
|
+
x: 0,
|
2355
|
+
panel: 0,
|
2356
|
+
customEvents: [],
|
2357
|
+
|
2358
|
+
onSlide: function (fn) {
|
2359
|
+
this.carouselContainer.addEventListener('carousel-panel-move', fn, false);
|
2360
|
+
this.customEvents.push(['move', fn]);
|
2361
|
+
},
|
2362
|
+
destroy: function () {
|
2363
|
+
while ( this.customEvents.length ) {
|
2364
|
+
this.carouselContainer.removeEventListener('carousel-panel-' + this.customEvents[0][0], this.customEvents[0][1], false);
|
2365
|
+
this.customEvents.shift();
|
2366
|
+
}
|
2367
|
+
// Remove event listeners:
|
2368
|
+
this.carouselContainer.removeEventListener(startEvent, this, false);
|
2369
|
+
this.carouselContainer.removeEventListener(moveEvent, this, false);
|
2370
|
+
this.carouselContainer.removeEventListener(endEvent, this, false);
|
2371
|
+
this.track.removeEventListener(transitionEndEvent, this, false);
|
2372
|
+
},
|
2373
|
+
refreshSize: function () {
|
2374
|
+
this.carouselContainerWidth = this.carouselContainer.clientWidth;
|
2375
|
+
this.carouselContainerHeight = this.carouselContainer.clientHeight;
|
2376
|
+
this.panelWidth = this.carouselContainerWidth;
|
2377
|
+
this.maxX = -this.options.panels * this.panelWidth + this.carouselContainerWidth;
|
2378
|
+
this.snapThreshold = this.options.snapThreshold === null ?
|
2379
|
+
Math.round(this.panelWidth * 0.15) :
|
2380
|
+
/%/.test(this.options.snapThreshold) ?
|
2381
|
+
Math.round(this.panelWidth * this.options.snapThreshold.replace('%', '') / 100) :
|
2382
|
+
this.options.snapThreshold;
|
2383
|
+
},
|
2384
|
+
|
2385
|
+
updatePanelCount: function (n) {
|
2386
|
+
this.options.panels = n;
|
2387
|
+
this.maxX = -this.options.panels * this.panelWidth + this.carouselContainerWidth;
|
2388
|
+
},
|
2389
|
+
|
2390
|
+
goToPanel: function (p) {
|
2391
|
+
this.carouselPanels[this.currentPanel].className = this.carouselPanels[this.currentPanel].className.replace(/(^|\s)carousel-panel-active(\s|$)/, '');
|
2392
|
+
p = p < 0 ? 0 : p > this.options.panels-1 ? this.options.panels - 1 : p;
|
2393
|
+
console.log('p: ' , p);
|
2394
|
+
this.panel = p;
|
2395
|
+
this.track.style[transitionDuration] = '0s';
|
2396
|
+
this.getPosition(-p * this.panelWidth);
|
2397
|
+
this.currentPanel = (this.panel + 1) - Math.floor((this.panel + 1) / 3) * 3;
|
2398
|
+
this.carouselPanels[this.currentPanel].className = this.carouselPanels[this.currentPanel].className + ' carousel-panel-active';
|
2399
|
+
if (this.currentPanel === 0) {
|
2400
|
+
this.carouselPanels[2].style.left = this.panel * 100 - 100 + '%';
|
2401
|
+
this.carouselPanels[0].style.left = this.panel * 100 + '%';
|
2402
|
+
this.carouselPanels[1].style.left = this.panel * 100 + 100 + '%';
|
2403
|
+
$(this.carouselPanels[2]).data('upcomingPanelIndex', this.panel === 0 ? this.options.panels - 1 : this.panel - 1);
|
2404
|
+
$(this.carouselPanels[0]).data('upcomingPanelIndex', this.panel);
|
2405
|
+
$(this.carouselPanels[1]).data('upcomingPanelIndex', this.panel === this.options.panels - 1 ? 0 : this.panel + 1);
|
2406
|
+
} else if (this.currentPanel === 1) {
|
2407
|
+
this.carouselPanels[0].style.left = this.panel * 100 - 100 + '%';
|
2408
|
+
this.carouselPanels[1].style.left = this.panel * 100 + '%';
|
2409
|
+
this.carouselPanels[2].style.left = this.panel * 100 + 100 + '%';
|
2410
|
+
$(this.carouselPanels[0]).data('upcomingPanelIndex', this.panel === 0 ? this.options.panels - 1 : this.panel - 1);
|
2411
|
+
$(this.carouselPanels[1]).data('upcomingPanelIndex', this.panel);
|
2412
|
+
$(this.carouselPanels[2]).data('upcomingPanelIndex', this.panel === this.options.panels - 1 ? 0 : this.panel + 1);
|
2413
|
+
} else {
|
2414
|
+
this.carouselPanels[1].style.left = this.panel * 100 - 100 + '%';
|
2415
|
+
this.carouselPanels[2].style.left = this.panel * 100 + '%';
|
2416
|
+
this.carouselPanels[0].style.left = this.panel * 100 + 100 + '%';
|
2417
|
+
$(this.carouselPanels[1]).data('upcomingPanelIndex', this.panel === 0 ? this.options.panels - 1 : this.panel - 1);
|
2418
|
+
$(this.carouselPanels[2]).data('upcomingPanelIndex', this.panel);
|
2419
|
+
$(this.carouselPanels[0]).data('upcomingPanelIndex', this.panel === this.options.panels - 1 ? 0 : this.panel + 1);
|
2420
|
+
}
|
2421
|
+
this.slide();
|
2422
|
+
},
|
2423
|
+
handleEvent: function (e) {
|
2424
|
+
switch (e.type) {
|
2425
|
+
case startEvent:
|
2426
|
+
this.start(e);
|
2427
|
+
break;
|
2428
|
+
case moveEvent:
|
2429
|
+
this.move(e);
|
2430
|
+
break;
|
2431
|
+
case cancelEvent:
|
2432
|
+
case endEvent:
|
2433
|
+
this.end(e);
|
2434
|
+
break;
|
2435
|
+
}
|
2436
|
+
},
|
2437
|
+
getPosition: function (x) {
|
2438
|
+
this.x = x;
|
2439
|
+
this.track.style[transform] = 'translate(' + x + 'px,0) translateZ(0)';
|
2440
|
+
},
|
2441
|
+
resize: function () {
|
2442
|
+
this.refreshSize();
|
2443
|
+
this.track.style[transitionDuration] = '0s';
|
2444
|
+
this.getPosition(-this.panel * this.panelWidth);
|
2445
|
+
},
|
2446
|
+
start: function (e) {
|
2447
|
+
if (this.initiated) return;
|
2448
|
+
var point = hasTouch ? e.touches[0] : e;
|
2449
|
+
this.initiated = true;
|
2450
|
+
this.moved = false;
|
2451
|
+
this.thresholdExceeded = false;
|
2452
|
+
this.startX = point.pageX;
|
2453
|
+
this.startY = point.pageY;
|
2454
|
+
this.pointX = point.pageX;
|
2455
|
+
this.pointY = point.pageY;
|
2456
|
+
this.stepsX = 0;
|
2457
|
+
this.stepsY = 0;
|
2458
|
+
this.directionX = 0;
|
2459
|
+
this.directionLocked = false;
|
2460
|
+
this.track.style[transitionDuration] = '0s';
|
2461
|
+
this.event('touchstart');
|
2462
|
+
},
|
2463
|
+
|
2464
|
+
move: function (e) {
|
2465
|
+
if (!this.initiated) return;
|
2466
|
+
var point = hasTouch ? e.touches[0] : e;
|
2467
|
+
var deltaX = point.pageX - this.pointX;
|
2468
|
+
var deltaY = point.pageY - this.pointY;
|
2469
|
+
var newX = this.x + deltaX;
|
2470
|
+
var dist = Math.abs(point.pageX - this.startX);
|
2471
|
+
this.moved = true;
|
2472
|
+
this.pointX = point.pageX;
|
2473
|
+
this.pointY = point.pageY;
|
2474
|
+
this.directionX = deltaX > 0 ? 1 : deltaX < 0 ? -1 : 0;
|
2475
|
+
this.stepsX += Math.abs(deltaX);
|
2476
|
+
this.stepsY += Math.abs(deltaY);
|
2477
|
+
// Use buffer to calculate direction of swipe:
|
2478
|
+
if (this.stepsX < 10 && this.stepsY < 10) {
|
2479
|
+
return;
|
2480
|
+
}
|
2481
|
+
// If scrolling vertically, cancel:
|
2482
|
+
if (!this.directionLocked && this.stepsY > this.stepsX) {
|
2483
|
+
this.initiated = false;
|
2484
|
+
return;
|
2485
|
+
}
|
2486
|
+
e.preventDefault();
|
2487
|
+
this.directionLocked = true;
|
2488
|
+
if (!this.options.loop && (newX > 0 || newX < this.maxX)) {
|
2489
|
+
newX = this.x + (deltaX / 2);
|
2490
|
+
}
|
2491
|
+
this.getPosition(newX);
|
2492
|
+
},
|
2493
|
+
|
2494
|
+
end: function (e) {
|
2495
|
+
if (!this.initiated) return;
|
2496
|
+
var point = hasTouch ? e.changedTouches[0] : e;
|
2497
|
+
var dist = Math.abs(point.pageX - this.startX);
|
2498
|
+
this.initiated = false;
|
2499
|
+
if (!this.moved) return;
|
2500
|
+
if (!this.options.loop && (this.x > 0 || this.x < this.maxX)) {
|
2501
|
+
dist = 0;
|
2502
|
+
}
|
2503
|
+
// Check if exceeded snap threshold:
|
2504
|
+
if (dist < this.snapThreshold) {
|
2505
|
+
this.track.style[transitionDuration] = Math.floor(300 * dist / this.snapThreshold) + 'ms';
|
2506
|
+
this.getPosition(-this.panel * this.panelWidth);
|
2507
|
+
return;
|
2508
|
+
}
|
2509
|
+
this.checkPosition();
|
2510
|
+
},
|
2511
|
+
|
2512
|
+
checkPosition: function () {
|
2513
|
+
var panelMove;
|
2514
|
+
var pageFlipIndex;
|
2515
|
+
var className;
|
2516
|
+
this.carouselPanels[this.currentPanel].className = '';
|
2517
|
+
// Slide the panel:
|
2518
|
+
if (this.directionX > 0) {
|
2519
|
+
this.panel = -Math.ceil(this.x / this.panelWidth);
|
2520
|
+
this.currentPanel = (this.panel + 1) - Math.floor((this.panel + 1) / 3) * 3;
|
2521
|
+
panelMove = this.currentPanel - 1;
|
2522
|
+
panelMove = panelMove < 0 ? 2 : panelMove;
|
2523
|
+
this.carouselPanels[panelMove].style.left = this.panel * 100 - 100 + '%';
|
2524
|
+
pageFlipIndex = this.panel - 1;
|
2525
|
+
} else {
|
2526
|
+
this.panel = -Math.floor(this.x / this.panelWidth);
|
2527
|
+
this.currentPanel = (this.panel + 1) - Math.floor((this.panel + 1) / 3) * 3;
|
2528
|
+
panelMove = this.currentPanel + 1;
|
2529
|
+
panelMove = panelMove > 2 ? 0 : panelMove;
|
2530
|
+
this.carouselPanels[panelMove].style.left = this.panel * 100 + 100 + '%';
|
2531
|
+
pageFlipIndex = this.panel + 1;
|
2532
|
+
}
|
2533
|
+
// Add active class to current panel:
|
2534
|
+
className = this.carouselPanels[this.currentPanel].className;
|
2535
|
+
/(^|\s)carousel-panel-active(\s|$)/.test(className) || (this.carouselPanels[this.currentPanel].className = !className ? 'carousel-panel-active' : className + ' carousel-panel-active');
|
2536
|
+
className = this.carouselPanels[panelMove].className;
|
2537
|
+
pageFlipIndex = pageFlipIndex - Math.floor(pageFlipIndex / this.options.panels) * this.options.panels;
|
2538
|
+
$(this.carouselPanels[panelMove]).data('upcomingPanelIndex', pageFlipIndex);
|
2539
|
+
// Index to be loaded in the newly moved panel:
|
2540
|
+
var newX = -this.panel * this.panelWidth;
|
2541
|
+
this.track.style[transitionDuration] = Math.floor(500 * Math.abs(this.x - newX) / this.panelWidth) + 'ms';
|
2542
|
+
// Hide the next panel if looping disabled:
|
2543
|
+
if (!this.options.loop) {
|
2544
|
+
this.carouselPanels[panelMove].style.visibility = newX === 0 || newX === this.maxX ? 'hidden' : '';
|
2545
|
+
}
|
2546
|
+
if (this.x === newX) {
|
2547
|
+
this.slide();
|
2548
|
+
} else {
|
2549
|
+
this.getPosition(newX);
|
2550
|
+
this.slide();
|
2551
|
+
}
|
2552
|
+
},
|
2553
|
+
|
2554
|
+
slide: function () {
|
2555
|
+
this.event('move');
|
2556
|
+
},
|
2557
|
+
event: function (type) {
|
2558
|
+
var ev = document.createEvent("Event");
|
2559
|
+
ev.initEvent('carousel-panel-' + type, true, true);
|
2560
|
+
this.carouselContainer.dispatchEvent(ev);
|
2561
|
+
}
|
2562
|
+
};
|
2563
|
+
function prefixStyle (style) {
|
2564
|
+
if ( vendor === '' ) return style;
|
2565
|
+
style = style.charAt(0).toUpperCase() + style.substr(1);
|
2566
|
+
return vendor + style;
|
2567
|
+
}
|
2568
|
+
return UICarousel;
|
2569
|
+
})();
|
2570
|
+
/*
|
2571
|
+
options = {
|
2572
|
+
target : (container of carousel),
|
2573
|
+
panels: (array of content for panels),
|
2574
|
+
loop: true/false
|
2575
|
+
}
|
2576
|
+
*/
|
2577
|
+
$.extend({
|
2578
|
+
UISetupCarousel : function ( options ) {
|
2579
|
+
// Method to adjust panel content for RTL:
|
2580
|
+
function reverseList ( array ) {
|
2581
|
+
var a = array.shift(0);
|
2582
|
+
array.reverse();
|
2583
|
+
array.unshift(a);
|
2584
|
+
return array;
|
2585
|
+
}
|
2586
|
+
if (!options) return;
|
2587
|
+
options.loop = options.loop || false;
|
2588
|
+
var carousel = new UICarousel({
|
2589
|
+
target: options.target,
|
2590
|
+
panels: options.panels.length,
|
2591
|
+
loop: options.loop,
|
2592
|
+
pagination: options.pagination
|
2593
|
+
});
|
2594
|
+
$(options.target).data('carousel', carousel);
|
2595
|
+
// Reverse array of data if RTL:
|
2596
|
+
if ($.isRTL) options.panels = reverseList(options.panels);
|
2597
|
+
var panel;
|
2598
|
+
// Load initial data:
|
2599
|
+
for (var i = 0; i < 3; i++) {
|
2600
|
+
panel = (i === 0) ? options.panels.length - 1 : i - 1;
|
2601
|
+
carousel.carouselPanels[i].innerHTML = options.panels[Number(panel)];
|
2602
|
+
}
|
2603
|
+
var index = 0;
|
2604
|
+
var pagination = $(options.target).next('.pagination');
|
2605
|
+
carousel.onSlide(function () {
|
2606
|
+
for (var i = 0; i < 3; i++) {
|
2607
|
+
var upcoming = $(carousel.carouselPanels[i]).data('upcomingPanelIndex');
|
2608
|
+
carousel.carouselPanels[i].innerHTML = options.panels[Number(upcoming)];
|
2609
|
+
}
|
2610
|
+
index = $('.carousel-panel-active').data('upcomingPanelIndex');
|
2611
|
+
pagination.find('li').removeClass('selected');
|
2612
|
+
// Handle pagination differently if RTL:
|
2613
|
+
if ($.isRTL) {
|
2614
|
+
pagination.find('li').removeClass('selected');
|
2615
|
+
if (index < 1) {
|
2616
|
+
pagination.find('li').eq(0).addClass('selected');
|
2617
|
+
} else {
|
2618
|
+
pagination.find('li').eq(options.panels.length - index).addClass('selected');
|
2619
|
+
}
|
2620
|
+
} else {
|
2621
|
+
pagination.find('li').eq(index).addClass('selected');
|
2622
|
+
}
|
2623
|
+
});
|
2624
|
+
$(options.target).on('mousedown', 'img', function() {return false;});
|
2625
|
+
var width = $(options.target).css('width');
|
2626
|
+
pagination.css('width', width);
|
2627
|
+
pagination.on('click', 'li', function() {
|
2628
|
+
$(this).siblings('li').removeClass('selected');
|
2629
|
+
$(this).addClass('selected');
|
2630
|
+
var goto = 0;
|
2631
|
+
// Handle pagination differently if RTL:
|
2632
|
+
if ($.isRTL) {
|
2633
|
+
var reverse = $(this).parent().children('li').length;
|
2634
|
+
if ($(this).index() === 0) {
|
2635
|
+
carousel.goToPanel(0);
|
2636
|
+
} else {
|
2637
|
+
goto = reverse - $(this).index();
|
2638
|
+
carousel.goToPanel(goto);
|
2639
|
+
}
|
2640
|
+
$(this).siblings('li').removeClass('selected');
|
2641
|
+
$(this).addClass('selected');
|
2642
|
+
} else {
|
2643
|
+
if ($(this).index() === 0) {
|
2644
|
+
carousel.goToPanel(0);
|
2645
|
+
} else {
|
2646
|
+
carousel.goToPanel($(this).index());
|
2647
|
+
}
|
2648
|
+
}
|
2649
|
+
});
|
2650
|
+
}
|
2651
|
+
});
|
2652
|
+
});
|
2653
|
+
|
2654
|
+
|
2655
|
+
$.fn.extend({
|
2656
|
+
UIRange : function () {
|
2657
|
+
if ($.isWin) return;
|
2658
|
+
if (this[0].nodeName !== 'INPUT') return;
|
2659
|
+
var input = $(this);
|
2660
|
+
var newPlace;
|
2661
|
+
var width = input.width();
|
2662
|
+
var newPoint = (input.val() - input.attr("min")) / (input.attr("max") - input.attr("min"));
|
2663
|
+
var offset = -1.3;
|
2664
|
+
if (newPoint < 0) {
|
2665
|
+
newPlace = 0;
|
2666
|
+
} else if (newPoint > 1) {
|
2667
|
+
newPlace = width;
|
2668
|
+
} else {
|
2669
|
+
newPlace = width * newPoint + offset; offset -= newPoint;
|
2670
|
+
}
|
2671
|
+
input.css({'background-size': Math.round(newPlace) + 'px 10px'});
|
2672
|
+
}
|
2673
|
+
});
|
2674
|
+
$(function() {
|
2675
|
+
$('input[type=range]').forEach(function(ctx) {
|
2676
|
+
$(ctx).UIRange();
|
2677
|
+
});
|
2678
|
+
$('body').on('input', 'input[type=range]', function() {
|
2679
|
+
$(this).UIRange();
|
2680
|
+
});
|
2681
|
+
});
|
2682
|
+
|
2683
|
+
|
2684
|
+
// Widget to enable styled select boxes (pickers):
|
2685
|
+
$.extend({
|
2686
|
+
UISelectBox: function() {
|
2687
|
+
var showSelectBox = function (element) {
|
2688
|
+
var event;
|
2689
|
+
event = document.createEvent('MouseEvents');
|
2690
|
+
event.initMouseEvent('mousedown', true, true, window);
|
2691
|
+
element.dispatchEvent(event);
|
2692
|
+
};
|
2693
|
+
if (!$.isDesktop && $.isiOS) {
|
2694
|
+
$('.select-box-label').forEach(function(ctx) {
|
2695
|
+
var label = $(ctx);
|
2696
|
+
var select = label.prev();
|
2697
|
+
if (!select[0].id) {
|
2698
|
+
select.attr('id', $.Uuid());
|
2699
|
+
}
|
2700
|
+
select.trigger('singletap');
|
2701
|
+
label.text(select.val());
|
2702
|
+
label.attr('for', select.attr('id'));
|
2703
|
+
});
|
2704
|
+
$('.select-box select').on('change', function() {
|
2705
|
+
$(this).next().text($(this).val());
|
2706
|
+
});
|
2707
|
+
} else if (!$.isDesktop) {
|
2708
|
+
var showDropdown = function (element) {
|
2709
|
+
var event;
|
2710
|
+
event = document.createEvent('MouseEvents');
|
2711
|
+
event.initMouseEvent('mousedown', true, true, window);
|
2712
|
+
element.dispatchEvent(event);
|
2713
|
+
};
|
2714
|
+
if (!$.isDesktop) {
|
2715
|
+
$('.select-box-label').forEach(function(ctx) {
|
2716
|
+
if (!ctx.id) {
|
2717
|
+
$(ctx).prev().attr('id', $.Uuid());
|
2718
|
+
}
|
2719
|
+
var val = $(ctx).siblings('select').val();
|
2720
|
+
$(ctx).text(val);
|
2721
|
+
});
|
2722
|
+
$('.select-box select').on('change', function() {
|
2723
|
+
var val = $(this).find("option:selected").text();
|
2724
|
+
var $this = $(this);
|
2725
|
+
$this.next('label').text($(this).val());
|
2726
|
+
$this.siblings('label').text(val);
|
2727
|
+
});
|
2728
|
+
$('body').on('singletap', '.select-box-label', function() {
|
2729
|
+
showDropdown($('select')[0]);
|
2730
|
+
});
|
2731
|
+
}
|
2732
|
+
}
|
2733
|
+
}
|
2734
|
+
});
|
2735
|
+
$(function() {
|
2736
|
+
$.UISelectBox();
|
2737
|
+
});
|
2738
|
+
|
2739
|
+
|
2740
|
+
///////////////////////////////////////
|
2741
|
+
// Initialize horizontal scroll panels:
|
2742
|
+
///////////////////////////////////////
|
2743
|
+
$.fn.extend({
|
2744
|
+
UIHorizontalScrollPanel : function () {
|
2745
|
+
return this.each(function() {
|
2746
|
+
var scrollPanel = $(this).find('ul');
|
2747
|
+
var panelsWidth = 0;
|
2748
|
+
scrollPanel.find('li').each(function(_, ctx) {
|
2749
|
+
panelsWidth += parseInt($(ctx).outerWidth(true));
|
2750
|
+
});
|
2751
|
+
var parentPadding = (parseInt($(this).css('padding-left')) + parseInt($(this).css('padding-right')));
|
2752
|
+
scrollPanel.css('width', (panelsWidth + (parentPadding + parentPadding / 2)));
|
2753
|
+
});
|
2754
|
+
}
|
2755
|
+
});
|
2756
|
+
|
2757
|
+
|
2758
|
+
//////////////////////////////////////////
|
2759
|
+
// Plugin to setup automatic data binding:
|
2760
|
+
//////////////////////////////////////////
|
2761
|
+
$.extend($, {
|
2762
|
+
UIBindData : function () {
|
2763
|
+
|
2764
|
+
var controllers = $('[data-controller]');
|
2765
|
+
var broadcasts = [];
|
2766
|
+
|
2767
|
+
// Define function to create broadcasts:
|
2768
|
+
//======================================
|
2769
|
+
var createBroadcaster = function(controller) {
|
2770
|
+
var broadcast = 'data-binding-' + $(controller).attr('data-controller');
|
2771
|
+
broadcasts.push(broadcast);
|
2772
|
+
};
|
2773
|
+
|
2774
|
+
// Loop controllers, create broadcasts,
|
2775
|
+
// subscribe models to broadcasts:
|
2776
|
+
//=====================================
|
2777
|
+
controllers.each(function(idx, ctx) {
|
2778
|
+
var model = $(ctx).attr('data-controller');
|
2779
|
+
createBroadcaster(ctx);
|
2780
|
+
// Subscribe and update elements with data:
|
2781
|
+
$.subscribe(broadcasts[idx], function(event, value) {
|
2782
|
+
var element = '[data-model=' + model + ']';
|
2783
|
+
$(element).text(value);
|
2784
|
+
});
|
2785
|
+
});
|
2786
|
+
|
2787
|
+
// Bind events to controllers to publish broadcasts:
|
2788
|
+
//==================================================
|
2789
|
+
$('body').on('input change', '[data-controller]', function(event) {
|
2790
|
+
var broadcast = 'data-binding-' + $(this).attr('data-controller');
|
2791
|
+
$.publish(broadcast, $(this).val());
|
2792
|
+
});
|
2793
|
+
}
|
2794
|
+
});
|
2795
|
+
|
2796
|
+
})(window.CHUIJSLIB);
|