History

ModbusAdapters: Fixed security issues in Modbus configuration screen GSF.Web: Cleaned up new embedded resources

J. Ritchie Carroll committed 9 years ago

Commit 970956d1 parent 230686d36 files · +72369 −1648Browse files

Showing the changes to Source/Libraries/GSF.Web/Model/Scripts (3 of 36 files). Show all

Unified · Split

3 files
  1. Source/Libraries/GSF.Web/Model/Scripts/ObsoleteFiles.txt +10 −0
  2. Source/Libraries/GSF.Web/Model/Scripts/bootstrap-datepicker.js +1918 −0
  3. Source/Libraries/GSF.Web/Model/Scripts/bootstrap-toolkit.js +234 −0
Source/Libraries/GSF.Web/Model/Scripts/ObsoleteFiles.txt+10−0
@@ -0,0 +1,10 @@
1+!WARNING: The location for the following resources have been moved!
2+ New resource path is "/@GSF/Web/Shared/Scripts/", please update scripts to use these new locations:
3+
4+ /@GSF/Web/Model/Scripts/angular1.5.8.js => /@GSF/Web/Shared/Scripts/angular.js
5+ /@GSF/Web/Model/Scripts/gsf.web.client.js => /@GSF/Web/Shared/Scripts/gsf.web.client.js
6+ /@GSF/Web/Model/Scripts/gsf.web.knockout.js => /@GSF/Web/Shared/Scripts/gsf.web.knockout.js
7+ /@GSF/Web/Model/Scripts/gsf.web.primeui.js => /@GSF/Web/Shared/Scripts/gsf.web.primeui.js
8+ /@GSF/Web/Model/Scripts/js.cookie.js => /@GSF/Web/Shared/Scripts/js.cookie.js
9+ /@GSF/Web/Model/Scripts/ko.reactor.js => /@GSF/Web/Shared/Scripts/knockout.reactor.js
10+/@GSF/Web/Model/Scripts/ko.observableDictionary.js => /@GSF/Web/Shared/Scripts/knockout.obeservableDictionary.js
Source/Libraries/GSF.Web/Model/Scripts/bootstrap-datepicker.js+1918−0
@@ -0,0 +1,1918 @@
1+/*!
2+ * Datepicker for Bootstrap v1.5.1 (https://github.com/eternicode/bootstrap-datepicker)
3+ *
4+ * Copyright 2012 Stefan Petre
5+ * Improvements by Andrew Rowls
6+ * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)
7+ */(function(factory){
8+ if (typeof define === "function" && define.amd) {
9+ define(["jquery"], factory);
10+ } else if (typeof exports === 'object') {
11+ factory(require('jquery'));
12+ } else {
13+ factory(jQuery);
14+ }
15+}(function($, undefined){
16+
17+ function UTCDate(){
18+ return new Date(Date.UTC.apply(Date, arguments));
19+ }
20+ function UTCToday(){
21+ var today = new Date();
22+ return UTCDate(today.getFullYear(), today.getMonth(), today.getDate());
23+ }
24+ function isUTCEquals(date1, date2) {
25+ return (
26+ date1.getUTCFullYear() === date2.getUTCFullYear() &&
27+ date1.getUTCMonth() === date2.getUTCMonth() &&
28+ date1.getUTCDate() === date2.getUTCDate()
29+ );
30+ }
31+ function alias(method){
32+ return function(){
33+ return this[method].apply(this, arguments);
34+ };
35+ }
36+ function isValidDate(d) {
37+ return d && !isNaN(d.getTime());
38+ }
39+
40+ var DateArray = (function(){
41+ var extras = {
42+ get: function(i){
43+ return this.slice(i)[0];
44+ },
45+ contains: function(d){
46+ // Array.indexOf is not cross-browser;
47+ // $.inArray doesn't work with Dates
48+ var val = d && d.valueOf();
49+ for (var i=0, l=this.length; i < l; i++)
50+ if (this[i].valueOf() === val)
51+ return i;
52+ return -1;
53+ },
54+ remove: function(i){
55+ this.splice(i,1);
56+ },
57+ replace: function(new_array){
58+ if (!new_array)
59+ return;
60+ if (!$.isArray(new_array))
61+ new_array = [new_array];
62+ this.clear();
63+ this.push.apply(this, new_array);
64+ },
65+ clear: function(){
66+ this.length = 0;
67+ },
68+ copy: function(){
69+ var a = new DateArray();
70+ a.replace(this);
71+ return a;
72+ }
73+ };
74+
75+ return function(){
76+ var a = [];
77+ a.push.apply(a, arguments);
78+ $.extend(a, extras);
79+ return a;
80+ };
81+ })();
82+
83+
84+ // Picker object
85+
86+ var Datepicker = function(element, options){
87+ $(element).data('datepicker', this);
88+ this._process_options(options);
89+
90+ this.dates = new DateArray();
91+ this.viewDate = this.o.defaultViewDate;
92+ this.focusDate = null;
93+
94+ this.element = $(element);
95+ this.isInline = false;
96+ this.isInput = this.element.is('input');
97+ this.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;
98+ this.hasInput = this.component && this.element.find('input').length;
99+ if (this.component && this.component.length === 0)
100+ this.component = false;
101+
102+ this.picker = $(DPGlobal.template);
103+ this._buildEvents();
104+ this._attachEvents();
105+
106+ if (this.isInline){
107+ this.picker.addClass('datepicker-inline').appendTo(this.element);
108+ }
109+ else {
110+ this.picker.addClass('datepicker-dropdown dropdown-menu');
111+ }
112+
113+ if (this.o.rtl){
114+ this.picker.addClass('datepicker-rtl');
115+ }
116+
117+ this.viewMode = this.o.startView;
118+
119+ if (this.o.calendarWeeks)
120+ this.picker.find('thead .datepicker-title, tfoot .today, tfoot .clear')
121+ .attr('colspan', function(i, val){
122+ return parseInt(val) + 1;
123+ });
124+
125+ this._allow_update = false;
126+
127+ this.setStartDate(this._o.startDate);
128+ this.setEndDate(this._o.endDate);
129+ this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);
130+ this.setDaysOfWeekHighlighted(this.o.daysOfWeekHighlighted);
131+ this.setDatesDisabled(this.o.datesDisabled);
132+
133+ this.fillDow();
134+ this.fillMonths();
135+
136+ this._allow_update = true;
137+
138+ this.update();
139+ this.showMode();
140+
141+ if (this.isInline){
142+ this.show();
143+ }
144+ };
145+
146+ Datepicker.prototype = {
147+ constructor: Datepicker,
148+
149+ _process_options: function(opts){
150+ // Store raw options for reference
151+ this._o = $.extend({}, this._o, opts);
152+ // Processed options
153+ var o = this.o = $.extend({}, this._o);
154+
155+ // Check if "de-DE" style date is available, if not language should
156+ // fallback to 2 letter code eg "de"
157+ var lang = o.language;
158+ if (!dates[lang]){
159+ lang = lang.split('-')[0];
160+ if (!dates[lang])
161+ lang = defaults.language;
162+ }
163+ o.language = lang;
164+
165+ switch (o.startView){
166+ case 2:
167+ case 'decade':
168+ o.startView = 2;
169+ break;
170+ case 1:
171+ case 'year':
172+ o.startView = 1;
173+ break;
174+ default:
175+ o.startView = 0;
176+ }
177+
178+ switch (o.minViewMode){
179+ case 1:
180+ case 'months':
181+ o.minViewMode = 1;
182+ break;
183+ case 2:
184+ case 'years':
185+ o.minViewMode = 2;
186+ break;
187+ default:
188+ o.minViewMode = 0;
189+ }
190+
191+ switch (o.maxViewMode) {
192+ case 0:
193+ case 'days':
194+ o.maxViewMode = 0;
195+ break;
196+ case 1:
197+ case 'months':
198+ o.maxViewMode = 1;
199+ break;
200+ default:
201+ o.maxViewMode = 2;
202+ }
203+
204+ o.startView = Math.min(o.startView, o.maxViewMode);
205+ o.startView = Math.max(o.startView, o.minViewMode);
206+
207+ // true, false, or Number > 0
208+ if (o.multidate !== true){
209+ o.multidate = Number(o.multidate) || false;
210+ if (o.multidate !== false)
211+ o.multidate = Math.max(0, o.multidate);
212+ }
213+ o.multidateSeparator = String(o.multidateSeparator);
214+
215+ o.weekStart %= 7;
216+ o.weekEnd = (o.weekStart + 6) % 7;
217+
218+ var format = DPGlobal.parseFormat(o.format);
219+ if (o.startDate !== -Infinity){
220+ if (!!o.startDate){
221+ if (o.startDate instanceof Date)
222+ o.startDate = this._local_to_utc(this._zero_time(o.startDate));
223+ else
224+ o.startDate = DPGlobal.parseDate(o.startDate, format, o.language);
225+ }
226+ else {
227+ o.startDate = -Infinity;
228+ }
229+ }
230+ if (o.endDate !== Infinity){
231+ if (!!o.endDate){
232+ if (o.endDate instanceof Date)
233+ o.endDate = this._local_to_utc(this._zero_time(o.endDate));
234+ else
235+ o.endDate = DPGlobal.parseDate(o.endDate, format, o.language);
236+ }
237+ else {
238+ o.endDate = Infinity;
239+ }
240+ }
241+
242+ o.daysOfWeekDisabled = o.daysOfWeekDisabled||[];
243+ if (!$.isArray(o.daysOfWeekDisabled))
244+ o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/);
245+ o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){
246+ return parseInt(d, 10);
247+ });
248+
249+ o.daysOfWeekHighlighted = o.daysOfWeekHighlighted||[];
250+ if (!$.isArray(o.daysOfWeekHighlighted))
251+ o.daysOfWeekHighlighted = o.daysOfWeekHighlighted.split(/[,\s]*/);
252+ o.daysOfWeekHighlighted = $.map(o.daysOfWeekHighlighted, function(d){
253+ return parseInt(d, 10);
254+ });
255+
256+ o.datesDisabled = o.datesDisabled||[];
257+ if (!$.isArray(o.datesDisabled)) {
258+ var datesDisabled = [];
259+ datesDisabled.push(DPGlobal.parseDate(o.datesDisabled, format, o.language));
260+ o.datesDisabled = datesDisabled;
261+ }
262+ o.datesDisabled = $.map(o.datesDisabled,function(d){
263+ return DPGlobal.parseDate(d, format, o.language);
264+ });
265+
266+ var plc = String(o.orientation).toLowerCase().split(/\s+/g),
267+ _plc = o.orientation.toLowerCase();
268+ plc = $.grep(plc, function(word){
269+ return /^auto|left|right|top|bottom$/.test(word);
270+ });
271+ o.orientation = {x: 'auto', y: 'auto'};
272+ if (!_plc || _plc === 'auto')
273+ ; // no action
274+ else if (plc.length === 1){
275+ switch (plc[0]){
276+ case 'top':
277+ case 'bottom':
278+ o.orientation.y = plc[0];
279+ break;
280+ case 'left':
281+ case 'right':
282+ o.orientation.x = plc[0];
283+ break;
284+ }
285+ }
286+ else {
287+ _plc = $.grep(plc, function(word){
288+ return /^left|right$/.test(word);
289+ });
290+ o.orientation.x = _plc[0] || 'auto';
291+
292+ _plc = $.grep(plc, function(word){
293+ return /^top|bottom$/.test(word);
294+ });
295+ o.orientation.y = _plc[0] || 'auto';
296+ }
297+ if (o.defaultViewDate) {
298+ var year = o.defaultViewDate.year || new Date().getFullYear();
299+ var month = o.defaultViewDate.month || 0;
300+ var day = o.defaultViewDate.day || 1;
301+ o.defaultViewDate = UTCDate(year, month, day);
302+ } else {
303+ o.defaultViewDate = UTCToday();
304+ }
305+ },
306+ _events: [],
307+ _secondaryEvents: [],
308+ _applyEvents: function(evs){
309+ for (var i=0, el, ch, ev; i < evs.length; i++){
310+ el = evs[i][0];
311+ if (evs[i].length === 2){
312+ ch = undefined;
313+ ev = evs[i][1];
314+ }
315+ else if (evs[i].length === 3){
316+ ch = evs[i][1];
317+ ev = evs[i][2];
318+ }
319+ el.on(ev, ch);
320+ }
321+ },
322+ _unapplyEvents: function(evs){
323+ for (var i=0, el, ev, ch; i < evs.length; i++){
324+ el = evs[i][0];
325+ if (evs[i].length === 2){
326+ ch = undefined;
327+ ev = evs[i][1];
328+ }
329+ else if (evs[i].length === 3){
330+ ch = evs[i][1];
331+ ev = evs[i][2];
332+ }
333+ el.off(ev, ch);
334+ }
335+ },
336+ _buildEvents: function(){
337+ var events = {
338+ keyup: $.proxy(function(e){
339+ if ($.inArray(e.keyCode, [27, 37, 39, 38, 40, 32, 13, 9]) === -1)
340+ this.update();
341+ }, this),
342+ keydown: $.proxy(this.keydown, this),
343+ paste: $.proxy(this.paste, this)
344+ };
345+
346+ if (this.o.showOnFocus === true) {
347+ events.focus = $.proxy(this.show, this);
348+ }
349+
350+ if (this.isInput) { // single input
351+ this._events = [
352+ [this.element, events]
353+ ];
354+ }
355+ else if (this.component && this.hasInput) { // component: input + button
356+ this._events = [
357+ // For components that are not readonly, allow keyboard nav
358+ [this.element.find('input'), events],
359+ [this.component, {
360+ click: $.proxy(this.show, this)
361+ }]
362+ ];
363+ }
364+ else if (this.element.is('div')){ // inline datepicker
365+ this.isInline = true;
366+ }
367+ else {
368+ this._events = [
369+ [this.element, {
370+ click: $.proxy(this.show, this)
371+ }]
372+ ];
373+ }
374+ this._events.push(
375+ // Component: listen for blur on element descendants
376+ [this.element, '*', {
377+ blur: $.proxy(function(e){
378+ this._focused_from = e.target;
379+ }, this)
380+ }],
381+ // Input: listen for blur on element
382+ [this.element, {
383+ blur: $.proxy(function(e){
384+ this._focused_from = e.target;
385+ }, this)
386+ }]
387+ );
388+
389+ if (this.o.immediateUpdates) {
390+ // Trigger input updates immediately on changed year/month
391+ this._events.push([this.element, {
392+ 'changeYear changeMonth': $.proxy(function(e){
393+ this.update(e.date);
394+ }, this)
395+ }]);
396+ }
397+
398+ this._secondaryEvents = [
399+ [this.picker, {
400+ click: $.proxy(this.click, this)
401+ }],
402+ [$(window), {
403+ resize: $.proxy(this.place, this)
404+ }],
405+ [$(document), {
406+ mousedown: $.proxy(function(e){
407+ // Clicked outside the datepicker, hide it
408+ if (!(
409+ this.element.is(e.target) ||
410+ this.element.find(e.target).length ||
411+ this.picker.is(e.target) ||
412+ this.picker.find(e.target).length ||
413+ this.picker.hasClass('datepicker-inline')
414+ )){
415+ this.hide();
416+ }
417+ }, this)
418+ }]
419+ ];
420+ },
421+ _attachEvents: function(){
422+ this._detachEvents();
423+ this._applyEvents(this._events);
424+ },
425+ _detachEvents: function(){
426+ this._unapplyEvents(this._events);
427+ },
428+ _attachSecondaryEvents: function(){
429+ this._detachSecondaryEvents();
430+ this._applyEvents(this._secondaryEvents);
431+ },
432+ _detachSecondaryEvents: function(){
433+ this._unapplyEvents(this._secondaryEvents);
434+ },
435+ _trigger: function(event, altdate){
436+ var date = altdate || this.dates.get(-1),
437+ local_date = this._utc_to_local(date);
438+
439+ this.element.trigger({
440+ type: event,
441+ date: local_date,
442+ dates: $.map(this.dates, this._utc_to_local),
443+ format: $.proxy(function(ix, format){
444+ if (arguments.length === 0){
445+ ix = this.dates.length - 1;
446+ format = this.o.format;
447+ }
448+ else if (typeof ix === 'string'){
449+ format = ix;
450+ ix = this.dates.length - 1;
451+ }
452+ format = format || this.o.format;
453+ var date = this.dates.get(ix);
454+ return DPGlobal.formatDate(date, format, this.o.language);
455+ }, this)
456+ });
457+ },
458+
459+ show: function(){
460+ var element = this.component ? this.element.find('input') : this.element;
461+ if (element.attr('readonly') && this.o.enableOnReadonly === false)
462+ return;
463+ if (!this.isInline)
464+ this.picker.appendTo(this.o.container);
465+ this.place();
466+ this.picker.show();
467+ this._attachSecondaryEvents();
468+ this._trigger('show');
469+ if ((window.navigator.msMaxTouchPoints || 'ontouchstart' in document) && this.o.disableTouchKeyboard) {
470+ $(this.element).blur();
471+ }
472+ return this;
473+ },
474+
475+ hide: function(){
476+ if (this.isInline)
477+ return this;
478+ if (!this.picker.is(':visible'))
479+ return this;
480+ this.focusDate = null;
481+ this.picker.hide().detach();
482+ this._detachSecondaryEvents();
483+ this.viewMode = this.o.startView;
484+ this.showMode();
485+
486+ if (
487+ this.o.forceParse &&
488+ (
489+ this.isInput && this.element.val() ||
490+ this.hasInput && this.element.find('input').val()
491+ )
492+ )
493+ this.setValue();
494+ this._trigger('hide');
495+ return this;
496+ },
497+
498+ remove: function(){
499+ this.hide();
500+ this._detachEvents();
501+ this._detachSecondaryEvents();
502+ this.picker.remove();
503+ delete this.element.data().datepicker;
504+ if (!this.isInput){
505+ delete this.element.data().date;
506+ }
507+ return this;
508+ },
509+
510+ paste: function(evt){
511+ var dateString;
512+ if (evt.originalEvent.clipboardData && evt.originalEvent.clipboardData.types
513+ && $.inArray('text/plain', evt.originalEvent.clipboardData.types) !== -1) {
514+ dateString = evt.originalEvent.clipboardData.getData('text/plain');
515+ }
516+ else if (window.clipboardData) {
517+ dateString = window.clipboardData.getData('Text');
518+ }
519+ else {
520+ return;
521+ }
522+ this.setDate(dateString);
523+ this.update();
524+ evt.preventDefault();
525+ },
526+
527+ _utc_to_local: function(utc){
528+ return utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000));
529+ },
530+ _local_to_utc: function(local){
531+ return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000));
532+ },
533+ _zero_time: function(local){
534+ return local && new Date(local.getFullYear(), local.getMonth(), local.getDate());
535+ },
536+ _zero_utc_time: function(utc){
537+ return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()));
538+ },
539+
540+ getDates: function(){
541+ return $.map(this.dates, this._utc_to_local);
542+ },
543+
544+ getUTCDates: function(){
545+ return $.map(this.dates, function(d){
546+ return new Date(d);
547+ });
548+ },
549+
550+ getDate: function(){
551+ return this._utc_to_local(this.getUTCDate());
552+ },
553+
554+ getUTCDate: function(){
555+ var selected_date = this.dates.get(-1);
556+ if (typeof selected_date !== 'undefined') {
557+ return new Date(selected_date);
558+ } else {
559+ return null;
560+ }
561+ },
562+
563+ clearDates: function(){
564+ var element;
565+ if (this.isInput) {
566+ element = this.element;
567+ } else if (this.component) {
568+ element = this.element.find('input');
569+ }
570+
571+ if (element) {
572+ element.val('');
573+ }
574+
575+ this.update();
576+ this._trigger('changeDate');
577+
578+ if (this.o.autoclose) {
579+ this.hide();
580+ }
581+ },
582+ setDates: function(){
583+ var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
584+ this.update.apply(this, args);
585+ this._trigger('changeDate');
586+ this.setValue();
587+ return this;
588+ },
589+
590+ setUTCDates: function(){
591+ var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
592+ this.update.apply(this, $.map(args, this._utc_to_local));
593+ this._trigger('changeDate');
594+ this.setValue();
595+ return this;
596+ },
597+
598+ setDate: alias('setDates'),
599+ setUTCDate: alias('setUTCDates'),
600+
601+ setValue: function(){
602+ var formatted = this.getFormattedDate();
603+ if (!this.isInput){
604+ if (this.component){
605+ this.element.find('input').val(formatted);
606+ }
607+ }
608+ else {
609+ this.element.val(formatted);
610+ }
611+ return this;
612+ },
613+
614+ getFormattedDate: function(format){
615+ if (format === undefined)
616+ format = this.o.format;
617+
618+ var lang = this.o.language;
619+ return $.map(this.dates, function(d){
620+ return DPGlobal.formatDate(d, format, lang);
621+ }).join(this.o.multidateSeparator);
622+ },
623+
624+ setStartDate: function(startDate){
625+ this._process_options({startDate: startDate});
626+ this.update();
627+ this.updateNavArrows();
628+ return this;
629+ },
630+
631+ setEndDate: function(endDate){
632+ this._process_options({endDate: endDate});
633+ this.update();
634+ this.updateNavArrows();
635+ return this;
636+ },
637+
638+ setDaysOfWeekDisabled: function(daysOfWeekDisabled){
639+ this._process_options({daysOfWeekDisabled: daysOfWeekDisabled});
640+ this.update();
641+ this.updateNavArrows();
642+ return this;
643+ },
644+
645+ setDaysOfWeekHighlighted: function(daysOfWeekHighlighted){
646+ this._process_options({daysOfWeekHighlighted: daysOfWeekHighlighted});
647+ this.update();
648+ return this;
649+ },
650+
651+ setDatesDisabled: function(datesDisabled){
652+ this._process_options({datesDisabled: datesDisabled});
653+ this.update();
654+ this.updateNavArrows();
655+ },
656+
657+ place: function(){
658+ if (this.isInline)
659+ return this;
660+ var calendarWidth = this.picker.outerWidth(),
661+ calendarHeight = this.picker.outerHeight(),
662+ visualPadding = 10,
663+ container = $(this.o.container),
664+ windowWidth = container.width(),
665+ scrollTop = this.o.container === 'body' ? $(document).scrollTop() : container.scrollTop(),
666+ appendOffset = container.offset();
667+
668+ var parentsZindex = [];
669+ this.element.parents().each(function(){
670+ var itemZIndex = $(this).css('z-index');
671+ if (itemZIndex !== 'auto' && itemZIndex !== 0) parentsZindex.push(parseInt(itemZIndex));
672+ });
673+ var zIndex = Math.max.apply(Math, parentsZindex) + this.o.zIndexOffset;
674+ var offset = this.component ? this.component.parent().offset() : this.element.offset();
675+ var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);
676+ var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);
677+ var left = offset.left - appendOffset.left,
678+ top = offset.top - appendOffset.top;
679+
680+ if (this.o.container !== 'body') {
681+ top += scrollTop;
682+ }
683+
684+ this.picker.removeClass(
685+ 'datepicker-orient-top datepicker-orient-bottom '+
686+ 'datepicker-orient-right datepicker-orient-left'
687+ );
688+
689+ if (this.o.orientation.x !== 'auto'){
690+ this.picker.addClass('datepicker-orient-' + this.o.orientation.x);
691+ if (this.o.orientation.x === 'right')
692+ left -= calendarWidth - width;
693+ }
694+ // auto x orientation is best-placement: if it crosses a window
695+ // edge, fudge it sideways
696+ else {
697+ if (offset.left < 0) {
698+ // component is outside the window on the left side. Move it into visible range
699+ this.picker.addClass('datepicker-orient-left');
700+ left -= offset.left - visualPadding;
701+ } else if (left + calendarWidth > windowWidth) {
702+ // the calendar passes the widow right edge. Align it to component right side
703+ this.picker.addClass('datepicker-orient-right');
704+ left += width - calendarWidth;
705+ } else {
706+ // Default to left
707+ this.picker.addClass('datepicker-orient-left');
708+ }
709+ }
710+
711+ // auto y orientation is best-situation: top or bottom, no fudging,
712+ // decision based on which shows more of the calendar
713+ var yorient = this.o.orientation.y,
714+ top_overflow;
715+ if (yorient === 'auto'){
716+ top_overflow = -scrollTop + top - calendarHeight;
717+ yorient = top_overflow < 0 ? 'bottom' : 'top';
718+ }
719+
720+ this.picker.addClass('datepicker-orient-' + yorient);
721+ if (yorient === 'top')
722+ top -= calendarHeight + parseInt(this.picker.css('padding-top'));
723+ else
724+ top += height;
725+
726+ if (this.o.rtl) {
727+ var right = windowWidth - (left + width);
728+ this.picker.css({
729+ top: top,
730+ right: right,
731+ zIndex: zIndex
732+ });
733+ } else {
734+ this.picker.css({
735+ top: top,
736+ left: left,
737+ zIndex: zIndex
738+ });
739+ }
740+ return this;
741+ },
742+
743+ _allow_update: true,
744+ update: function(){
745+ if (!this._allow_update)
746+ return this;
747+
748+ var oldDates = this.dates.copy(),
749+ dates = [],
750+ fromArgs = false;
751+ if (arguments.length){
752+ $.each(arguments, $.proxy(function(i, date){
753+ if (date instanceof Date)
754+ date = this._local_to_utc(date);
755+ dates.push(date);
756+ }, this));
757+ fromArgs = true;
758+ }
759+ else {
760+ dates = this.isInput
761+ ? this.element.val()
762+ : this.element.data('date') || this.element.find('input').val();
763+ if (dates && this.o.multidate)
764+ dates = dates.split(this.o.multidateSeparator);
765+ else
766+ dates = [dates];
767+ delete this.element.data().date;
768+ }
769+
770+ dates = $.map(dates, $.proxy(function(date){
771+ return DPGlobal.parseDate(date, this.o.format, this.o.language);
772+ }, this));
773+ dates = $.grep(dates, $.proxy(function(date){
774+ return (
775+ !this.dateWithinRange(date) ||
776+ !date
777+ );
778+ }, this), true);
779+ this.dates.replace(dates);
780+
781+ if (this.dates.length)
782+ this.viewDate = new Date(this.dates.get(-1));
783+ else if (this.viewDate < this.o.startDate)
784+ this.viewDate = new Date(this.o.startDate);
785+ else if (this.viewDate > this.o.endDate)
786+ this.viewDate = new Date(this.o.endDate);
787+ else
788+ this.viewDate = this.o.defaultViewDate;
789+
790+ if (fromArgs){
791+ // setting date by clicking
792+ this.setValue();
793+ }
794+ else if (dates.length){
795+ // setting date by typing
796+ if (String(oldDates) !== String(this.dates))
797+ this._trigger('changeDate');
798+ }
799+ if (!this.dates.length && oldDates.length)
800+ this._trigger('clearDate');
801+
802+ this.fill();
803+ this.element.change();
804+ return this;
805+ },
806+
807+ fillDow: function(){
808+ var dowCnt = this.o.weekStart,
809+ html = '<tr>';
810+ if (this.o.calendarWeeks){
811+ this.picker.find('.datepicker-days .datepicker-switch')
812+ .attr('colspan', function(i, val){
813+ return parseInt(val) + 1;
814+ });
815+ html += '<th class="cw">&#160;</th>';
816+ }
817+ while (dowCnt < this.o.weekStart + 7){
818+ html += '<th class="dow">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';
819+ }
820+ html += '</tr>';
821+ this.picker.find('.datepicker-days thead').append(html);
822+ },
823+
824+ fillMonths: function(){
825+ var html = '',
826+ i = 0;
827+ while (i < 12){
828+ html += '<span class="month">'+dates[this.o.language].monthsShort[i++]+'</span>';
829+ }
830+ this.picker.find('.datepicker-months td').html(html);
831+ },
832+
833+ setRange: function(range){
834+ if (!range || !range.length)
835+ delete this.range;
836+ else
837+ this.range = $.map(range, function(d){
838+ return d.valueOf();
839+ });
840+ this.fill();
841+ },
842+
843+ getClassNames: function(date){
844+ var cls = [],
845+ year = this.viewDate.getUTCFullYear(),
846+ month = this.viewDate.getUTCMonth(),
847+ today = new Date();
848+ if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){
849+ cls.push('old');
850+ }
851+ else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
852+ cls.push('new');
853+ }
854+ if (this.focusDate && date.valueOf() === this.focusDate.valueOf())
855+ cls.push('focused');
856+ // Compare internal UTC date with local today, not UTC today
857+ if (this.o.todayHighlight &&
858+ date.getUTCFullYear() === today.getFullYear() &&
859+ date.getUTCMonth() === today.getMonth() &&
860+ date.getUTCDate() === today.getDate()){
861+ cls.push('today');
862+ }
863+ if (this.dates.contains(date) !== -1)
864+ cls.push('active');
865+ if (!this.dateWithinRange(date) || this.dateIsDisabled(date)){
866+ cls.push('disabled');
867+ }
868+ if ($.inArray(date.getUTCDay(), this.o.daysOfWeekHighlighted) !== -1){
869+ cls.push('highlighted');
870+ }
871+
872+ if (this.range){
873+ if (date > this.range[0] && date < this.range[this.range.length-1]){
874+ cls.push('range');
875+ }
876+ if ($.inArray(date.valueOf(), this.range) !== -1){
877+ cls.push('selected');
878+ }
879+ if (date.valueOf() === this.range[0]){
880+ cls.push('range-start');
881+ }
882+ if (date.valueOf() === this.range[this.range.length-1]){
883+ cls.push('range-end');
884+ }
885+ }
886+ return cls;
887+ },
888+
889+ fill: function(){
890+ var d = new Date(this.viewDate),
891+ year = d.getUTCFullYear(),
892+ month = d.getUTCMonth(),
893+ startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
894+ startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
895+ endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
896+ endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
897+ todaytxt = dates[this.o.language].today || dates['en'].today || '',
898+ cleartxt = dates[this.o.language].clear || dates['en'].clear || '',
899+ titleFormat = dates[this.o.language].titleFormat || dates['en'].titleFormat,
900+ tooltip;
901+ if (isNaN(year) || isNaN(month))
902+ return;
903+ this.picker.find('.datepicker-days thead .datepicker-switch')
904+ .text(DPGlobal.formatDate(new UTCDate(year, month), titleFormat, this.o.language));
905+ this.picker.find('tfoot .today')
906+ .text(todaytxt)
907+ .toggle(this.o.todayBtn !== false);
908+ this.picker.find('tfoot .clear')
909+ .text(cleartxt)
910+ .toggle(this.o.clearBtn !== false);
911+ this.picker.find('thead .datepicker-title')
912+ .text(this.o.title)
913+ .toggle(this.o.title !== '');
914+ this.updateNavArrows();
915+ this.fillMonths();
916+ var prevMonth = UTCDate(year, month-1, 28),
917+ day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
918+ prevMonth.setUTCDate(day);
919+ prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);
920+ var nextMonth = new Date(prevMonth);
921+ if (prevMonth.getUTCFullYear() < 100){
922+ nextMonth.setUTCFullYear(prevMonth.getUTCFullYear());
923+ }
924+ nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
925+ nextMonth = nextMonth.valueOf();
926+ var html = [];
927+ var clsName;
928+ while (prevMonth.valueOf() < nextMonth){
929+ if (prevMonth.getUTCDay() === this.o.weekStart){
930+ html.push('<tr>');
931+ if (this.o.calendarWeeks){
932+ // ISO 8601: First week contains first thursday.
933+ // ISO also states week starts on Monday, but we can be more abstract here.
934+ var
935+ // Start of current week: based on weekstart/current date
936+ ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
937+ // Thursday of this week
938+ th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
939+ // First Thursday of year, year from thursday
940+ yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),
941+ // Calendar week: ms between thursdays, div ms per day, div 7 days
942+ calWeek = (th - yth) / 864e5 / 7 + 1;
943+ html.push('<td class="cw">'+ calWeek +'</td>');
944+
945+ }
946+ }
947+ clsName = this.getClassNames(prevMonth);
948+ clsName.push('day');
949+
950+ if (this.o.beforeShowDay !== $.noop){
951+ var before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
952+ if (before === undefined)
953+ before = {};
954+ else if (typeof(before) === 'boolean')
955+ before = {enabled: before};
956+ else if (typeof(before) === 'string')
957+ before = {classes: before};
958+ if (before.enabled === false)
959+ clsName.push('disabled');
960+ if (before.classes)
961+ clsName = clsName.concat(before.classes.split(/\s+/));
962+ if (before.tooltip)
963+ tooltip = before.tooltip;
964+ }
965+
966+ clsName = $.unique(clsName);
967+ html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>'+prevMonth.getUTCDate() + '</td>');
968+ tooltip = null;
969+ if (prevMonth.getUTCDay() === this.o.weekEnd){
970+ html.push('</tr>');
971+ }
972+ prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
973+ }
974+ this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
975+
976+ var monthsTitle = dates[this.o.language].monthsTitle || dates['en'].monthsTitle || 'Months';
977+ var months = this.picker.find('.datepicker-months')
978+ .find('.datepicker-switch')
979+ .text(this.o.maxViewMode < 2 ? monthsTitle : year)
980+ .end()
981+ .find('span').removeClass('active');
982+
983+ $.each(this.dates, function(i, d){
984+ if (d.getUTCFullYear() === year)
985+ months.eq(d.getUTCMonth()).addClass('active');
986+ });
987+
988+ if (year < startYear || year > endYear){
989+ months.addClass('disabled');
990+ }
991+ if (year === startYear){
992+ months.slice(0, startMonth).addClass('disabled');
993+ }
994+ if (year === endYear){
995+ months.slice(endMonth+1).addClass('disabled');
996+ }
997+
998+ if (this.o.beforeShowMonth !== $.noop){
999+ var that = this;
1000+ $.each(months, function(i, month){
1001+ if (!$(month).hasClass('disabled')) {
1002+ var moDate = new Date(year, i, 1);
1003+ var before = that.o.beforeShowMonth(moDate);
1004+ if (before === false)
1005+ $(month).addClass('disabled');
1006+ }
1007+ });
1008+ }
1009+
1010+ html = '';
1011+ year = parseInt(year/10, 10) * 10;
1012+ var yearCont = this.picker.find('.datepicker-years')
1013+ .find('.datepicker-switch')
1014+ .text(year + '-' + (year + 9))
1015+ .end()
1016+ .find('td');
1017+ year -= 1;
1018+ var years = $.map(this.dates, function(d){
1019+ return d.getUTCFullYear();
1020+ }),
1021+ classes;
1022+ for (var i = -1; i < 11; i++){
1023+ classes = ['year'];
1024+ tooltip = null;
1025+
1026+ if (i === -1)
1027+ classes.push('old');
1028+ else if (i === 10)
1029+ classes.push('new');
1030+ if ($.inArray(year, years) !== -1)
1031+ classes.push('active');
1032+ if (year < startYear || year > endYear)
1033+ classes.push('disabled');
1034+
1035+ if (this.o.beforeShowYear !== $.noop) {
1036+ var yrBefore = this.o.beforeShowYear(new Date(year, 0, 1));
1037+ if (yrBefore === undefined)
1038+ yrBefore = {};
1039+ else if (typeof(yrBefore) === 'boolean')
1040+ yrBefore = {enabled: yrBefore};
1041+ else if (typeof(yrBefore) === 'string')
1042+ yrBefore = {classes: yrBefore};
1043+ if (yrBefore.enabled === false)
1044+ classes.push('disabled');
1045+ if (yrBefore.classes)
1046+ classes = classes.concat(yrBefore.classes.split(/\s+/));
1047+ if (yrBefore.tooltip)
1048+ tooltip = yrBefore.tooltip;
1049+ }
1050+
1051+ html += '<span class="' + classes.join(' ') + '"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>' + year + '</span>';
1052+ year += 1;
1053+ }
1054+ yearCont.html(html);
1055+ },
1056+
1057+ updateNavArrows: function(){
1058+ if (!this._allow_update)
1059+ return;
1060+
1061+ var d = new Date(this.viewDate),
1062+ year = d.getUTCFullYear(),
1063+ month = d.getUTCMonth();
1064+ switch (this.viewMode){
1065+ case 0:
1066+ if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){
1067+ this.picker.find('.prev').css({visibility: 'hidden'});
1068+ }
1069+ else {
1070+ this.picker.find('.prev').css({visibility: 'visible'});
1071+ }
1072+ if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){
1073+ this.picker.find('.next').css({visibility: 'hidden'});
1074+ }
1075+ else {
1076+ this.picker.find('.next').css({visibility: 'visible'});
1077+ }
1078+ break;
1079+ case 1:
1080+ case 2:
1081+ if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() || this.o.maxViewMode < 2){
1082+ this.picker.find('.prev').css({visibility: 'hidden'});
1083+ }
1084+ else {
1085+ this.picker.find('.prev').css({visibility: 'visible'});
1086+ }
1087+ if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() || this.o.maxViewMode < 2){
1088+ this.picker.find('.next').css({visibility: 'hidden'});
1089+ }
1090+ else {
1091+ this.picker.find('.next').css({visibility: 'visible'});
1092+ }
1093+ break;
1094+ }
1095+ },
1096+
1097+ click: function(e){
1098+ e.preventDefault();
1099+ e.stopPropagation();
1100+ var target = $(e.target).closest('span, td, th'),
1101+ year, month, day;
1102+ if (target.length === 1){
1103+ switch (target[0].nodeName.toLowerCase()){
1104+ case 'th':
1105+ switch (target[0].className){
1106+ case 'datepicker-switch':
1107+ this.showMode(1);
1108+ break;
1109+ case 'prev':
1110+ case 'next':
1111+ var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1);
1112+ switch (this.viewMode){
1113+ case 0:
1114+ this.viewDate = this.moveMonth(this.viewDate, dir);
1115+ this._trigger('changeMonth', this.viewDate);
1116+ break;
1117+ case 1:
1118+ case 2:
1119+ this.viewDate = this.moveYear(this.viewDate, dir);
1120+ if (this.viewMode === 1)
1121+ this._trigger('changeYear', this.viewDate);
1122+ break;
1123+ }
1124+ this.fill();
1125+ break;
1126+ case 'today':
1127+ this.showMode(-2);
1128+ var which = this.o.todayBtn === 'linked' ? null : 'view';
1129+ this._setDate(UTCToday(), which);
1130+ break;
1131+ case 'clear':
1132+ this.clearDates();
1133+ break;
1134+ }
1135+ break;
1136+ case 'span':
1137+ if (!target.hasClass('disabled')){
1138+ this.viewDate.setUTCDate(1);
1139+ if (target.hasClass('month')){
1140+ day = 1;
1141+ month = target.parent().find('span').index(target);
1142+ year = this.viewDate.getUTCFullYear();
1143+ this.viewDate.setUTCMonth(month);
1144+ this._trigger('changeMonth', this.viewDate);
1145+ if (this.o.minViewMode === 1){
1146+ this._setDate(UTCDate(year, month, day));
1147+ this.showMode();
1148+ } else {
1149+ this.showMode(-1);
1150+ }
1151+ }
1152+ else {
1153+ day = 1;
1154+ month = 0;
1155+ year = parseInt(target.text(), 10)||0;
1156+ this.viewDate.setUTCFullYear(year);
1157+ this._trigger('changeYear', this.viewDate);
1158+ if (this.o.minViewMode === 2){
1159+ this._setDate(UTCDate(year, month, day));
1160+ }
1161+ this.showMode(-1);
1162+ }
1163+ this.fill();
1164+ }
1165+ break;
1166+ case 'td':
1167+ if (target.hasClass('day') && !target.hasClass('disabled')){
1168+ day = parseInt(target.text(), 10)||1;
1169+ year = this.viewDate.getUTCFullYear();
1170+ month = this.viewDate.getUTCMonth();
1171+ if (target.hasClass('old')){
1172+ if (month === 0){
1173+ month = 11;
1174+ year -= 1;
1175+ }
1176+ else {
1177+ month -= 1;
1178+ }
1179+ }
1180+ else if (target.hasClass('new')){
1181+ if (month === 11){
1182+ month = 0;
1183+ year += 1;
1184+ }
1185+ else {
1186+ month += 1;
1187+ }
1188+ }
1189+ this._setDate(UTCDate(year, month, day));
1190+ }
1191+ break;
1192+ }
1193+ }
1194+ if (this.picker.is(':visible') && this._focused_from){
1195+ $(this._focused_from).focus();
1196+ }
1197+ delete this._focused_from;
1198+ },
1199+
1200+ _toggle_multidate: function(date){
1201+ var ix = this.dates.contains(date);
1202+ if (!date){
1203+ this.dates.clear();
1204+ }
1205+
1206+ if (ix !== -1){
1207+ if (this.o.multidate === true || this.o.multidate > 1 || this.o.toggleActive){
1208+ this.dates.remove(ix);
1209+ }
1210+ } else if (this.o.multidate === false) {
1211+ this.dates.clear();
1212+ this.dates.push(date);
1213+ }
1214+ else {
1215+ this.dates.push(date);
1216+ }
1217+
1218+ if (typeof this.o.multidate === 'number')
1219+ while (this.dates.length > this.o.multidate)
1220+ this.dates.remove(0);
1221+ },
1222+
1223+ _setDate: function(date, which){
1224+ if (!which || which === 'date')
1225+ this._toggle_multidate(date && new Date(date));
1226+ if (!which || which === 'view')
1227+ this.viewDate = date && new Date(date);
1228+
1229+ this.fill();
1230+ this.setValue();
1231+ if (!which || which !== 'view') {
1232+ this._trigger('changeDate');
1233+ }
1234+ var element;
1235+ if (this.isInput){
1236+ element = this.element;
1237+ }
1238+ else if (this.component){
1239+ element = this.element.find('input');
1240+ }
1241+ if (element){
1242+ element.change();
1243+ }
1244+ if (this.o.autoclose && (!which || which === 'date')){
1245+ this.hide();
1246+ }
1247+ },
1248+
1249+ moveDay: function(date, dir){
1250+ var newDate = new Date(date);
1251+ newDate.setUTCDate(date.getUTCDate() + dir);
1252+
1253+ return newDate;
1254+ },
1255+
1256+ moveWeek: function(date, dir){
1257+ return this.moveDay(date, dir * 7);
1258+ },
1259+
1260+ moveMonth: function(date, dir){
1261+ if (!isValidDate(date))
1262+ return this.o.defaultViewDate;
1263+ if (!dir)
1264+ return date;
1265+ var new_date = new Date(date.valueOf()),
1266+ day = new_date.getUTCDate(),
1267+ month = new_date.getUTCMonth(),
1268+ mag = Math.abs(dir),
1269+ new_month, test;
1270+ dir = dir > 0 ? 1 : -1;
1271+ if (mag === 1){
1272+ test = dir === -1
1273+ // If going back one month, make sure month is not current month
1274+ // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)
1275+ ? function(){
1276+ return new_date.getUTCMonth() === month;
1277+ }
1278+ // If going forward one month, make sure month is as expected
1279+ // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)
1280+ : function(){
1281+ return new_date.getUTCMonth() !== new_month;
1282+ };
1283+ new_month = month + dir;
1284+ new_date.setUTCMonth(new_month);
1285+ // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
1286+ if (new_month < 0 || new_month > 11)
1287+ new_month = (new_month + 12) % 12;
1288+ }
1289+ else {
1290+ // For magnitudes >1, move one month at a time...
1291+ for (var i=0; i < mag; i++)
1292+ // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
1293+ new_date = this.moveMonth(new_date, dir);
1294+ // ...then reset the day, keeping it in the new month
1295+ new_month = new_date.getUTCMonth();
1296+ new_date.setUTCDate(day);
1297+ test = function(){
1298+ return new_month !== new_date.getUTCMonth();
1299+ };
1300+ }
1301+ // Common date-resetting loop -- if date is beyond end of month, make it
1302+ // end of month
1303+ while (test()){
1304+ new_date.setUTCDate(--day);
1305+ new_date.setUTCMonth(new_month);
1306+ }
1307+ return new_date;
1308+ },
1309+
1310+ moveYear: function(date, dir){
1311+ return this.moveMonth(date, dir*12);
1312+ },
1313+
1314+ moveAvailableDate: function(date, dir, fn){
1315+ do {
1316+ date = this[fn](date, dir);
1317+
1318+ if (!this.dateWithinRange(date))
1319+ return false;
1320+
1321+ fn = 'moveDay';
1322+ }
1323+ while (this.dateIsDisabled(date));
1324+
1325+ return date;
1326+ },
1327+
1328+ weekOfDateIsDisabled: function(date){
1329+ return $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1;
1330+ },
1331+
1332+ dateIsDisabled: function(date){
1333+ return (
1334+ this.weekOfDateIsDisabled(date) ||
1335+ $.grep(this.o.datesDisabled, function(d){
1336+ return isUTCEquals(date, d);
1337+ }).length > 0
1338+ );
1339+ },
1340+
1341+ dateWithinRange: function(date){
1342+ return date >= this.o.startDate && date <= this.o.endDate;
1343+ },
1344+
1345+ keydown: function(e){
1346+ if (!this.picker.is(':visible')){
1347+ if (e.keyCode === 40 || e.keyCode === 27) { // allow down to re-show picker
1348+ this.show();
1349+ e.stopPropagation();
1350+ }
1351+ return;
1352+ }
1353+ var dateChanged = false,
1354+ dir, newViewDate,
1355+ focusDate = this.focusDate || this.viewDate;
1356+ switch (e.keyCode){
1357+ case 27: // escape
1358+ if (this.focusDate){
1359+ this.focusDate = null;
1360+ this.viewDate = this.dates.get(-1) || this.viewDate;
1361+ this.fill();
1362+ }
1363+ else
1364+ this.hide();
1365+ e.preventDefault();
1366+ e.stopPropagation();
1367+ break;
1368+ case 37: // left
1369+ case 38: // up
1370+ case 39: // right
1371+ case 40: // down
1372+ if (!this.o.keyboardNavigation || this.o.daysOfWeekDisabled.length === 7)
1373+ break;
1374+ dir = e.keyCode === 37 || e.keyCode === 38 ? -1 : 1;
1375+ if (e.ctrlKey){
1376+ newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear');
1377+
1378+ if (newViewDate)
1379+ this._trigger('changeYear', this.viewDate);
1380+ }
1381+ else if (e.shiftKey){
1382+ newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');
1383+
1384+ if (newViewDate)
1385+ this._trigger('changeMonth', this.viewDate);
1386+ }
1387+ else if (e.keyCode === 37 || e.keyCode === 39){
1388+ newViewDate = this.moveAvailableDate(focusDate, dir, 'moveDay');
1389+ }
1390+ else if (!this.weekOfDateIsDisabled(focusDate)){
1391+ newViewDate = this.moveAvailableDate(focusDate, dir, 'moveWeek');
1392+ }
1393+ if (newViewDate){
1394+ this.focusDate = this.viewDate = newViewDate;
1395+ this.setValue();
1396+ this.fill();
1397+ e.preventDefault();
1398+ }
1399+ break;
1400+ case 13: // enter
1401+ if (!this.o.forceParse)
1402+ break;
1403+ focusDate = this.focusDate || this.dates.get(-1) || this.viewDate;
1404+ if (this.o.keyboardNavigation) {
1405+ this._toggle_multidate(focusDate);
1406+ dateChanged = true;
1407+ }
1408+ this.focusDate = null;
1409+ this.viewDate = this.dates.get(-1) || this.viewDate;
1410+ this.setValue();
1411+ this.fill();
1412+ if (this.picker.is(':visible')){
1413+ e.preventDefault();
1414+ e.stopPropagation();
1415+ if (this.o.autoclose)
1416+ this.hide();
1417+ }
1418+ break;
1419+ case 9: // tab
1420+ this.focusDate = null;
1421+ this.viewDate = this.dates.get(-1) || this.viewDate;
1422+ this.fill();
1423+ this.hide();
1424+ break;
1425+ }
1426+ if (dateChanged){
1427+ if (this.dates.length)
1428+ this._trigger('changeDate');
1429+ else
1430+ this._trigger('clearDate');
1431+ var element;
1432+ if (this.isInput){
1433+ element = this.element;
1434+ }
1435+ else if (this.component){
1436+ element = this.element.find('input');
1437+ }
1438+ if (element){
1439+ element.change();
1440+ }
1441+ }
1442+ },
1443+
1444+ showMode: function(dir){
1445+ if (dir){
1446+ this.viewMode = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, this.viewMode + dir));
1447+ }
1448+ this.picker
1449+ .children('div')
1450+ .hide()
1451+ .filter('.datepicker-' + DPGlobal.modes[this.viewMode].clsName)
1452+ .show();
1453+ this.updateNavArrows();
1454+ }
1455+ };
1456+
1457+ var DateRangePicker = function(element, options){
1458+ $(element).data('datepicker', this);
1459+ this.element = $(element);
1460+ this.inputs = $.map(options.inputs, function(i){
1461+ return i.jquery ? i[0] : i;
1462+ });
1463+ delete options.inputs;
1464+
1465+ datepickerPlugin.call($(this.inputs), options)
1466+ .on('changeDate', $.proxy(this.dateUpdated, this));
1467+
1468+ this.pickers = $.map(this.inputs, function(i){
1469+ return $(i).data('datepicker');
1470+ });
1471+ this.updateDates();
1472+ };
1473+ DateRangePicker.prototype = {
1474+ updateDates: function(){
1475+ this.dates = $.map(this.pickers, function(i){
1476+ return i.getUTCDate();
1477+ });
1478+ this.updateRanges();
1479+ },
1480+ updateRanges: function(){
1481+ var range = $.map(this.dates, function(d){
1482+ return d.valueOf();
1483+ });
1484+ $.each(this.pickers, function(i, p){
1485+ p.setRange(range);
1486+ });
1487+ },
1488+ dateUpdated: function(e){
1489+ // `this.updating` is a workaround for preventing infinite recursion
1490+ // between `changeDate` triggering and `setUTCDate` calling. Until
1491+ // there is a better mechanism.
1492+ if (this.updating)
1493+ return;
1494+ this.updating = true;
1495+
1496+ var dp = $(e.target).data('datepicker');
1497+
1498+ if (typeof(dp) === "undefined") {
1499+ return;
1500+ }
1501+
1502+ var new_date = dp.getUTCDate(),
1503+ i = $.inArray(e.target, this.inputs),
1504+ j = i - 1,
1505+ k = i + 1,
1506+ l = this.inputs.length;
1507+ if (i === -1)
1508+ return;
1509+
1510+ $.each(this.pickers, function(i, p){
1511+ if (!p.getUTCDate())
1512+ p.setUTCDate(new_date);
1513+ });
1514+
1515+ if (new_date < this.dates[j]){
1516+ // Date being moved earlier/left
1517+ while (j >= 0 && new_date < this.dates[j]){
1518+ this.pickers[j--].setUTCDate(new_date);
1519+ }
1520+ }
1521+ else if (new_date > this.dates[k]){
1522+ // Date being moved later/right
1523+ while (k < l && new_date > this.dates[k]){
1524+ this.pickers[k++].setUTCDate(new_date);
1525+ }
1526+ }
1527+ this.updateDates();
1528+
1529+ delete this.updating;
1530+ },
1531+ remove: function(){
1532+ $.map(this.pickers, function(p){ p.remove(); });
1533+ delete this.element.data().datepicker;
1534+ }
1535+ };
1536+
1537+ function opts_from_el(el, prefix){
1538+ // Derive options from element data-attrs
1539+ var data = $(el).data(),
1540+ out = {}, inkey,
1541+ replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])');
1542+ prefix = new RegExp('^' + prefix.toLowerCase());
1543+ function re_lower(_,a){
1544+ return a.toLowerCase();
1545+ }
1546+ for (var key in data)
1547+ if (prefix.test(key)){
1548+ inkey = key.replace(replace, re_lower);
1549+ out[inkey] = data[key];
1550+ }
1551+ return out;
1552+ }
1553+
1554+ function opts_from_locale(lang){
1555+ // Derive options from locale plugins
1556+ var out = {};
1557+ // Check if "de-DE" style date is available, if not language should
1558+ // fallback to 2 letter code eg "de"
1559+ if (!dates[lang]){
1560+ lang = lang.split('-')[0];
1561+ if (!dates[lang])
1562+ return;
1563+ }
1564+ var d = dates[lang];
1565+ $.each(locale_opts, function(i,k){
1566+ if (k in d)
1567+ out[k] = d[k];
1568+ });
1569+ return out;
1570+ }
1571+
1572+ var old = $.fn.datepicker;
1573+ var datepickerPlugin = function(option){
1574+ var args = Array.apply(null, arguments);
1575+ args.shift();
1576+ var internal_return;
1577+ this.each(function(){
1578+ var $this = $(this),
1579+ data = $this.data('datepicker'),
1580+ options = typeof option === 'object' && option;
1581+ if (!data){
1582+ var elopts = opts_from_el(this, 'date'),
1583+ // Preliminary otions
1584+ xopts = $.extend({}, defaults, elopts, options),
1585+ locopts = opts_from_locale(xopts.language),
1586+ // Options priority: js args, data-attrs, locales, defaults
1587+ opts = $.extend({}, defaults, locopts, elopts, options);
1588+ if ($this.hasClass('input-daterange') || opts.inputs){
1589+ $.extend(opts, {
1590+ inputs: opts.inputs || $this.find('input').toArray()
1591+ });
1592+ data = new DateRangePicker(this, opts);
1593+ }
1594+ else {
1595+ data = new Datepicker(this, opts);
1596+ }
1597+ $this.data('datepicker', data);
1598+ }
1599+ if (typeof option === 'string' && typeof data[option] === 'function'){
1600+ internal_return = data[option].apply(data, args);
1601+ }
1602+ });
1603+
1604+ if (
1605+ internal_return === undefined ||
1606+ internal_return instanceof Datepicker ||
1607+ internal_return instanceof DateRangePicker
1608+ )
1609+ return this;
1610+
1611+ if (this.length > 1)
1612+ throw new Error('Using only allowed for the collection of a single element (' + option + ' function)');
1613+ else
1614+ return internal_return;
1615+ };
1616+ $.fn.datepicker = datepickerPlugin;
1617+
1618+ var defaults = $.fn.datepicker.defaults = {
1619+ autoclose: false,
1620+ beforeShowDay: $.noop,
1621+ beforeShowMonth: $.noop,
1622+ beforeShowYear: $.noop,
1623+ calendarWeeks: false,
1624+ clearBtn: false,
1625+ toggleActive: false,
1626+ daysOfWeekDisabled: [],
1627+ daysOfWeekHighlighted: [],
1628+ datesDisabled: [],
1629+ endDate: Infinity,
1630+ forceParse: true,
1631+ format: 'mm/dd/yyyy',
1632+ keyboardNavigation: true,
1633+ language: 'en',
1634+ minViewMode: 0,
1635+ maxViewMode: 2,
1636+ multidate: false,
1637+ multidateSeparator: ',',
1638+ orientation: "auto",
1639+ rtl: false,
1640+ startDate: -Infinity,
1641+ startView: 0,
1642+ todayBtn: false,
1643+ todayHighlight: false,
1644+ weekStart: 0,
1645+ disableTouchKeyboard: false,
1646+ enableOnReadonly: true,
1647+ showOnFocus: true,
1648+ zIndexOffset: 10,
1649+ container: 'body',
1650+ immediateUpdates: false,
1651+ title: ''
1652+ };
1653+ var locale_opts = $.fn.datepicker.locale_opts = [
1654+ 'format',
1655+ 'rtl',
1656+ 'weekStart'
1657+ ];
1658+ $.fn.datepicker.Constructor = Datepicker;
1659+ var dates = $.fn.datepicker.dates = {
1660+ en: {
1661+ days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
1662+ daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
1663+ daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
1664+ months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
1665+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
1666+ today: "Today",
1667+ clear: "Clear",
1668+ titleFormat: "MM yyyy"
1669+ }
1670+ };
1671+
1672+ var DPGlobal = {
1673+ modes: [
1674+ {
1675+ clsName: 'days',
1676+ navFnc: 'Month',
1677+ navStep: 1
1678+ },
1679+ {
1680+ clsName: 'months',
1681+ navFnc: 'FullYear',
1682+ navStep: 1
1683+ },
1684+ {
1685+ clsName: 'years',
1686+ navFnc: 'FullYear',
1687+ navStep: 10
1688+ }],
1689+ isLeapYear: function(year){
1690+ return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
1691+ },
1692+ getDaysInMonth: function(year, month){
1693+ return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
1694+ },
1695+ validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
1696+ nonpunctuation: /[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,
1697+ parseFormat: function(format){
1698+ if (typeof format.toValue === 'function' && typeof format.toDisplay === 'function')
1699+ return format;
1700+ // IE treats \0 as a string end in inputs (truncating the value),
1701+ // so it's a bad format delimiter, anyway
1702+ var separators = format.replace(this.validParts, '\0').split('\0'),
1703+ parts = format.match(this.validParts);
1704+ if (!separators || !separators.length || !parts || parts.length === 0){
1705+ throw new Error("Invalid date format.");
1706+ }
1707+ return {separators: separators, parts: parts};
1708+ },
1709+ parseDate: function(date, format, language){
1710+ if (!date)
1711+ return undefined;
1712+ if (date instanceof Date)
1713+ return date;
1714+ if (typeof format === 'string')
1715+ format = DPGlobal.parseFormat(format);
1716+ if (format.toValue)
1717+ return format.toValue(date, format, language);
1718+ var part_re = /([\-+]\d+)([dmwy])/,
1719+ parts = date.match(/([\-+]\d+)([dmwy])/g),
1720+ fn_map = {
1721+ d: 'moveDay',
1722+ m: 'moveMonth',
1723+ w: 'moveWeek',
1724+ y: 'moveYear'
1725+ },
1726+ part, dir, i, fn;
1727+ if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){
1728+ date = new Date();
1729+ for (i=0; i < parts.length; i++){
1730+ part = part_re.exec(parts[i]);
1731+ dir = parseInt(part[1]);
1732+ fn = fn_map[part[2]];
1733+ date = Datepicker.prototype[fn](date, dir);
1734+ }
1735+ return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
1736+ }
1737+ parts = date && date.match(this.nonpunctuation) || [];
1738+ date = new Date();
1739+ var parsed = {},
1740+ setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
1741+ setters_map = {
1742+ yyyy: function(d,v){
1743+ return d.setUTCFullYear(v);
1744+ },
1745+ yy: function(d,v){
1746+ return d.setUTCFullYear(2000+v);
1747+ },
1748+ m: function(d,v){
1749+ if (isNaN(d))
1750+ return d;
1751+ v -= 1;
1752+ while (v < 0) v += 12;
1753+ v %= 12;
1754+ d.setUTCMonth(v);
1755+ while (d.getUTCMonth() !== v)
1756+ d.setUTCDate(d.getUTCDate()-1);
1757+ return d;
1758+ },
1759+ d: function(d,v){
1760+ return d.setUTCDate(v);
1761+ }
1762+ },
1763+ val, filtered;
1764+ setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
1765+ setters_map['dd'] = setters_map['d'];
1766+ date = UTCToday();
1767+ var fparts = format.parts.slice();
1768+ // Remove noop parts
1769+ if (parts.length !== fparts.length){
1770+ fparts = $(fparts).filter(function(i,p){
1771+ return $.inArray(p, setters_order) !== -1;
1772+ }).toArray();
1773+ }
1774+ // Process remainder
1775+ function match_part(){
1776+ var m = this.slice(0, parts[i].length),
1777+ p = parts[i].slice(0, m.length);
1778+ return m.toLowerCase() === p.toLowerCase();
1779+ }
1780+ if (parts.length === fparts.length){
1781+ var cnt;
1782+ for (i=0, cnt = fparts.length; i < cnt; i++){
1783+ val = parseInt(parts[i], 10);
1784+ part = fparts[i];
1785+ if (isNaN(val)){
1786+ switch (part){
1787+ case 'MM':
1788+ filtered = $(dates[language].months).filter(match_part);
1789+ val = $.inArray(filtered[0], dates[language].months) + 1;
1790+ break;
1791+ case 'M':
1792+ filtered = $(dates[language].monthsShort).filter(match_part);
1793+ val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
1794+ break;
1795+ }
1796+ }
1797+ parsed[part] = val;
1798+ }
1799+ var _date, s;
1800+ for (i=0; i < setters_order.length; i++){
1801+ s = setters_order[i];
1802+ if (s in parsed && !isNaN(parsed[s])){
1803+ _date = new Date(date);
1804+ setters_map[s](_date, parsed[s]);
1805+ if (!isNaN(_date))
1806+ date = _date;
1807+ }
1808+ }
1809+ }
1810+ return date;
1811+ },
1812+ formatDate: function(date, format, language){
1813+ if (!date)
1814+ return '';
1815+ if (typeof format === 'string')
1816+ format = DPGlobal.parseFormat(format);
1817+ if (format.toDisplay)
1818+ return format.toDisplay(date, format, language);
1819+ var val = {
1820+ d: date.getUTCDate(),
1821+ D: dates[language].daysShort[date.getUTCDay()],
1822+ DD: dates[language].days[date.getUTCDay()],
1823+ m: date.getUTCMonth() + 1,
1824+ M: dates[language].monthsShort[date.getUTCMonth()],
1825+ MM: dates[language].months[date.getUTCMonth()],
1826+ yy: date.getUTCFullYear().toString().substring(2),
1827+ yyyy: date.getUTCFullYear()
1828+ };
1829+ val.dd = (val.d < 10 ? '0' : '') + val.d;
1830+ val.mm = (val.m < 10 ? '0' : '') + val.m;
1831+ date = [];
1832+ var seps = $.extend([], format.separators);
1833+ for (var i=0, cnt = format.parts.length; i <= cnt; i++){
1834+ if (seps.length)
1835+ date.push(seps.shift());
1836+ date.push(val[format.parts[i]]);
1837+ }
1838+ return date.join('');
1839+ },
1840+ headTemplate: '<thead>'+
1841+ '<tr>'+
1842+ '<th colspan="7" class="datepicker-title"></th>'+
1843+ '</tr>'+
1844+ '<tr>'+
1845+ '<th class="prev">&#171;</th>'+
1846+ '<th colspan="5" class="datepicker-switch"></th>'+
1847+ '<th class="next">&#187;</th>'+
1848+ '</tr>'+
1849+ '</thead>',
1850+ contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
1851+ footTemplate: '<tfoot>'+
1852+ '<tr>'+
1853+ '<th colspan="7" class="today"></th>'+
1854+ '</tr>'+
1855+ '<tr>'+
1856+ '<th colspan="7" class="clear"></th>'+
1857+ '</tr>'+
1858+ '</tfoot>'
1859+ };
1860+ DPGlobal.template = '<div class="datepicker">'+
1861+ '<div class="datepicker-days">'+
1862+ '<table class=" table-condensed">'+
1863+ DPGlobal.headTemplate+
1864+ '<tbody></tbody>'+
1865+ DPGlobal.footTemplate+
1866+ '</table>'+
1867+ '</div>'+
1868+ '<div class="datepicker-months">'+
1869+ '<table class="table-condensed">'+
1870+ DPGlobal.headTemplate+
1871+ DPGlobal.contTemplate+
1872+ DPGlobal.footTemplate+
1873+ '</table>'+
1874+ '</div>'+
1875+ '<div class="datepicker-years">'+
1876+ '<table class="table-condensed">'+
1877+ DPGlobal.headTemplate+
1878+ DPGlobal.contTemplate+
1879+ DPGlobal.footTemplate+
1880+ '</table>'+
1881+ '</div>'+
1882+ '</div>';
1883+
1884+ $.fn.datepicker.DPGlobal = DPGlobal;
1885+
1886+
1887+ /* DATEPICKER NO CONFLICT
1888+ * =================== */
1889+
1890+ $.fn.datepicker.noConflict = function(){
1891+ $.fn.datepicker = old;
1892+ return this;
1893+ };
1894+
1895+ /* DATEPICKER VERSION
1896+ * =================== */
1897+ $.fn.datepicker.version = '1.5.1';
1898+
1899+ /* DATEPICKER DATA-API
1900+ * ================== */
1901+
1902+ $(document).on(
1903+ 'focus.datepicker.data-api click.datepicker.data-api',
1904+ '[data-provide="datepicker"]',
1905+ function(e){
1906+ var $this = $(this);
1907+ if ($this.data('datepicker'))
1908+ return;
1909+ e.preventDefault();
1910+ // component click requires us to explicitly show it
1911+ datepickerPlugin.call($this, 'show');
1912+ }
1913+ );
1914+ $(function(){
1915+ datepickerPlugin.call($('[data-provide="datepicker-inline"]'));
1916+ });
1917+
1918+}));
Source/Libraries/GSF.Web/Model/Scripts/bootstrap-toolkit.js+234−0
@@ -0,0 +1,234 @@
1+/*!
2+ * Responsive Bootstrap Toolkit
3+ * Author: Maciej Gurban
4+ * License: MIT
5+ * Version: 2.5.1 (2015-11-02)
6+ * Origin: https://github.com/maciej-gurban/responsive-bootstrap-toolkit
7+ */
8+;var ResponsiveBootstrapToolkit = (function($){
9+
10+ // Internal methods
11+ var internal = {
12+
13+ /**
14+ * Breakpoint detection divs for each framework version
15+ */
16+ detectionDivs: {
17+ // Bootstrap 3
18+ bootstrap: {
19+ 'xs': $('<div class="device-xs visible-xs visible-xs-block"></div>'),
20+ 'sm': $('<div class="device-sm visible-sm visible-sm-block"></div>'),
21+ 'md': $('<div class="device-md visible-md visible-md-block"></div>'),
22+ 'lg': $('<div class="device-lg visible-lg visible-lg-block"></div>')
23+ },
24+ // Foundation 5
25+ foundation: {
26+ 'small': $('<div class="device-xs show-for-small-only"></div>'),
27+ 'medium': $('<div class="device-sm show-for-medium-only"></div>'),
28+ 'large': $('<div class="device-md show-for-large-only"></div>'),
29+ 'xlarge': $('<div class="device-lg show-for-xlarge-only"></div>')
30+ }
31+ },
32+
33+ /**
34+ * Append visibility divs after DOM laoded
35+ */
36+ applyDetectionDivs: function() {
37+ $(document).ready(function(){
38+ $.each(self.breakpoints, function(alias){
39+ self.breakpoints[alias].appendTo('.responsive-bootstrap-toolkit');
40+ });
41+ });
42+ },
43+
44+ /**
45+ * Determines whether passed string is a parsable expression
46+ */
47+ isAnExpression: function( str ) {
48+ return (str.charAt(0) == '<' || str.charAt(0) == '>');
49+ },
50+
51+ /**
52+ * Splits the expression in into <|> [=] alias
53+ */
54+ splitExpression: function( str ) {
55+
56+ // Used operator
57+ var operator = str.charAt(0);
58+ // Include breakpoint equal to alias?
59+ var orEqual = (str.charAt(1) == '=') ? true : false;
60+
61+ /**
62+ * Index at which breakpoint name starts.
63+ *
64+ * For: >sm, index = 1
65+ * For: >=sm, index = 2
66+ */
67+ var index = 1 + (orEqual ? 1 : 0);
68+
69+ /**
70+ * The remaining part of the expression, after the operator, will be treated as the
71+ * breakpoint name to compare with
72+ */
73+ var breakpointName = str.slice(index);
74+
75+ return {
76+ operator: operator,
77+ orEqual: orEqual,
78+ breakpointName: breakpointName
79+ };
80+ },
81+
82+ /**
83+ * Returns true if currently active breakpoint matches the expression
84+ */
85+ isAnyActive: function( breakpoints ) {
86+ var found = false;
87+ $.each(breakpoints, function( index, alias ) {
88+ // Once first breakpoint matches, return true and break out of the loop
89+ if( self.breakpoints[ alias ].is(':visible') ) {
90+ found = true;
91+ return false;
92+ }
93+ });
94+ return found;
95+ },
96+
97+ /**
98+ * Determines whether current breakpoint matches the expression given
99+ */
100+ isMatchingExpression: function( str ) {
101+
102+ var expression = internal.splitExpression( str );
103+
104+ // Get names of all breakpoints
105+ var breakpointList = Object.keys(self.breakpoints);
106+
107+ // Get index of sought breakpoint in the list
108+ var pos = breakpointList.indexOf( expression.breakpointName );
109+
110+ // Breakpoint found
111+ if( pos !== -1 ) {
112+
113+ var start = 0;
114+ var end = 0;
115+
116+ /**
117+ * Parsing viewport.is('<=md') we interate from smallest breakpoint ('xs') and end
118+ * at 'md' breakpoint, indicated in the expression,
119+ * That makes: start = 0, end = 2 (index of 'md' breakpoint)
120+ *
121+ * Parsing viewport.is('<md') we start at index 'xs' breakpoint, and end at
122+ * 'sm' breakpoint, one before 'md'.
123+ * Which makes: start = 0, end = 1
124+ */
125+ if( expression.operator == '<' ) {
126+ start = 0;
127+ end = expression.orEqual ? ++pos : pos;
128+ }
129+ /**
130+ * Parsing viewport.is('>=sm') we interate from breakpoint 'sm' and end at the end
131+ * of breakpoint list.
132+ * That makes: start = 1, end = undefined
133+ *
134+ * Parsing viewport.is('>sm') we start at breakpoint 'md' and end at the end of
135+ * breakpoint list.
136+ * Which makes: start = 2, end = undefined
137+ */
138+ if( expression.operator == '>' ) {
139+ start = expression.orEqual ? pos : ++pos;
140+ end = undefined;
141+ }
142+
143+ var acceptedBreakpoints = breakpointList.slice(start, end);
144+
145+ return internal.isAnyActive( acceptedBreakpoints );
146+
147+ }
148+ }
149+
150+ };
151+
152+ // Public methods and properties
153+ var self = {
154+
155+ /**
156+ * Determines default debouncing interval of 'changed' method
157+ */
158+ interval: 300,
159+
160+ /**
161+ *
162+ */
163+ framework: null,
164+
165+ /**
166+ * Breakpoint aliases, listed from smallest to biggest
167+ */
168+ breakpoints: null,
169+
170+ /**
171+ * Returns true if current breakpoint matches passed alias
172+ */
173+ is: function( str ) {
174+ if( internal.isAnExpression( str ) ) {
175+ return internal.isMatchingExpression( str );
176+ }
177+ return self.breakpoints[ str ] && self.breakpoints[ str ].is(':visible');
178+ },
179+
180+ /**
181+ * Determines which framework-specific breakpoint detection divs to use
182+ */
183+ use: function( frameworkName, breakpoints ) {
184+ self.framework = frameworkName.toLowerCase();
185+
186+ if( self.framework === 'bootstrap' || self.framework === 'foundation') {
187+ self.breakpoints = internal.detectionDivs[ self.framework ];
188+ } else {
189+ self.breakpoints = breakpoints;
190+ }
191+
192+ internal.applyDetectionDivs();
193+ },
194+
195+ /**
196+ * Returns current breakpoint alias
197+ */
198+ current: function(){
199+ var name = 'unrecognized';
200+ $.each(self.breakpoints, function(alias){
201+ if (self.is(alias)) {
202+ name = alias;
203+ }
204+ });
205+ return name;
206+ },
207+
208+ /*
209+ * Waits specified number of miliseconds before executing a callback
210+ */
211+ changed: function(fn, ms) {
212+ var timer;
213+ return function(){
214+ clearTimeout(timer);
215+ timer = setTimeout(function(){
216+ fn();
217+ }, ms || self.interval);
218+ };
219+ }
220+
221+ };
222+
223+ // Create a placeholder
224+ $(document).ready(function(){
225+ $('<div class="responsive-bootstrap-toolkit"></div>').appendTo('body');
226+ });
227+
228+ if( self.framework === null ) {
229+ self.use('bootstrap');
230+ }
231+
232+ return self;
233+
234+})(jQuery);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t