From 7d3d494bfe7457e7dc0335649817f818ba50e1f6 Mon Sep 17 00:00:00 2001 From: Eero L Date: Sun, 2 Jun 2019 15:11:28 +0300 Subject: [PATCH] Added link file pointing to sources of libraries, changed library files to match their links exactly --- Libraries/FileSaver.min.js | 5 +- Libraries/duration-picker.css | 24 - Libraries/duration-picker.min.js | 1 - Libraries/jquery.timepicker.js | 864 +++++++++++++++++++++++++++++ Libraries/jquery.timepicker.min.js | 10 - Libraries/links.txt | 4 + manifest.json | 2 +- options.html | 2 +- 8 files changed, 873 insertions(+), 39 deletions(-) delete mode 100644 Libraries/duration-picker.css delete mode 100644 Libraries/duration-picker.min.js create mode 100644 Libraries/jquery.timepicker.js delete mode 100644 Libraries/jquery.timepicker.min.js create mode 100644 Libraries/links.txt diff --git a/Libraries/FileSaver.min.js b/Libraries/FileSaver.min.js index 9a1e397..2104716 100644 --- a/Libraries/FileSaver.min.js +++ b/Libraries/FileSaver.min.js @@ -1,2 +1,3 @@ -/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ -var saveAs=saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,a=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},i=/constructor/i.test(e.HTMLElement)||e.safari,f=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},s="application/octet-stream",d=1e3*40,c=function(e){var t=function(){if(typeof e==="string"){n().revokeObjectURL(e)}else{e.remove()}};setTimeout(t,d)},l=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var o=e["on"+t[r]];if(typeof o==="function"){try{o.call(e,n||e)}catch(a){u(a)}}}},p=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob([String.fromCharCode(65279),e],{type:e.type})}return e},v=function(t,u,d){if(!d){t=p(t)}var v=this,w=t.type,m=w===s,y,h=function(){l(v,"writestart progress write writeend".split(" "))},S=function(){if((f||m&&i)&&e.FileReader){var r=new FileReader;r.onloadend=function(){var t=f?r.result:r.result.replace(/^data:[^;]*;/,"data:attachment/file;");var n=e.open(t,"_blank");if(!n)e.location.href=t;t=undefined;v.readyState=v.DONE;h()};r.readAsDataURL(t);v.readyState=v.INIT;return}if(!y){y=n().createObjectURL(t)}if(m){e.location.href=y}else{var o=e.open(y,"_blank");if(!o){e.location.href=y}}v.readyState=v.DONE;h();c(y)};v.readyState=v.INIT;if(o){y=n().createObjectURL(t);setTimeout(function(){r.href=y;r.download=u;a(r);h();c(y);v.readyState=v.DONE});return}S()},w=v.prototype,m=function(e,t,n){return new v(e,t||e.name||"download",n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){t=t||e.name||"download";if(!n){e=p(e)}return navigator.msSaveOrOpenBlob(e,t)}}w.abort=function(){};w.readyState=w.INIT=0;w.WRITING=1;w.DONE=2;w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null;return m}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!==null){define("FileSaver.js",function(){return saveAs})} +(function(a,b){if("function"==typeof define&&define.amd)define([],b);else if("undefined"!=typeof exports)b();else{b(),a.FileSaver={exports:{}}.exports}})(this,function(){"use strict";function b(a,b){return"undefined"==typeof b?b={autoBom:!1}:"object"!=typeof b&&(console.warn("Deprecated: Expected third argument to be a object"),b={autoBom:!b}),b.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\uFEFF",a],{type:a.type}):a}function c(b,c,d){var e=new XMLHttpRequest;e.open("GET",b),e.responseType="blob",e.onload=function(){a(e.response,c,d)},e.onerror=function(){console.error("could not download file")},e.send()}function d(a){var b=new XMLHttpRequest;b.open("HEAD",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent("click"))}catch(c){var b=document.createEvent("MouseEvents");b.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:void 0,a=f.saveAs||("object"!=typeof window||window!==f?function(){}:"download"in HTMLAnchorElement.prototype?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement("a");g=g||b.name||"download",j.download=g,j.rel="noopener","string"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target="_blank")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:"msSaveOrOpenBlob"in navigator?function(f,g,h){if(g=g||f.name||"download","string"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement("a");i.href=f,i.target="_blank",setTimeout(function(){e(i)})}}:function(a,b,d,e){if(e=e||open("","_blank"),e&&(e.document.title=e.document.body.innerText="downloading..."),"string"==typeof a)return c(a,b,d);var g="application/octet-stream"===a.type,h=/constructor/i.test(f.HTMLElement)||f.safari,i=/CriOS\/[\d]+/.test(navigator.userAgent);if((i||g&&h)&&"object"==typeof FileReader){var j=new FileReader;j.onloadend=function(){var a=j.result;a=i?a:a.replace(/^data:[^;]*;/,"data:attachment/file;"),e?e.location.href=a:location=a,e=null},j.readAsDataURL(a)}else{var k=f.URL||f.webkitURL,l=k.createObjectURL(a);e?e.location=l:location.href=l,e=null,setTimeout(function(){k.revokeObjectURL(l)},4E4)}});f.saveAs=a.saveAs=a,"undefined"!=typeof module&&(module.exports=a)}); + +//# sourceMappingURL=FileSaver.min.js.map \ No newline at end of file diff --git a/Libraries/duration-picker.css b/Libraries/duration-picker.css deleted file mode 100644 index 4e8bd1c..0000000 --- a/Libraries/duration-picker.css +++ /dev/null @@ -1,24 +0,0 @@ -.durationpicker-container { - background-color: white; - border: 1px solid darkgrey; - display: inline-block; - width: auto; -} - -.durationpicker-innercontainer { - display: inline-block; - width: auto; - padding-right: 5px; -} - -.durationpicker-duration { - width: 50px; - display: inline-block; - border: none; - padding-left: 10%; - text-align: right; -} - -.durationpicker-label { - display: inline-block; -} diff --git a/Libraries/duration-picker.min.js b/Libraries/duration-picker.min.js deleted file mode 100644 index 3d284cb..0000000 --- a/Libraries/duration-picker.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(i){function t(i,t){for(var e in Object.keys(i))-1!=t.stages.indexOf(Object.keys(i)[e])&&t.jqitem.find("#duration-"+Object.keys(i)[e]).val(i[Object.keys(i)[e]])}function e(i){var t=[];for(var e in Object.keys(i))-1==["classname","responsive","type"].indexOf(Object.keys(i)[e])&&t.push(Object.keys(i)[e]);return t}function n(i,t){var e='
',n=i.type;for(var s in t)e+='
'+i[t[s]].label+"
";return e+="
"}var s=function(t,s){this.settings=s,this.stages=e(this.settings),this.template=n(this.settings,this.stages),this.jqitem=i(this.template),this.jqchildren=this.jqitem.children(),this.element=i(t),this.setup(),this.resize(),this.jqchildren.find(".durationpicker-duration").trigger("change")};s.prototype={constructor:s,setup:function(){this.element.before(this.jqitem),this.element.hide(),this.jqchildren.find(".durationpicker-duration").on("change",{ths:this},function(t){var e=t.data.ths.element,n="";i(this).parent().parent().find("input").each(function(){var t=i(this),e=0;null!=t.val()&&""!=t.val()&&(e=t.val()),n+=e+" "+t.next().text()+","}),n=n.slice(0,-1),e.val(n)}),i(".durationpicker-duration").trigger("change"),window.addEventListener("resize",this.resize.bind(this))},resize:function(){if(this.settings.responsive){var t=parseInt(this.jqitem.css("padding-left").split("px")[0])+parseInt(this.jqitem.css("padding-right").split("px")[0]),e=t,n=t;this.jqchildren.each(function(){var t=i(this);e+=t.outerWidth(),n+=t.outerHeight()}),this.jqitem.parent().width()').addClass('ui-timepicker-container') + .addClass('ui-timepicker-hidden ui-helper-hidden') + .appendTo('body') + .hide(); + widget.ui = $( '
' ).addClass('ui-timepicker') + .addClass('ui-widget ui-widget-content ui-menu') + .addClass('ui-corner-all') + .appendTo(widget.container); + widget.viewport = $('').addClass( 'ui-timepicker-viewport' ) + .appendTo( widget.ui ); + + if ($.fn.jquery >= '1.4.2') { + widget.ui.delegate('a', 'mouseenter.timepicker', function() { + // passing false instead of an instance object tells the function + // to use the current instance + widget.activate(false, $(this).parent()); + }).delegate('a', 'mouseleave.timepicker', function() { + widget.deactivate(false); + }).delegate('a', 'click.timepicker', function(event) { + event.preventDefault(); + widget.select(false, $(this).parent()); + }); + } + } + }; + + $.TimePicker.count = 0; + $.TimePicker.instance = function() { + if (!$.TimePicker._instance) { + $.TimePicker._instance = new $.TimePicker(); + } + return $.TimePicker._instance; + }; + + $.TimePicker.prototype = { + // extracted from from jQuery UI Core + // http://github,com/jquery/jquery-ui/blob/master/ui/jquery.ui.core.js + keyCode: { + ALT: 18, + BLOQ_MAYUS: 20, + CTRL: 17, + DOWN: 40, + END: 35, + ENTER: 13, + HOME: 36, + LEFT: 37, + NUMPAD_ENTER: 108, + PAGE_DOWN: 34, + PAGE_UP: 33, + RIGHT: 39, + SHIFT: 16, + TAB: 9, + UP: 38 + }, + + _items: function(i, startTime) { + var widget = this, ul = $(''), item = null, time, end; + + // interval should be a multiple of 60 if timeFormat is not + // showing minutes + if (i.options.timeFormat.indexOf('m') === -1 && i.options.interval % 60 !== 0) { + i.options.interval = Math.max(Math.round(i.options.interval / 60), 1) * 60; + } + + if (startTime) { + time = normalize(startTime); + } else if (i.options.startTime) { + time = normalize(i.options.startTime); + } else { + time = normalize(i.options.startHour, i.options.startMinutes); + } + + end = new Date(time.getTime() + 24 * 60 * 60 * 1000); + + while(time < end) { + if (widget._isValidTime(i, time)) { + item = $('
  • ').addClass('ui-menu-item').appendTo(ul); + $('').addClass('ui-corner-all').text($.fn.timepicker.formatTime(i.options.timeFormat, time)).appendTo(item); + item.data('time-value', time); + } + time = new Date(time.getTime() + i.options.interval * 60 * 1000); + } + + return ul.children(); + }, + + _isValidTime: function(i, time) { + var min = null, max = null; + + time = normalize(time); + + if (i.options.minTime !== null) { + min = normalize(i.options.minTime); + } else if (i.options.minHour !== null || i.options.minMinutes !== null) { + min = normalize(i.options.minHour, i.options.minMinutes); + } + + if (i.options.maxTime !== null) { + max = normalize(i.options.maxTime); + } else if (i.options.maxHour !== null || i.options.maxMinutes !== null) { + max = normalize(i.options.maxHour, i.options.maxMinutes); + } + + if (min !== null && max !== null) { + return time >= min && time <= max; + } else if (min !== null) { + return time >= min; + } else if (max !== null) { + return time <= max; + } + + return true; + }, + + _hasScroll: function() { + // fix for jQuery 1.6 new prop method + var m = typeof this.ui.prop !== 'undefined' ? 'prop' : 'attr'; + return this.ui.height() < this.ui[m]('scrollHeight'); + }, + + /** + * TODO: Write me! + * + * @param i + * @param direction + * @param edge + * */ + _move: function(i, direction, edge) { + var widget = this; + if (widget.closed()) { + widget.open(i); + } + if (!widget.active) { + widget.activate( i, widget.viewport.children( edge ) ); + return; + } + var next = widget.active[direction + 'All']('.ui-menu-item').eq(0); + if (next.length) { + widget.activate(i, next); + } else { + widget.activate( i, widget.viewport.children( edge ) ); + } + }, + + // + // protected methods + // + + register: function(node, options) { + var widget = this, i = {}; // timepicker instance object + + i.element = $(node); + + if (i.element.data('TimePicker')) { + return; + } + + i.options = $.metadata ? $.extend({}, options, i.element.metadata()) : $.extend({}, options); + i.widget = widget; + + // proxy functions for the exposed api methods + $.extend(i, { + next: function() {return widget.next(i) ;}, + previous: function() {return widget.previous(i) ;}, + first: function() { return widget.first(i) ;}, + last: function() { return widget.last(i) ;}, + selected: function() { return widget.selected(i) ;}, + open: function() { return widget.open(i) ;}, + close: function() { return widget.close(i) ;}, + closed: function() { return widget.closed(i) ;}, + destroy: function() { return widget.destroy(i) ;}, + + parse: function(str) { return widget.parse(i, str) ;}, + format: function(time, format) { return widget.format(i, time, format); }, + getTime: function() { return widget.getTime(i) ;}, + setTime: function(time, silent) { return widget.setTime(i, time, silent); }, + option: function(name, value) { return widget.option(i, name, value); } + }); + + widget._setDefaultTime(i); + widget._addInputEventsHandlers(i); + + i.element.data('TimePicker', i); + }, + + _setDefaultTime: function(i) { + if (i.options.defaultTime === 'now') { + i.setTime(normalize(new Date())); + } else if (i.options.defaultTime && i.options.defaultTime.getFullYear) { + i.setTime(normalize(i.options.defaultTime)); + } else if (i.options.defaultTime) { + i.setTime($.fn.timepicker.parseTime(i.options.defaultTime)); + } + }, + + _addInputEventsHandlers: function(i) { + var widget = this; + + i.element.bind('keydown.timepicker', function(event) { + switch (event.which || event.keyCode) { + case widget.keyCode.ENTER: + case widget.keyCode.NUMPAD_ENTER: + event.preventDefault(); + if (widget.closed()) { + i.element.trigger('change.timepicker'); + } else { + widget.select(i, widget.active); + } + break; + case widget.keyCode.UP: + i.previous(); + break; + case widget.keyCode.DOWN: + i.next(); + break; + default: + if (!widget.closed()) { + i.close(true); + } + break; + } + }).bind('focus.timepicker', function() { + i.open(); + }).bind('blur.timepicker', function() { + setTimeout(function() { + if (i.element.data('timepicker-user-clicked-outside')) { + i.close(); + } + }); + }).bind('change.timepicker', function() { + if (i.closed()) { + i.setTime($.fn.timepicker.parseTime(i.element.val())); + } + }); + }, + + select: function(i, item) { + var widget = this, instance = i === false ? widget.instance : i; + widget.setTime(instance, $.fn.timepicker.parseTime(item.children('a').text())); + widget.close(instance, true); + }, + + activate: function(i, item) { + var widget = this, instance = i === false ? widget.instance : i; + + if (instance !== widget.instance) { + return; + } else { + widget.deactivate(); + } + + if (widget._hasScroll()) { + var offset = item.offset().top - widget.ui.offset().top, + scroll = widget.ui.scrollTop(), + height = widget.ui.height(); + if (offset < 0) { + widget.ui.scrollTop(scroll + offset); + } else if (offset >= height) { + widget.ui.scrollTop(scroll + offset - height + item.height()); + } + } + + widget.active = item.eq(0).children('a').addClass('ui-state-hover') + .attr('id', 'ui-active-item') + .end(); + }, + + deactivate: function() { + var widget = this; + if (!widget.active) { return; } + widget.active.children('a').removeClass('ui-state-hover').removeAttr('id'); + widget.active = null; + }, + + /** + * _activate, _deactivate, first, last, next, previous, _move and + * _hasScroll were extracted from jQuery UI Menu + * http://github,com/jquery/jquery-ui/blob/menu/ui/jquery.ui.menu.js + */ + + // + // public methods + // + + next: function(i) { + if (this.closed() || this.instance === i) { + this._move(i, 'next', '.ui-menu-item:first'); + } + return i.element; + }, + + previous: function(i) { + if (this.closed() || this.instance === i) { + this._move(i, 'prev', '.ui-menu-item:last'); + } + return i.element; + }, + + first: function(i) { + if (this.instance === i) { + return this.active && this.active.prevAll('.ui-menu-item').length === 0; + } + return false; + }, + + last: function(i) { + if (this.instance === i) { + return this.active && this.active.nextAll('.ui-menu-item').length === 0; + } + return false; + }, + + selected: function(i) { + if (this.instance === i) { + return this.active ? this.active : null; + } + return null; + }, + + open: function(i) { + var widget = this, + selectedTime = i.getTime(), + arrange = i.options.dynamic && selectedTime; + + // return if dropdown is disabled + if (!i.options.dropdown) { return i.element; } + + // fix for issue https://github.com/wvega/timepicker/issues/56 + // idea from https://prototype.lighthouseapp.com/projects/8887/tickets/248-results-popup-from-ajaxautocompleter-disappear-when-user-clicks-on-scrollbars-in-ie6ie7 + i.element.data('timepicker-event-namespace', Math.random()); + + $(document).bind('click.timepicker-' + i.element.data('timepicker-event-namespace'), function(event) { + if (i.element.get(0) === event.target) { + i.element.data('timepicker-user-clicked-outside', false); + } else { + i.element.data('timepicker-user-clicked-outside', true).blur(); + } + }); + + // if a date is already selected and options.dynamic is true, + // arrange the items in the list so the first item is + // cronologically right after the selected date. + // TODO: set selectedTime + if (i.rebuild || !i.items || arrange) { + i.items = widget._items(i, arrange ? selectedTime : null); + } + + // remove old li elements keeping associated events, then append + // the new li elements to the ul + if (i.rebuild || widget.instance !== i || arrange) { + // handle menu events when using jQuery versions previous to + // 1.4.2 (thanks to Brian Link) + // http://github.com/wvega/timepicker/issues#issue/4 + if ($.fn.jquery < '1.4.2') { + widget.viewport.children().remove(); + widget.viewport.append(i.items); + widget.viewport.find('a').bind('mouseover.timepicker', function() { + widget.activate(i, $(this).parent()); + }).bind('mouseout.timepicker', function() { + widget.deactivate(i); + }).bind('click.timepicker', function(event) { + event.preventDefault(); + widget.select(i, $(this).parent()); + }); + } else { + widget.viewport.children().detach(); + widget.viewport.append(i.items); + } + } + + i.rebuild = false; + + // theme + widget.container.removeClass('ui-helper-hidden ui-timepicker-hidden ui-timepicker-standard ui-timepicker-corners').show(); + + switch (i.options.theme) { + case 'standard': + widget.container.addClass('ui-timepicker-standard'); + break; + case 'standard-rounded-corners': + widget.container.addClass('ui-timepicker-standard ui-timepicker-corners'); + break; + default: + break; + } + + /* resize ui */ + + // we are hiding the scrollbar in the dropdown menu adding a 40px + // padding to the wrapper element making the scrollbar appear in the + // part of the wrapper that's hidden by the container (a DIV). + if ( ! widget.container.hasClass( 'ui-timepicker-no-scrollbar' ) && ! i.options.scrollbar ) { + widget.container.addClass( 'ui-timepicker-no-scrollbar' ); + widget.viewport.css( { paddingRight: 40 } ); + } + + var containerDecorationHeight = widget.container.outerHeight() - widget.container.height(), + zindex = i.options.zindex ? i.options.zindex : i.element.offsetParent().css( 'z-index' ), + elementOffset = i.element.offset(); + + // position the container right below the element, or as close to as possible. + widget.container.css( { + top: elementOffset.top + i.element.outerHeight(), + left: elementOffset.left + } ); + + // then show the container so that the browser can consider the timepicker's + // height to calculate the page's total height and decide if adding scrollbars + // is necessary. + widget.container.show(); + + // now we need to calculate the element offset and position the container again. + // If the browser added scrollbars, the container's original position is not aligned + // with the element's final position. This step fixes that problem. + widget.container.css( { + left: i.element.offset().left, + height: widget.ui.outerHeight() + containerDecorationHeight, + width: i.element.outerWidth(), + zIndex: zindex, + cursor: 'default' + } ); + + var calculatedWidth = widget.container.width() - ( widget.ui.outerWidth() - widget.ui.width() ); + + // hardcode ui, viewport and item's width. I couldn't get it to work using CSS only + widget.ui.css( { width: calculatedWidth } ); + widget.viewport.css( { width: calculatedWidth } ); + i.items.css( { width: calculatedWidth } ); + + // XXX: what's this line doing here? + widget.instance = i; + + // try to match input field's current value with an item in the + // dropdown + if (selectedTime) { + i.items.each(function() { + var item = $(this), time; + + if ($.fn.jquery < '1.4.2') { + time = $.fn.timepicker.parseTime(item.find('a').text()); + } else { + time = item.data('time-value'); + } + + if (time.getTime() === selectedTime.getTime()) { + widget.activate(i, item); + return false; + } + return true; + }); + } else { + widget.deactivate(i); + } + + // don't break the chain + return i.element; + }, + + close: function(i) { + var widget = this; + + if (widget.instance === i) { + widget.container.addClass('ui-helper-hidden ui-timepicker-hidden').hide(); + widget.ui.scrollTop(0); + widget.ui.children().removeClass('ui-state-hover'); + } + + $(document).unbind('click.timepicker-' + i.element.data('timepicker-event-namespace')); + + return i.element; + }, + + closed: function() { + return this.ui.is(':hidden'); + }, + + destroy: function(i) { + var widget = this; + widget.close(i, true); + return i.element.unbind('.timepicker').data('TimePicker', null); + }, + + // + + parse: function(i, str) { + return $.fn.timepicker.parseTime(str); + }, + + format: function(i, time, format) { + format = format || i.options.timeFormat; + return $.fn.timepicker.formatTime(format, time); + }, + + getTime: function(i) { + var widget = this, + current = $.fn.timepicker.parseTime(i.element.val()); + + // if current value is not valid, we return null. + // stored Date object is ignored, because the current value + // (valid or invalid) always takes priority + if (current instanceof Date && !widget._isValidTime(i, current)) { + return null; + } else if (current instanceof Date && i.selectedTime) { + // if the textfield's value and the stored Date object + // have the same representation using current format + // we prefer the stored Date object to avoid unnecesary + // lost of precision. + if (i.format(current) === i.format(i.selectedTime)) { + return i.selectedTime; + } else { + return current; + } + } else if (current instanceof Date) { + return current; + } else { + return null; + } + }, + + setTime: function(i, time, silent) { + var widget = this, previous = i.selectedTime; + + if (typeof time === 'string') { + time = i.parse(time); + } + + if (time && time.getMinutes && widget._isValidTime(i, time)) { + time = normalize(time); + i.selectedTime = time; + i.element.val(i.format(time, i.options.timeFormat)); + + // TODO: add documentaion about setTime being chainable + if (silent) { return i; } + } else { + i.selectedTime = null; + } + + // custom change event and change callback + // TODO: add documentation about this event + if (previous !== null || i.selectedTime !== null) { + i.element.trigger('time-change', [time]); + if ($.isFunction(i.options.change)) { + i.options.change.apply(i.element, [time]); + } + } + + return i.element; + }, + + option: function(i, name, value) { + if (typeof value === 'undefined') { + return i.options[name]; + } + + var time = i.getTime(), + options, destructive; + + if (typeof name === 'string') { + options = {}; + options[name] = value; + } else { + options = name; + } + + // some options require rebuilding the dropdown items + destructive = ['minHour', 'minMinutes', 'minTime', + 'maxHour', 'maxMinutes', 'maxTime', + 'startHour', 'startMinutes', 'startTime', + 'timeFormat', 'interval', 'dropdown']; + + + $.each(options, function(name) { + i.options[name] = options[name]; + i.rebuild = i.rebuild || $.inArray(name, destructive) > -1; + }); + + if (i.rebuild) { + i.setTime(time); + } + } + }; + + $.TimePicker.defaults = { + timeFormat: 'hh:mm p', + minHour: null, + minMinutes: null, + minTime: null, + maxHour: null, + maxMinutes: null, + maxTime: null, + startHour: null, + startMinutes: null, + startTime: null, + interval: 30, + dynamic: true, + theme: 'standard', + zindex: null, + dropdown: true, + scrollbar: false, + // callbacks + change: function(/*time*/) {} + }; + + $.TimePicker.methods = { + chainable: [ + 'next', + 'previous', + 'open', + 'close', + 'destroy', + 'setTime' + ] + }; + + $.fn.timepicker = function(options) { + // support calling API methods using the following syntax: + // $(...).timepicker('parse', '11p'); + if (typeof options === 'string') { + var args = Array.prototype.slice.call(arguments, 1), + method, result; + + // chainable API methods + if (options === 'option' && arguments.length > 2) { + method = 'each'; + } else if ($.inArray(options, $.TimePicker.methods.chainable) !== -1) { + method = 'each'; + // API methods that return a value + } else { + method = 'map'; + } + + result = this[method](function() { + var element = $(this), i = element.data('TimePicker'); + if (typeof i === 'object') { + return i[options].apply(i, args); + } + }); + + if (method === 'map' && this.length === 1) { + return $.makeArray(result).shift(); + } else if (method === 'map') { + return $.makeArray(result); + } else { + return result; + } + } + + // calling the constructor again on a jQuery object with a single + // element returns a reference to a TimePicker object. + if (this.length === 1 && this.data('TimePicker')) { + return this.data('TimePicker'); + } + + var globals = $.extend({}, $.TimePicker.defaults, options); + + return this.each(function() { + $.TimePicker.instance().register(this, globals); + }); + }; + + /** + * TODO: documentation + */ + $.fn.timepicker.formatTime = function(format, time) { + var hours = time.getHours(), + hours12 = hours % 12, + minutes = time.getMinutes(), + seconds = time.getSeconds(), + replacements = { + hh: pad((hours12 === 0 ? 12 : hours12).toString(), '0', 2), + HH: pad(hours.toString(), '0', 2), + mm: pad(minutes.toString(), '0', 2), + ss: pad(seconds.toString(), '0', 2), + h: (hours12 === 0 ? 12 : hours12), + H: hours, + m: minutes, + s: seconds, + p: hours > 11 ? 'PM' : 'AM' + }, + str = format, k = ''; + for (k in replacements) { + if (replacements.hasOwnProperty(k)) { + str = str.replace(new RegExp(k,'g'), replacements[k]); + } + } + // replacements is not guaranteed to be order and the 'p' can cause problems + str = str.replace(new RegExp('a','g'), hours > 11 ? 'pm' : 'am'); + return str; + }; + + /** + * Convert a string representing a given time into a Date object. + * + * The Date object will have attributes others than hours, minutes and + * seconds set to current local time values. The function will return + * false if given string can't be converted. + * + * If there is an 'a' in the string we set am to true, if there is a 'p' + * we set pm to true, if both are present only am is setted to true. + * + * All non-digit characters are removed from the string before trying to + * parse the time. + * + * '' can't be converted and the function returns false. + * '1' is converted to 01:00:00 am + * '11' is converted to 11:00:00 am + * '111' is converted to 01:11:00 am + * '1111' is converted to 11:11:00 am + * '11111' is converted to 01:11:11 am + * '111111' is converted to 11:11:11 am + * + * Only the first six (or less) characters are considered. + * + * Special case: + * + * When hours is greater than 24 and the last digit is less or equal than 6, and minutes + * and seconds are less or equal than 60, we append a trailing zero and + * start parsing process again. Examples: + * + * '95' is treated as '950' and converted to 09:50:00 am + * '46' is treated as '460' and converted to 05:00:00 am + * '57' can't be converted and the function returns false. + * + * For a detailed list of supported formats check the unit tests at + * http://github.com/wvega/timepicker/tree/master/tests/ + */ + $.fn.timepicker.parseTime = (function() { + var patterns = [ + // 1, 12, 123, 1234, 12345, 123456 + [/^(\d+)$/, '$1'], + // :1, :2, :3, :4 ... :9 + [/^:(\d)$/, '$10'], + // :1, :12, :123, :1234 ... + [/^:(\d+)/, '$1'], + // 6:06, 5:59, 5:8 + [/^(\d):([7-9])$/, '0$10$2'], + [/^(\d):(\d\d)$/, '$1$2'], + [/^(\d):(\d{1,})$/, '0$1$20'], + // 10:8, 10:10, 10:34 + [/^(\d\d):([7-9])$/, '$10$2'], + [/^(\d\d):(\d)$/, '$1$20'], + [/^(\d\d):(\d*)$/, '$1$2'], + // 123:4, 1234:456 + [/^(\d{3,}):(\d)$/, '$10$2'], + [/^(\d{3,}):(\d{2,})/, '$1$2'], + // + [/^(\d):(\d):(\d)$/, '0$10$20$3'], + [/^(\d{1,2}):(\d):(\d\d)/, '$10$2$3'] + ], + length = patterns.length; + + return function(str) { + var time = normalize(new Date()), + am = false, pm = false, h = false, m = false, s = false; + + if (typeof str === 'undefined' || !str.toLowerCase) { return null; } + + str = str.toLowerCase(); + am = /a/.test(str); + pm = am ? false : /p/.test(str); + str = str.replace(/[^0-9:]/g, '').replace(/:+/g, ':'); + + for (var k = 0; k < length; k = k + 1) { + if (patterns[k][0].test(str)) { + str = str.replace(patterns[k][0], patterns[k][1]); + break; + } + } + str = str.replace(/:/g, ''); + + if (str.length === 1) { + h = str; + } else if (str.length === 2) { + h = str; + } else if (str.length === 3 || str.length === 5) { + h = str.substr(0, 1); + m = str.substr(1, 2); + s = str.substr(3, 2); + } else if (str.length === 4 || str.length > 5) { + h = str.substr(0, 2); + m = str.substr(2, 2); + s = str.substr(4, 2); + } + + if (str.length > 0 && str.length < 5) { + if (str.length < 3) { + m = 0; + } + s = 0; + } + + if (h === false || m === false || s === false) { + return false; + } + + h = parseInt(h, 10); + m = parseInt(m, 10); + s = parseInt(s, 10); + + if (am && h === 12) { + h = 0; + } else if (pm && h < 12) { + h = h + 12; + } + + if (h > 24) { + if (str.length >= 6) { + return $.fn.timepicker.parseTime(str.substr(0,5)); + } else { + return $.fn.timepicker.parseTime(str + '0' + (am ? 'a' : '') + (pm ? 'p' : '')); + } + } else { + time.setHours(h, m, s); + return time; + } + }; + })(); + })(); +})); diff --git a/Libraries/jquery.timepicker.min.js b/Libraries/jquery.timepicker.min.js deleted file mode 100644 index fe895a0..0000000 --- a/Libraries/jquery.timepicker.min.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * jQuery Timepicker - v1.3.5 - 2016-07-10 - * http://timepicker.co - * - * Enhances standard form input fields helping users to select (or type) times. - * - * Copyright (c) 2016 Willington Vega; Licensed MIT, GPL - */ - -!function(a){"object"==typeof module&&"object"==typeof module.exports?a(require("jquery"),window,document):"undefined"!=typeof jQuery&&a(jQuery,window,document)}(function(a,b,c,d){!function(){function b(a,b,c){return new Array(c+1-a.length).join(b)+a}function d(){if(1===arguments.length){var b=arguments[0];return"string"==typeof b&&(b=a.fn.timepicker.parseTime(b)),new Date(0,0,0,b.getHours(),b.getMinutes(),b.getSeconds())}return 3===arguments.length?new Date(0,0,0,arguments[0],arguments[1],arguments[2]):2===arguments.length?new Date(0,0,0,arguments[0],arguments[1],0):new Date(0,0,0)}a.TimePicker=function(){var b=this;b.container=a(".ui-timepicker-container"),b.ui=b.container.find(".ui-timepicker"),0===b.container.length&&(b.container=a("
    ").addClass("ui-timepicker-container").addClass("ui-timepicker-hidden ui-helper-hidden").appendTo("body").hide(),b.ui=a("
    ").addClass("ui-timepicker").addClass("ui-widget ui-widget-content ui-menu").addClass("ui-corner-all").appendTo(b.container),b.viewport=a("
      ").addClass("ui-timepicker-viewport").appendTo(b.ui),a.fn.jquery>="1.4.2"&&b.ui.delegate("a","mouseenter.timepicker",function(){b.activate(!1,a(this).parent())}).delegate("a","mouseleave.timepicker",function(){b.deactivate(!1)}).delegate("a","click.timepicker",function(c){c.preventDefault(),b.select(!1,a(this).parent())}))},a.TimePicker.count=0,a.TimePicker.instance=function(){return a.TimePicker._instance||(a.TimePicker._instance=new a.TimePicker),a.TimePicker._instance},a.TimePicker.prototype={keyCode:{ALT:18,BLOQ_MAYUS:20,CTRL:17,DOWN:40,END:35,ENTER:13,HOME:36,LEFT:37,NUMPAD_ENTER:108,PAGE_DOWN:34,PAGE_UP:33,RIGHT:39,SHIFT:16,TAB:9,UP:38},_items:function(b,c){var e,f,g=this,h=a("
        "),i=null;for(-1===b.options.timeFormat.indexOf("m")&&b.options.interval%60!==0&&(b.options.interval=60*Math.max(Math.round(b.options.interval/60),1)),e=c?d(c):b.options.startTime?d(b.options.startTime):d(b.options.startHour,b.options.startMinutes),f=new Date(e.getTime()+864e5);f>e;)g._isValidTime(b,e)&&(i=a("
      • ").addClass("ui-menu-item").appendTo(h),a("").addClass("ui-corner-all").text(a.fn.timepicker.formatTime(b.options.timeFormat,e)).appendTo(i),i.data("time-value",e)),e=new Date(e.getTime()+60*b.options.interval*1e3);return h.children()},_isValidTime:function(a,b){var c=null,e=null;return b=d(b),null!==a.options.minTime?c=d(a.options.minTime):(null!==a.options.minHour||null!==a.options.minMinutes)&&(c=d(a.options.minHour,a.options.minMinutes)),null!==a.options.maxTime?e=d(a.options.maxTime):(null!==a.options.maxHour||null!==a.options.maxMinutes)&&(e=d(a.options.maxHour,a.options.maxMinutes)),null!==c&&null!==e?b>=c&&e>=b:null!==c?b>=c:null!==e?e>=b:!0},_hasScroll:function(){var a="undefined"!=typeof this.ui.prop?"prop":"attr";return this.ui.height()e?c.ui.scrollTop(f+e):e>=g&&c.ui.scrollTop(f+e-g+b.height())}c.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-item").end()}},deactivate:function(){var a=this;a.active&&(a.active.children("a").removeClass("ui-state-hover").removeAttr("id"),a.active=null)},next:function(a){return(this.closed()||this.instance===a)&&this._move(a,"next",".ui-menu-item:first"),a.element},previous:function(a){return(this.closed()||this.instance===a)&&this._move(a,"prev",".ui-menu-item:last"),a.element},first:function(a){return this.instance===a?this.active&&0===this.active.prevAll(".ui-menu-item").length:!1},last:function(a){return this.instance===a?this.active&&0===this.active.nextAll(".ui-menu-item").length:!1},selected:function(a){return this.instance===a&&this.active?this.active:null},open:function(b){var d=this,e=b.getTime(),f=b.options.dynamic&&e;if(!b.options.dropdown)return b.element;switch(b.element.data("timepicker-event-namespace",Math.random()),a(c).bind("click.timepicker-"+b.element.data("timepicker-event-namespace"),function(a){b.element.get(0)===a.target?b.element.data("timepicker-user-clicked-outside",!1):b.element.data("timepicker-user-clicked-outside",!0).blur()}),(b.rebuild||!b.items||f)&&(b.items=d._items(b,f?e:null)),(b.rebuild||d.instance!==b||f)&&(a.fn.jquery<"1.4.2"?(d.viewport.children().remove(),d.viewport.append(b.items),d.viewport.find("a").bind("mouseover.timepicker",function(){d.activate(b,a(this).parent())}).bind("mouseout.timepicker",function(){d.deactivate(b)}).bind("click.timepicker",function(c){c.preventDefault(),d.select(b,a(this).parent())})):(d.viewport.children().detach(),d.viewport.append(b.items))),b.rebuild=!1,d.container.removeClass("ui-helper-hidden ui-timepicker-hidden ui-timepicker-standard ui-timepicker-corners").show(),b.options.theme){case"standard":d.container.addClass("ui-timepicker-standard");break;case"standard-rounded-corners":d.container.addClass("ui-timepicker-standard ui-timepicker-corners")}d.container.hasClass("ui-timepicker-no-scrollbar")||b.options.scrollbar||(d.container.addClass("ui-timepicker-no-scrollbar"),d.viewport.css({paddingRight:40}));var g=d.container.outerHeight()-d.container.height(),h=b.options.zindex?b.options.zindex:b.element.offsetParent().css("z-index"),i=b.element.offset();d.container.css({top:i.top+b.element.outerHeight(),left:i.left}),d.container.show(),d.container.css({left:b.element.offset().left,height:d.ui.outerHeight()+g,width:b.element.outerWidth(),zIndex:h,cursor:"default"});var j=d.container.width()-(d.ui.outerWidth()-d.ui.width());return d.ui.css({width:j}),d.viewport.css({width:j}),b.items.css({width:j}),d.instance=b,e?b.items.each(function(){var c,f=a(this);return c=a.fn.jquery<"1.4.2"?a.fn.timepicker.parseTime(f.find("a").text()):f.data("time-value"),c.getTime()===e.getTime()?(d.activate(b,f),!1):!0}):d.deactivate(b),b.element},close:function(b){var d=this;return d.instance===b&&(d.container.addClass("ui-helper-hidden ui-timepicker-hidden").hide(),d.ui.scrollTop(0),d.ui.children().removeClass("ui-state-hover")),a(c).unbind("click.timepicker-"+b.element.data("timepicker-event-namespace")),b.element},closed:function(){return this.ui.is(":hidden")},destroy:function(a){var b=this;return b.close(a,!0),a.element.unbind(".timepicker").data("TimePicker",null)},parse:function(b,c){return a.fn.timepicker.parseTime(c)},format:function(b,c,d){return d=d||b.options.timeFormat,a.fn.timepicker.formatTime(d,c)},getTime:function(b){var c=this,d=a.fn.timepicker.parseTime(b.element.val());return d instanceof Date&&!c._isValidTime(b,d)?null:d instanceof Date&&b.selectedTime?b.format(d)===b.format(b.selectedTime)?b.selectedTime:d:d instanceof Date?d:null},setTime:function(b,c,e){var f=this,g=b.selectedTime;if("string"==typeof c&&(c=b.parse(c)),c&&c.getMinutes&&f._isValidTime(b,c)){if(c=d(c),b.selectedTime=c,b.element.val(b.format(c,b.options.timeFormat)),e)return b}else b.selectedTime=null;return(null!==g||null!==b.selectedTime)&&(b.element.trigger("time-change",[c]),a.isFunction(b.options.change)&&b.options.change.apply(b.element,[c])),b.element},option:function(b,c,d){if("undefined"==typeof d)return b.options[c];var e,f,g=b.getTime();"string"==typeof c?(e={},e[c]=d):e=c,f=["minHour","minMinutes","minTime","maxHour","maxMinutes","maxTime","startHour","startMinutes","startTime","timeFormat","interval","dropdown"],a.each(e,function(c){b.options[c]=e[c],b.rebuild=b.rebuild||a.inArray(c,f)>-1}),b.rebuild&&b.setTime(g)}},a.TimePicker.defaults={timeFormat:"hh:mm p",minHour:null,minMinutes:null,minTime:null,maxHour:null,maxMinutes:null,maxTime:null,startHour:null,startMinutes:null,startTime:null,interval:30,dynamic:!0,theme:"standard",zindex:null,dropdown:!0,scrollbar:!1,change:function(){}},a.TimePicker.methods={chainable:["next","previous","open","close","destroy","setTime"]},a.fn.timepicker=function(b){if("string"==typeof b){var c,d,e=Array.prototype.slice.call(arguments,1);return c="option"===b&&arguments.length>2?"each":-1!==a.inArray(b,a.TimePicker.methods.chainable)?"each":"map",d=this[c](function(){var c=a(this),d=c.data("TimePicker");return"object"==typeof d?d[b].apply(d,e):void 0}),"map"===c&&1===this.length?a.makeArray(d).shift():"map"===c?a.makeArray(d):d}if(1===this.length&&this.data("TimePicker"))return this.data("TimePicker");var f=a.extend({},a.TimePicker.defaults,b);return this.each(function(){a.TimePicker.instance().register(this,f)})},a.fn.timepicker.formatTime=function(a,c){var d=c.getHours(),e=d%12,f=c.getMinutes(),g=c.getSeconds(),h={hh:b((0===e?12:e).toString(),"0",2),HH:b(d.toString(),"0",2),mm:b(f.toString(),"0",2),ss:b(g.toString(),"0",2),h:0===e?12:e,H:d,m:f,s:g,p:d>11?"PM":"AM"},i=a,j="";for(j in h)h.hasOwnProperty(j)&&(i=i.replace(new RegExp(j,"g"),h[j]));return i=i.replace(new RegExp("a","g"),d>11?"pm":"am")},a.fn.timepicker.parseTime=function(){var b=[[/^(\d+)$/,"$1"],[/^:(\d)$/,"$10"],[/^:(\d+)/,"$1"],[/^(\d):([7-9])$/,"0$10$2"],[/^(\d):(\d\d)$/,"$1$2"],[/^(\d):(\d{1,})$/,"0$1$20"],[/^(\d\d):([7-9])$/,"$10$2"],[/^(\d\d):(\d)$/,"$1$20"],[/^(\d\d):(\d*)$/,"$1$2"],[/^(\d{3,}):(\d)$/,"$10$2"],[/^(\d{3,}):(\d{2,})/,"$1$2"],[/^(\d):(\d):(\d)$/,"0$10$20$3"],[/^(\d{1,2}):(\d):(\d\d)/,"$10$2$3"]],c=b.length;return function(e){var f=d(new Date),g=!1,h=!1,i=!1,j=!1,k=!1;if("undefined"==typeof e||!e.toLowerCase)return null;e=e.toLowerCase(),g=/a/.test(e),h=g?!1:/p/.test(e),e=e.replace(/[^0-9:]/g,"").replace(/:+/g,":");for(var l=0;c>l;l+=1)if(b[l][0].test(e)){e=e.replace(b[l][0],b[l][1]);break}return e=e.replace(/:/g,""),1===e.length?i=e:2===e.length?i=e:3===e.length||5===e.length?(i=e.substr(0,1),j=e.substr(1,2),k=e.substr(3,2)):(4===e.length||e.length>5)&&(i=e.substr(0,2),j=e.substr(2,2),k=e.substr(4,2)),e.length>0&&e.length<5&&(e.length<3&&(j=0),k=0),i===!1||j===!1||k===!1?!1:(i=parseInt(i,10),j=parseInt(j,10),k=parseInt(k,10),g&&12===i?i=0:h&&12>i&&(i+=12),i>24?e.length>=6?a.fn.timepicker.parseTime(e.substr(0,5)):a.fn.timepicker.parseTime(e+"0"+(g?"a":"")+(h?"p":"")):(f.setHours(i,j,k),f))}}()}()}); \ No newline at end of file diff --git a/Libraries/links.txt b/Libraries/links.txt new file mode 100644 index 0000000..1524786 --- /dev/null +++ b/Libraries/links.txt @@ -0,0 +1,4 @@ +jquery-3.2.1.min.js: https://code.jquery.com/jquery-3.2.1.min.js +jquery-ui.min.js downloaded using download builder: https://jqueryui.com/download/ +FileSaver.min.js: https://github.com/eligrey/FileSaver.js/blob/v2.0.2/dist/FileSaver.min.js +jquery.timepicker.js: https://github.com/wvega/timepicker/blob/1.3.5/jquery.timepicker.js \ No newline at end of file diff --git a/manifest.json b/manifest.json index c652a9f..026b46f 100644 --- a/manifest.json +++ b/manifest.json @@ -3,7 +3,7 @@ "name": "Dawdle block", "short_name": "Dawdle block", "description": "Put time limits on unproductive sites.", - "version": "1.1.3", + "version": "1.1.4", "options_ui": { "page": "options.html", diff --git a/options.html b/options.html index 484104c..7fe747d 100644 --- a/options.html +++ b/options.html @@ -251,7 +251,7 @@

        Whitelist

        - +