/* * TypeWatch 3 * * Examples/Docs: github.com/dennyferra/TypeWatch * * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html */ !function(root, factory) { if (typeof define === 'function' && define.amd) { define(['jquery'], factory); } else if (typeof exports === 'object') { factory(require('jquery')); } else { factory(root.jQuery); } }(this, function($) { 'use strict'; $.fn.typeWatch = function(o) { // The default input types that are supported var _supportedInputTypes = ['TEXT', 'TEXTAREA', 'PASSWORD', 'TEL', 'SEARCH', 'URL', 'EMAIL', 'DATETIME', 'DATE', 'MONTH', 'WEEK', 'TIME', 'DATETIME-LOCAL', 'NUMBER', 'RANGE', 'DIV']; // Options var options = $.extend({ wait: 750, callback: function() { }, highlight: true, captureLength: 2, allowSubmit: false, inputTypes: _supportedInputTypes }, o); function checkElement(timer, override) { var value = timer.type === 'DIV' ? jQuery(timer.el).html() : jQuery(timer.el).val(); // If has capture length and has changed value // Or override and has capture length or allowSubmit option is true // Or capture length is zero and changed value if ((value.length >= options.captureLength && value != timer.text) || (override && (value.length >= options.captureLength || options.allowSubmit)) || (value.length == 0 && timer.text)) { timer.text = value; timer.cb.call(timer.el, value); } }; function watchElement(elem) { var elementType = (elem.type || elem.nodeName).toUpperCase(); if (jQuery.inArray(elementType, options.inputTypes) >= 0) { // Allocate timer element var timer = { timer: null, text: (elementType === 'DIV') ? jQuery(elem).html() : jQuery(elem).val(), cb: options.callback, el: elem, type: elementType, wait: options.wait }; // Set focus action (highlight) if (options.highlight && elementType !== 'DIV') jQuery(elem).focus(function() { this.select(); }); // Key watcher / clear and reset the timer var startWatch = function(evt) { var timerWait = timer.wait; var overrideBool = false; var evtElementType = elementType; // If enter key is pressed and not a TEXTAREA or DIV if (typeof evt.keyCode != 'undefined' && evt.keyCode == 13 && evtElementType !== 'TEXTAREA' && elementType !== 'DIV') { timerWait = 1; overrideBool = true; } var timerCallbackFx = function() { checkElement(timer, overrideBool) } // Clear timer clearTimeout(timer.timer); timer.timer = setTimeout(timerCallbackFx, timerWait); }; jQuery(elem).on('keydown paste cut input', startWatch); } }; // Watch each element return this.each(function() { watchElement(this); }); }; }); ; /** * Featherlight - ultra slim jQuery lightbox * Version 1.7.14-UMD - http://noelboss.github.io/featherlight/ * * Copyright 2019, Noël Raoul Bossart (http://www.noelboss.com) * MIT Licensed. **/ (function (factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(['jquery'], factory); } else if (typeof module === 'object' && module.exports) { // Node/CommonJS module.exports = function (root, jQuery) { if (jQuery === undefined) { // require('jQuery') returns a factory that requires window to // build a jQuery instance, we normalize how we use modules // that require this pattern but the window provided is a noop // if it's defined (how jquery works) if (typeof window !== 'undefined') { jQuery = require('jquery'); } else { jQuery = require('jquery')(root); } } factory(jQuery); return jQuery; }; } else { // Browser globals factory(jQuery); } })(function ($) { "use strict"; if ('undefined' === typeof $) { if ('console' in window) { window.console.info('Too much lightness, Featherlight needs jQuery.'); } return; } if ($.fn.jquery.match(/-ajax/)) { if ('console' in window) { window.console.info('Featherlight needs regular jQuery, not the slim version.'); } return; } /* Featherlight is exported as $.featherlight. It is a function used to open a featherlight lightbox. [tech] Featherlight uses prototype inheritance. Each opened lightbox will have a corresponding object. That object may have some attributes that override the prototype's. Extensions created with Featherlight.extend will have their own prototype that inherits from Featherlight's prototype, thus attributes can be overriden either at the object level, or at the extension level. To create callbacks that chain themselves instead of overriding, use chainCallbacks. For those familiar with CoffeeScript, this correspond to Featherlight being a class and the Gallery being a class extending Featherlight. The chainCallbacks is used since we don't have access to CoffeeScript's `super`. */ function Featherlight($content, config) { if (this instanceof Featherlight) { /* called with new */ this.id = Featherlight.id++; this.setup($content, config); this.chainCallbacks(Featherlight._callbackChain); } else { var fl = new Featherlight($content, config); fl.open(); return fl; } } var opened = [], pruneOpened = function (remove) { opened = $.grep(opened, function (fl) { return fl !== remove && fl.$instance.closest('body').length > 0; }); return opened; }; // Removes keys of `set` from `obj` and returns the removed key/values. function slice(obj, set) { var r = {}; for (var key in obj) { if (key in set) { r[key] = obj[key]; delete obj[key]; } } return r; } // NOTE: List of available [iframe attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe). var iFrameAttributeSet = { allow: 1, allowfullscreen: 1, frameborder: 1, height: 1, longdesc: 1, marginheight: 1, marginwidth: 1, mozallowfullscreen: 1, name: 1, referrerpolicy: 1, sandbox: 1, scrolling: 1, src: 1, srcdoc: 1, style: 1, webkitallowfullscreen: 1, width: 1 }; // Converts camelCased attributes to dasherized versions for given prefix: // parseAttrs({hello: 1, hellFrozeOver: 2}, 'hell') => {froze-over: 2} function parseAttrs(obj, prefix) { var attrs = {}, regex = new RegExp('^' + prefix + '([A-Z])(.*)'); for (var key in obj) { var match = key.match(regex); if (match) { var dasherized = (match[1] + match[2].replace(/([A-Z])/g, '-$1')).toLowerCase(); attrs[dasherized] = obj[key]; } } return attrs; } /* document wide key handler */ var eventMap = { keyup: 'onKeyUp', resize: 'onResize' }; var globalEventHandler = function (event) { $.each(Featherlight.opened().reverse(), function () { if (!event.isDefaultPrevented()) { if (false === this[eventMap[event.type]](event)) { event.preventDefault(); event.stopPropagation(); return false; } } }); }; var toggleGlobalEvents = function (set) { if (set !== Featherlight._globalHandlerInstalled) { Featherlight._globalHandlerInstalled = set; var events = $.map(eventMap, function (_, name) { return name + '.' + Featherlight.prototype.namespace; }).join(' '); $(window)[set ? 'on' : 'off'](events, globalEventHandler); } }; Featherlight.prototype = { constructor: Featherlight, /*** defaults ***/ /* extend featherlight with defaults and methods */ namespace: 'featherlight', /* Name of the events and css class prefix */ targetAttr: 'data-featherlight', /* Attribute of the triggered element that contains the selector to the lightbox content */ variant: null, /* Class that will be added to change look of the lightbox */ resetCss: false, /* Reset all css */ background: null, /* Custom DOM for the background, wrapper and the closebutton */ openTrigger: 'click', /* Event that triggers the lightbox */ closeTrigger: 'click', /* Event that triggers the closing of the lightbox */ filter: null, /* Selector to filter events. Think $(...).on('click', filter, eventHandler) */ root: 'body', /* Where to append featherlights */ openSpeed: 250, /* Duration of opening animation */ closeSpeed: 250, /* Duration of closing animation */ closeOnClick: 'background', /* Close lightbox on click ('background', 'anywhere' or false) */ closeOnEsc: true, /* Close lightbox when pressing esc */ closeIcon: '✕', /* Close icon */ loading: '', /* Content to show while initial content is loading */ persist: false, /* If set, the content will persist and will be shown again when opened again. 'shared' is a special value when binding multiple elements for them to share the same content */ otherClose: null, /* Selector for alternate close buttons (e.g. "a.close") */ beforeOpen: $.noop, /* Called before open. can return false to prevent opening of lightbox. Gets event as parameter, this contains all data */ beforeContent: $.noop, /* Called when content is loaded. Gets event as parameter, this contains all data */ beforeClose: $.noop, /* Called before close. can return false to prevent closing of lightbox. Gets event as parameter, this contains all data */ afterOpen: $.noop, /* Called after open. Gets event as parameter, this contains all data */ afterContent: $.noop, /* Called after content is ready and has been set. Gets event as parameter, this contains all data */ afterClose: $.noop, /* Called after close. Gets event as parameter, this contains all data */ onKeyUp: $.noop, /* Called on key up for the frontmost featherlight */ onResize: $.noop, /* Called after new content and when a window is resized */ type: null, /* Specify type of lightbox. If unset, it will check for the targetAttrs value. */ contentFilters: ['jquery', 'image', 'html', 'ajax', 'iframe', 'text'], /* List of content filters to use to determine the content */ /*** methods ***/ /* setup iterates over a single instance of featherlight and prepares the background and binds the events */ setup: function (target, config) { /* all arguments are optional */ if (typeof target === 'object' && target instanceof $ === false && !config) { config = target; target = undefined; } var self = $.extend(this, config, { target: target }), css = !self.resetCss ? self.namespace : self.namespace + '-reset', /* by adding -reset to the classname, we reset all the default css */ $background = $(self.background || [ '