UNPKG

flounder

Version:
1,618 lines (1,402 loc) 167 kB
/*! * Flounder JavaScript Stylable Selectbox v1.3.13 * https://github.com/sociomantic-tsunami/flounder * * Copyright 2015-2018 Sociomantic Labs and other contributors * Released under the MIT license * https://github.com/sociomantic-tsunami/flounder/license * * Date: Thu Oct 11 2018 * * "This, so far, is the best Flounder ever" */(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ "use strict"; // rawAsap provides everything we need except exception management. var rawAsap = require("./raw"); // RawTasks are recycled to reduce GC churn. var freeTasks = []; // We queue errors to ensure they are thrown in right order (FIFO). // Array-as-queue is good enough here, since we are just dealing with exceptions. var pendingErrors = []; var requestErrorThrow = rawAsap.makeRequestCallFromTimer(throwFirstError); function throwFirstError() { if (pendingErrors.length) { throw pendingErrors.shift(); } } /** * Calls a task as soon as possible after returning, in its own event, with priority * over other events like animation, reflow, and repaint. An error thrown from an * event will not interrupt, nor even substantially slow down the processing of * other events, but will be rather postponed to a lower priority event. * @param {{call}} task A callable object, typically a function that takes no * arguments. */ module.exports = asap; function asap(task) { var rawTask; if (freeTasks.length) { rawTask = freeTasks.pop(); } else { rawTask = new RawTask(); } rawTask.task = task; rawAsap(rawTask); } // We wrap tasks with recyclable task objects. A task object implements // `call`, just like a function. function RawTask() { this.task = null; } // The sole purpose of wrapping the task is to catch the exception and recycle // the task object after its single use. RawTask.prototype.call = function () { try { this.task.call(); } catch (error) { if (asap.onerror) { // This hook exists purely for testing purposes. // Its name will be periodically randomized to break any code that // depends on its existence. asap.onerror(error); } else { // In a web browser, exceptions are not fatal. However, to avoid // slowing down the queue of pending tasks, we rethrow the error in a // lower priority turn. pendingErrors.push(error); requestErrorThrow(); } } finally { this.task = null; freeTasks[freeTasks.length] = this; } }; },{"./raw":2}],2:[function(require,module,exports){ (function (global){ "use strict"; // Use the fastest means possible to execute a task in its own turn, with // priority over other events including IO, animation, reflow, and redraw // events in browsers. // // An exception thrown by a task will permanently interrupt the processing of // subsequent tasks. The higher level `asap` function ensures that if an // exception is thrown by a task, that the task queue will continue flushing as // soon as possible, but if you use `rawAsap` directly, you are responsible to // either ensure that no exceptions are thrown from your task, or to manually // call `rawAsap.requestFlush` if an exception is thrown. module.exports = rawAsap; function rawAsap(task) { if (!queue.length) { requestFlush(); flushing = true; } // Equivalent to push, but avoids a function call. queue[queue.length] = task; } var queue = []; // Once a flush has been requested, no further calls to `requestFlush` are // necessary until the next `flush` completes. var flushing = false; // `requestFlush` is an implementation-specific method that attempts to kick // off a `flush` event as quickly as possible. `flush` will attempt to exhaust // the event queue before yielding to the browser's own event loop. var requestFlush; // The position of the next task to execute in the task queue. This is // preserved between calls to `flush` so that it can be resumed if // a task throws an exception. var index = 0; // If a task schedules additional tasks recursively, the task queue can grow // unbounded. To prevent memory exhaustion, the task queue will periodically // truncate already-completed tasks. var capacity = 1024; // The flush function processes all tasks that have been scheduled with // `rawAsap` unless and until one of those tasks throws an exception. // If a task throws an exception, `flush` ensures that its state will remain // consistent and will resume where it left off when called again. // However, `flush` does not make any arrangements to be called again if an // exception is thrown. function flush() { while (index < queue.length) { var currentIndex = index; // Advance the index before calling the task. This ensures that we will // begin flushing on the next task the task throws an error. index = index + 1; queue[currentIndex].call(); // Prevent leaking memory for long chains of recursive calls to `asap`. // If we call `asap` within tasks scheduled by `asap`, the queue will // grow, but to avoid an O(n) walk for every task we execute, we don't // shift tasks off the queue after they have been executed. // Instead, we periodically shift 1024 tasks off the queue. if (index > capacity) { // Manually shift all values starting at the index back to the // beginning of the queue. for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) { queue[scan] = queue[scan + index]; } queue.length -= index; index = 0; } } queue.length = 0; index = 0; flushing = false; } // `requestFlush` is implemented using a strategy based on data collected from // every available SauceLabs Selenium web driver worker at time of writing. // https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593 // Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that // have WebKitMutationObserver but not un-prefixed MutationObserver. // Must use `global` or `self` instead of `window` to work in both frames and web // workers. `global` is a provision of Browserify, Mr, Mrs, or Mop. /* globals self */ var scope = typeof global !== "undefined" ? global : self; var BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver; // MutationObservers are desirable because they have high priority and work // reliably everywhere they are implemented. // They are implemented in all modern browsers. // // - Android 4-4.3 // - Chrome 26-34 // - Firefox 14-29 // - Internet Explorer 11 // - iPad Safari 6-7.1 // - iPhone Safari 7-7.1 // - Safari 6-7 if (typeof BrowserMutationObserver === "function") { requestFlush = makeRequestCallFromMutationObserver(flush); // MessageChannels are desirable because they give direct access to the HTML // task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera // 11-12, and in web workers in many engines. // Although message channels yield to any queued rendering and IO tasks, they // would be better than imposing the 4ms delay of timers. // However, they do not work reliably in Internet Explorer or Safari. // Internet Explorer 10 is the only browser that has setImmediate but does // not have MutationObservers. // Although setImmediate yields to the browser's renderer, it would be // preferrable to falling back to setTimeout since it does not have // the minimum 4ms penalty. // Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (and // Desktop to a lesser extent) that renders both setImmediate and // MessageChannel useless for the purposes of ASAP. // https://github.com/kriskowal/q/issues/396 // Timers are implemented universally. // We fall back to timers in workers in most engines, and in foreground // contexts in the following browsers. // However, note that even this simple case requires nuances to operate in a // broad spectrum of browsers. // // - Firefox 3-13 // - Internet Explorer 6-9 // - iPad Safari 4.3 // - Lynx 2.8.7 } else { requestFlush = makeRequestCallFromTimer(flush); } // `requestFlush` requests that the high priority event queue be flushed as // soon as possible. // This is useful to prevent an error thrown in a task from stalling the event // queue if the exception handled by Node.js’s // `process.on("uncaughtException")` or by a domain. rawAsap.requestFlush = requestFlush; // To request a high priority event, we induce a mutation observer by toggling // the text of a text node between "1" and "-1". function makeRequestCallFromMutationObserver(callback) { var toggle = 1; var observer = new BrowserMutationObserver(callback); var node = document.createTextNode(""); observer.observe(node, {characterData: true}); return function requestCall() { toggle = -toggle; node.data = toggle; }; } // The message channel technique was discovered by Malte Ubl and was the // original foundation for this library. // http://www.nonblocking.io/2011/06/windownexttick.html // Safari 6.0.5 (at least) intermittently fails to create message ports on a // page's first load. Thankfully, this version of Safari supports // MutationObservers, so we don't need to fall back in that case. // function makeRequestCallFromMessageChannel(callback) { // var channel = new MessageChannel(); // channel.port1.onmessage = callback; // return function requestCall() { // channel.port2.postMessage(0); // }; // } // For reasons explained above, we are also unable to use `setImmediate` // under any circumstances. // Even if we were, there is another bug in Internet Explorer 10. // It is not sufficient to assign `setImmediate` to `requestFlush` because // `setImmediate` must be called *by name* and therefore must be wrapped in a // closure. // Never forget. // function makeRequestCallFromSetImmediate(callback) { // return function requestCall() { // setImmediate(callback); // }; // } // Safari 6.0 has a problem where timers will get lost while the user is // scrolling. This problem does not impact ASAP because Safari 6.0 supports // mutation observers, so that implementation is used instead. // However, if we ever elect to use timers in Safari, the prevalent work-around // is to add a scroll event listener that calls for a flush. // `setTimeout` does not call the passed callback if the delay is less than // approximately 7 in web workers in Firefox 8 through 18, and sometimes not // even then. function makeRequestCallFromTimer(callback) { return function requestCall() { // We dispatch a timeout with a specified delay of 0 for engines that // can reliably accommodate that request. This will usually be snapped // to a 4 milisecond delay, but once we're flushing, there's no delay // between events. var timeoutHandle = setTimeout(handleTimer, 0); // However, since this timer gets frequently dropped in Firefox // workers, we enlist an interval handle that will try to fire // an event 20 times per second until it succeeds. var intervalHandle = setInterval(handleTimer, 50); function handleTimer() { // Whichever timer succeeds will cancel both timers and // execute the callback. clearTimeout(timeoutHandle); clearInterval(intervalHandle); callback(); } }; } // This is for `asap.js` only. // Its name will be periodically randomized to break any code that depends on // its existence. rawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer; // ASAP was originally a nextTick shim included in Q. This was factored out // into this ASAP package. It was later adapted to RSVP which made further // amendments. These decisions, particularly to marginalize MessageChannel and // to capture the MutationObserver implementation in a closure, were integrated // back into ASAP proper. // https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],3:[function(require,module,exports){ /** * http.js * * @author Mouse Braun <mouse@knoblau.ch> * @author Nicolas Brugneaux <nicolas.brugneaux@gmail.com> * * @package Microbe */ module.exports = function( Microbe ) { 'use strict'; var Promise = require( 'promise' ); /** * ## http * * Method takes as many as necessary parameters, with url being the only required. * The return then has the methods `.then( _cb )` and `.error( _cb )` * * @param {Object} _parameters http parameters. possible properties * method, url, data, user, password, headers, async * * @example µ.http( {url: './test.html', method: 'POST', data: { number: 67867} } ).then( function(){} ).catch( function(){} ); */ Microbe.http = function( _parameters ) { var req, method, url, data, user, password, headers, async; if ( !_parameters ) { return new Error( 'No parameters given' ); } else { if ( typeof _parameters === 'string' ) { _parameters = { url: _parameters }; } req = new XMLHttpRequest(); method = _parameters.method || 'GET'; url = _parameters.url; data = JSON.stringify( _parameters.data ) || null; user = _parameters.user || ''; password = _parameters.password || ''; headers = _parameters.headers || null; async = typeof _parameters.async === "boolean" ? _parameters.async : true; req.onreadystatechange = function() { if ( req.readyState === 4 ) { return req; } }; } req.open( method, url, async, user, password ); // weird Safari voodoo fix if ( method === 'POST' ) { req.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' ); } if ( headers ) { for ( var header in headers ) { req.setRequestHeader( header, headers[header] ); } } if ( async ) { return new Promise( function( resolve, reject ) { req.onerror = function() { reject( new Error( 'Network error!' ) ); }; req.send( data ); req.onload = function() { if ( req.status === 200 ) { resolve( req.response ); } else { reject( new Error( req.status ) ); } }; }); } else { var _response = function( _val ) { var _responses = { /** * ## .then * * Called after `http`, `http.get`, or `http.post`, this is * called passing the result as the first parameter to the callback * * @param {Function} _cb function to call after http request * * @return _Object_ contains the `.catch` method */ then: function( _cb ) { if ( _val.status === 200 ) { _cb( _val.responseText ); } return _responses; }, /** * ## .catch * * Called after `http`, `http.get`, or `http.post`, this is * called passing the error as the first parameter to the callback * * @param {Function} _cb function to call after http request * * @return _Object_ contains the `.then` method */ catch: function( _cb ) { if ( _val.status !== 200 ) { _cb( { status : _val.status, statusText : _val.statusText } ); } return _responses; } }; return _responses; }; req.send( data ); req.onloadend = function() { req.onreadystatechange(); return _response( req ); }; return req.onloadend(); } }; /** * ## http.get * * Syntactic shortcut for simple GET requests * * @param {String} _url file url * * @example µ.http.get( './test.html' ).then( function(){} ).catch( function(){} ); * * @return _Object_ contains `.then` and `.catch` */ Microbe.http.get = function( _url ) { return this( { url : _url, method : 'GET' } ); }; /** * ## http.post * * Syntactic shortcut for simple POST requests * * @param {String} _url file url * @param {Mixed} _data data to post to location {Object or String} * * @example µ.http.post( './test.html', { number: 67867} ).then( function(){} ).catch( function(){} ); * * @return _Object_ contains `.then` and `.catch` */ Microbe.http.post = function( _url, _data ) { return this( { url : _url, data : _data, method : 'POST' } ); }; }; },{"promise":4}],4:[function(require,module,exports){ 'use strict'; module.exports = require('./lib') },{"./lib":9}],5:[function(require,module,exports){ 'use strict'; var asap = require('asap/raw'); function noop() {} // States: // // 0 - pending // 1 - fulfilled with _value // 2 - rejected with _value // 3 - adopted the state of another promise, _value // // once the state is no longer pending (0) it is immutable // All `_` prefixed properties will be reduced to `_{random number}` // at build time to obfuscate them and discourage their use. // We don't use symbols or Object.defineProperty to fully hide them // because the performance isn't good enough. // to avoid using try/catch inside critical functions, we // extract them to here. var LAST_ERROR = null; var IS_ERROR = {}; function getThen(obj) { try { return obj.then; } catch (ex) { LAST_ERROR = ex; return IS_ERROR; } } function tryCallOne(fn, a) { try { return fn(a); } catch (ex) { LAST_ERROR = ex; return IS_ERROR; } } function tryCallTwo(fn, a, b) { try { fn(a, b); } catch (ex) { LAST_ERROR = ex; return IS_ERROR; } } module.exports = Promise; function Promise(fn) { if (typeof this !== 'object') { throw new TypeError('Promises must be constructed via new'); } if (typeof fn !== 'function') { throw new TypeError('Promise constructor\'s argument is not a function'); } this._40 = 0; this._65 = 0; this._55 = null; this._72 = null; if (fn === noop) return; doResolve(fn, this); } Promise._37 = null; Promise._87 = null; Promise._61 = noop; Promise.prototype.then = function(onFulfilled, onRejected) { if (this.constructor !== Promise) { return safeThen(this, onFulfilled, onRejected); } var res = new Promise(noop); handle(this, new Handler(onFulfilled, onRejected, res)); return res; }; function safeThen(self, onFulfilled, onRejected) { return new self.constructor(function (resolve, reject) { var res = new Promise(noop); res.then(resolve, reject); handle(self, new Handler(onFulfilled, onRejected, res)); }); } function handle(self, deferred) { while (self._65 === 3) { self = self._55; } if (Promise._37) { Promise._37(self); } if (self._65 === 0) { if (self._40 === 0) { self._40 = 1; self._72 = deferred; return; } if (self._40 === 1) { self._40 = 2; self._72 = [self._72, deferred]; return; } self._72.push(deferred); return; } handleResolved(self, deferred); } function handleResolved(self, deferred) { asap(function() { var cb = self._65 === 1 ? deferred.onFulfilled : deferred.onRejected; if (cb === null) { if (self._65 === 1) { resolve(deferred.promise, self._55); } else { reject(deferred.promise, self._55); } return; } var ret = tryCallOne(cb, self._55); if (ret === IS_ERROR) { reject(deferred.promise, LAST_ERROR); } else { resolve(deferred.promise, ret); } }); } function resolve(self, newValue) { // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure if (newValue === self) { return reject( self, new TypeError('A promise cannot be resolved with itself.') ); } if ( newValue && (typeof newValue === 'object' || typeof newValue === 'function') ) { var then = getThen(newValue); if (then === IS_ERROR) { return reject(self, LAST_ERROR); } if ( then === self.then && newValue instanceof Promise ) { self._65 = 3; self._55 = newValue; finale(self); return; } else if (typeof then === 'function') { doResolve(then.bind(newValue), self); return; } } self._65 = 1; self._55 = newValue; finale(self); } function reject(self, newValue) { self._65 = 2; self._55 = newValue; if (Promise._87) { Promise._87(self, newValue); } finale(self); } function finale(self) { if (self._40 === 1) { handle(self, self._72); self._72 = null; } if (self._40 === 2) { for (var i = 0; i < self._72.length; i++) { handle(self, self._72[i]); } self._72 = null; } } function Handler(onFulfilled, onRejected, promise){ this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; this.onRejected = typeof onRejected === 'function' ? onRejected : null; this.promise = promise; } /** * Take a potentially misbehaving resolver function and make sure * onFulfilled and onRejected are only called once. * * Makes no guarantees about asynchrony. */ function doResolve(fn, promise) { var done = false; var res = tryCallTwo(fn, function (value) { if (done) return; done = true; resolve(promise, value); }, function (reason) { if (done) return; done = true; reject(promise, reason); }); if (!done && res === IS_ERROR) { done = true; reject(promise, LAST_ERROR); } } },{"asap/raw":2}],6:[function(require,module,exports){ 'use strict'; var Promise = require('./core.js'); module.exports = Promise; Promise.prototype.done = function (onFulfilled, onRejected) { var self = arguments.length ? this.then.apply(this, arguments) : this; self.then(null, function (err) { setTimeout(function () { throw err; }, 0); }); }; },{"./core.js":5}],7:[function(require,module,exports){ 'use strict'; //This file contains the ES6 extensions to the core Promises/A+ API var Promise = require('./core.js'); module.exports = Promise; /* Static Functions */ var TRUE = valuePromise(true); var FALSE = valuePromise(false); var NULL = valuePromise(null); var UNDEFINED = valuePromise(undefined); var ZERO = valuePromise(0); var EMPTYSTRING = valuePromise(''); function valuePromise(value) { var p = new Promise(Promise._61); p._65 = 1; p._55 = value; return p; } Promise.resolve = function (value) { if (value instanceof Promise) return value; if (value === null) return NULL; if (value === undefined) return UNDEFINED; if (value === true) return TRUE; if (value === false) return FALSE; if (value === 0) return ZERO; if (value === '') return EMPTYSTRING; if (typeof value === 'object' || typeof value === 'function') { try { var then = value.then; if (typeof then === 'function') { return new Promise(then.bind(value)); } } catch (ex) { return new Promise(function (resolve, reject) { reject(ex); }); } } return valuePromise(value); }; Promise.all = function (arr) { var args = Array.prototype.slice.call(arr); return new Promise(function (resolve, reject) { if (args.length === 0) return resolve([]); var remaining = args.length; function res(i, val) { if (val && (typeof val === 'object' || typeof val === 'function')) { if (val instanceof Promise && val.then === Promise.prototype.then) { while (val._65 === 3) { val = val._55; } if (val._65 === 1) return res(i, val._55); if (val._65 === 2) reject(val._55); val.then(function (val) { res(i, val); }, reject); return; } else { var then = val.then; if (typeof then === 'function') { var p = new Promise(then.bind(val)); p.then(function (val) { res(i, val); }, reject); return; } } } args[i] = val; if (--remaining === 0) { resolve(args); } } for (var i = 0; i < args.length; i++) { res(i, args[i]); } }); }; Promise.reject = function (value) { return new Promise(function (resolve, reject) { reject(value); }); }; Promise.race = function (values) { return new Promise(function (resolve, reject) { values.forEach(function(value){ Promise.resolve(value).then(resolve, reject); }); }); }; /* Prototype Methods */ Promise.prototype['catch'] = function (onRejected) { return this.then(null, onRejected); }; },{"./core.js":5}],8:[function(require,module,exports){ 'use strict'; var Promise = require('./core.js'); module.exports = Promise; Promise.prototype['finally'] = function (f) { return this.then(function (value) { return Promise.resolve(f()).then(function () { return value; }); }, function (err) { return Promise.resolve(f()).then(function () { throw err; }); }); }; },{"./core.js":5}],9:[function(require,module,exports){ 'use strict'; module.exports = require('./core.js'); require('./done.js'); require('./finally.js'); require('./es6-extensions.js'); require('./node-extensions.js'); require('./synchronous.js'); },{"./core.js":5,"./done.js":6,"./es6-extensions.js":7,"./finally.js":8,"./node-extensions.js":10,"./synchronous.js":11}],10:[function(require,module,exports){ 'use strict'; // This file contains then/promise specific extensions that are only useful // for node.js interop var Promise = require('./core.js'); var asap = require('asap'); module.exports = Promise; /* Static Functions */ Promise.denodeify = function (fn, argumentCount) { if ( typeof argumentCount === 'number' && argumentCount !== Infinity ) { return denodeifyWithCount(fn, argumentCount); } else { return denodeifyWithoutCount(fn); } }; var callbackFn = ( 'function (err, res) {' + 'if (err) { rj(err); } else { rs(res); }' + '}' ); function denodeifyWithCount(fn, argumentCount) { var args = []; for (var i = 0; i < argumentCount; i++) { args.push('a' + i); } var body = [ 'return function (' + args.join(',') + ') {', 'var self = this;', 'return new Promise(function (rs, rj) {', 'var res = fn.call(', ['self'].concat(args).concat([callbackFn]).join(','), ');', 'if (res &&', '(typeof res === "object" || typeof res === "function") &&', 'typeof res.then === "function"', ') {rs(res);}', '});', '};' ].join(''); return Function(['Promise', 'fn'], body)(Promise, fn); } function denodeifyWithoutCount(fn) { var fnLength = Math.max(fn.length - 1, 3); var args = []; for (var i = 0; i < fnLength; i++) { args.push('a' + i); } var body = [ 'return function (' + args.join(',') + ') {', 'var self = this;', 'var args;', 'var argLength = arguments.length;', 'if (arguments.length > ' + fnLength + ') {', 'args = new Array(arguments.length + 1);', 'for (var i = 0; i < arguments.length; i++) {', 'args[i] = arguments[i];', '}', '}', 'return new Promise(function (rs, rj) {', 'var cb = ' + callbackFn + ';', 'var res;', 'switch (argLength) {', args.concat(['extra']).map(function (_, index) { return ( 'case ' + (index) + ':' + 'res = fn.call(' + ['self'].concat(args.slice(0, index)).concat('cb').join(',') + ');' + 'break;' ); }).join(''), 'default:', 'args[argLength] = cb;', 'res = fn.apply(self, args);', '}', 'if (res &&', '(typeof res === "object" || typeof res === "function") &&', 'typeof res.then === "function"', ') {rs(res);}', '});', '};' ].join(''); return Function( ['Promise', 'fn'], body )(Promise, fn); } Promise.nodeify = function (fn) { return function () { var args = Array.prototype.slice.call(arguments); var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null; var ctx = this; try { return fn.apply(this, arguments).nodeify(callback, ctx); } catch (ex) { if (callback === null || typeof callback == 'undefined') { return new Promise(function (resolve, reject) { reject(ex); }); } else { asap(function () { callback.call(ctx, ex); }) } } } }; Promise.prototype.nodeify = function (callback, ctx) { if (typeof callback != 'function') return this; this.then(function (value) { asap(function () { callback.call(ctx, null, value); }); }, function (err) { asap(function () { callback.call(ctx, err); }); }); }; },{"./core.js":5,"asap":1}],11:[function(require,module,exports){ 'use strict'; var Promise = require('./core.js'); module.exports = Promise; Promise.enableSynchronous = function () { Promise.prototype.isPending = function() { return this.getState() == 0; }; Promise.prototype.isFulfilled = function() { return this.getState() == 1; }; Promise.prototype.isRejected = function() { return this.getState() == 2; }; Promise.prototype.getValue = function () { if (this._65 === 3) { return this._55.getValue(); } if (!this.isFulfilled()) { throw new Error('Cannot get a value of an unfulfilled promise.'); } return this._55; }; Promise.prototype.getReason = function () { if (this._65 === 3) { return this._55.getReason(); } if (!this.isRejected()) { throw new Error('Cannot get a rejection reason of a non-rejected promise.'); } return this._55; }; Promise.prototype.getState = function () { if (this._65 === 3) { return this._55.getState(); } if (this._65 === -1 || this._65 === -2) { return 0; } return this._65; }; }; Promise.disableSynchronous = function() { Promise.prototype.isPending = undefined; Promise.prototype.isFulfilled = undefined; Promise.prototype.isRejected = undefined; Promise.prototype.getValue = undefined; Promise.prototype.getReason = undefined; Promise.prototype.getState = undefined; }; },{"./core.js":5}],12:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /* * Copyright (c) 2015-2018 dunnhumby Germany GmbH. * All rights reserved. * * This source code is licensed under the MIT license found in the LICENSE file * in the root directory of this source tree. * */ /* globals console */ var _utils = require('./utils'); var _utils2 = _interopRequireDefault(_utils); var _defaults = require('./defaults'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var api = { /** * ## buildFromUrl * * uses loadDataFromUrl and completes the entire build with the new data * * @param {String} url address to get the data from * @param {Function} callback function to run after getting the data * * @return {Void} void */ buildFromUrl: function buildFromUrl(url, callback) { var _this = this; this.loadDataFromUrl(url, function (data) { _this.data = data; if (callback) { callback(_this.data); } _this.rebuild(_this.data); }); return []; }, /** * ## clickByIndex * * programatically sets selected by index. If there are not enough elements * to match the index, then nothing is selected. Fires the onClick event * * @param {Mixed} index index to set flounder to. * _Number, or Array of numbers_ * @param {Boolean} multiple multiSelect or not * * @return {Void} void */ clickByIndex: function clickByIndex(index, multiple) { return this.setByIndex(index, multiple, false); }, /** * ## clickByText * * programatically sets selected by text string. If the text string * is not matched to an element, nothing will be selected. Fires the * onClick event * * @param {Mixed} text text to set flounder to. * _String, or Array of strings_ * @param {Boolean} multiple multiSelect or not * * @return {Void} void */ clickByText: function clickByText(text, multiple) { return this.setByText(text, multiple, false); }, /** * ## clickByValue * * programatically sets selected by value string. If the value string * is not matched to an element, nothing will be selected. Fires the * onClick event * * @param {Mixed} value value to set flounder to. * _String, or Array of strings_ * @param {Boolean} multiple multiSelect or not * * @return {Void} void */ clickByValue: function clickByValue(value, multiple) { return this.setByValue(value, multiple, false); }, /** * ## destroy * * removes flounder and all it`s events from the dom * * @return {Void} void */ destroy: function destroy() { this.componentWillUnmount(); var refs = this.refs; var classes = this.classes; var originalTarget = this.originalTarget; var tagName = originalTarget.tagName; if (tagName === 'INPUT' || tagName === 'SELECT') { var target = originalTarget.nextElementSibling; if (tagName === 'SELECT') { var firstOption = originalTarget[0]; if (firstOption && _utils2.default.hasClass(firstOption, classes.PLACEHOLDER)) { originalTarget.removeChild(firstOption); } } else { target = refs.flounder.parentNode; } try { var _classes = this.classes; target.parentNode.removeChild(target); originalTarget.tabIndex = 0; _utils2.default.removeClass(originalTarget, _classes.HIDDEN); } catch (e) { throw ' : this flounder may have already been removed'; } } else { try { var wrapper = refs.wrapper; var parent = wrapper.parentNode; parent.removeChild(wrapper); } catch (e) { throw ' : this flounder may have already been removed'; } } refs.flounder.flounder = originalTarget.flounder = this.target.flounder = null; }, /** * ## deselectAll * * deslects all data * * @param {Boolean} silent stifle the onChange event * * @return {Void} void */ deselectAll: function deselectAll(silent) { this.removeSelectedClass(); this.removeSelectedValue(); if (this.multiple) { var multiTagWrapper = this.refs.multiTagWrapper; if (multiTagWrapper) { var children = multiTagWrapper.children; for (var i = 0; i < children.length - 1; i++) { var el = children[i]; var lastEl = i === children.length - 1; if (!silent && lastEl) { el = el.children; el = el[0]; el.click(); } else { el.removeEventListener('click', this.removeMultiTag); el.remove(); } } this.addPlaceholder(); } } }, /** * ## disable * * disables flounder by adjusting listeners and classes * * @param {Boolean} bool disable or enable * * @return {Void} void */ disable: function disable(bool) { var refs = this.refs; var classes = this.classes; var flounder = refs.flounder; var selected = refs.selected; if (bool) { flounder.removeEventListener('keydown', this.checkFlounderKeypress); selected.removeEventListener('click', this.toggleList); _utils2.default.addClass(flounder, classes.DISABLED); } else { flounder.addEventListener('keydown', this.checkFlounderKeypress); selected.addEventListener('click', this.toggleList); _utils2.default.removeClass(flounder, classes.DISABLED); } }, /** * ## disableByIndex * * disables the options with the given index * * @param {Mixed} index index of the option * @param {Boolean} reenable enables the option instead * * @return {Void} void */ disableByIndex: function disableByIndex(index, reenable) { var refs = this.refs; if (typeof index !== 'string' && index.length) { var disableByIndex = this.disableByIndex.bind(this); return index.map(function (_i) { return disableByIndex(_i, reenable); }); } var data = refs.data; var length = data.length; if (index < 0) { length = data.length; index = length + index; } var el = data[index]; if (el) { var opt = refs.selectOptions[index]; var classes = this.classes; if (reenable) { opt.disabled = false; _utils2.default.removeClass(el, classes.DISABLED); } else { opt.disabled = true; _utils2.default.addClass(el, classes.DISABLED); } return [el, opt]; } console.warn('Flounder - No element to disable.'); }, /** * ## disableByText * * disables THE FIRST option that has the given value * * @param {Mixed} text value of the option * @param {Boolean} reenable enables the option instead * * @return {Void} void */ disableByText: function disableByText(text, reenable) { if (typeof text !== 'string' && text.length) { var disableByText = this.disableByText.bind(this); var _res = text.map(function (_v) { return disableByText(_v, reenable); }); return _res.length === 1 ? _res[0] : _res; } var res = []; this.refs.data.forEach(function (el, i) { var elText = el.innerHTML; if (elText === text) { res.push(i); } }); res = res.length === 1 ? res[0] : res; return this.disableByIndex(res, reenable); }, /** * ## disableByValue * * disables THE FIRST option that has the given value * * @param {Mixed} value value of the option * @param {Boolean} reenable enables the option instead * * @return {Void} void */ disableByValue: function disableByValue(value, reenable) { if (typeof value !== 'string' && value.length) { var disableByValue = this.disableByValue.bind(this); var _res2 = value.map(function (_v) { return disableByValue(_v, reenable); }); return _res2.length === 1 ? _res2[0] : _res2; } var res = this.refs.selectOptions.map(function (el, i) { return '' + el.value === '' + value ? i : null; }).filter(function (a) { return !!a || a === 0; }); res = res.length === 1 ? res[0] : res; return this.disableByIndex(res, reenable); }, /** * ## enableByIndex * * shortcut syntax to enable an index * * @param {Mixed} index index of the option to enable * * @return {Object} flounder(s) */ enableByIndex: function enableByIndex(index) { return this.disableByIndex(index, true); }, /** * ## enableByText * * shortcut syntax to enable by text * * @param {Mixed} text text of the option to enable * * @return {Object} flounder(s) */ enableByText: function enableByText(text) { return this.disableByText(text, true); }, /** * ## enableByValue * * shortcut syntax to enable a value * * @param {Mixed} value value of the option to enable * * @return {Object} flounder(s) */ enableByValue: function enableByValue(value) { this.disableByValue(value, true); }, /** * ## getData * * returns the option and div tags related to an option * * @param {Number} index index to return * * @return {Object} option and div tage */ getData: function getData(index) { var _this2 = this; var refs = this.refs; if (typeof index === 'number') { return { option: refs.selectOptions[index], div: refs.data[index] }; } else if (index && index.length && typeof index !== 'string') { return index.map(function (i) { return _this2.getData(i); }); } else if (!index) { return refs.selectOptions.map(function (el, i) { return _this2.getData(i); }); } console.warn('Flounder - Illegal parameter type.'); }, /** * ## getSelected * * returns the currently selected data of a SELECT box * * @return {Void} void */ getSelected: function getSelected() { var el = this.refs.select; var opts = []; var data = el.options; var classes = this.classes; for (var i = 0; i < data.length; i++) { var _el = data[i]; if (_el.selected && !_utils2.default.hasClass(_el, classes.PLACEHOLDER)) { opts.push(_el); } } return opts; }, /** * ## getSelectedValues * * returns the values of the currently selected data * * @return {Void} void */ getSelectedValues: function getSelectedValues() { return this.getSelected().map(function (_v) { return _v.value; }); }, /** * ## loadDataFromUrl * * loads data from a passed url * * @param {String} url address to get the data from * @param {Function} callback function to run after getting the data * * @return {Void} void */ loadDataFromUrl: function loadDataFromUrl(url, callback) { var _this3 = this; var classes = this.classes; _utils2.default.http.get(url).then(function (data) { if (data) { _this3.data = JSON.parse(data); if (callback) { callback(_this3.data); } } else { console.warn('no data recieved'); } }).catch(function (e) { console.warn('something happened: ', e); _this3.rebuild([{ text: '', value: '', index: 0, extraClass: classes.LOADING_FAILED }]); }); return [{ text: '', value: '', index: 0, extraClass: classes.LOADING }]; }, /** * ## rebuild * * after editing the data, this can be used to rebuild them * * @param {Array} data array with option information * @param {Object} props options object * * @return {Object} rebuilt flounder object */ rebuild: function rebuild(data, props) { if (props || !props && (typeof data === 'string' || data && typeof data.length !== 'number')) { return this.reconfigure(data, props); } data = this.data = data || this.data; props = this.props; var refs = this.refs; var select = refs.select; this.deselectAll(); this.removeOptionsListeners(); refs.select.innerHTML = ''; refs.select = false; this.defaultObj = (0, _defaults.setDefaultOption)(this, props, data, true); refs.optionsList.innerHTML = ''; if (refs.noMoreOptionsEl || _typeof(refs.noMoreOptionsEl) === undefined) { delete refs.noMoreOptionsEl; } if (refs.noResultsEl || _typeof(refs.noResultsEl) === undefine