phantom-blergh 0.1.1 → 0.1.2

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.
@@ -1,2 +1,2 @@
1
- /* skel.js v3.0.1 | (c) skel.io | MIT licensed */
1
+ /* skel.js v3.0.1 | (c) skel.io | MIT licensed */
2
2
  var skel=function(){"use strict";var t={breakpointIds:null,events:{},isInit:!1,obj:{attachments:{},breakpoints:{},head:null,states:{}},sd:"/",state:null,stateHandlers:{},stateId:"",vars:{},DOMReady:null,indexOf:null,isArray:null,iterate:null,matchesMedia:null,extend:function(e,n){t.iterate(n,function(i){t.isArray(n[i])?(t.isArray(e[i])||(e[i]=[]),t.extend(e[i],n[i])):"object"==typeof n[i]?("object"!=typeof e[i]&&(e[i]={}),t.extend(e[i],n[i])):e[i]=n[i]})},newStyle:function(t){var e=document.createElement("style");return e.type="text/css",e.innerHTML=t,e},_canUse:null,canUse:function(e){t._canUse||(t._canUse=document.createElement("div"));var n=t._canUse.style,i=e.charAt(0).toUpperCase()+e.slice(1);return e in n||"Moz"+i in n||"Webkit"+i in n||"O"+i in n||"ms"+i in n},on:function(e,n){var i=e.split(/[\s]+/);return t.iterate(i,function(e){var a=i[e];if(t.isInit){if("init"==a)return void n();if("change"==a)n();else{var r=a.charAt(0);if("+"==r||"!"==r){var o=a.substring(1);if(o in t.obj.breakpoints)if("+"==r&&t.obj.breakpoints[o].active)n();else if("!"==r&&!t.obj.breakpoints[o].active)return void n()}}}t.events[a]||(t.events[a]=[]),t.events[a].push(n)}),t},trigger:function(e){return t.events[e]&&0!=t.events[e].length?(t.iterate(t.events[e],function(n){t.events[e][n]()}),t):void 0},breakpoint:function(e){return t.obj.breakpoints[e]},breakpoints:function(e){function n(t,e){this.name=this.id=t,this.media=e,this.active=!1,this.wasActive=!1}return n.prototype.matches=function(){return t.matchesMedia(this.media)},n.prototype.sync=function(){this.wasActive=this.active,this.active=this.matches()},t.iterate(e,function(i){t.obj.breakpoints[i]=new n(i,e[i])}),window.setTimeout(function(){t.poll()},0),t},addStateHandler:function(e,n){t.stateHandlers[e]=n},callStateHandler:function(e){var n=t.stateHandlers[e]();t.iterate(n,function(e){t.state.attachments.push(n[e])})},changeState:function(e){t.iterate(t.obj.breakpoints,function(e){t.obj.breakpoints[e].sync()}),t.vars.lastStateId=t.stateId,t.stateId=e,t.breakpointIds=t.stateId===t.sd?[]:t.stateId.substring(1).split(t.sd),t.obj.states[t.stateId]?t.state=t.obj.states[t.stateId]:(t.obj.states[t.stateId]={attachments:[]},t.state=t.obj.states[t.stateId],t.iterate(t.stateHandlers,t.callStateHandler)),t.detachAll(t.state.attachments),t.attachAll(t.state.attachments),t.vars.stateId=t.stateId,t.vars.state=t.state,t.trigger("change"),t.iterate(t.obj.breakpoints,function(e){t.obj.breakpoints[e].active?t.obj.breakpoints[e].wasActive||t.trigger("+"+e):t.obj.breakpoints[e].wasActive&&t.trigger("-"+e)})},generateStateConfig:function(e,n){var i={};return t.extend(i,e),t.iterate(t.breakpointIds,function(e){t.extend(i,n[t.breakpointIds[e]])}),i},getStateId:function(){var e="";return t.iterate(t.obj.breakpoints,function(n){var i=t.obj.breakpoints[n];i.matches()&&(e+=t.sd+i.id)}),e},poll:function(){var e="";e=t.getStateId(),""===e&&(e=t.sd),e!==t.stateId&&t.changeState(e)},_attach:null,attach:function(e){var n=t.obj.head,i=e.element;return i.parentNode&&i.parentNode.tagName?!1:(t._attach||(t._attach=n.firstChild),n.insertBefore(i,t._attach.nextSibling),e.permanent&&(t._attach=i),!0)},attachAll:function(e){var n=[];t.iterate(e,function(t){n[e[t].priority]||(n[e[t].priority]=[]),n[e[t].priority].push(e[t])}),n.reverse(),t.iterate(n,function(e){t.iterate(n[e],function(i){t.attach(n[e][i])})})},detach:function(t){var e=t.element;return t.permanent||!e.parentNode||e.parentNode&&!e.parentNode.tagName?!1:(e.parentNode.removeChild(e),!0)},detachAll:function(e){var n={};t.iterate(e,function(t){n[e[t].id]=!0}),t.iterate(t.obj.attachments,function(e){e in n||t.detach(t.obj.attachments[e])})},attachment:function(e){return e in t.obj.attachments?t.obj.attachments[e]:null},newAttachment:function(e,n,i,a){return t.obj.attachments[e]={id:e,element:n,priority:i,permanent:a}},init:function(){t.initMethods(),t.initVars(),t.initEvents(),t.obj.head=document.getElementsByTagName("head")[0],t.isInit=!0,t.trigger("init")},initEvents:function(){t.on("resize",function(){t.poll()}),t.on("orientationChange",function(){t.poll()}),t.DOMReady(function(){t.trigger("ready")}),window.onload&&t.on("load",window.onload),window.onload=function(){t.trigger("load")},window.onresize&&t.on("resize",window.onresize),window.onresize=function(){t.trigger("resize")},window.onorientationchange&&t.on("orientationChange",window.onorientationchange),window.onorientationchange=function(){t.trigger("orientationChange")}},initMethods:function(){document.addEventListener?!function(e,n){t.DOMReady=n()}("domready",function(){function t(t){for(r=1;t=n.shift();)t()}var e,n=[],i=document,a="DOMContentLoaded",r=/^loaded|^c/.test(i.readyState);return i.addEventListener(a,e=function(){i.removeEventListener(a,e),t()}),function(t){r?t():n.push(t)}}):!function(e,n){t.DOMReady=n()}("domready",function(t){function e(t){for(h=1;t=i.shift();)t()}var n,i=[],a=!1,r=document,o=r.documentElement,s=o.doScroll,c="DOMContentLoaded",d="addEventListener",u="onreadystatechange",l="readyState",f=s?/^loaded|^c/:/^loaded|c/,h=f.test(r[l]);return r[d]&&r[d](c,n=function(){r.removeEventListener(c,n,a),e()},a),s&&r.attachEvent(u,n=function(){/^c/.test(r[l])&&(r.detachEvent(u,n),e())}),t=s?function(e){self!=top?h?e():i.push(e):function(){try{o.doScroll("left")}catch(n){return setTimeout(function(){t(e)},50)}e()}()}:function(t){h?t():i.push(t)}}),Array.prototype.indexOf?t.indexOf=function(t,e){return t.indexOf(e)}:t.indexOf=function(t,e){if("string"==typeof t)return t.indexOf(e);var n,i,a=e?e:0;if(!this)throw new TypeError;if(i=this.length,0===i||a>=i)return-1;for(0>a&&(a=i-Math.abs(a)),n=a;i>n;n++)if(this[n]===t)return n;return-1},Array.isArray?t.isArray=function(t){return Array.isArray(t)}:t.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)},Object.keys?t.iterate=function(t,e){if(!t)return[];var n,i=Object.keys(t);for(n=0;i[n]&&e(i[n],t[i[n]])!==!1;n++);}:t.iterate=function(t,e){if(!t)return[];var n;for(n in t)if(Object.prototype.hasOwnProperty.call(t,n)&&e(n,t[n])===!1)break},window.matchMedia?t.matchesMedia=function(t){return""==t?!0:window.matchMedia(t).matches}:window.styleMedia||window.media?t.matchesMedia=function(t){if(""==t)return!0;var e=window.styleMedia||window.media;return e.matchMedium(t||"all")}:window.getComputedStyle?t.matchesMedia=function(t){if(""==t)return!0;var e=document.createElement("style"),n=document.getElementsByTagName("script")[0],i=null;e.type="text/css",e.id="matchmediajs-test",n.parentNode.insertBefore(e,n),i="getComputedStyle"in window&&window.getComputedStyle(e,null)||e.currentStyle;var a="@media "+t+"{ #matchmediajs-test { width: 1px; } }";return e.styleSheet?e.styleSheet.cssText=a:e.textContent=a,"1px"===i.width}:t.matchesMedia=function(t){if(""==t)return!0;var e,n,i,a,r={"min-width":null,"max-width":null},o=!1;for(i=t.split(/\s+and\s+/),e=0;e<i.length;e++)n=i[e],"("==n.charAt(0)&&(n=n.substring(1,n.length-1),a=n.split(/:\s+/),2==a.length&&(r[a[0].replace(/^\s+|\s+$/g,"")]=parseInt(a[1]),o=!0));if(!o)return!1;var s=document.documentElement.clientWidth,c=document.documentElement.clientHeight;return null!==r["min-width"]&&s<r["min-width"]||null!==r["max-width"]&&s>r["max-width"]||null!==r["min-height"]&&c<r["min-height"]||null!==r["max-height"]&&c>r["max-height"]?!1:!0},navigator.userAgent.match(/MSIE ([0-9]+)/)&&RegExp.$1<9&&(t.newStyle=function(t){var e=document.createElement("span");return e.innerHTML='&nbsp;<style type="text/css">'+t+"</style>",e})},initVars:function(){var e,n,i,a=navigator.userAgent;e="other",n=0,i=[["firefox",/Firefox\/([0-9\.]+)/],["bb",/BlackBerry.+Version\/([0-9\.]+)/],["bb",/BB[0-9]+.+Version\/([0-9\.]+)/],["opera",/OPR\/([0-9\.]+)/],["opera",/Opera\/([0-9\.]+)/],["edge",/Edge\/([0-9\.]+)/],["safari",/Version\/([0-9\.]+).+Safari/],["chrome",/Chrome\/([0-9\.]+)/],["ie",/MSIE ([0-9]+)/],["ie",/Trident\/.+rv:([0-9]+)/]],t.iterate(i,function(t,i){return a.match(i[1])?(e=i[0],n=parseFloat(RegExp.$1),!1):void 0}),t.vars.browser=e,t.vars.browserVersion=n,e="other",n=0,i=[["ios",/([0-9_]+) like Mac OS X/,function(t){return t.replace("_",".").replace("_","")}],["ios",/CPU like Mac OS X/,function(t){return 0}],["wp",/Windows Phone ([0-9\.]+)/,null],["android",/Android ([0-9\.]+)/,null],["mac",/Macintosh.+Mac OS X ([0-9_]+)/,function(t){return t.replace("_",".").replace("_","")}],["windows",/Windows NT ([0-9\.]+)/,null],["bb",/BlackBerry.+Version\/([0-9\.]+)/,null],["bb",/BB[0-9]+.+Version\/([0-9\.]+)/,null]],t.iterate(i,function(t,i){return a.match(i[1])?(e=i[0],n=parseFloat(i[2]?i[2](RegExp.$1):RegExp.$1),!1):void 0}),t.vars.os=e,t.vars.osVersion=n,t.vars.IEVersion="ie"==t.vars.browser?t.vars.browserVersion:99,t.vars.touch="wp"==t.vars.os?navigator.msMaxTouchPoints>0:!!("ontouchstart"in window),t.vars.mobile="wp"==t.vars.os||"android"==t.vars.os||"ios"==t.vars.os||"bb"==t.vars.os}};return t.init(),t}();!function(t,e){"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?module.exports=e():t.skel=e()}(this,function(){return skel});
data/assets/js/util.js CHANGED
@@ -1,587 +1,587 @@
1
- (function($) {
2
-
3
- /**
4
- * Generate an indented list of links from a nav. Meant for use with panel().
5
- * @return {jQuery} jQuery object.
6
- */
7
- $.fn.navList = function() {
8
-
9
- var $this = $(this);
10
- $a = $this.find('a'),
11
- b = [];
12
-
13
- $a.each(function() {
14
-
15
- var $this = $(this),
16
- indent = Math.max(0, $this.parents('li').length - 1),
17
- href = $this.attr('href'),
18
- target = $this.attr('target');
19
-
20
- b.push(
21
- '<a ' +
22
- 'class="link depth-' + indent + '"' +
23
- ( (typeof target !== 'undefined' && target != '') ? ' target="' + target + '"' : '') +
24
- ( (typeof href !== 'undefined' && href != '') ? ' href="' + href + '"' : '') +
25
- '>' +
26
- '<span class="indent-' + indent + '"></span>' +
27
- $this.text() +
28
- '</a>'
29
- );
30
-
31
- });
32
-
33
- return b.join('');
34
-
35
- };
36
-
37
- /**
38
- * Panel-ify an element.
39
- * @param {object} userConfig User config.
40
- * @return {jQuery} jQuery object.
41
- */
42
- $.fn.panel = function(userConfig) {
43
-
44
- // No elements?
45
- if (this.length == 0)
46
- return $this;
47
-
48
- // Multiple elements?
49
- if (this.length > 1) {
50
-
51
- for (var i=0; i < this.length; i++)
52
- $(this[i]).panel(userConfig);
53
-
54
- return $this;
55
-
56
- }
57
-
58
- // Vars.
59
- var $this = $(this),
60
- $body = $('body'),
61
- $window = $(window),
62
- id = $this.attr('id'),
63
- config;
64
-
65
- // Config.
66
- config = $.extend({
67
-
68
- // Delay.
69
- delay: 0,
70
-
71
- // Hide panel on link click.
72
- hideOnClick: false,
73
-
74
- // Hide panel on escape keypress.
75
- hideOnEscape: false,
76
-
77
- // Hide panel on swipe.
78
- hideOnSwipe: false,
79
-
80
- // Reset scroll position on hide.
81
- resetScroll: false,
82
-
83
- // Reset forms on hide.
84
- resetForms: false,
85
-
86
- // Side of viewport the panel will appear.
87
- side: null,
88
-
89
- // Target element for "class".
90
- target: $this,
91
-
92
- // Class to toggle.
93
- visibleClass: 'visible'
94
-
95
- }, userConfig);
96
-
97
- // Expand "target" if it's not a jQuery object already.
98
- if (typeof config.target != 'jQuery')
99
- config.target = $(config.target);
100
-
101
- // Panel.
102
-
103
- // Methods.
104
- $this._hide = function(event) {
105
-
106
- // Already hidden? Bail.
107
- if (!config.target.hasClass(config.visibleClass))
108
- return;
109
-
110
- // If an event was provided, cancel it.
111
- if (event) {
112
-
113
- event.preventDefault();
114
- event.stopPropagation();
115
-
116
- }
117
-
118
- // Hide.
119
- config.target.removeClass(config.visibleClass);
120
-
121
- // Post-hide stuff.
122
- window.setTimeout(function() {
123
-
124
- // Reset scroll position.
125
- if (config.resetScroll)
126
- $this.scrollTop(0);
127
-
128
- // Reset forms.
129
- if (config.resetForms)
130
- $this.find('form').each(function() {
131
- this.reset();
132
- });
133
-
134
- }, config.delay);
135
-
136
- };
137
-
138
- // Vendor fixes.
139
- $this
140
- .css('-ms-overflow-style', '-ms-autohiding-scrollbar')
141
- .css('-webkit-overflow-scrolling', 'touch');
142
-
143
- // Hide on click.
144
- if (config.hideOnClick) {
145
-
146
- $this.find('a')
147
- .css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');
148
-
149
- $this
150
- .on('click', 'a', function(event) {
151
-
152
- var $a = $(this),
153
- href = $a.attr('href'),
154
- target = $a.attr('target');
155
-
156
- if (!href || href == '#' || href == '' || href == '#' + id)
157
- return;
158
-
159
- // Cancel original event.
160
- event.preventDefault();
161
- event.stopPropagation();
162
-
163
- // Hide panel.
164
- $this._hide();
165
-
166
- // Redirect to href.
167
- window.setTimeout(function() {
168
-
169
- if (target == '_blank')
170
- window.open(href);
171
- else
172
- window.location.href = href;
173
-
174
- }, config.delay + 10);
175
-
176
- });
177
-
178
- }
179
-
180
- // Event: Touch stuff.
181
- $this.on('touchstart', function(event) {
182
-
183
- $this.touchPosX = event.originalEvent.touches[0].pageX;
184
- $this.touchPosY = event.originalEvent.touches[0].pageY;
185
-
186
- })
187
-
188
- $this.on('touchmove', function(event) {
189
-
190
- if ($this.touchPosX === null
191
- || $this.touchPosY === null)
192
- return;
193
-
194
- var diffX = $this.touchPosX - event.originalEvent.touches[0].pageX,
195
- diffY = $this.touchPosY - event.originalEvent.touches[0].pageY,
196
- th = $this.outerHeight(),
197
- ts = ($this.get(0).scrollHeight - $this.scrollTop());
198
-
199
- // Hide on swipe?
200
- if (config.hideOnSwipe) {
201
-
202
- var result = false,
203
- boundary = 20,
204
- delta = 50;
205
-
206
- switch (config.side) {
207
-
208
- case 'left':
209
- result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta);
210
- break;
211
-
212
- case 'right':
213
- result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta));
214
- break;
215
-
216
- case 'top':
217
- result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta);
218
- break;
219
-
220
- case 'bottom':
221
- result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta));
222
- break;
223
-
224
- default:
225
- break;
226
-
227
- }
228
-
229
- if (result) {
230
-
231
- $this.touchPosX = null;
232
- $this.touchPosY = null;
233
- $this._hide();
234
-
235
- return false;
236
-
237
- }
238
-
239
- }
240
-
241
- // Prevent vertical scrolling past the top or bottom.
242
- if (($this.scrollTop() < 0 && diffY < 0)
243
- || (ts > (th - 2) && ts < (th + 2) && diffY > 0)) {
244
-
245
- event.preventDefault();
246
- event.stopPropagation();
247
-
248
- }
249
-
250
- });
251
-
252
- // Event: Prevent certain events inside the panel from bubbling.
253
- $this.on('click touchend touchstart touchmove', function(event) {
254
- event.stopPropagation();
255
- });
256
-
257
- // Event: Hide panel if a child anchor tag pointing to its ID is clicked.
258
- $this.on('click', 'a[href="#' + id + '"]', function(event) {
259
-
260
- event.preventDefault();
261
- event.stopPropagation();
262
-
263
- config.target.removeClass(config.visibleClass);
264
-
265
- });
266
-
267
- // Body.
268
-
269
- // Event: Hide panel on body click/tap.
270
- $body.on('click touchend', function(event) {
271
- $this._hide(event);
272
- });
273
-
274
- // Event: Toggle.
275
- $body.on('click', 'a[href="#' + id + '"]', function(event) {
276
-
277
- event.preventDefault();
278
- event.stopPropagation();
279
-
280
- config.target.toggleClass(config.visibleClass);
281
-
282
- });
283
-
284
- // Window.
285
-
286
- // Event: Hide on ESC.
287
- if (config.hideOnEscape)
288
- $window.on('keydown', function(event) {
289
-
290
- if (event.keyCode == 27)
291
- $this._hide(event);
292
-
293
- });
294
-
295
- return $this;
296
-
297
- };
298
-
299
- /**
300
- * Apply "placeholder" attribute polyfill to one or more forms.
301
- * @return {jQuery} jQuery object.
302
- */
303
- $.fn.placeholder = function() {
304
-
305
- // Browser natively supports placeholders? Bail.
306
- if (typeof (document.createElement('input')).placeholder != 'undefined')
307
- return $(this);
308
-
309
- // No elements?
310
- if (this.length == 0)
311
- return $this;
312
-
313
- // Multiple elements?
314
- if (this.length > 1) {
315
-
316
- for (var i=0; i < this.length; i++)
317
- $(this[i]).placeholder();
318
-
319
- return $this;
320
-
321
- }
322
-
323
- // Vars.
324
- var $this = $(this);
325
-
326
- // Text, TextArea.
327
- $this.find('input[type=text],textarea')
328
- .each(function() {
329
-
330
- var i = $(this);
331
-
332
- if (i.val() == ''
333
- || i.val() == i.attr('placeholder'))
334
- i
335
- .addClass('polyfill-placeholder')
336
- .val(i.attr('placeholder'));
337
-
338
- })
339
- .on('blur', function() {
340
-
341
- var i = $(this);
342
-
343
- if (i.attr('name').match(/-polyfill-field$/))
344
- return;
345
-
346
- if (i.val() == '')
347
- i
348
- .addClass('polyfill-placeholder')
349
- .val(i.attr('placeholder'));
350
-
351
- })
352
- .on('focus', function() {
353
-
354
- var i = $(this);
355
-
356
- if (i.attr('name').match(/-polyfill-field$/))
357
- return;
358
-
359
- if (i.val() == i.attr('placeholder'))
360
- i
361
- .removeClass('polyfill-placeholder')
362
- .val('');
363
-
364
- });
365
-
366
- // Password.
367
- $this.find('input[type=password]')
368
- .each(function() {
369
-
370
- var i = $(this);
371
- var x = $(
372
- $('<div>')
373
- .append(i.clone())
374
- .remove()
375
- .html()
376
- .replace(/type="password"/i, 'type="text"')
377
- .replace(/type=password/i, 'type=text')
378
- );
379
-
380
- if (i.attr('id') != '')
381
- x.attr('id', i.attr('id') + '-polyfill-field');
382
-
383
- if (i.attr('name') != '')
384
- x.attr('name', i.attr('name') + '-polyfill-field');
385
-
386
- x.addClass('polyfill-placeholder')
387
- .val(x.attr('placeholder')).insertAfter(i);
388
-
389
- if (i.val() == '')
390
- i.hide();
391
- else
392
- x.hide();
393
-
394
- i
395
- .on('blur', function(event) {
396
-
397
- event.preventDefault();
398
-
399
- var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
400
-
401
- if (i.val() == '') {
402
-
403
- i.hide();
404
- x.show();
405
-
406
- }
407
-
408
- });
409
-
410
- x
411
- .on('focus', function(event) {
412
-
413
- event.preventDefault();
414
-
415
- var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']');
416
-
417
- x.hide();
418
-
419
- i
420
- .show()
421
- .focus();
422
-
423
- })
424
- .on('keypress', function(event) {
425
-
426
- event.preventDefault();
427
- x.val('');
428
-
429
- });
430
-
431
- });
432
-
433
- // Events.
434
- $this
435
- .on('submit', function() {
436
-
437
- $this.find('input[type=text],input[type=password],textarea')
438
- .each(function(event) {
439
-
440
- var i = $(this);
441
-
442
- if (i.attr('name').match(/-polyfill-field$/))
443
- i.attr('name', '');
444
-
445
- if (i.val() == i.attr('placeholder')) {
446
-
447
- i.removeClass('polyfill-placeholder');
448
- i.val('');
449
-
450
- }
451
-
452
- });
453
-
454
- })
455
- .on('reset', function(event) {
456
-
457
- event.preventDefault();
458
-
459
- $this.find('select')
460
- .val($('option:first').val());
461
-
462
- $this.find('input,textarea')
463
- .each(function() {
464
-
465
- var i = $(this),
466
- x;
467
-
468
- i.removeClass('polyfill-placeholder');
469
-
470
- switch (this.type) {
471
-
472
- case 'submit':
473
- case 'reset':
474
- break;
475
-
476
- case 'password':
477
- i.val(i.attr('defaultValue'));
478
-
479
- x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
480
-
481
- if (i.val() == '') {
482
- i.hide();
483
- x.show();
484
- }
485
- else {
486
- i.show();
487
- x.hide();
488
- }
489
-
490
- break;
491
-
492
- case 'checkbox':
493
- case 'radio':
494
- i.attr('checked', i.attr('defaultValue'));
495
- break;
496
-
497
- case 'text':
498
- case 'textarea':
499
- i.val(i.attr('defaultValue'));
500
-
501
- if (i.val() == '') {
502
- i.addClass('polyfill-placeholder');
503
- i.val(i.attr('placeholder'));
504
- }
505
-
506
- break;
507
-
508
- default:
509
- i.val(i.attr('defaultValue'));
510
- break;
511
-
512
- }
513
- });
514
-
515
- });
516
-
517
- return $this;
518
-
519
- };
520
-
521
- /**
522
- * Moves elements to/from the first positions of their respective parents.
523
- * @param {jQuery} $elements Elements (or selector) to move.
524
- * @param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations.
525
- */
526
- $.prioritize = function($elements, condition) {
527
-
528
- var key = '__prioritize';
529
-
530
- // Expand $elements if it's not already a jQuery object.
531
- if (typeof $elements != 'jQuery')
532
- $elements = $($elements);
533
-
534
- // Step through elements.
535
- $elements.each(function() {
536
-
537
- var $e = $(this), $p,
538
- $parent = $e.parent();
539
-
540
- // No parent? Bail.
541
- if ($parent.length == 0)
542
- return;
543
-
544
- // Not moved? Move it.
545
- if (!$e.data(key)) {
546
-
547
- // Condition is false? Bail.
548
- if (!condition)
549
- return;
550
-
551
- // Get placeholder (which will serve as our point of reference for when this element needs to move back).
552
- $p = $e.prev();
553
-
554
- // Couldn't find anything? Means this element's already at the top, so bail.
555
- if ($p.length == 0)
556
- return;
557
-
558
- // Move element to top of parent.
559
- $e.prependTo($parent);
560
-
561
- // Mark element as moved.
562
- $e.data(key, $p);
563
-
564
- }
565
-
566
- // Moved already?
567
- else {
568
-
569
- // Condition is true? Bail.
570
- if (condition)
571
- return;
572
-
573
- $p = $e.data(key);
574
-
575
- // Move element back to its original location (using our placeholder).
576
- $e.insertAfter($p);
577
-
578
- // Unmark element as moved.
579
- $e.removeData(key);
580
-
581
- }
582
-
583
- });
584
-
585
- };
586
-
1
+ (function($) {
2
+
3
+ /**
4
+ * Generate an indented list of links from a nav. Meant for use with panel().
5
+ * @return {jQuery} jQuery object.
6
+ */
7
+ $.fn.navList = function() {
8
+
9
+ var $this = $(this);
10
+ $a = $this.find('a'),
11
+ b = [];
12
+
13
+ $a.each(function() {
14
+
15
+ var $this = $(this),
16
+ indent = Math.max(0, $this.parents('li').length - 1),
17
+ href = $this.attr('href'),
18
+ target = $this.attr('target');
19
+
20
+ b.push(
21
+ '<a ' +
22
+ 'class="link depth-' + indent + '"' +
23
+ ( (typeof target !== 'undefined' && target != '') ? ' target="' + target + '"' : '') +
24
+ ( (typeof href !== 'undefined' && href != '') ? ' href="' + href + '"' : '') +
25
+ '>' +
26
+ '<span class="indent-' + indent + '"></span>' +
27
+ $this.text() +
28
+ '</a>'
29
+ );
30
+
31
+ });
32
+
33
+ return b.join('');
34
+
35
+ };
36
+
37
+ /**
38
+ * Panel-ify an element.
39
+ * @param {object} userConfig User config.
40
+ * @return {jQuery} jQuery object.
41
+ */
42
+ $.fn.panel = function(userConfig) {
43
+
44
+ // No elements?
45
+ if (this.length == 0)
46
+ return $this;
47
+
48
+ // Multiple elements?
49
+ if (this.length > 1) {
50
+
51
+ for (var i=0; i < this.length; i++)
52
+ $(this[i]).panel(userConfig);
53
+
54
+ return $this;
55
+
56
+ }
57
+
58
+ // Vars.
59
+ var $this = $(this),
60
+ $body = $('body'),
61
+ $window = $(window),
62
+ id = $this.attr('id'),
63
+ config;
64
+
65
+ // Config.
66
+ config = $.extend({
67
+
68
+ // Delay.
69
+ delay: 0,
70
+
71
+ // Hide panel on link click.
72
+ hideOnClick: false,
73
+
74
+ // Hide panel on escape keypress.
75
+ hideOnEscape: false,
76
+
77
+ // Hide panel on swipe.
78
+ hideOnSwipe: false,
79
+
80
+ // Reset scroll position on hide.
81
+ resetScroll: false,
82
+
83
+ // Reset forms on hide.
84
+ resetForms: false,
85
+
86
+ // Side of viewport the panel will appear.
87
+ side: null,
88
+
89
+ // Target element for "class".
90
+ target: $this,
91
+
92
+ // Class to toggle.
93
+ visibleClass: 'visible'
94
+
95
+ }, userConfig);
96
+
97
+ // Expand "target" if it's not a jQuery object already.
98
+ if (typeof config.target != 'jQuery')
99
+ config.target = $(config.target);
100
+
101
+ // Panel.
102
+
103
+ // Methods.
104
+ $this._hide = function(event) {
105
+
106
+ // Already hidden? Bail.
107
+ if (!config.target.hasClass(config.visibleClass))
108
+ return;
109
+
110
+ // If an event was provided, cancel it.
111
+ if (event) {
112
+
113
+ event.preventDefault();
114
+ event.stopPropagation();
115
+
116
+ }
117
+
118
+ // Hide.
119
+ config.target.removeClass(config.visibleClass);
120
+
121
+ // Post-hide stuff.
122
+ window.setTimeout(function() {
123
+
124
+ // Reset scroll position.
125
+ if (config.resetScroll)
126
+ $this.scrollTop(0);
127
+
128
+ // Reset forms.
129
+ if (config.resetForms)
130
+ $this.find('form').each(function() {
131
+ this.reset();
132
+ });
133
+
134
+ }, config.delay);
135
+
136
+ };
137
+
138
+ // Vendor fixes.
139
+ $this
140
+ .css('-ms-overflow-style', '-ms-autohiding-scrollbar')
141
+ .css('-webkit-overflow-scrolling', 'touch');
142
+
143
+ // Hide on click.
144
+ if (config.hideOnClick) {
145
+
146
+ $this.find('a')
147
+ .css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');
148
+
149
+ $this
150
+ .on('click', 'a', function(event) {
151
+
152
+ var $a = $(this),
153
+ href = $a.attr('href'),
154
+ target = $a.attr('target');
155
+
156
+ if (!href || href == '#' || href == '' || href == '#' + id)
157
+ return;
158
+
159
+ // Cancel original event.
160
+ event.preventDefault();
161
+ event.stopPropagation();
162
+
163
+ // Hide panel.
164
+ $this._hide();
165
+
166
+ // Redirect to href.
167
+ window.setTimeout(function() {
168
+
169
+ if (target == '_blank')
170
+ window.open(href);
171
+ else
172
+ window.location.href = href;
173
+
174
+ }, config.delay + 10);
175
+
176
+ });
177
+
178
+ }
179
+
180
+ // Event: Touch stuff.
181
+ $this.on('touchstart', function(event) {
182
+
183
+ $this.touchPosX = event.originalEvent.touches[0].pageX;
184
+ $this.touchPosY = event.originalEvent.touches[0].pageY;
185
+
186
+ })
187
+
188
+ $this.on('touchmove', function(event) {
189
+
190
+ if ($this.touchPosX === null
191
+ || $this.touchPosY === null)
192
+ return;
193
+
194
+ var diffX = $this.touchPosX - event.originalEvent.touches[0].pageX,
195
+ diffY = $this.touchPosY - event.originalEvent.touches[0].pageY,
196
+ th = $this.outerHeight(),
197
+ ts = ($this.get(0).scrollHeight - $this.scrollTop());
198
+
199
+ // Hide on swipe?
200
+ if (config.hideOnSwipe) {
201
+
202
+ var result = false,
203
+ boundary = 20,
204
+ delta = 50;
205
+
206
+ switch (config.side) {
207
+
208
+ case 'left':
209
+ result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta);
210
+ break;
211
+
212
+ case 'right':
213
+ result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta));
214
+ break;
215
+
216
+ case 'top':
217
+ result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta);
218
+ break;
219
+
220
+ case 'bottom':
221
+ result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta));
222
+ break;
223
+
224
+ default:
225
+ break;
226
+
227
+ }
228
+
229
+ if (result) {
230
+
231
+ $this.touchPosX = null;
232
+ $this.touchPosY = null;
233
+ $this._hide();
234
+
235
+ return false;
236
+
237
+ }
238
+
239
+ }
240
+
241
+ // Prevent vertical scrolling past the top or bottom.
242
+ if (($this.scrollTop() < 0 && diffY < 0)
243
+ || (ts > (th - 2) && ts < (th + 2) && diffY > 0)) {
244
+
245
+ event.preventDefault();
246
+ event.stopPropagation();
247
+
248
+ }
249
+
250
+ });
251
+
252
+ // Event: Prevent certain events inside the panel from bubbling.
253
+ $this.on('click touchend touchstart touchmove', function(event) {
254
+ event.stopPropagation();
255
+ });
256
+
257
+ // Event: Hide panel if a child anchor tag pointing to its ID is clicked.
258
+ $this.on('click', 'a[href="#' + id + '"]', function(event) {
259
+
260
+ event.preventDefault();
261
+ event.stopPropagation();
262
+
263
+ config.target.removeClass(config.visibleClass);
264
+
265
+ });
266
+
267
+ // Body.
268
+
269
+ // Event: Hide panel on body click/tap.
270
+ $body.on('click touchend', function(event) {
271
+ $this._hide(event);
272
+ });
273
+
274
+ // Event: Toggle.
275
+ $body.on('click', 'a[href="#' + id + '"]', function(event) {
276
+
277
+ event.preventDefault();
278
+ event.stopPropagation();
279
+
280
+ config.target.toggleClass(config.visibleClass);
281
+
282
+ });
283
+
284
+ // Window.
285
+
286
+ // Event: Hide on ESC.
287
+ if (config.hideOnEscape)
288
+ $window.on('keydown', function(event) {
289
+
290
+ if (event.keyCode == 27)
291
+ $this._hide(event);
292
+
293
+ });
294
+
295
+ return $this;
296
+
297
+ };
298
+
299
+ /**
300
+ * Apply "placeholder" attribute polyfill to one or more forms.
301
+ * @return {jQuery} jQuery object.
302
+ */
303
+ $.fn.placeholder = function() {
304
+
305
+ // Browser natively supports placeholders? Bail.
306
+ if (typeof (document.createElement('input')).placeholder != 'undefined')
307
+ return $(this);
308
+
309
+ // No elements?
310
+ if (this.length == 0)
311
+ return $this;
312
+
313
+ // Multiple elements?
314
+ if (this.length > 1) {
315
+
316
+ for (var i=0; i < this.length; i++)
317
+ $(this[i]).placeholder();
318
+
319
+ return $this;
320
+
321
+ }
322
+
323
+ // Vars.
324
+ var $this = $(this);
325
+
326
+ // Text, TextArea.
327
+ $this.find('input[type=text],textarea')
328
+ .each(function() {
329
+
330
+ var i = $(this);
331
+
332
+ if (i.val() == ''
333
+ || i.val() == i.attr('placeholder'))
334
+ i
335
+ .addClass('polyfill-placeholder')
336
+ .val(i.attr('placeholder'));
337
+
338
+ })
339
+ .on('blur', function() {
340
+
341
+ var i = $(this);
342
+
343
+ if (i.attr('name').match(/-polyfill-field$/))
344
+ return;
345
+
346
+ if (i.val() == '')
347
+ i
348
+ .addClass('polyfill-placeholder')
349
+ .val(i.attr('placeholder'));
350
+
351
+ })
352
+ .on('focus', function() {
353
+
354
+ var i = $(this);
355
+
356
+ if (i.attr('name').match(/-polyfill-field$/))
357
+ return;
358
+
359
+ if (i.val() == i.attr('placeholder'))
360
+ i
361
+ .removeClass('polyfill-placeholder')
362
+ .val('');
363
+
364
+ });
365
+
366
+ // Password.
367
+ $this.find('input[type=password]')
368
+ .each(function() {
369
+
370
+ var i = $(this);
371
+ var x = $(
372
+ $('<div>')
373
+ .append(i.clone())
374
+ .remove()
375
+ .html()
376
+ .replace(/type="password"/i, 'type="text"')
377
+ .replace(/type=password/i, 'type=text')
378
+ );
379
+
380
+ if (i.attr('id') != '')
381
+ x.attr('id', i.attr('id') + '-polyfill-field');
382
+
383
+ if (i.attr('name') != '')
384
+ x.attr('name', i.attr('name') + '-polyfill-field');
385
+
386
+ x.addClass('polyfill-placeholder')
387
+ .val(x.attr('placeholder')).insertAfter(i);
388
+
389
+ if (i.val() == '')
390
+ i.hide();
391
+ else
392
+ x.hide();
393
+
394
+ i
395
+ .on('blur', function(event) {
396
+
397
+ event.preventDefault();
398
+
399
+ var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
400
+
401
+ if (i.val() == '') {
402
+
403
+ i.hide();
404
+ x.show();
405
+
406
+ }
407
+
408
+ });
409
+
410
+ x
411
+ .on('focus', function(event) {
412
+
413
+ event.preventDefault();
414
+
415
+ var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']');
416
+
417
+ x.hide();
418
+
419
+ i
420
+ .show()
421
+ .focus();
422
+
423
+ })
424
+ .on('keypress', function(event) {
425
+
426
+ event.preventDefault();
427
+ x.val('');
428
+
429
+ });
430
+
431
+ });
432
+
433
+ // Events.
434
+ $this
435
+ .on('submit', function() {
436
+
437
+ $this.find('input[type=text],input[type=password],textarea')
438
+ .each(function(event) {
439
+
440
+ var i = $(this);
441
+
442
+ if (i.attr('name').match(/-polyfill-field$/))
443
+ i.attr('name', '');
444
+
445
+ if (i.val() == i.attr('placeholder')) {
446
+
447
+ i.removeClass('polyfill-placeholder');
448
+ i.val('');
449
+
450
+ }
451
+
452
+ });
453
+
454
+ })
455
+ .on('reset', function(event) {
456
+
457
+ event.preventDefault();
458
+
459
+ $this.find('select')
460
+ .val($('option:first').val());
461
+
462
+ $this.find('input,textarea')
463
+ .each(function() {
464
+
465
+ var i = $(this),
466
+ x;
467
+
468
+ i.removeClass('polyfill-placeholder');
469
+
470
+ switch (this.type) {
471
+
472
+ case 'submit':
473
+ case 'reset':
474
+ break;
475
+
476
+ case 'password':
477
+ i.val(i.attr('defaultValue'));
478
+
479
+ x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
480
+
481
+ if (i.val() == '') {
482
+ i.hide();
483
+ x.show();
484
+ }
485
+ else {
486
+ i.show();
487
+ x.hide();
488
+ }
489
+
490
+ break;
491
+
492
+ case 'checkbox':
493
+ case 'radio':
494
+ i.attr('checked', i.attr('defaultValue'));
495
+ break;
496
+
497
+ case 'text':
498
+ case 'textarea':
499
+ i.val(i.attr('defaultValue'));
500
+
501
+ if (i.val() == '') {
502
+ i.addClass('polyfill-placeholder');
503
+ i.val(i.attr('placeholder'));
504
+ }
505
+
506
+ break;
507
+
508
+ default:
509
+ i.val(i.attr('defaultValue'));
510
+ break;
511
+
512
+ }
513
+ });
514
+
515
+ });
516
+
517
+ return $this;
518
+
519
+ };
520
+
521
+ /**
522
+ * Moves elements to/from the first positions of their respective parents.
523
+ * @param {jQuery} $elements Elements (or selector) to move.
524
+ * @param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations.
525
+ */
526
+ $.prioritize = function($elements, condition) {
527
+
528
+ var key = '__prioritize';
529
+
530
+ // Expand $elements if it's not already a jQuery object.
531
+ if (typeof $elements != 'jQuery')
532
+ $elements = $($elements);
533
+
534
+ // Step through elements.
535
+ $elements.each(function() {
536
+
537
+ var $e = $(this), $p,
538
+ $parent = $e.parent();
539
+
540
+ // No parent? Bail.
541
+ if ($parent.length == 0)
542
+ return;
543
+
544
+ // Not moved? Move it.
545
+ if (!$e.data(key)) {
546
+
547
+ // Condition is false? Bail.
548
+ if (!condition)
549
+ return;
550
+
551
+ // Get placeholder (which will serve as our point of reference for when this element needs to move back).
552
+ $p = $e.prev();
553
+
554
+ // Couldn't find anything? Means this element's already at the top, so bail.
555
+ if ($p.length == 0)
556
+ return;
557
+
558
+ // Move element to top of parent.
559
+ $e.prependTo($parent);
560
+
561
+ // Mark element as moved.
562
+ $e.data(key, $p);
563
+
564
+ }
565
+
566
+ // Moved already?
567
+ else {
568
+
569
+ // Condition is true? Bail.
570
+ if (condition)
571
+ return;
572
+
573
+ $p = $e.data(key);
574
+
575
+ // Move element back to its original location (using our placeholder).
576
+ $e.insertAfter($p);
577
+
578
+ // Unmark element as moved.
579
+ $e.removeData(key);
580
+
581
+ }
582
+
583
+ });
584
+
585
+ };
586
+
587
587
  })(jQuery);