You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
10495 lines
320 KiB
10495 lines
320 KiB
/*! 1.19.0 | © Algolia | github.com/algolia/places */
|
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
module.exports = factory();
|
|
else if(typeof define === 'function' && define.amd)
|
|
define([], factory);
|
|
else if(typeof exports === 'object')
|
|
exports["placesInstantsearchWidget"] = factory();
|
|
else
|
|
root["placesInstantsearchWidget"] = factory();
|
|
})(window, function() {
|
|
return /******/ (function(modules) { // webpackBootstrap
|
|
/******/ // The module cache
|
|
/******/ var installedModules = {};
|
|
/******/
|
|
/******/ // The require function
|
|
/******/ function __webpack_require__(moduleId) {
|
|
/******/
|
|
/******/ // Check if module is in cache
|
|
/******/ if(installedModules[moduleId]) {
|
|
/******/ return installedModules[moduleId].exports;
|
|
/******/ }
|
|
/******/ // Create a new module (and put it into the cache)
|
|
/******/ var module = installedModules[moduleId] = {
|
|
/******/ i: moduleId,
|
|
/******/ l: false,
|
|
/******/ exports: {}
|
|
/******/ };
|
|
/******/
|
|
/******/ // Execute the module function
|
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
/******/
|
|
/******/ // Flag the module as loaded
|
|
/******/ module.l = true;
|
|
/******/
|
|
/******/ // Return the exports of the module
|
|
/******/ return module.exports;
|
|
/******/ }
|
|
/******/
|
|
/******/
|
|
/******/ // expose the modules object (__webpack_modules__)
|
|
/******/ __webpack_require__.m = modules;
|
|
/******/
|
|
/******/ // expose the module cache
|
|
/******/ __webpack_require__.c = installedModules;
|
|
/******/
|
|
/******/ // define getter function for harmony exports
|
|
/******/ __webpack_require__.d = function(exports, name, getter) {
|
|
/******/ if(!__webpack_require__.o(exports, name)) {
|
|
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
|
/******/ }
|
|
/******/ };
|
|
/******/
|
|
/******/ // define __esModule on exports
|
|
/******/ __webpack_require__.r = function(exports) {
|
|
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
|
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
/******/ }
|
|
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
|
/******/ };
|
|
/******/
|
|
/******/ // create a fake namespace object
|
|
/******/ // mode & 1: value is a module id, require it
|
|
/******/ // mode & 2: merge all properties of value into the ns
|
|
/******/ // mode & 4: return value when already ns object
|
|
/******/ // mode & 8|1: behave like require
|
|
/******/ __webpack_require__.t = function(value, mode) {
|
|
/******/ if(mode & 1) value = __webpack_require__(value);
|
|
/******/ if(mode & 8) return value;
|
|
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
|
/******/ var ns = Object.create(null);
|
|
/******/ __webpack_require__.r(ns);
|
|
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
|
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
|
/******/ return ns;
|
|
/******/ };
|
|
/******/
|
|
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
|
/******/ __webpack_require__.n = function(module) {
|
|
/******/ var getter = module && module.__esModule ?
|
|
/******/ function getDefault() { return module['default']; } :
|
|
/******/ function getModuleExports() { return module; };
|
|
/******/ __webpack_require__.d(getter, 'a', getter);
|
|
/******/ return getter;
|
|
/******/ };
|
|
/******/
|
|
/******/ // Object.prototype.hasOwnProperty.call
|
|
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
|
/******/
|
|
/******/ // __webpack_public_path__
|
|
/******/ __webpack_require__.p = "";
|
|
/******/
|
|
/******/
|
|
/******/ // Load entry module and return exports
|
|
/******/ return __webpack_require__(__webpack_require__.s = 72);
|
|
/******/ })
|
|
/************************************************************************/
|
|
/******/ ([
|
|
/* 0 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var DOM = __webpack_require__(2);
|
|
|
|
function escapeRegExp(str) {
|
|
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
|
|
}
|
|
|
|
module.exports = {
|
|
// those methods are implemented differently
|
|
// depending on which build it is, using
|
|
// $... or angular... or Zepto... or require(...)
|
|
isArray: null,
|
|
isFunction: null,
|
|
isObject: null,
|
|
bind: null,
|
|
each: null,
|
|
map: null,
|
|
mixin: null,
|
|
|
|
isMsie: function(agentString) {
|
|
if (agentString === undefined) { agentString = navigator.userAgent; }
|
|
// from https://github.com/ded/bowser/blob/master/bowser.js
|
|
if ((/(msie|trident)/i).test(agentString)) {
|
|
var match = agentString.match(/(msie |rv:)(\d+(.\d+)?)/i);
|
|
if (match) { return match[2]; }
|
|
}
|
|
return false;
|
|
},
|
|
|
|
// http://stackoverflow.com/a/6969486
|
|
escapeRegExChars: function(str) {
|
|
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
|
|
},
|
|
|
|
isNumber: function(obj) { return typeof obj === 'number'; },
|
|
|
|
toStr: function toStr(s) {
|
|
return s === undefined || s === null ? '' : s + '';
|
|
},
|
|
|
|
cloneDeep: function cloneDeep(obj) {
|
|
var clone = this.mixin({}, obj);
|
|
var self = this;
|
|
this.each(clone, function(value, key) {
|
|
if (value) {
|
|
if (self.isArray(value)) {
|
|
clone[key] = [].concat(value);
|
|
} else if (self.isObject(value)) {
|
|
clone[key] = self.cloneDeep(value);
|
|
}
|
|
}
|
|
});
|
|
return clone;
|
|
},
|
|
|
|
error: function(msg) {
|
|
throw new Error(msg);
|
|
},
|
|
|
|
every: function(obj, test) {
|
|
var result = true;
|
|
if (!obj) {
|
|
return result;
|
|
}
|
|
this.each(obj, function(val, key) {
|
|
if (result) {
|
|
result = test.call(null, val, key, obj) && result;
|
|
}
|
|
});
|
|
return !!result;
|
|
},
|
|
|
|
any: function(obj, test) {
|
|
var found = false;
|
|
if (!obj) {
|
|
return found;
|
|
}
|
|
this.each(obj, function(val, key) {
|
|
if (test.call(null, val, key, obj)) {
|
|
found = true;
|
|
return false;
|
|
}
|
|
});
|
|
return found;
|
|
},
|
|
|
|
getUniqueId: (function() {
|
|
var counter = 0;
|
|
return function() { return counter++; };
|
|
})(),
|
|
|
|
templatify: function templatify(obj) {
|
|
if (this.isFunction(obj)) {
|
|
return obj;
|
|
}
|
|
var $template = DOM.element(obj);
|
|
if ($template.prop('tagName') === 'SCRIPT') {
|
|
return function template() { return $template.text(); };
|
|
}
|
|
return function template() { return String(obj); };
|
|
},
|
|
|
|
defer: function(fn) { setTimeout(fn, 0); },
|
|
|
|
noop: function() {},
|
|
|
|
formatPrefix: function(prefix, noPrefix) {
|
|
return noPrefix ? '' : prefix + '-';
|
|
},
|
|
|
|
className: function(prefix, clazz, skipDot) {
|
|
return (skipDot ? '' : '.') + prefix + clazz;
|
|
},
|
|
|
|
escapeHighlightedString: function(str, highlightPreTag, highlightPostTag) {
|
|
highlightPreTag = highlightPreTag || '<em>';
|
|
var pre = document.createElement('div');
|
|
pre.appendChild(document.createTextNode(highlightPreTag));
|
|
|
|
highlightPostTag = highlightPostTag || '</em>';
|
|
var post = document.createElement('div');
|
|
post.appendChild(document.createTextNode(highlightPostTag));
|
|
|
|
var div = document.createElement('div');
|
|
div.appendChild(document.createTextNode(str));
|
|
return div.innerHTML
|
|
.replace(RegExp(escapeRegExp(pre.innerHTML), 'g'), highlightPreTag)
|
|
.replace(RegExp(escapeRegExp(post.innerHTML), 'g'), highlightPostTag);
|
|
}
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 1 */
|
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
|
|
"use strict";
|
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
|
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
|
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
var extractParams = function extractParams(_ref) {
|
|
var hitsPerPage = _ref.hitsPerPage,
|
|
postcodeSearch = _ref.postcodeSearch,
|
|
aroundLatLng = _ref.aroundLatLng,
|
|
aroundRadius = _ref.aroundRadius,
|
|
aroundLatLngViaIP = _ref.aroundLatLngViaIP,
|
|
insideBoundingBox = _ref.insideBoundingBox,
|
|
insidePolygon = _ref.insidePolygon,
|
|
getRankingInfo = _ref.getRankingInfo,
|
|
countries = _ref.countries,
|
|
language = _ref.language,
|
|
type = _ref.type;
|
|
var extracted = {
|
|
countries: countries,
|
|
hitsPerPage: hitsPerPage || 5,
|
|
language: language || navigator.language.split('-')[0],
|
|
type: type
|
|
};
|
|
|
|
if (Array.isArray(countries)) {
|
|
extracted.countries = extracted.countries.map(function (country) {
|
|
return country.toLowerCase();
|
|
});
|
|
}
|
|
|
|
if (typeof extracted.language === 'string') {
|
|
extracted.language = extracted.language.toLowerCase();
|
|
}
|
|
|
|
if (aroundLatLng) {
|
|
extracted.aroundLatLng = aroundLatLng;
|
|
} else if (aroundLatLngViaIP !== undefined) {
|
|
extracted.aroundLatLngViaIP = aroundLatLngViaIP;
|
|
}
|
|
|
|
if (postcodeSearch) {
|
|
extracted.restrictSearchableAttributes = 'postcode';
|
|
}
|
|
|
|
return _objectSpread(_objectSpread({}, extracted), {}, {
|
|
aroundRadius: aroundRadius,
|
|
insideBoundingBox: insideBoundingBox,
|
|
insidePolygon: insidePolygon,
|
|
getRankingInfo: getRankingInfo
|
|
});
|
|
};
|
|
|
|
var extractControls = function extractControls(_ref2) {
|
|
var _ref2$useDeviceLocati = _ref2.useDeviceLocation,
|
|
useDeviceLocation = _ref2$useDeviceLocati === void 0 ? false : _ref2$useDeviceLocati,
|
|
_ref2$computeQueryPar = _ref2.computeQueryParams,
|
|
computeQueryParams = _ref2$computeQueryPar === void 0 ? function (params) {
|
|
return params;
|
|
} : _ref2$computeQueryPar,
|
|
formatInputValue = _ref2.formatInputValue,
|
|
_ref2$onHits = _ref2.onHits,
|
|
onHits = _ref2$onHits === void 0 ? function () {} : _ref2$onHits,
|
|
_ref2$onError = _ref2.onError,
|
|
onError = _ref2$onError === void 0 ? function (e) {
|
|
throw e;
|
|
} : _ref2$onError,
|
|
onRateLimitReached = _ref2.onRateLimitReached,
|
|
onInvalidCredentials = _ref2.onInvalidCredentials;
|
|
return {
|
|
useDeviceLocation: useDeviceLocation,
|
|
computeQueryParams: computeQueryParams,
|
|
formatInputValue: formatInputValue,
|
|
onHits: onHits,
|
|
onError: onError,
|
|
onRateLimitReached: onRateLimitReached,
|
|
onInvalidCredentials: onInvalidCredentials
|
|
};
|
|
};
|
|
|
|
var params = {};
|
|
var controls = {};
|
|
|
|
var configure = function configure(configuration) {
|
|
params = extractParams(_objectSpread(_objectSpread({}, params), configuration));
|
|
controls = extractControls(_objectSpread(_objectSpread({}, controls), configuration));
|
|
return {
|
|
params: params,
|
|
controls: controls
|
|
};
|
|
};
|
|
|
|
/* harmony default export */ __webpack_exports__["a"] = (configure);
|
|
|
|
/***/ }),
|
|
/* 2 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
module.exports = {
|
|
element: null
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 3 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
var hasOwn = Object.prototype.hasOwnProperty;
|
|
var toString = Object.prototype.toString;
|
|
|
|
module.exports = function forEach (obj, fn, ctx) {
|
|
if (toString.call(fn) !== '[object Function]') {
|
|
throw new TypeError('iterator must be a function');
|
|
}
|
|
var l = obj.length;
|
|
if (l === +l) {
|
|
for (var i = 0; i < l; i++) {
|
|
fn.call(ctx, obj[i], i, obj);
|
|
}
|
|
} else {
|
|
for (var k in obj) {
|
|
if (hasOwn.call(obj, k)) {
|
|
fn.call(ctx, obj[k], k, obj);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 4 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = function clone(obj) {
|
|
return JSON.parse(JSON.stringify(obj));
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 5 */
|
|
/***/ (function(module, exports) {
|
|
|
|
var g;
|
|
|
|
// This works in non-strict mode
|
|
g = (function() {
|
|
return this;
|
|
})();
|
|
|
|
try {
|
|
// This works if eval is allowed (see CSP)
|
|
g = g || new Function("return this")();
|
|
} catch (e) {
|
|
// This works if the window reference is available
|
|
if (typeof window === "object") g = window;
|
|
}
|
|
|
|
// g can still be undefined, but nothing to do about it...
|
|
// We return undefined, instead of nothing here, so it's
|
|
// easier to handle this case. if(!global) { ...}
|
|
|
|
module.exports = g;
|
|
|
|
|
|
/***/ }),
|
|
/* 6 */
|
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony default export */ __webpack_exports__["default"] = ('1.19.0');
|
|
|
|
/***/ }),
|
|
/* 7 */
|
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
|
|
"use strict";
|
|
/* harmony default export */ __webpack_exports__["a"] = ("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 14 20\"><path d=\"M7 0C3.13 0 0 3.13 0 7c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5C5.62 9.5 4.5 8.38 4.5 7S5.62 4.5 7 4.5 9.5 5.62 9.5 7 8.38 9.5 7 9.5z\"/></svg>\n");
|
|
|
|
/***/ }),
|
|
/* 8 */
|
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
// CONCATENATED MODULE: ./src/formatInputValue.js
|
|
function formatInputValue(_ref) {
|
|
var administrative = _ref.administrative,
|
|
city = _ref.city,
|
|
country = _ref.country,
|
|
name = _ref.name,
|
|
type = _ref.type;
|
|
var out = "".concat(name).concat(type !== 'country' && country !== undefined ? ',' : '', "\n ").concat(city ? "".concat(city, ",") : '', "\n ").concat(administrative ? "".concat(administrative, ",") : '', "\n ").concat(country ? country : '').replace(/\s*\n\s*/g, ' ').trim();
|
|
return out;
|
|
}
|
|
// EXTERNAL MODULE: ./src/icons/address.svg
|
|
var address = __webpack_require__(7);
|
|
|
|
// CONCATENATED MODULE: ./src/icons/city.svg
|
|
/* harmony default export */ var city = ("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 18 19\"><path d=\"M12 9V3L9 0 6 3v2H0v14h18V9h-6zm-8 8H2v-2h2v2zm0-4H2v-2h2v2zm0-4H2V7h2v2zm6 8H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V7h2v2zm0-4H8V3h2v2zm6 12h-2v-2h2v2zm0-4h-2v-2h2v2z\"/></svg>\n");
|
|
// CONCATENATED MODULE: ./src/icons/country.svg
|
|
/* harmony default export */ var country = ("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\">\n <path d=\"M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0zM9 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L7 13v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H6V8h2c.55 0 1-.45 1-1V5h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z\"/>\n</svg>\n");
|
|
// CONCATENATED MODULE: ./src/icons/bus.svg
|
|
/* harmony default export */ var bus = ("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 54.9 50.5\"><path d=\"M9.6 12.7H8.5c-2.3 0-4.1 1.9-4.1 4.1v1.1c0 2.2 1.8 4 4 4.1v21.7h-.7c-1.3 0-2.3 1-2.3 2.3h7.1c0-1.3-1-2.3-2.3-2.3h-.5V22.1c2.2-.1 4-1.9 4-4.1v-1.1c0-2.3-1.8-4.2-4.1-4.2zM46 7.6h-7.5c0-1.8-1.5-3.3-3.3-3.3h-3.6c-1.8 0-3.3 1.5-3.3 3.3H21c-2.5 0-4.6 2-4.6 4.6v26.3c0 1.7 1.3 3.1 3 3.1h.8v1.6c0 1.7 1.4 3.1 3.1 3.1 1.7 0 3-1.4 3-3.1v-1.6h14.3v1.6c0 1.7 1.4 3.1 3.1 3.1 1.7 0 3.1-1.4 3.1-3.1v-1.6h.8c1.7 0 3.1-1.4 3.1-3.1V12.2c-.2-2.5-2.2-4.6-4.7-4.6zm-27.4 4.6c0-1.3 1.1-2.4 2.4-2.4h25c1.3 0 2.4 1.1 2.4 2.4v.3c0 1.3-1.1 2.4-2.4 2.4H21c-1.3 0-2.4-1.1-2.4-2.4v-.3zM21 38c-1.5 0-2.7-1.2-2.7-2.7 0-1.5 1.2-2.7 2.7-2.7 1.5 0 2.7 1.2 2.7 2.7 0 1.5-1.2 2.7-2.7 2.7zm0-10.1c-1.3 0-2.4-1.1-2.4-2.4v-6.6c0-1.3 1.1-2.4 2.4-2.4h25c1.3 0 2.4 1.1 2.4 2.4v6.6c0 1.3-1.1 2.4-2.4 2.4H21zm24.8 10c-1.5 0-2.7-1.2-2.7-2.7 0-1.5 1.2-2.7 2.7-2.7 1.5 0 2.7 1.2 2.7 2.7 0 1.5-1.2 2.7-2.7 2.7z\"/></svg>\n");
|
|
// CONCATENATED MODULE: ./src/icons/train.svg
|
|
/* harmony default export */ var train = ("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 15 20\">\n <path d=\"M13.105 20l-2.366-3.354H4.26L1.907 20H0l3.297-4.787c-1.1-.177-2.196-1.287-2.194-2.642V2.68C1.1 1.28 2.317-.002 3.973 0h7.065c1.647-.002 2.863 1.28 2.86 2.676v9.895c.003 1.36-1.094 2.47-2.194 2.647L15 20h-1.895zM6.11 2h2.78c.264 0 .472-.123.472-.27v-.46c0-.147-.22-.268-.472-.27H6.11c-.252.002-.47.123-.47.27v.46c0 .146.206.27.47.27zm6.26 3.952V4.175c-.004-.74-.5-1.387-1.436-1.388H4.066c-.936 0-1.43.648-1.436 1.388v1.777c-.002.86.644 1.384 1.436 1.388h6.868c.793-.004 1.44-.528 1.436-1.388zm-8.465 5.386c-.69-.003-1.254.54-1.252 1.21-.002.673.56 1.217 1.252 1.222.697-.006 1.26-.55 1.262-1.22-.002-.672-.565-1.215-1.262-1.212zm8.42 1.21c-.005-.67-.567-1.213-1.265-1.21-.69-.003-1.253.54-1.25 1.21-.003.673.56 1.217 1.25 1.222.698-.006 1.26-.55 1.264-1.22z\"/>\n</svg>\n");
|
|
// CONCATENATED MODULE: ./src/icons/townhall.svg
|
|
/* harmony default export */ var townhall = ("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\"><path d=\"M12 .6L2.5 6.9h18.9L12 .6zM3.8 8.2c-.7 0-1.3.6-1.3 1.3v8.8L.3 22.1c-.2.3-.3.5-.3.6 0 .6.8.6 1.3.6h21.5c.4 0 1.3 0 1.3-.6 0-.2-.1-.3-.3-.6l-2.2-3.8V9.5c0-.7-.6-1.3-1.3-1.3H3.8zm2.5 2.5c.7 0 1.1.6 1.3 1.3v7.6H5.1V12c0-.7.5-1.3 1.2-1.3zm5.7 0c.7 0 1.3.6 1.3 1.3v7.6h-2.5V12c-.1-.7.5-1.3 1.2-1.3zm5.7 0c.7 0 1.3.6 1.3 1.3v7.6h-2.5V12c-.1-.7.5-1.3 1.2-1.3z\"/></svg>\n");
|
|
// CONCATENATED MODULE: ./src/icons/plane.svg
|
|
/* harmony default export */ var plane = ("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\"><path d=\"M22.9 1.1s1.3.3-4.3 6.5l.7 3.8.2-.2c.4-.4 1-.4 1.3 0 .4.4.4 1 0 1.3l-1.2 1.2.3 1.7.1-.1c.4-.4 1-.4 1.3 0 .4.4.4 1 0 1.3l-1.1 1.1c.2 1.9.3 3.6.1 4.5 0 0-1.2 1.2-1.8.5 0 0-2.3-7.7-3.8-11.1-5.9 6-6.4 5.6-6.4 5.6s1.2 3.8-.2 5.2l-2.3-4.3h.1l-4.3-2.3c1.3-1.3 5.2-.2 5.2-.2s-.5-.4 5.6-6.3C8.9 7.7 1.2 5.5 1.2 5.5c-.7-.7.5-1.8.5-1.8.9-.2 2.6-.1 4.5.1l1.1-1.1c.4-.4 1-.4 1.3 0 .4.4.4 1 0 1.3l1.7.3 1.2-1.2c.4-.4 1-.4 1.3 0 .4.4.4 1 0 1.3l-.2.2 3.8.7c6.2-5.5 6.5-4.2 6.5-4.2z\"/></svg>\n");
|
|
// CONCATENATED MODULE: ./src/formatDropdownValue.js
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var icons = {
|
|
address: address["a" /* default */],
|
|
city: city,
|
|
country: country,
|
|
busStop: bus,
|
|
trainStation: train,
|
|
townhall: townhall,
|
|
airport: plane
|
|
};
|
|
function formatDropdownValue(_ref) {
|
|
var type = _ref.type,
|
|
highlight = _ref.highlight;
|
|
var name = highlight.name,
|
|
administrative = highlight.administrative,
|
|
city = highlight.city,
|
|
country = highlight.country;
|
|
var out = "<span class=\"ap-suggestion-icon\">".concat(icons[type].trim(), "</span>\n<span class=\"ap-name\">").concat(name, "</span>\n<span class=\"ap-address\">\n ").concat([city, administrative, country].filter(function (token) {
|
|
return token !== undefined;
|
|
}).join(', '), "</span>").replace(/\s*\n\s*/g, ' ');
|
|
return out;
|
|
}
|
|
// CONCATENATED MODULE: ./src/icons/algolia.svg
|
|
/* harmony default export */ var algolia = ("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"117\" height=\"17\" viewBox=\"0 0 130 19\"><g fill=\"none\" fill-rule=\"evenodd\"><g fill-rule=\"nonzero\"><path fill=\"#5468FF\" d=\"M59.399.044h13.299a2.372 2.372 0 0 1 2.377 2.364v13.234a2.372 2.372 0 0 1-2.377 2.364H59.399a2.372 2.372 0 0 1-2.377-2.364V2.403A2.368 2.368 0 0 1 59.399.044z\"/><path fill=\"#FFF\" d=\"M66.257 4.582c-2.815 0-5.1 2.272-5.1 5.078 0 2.806 2.284 5.072 5.1 5.072 2.815 0 5.1-2.272 5.1-5.078 0-2.806-2.279-5.072-5.1-5.072zm0 8.652c-1.983 0-3.593-1.602-3.593-3.574 0-1.972 1.61-3.574 3.593-3.574 1.983 0 3.593 1.602 3.593 3.574a3.582 3.582 0 0 1-3.593 3.574zm0-6.418V9.48c0 .076.082.131.153.093l2.377-1.226c.055-.027.071-.093.044-.147a2.96 2.96 0 0 0-2.465-1.487c-.055 0-.11.044-.11.104h.001zm-3.33-1.956l-.312-.31a.783.783 0 0 0-1.106 0l-.372.37a.773.773 0 0 0 0 1.1l.307.305c.049.05.121.038.164-.01.181-.246.378-.48.597-.698.225-.223.455-.42.707-.599.055-.033.06-.109.016-.158h-.001zm5.001-.806v-.616a.781.781 0 0 0-.783-.779h-1.824a.78.78 0 0 0-.783.78v.631c0 .071.066.12.137.104a5.736 5.736 0 0 1 1.588-.223c.52 0 1.035.071 1.534.207a.106.106 0 0 0 .131-.104z\"/><path fill=\"#252C61\" d=\"M5.027 10.246c0 .698-.252 1.246-.757 1.644-.505.397-1.201.596-2.089.596-.888 0-1.615-.138-2.181-.414v-1.214c.358.168.739.301 1.141.397.403.097.778.145 1.125.145.508 0 .884-.097 1.125-.29a.945.945 0 0 0 .363-.779.978.978 0 0 0-.333-.747c-.222-.204-.68-.446-1.375-.725C1.33 8.57.825 8.24.531 7.865c-.294-.372-.44-.82-.44-1.343 0-.655.233-1.17.698-1.547.465-.376 1.09-.564 1.875-.564.752 0 1.5.165 2.245.494l-.408 1.047c-.698-.294-1.321-.44-1.869-.44-.415 0-.73.09-.945.271a.89.89 0 0 0-.322.717c0 .204.043.38.129.524.086.145.227.282.424.411.197.13.551.3 1.063.51.577.24.999.464 1.268.671.269.208.465.442.591.704.125.261.188.57.188.924l-.001.002zm3.98 2.24c-.924 0-1.646-.269-2.167-.808-.521-.539-.781-1.28-.781-2.226 0-.97.242-1.733.725-2.288.483-.555 1.148-.833 1.993-.833.784 0 1.404.238 1.858.714.455.476.682 1.132.682 1.966v.682H7.359c.018.577.174 1.02.467 1.33.294.31.707.464 1.241.464.351 0 .678-.033.98-.099a5.1 5.1 0 0 0 .975-.33v1.026a3.865 3.865 0 0 1-.935.312 5.723 5.723 0 0 1-1.08.091zm7.46-.107l-.252-.827h-.043c-.286.362-.575.608-.865.74-.29.13-.662.195-1.117.195-.584 0-1.039-.158-1.367-.473-.328-.315-.491-.76-.491-1.337 0-.612.227-1.074.682-1.386.455-.312 1.148-.482 2.079-.51l1.026-.032v-.317c0-.38-.089-.663-.266-.85-.177-.189-.452-.283-.824-.283-.304 0-.596.045-.875.134a6.68 6.68 0 0 0-.806.317l-.408-.902a4.414 4.414 0 0 1 1.058-.384 4.856 4.856 0 0 1 1.085-.132c.756 0 1.326.165 1.711.494.385.33.577.847.577 1.552v4.001h-.904zm5.677-6.048c.254 0 .464.018.628.054l-.124 1.176a2.383 2.383 0 0 0-.559-.064c-.505 0-.914.165-1.227.494-.313.33-.47.757-.47 1.284v3.104H19.13V6.44h.988l.167 1.047h.064c.197-.354.454-.636.771-.843a1.83 1.83 0 0 1 1.023-.312h.001zm4.125 6.155c-.899 0-1.582-.262-2.049-.787-.467-.525-.701-1.277-.701-2.259 0-.999.244-1.767.733-2.304.489-.537 1.195-.806 2.119-.806.627 0 1.191.116 1.692.35l-.381 1.014c-.534-.208-.974-.312-1.321-.312-1.028 0-1.542.682-1.542 2.046 0 .666.128 1.166.384 1.501.256.335.631.502 1.125.502a3.23 3.23 0 0 0 1.595-.419v1.101a2.53 2.53 0 0 1-.722.285 4.356 4.356 0 0 1-.932.086v.002zm8.277-.107h-1.268V8.727c0-.458-.092-.8-.277-1.026-.184-.226-.477-.338-.878-.338-.53 0-.919.158-1.168.475-.249.317-.373.848-.373 1.593v2.95H29.32V4.022h1.262v2.122c0 .34-.021.704-.064 1.09h.081a1.76 1.76 0 0 1 .717-.666c.306-.158.663-.236 1.072-.236 1.439 0 2.159.725 2.159 2.175v3.873l-.001-.002zm7.648-6.048c.741 0 1.319.27 1.732.806.414.537.62 1.291.62 2.261 0 .974-.209 1.732-.628 2.275-.419.542-1.001.814-1.746.814-.752 0-1.336-.27-1.751-.81h-.086l-.231.703h-.945V4.023h1.262V6.01l-.021.655-.032.553h.054c.401-.59.992-.886 1.772-.886zm2.917.107h1.375l1.208 3.368c.183.48.304.931.365 1.354h.043c.032-.197.091-.436.177-.717.086-.28.541-1.616 1.364-4.004h1.364l-2.541 6.73c-.462 1.235-1.232 1.853-2.31 1.853-.279 0-.551-.03-.816-.09v-1c.19.043.406.064.65.064.609 0 1.037-.353 1.284-1.058l.22-.559-2.385-5.94h.002zm-3.244.924c-.508 0-.875.15-1.098.448-.224.3-.339.8-.346 1.501v.086c0 .723.115 1.247.344 1.571.229.324.603.486 1.123.486.448 0 .787-.177 1.018-.532.231-.354.346-.867.346-1.536 0-1.35-.462-2.025-1.386-2.025l-.001.001zm-27.28 4.157c.458 0 .826-.128 1.104-.384.278-.256.416-.615.416-1.077v-.516l-.763.032c-.594.021-1.027.121-1.297.298s-.406.448-.406.814c0 .265.079.47.236.615.158.145.394.218.709.218h.001zM8.775 7.287c-.401 0-.722.127-.964.381s-.386.625-.432 1.112h2.696c-.007-.49-.125-.862-.354-1.115-.229-.252-.544-.379-.945-.379l-.001.001z\"/></g><path fill=\"#5468FF\" d=\"M102.162 13.784c0 1.455-.372 2.517-1.123 3.193-.75.676-1.895 1.013-3.44 1.013-.564 0-1.736-.109-2.673-.316l.345-1.689c.783.163 1.819.207 2.361.207.86 0 1.473-.174 1.84-.523.367-.349.548-.866.548-1.553v-.349a6.374 6.374 0 0 1-.838.316 4.151 4.151 0 0 1-1.194.158 4.515 4.515 0 0 1-1.616-.278 3.385 3.385 0 0 1-1.254-.817 3.744 3.744 0 0 1-.811-1.35c-.192-.54-.29-1.505-.29-2.213 0-.665.104-1.498.307-2.054a3.925 3.925 0 0 1 .904-1.433 4.124 4.124 0 0 1 1.441-.926 5.31 5.31 0 0 1 1.945-.365c.696 0 1.337.087 1.961.191a15.86 15.86 0 0 1 1.588.332v8.456h-.001zm-5.955-4.206c0 .893.197 1.885.592 2.3.394.413.904.62 1.528.62.34 0 .663-.049.964-.142a2.75 2.75 0 0 0 .734-.332v-5.29a8.531 8.531 0 0 0-1.413-.18c-.778-.022-1.369.294-1.786.801-.411.507-.619 1.395-.619 2.223zm16.121 0c0 .72-.104 1.264-.318 1.858a4.389 4.389 0 0 1-.904 1.52c-.389.42-.854.746-1.402.975-.548.23-1.391.36-1.813.36-.422-.005-1.26-.125-1.802-.36a4.088 4.088 0 0 1-1.397-.975 4.486 4.486 0 0 1-.909-1.52 5.037 5.037 0 0 1-.329-1.858c0-.719.099-1.41.318-1.999.219-.588.526-1.09.92-1.509.394-.42.865-.74 1.402-.97a4.547 4.547 0 0 1 1.786-.338 4.69 4.69 0 0 1 1.791.338c.548.23 1.019.55 1.402.97.389.42.69.921.909 1.51.23.587.345 1.28.345 1.998h.001zm-2.192.005c0-.92-.203-1.689-.597-2.223-.394-.539-.948-.806-1.654-.806-.707 0-1.26.267-1.654.806-.394.54-.586 1.302-.586 2.223 0 .932.197 1.558.592 2.098.394.545.948.812 1.654.812.707 0 1.26-.272 1.654-.812.394-.545.592-1.166.592-2.098h-.001zm6.963 4.708c-3.511.016-3.511-2.822-3.511-3.274L113.583.95l2.142-.338v10.003c0 .256 0 1.88 1.375 1.885v1.793h-.001zM120.873 14.291h-2.153V5.095l2.153-.338zM119.794 3.75c.718 0 1.304-.579 1.304-1.292 0-.714-.581-1.29-1.304-1.29-.723 0-1.304.577-1.304 1.29 0 .714.586 1.291 1.304 1.291zm6.431 1.012c.707 0 1.304.087 1.786.262.482.174.871.42 1.156.73.285.311.488.735.608 1.182.126.447.186.937.186 1.476v5.481a25.24 25.24 0 0 1-1.495.251c-.668.098-1.419.147-2.251.147a6.829 6.829 0 0 1-1.517-.158 3.213 3.213 0 0 1-1.178-.507 2.455 2.455 0 0 1-.761-.904c-.181-.37-.274-.893-.274-1.438 0-.523.104-.855.307-1.215.208-.36.487-.654.838-.883a3.609 3.609 0 0 1 1.227-.49 7.073 7.073 0 0 1 2.202-.103c.263.027.537.076.833.147v-.349c0-.245-.027-.479-.088-.697a1.486 1.486 0 0 0-.307-.583c-.148-.169-.34-.3-.581-.392a2.536 2.536 0 0 0-.915-.163c-.493 0-.942.06-1.353.131-.411.071-.75.153-1.008.245l-.257-1.749c.268-.093.668-.185 1.183-.278a9.335 9.335 0 0 1 1.66-.142h-.001zm.179 7.73c.657 0 1.145-.038 1.484-.104V10.22a5.097 5.097 0 0 0-1.978-.104c-.241.033-.46.098-.652.191a1.167 1.167 0 0 0-.466.392c-.121.17-.175.267-.175.523 0 .501.175.79.493.981.323.196.75.29 1.293.29h.001zM84.108 4.816c.707 0 1.304.087 1.786.262.482.174.871.42 1.156.73.29.316.487.735.608 1.182.126.447.186.937.186 1.476v5.481a25.24 25.24 0 0 1-1.495.251c-.668.098-1.419.147-2.251.147a6.829 6.829 0 0 1-1.517-.158 3.213 3.213 0 0 1-1.178-.507 2.455 2.455 0 0 1-.761-.904c-.181-.37-.274-.893-.274-1.438 0-.523.104-.855.307-1.215.208-.36.487-.654.838-.883a3.609 3.609 0 0 1 1.227-.49 7.073 7.073 0 0 1 2.202-.103c.257.027.537.076.833.147v-.349c0-.245-.027-.479-.088-.697a1.486 1.486 0 0 0-.307-.583c-.148-.169-.34-.3-.581-.392a2.536 2.536 0 0 0-.915-.163c-.493 0-.942.06-1.353.131-.411.071-.75.153-1.008.245l-.257-1.749c.268-.093.668-.185 1.183-.278a8.89 8.89 0 0 1 1.66-.142h-.001zm.185 7.736c.657 0 1.145-.038 1.484-.104V10.28a5.097 5.097 0 0 0-1.978-.104c-.241.033-.46.098-.652.191a1.167 1.167 0 0 0-.466.392c-.121.17-.175.267-.175.523 0 .501.175.79.493.981.318.191.75.29 1.293.29h.001zm8.683 1.738c-3.511.016-3.511-2.822-3.511-3.274L89.46.948 91.602.61v10.003c0 .256 0 1.88 1.375 1.885v1.793h-.001z\"/></g></svg>");
|
|
// CONCATENATED MODULE: ./src/icons/osm.svg
|
|
/* harmony default export */ var osm = ("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\">\n <path fill=\"#797979\" fill-rule=\"evenodd\" d=\"M6.577.5L5.304.005 2.627 1.02 0 0l.992 2.767-.986 2.685.998 2.76-1 2.717.613.22 3.39-3.45.563.06.726-.69s-.717-.92-.91-1.86c.193-.146.184-.14.355-.285C4.1 1.93 6.58.5 6.58.5zm-4.17 11.354l.22.12 2.68-1.05 2.62 1.04 2.644-1.03 1.02-2.717-.33-.944s-1.13 1.26-3.44.878c-.174.29-.25.37-.25.37s-1.11-.31-1.683-.89c-.573.58-.795.71-.795.71l.08.634-2.76 2.89zm6.26-4.395c1.817 0 3.29-1.53 3.29-3.4 0-1.88-1.473-3.4-3.29-3.4s-3.29 1.52-3.29 3.4c0 1.87 1.473 3.4 3.29 3.4z\"/>\n</svg>\n");
|
|
// CONCATENATED MODULE: ./src/defaultTemplates.js
|
|
|
|
|
|
|
|
|
|
/* harmony default export */ var defaultTemplates = __webpack_exports__["a"] = ({
|
|
footer: "<div class=\"ap-footer\">\n <a href=\"https://www.algolia.com/places\" title=\"Search by Algolia\" class=\"ap-footer-algolia\">".concat(algolia.trim(), "</a>\n using <a href=\"https://community.algolia.com/places/documentation.html#license\" class=\"ap-footer-osm\" title=\"Algolia Places data \xA9 OpenStreetMap contributors\">").concat(osm.trim(), " <span>data</span></a>\n </div>"),
|
|
value: formatInputValue,
|
|
suggestion: formatDropdownValue
|
|
});
|
|
|
|
/***/ }),
|
|
/* 9 */
|
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
// EXPORTS
|
|
__webpack_require__.d(__webpack_exports__, "a", function() { return /* binding */ formatHit; });
|
|
|
|
// CONCATENATED MODULE: ./src/findCountryCode.js
|
|
function findCountryCode(tags) {
|
|
for (var tagIndex = 0; tagIndex < tags.length; tagIndex++) {
|
|
var tag = tags[tagIndex];
|
|
var find = tag.match(/country\/(.*)?/);
|
|
|
|
if (find) {
|
|
return find[1];
|
|
}
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
// CONCATENATED MODULE: ./src/findType.js
|
|
function findType(tags) {
|
|
var types = {
|
|
country: 'country',
|
|
city: 'city',
|
|
'amenity/bus_station': 'busStop',
|
|
'amenity/townhall': 'townhall',
|
|
'railway/station': 'trainStation',
|
|
'aeroway/aerodrome': 'airport',
|
|
'aeroway/terminal': 'airport',
|
|
'aeroway/gate': 'airport'
|
|
};
|
|
|
|
for (var t in types) {
|
|
if (tags.indexOf(t) !== -1) {
|
|
return types[t];
|
|
}
|
|
}
|
|
|
|
return 'address';
|
|
}
|
|
// CONCATENATED MODULE: ./src/formatHit.js
|
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
|
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
|
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
|
|
|
|
|
|
function getBestHighlightedForm(highlightedValues) {
|
|
var defaultValue = highlightedValues[0].value; // collect all other matches
|
|
|
|
var bestAttributes = [];
|
|
|
|
for (var i = 1; i < highlightedValues.length; ++i) {
|
|
if (highlightedValues[i].matchLevel !== 'none') {
|
|
bestAttributes.push({
|
|
index: i,
|
|
words: highlightedValues[i].matchedWords
|
|
});
|
|
}
|
|
} // no matches in this attribute, retrieve first value
|
|
|
|
|
|
if (bestAttributes.length === 0) {
|
|
return defaultValue;
|
|
} // sort the matches by `desc(words), asc(index)`
|
|
|
|
|
|
bestAttributes.sort(function (a, b) {
|
|
if (a.words > b.words) {
|
|
return -1;
|
|
} else if (a.words < b.words) {
|
|
return 1;
|
|
}
|
|
|
|
return a.index - b.index;
|
|
}); // and append the best match to the first value
|
|
|
|
return bestAttributes[0].index === 0 ? "".concat(defaultValue, " (").concat(highlightedValues[bestAttributes[1].index].value, ")") : "".concat(highlightedValues[bestAttributes[0].index].value, " (").concat(defaultValue, ")");
|
|
}
|
|
|
|
function getBestPostcode(postcodes, highlightedPostcodes) {
|
|
var defaultValue = highlightedPostcodes[0].value; // collect all other matches
|
|
|
|
var bestAttributes = [];
|
|
|
|
for (var i = 1; i < highlightedPostcodes.length; ++i) {
|
|
if (highlightedPostcodes[i].matchLevel !== 'none') {
|
|
bestAttributes.push({
|
|
index: i,
|
|
words: highlightedPostcodes[i].matchedWords
|
|
});
|
|
}
|
|
} // no matches in this attribute, retrieve first value
|
|
|
|
|
|
if (bestAttributes.length === 0) {
|
|
return {
|
|
postcode: postcodes[0],
|
|
highlightedPostcode: defaultValue
|
|
};
|
|
} // sort the matches by `desc(words)`
|
|
|
|
|
|
bestAttributes.sort(function (a, b) {
|
|
if (a.words > b.words) {
|
|
return -1;
|
|
} else if (a.words < b.words) {
|
|
return 1;
|
|
}
|
|
|
|
return a.index - b.index;
|
|
});
|
|
var postcode = postcodes[bestAttributes[0].index];
|
|
return {
|
|
postcode: postcode,
|
|
highlightedPostcode: highlightedPostcodes[bestAttributes[0].index].value
|
|
};
|
|
}
|
|
|
|
function formatHit(_ref) {
|
|
var formatInputValue = _ref.formatInputValue,
|
|
hit = _ref.hit,
|
|
hitIndex = _ref.hitIndex,
|
|
query = _ref.query,
|
|
rawAnswer = _ref.rawAnswer;
|
|
|
|
try {
|
|
var name = hit.locale_names[0];
|
|
var country = hit.country;
|
|
var administrative = hit.administrative && hit.administrative[0] !== name ? hit.administrative[0] : undefined;
|
|
var city = hit.city && hit.city[0] !== name ? hit.city[0] : undefined;
|
|
var suburb = hit.suburb && hit.suburb[0] !== name ? hit.suburb[0] : undefined;
|
|
var county = hit.county && hit.county[0] !== name ? hit.county[0] : undefined;
|
|
|
|
var _ref2 = hit.postcode && hit.postcode.length ? getBestPostcode(hit.postcode, hit._highlightResult.postcode) : {
|
|
postcode: undefined,
|
|
highlightedPostcode: undefined
|
|
},
|
|
postcode = _ref2.postcode,
|
|
highlightedPostcode = _ref2.highlightedPostcode;
|
|
|
|
var highlight = {
|
|
name: getBestHighlightedForm(hit._highlightResult.locale_names),
|
|
city: city ? getBestHighlightedForm(hit._highlightResult.city) : undefined,
|
|
administrative: administrative ? getBestHighlightedForm(hit._highlightResult.administrative) : undefined,
|
|
country: country ? hit._highlightResult.country.value : undefined,
|
|
suburb: suburb ? getBestHighlightedForm(hit._highlightResult.suburb) : undefined,
|
|
county: county ? getBestHighlightedForm(hit._highlightResult.county) : undefined,
|
|
postcode: highlightedPostcode
|
|
};
|
|
var suggestion = {
|
|
name: name,
|
|
administrative: administrative,
|
|
county: county,
|
|
city: city,
|
|
suburb: suburb,
|
|
country: country,
|
|
countryCode: findCountryCode(hit._tags),
|
|
type: findType(hit._tags),
|
|
latlng: {
|
|
lat: hit._geoloc.lat,
|
|
lng: hit._geoloc.lng
|
|
},
|
|
postcode: postcode,
|
|
postcodes: hit.postcode && hit.postcode.length ? hit.postcode : undefined
|
|
}; // this is the value to put inside the <input value=
|
|
|
|
var value = formatInputValue(suggestion);
|
|
return _objectSpread(_objectSpread({}, suggestion), {}, {
|
|
highlight: highlight,
|
|
hit: hit,
|
|
hitIndex: hitIndex,
|
|
query: query,
|
|
rawAnswer: rawAnswer,
|
|
value: value
|
|
});
|
|
} catch (e) {
|
|
/* eslint-disable no-console */
|
|
console.error('Could not parse object', hit);
|
|
console.error(e);
|
|
/* eslint-enable no-console */
|
|
|
|
return {
|
|
value: 'Could not parse object'
|
|
};
|
|
}
|
|
}
|
|
|
|
/***/ }),
|
|
/* 10 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// shim for using process in browser
|
|
var process = module.exports = {};
|
|
|
|
// cached from whatever global is present so that test runners that stub it
|
|
// don't break things. But we need to wrap it in a try catch in case it is
|
|
// wrapped in strict mode code which doesn't define any globals. It's inside a
|
|
// function because try/catches deoptimize in certain engines.
|
|
|
|
var cachedSetTimeout;
|
|
var cachedClearTimeout;
|
|
|
|
function defaultSetTimout() {
|
|
throw new Error('setTimeout has not been defined');
|
|
}
|
|
function defaultClearTimeout () {
|
|
throw new Error('clearTimeout has not been defined');
|
|
}
|
|
(function () {
|
|
try {
|
|
if (typeof setTimeout === 'function') {
|
|
cachedSetTimeout = setTimeout;
|
|
} else {
|
|
cachedSetTimeout = defaultSetTimout;
|
|
}
|
|
} catch (e) {
|
|
cachedSetTimeout = defaultSetTimout;
|
|
}
|
|
try {
|
|
if (typeof clearTimeout === 'function') {
|
|
cachedClearTimeout = clearTimeout;
|
|
} else {
|
|
cachedClearTimeout = defaultClearTimeout;
|
|
}
|
|
} catch (e) {
|
|
cachedClearTimeout = defaultClearTimeout;
|
|
}
|
|
} ())
|
|
function runTimeout(fun) {
|
|
if (cachedSetTimeout === setTimeout) {
|
|
//normal enviroments in sane situations
|
|
return setTimeout(fun, 0);
|
|
}
|
|
// if setTimeout wasn't available but was latter defined
|
|
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
|
|
cachedSetTimeout = setTimeout;
|
|
return setTimeout(fun, 0);
|
|
}
|
|
try {
|
|
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|
return cachedSetTimeout(fun, 0);
|
|
} catch(e){
|
|
try {
|
|
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|
return cachedSetTimeout.call(null, fun, 0);
|
|
} catch(e){
|
|
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
|
|
return cachedSetTimeout.call(this, fun, 0);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
function runClearTimeout(marker) {
|
|
if (cachedClearTimeout === clearTimeout) {
|
|
//normal enviroments in sane situations
|
|
return clearTimeout(marker);
|
|
}
|
|
// if clearTimeout wasn't available but was latter defined
|
|
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
|
|
cachedClearTimeout = clearTimeout;
|
|
return clearTimeout(marker);
|
|
}
|
|
try {
|
|
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|
return cachedClearTimeout(marker);
|
|
} catch (e){
|
|
try {
|
|
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|
return cachedClearTimeout.call(null, marker);
|
|
} catch (e){
|
|
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
|
|
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
|
|
return cachedClearTimeout.call(this, marker);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
var queue = [];
|
|
var draining = false;
|
|
var currentQueue;
|
|
var queueIndex = -1;
|
|
|
|
function cleanUpNextTick() {
|
|
if (!draining || !currentQueue) {
|
|
return;
|
|
}
|
|
draining = false;
|
|
if (currentQueue.length) {
|
|
queue = currentQueue.concat(queue);
|
|
} else {
|
|
queueIndex = -1;
|
|
}
|
|
if (queue.length) {
|
|
drainQueue();
|
|
}
|
|
}
|
|
|
|
function drainQueue() {
|
|
if (draining) {
|
|
return;
|
|
}
|
|
var timeout = runTimeout(cleanUpNextTick);
|
|
draining = true;
|
|
|
|
var len = queue.length;
|
|
while(len) {
|
|
currentQueue = queue;
|
|
queue = [];
|
|
while (++queueIndex < len) {
|
|
if (currentQueue) {
|
|
currentQueue[queueIndex].run();
|
|
}
|
|
}
|
|
queueIndex = -1;
|
|
len = queue.length;
|
|
}
|
|
currentQueue = null;
|
|
draining = false;
|
|
runClearTimeout(timeout);
|
|
}
|
|
|
|
process.nextTick = function (fun) {
|
|
var args = new Array(arguments.length - 1);
|
|
if (arguments.length > 1) {
|
|
for (var i = 1; i < arguments.length; i++) {
|
|
args[i - 1] = arguments[i];
|
|
}
|
|
}
|
|
queue.push(new Item(fun, args));
|
|
if (queue.length === 1 && !draining) {
|
|
runTimeout(drainQueue);
|
|
}
|
|
};
|
|
|
|
// v8 likes predictible objects
|
|
function Item(fun, array) {
|
|
this.fun = fun;
|
|
this.array = array;
|
|
}
|
|
Item.prototype.run = function () {
|
|
this.fun.apply(null, this.array);
|
|
};
|
|
process.title = 'browser';
|
|
process.browser = true;
|
|
process.env = {};
|
|
process.argv = [];
|
|
process.version = ''; // empty string to avoid regexp issues
|
|
process.versions = {};
|
|
|
|
function noop() {}
|
|
|
|
process.on = noop;
|
|
process.addListener = noop;
|
|
process.once = noop;
|
|
process.off = noop;
|
|
process.removeListener = noop;
|
|
process.removeAllListeners = noop;
|
|
process.emit = noop;
|
|
process.prependListener = noop;
|
|
process.prependOnceListener = noop;
|
|
|
|
process.listeners = function (name) { return [] }
|
|
|
|
process.binding = function (name) {
|
|
throw new Error('process.binding is not supported');
|
|
};
|
|
|
|
process.cwd = function () { return '/' };
|
|
process.chdir = function (dir) {
|
|
throw new Error('process.chdir is not supported');
|
|
};
|
|
process.umask = function() { return 0; };
|
|
|
|
|
|
/***/ }),
|
|
/* 11 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
// This file hosts our error definitions
|
|
// We use custom error "types" so that we can act on them when we need it
|
|
// e.g.: if error instanceof errors.UnparsableJSON then..
|
|
|
|
var inherits = __webpack_require__(21);
|
|
|
|
function AlgoliaSearchError(message, extraProperties) {
|
|
var forEach = __webpack_require__(3);
|
|
|
|
var error = this;
|
|
|
|
// try to get a stacktrace
|
|
if (typeof Error.captureStackTrace === 'function') {
|
|
Error.captureStackTrace(this, this.constructor);
|
|
} else {
|
|
error.stack = (new Error()).stack || 'Cannot get a stacktrace, browser is too old';
|
|
}
|
|
|
|
this.name = 'AlgoliaSearchError';
|
|
this.message = message || 'Unknown error';
|
|
|
|
if (extraProperties) {
|
|
forEach(extraProperties, function addToErrorObject(value, key) {
|
|
error[key] = value;
|
|
});
|
|
}
|
|
}
|
|
|
|
inherits(AlgoliaSearchError, Error);
|
|
|
|
function createCustomError(name, message) {
|
|
function AlgoliaSearchCustomError() {
|
|
var args = Array.prototype.slice.call(arguments, 0);
|
|
|
|
// custom message not set, use default
|
|
if (typeof args[0] !== 'string') {
|
|
args.unshift(message);
|
|
}
|
|
|
|
AlgoliaSearchError.apply(this, args);
|
|
this.name = 'AlgoliaSearch' + name + 'Error';
|
|
}
|
|
|
|
inherits(AlgoliaSearchCustomError, AlgoliaSearchError);
|
|
|
|
return AlgoliaSearchCustomError;
|
|
}
|
|
|
|
// late exports to let various fn defs and inherits take place
|
|
module.exports = {
|
|
AlgoliaSearchError: AlgoliaSearchError,
|
|
UnparsableJSON: createCustomError(
|
|
'UnparsableJSON',
|
|
'Could not parse the incoming response as JSON, see err.more for details'
|
|
),
|
|
RequestTimeout: createCustomError(
|
|
'RequestTimeout',
|
|
'Request timed out before getting a response'
|
|
),
|
|
Network: createCustomError(
|
|
'Network',
|
|
'Network issue, see err.more for details'
|
|
),
|
|
JSONPScriptFail: createCustomError(
|
|
'JSONPScriptFail',
|
|
'<script> was loaded but did not call our provided callback'
|
|
),
|
|
ValidUntilNotFound: createCustomError(
|
|
'ValidUntilNotFound',
|
|
'The SecuredAPIKey does not have a validUntil parameter.'
|
|
),
|
|
JSONPScriptError: createCustomError(
|
|
'JSONPScriptError',
|
|
'<script> unable to load due to an `error` event on it'
|
|
),
|
|
ObjectNotFound: createCustomError(
|
|
'ObjectNotFound',
|
|
'Object not found'
|
|
),
|
|
Unknown: createCustomError(
|
|
'Unknown',
|
|
'Unknown error occured'
|
|
)
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 12 */
|
|
/***/ (function(module, exports) {
|
|
|
|
var toString = {}.toString;
|
|
|
|
module.exports = Array.isArray || function (arr) {
|
|
return toString.call(arr) == '[object Array]';
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 13 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var foreach = __webpack_require__(3);
|
|
|
|
module.exports = function map(arr, fn) {
|
|
var newArr = [];
|
|
foreach(arr, function(item, itemIndex) {
|
|
newArr.push(fn(item, itemIndex, arr));
|
|
});
|
|
return newArr;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 14 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/* WEBPACK VAR INJECTION */(function(process) {/**
|
|
* This is the web browser implementation of `debug()`.
|
|
*
|
|
* Expose `debug()` as the module.
|
|
*/
|
|
|
|
exports = module.exports = __webpack_require__(43);
|
|
exports.log = log;
|
|
exports.formatArgs = formatArgs;
|
|
exports.save = save;
|
|
exports.load = load;
|
|
exports.useColors = useColors;
|
|
exports.storage = 'undefined' != typeof chrome
|
|
&& 'undefined' != typeof chrome.storage
|
|
? chrome.storage.local
|
|
: localstorage();
|
|
|
|
/**
|
|
* Colors.
|
|
*/
|
|
|
|
exports.colors = [
|
|
'lightseagreen',
|
|
'forestgreen',
|
|
'goldenrod',
|
|
'dodgerblue',
|
|
'darkorchid',
|
|
'crimson'
|
|
];
|
|
|
|
/**
|
|
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
|
|
* and the Firebug extension (any Firefox version) are known
|
|
* to support "%c" CSS customizations.
|
|
*
|
|
* TODO: add a `localStorage` variable to explicitly enable/disable colors
|
|
*/
|
|
|
|
function useColors() {
|
|
// NB: In an Electron preload script, document will be defined but not fully
|
|
// initialized. Since we know we're in Chrome, we'll just detect this case
|
|
// explicitly
|
|
if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') {
|
|
return true;
|
|
}
|
|
|
|
// is webkit? http://stackoverflow.com/a/16459606/376773
|
|
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
|
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
|
// is firebug? http://stackoverflow.com/a/398120/376773
|
|
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
|
// is firefox >= v31?
|
|
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
|
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
|
|
// double check webkit in userAgent just in case we are in a worker
|
|
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
|
|
}
|
|
|
|
/**
|
|
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
|
|
*/
|
|
|
|
exports.formatters.j = function(v) {
|
|
try {
|
|
return JSON.stringify(v);
|
|
} catch (err) {
|
|
return '[UnexpectedJSONParseError]: ' + err.message;
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* Colorize log arguments if enabled.
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
function formatArgs(args) {
|
|
var useColors = this.useColors;
|
|
|
|
args[0] = (useColors ? '%c' : '')
|
|
+ this.namespace
|
|
+ (useColors ? ' %c' : ' ')
|
|
+ args[0]
|
|
+ (useColors ? '%c ' : ' ')
|
|
+ '+' + exports.humanize(this.diff);
|
|
|
|
if (!useColors) return;
|
|
|
|
var c = 'color: ' + this.color;
|
|
args.splice(1, 0, c, 'color: inherit')
|
|
|
|
// the final "%c" is somewhat tricky, because there could be other
|
|
// arguments passed either before or after the %c, so we need to
|
|
// figure out the correct index to insert the CSS into
|
|
var index = 0;
|
|
var lastC = 0;
|
|
args[0].replace(/%[a-zA-Z%]/g, function(match) {
|
|
if ('%%' === match) return;
|
|
index++;
|
|
if ('%c' === match) {
|
|
// we only are interested in the *last* %c
|
|
// (the user may have provided their own)
|
|
lastC = index;
|
|
}
|
|
});
|
|
|
|
args.splice(lastC, 0, c);
|
|
}
|
|
|
|
/**
|
|
* Invokes `console.log()` when available.
|
|
* No-op when `console.log` is not a "function".
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
function log() {
|
|
// this hackery is required for IE8/9, where
|
|
// the `console.log` function doesn't have 'apply'
|
|
return 'object' === typeof console
|
|
&& console.log
|
|
&& Function.prototype.apply.call(console.log, console, arguments);
|
|
}
|
|
|
|
/**
|
|
* Save `namespaces`.
|
|
*
|
|
* @param {String} namespaces
|
|
* @api private
|
|
*/
|
|
|
|
function save(namespaces) {
|
|
try {
|
|
if (null == namespaces) {
|
|
exports.storage.removeItem('debug');
|
|
} else {
|
|
exports.storage.debug = namespaces;
|
|
}
|
|
} catch(e) {}
|
|
}
|
|
|
|
/**
|
|
* Load `namespaces`.
|
|
*
|
|
* @return {String} returns the previously persisted debug modes
|
|
* @api private
|
|
*/
|
|
|
|
function load() {
|
|
var r;
|
|
try {
|
|
r = exports.storage.debug;
|
|
} catch(e) {}
|
|
|
|
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
|
|
if (!r && typeof process !== 'undefined' && 'env' in process) {
|
|
r = process.env.DEBUG;
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
/**
|
|
* Enable namespaces listed in `localStorage.debug` initially.
|
|
*/
|
|
|
|
exports.enable(load());
|
|
|
|
/**
|
|
* Localstorage attempts to return the localstorage.
|
|
*
|
|
* This is necessary because safari throws
|
|
* when a user disables cookies/localstorage
|
|
* and you attempt to access it.
|
|
*
|
|
* @return {LocalStorage}
|
|
* @api private
|
|
*/
|
|
|
|
function localstorage() {
|
|
try {
|
|
return window.localStorage;
|
|
} catch (e) {}
|
|
}
|
|
|
|
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(10)))
|
|
|
|
/***/ }),
|
|
/* 15 */
|
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
|
|
"use strict";
|
|
/* harmony default export */ __webpack_exports__["a"] = (".algolia-places {\n width: 100%;\n}\n\n.ap-input, .ap-hint {\n width: 100%;\n padding-right: 35px;\n padding-left: 16px;\n line-height: 40px;\n height: 40px;\n border: 1px solid #CCC;\n border-radius: 3px;\n outline: none;\n font: inherit;\n appearance: none;\n -webkit-appearance: none;\n box-sizing: border-box;\n}\n\n.ap-input::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n.ap-input::-ms-clear {\n display: none;\n}\n\n.ap-input:hover ~ .ap-input-icon svg,\n.ap-input:focus ~ .ap-input-icon svg,\n.ap-input-icon:hover svg {\n fill: #aaaaaa;\n}\n\n.ap-dropdown-menu {\n width: 100%;\n background: #ffffff;\n box-shadow: 0 1px 10px rgba(0, 0, 0, 0.2), 0 2px 4px 0 rgba(0, 0, 0, 0.1);\n border-radius: 3px;\n margin-top: 3px;\n overflow: hidden;\n}\n\n.ap-suggestion {\n cursor: pointer;\n height: 46px;\n line-height: 46px;\n padding-left: 18px;\n overflow: hidden;\n}\n\n.ap-suggestion em {\n font-weight: bold;\n font-style: normal;\n}\n\n.ap-address {\n font-size: smaller;\n margin-left: 12px;\n color: #aaaaaa;\n}\n\n.ap-suggestion-icon {\n margin-right: 10px;\n width: 14px;\n height: 20px;\n vertical-align: middle;\n}\n\n.ap-suggestion-icon svg {\n display: inherit;\n -webkit-transform: scale(0.9) translateY(2px);\n transform: scale(0.9) translateY(2px);\n fill: #cfcfcf;\n}\n\n.ap-input-icon {\n border: 0;\n background: transparent;\n position: absolute;\n top: 0;\n bottom: 0;\n right: 16px;\n outline: none;\n}\n\n.ap-input-icon.ap-icon-pin {\n cursor: pointer;\n}\n\n.ap-input-icon svg {\n fill: #cfcfcf;\n position: absolute;\n top: 50%;\n right: 0;\n -webkit-transform: translateY(-50%);\n transform: translateY(-50%);\n}\n\n.ap-cursor {\n background: #efefef;\n}\n\n.ap-cursor .ap-suggestion-icon svg {\n -webkit-transform: scale(1) translateY(2px);\n transform: scale(1) translateY(2px);\n fill: #aaaaaa;\n}\n\n.ap-footer {\n opacity: .8;\n text-align: right;\n padding: .5em 1em .5em 0;\n font-size: 12px;\n line-height: 12px;\n}\n\n.ap-footer a {\n color: inherit;\n text-decoration: none;\n}\n\n.ap-footer a svg {\n vertical-align: middle;\n}\n\n.ap-footer:hover {\n opacity: 1;\n}\n");
|
|
|
|
/***/ }),
|
|
/* 16 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var immediate = __webpack_require__(58);
|
|
var splitter = /\s+/;
|
|
|
|
module.exports = {
|
|
onSync: onSync,
|
|
onAsync: onAsync,
|
|
off: off,
|
|
trigger: trigger
|
|
};
|
|
|
|
function on(method, types, cb, context) {
|
|
var type;
|
|
|
|
if (!cb) {
|
|
return this;
|
|
}
|
|
|
|
types = types.split(splitter);
|
|
cb = context ? bindContext(cb, context) : cb;
|
|
|
|
this._callbacks = this._callbacks || {};
|
|
|
|
while (type = types.shift()) {
|
|
this._callbacks[type] = this._callbacks[type] || {sync: [], async: []};
|
|
this._callbacks[type][method].push(cb);
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
function onAsync(types, cb, context) {
|
|
return on.call(this, 'async', types, cb, context);
|
|
}
|
|
|
|
function onSync(types, cb, context) {
|
|
return on.call(this, 'sync', types, cb, context);
|
|
}
|
|
|
|
function off(types) {
|
|
var type;
|
|
|
|
if (!this._callbacks) {
|
|
return this;
|
|
}
|
|
|
|
types = types.split(splitter);
|
|
|
|
while (type = types.shift()) {
|
|
delete this._callbacks[type];
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
function trigger(types) {
|
|
var type;
|
|
var callbacks;
|
|
var args;
|
|
var syncFlush;
|
|
var asyncFlush;
|
|
|
|
if (!this._callbacks) {
|
|
return this;
|
|
}
|
|
|
|
types = types.split(splitter);
|
|
args = [].slice.call(arguments, 1);
|
|
|
|
while ((type = types.shift()) && (callbacks = this._callbacks[type])) { // eslint-disable-line
|
|
syncFlush = getFlush(callbacks.sync, this, [type].concat(args));
|
|
asyncFlush = getFlush(callbacks.async, this, [type].concat(args));
|
|
|
|
if (syncFlush()) {
|
|
immediate(asyncFlush);
|
|
}
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
function getFlush(callbacks, context, args) {
|
|
return flush;
|
|
|
|
function flush() {
|
|
var cancelled;
|
|
|
|
for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) {
|
|
// only cancel if the callback explicitly returns false
|
|
cancelled = callbacks[i].apply(context, args) === false;
|
|
}
|
|
|
|
return !cancelled;
|
|
}
|
|
}
|
|
|
|
function bindContext(fn, context) {
|
|
return fn.bind ?
|
|
fn.bind(context) :
|
|
function() { fn.apply(context, [].slice.call(arguments, 0)); };
|
|
}
|
|
|
|
|
|
/***/ }),
|
|
/* 17 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _ = __webpack_require__(0);
|
|
|
|
var css = {
|
|
wrapper: {
|
|
position: 'relative',
|
|
display: 'inline-block'
|
|
},
|
|
hint: {
|
|
position: 'absolute',
|
|
top: '0',
|
|
left: '0',
|
|
borderColor: 'transparent',
|
|
boxShadow: 'none',
|
|
// #741: fix hint opacity issue on iOS
|
|
opacity: '1'
|
|
},
|
|
input: {
|
|
position: 'relative',
|
|
verticalAlign: 'top',
|
|
backgroundColor: 'transparent'
|
|
},
|
|
inputWithNoHint: {
|
|
position: 'relative',
|
|
verticalAlign: 'top'
|
|
},
|
|
dropdown: {
|
|
position: 'absolute',
|
|
top: '100%',
|
|
left: '0',
|
|
zIndex: '100',
|
|
display: 'none'
|
|
},
|
|
suggestions: {
|
|
display: 'block'
|
|
},
|
|
suggestion: {
|
|
whiteSpace: 'nowrap',
|
|
cursor: 'pointer'
|
|
},
|
|
suggestionChild: {
|
|
whiteSpace: 'normal'
|
|
},
|
|
ltr: {
|
|
left: '0',
|
|
right: 'auto'
|
|
},
|
|
rtl: {
|
|
left: 'auto',
|
|
right: '0'
|
|
},
|
|
defaultClasses: {
|
|
root: 'algolia-autocomplete',
|
|
prefix: 'aa',
|
|
noPrefix: false,
|
|
dropdownMenu: 'dropdown-menu',
|
|
input: 'input',
|
|
hint: 'hint',
|
|
suggestions: 'suggestions',
|
|
suggestion: 'suggestion',
|
|
cursor: 'cursor',
|
|
dataset: 'dataset',
|
|
empty: 'empty'
|
|
},
|
|
// will be merged with the default ones if appendTo is used
|
|
appendTo: {
|
|
wrapper: {
|
|
position: 'absolute',
|
|
zIndex: '100',
|
|
display: 'none'
|
|
},
|
|
input: {},
|
|
inputWithNoHint: {},
|
|
dropdown: {
|
|
display: 'block'
|
|
}
|
|
}
|
|
};
|
|
|
|
// ie specific styling
|
|
if (_.isMsie()) {
|
|
// ie6-8 (and 9?) doesn't fire hover and click events for elements with
|
|
// transparent backgrounds, for a workaround, use 1x1 transparent gif
|
|
_.mixin(css.input, {
|
|
backgroundImage: 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)'
|
|
});
|
|
}
|
|
|
|
// ie7 and under specific styling
|
|
if (_.isMsie() && _.isMsie() <= 7) {
|
|
// if someone can tell me why this is necessary to align
|
|
// the hint with the query in ie7, i'll send you $5 - @JakeHarding
|
|
_.mixin(css.input, {marginTop: '-1px'});
|
|
}
|
|
|
|
module.exports = css;
|
|
|
|
|
|
/***/ }),
|
|
/* 18 */
|
|
/***/ (function(module, exports) {
|
|
|
|
var containers = []; // will store container HTMLElement references
|
|
var styleElements = []; // will store {prepend: HTMLElement, append: HTMLElement}
|
|
|
|
var usage = 'insert-css: You need to provide a CSS string. Usage: insertCss(cssString[, options]).';
|
|
|
|
function insertCss(css, options) {
|
|
options = options || {};
|
|
|
|
if (css === undefined) {
|
|
throw new Error(usage);
|
|
}
|
|
|
|
var position = options.prepend === true ? 'prepend' : 'append';
|
|
var container = options.container !== undefined ? options.container : document.querySelector('head');
|
|
var containerId = containers.indexOf(container);
|
|
|
|
// first time we see this container, create the necessary entries
|
|
if (containerId === -1) {
|
|
containerId = containers.push(container) - 1;
|
|
styleElements[containerId] = {};
|
|
}
|
|
|
|
// try to get the correponding container + position styleElement, create it otherwise
|
|
var styleElement;
|
|
|
|
if (styleElements[containerId] !== undefined && styleElements[containerId][position] !== undefined) {
|
|
styleElement = styleElements[containerId][position];
|
|
} else {
|
|
styleElement = styleElements[containerId][position] = createStyleElement();
|
|
|
|
if (position === 'prepend') {
|
|
container.insertBefore(styleElement, container.childNodes[0]);
|
|
} else {
|
|
container.appendChild(styleElement);
|
|
}
|
|
}
|
|
|
|
// strip potential UTF-8 BOM if css was read from a file
|
|
if (css.charCodeAt(0) === 0xFEFF) { css = css.substr(1, css.length); }
|
|
|
|
// actually add the stylesheet
|
|
if (styleElement.styleSheet) {
|
|
styleElement.styleSheet.cssText += css
|
|
} else {
|
|
styleElement.textContent += css;
|
|
}
|
|
|
|
return styleElement;
|
|
};
|
|
|
|
function createStyleElement() {
|
|
var styleElement = document.createElement('style');
|
|
styleElement.setAttribute('type', 'text/css');
|
|
return styleElement;
|
|
}
|
|
|
|
module.exports = insertCss;
|
|
module.exports.insertCss = insertCss;
|
|
|
|
|
|
/***/ }),
|
|
/* 19 */
|
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
|
|
"use strict";
|
|
// ESM COMPAT FLAG
|
|
__webpack_require__.r(__webpack_exports__);
|
|
|
|
// EXPORTS
|
|
__webpack_require__.d(__webpack_exports__, "default", function() { return /* binding */ createAutocompleteDataset; });
|
|
|
|
// EXTERNAL MODULE: ./src/configure/index.js
|
|
var configure = __webpack_require__(1);
|
|
|
|
// EXTERNAL MODULE: ./src/formatHit.js + 2 modules
|
|
var formatHit = __webpack_require__(9);
|
|
|
|
// EXTERNAL MODULE: ./src/version.js
|
|
var version = __webpack_require__(6);
|
|
|
|
// CONCATENATED MODULE: ./src/createAutocompleteSource.js
|
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
|
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
|
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
|
|
|
|
|
|
function createAutocompleteSource(_ref) {
|
|
var algoliasearch = _ref.algoliasearch,
|
|
clientOptions = _ref.clientOptions,
|
|
apiKey = _ref.apiKey,
|
|
appId = _ref.appId,
|
|
hitsPerPage = _ref.hitsPerPage,
|
|
postcodeSearch = _ref.postcodeSearch,
|
|
aroundLatLng = _ref.aroundLatLng,
|
|
aroundRadius = _ref.aroundRadius,
|
|
aroundLatLngViaIP = _ref.aroundLatLngViaIP,
|
|
insideBoundingBox = _ref.insideBoundingBox,
|
|
insidePolygon = _ref.insidePolygon,
|
|
getRankingInfo = _ref.getRankingInfo,
|
|
countries = _ref.countries,
|
|
formatInputValue = _ref.formatInputValue,
|
|
_ref$computeQueryPara = _ref.computeQueryParams,
|
|
computeQueryParams = _ref$computeQueryPara === void 0 ? function (params) {
|
|
return params;
|
|
} : _ref$computeQueryPara,
|
|
_ref$useDeviceLocatio = _ref.useDeviceLocation,
|
|
useDeviceLocation = _ref$useDeviceLocatio === void 0 ? false : _ref$useDeviceLocatio,
|
|
_ref$language = _ref.language,
|
|
language = _ref$language === void 0 ? navigator.language.split('-')[0] : _ref$language,
|
|
_ref$onHits = _ref.onHits,
|
|
onHits = _ref$onHits === void 0 ? function () {} : _ref$onHits,
|
|
_ref$onError = _ref.onError,
|
|
onError = _ref$onError === void 0 ? function (e) {
|
|
throw e;
|
|
} : _ref$onError,
|
|
onRateLimitReached = _ref.onRateLimitReached,
|
|
onInvalidCredentials = _ref.onInvalidCredentials,
|
|
type = _ref.type;
|
|
var placesClient = algoliasearch.initPlaces(appId, apiKey, clientOptions);
|
|
placesClient.as.addAlgoliaAgent("Algolia Places ".concat(version["default"]));
|
|
var configuration = Object(configure["a" /* default */])({
|
|
hitsPerPage: hitsPerPage,
|
|
type: type,
|
|
postcodeSearch: postcodeSearch,
|
|
countries: countries,
|
|
language: language,
|
|
aroundLatLng: aroundLatLng,
|
|
aroundRadius: aroundRadius,
|
|
aroundLatLngViaIP: aroundLatLngViaIP,
|
|
insideBoundingBox: insideBoundingBox,
|
|
insidePolygon: insidePolygon,
|
|
getRankingInfo: getRankingInfo,
|
|
formatInputValue: formatInputValue,
|
|
computeQueryParams: computeQueryParams,
|
|
useDeviceLocation: useDeviceLocation,
|
|
onHits: onHits,
|
|
onError: onError,
|
|
onRateLimitReached: onRateLimitReached,
|
|
onInvalidCredentials: onInvalidCredentials
|
|
});
|
|
var params = configuration.params;
|
|
var controls = configuration.controls;
|
|
var userCoords;
|
|
var tracker = null;
|
|
|
|
if (controls.useDeviceLocation) {
|
|
tracker = navigator.geolocation.watchPosition(function (_ref2) {
|
|
var coords = _ref2.coords;
|
|
userCoords = "".concat(coords.latitude, ",").concat(coords.longitude);
|
|
});
|
|
}
|
|
|
|
function searcher(query, cb) {
|
|
var searchParams = _objectSpread(_objectSpread({}, params), {}, {
|
|
query: query
|
|
});
|
|
|
|
if (userCoords) {
|
|
searchParams.aroundLatLng = userCoords;
|
|
}
|
|
|
|
return placesClient.search(controls.computeQueryParams(searchParams)).then(function (content) {
|
|
var hits = content.hits.map(function (hit, hitIndex) {
|
|
return Object(formatHit["a" /* default */])({
|
|
formatInputValue: controls.formatInputValue,
|
|
hit: hit,
|
|
hitIndex: hitIndex,
|
|
query: query,
|
|
rawAnswer: content
|
|
});
|
|
});
|
|
controls.onHits({
|
|
hits: hits,
|
|
query: query,
|
|
rawAnswer: content
|
|
});
|
|
return hits;
|
|
}).then(cb)["catch"](function (e) {
|
|
if (e.statusCode === 403 && e.message === 'Invalid Application-ID or API key') {
|
|
controls.onInvalidCredentials();
|
|
return;
|
|
} else if (e.statusCode === 429) {
|
|
controls.onRateLimitReached();
|
|
return;
|
|
}
|
|
|
|
controls.onError(e);
|
|
});
|
|
}
|
|
|
|
searcher.configure = function (partial) {
|
|
var updated = Object(configure["a" /* default */])(_objectSpread(_objectSpread(_objectSpread({}, params), controls), partial));
|
|
params = updated.params;
|
|
controls = updated.controls;
|
|
|
|
if (controls.useDeviceLocation && tracker === null) {
|
|
tracker = navigator.geolocation.watchPosition(function (_ref3) {
|
|
var coords = _ref3.coords;
|
|
userCoords = "".concat(coords.latitude, ",").concat(coords.longitude);
|
|
});
|
|
} else if (!controls.useDeviceLocation && tracker !== null) {
|
|
navigator.geolocation.clearWatch(tracker);
|
|
tracker = null;
|
|
userCoords = null;
|
|
}
|
|
};
|
|
|
|
return searcher;
|
|
}
|
|
// EXTERNAL MODULE: ./src/defaultTemplates.js + 10 modules
|
|
var defaultTemplates = __webpack_require__(8);
|
|
|
|
// CONCATENATED MODULE: ./src/createAutocompleteDataset.js
|
|
function createAutocompleteDataset_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
|
|
function createAutocompleteDataset_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { createAutocompleteDataset_ownKeys(Object(source), true).forEach(function (key) { createAutocompleteDataset_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { createAutocompleteDataset_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
|
|
function createAutocompleteDataset_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
|
|
|
|
function createAutocompleteDataset(options) {
|
|
var templates = createAutocompleteDataset_objectSpread(createAutocompleteDataset_objectSpread({}, defaultTemplates["a" /* default */]), options.templates);
|
|
|
|
var source = createAutocompleteSource(createAutocompleteDataset_objectSpread(createAutocompleteDataset_objectSpread({}, options), {}, {
|
|
formatInputValue: templates.value,
|
|
templates: undefined
|
|
}));
|
|
return {
|
|
source: source,
|
|
templates: templates,
|
|
displayKey: 'value',
|
|
name: 'places',
|
|
cache: false
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 20 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var AlgoliaSearchCore = __webpack_require__(34);
|
|
var createAlgoliasearch = __webpack_require__(45);
|
|
|
|
module.exports = createAlgoliasearch(AlgoliaSearchCore, 'Browser (lite)');
|
|
|
|
|
|
/***/ }),
|
|
/* 21 */
|
|
/***/ (function(module, exports) {
|
|
|
|
if (typeof Object.create === 'function') {
|
|
// implementation from standard node.js 'util' module
|
|
module.exports = function inherits(ctor, superCtor) {
|
|
if (superCtor) {
|
|
ctor.super_ = superCtor
|
|
ctor.prototype = Object.create(superCtor.prototype, {
|
|
constructor: {
|
|
value: ctor,
|
|
enumerable: false,
|
|
writable: true,
|
|
configurable: true
|
|
}
|
|
})
|
|
}
|
|
};
|
|
} else {
|
|
// old school shim for old browsers
|
|
module.exports = function inherits(ctor, superCtor) {
|
|
if (superCtor) {
|
|
ctor.super_ = superCtor
|
|
var TempCtor = function () {}
|
|
TempCtor.prototype = superCtor.prototype
|
|
ctor.prototype = new TempCtor()
|
|
ctor.prototype.constructor = ctor
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/***/ }),
|
|
/* 22 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
module.exports = buildSearchMethod;
|
|
|
|
var errors = __webpack_require__(11);
|
|
|
|
/**
|
|
* Creates a search method to be used in clients
|
|
* @param {string} queryParam the name of the attribute used for the query
|
|
* @param {string} url the url
|
|
* @return {function} the search method
|
|
*/
|
|
function buildSearchMethod(queryParam, url) {
|
|
/**
|
|
* The search method. Prepares the data and send the query to Algolia.
|
|
* @param {string} query the string used for query search
|
|
* @param {object} args additional parameters to send with the search
|
|
* @param {function} [callback] the callback to be called with the client gets the answer
|
|
* @return {undefined|Promise} If the callback is not provided then this methods returns a Promise
|
|
*/
|
|
return function search(query, args, callback) {
|
|
// warn V2 users on how to search
|
|
if (typeof query === 'function' && typeof args === 'object' ||
|
|
typeof callback === 'object') {
|
|
// .search(query, params, cb)
|
|
// .search(cb, params)
|
|
throw new errors.AlgoliaSearchError('index.search usage is index.search(query, params, cb)');
|
|
}
|
|
|
|
// Normalizing the function signature
|
|
if (arguments.length === 0 || typeof query === 'function') {
|
|
// Usage : .search(), .search(cb)
|
|
callback = query;
|
|
query = '';
|
|
} else if (arguments.length === 1 || typeof args === 'function') {
|
|
// Usage : .search(query/args), .search(query, cb)
|
|
callback = args;
|
|
args = undefined;
|
|
}
|
|
// At this point we have 3 arguments with values
|
|
|
|
// Usage : .search(args) // careful: typeof null === 'object'
|
|
if (typeof query === 'object' && query !== null) {
|
|
args = query;
|
|
query = undefined;
|
|
} else if (query === undefined || query === null) { // .search(undefined/null)
|
|
query = '';
|
|
}
|
|
|
|
var params = '';
|
|
|
|
if (query !== undefined) {
|
|
params += queryParam + '=' + encodeURIComponent(query);
|
|
}
|
|
|
|
var additionalUA;
|
|
if (args !== undefined) {
|
|
if (args.additionalUA) {
|
|
additionalUA = args.additionalUA;
|
|
delete args.additionalUA;
|
|
}
|
|
// `_getSearchParams` will augment params, do not be fooled by the = versus += from previous if
|
|
params = this.as._getSearchParams(args, params);
|
|
}
|
|
|
|
|
|
return this._search(params, url, callback, additionalUA);
|
|
};
|
|
}
|
|
|
|
|
|
/***/ }),
|
|
/* 23 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
module.exports = function omit(obj, test) {
|
|
var keys = __webpack_require__(40);
|
|
var foreach = __webpack_require__(3);
|
|
|
|
var filtered = {};
|
|
|
|
foreach(keys(obj), function doFilter(keyName) {
|
|
if (test(keyName) !== true) {
|
|
filtered[keyName] = obj[keyName];
|
|
}
|
|
});
|
|
|
|
return filtered;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 24 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var toStr = Object.prototype.toString;
|
|
|
|
module.exports = function isArguments(value) {
|
|
var str = toStr.call(value);
|
|
var isArgs = str === '[object Arguments]';
|
|
if (!isArgs) {
|
|
isArgs = str !== '[object Array]' &&
|
|
value !== null &&
|
|
typeof value === 'object' &&
|
|
typeof value.length === 'number' &&
|
|
value.length >= 0 &&
|
|
toStr.call(value.callee) === '[object Function]';
|
|
}
|
|
return isArgs;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 25 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
var stringifyPrimitive = function(v) {
|
|
switch (typeof v) {
|
|
case 'string':
|
|
return v;
|
|
|
|
case 'boolean':
|
|
return v ? 'true' : 'false';
|
|
|
|
case 'number':
|
|
return isFinite(v) ? v : '';
|
|
|
|
default:
|
|
return '';
|
|
}
|
|
};
|
|
|
|
module.exports = function(obj, sep, eq, name) {
|
|
sep = sep || '&';
|
|
eq = eq || '=';
|
|
if (obj === null) {
|
|
obj = undefined;
|
|
}
|
|
|
|
if (typeof obj === 'object') {
|
|
return map(objectKeys(obj), function(k) {
|
|
var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
|
|
if (isArray(obj[k])) {
|
|
return map(obj[k], function(v) {
|
|
return ks + encodeURIComponent(stringifyPrimitive(v));
|
|
}).join(sep);
|
|
} else {
|
|
return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
|
|
}
|
|
}).join(sep);
|
|
|
|
}
|
|
|
|
if (!name) return '';
|
|
return encodeURIComponent(stringifyPrimitive(name)) + eq +
|
|
encodeURIComponent(stringifyPrimitive(obj));
|
|
};
|
|
|
|
var isArray = Array.isArray || function (xs) {
|
|
return Object.prototype.toString.call(xs) === '[object Array]';
|
|
};
|
|
|
|
function map (xs, f) {
|
|
if (xs.map) return xs.map(f);
|
|
var res = [];
|
|
for (var i = 0; i < xs.length; i++) {
|
|
res.push(f(xs[i], i));
|
|
}
|
|
return res;
|
|
}
|
|
|
|
var objectKeys = Object.keys || function (obj) {
|
|
var res = [];
|
|
for (var key in obj) {
|
|
if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
|
|
}
|
|
return res;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 26 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var namespace = 'autocomplete:';
|
|
|
|
var _ = __webpack_require__(0);
|
|
var DOM = __webpack_require__(2);
|
|
|
|
// constructor
|
|
// -----------
|
|
|
|
function EventBus(o) {
|
|
if (!o || !o.el) {
|
|
_.error('EventBus initialized without el');
|
|
}
|
|
|
|
this.$el = DOM.element(o.el);
|
|
}
|
|
|
|
// instance methods
|
|
// ----------------
|
|
|
|
_.mixin(EventBus.prototype, {
|
|
|
|
// ### public
|
|
|
|
trigger: function(type, suggestion, dataset, context) {
|
|
var event = _.Event(namespace + type);
|
|
this.$el.trigger(event, [suggestion, dataset, context]);
|
|
return event;
|
|
}
|
|
});
|
|
|
|
module.exports = EventBus;
|
|
|
|
|
|
/***/ }),
|
|
/* 27 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
module.exports = {
|
|
wrapper: '<span class="%ROOT%"></span>',
|
|
dropdown: '<span class="%PREFIX%%DROPDOWN_MENU%"></span>',
|
|
dataset: '<div class="%PREFIX%%DATASET%-%CLASS%"></div>',
|
|
suggestions: '<span class="%PREFIX%%SUGGESTIONS%"></span>',
|
|
suggestion: '<div class="%PREFIX%%SUGGESTION%"></div>'
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 28 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = "0.37.1";
|
|
|
|
|
|
/***/ }),
|
|
/* 29 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
module.exports = function parseAlgoliaClientVersion(agent) {
|
|
var parsed =
|
|
// User agent for algoliasearch >= 3.33.0
|
|
agent.match(/Algolia for JavaScript \((\d+\.)(\d+\.)(\d+)\)/) ||
|
|
// User agent for algoliasearch < 3.33.0
|
|
agent.match(/Algolia for vanilla JavaScript (\d+\.)(\d+\.)(\d+)/);
|
|
|
|
if (parsed) {
|
|
return [parsed[1], parsed[2], parsed[3]];
|
|
}
|
|
|
|
return undefined;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 30 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// polyfill for navigator.language (IE <= 10)
|
|
// not polyfilled by https://cdn.polyfill.io/v2/docs/
|
|
// Defined: http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#navigatorlanguage
|
|
// with allowable values at http://www.ietf.org/rfc/bcp/bcp47.txt
|
|
// Note that the HTML spec suggests that anonymizing services return "en-US" by default for
|
|
// user privacy (so your app may wish to provide a means of changing the locale)
|
|
if (!('language' in navigator)) {
|
|
navigator.language = // IE 10 in IE8 mode on Windows 7 uses upper-case in
|
|
// navigator.userLanguage country codes but per
|
|
// http://msdn.microsoft.com/en-us/library/ie/ms533052.aspx (via
|
|
// http://msdn.microsoft.com/en-us/library/ie/ms534713.aspx), they
|
|
// appear to be in lower case, so we bring them into harmony with navigator.language.
|
|
navigator.userLanguage && navigator.userLanguage.replace(/-[a-z]{2}$/, String.prototype.toUpperCase) || 'en-US'; // Default for anonymizing services: http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#navigatorlanguage
|
|
}
|
|
|
|
/***/ }),
|
|
/* 31 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
var R = typeof Reflect === 'object' ? Reflect : null
|
|
var ReflectApply = R && typeof R.apply === 'function'
|
|
? R.apply
|
|
: function ReflectApply(target, receiver, args) {
|
|
return Function.prototype.apply.call(target, receiver, args);
|
|
}
|
|
|
|
var ReflectOwnKeys
|
|
if (R && typeof R.ownKeys === 'function') {
|
|
ReflectOwnKeys = R.ownKeys
|
|
} else if (Object.getOwnPropertySymbols) {
|
|
ReflectOwnKeys = function ReflectOwnKeys(target) {
|
|
return Object.getOwnPropertyNames(target)
|
|
.concat(Object.getOwnPropertySymbols(target));
|
|
};
|
|
} else {
|
|
ReflectOwnKeys = function ReflectOwnKeys(target) {
|
|
return Object.getOwnPropertyNames(target);
|
|
};
|
|
}
|
|
|
|
function ProcessEmitWarning(warning) {
|
|
if (console && console.warn) console.warn(warning);
|
|
}
|
|
|
|
var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
|
|
return value !== value;
|
|
}
|
|
|
|
function EventEmitter() {
|
|
EventEmitter.init.call(this);
|
|
}
|
|
module.exports = EventEmitter;
|
|
|
|
// Backwards-compat with node 0.10.x
|
|
EventEmitter.EventEmitter = EventEmitter;
|
|
|
|
EventEmitter.prototype._events = undefined;
|
|
EventEmitter.prototype._eventsCount = 0;
|
|
EventEmitter.prototype._maxListeners = undefined;
|
|
|
|
// By default EventEmitters will print a warning if more than 10 listeners are
|
|
// added to it. This is a useful default which helps finding memory leaks.
|
|
var defaultMaxListeners = 10;
|
|
|
|
function checkListener(listener) {
|
|
if (typeof listener !== 'function') {
|
|
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
|
|
}
|
|
}
|
|
|
|
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
|
|
enumerable: true,
|
|
get: function() {
|
|
return defaultMaxListeners;
|
|
},
|
|
set: function(arg) {
|
|
if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
|
|
throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
|
|
}
|
|
defaultMaxListeners = arg;
|
|
}
|
|
});
|
|
|
|
EventEmitter.init = function() {
|
|
|
|
if (this._events === undefined ||
|
|
this._events === Object.getPrototypeOf(this)._events) {
|
|
this._events = Object.create(null);
|
|
this._eventsCount = 0;
|
|
}
|
|
|
|
this._maxListeners = this._maxListeners || undefined;
|
|
};
|
|
|
|
// Obviously not all Emitters should be limited to 10. This function allows
|
|
// that to be increased. Set to zero for unlimited.
|
|
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
|
|
if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
|
|
throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
|
|
}
|
|
this._maxListeners = n;
|
|
return this;
|
|
};
|
|
|
|
function _getMaxListeners(that) {
|
|
if (that._maxListeners === undefined)
|
|
return EventEmitter.defaultMaxListeners;
|
|
return that._maxListeners;
|
|
}
|
|
|
|
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
|
|
return _getMaxListeners(this);
|
|
};
|
|
|
|
EventEmitter.prototype.emit = function emit(type) {
|
|
var args = [];
|
|
for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
|
|
var doError = (type === 'error');
|
|
|
|
var events = this._events;
|
|
if (events !== undefined)
|
|
doError = (doError && events.error === undefined);
|
|
else if (!doError)
|
|
return false;
|
|
|
|
// If there is no 'error' event listener then throw.
|
|
if (doError) {
|
|
var er;
|
|
if (args.length > 0)
|
|
er = args[0];
|
|
if (er instanceof Error) {
|
|
// Note: The comments on the `throw` lines are intentional, they show
|
|
// up in Node's output if this results in an unhandled exception.
|
|
throw er; // Unhandled 'error' event
|
|
}
|
|
// At least give some kind of context to the user
|
|
var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
|
|
err.context = er;
|
|
throw err; // Unhandled 'error' event
|
|
}
|
|
|
|
var handler = events[type];
|
|
|
|
if (handler === undefined)
|
|
return false;
|
|
|
|
if (typeof handler === 'function') {
|
|
ReflectApply(handler, this, args);
|
|
} else {
|
|
var len = handler.length;
|
|
var listeners = arrayClone(handler, len);
|
|
for (var i = 0; i < len; ++i)
|
|
ReflectApply(listeners[i], this, args);
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
function _addListener(target, type, listener, prepend) {
|
|
var m;
|
|
var events;
|
|
var existing;
|
|
|
|
checkListener(listener);
|
|
|
|
events = target._events;
|
|
if (events === undefined) {
|
|
events = target._events = Object.create(null);
|
|
target._eventsCount = 0;
|
|
} else {
|
|
// To avoid recursion in the case that type === "newListener"! Before
|
|
// adding it to the listeners, first emit "newListener".
|
|
if (events.newListener !== undefined) {
|
|
target.emit('newListener', type,
|
|
listener.listener ? listener.listener : listener);
|
|
|
|
// Re-assign `events` because a newListener handler could have caused the
|
|
// this._events to be assigned to a new object
|
|
events = target._events;
|
|
}
|
|
existing = events[type];
|
|
}
|
|
|
|
if (existing === undefined) {
|
|
// Optimize the case of one listener. Don't need the extra array object.
|
|
existing = events[type] = listener;
|
|
++target._eventsCount;
|
|
} else {
|
|
if (typeof existing === 'function') {
|
|
// Adding the second element, need to change to array.
|
|
existing = events[type] =
|
|
prepend ? [listener, existing] : [existing, listener];
|
|
// If we've already got an array, just append.
|
|
} else if (prepend) {
|
|
existing.unshift(listener);
|
|
} else {
|
|
existing.push(listener);
|
|
}
|
|
|
|
// Check for listener leak
|
|
m = _getMaxListeners(target);
|
|
if (m > 0 && existing.length > m && !existing.warned) {
|
|
existing.warned = true;
|
|
// No error code for this since it is a Warning
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
var w = new Error('Possible EventEmitter memory leak detected. ' +
|
|
existing.length + ' ' + String(type) + ' listeners ' +
|
|
'added. Use emitter.setMaxListeners() to ' +
|
|
'increase limit');
|
|
w.name = 'MaxListenersExceededWarning';
|
|
w.emitter = target;
|
|
w.type = type;
|
|
w.count = existing.length;
|
|
ProcessEmitWarning(w);
|
|
}
|
|
}
|
|
|
|
return target;
|
|
}
|
|
|
|
EventEmitter.prototype.addListener = function addListener(type, listener) {
|
|
return _addListener(this, type, listener, false);
|
|
};
|
|
|
|
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
|
|
|
|
EventEmitter.prototype.prependListener =
|
|
function prependListener(type, listener) {
|
|
return _addListener(this, type, listener, true);
|
|
};
|
|
|
|
function onceWrapper() {
|
|
if (!this.fired) {
|
|
this.target.removeListener(this.type, this.wrapFn);
|
|
this.fired = true;
|
|
if (arguments.length === 0)
|
|
return this.listener.call(this.target);
|
|
return this.listener.apply(this.target, arguments);
|
|
}
|
|
}
|
|
|
|
function _onceWrap(target, type, listener) {
|
|
var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
|
|
var wrapped = onceWrapper.bind(state);
|
|
wrapped.listener = listener;
|
|
state.wrapFn = wrapped;
|
|
return wrapped;
|
|
}
|
|
|
|
EventEmitter.prototype.once = function once(type, listener) {
|
|
checkListener(listener);
|
|
this.on(type, _onceWrap(this, type, listener));
|
|
return this;
|
|
};
|
|
|
|
EventEmitter.prototype.prependOnceListener =
|
|
function prependOnceListener(type, listener) {
|
|
checkListener(listener);
|
|
this.prependListener(type, _onceWrap(this, type, listener));
|
|
return this;
|
|
};
|
|
|
|
// Emits a 'removeListener' event if and only if the listener was removed.
|
|
EventEmitter.prototype.removeListener =
|
|
function removeListener(type, listener) {
|
|
var list, events, position, i, originalListener;
|
|
|
|
checkListener(listener);
|
|
|
|
events = this._events;
|
|
if (events === undefined)
|
|
return this;
|
|
|
|
list = events[type];
|
|
if (list === undefined)
|
|
return this;
|
|
|
|
if (list === listener || list.listener === listener) {
|
|
if (--this._eventsCount === 0)
|
|
this._events = Object.create(null);
|
|
else {
|
|
delete events[type];
|
|
if (events.removeListener)
|
|
this.emit('removeListener', type, list.listener || listener);
|
|
}
|
|
} else if (typeof list !== 'function') {
|
|
position = -1;
|
|
|
|
for (i = list.length - 1; i >= 0; i--) {
|
|
if (list[i] === listener || list[i].listener === listener) {
|
|
originalListener = list[i].listener;
|
|
position = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (position < 0)
|
|
return this;
|
|
|
|
if (position === 0)
|
|
list.shift();
|
|
else {
|
|
spliceOne(list, position);
|
|
}
|
|
|
|
if (list.length === 1)
|
|
events[type] = list[0];
|
|
|
|
if (events.removeListener !== undefined)
|
|
this.emit('removeListener', type, originalListener || listener);
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
|
|
|
|
EventEmitter.prototype.removeAllListeners =
|
|
function removeAllListeners(type) {
|
|
var listeners, events, i;
|
|
|
|
events = this._events;
|
|
if (events === undefined)
|
|
return this;
|
|
|
|
// not listening for removeListener, no need to emit
|
|
if (events.removeListener === undefined) {
|
|
if (arguments.length === 0) {
|
|
this._events = Object.create(null);
|
|
this._eventsCount = 0;
|
|
} else if (events[type] !== undefined) {
|
|
if (--this._eventsCount === 0)
|
|
this._events = Object.create(null);
|
|
else
|
|
delete events[type];
|
|
}
|
|
return this;
|
|
}
|
|
|
|
// emit removeListener for all listeners on all events
|
|
if (arguments.length === 0) {
|
|
var keys = Object.keys(events);
|
|
var key;
|
|
for (i = 0; i < keys.length; ++i) {
|
|
key = keys[i];
|
|
if (key === 'removeListener') continue;
|
|
this.removeAllListeners(key);
|
|
}
|
|
this.removeAllListeners('removeListener');
|
|
this._events = Object.create(null);
|
|
this._eventsCount = 0;
|
|
return this;
|
|
}
|
|
|
|
listeners = events[type];
|
|
|
|
if (typeof listeners === 'function') {
|
|
this.removeListener(type, listeners);
|
|
} else if (listeners !== undefined) {
|
|
// LIFO order
|
|
for (i = listeners.length - 1; i >= 0; i--) {
|
|
this.removeListener(type, listeners[i]);
|
|
}
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
function _listeners(target, type, unwrap) {
|
|
var events = target._events;
|
|
|
|
if (events === undefined)
|
|
return [];
|
|
|
|
var evlistener = events[type];
|
|
if (evlistener === undefined)
|
|
return [];
|
|
|
|
if (typeof evlistener === 'function')
|
|
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
|
|
|
|
return unwrap ?
|
|
unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
|
|
}
|
|
|
|
EventEmitter.prototype.listeners = function listeners(type) {
|
|
return _listeners(this, type, true);
|
|
};
|
|
|
|
EventEmitter.prototype.rawListeners = function rawListeners(type) {
|
|
return _listeners(this, type, false);
|
|
};
|
|
|
|
EventEmitter.listenerCount = function(emitter, type) {
|
|
if (typeof emitter.listenerCount === 'function') {
|
|
return emitter.listenerCount(type);
|
|
} else {
|
|
return listenerCount.call(emitter, type);
|
|
}
|
|
};
|
|
|
|
EventEmitter.prototype.listenerCount = listenerCount;
|
|
function listenerCount(type) {
|
|
var events = this._events;
|
|
|
|
if (events !== undefined) {
|
|
var evlistener = events[type];
|
|
|
|
if (typeof evlistener === 'function') {
|
|
return 1;
|
|
} else if (evlistener !== undefined) {
|
|
return evlistener.length;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
EventEmitter.prototype.eventNames = function eventNames() {
|
|
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
|
|
};
|
|
|
|
function arrayClone(arr, n) {
|
|
var copy = new Array(n);
|
|
for (var i = 0; i < n; ++i)
|
|
copy[i] = arr[i];
|
|
return copy;
|
|
}
|
|
|
|
function spliceOne(list, index) {
|
|
for (; index + 1 < list.length; index++)
|
|
list[index] = list[index + 1];
|
|
list.pop();
|
|
}
|
|
|
|
function unwrapListeners(arr) {
|
|
var ret = new Array(arr.length);
|
|
for (var i = 0; i < ret.length; ++i) {
|
|
ret[i] = arr[i].listener || arr[i];
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
/***/ }),
|
|
/* 32 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
module.exports = __webpack_require__(54);
|
|
|
|
|
|
/***/ }),
|
|
/* 33 */
|
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
|
|
"use strict";
|
|
// ESM COMPAT FLAG
|
|
__webpack_require__.r(__webpack_exports__);
|
|
|
|
// EXPORTS
|
|
__webpack_require__.d(__webpack_exports__, "default", function() { return /* binding */ places_places; });
|
|
|
|
// EXTERNAL MODULE: ./node_modules/events/events.js
|
|
var events = __webpack_require__(31);
|
|
var events_default = /*#__PURE__*/__webpack_require__.n(events);
|
|
|
|
// EXTERNAL MODULE: ./node_modules/algoliasearch/src/browser/builds/algoliasearchLite.js
|
|
var algoliasearchLite = __webpack_require__(20);
|
|
var algoliasearchLite_default = /*#__PURE__*/__webpack_require__.n(algoliasearchLite);
|
|
|
|
// EXTERNAL MODULE: ./node_modules/autocomplete.js/index.js
|
|
var autocomplete_js = __webpack_require__(32);
|
|
var autocomplete_js_default = /*#__PURE__*/__webpack_require__.n(autocomplete_js);
|
|
|
|
// EXTERNAL MODULE: ./src/navigatorLanguage.js
|
|
var navigatorLanguage = __webpack_require__(30);
|
|
|
|
// EXTERNAL MODULE: ./src/createAutocompleteDataset.js + 1 modules
|
|
var createAutocompleteDataset = __webpack_require__(19);
|
|
|
|
// CONCATENATED MODULE: ./src/icons/clear.svg
|
|
/* harmony default export */ var icons_clear = ("<svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M.566 1.698L0 1.13 1.132 0l.565.566L6 4.868 10.302.566 10.868 0 12 1.132l-.566.565L7.132 6l4.302 4.3.566.568L10.868 12l-.565-.566L6 7.132l-4.3 4.302L1.13 12 0 10.868l.566-.565L4.868 6 .566 1.698z\"/></svg>\n");
|
|
// EXTERNAL MODULE: ./src/icons/address.svg
|
|
var address = __webpack_require__(7);
|
|
|
|
// EXTERNAL MODULE: ./src/places.css
|
|
var places = __webpack_require__(15);
|
|
|
|
// EXTERNAL MODULE: ./node_modules/insert-css/index.js
|
|
var insert_css = __webpack_require__(18);
|
|
var insert_css_default = /*#__PURE__*/__webpack_require__.n(insert_css);
|
|
|
|
// CONCATENATED MODULE: ./src/errors.js
|
|
/* harmony default export */ var errors = ({
|
|
multiContainers: "Algolia Places: 'container' must point to a single <input> element.\nExample: instantiate the library twice if you want to bind two <inputs>.\n\nSee https://community.algolia.com/places/documentation.html#api-options-container",
|
|
badContainer: "Algolia Places: 'container' must point to an <input> element.\n\nSee https://community.algolia.com/places/documentation.html#api-options-container",
|
|
rateLimitReached: "Algolia Places: Current rate limit reached.\n\nSign up for a free 100,000 queries/month account at\nhttps://www.algolia.com/users/sign_up/places.\n\nOr upgrade your 100,000 queries/month plan by contacting us at\nhttps://community.algolia.com/places/contact.html.",
|
|
invalidCredentials: "The APP ID or API key provided is invalid.",
|
|
invalidAppId: "Your APP ID is invalid. A Places APP ID starts with 'pl'. You must create a valid Places app first.\n\nCreate a free Places app here: https://www.algolia.com/users/sign_up/places"
|
|
});
|
|
// EXTERNAL MODULE: ./src/configure/index.js
|
|
var configure = __webpack_require__(1);
|
|
|
|
// EXTERNAL MODULE: ./src/formatHit.js + 2 modules
|
|
var formatHit = __webpack_require__(9);
|
|
|
|
// EXTERNAL MODULE: ./src/version.js
|
|
var version = __webpack_require__(6);
|
|
|
|
// EXTERNAL MODULE: ./src/defaultTemplates.js + 10 modules
|
|
var defaultTemplates = __webpack_require__(8);
|
|
|
|
// CONCATENATED MODULE: ./src/createReverseGeocodingSource.js
|
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
|
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
|
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var filterApplicableParams = function filterApplicableParams(params) {
|
|
var hitsPerPage = params.hitsPerPage,
|
|
aroundLatLng = params.aroundLatLng,
|
|
getRankingInfo = params.getRankingInfo,
|
|
language = params.language;
|
|
var filtered = {};
|
|
|
|
if (typeof hitsPerPage === 'number') {
|
|
filtered.hitsPerPage = hitsPerPage;
|
|
}
|
|
|
|
if (typeof language === 'string') {
|
|
filtered.language = language;
|
|
}
|
|
|
|
if (typeof getRankingInfo === 'boolean') {
|
|
filtered.getRankingInfo = getRankingInfo;
|
|
}
|
|
|
|
if (typeof aroundLatLng === 'string') {
|
|
filtered.aroundLatLng = aroundLatLng;
|
|
}
|
|
|
|
return filtered;
|
|
};
|
|
|
|
var createReverseGeocodingSource_createReverseGeocodingSource = function createReverseGeocodingSource(_ref) {
|
|
var algoliasearch = _ref.algoliasearch,
|
|
clientOptions = _ref.clientOptions,
|
|
apiKey = _ref.apiKey,
|
|
appId = _ref.appId,
|
|
hitsPerPage = _ref.hitsPerPage,
|
|
aroundLatLng = _ref.aroundLatLng,
|
|
getRankingInfo = _ref.getRankingInfo,
|
|
_ref$formatInputValue = _ref.formatInputValue,
|
|
formatInputValue = _ref$formatInputValue === void 0 ? defaultTemplates["a" /* default */].value : _ref$formatInputValue,
|
|
_ref$language = _ref.language,
|
|
language = _ref$language === void 0 ? navigator.language.split('-')[0] : _ref$language,
|
|
_ref$onHits = _ref.onHits,
|
|
onHits = _ref$onHits === void 0 ? function () {} : _ref$onHits,
|
|
_ref$onError = _ref.onError,
|
|
onError = _ref$onError === void 0 ? function (e) {
|
|
throw e;
|
|
} : _ref$onError,
|
|
onRateLimitReached = _ref.onRateLimitReached,
|
|
onInvalidCredentials = _ref.onInvalidCredentials;
|
|
var placesClient = algoliasearch.initPlaces(appId, apiKey, clientOptions);
|
|
placesClient.as.addAlgoliaAgent("Algolia Places ".concat(version["default"]));
|
|
var configuration = Object(configure["a" /* default */])({
|
|
apiKey: apiKey,
|
|
appId: appId,
|
|
hitsPerPage: hitsPerPage,
|
|
aroundLatLng: aroundLatLng,
|
|
getRankingInfo: getRankingInfo,
|
|
language: language,
|
|
formatInputValue: formatInputValue,
|
|
onHits: onHits,
|
|
onError: onError,
|
|
onRateLimitReached: onRateLimitReached,
|
|
onInvalidCredentials: onInvalidCredentials
|
|
});
|
|
var params = filterApplicableParams(configuration.params);
|
|
var controls = configuration.controls;
|
|
|
|
var searcher = function searcher(queryAroundLatLng, cb) {
|
|
var finalAroundLatLng = queryAroundLatLng || params.aroundLatLng;
|
|
|
|
if (!finalAroundLatLng) {
|
|
var error = new Error('A location must be provided for reverse geocoding');
|
|
return Promise.reject(error);
|
|
}
|
|
|
|
return placesClient.reverse(_objectSpread(_objectSpread({}, params), {}, {
|
|
aroundLatLng: finalAroundLatLng
|
|
})).then(function (content) {
|
|
var hits = content.hits.map(function (hit, hitIndex) {
|
|
return Object(formatHit["a" /* default */])({
|
|
formatInputValue: controls.formatInputValue,
|
|
hit: hit,
|
|
hitIndex: hitIndex,
|
|
query: finalAroundLatLng,
|
|
rawAnswer: content
|
|
});
|
|
});
|
|
controls.onHits({
|
|
hits: hits,
|
|
query: finalAroundLatLng,
|
|
rawAnswer: content
|
|
});
|
|
return hits;
|
|
}).then(cb)["catch"](function (e) {
|
|
if (e.statusCode === 403 && e.message === 'Invalid Application-ID or API key') {
|
|
controls.onInvalidCredentials();
|
|
return;
|
|
} else if (e.statusCode === 429) {
|
|
controls.onRateLimitReached();
|
|
return;
|
|
}
|
|
|
|
controls.onError(e);
|
|
});
|
|
};
|
|
|
|
searcher.configure = function (partial) {
|
|
var updated = Object(configure["a" /* default */])(_objectSpread(_objectSpread(_objectSpread({}, params), controls), partial));
|
|
params = filterApplicableParams(updated.params);
|
|
controls = updated.controls;
|
|
return searcher;
|
|
};
|
|
|
|
return searcher;
|
|
};
|
|
|
|
/* harmony default export */ var src_createReverseGeocodingSource = (createReverseGeocodingSource_createReverseGeocodingSource);
|
|
// CONCATENATED MODULE: ./src/places.js
|
|
function places_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
|
|
function places_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { places_ownKeys(Object(source), true).forEach(function (key) { places_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { places_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
|
|
function places_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
|
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
|
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
|
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
|
|
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; 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"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
|
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
insert_css_default()(places["a" /* default */], {
|
|
prepend: true
|
|
});
|
|
|
|
|
|
|
|
var applyAttributes = function applyAttributes(elt, attrs) {
|
|
Object.entries(attrs).forEach(function (_ref) {
|
|
var _ref2 = _slicedToArray(_ref, 2),
|
|
name = _ref2[0],
|
|
value = _ref2[1];
|
|
|
|
elt.setAttribute(name, "".concat(value));
|
|
});
|
|
return elt;
|
|
};
|
|
|
|
function places_places(options) {
|
|
var container = options.container,
|
|
style = options.style,
|
|
accessibility = options.accessibility,
|
|
_options$autocomplete = options.autocompleteOptions,
|
|
userAutocompleteOptions = _options$autocomplete === void 0 ? {} : _options$autocomplete; // multiple DOM elements targeted
|
|
|
|
if (container instanceof NodeList) {
|
|
if (container.length > 1) {
|
|
throw new Error(errors.multiContainers);
|
|
} // if single node NodeList received, resolve to the first one
|
|
|
|
|
|
return places_places(places_objectSpread(places_objectSpread({}, options), {}, {
|
|
container: container[0]
|
|
}));
|
|
} // container sent as a string, resolve it for multiple DOM elements issue
|
|
|
|
|
|
if (typeof container === 'string') {
|
|
var resolvedContainer = document.querySelectorAll(container);
|
|
return places_places(places_objectSpread(places_objectSpread({}, options), {}, {
|
|
container: resolvedContainer
|
|
}));
|
|
} // if not an <input>, error
|
|
|
|
|
|
if (!(container instanceof HTMLInputElement)) {
|
|
throw new Error(errors.badContainer);
|
|
}
|
|
|
|
var placesInstance = new events_default.a();
|
|
var prefix = "ap".concat(style === false ? '-nostyle' : '');
|
|
|
|
var autocompleteOptions = places_objectSpread({
|
|
autoselect: true,
|
|
hint: false,
|
|
cssClasses: {
|
|
root: "algolia-places".concat(style === false ? '-nostyle' : ''),
|
|
prefix: prefix
|
|
},
|
|
debug: "production" === 'development'
|
|
}, userAutocompleteOptions);
|
|
|
|
var autocompleteDataset = Object(createAutocompleteDataset["default"])(places_objectSpread(places_objectSpread({}, options), {}, {
|
|
algoliasearch: algoliasearchLite_default.a,
|
|
onHits: function onHits(_ref3) {
|
|
var hits = _ref3.hits,
|
|
rawAnswer = _ref3.rawAnswer,
|
|
query = _ref3.query;
|
|
return placesInstance.emit('suggestions', {
|
|
rawAnswer: rawAnswer,
|
|
query: query,
|
|
suggestions: hits
|
|
});
|
|
},
|
|
onError: function onError(e) {
|
|
return placesInstance.emit('error', e);
|
|
},
|
|
onRateLimitReached: function onRateLimitReached() {
|
|
var listeners = placesInstance.listenerCount('limit');
|
|
|
|
if (listeners === 0) {
|
|
console.log(errors.rateLimitReached); // eslint-disable-line no-console
|
|
|
|
return;
|
|
}
|
|
|
|
placesInstance.emit('limit', {
|
|
message: errors.rateLimitReached
|
|
});
|
|
},
|
|
onInvalidCredentials: function onInvalidCredentials() {
|
|
if (options && options.appId && options.appId.startsWith('pl')) {
|
|
console.error(errors.invalidCredentials); // eslint-disable-line no-console
|
|
} else {
|
|
console.error(errors.invalidAppId); // eslint-disable-line no-console
|
|
}
|
|
},
|
|
container: undefined
|
|
}));
|
|
var autocompleteInstance = autocomplete_js_default()(container, autocompleteOptions, autocompleteDataset);
|
|
var autocompleteContainer = container.parentNode;
|
|
var autocompleteChangeEvents = ['selected', 'autocompleted'];
|
|
autocompleteChangeEvents.forEach(function (eventName) {
|
|
autocompleteInstance.on("autocomplete:".concat(eventName), function (_, suggestion) {
|
|
placesInstance.emit('change', {
|
|
rawAnswer: suggestion.rawAnswer,
|
|
query: suggestion.query,
|
|
suggestion: suggestion,
|
|
suggestionIndex: suggestion.hitIndex
|
|
});
|
|
});
|
|
});
|
|
autocompleteInstance.on('autocomplete:cursorchanged', function (_, suggestion) {
|
|
placesInstance.emit('cursorchanged', {
|
|
rawAnswer: suggestion.rawAnswer,
|
|
query: suggestion.query,
|
|
suggestion: suggestion,
|
|
suggestionIndex: suggestion.hitIndex
|
|
});
|
|
});
|
|
var clear = document.createElement('button');
|
|
clear.setAttribute('type', 'button');
|
|
clear.setAttribute('aria-label', 'clear');
|
|
|
|
if (accessibility && accessibility.clearButton && accessibility.clearButton instanceof Object) {
|
|
applyAttributes(clear, accessibility.clearButton);
|
|
}
|
|
|
|
clear.classList.add("".concat(prefix, "-input-icon"));
|
|
clear.classList.add("".concat(prefix, "-icon-clear"));
|
|
clear.innerHTML = icons_clear;
|
|
autocompleteContainer.appendChild(clear);
|
|
clear.style.display = 'none';
|
|
var pin = document.createElement('button');
|
|
pin.setAttribute('type', 'button');
|
|
pin.setAttribute('aria-label', 'focus');
|
|
|
|
if (accessibility && accessibility.pinButton && accessibility.pinButton instanceof Object) {
|
|
applyAttributes(pin, accessibility.pinButton);
|
|
}
|
|
|
|
pin.classList.add("".concat(prefix, "-input-icon"));
|
|
pin.classList.add("".concat(prefix, "-icon-pin"));
|
|
pin.innerHTML = address["a" /* default */];
|
|
autocompleteContainer.appendChild(pin);
|
|
pin.addEventListener('click', function () {
|
|
autocompleteDataset.source.configure({
|
|
useDeviceLocation: true
|
|
});
|
|
autocompleteInstance.focus();
|
|
placesInstance.emit('locate');
|
|
});
|
|
clear.addEventListener('click', function () {
|
|
autocompleteInstance.autocomplete.setVal('');
|
|
autocompleteInstance.focus();
|
|
clear.style.display = 'none';
|
|
pin.style.display = '';
|
|
placesInstance.emit('clear');
|
|
});
|
|
var previousQuery = '';
|
|
|
|
var inputListener = function inputListener() {
|
|
var query = autocompleteInstance.val();
|
|
|
|
if (query === '') {
|
|
pin.style.display = '';
|
|
clear.style.display = 'none';
|
|
|
|
if (previousQuery !== query) {
|
|
placesInstance.emit('clear');
|
|
}
|
|
} else {
|
|
clear.style.display = '';
|
|
pin.style.display = 'none';
|
|
}
|
|
|
|
previousQuery = query;
|
|
};
|
|
|
|
autocompleteContainer.querySelector(".".concat(prefix, "-input")).addEventListener('input', inputListener);
|
|
var autocompleteIsomorphicMethods = ['open', 'close'];
|
|
autocompleteIsomorphicMethods.forEach(function (methodName) {
|
|
placesInstance[methodName] = function () {
|
|
var _autocompleteInstance;
|
|
|
|
(_autocompleteInstance = autocompleteInstance.autocomplete)[methodName].apply(_autocompleteInstance, arguments);
|
|
};
|
|
});
|
|
|
|
placesInstance.getVal = function () {
|
|
return autocompleteInstance.val();
|
|
};
|
|
|
|
placesInstance.destroy = function () {
|
|
var _autocompleteInstance2;
|
|
|
|
autocompleteContainer.querySelector(".".concat(prefix, "-input")).removeEventListener('input', inputListener);
|
|
|
|
(_autocompleteInstance2 = autocompleteInstance.autocomplete).destroy.apply(_autocompleteInstance2, arguments);
|
|
};
|
|
|
|
placesInstance.setVal = function () {
|
|
var _autocompleteInstance3;
|
|
|
|
previousQuery = arguments.length <= 0 ? undefined : arguments[0];
|
|
|
|
if (previousQuery === '') {
|
|
pin.style.display = '';
|
|
clear.style.display = 'none';
|
|
} else {
|
|
clear.style.display = '';
|
|
pin.style.display = 'none';
|
|
}
|
|
|
|
(_autocompleteInstance3 = autocompleteInstance.autocomplete).setVal.apply(_autocompleteInstance3, arguments);
|
|
};
|
|
|
|
placesInstance.autocomplete = autocompleteInstance;
|
|
|
|
placesInstance.search = function () {
|
|
var query = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
return new Promise(function (resolve) {
|
|
autocompleteDataset.source(query, resolve);
|
|
});
|
|
};
|
|
|
|
placesInstance.configure = function (configuration) {
|
|
var safeConfig = places_objectSpread({}, configuration);
|
|
|
|
delete safeConfig.onHits;
|
|
delete safeConfig.onError;
|
|
delete safeConfig.onRateLimitReached;
|
|
delete safeConfig.onInvalidCredentials;
|
|
delete safeConfig.templates;
|
|
autocompleteDataset.source.configure(safeConfig);
|
|
return placesInstance;
|
|
};
|
|
|
|
placesInstance.reverse = src_createReverseGeocodingSource(places_objectSpread(places_objectSpread({}, options), {}, {
|
|
algoliasearch: algoliasearchLite_default.a,
|
|
formatInputValue: (options.templates || {}).value,
|
|
onHits: function onHits(_ref4) {
|
|
var hits = _ref4.hits,
|
|
rawAnswer = _ref4.rawAnswer,
|
|
query = _ref4.query;
|
|
return placesInstance.emit('reverse', {
|
|
rawAnswer: rawAnswer,
|
|
query: query,
|
|
suggestions: hits
|
|
});
|
|
},
|
|
onError: function onError(e) {
|
|
return placesInstance.emit('error', e);
|
|
},
|
|
onRateLimitReached: function onRateLimitReached() {
|
|
var listeners = placesInstance.listenerCount('limit');
|
|
|
|
if (listeners === 0) {
|
|
console.log(errors.rateLimitReached); // eslint-disable-line no-console
|
|
|
|
return;
|
|
}
|
|
|
|
placesInstance.emit('limit', {
|
|
message: errors.rateLimitReached
|
|
});
|
|
},
|
|
onInvalidCredentials: function onInvalidCredentials() {
|
|
if (options && options.appId && options.appId.startsWith('pl')) {
|
|
console.error(errors.invalidCredentials); // eslint-disable-line no-console
|
|
} else {
|
|
console.error(errors.invalidAppId); // eslint-disable-line no-console
|
|
}
|
|
}
|
|
}));
|
|
return placesInstance;
|
|
}
|
|
|
|
/***/ }),
|
|
/* 34 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/* WEBPACK VAR INJECTION */(function(process) {module.exports = AlgoliaSearchCore;
|
|
|
|
var errors = __webpack_require__(11);
|
|
var exitPromise = __webpack_require__(35);
|
|
var IndexCore = __webpack_require__(36);
|
|
var store = __webpack_require__(42);
|
|
|
|
// We will always put the API KEY in the JSON body in case of too long API KEY,
|
|
// to avoid query string being too long and failing in various conditions (our server limit, browser limit,
|
|
// proxies limit)
|
|
var MAX_API_KEY_LENGTH = 500;
|
|
var RESET_APP_DATA_TIMER =
|
|
process.env.RESET_APP_DATA_TIMER && parseInt(process.env.RESET_APP_DATA_TIMER, 10) ||
|
|
60 * 2 * 1000; // after 2 minutes reset to first host
|
|
|
|
/*
|
|
* Algolia Search library initialization
|
|
* https://www.algolia.com/
|
|
*
|
|
* @param {string} applicationID - Your applicationID, found in your dashboard
|
|
* @param {string} apiKey - Your API key, found in your dashboard
|
|
* @param {Object} [opts]
|
|
* @param {number} [opts.timeout=2000] - The request timeout set in milliseconds,
|
|
* another request will be issued after this timeout
|
|
* @param {string} [opts.protocol='https:'] - The protocol used to query Algolia Search API.
|
|
* Set to 'http:' to force using http.
|
|
* @param {Object|Array} [opts.hosts={
|
|
* read: [this.applicationID + '-dsn.algolia.net'].concat([
|
|
* this.applicationID + '-1.algolianet.com',
|
|
* this.applicationID + '-2.algolianet.com',
|
|
* this.applicationID + '-3.algolianet.com']
|
|
* ]),
|
|
* write: [this.applicationID + '.algolia.net'].concat([
|
|
* this.applicationID + '-1.algolianet.com',
|
|
* this.applicationID + '-2.algolianet.com',
|
|
* this.applicationID + '-3.algolianet.com']
|
|
* ]) - The hosts to use for Algolia Search API.
|
|
* If you provide them, you will less benefit from our HA implementation
|
|
*/
|
|
function AlgoliaSearchCore(applicationID, apiKey, opts) {
|
|
var debug = __webpack_require__(14)('algoliasearch');
|
|
|
|
var clone = __webpack_require__(4);
|
|
var isArray = __webpack_require__(12);
|
|
var map = __webpack_require__(13);
|
|
|
|
var usage = 'Usage: algoliasearch(applicationID, apiKey, opts)';
|
|
|
|
if (opts._allowEmptyCredentials !== true && !applicationID) {
|
|
throw new errors.AlgoliaSearchError('Please provide an application ID. ' + usage);
|
|
}
|
|
|
|
if (opts._allowEmptyCredentials !== true && !apiKey) {
|
|
throw new errors.AlgoliaSearchError('Please provide an API key. ' + usage);
|
|
}
|
|
|
|
this.applicationID = applicationID;
|
|
this.apiKey = apiKey;
|
|
|
|
this.hosts = {
|
|
read: [],
|
|
write: []
|
|
};
|
|
|
|
opts = opts || {};
|
|
|
|
this._timeouts = opts.timeouts || {
|
|
connect: 1 * 1000, // 500ms connect is GPRS latency
|
|
read: 2 * 1000,
|
|
write: 30 * 1000
|
|
};
|
|
|
|
// backward compat, if opts.timeout is passed, we use it to configure all timeouts like before
|
|
if (opts.timeout) {
|
|
this._timeouts.connect = this._timeouts.read = this._timeouts.write = opts.timeout;
|
|
}
|
|
|
|
var protocol = opts.protocol || 'https:';
|
|
// while we advocate for colon-at-the-end values: 'http:' for `opts.protocol`
|
|
// we also accept `http` and `https`. It's a common error.
|
|
if (!/:$/.test(protocol)) {
|
|
protocol = protocol + ':';
|
|
}
|
|
|
|
if (protocol !== 'http:' && protocol !== 'https:') {
|
|
throw new errors.AlgoliaSearchError('protocol must be `http:` or `https:` (was `' + opts.protocol + '`)');
|
|
}
|
|
|
|
this._checkAppIdData();
|
|
|
|
if (!opts.hosts) {
|
|
var defaultHosts = map(this._shuffleResult, function(hostNumber) {
|
|
return applicationID + '-' + hostNumber + '.algolianet.com';
|
|
});
|
|
|
|
// no hosts given, compute defaults
|
|
var mainSuffix = (opts.dsn === false ? '' : '-dsn') + '.algolia.net';
|
|
this.hosts.read = [this.applicationID + mainSuffix].concat(defaultHosts);
|
|
this.hosts.write = [this.applicationID + '.algolia.net'].concat(defaultHosts);
|
|
} else if (isArray(opts.hosts)) {
|
|
// when passing custom hosts, we need to have a different host index if the number
|
|
// of write/read hosts are different.
|
|
this.hosts.read = clone(opts.hosts);
|
|
this.hosts.write = clone(opts.hosts);
|
|
} else {
|
|
this.hosts.read = clone(opts.hosts.read);
|
|
this.hosts.write = clone(opts.hosts.write);
|
|
}
|
|
|
|
// add protocol and lowercase hosts
|
|
this.hosts.read = map(this.hosts.read, prepareHost(protocol));
|
|
this.hosts.write = map(this.hosts.write, prepareHost(protocol));
|
|
|
|
this.extraHeaders = {};
|
|
|
|
// In some situations you might want to warm the cache
|
|
this.cache = opts._cache || {};
|
|
|
|
this._ua = opts._ua;
|
|
this._useCache = opts._useCache === undefined || opts._cache ? true : opts._useCache;
|
|
this._useRequestCache = this._useCache && opts._useRequestCache;
|
|
this._useFallback = opts.useFallback === undefined ? true : opts.useFallback;
|
|
|
|
this._setTimeout = opts._setTimeout;
|
|
|
|
debug('init done, %j', this);
|
|
}
|
|
|
|
/*
|
|
* Get the index object initialized
|
|
*
|
|
* @param indexName the name of index
|
|
* @param callback the result callback with one argument (the Index instance)
|
|
*/
|
|
AlgoliaSearchCore.prototype.initIndex = function(indexName) {
|
|
return new IndexCore(this, indexName);
|
|
};
|
|
|
|
/**
|
|
* Add an extra field to the HTTP request
|
|
*
|
|
* @param name the header field name
|
|
* @param value the header field value
|
|
*/
|
|
AlgoliaSearchCore.prototype.setExtraHeader = function(name, value) {
|
|
this.extraHeaders[name.toLowerCase()] = value;
|
|
};
|
|
|
|
/**
|
|
* Get the value of an extra HTTP header
|
|
*
|
|
* @param name the header field name
|
|
*/
|
|
AlgoliaSearchCore.prototype.getExtraHeader = function(name) {
|
|
return this.extraHeaders[name.toLowerCase()];
|
|
};
|
|
|
|
/**
|
|
* Remove an extra field from the HTTP request
|
|
*
|
|
* @param name the header field name
|
|
*/
|
|
AlgoliaSearchCore.prototype.unsetExtraHeader = function(name) {
|
|
delete this.extraHeaders[name.toLowerCase()];
|
|
};
|
|
|
|
/**
|
|
* Augment sent x-algolia-agent with more data, each agent part
|
|
* is automatically separated from the others by a semicolon;
|
|
*
|
|
* @param algoliaAgent the agent to add
|
|
*/
|
|
AlgoliaSearchCore.prototype.addAlgoliaAgent = function(algoliaAgent) {
|
|
var algoliaAgentWithDelimiter = '; ' + algoliaAgent;
|
|
|
|
if (this._ua.indexOf(algoliaAgentWithDelimiter) === -1) {
|
|
this._ua += algoliaAgentWithDelimiter;
|
|
}
|
|
};
|
|
|
|
/*
|
|
* Wrapper that try all hosts to maximize the quality of service
|
|
*/
|
|
AlgoliaSearchCore.prototype._jsonRequest = function(initialOpts) {
|
|
this._checkAppIdData();
|
|
|
|
var requestDebug = __webpack_require__(14)('algoliasearch:' + initialOpts.url);
|
|
|
|
|
|
var body;
|
|
var cacheID;
|
|
var additionalUA = initialOpts.additionalUA || '';
|
|
var cache = initialOpts.cache;
|
|
var client = this;
|
|
var tries = 0;
|
|
var usingFallback = false;
|
|
var hasFallback = client._useFallback && client._request.fallback && initialOpts.fallback;
|
|
var headers;
|
|
|
|
if (
|
|
this.apiKey.length > MAX_API_KEY_LENGTH &&
|
|
initialOpts.body !== undefined &&
|
|
(initialOpts.body.params !== undefined || // index.search()
|
|
initialOpts.body.requests !== undefined) // client.search()
|
|
) {
|
|
initialOpts.body.apiKey = this.apiKey;
|
|
headers = this._computeRequestHeaders({
|
|
additionalUA: additionalUA,
|
|
withApiKey: false,
|
|
headers: initialOpts.headers
|
|
});
|
|
} else {
|
|
headers = this._computeRequestHeaders({
|
|
additionalUA: additionalUA,
|
|
headers: initialOpts.headers
|
|
});
|
|
}
|
|
|
|
if (initialOpts.body !== undefined) {
|
|
body = safeJSONStringify(initialOpts.body);
|
|
}
|
|
|
|
requestDebug('request start');
|
|
var debugData = [];
|
|
|
|
|
|
function doRequest(requester, reqOpts) {
|
|
client._checkAppIdData();
|
|
|
|
var startTime = new Date();
|
|
|
|
if (client._useCache && !client._useRequestCache) {
|
|
cacheID = initialOpts.url;
|
|
}
|
|
|
|
// as we sometime use POST requests to pass parameters (like query='aa'),
|
|
// the cacheID must also include the body to be different between calls
|
|
if (client._useCache && !client._useRequestCache && body) {
|
|
cacheID += '_body_' + reqOpts.body;
|
|
}
|
|
|
|
// handle cache existence
|
|
if (isCacheValidWithCurrentID(!client._useRequestCache, cache, cacheID)) {
|
|
requestDebug('serving response from cache');
|
|
|
|
var responseText = cache[cacheID];
|
|
|
|
// Cache response must match the type of the original one
|
|
return client._promise.resolve({
|
|
body: JSON.parse(responseText),
|
|
responseText: responseText
|
|
});
|
|
}
|
|
|
|
// if we reached max tries
|
|
if (tries >= client.hosts[initialOpts.hostType].length) {
|
|
if (!hasFallback || usingFallback) {
|
|
requestDebug('could not get any response');
|
|
// then stop
|
|
return client._promise.reject(new errors.AlgoliaSearchError(
|
|
'Cannot connect to the AlgoliaSearch API.' +
|
|
' Send an email to support@algolia.com to report and resolve the issue.' +
|
|
' Application id was: ' + client.applicationID, {debugData: debugData}
|
|
));
|
|
}
|
|
|
|
requestDebug('switching to fallback');
|
|
|
|
// let's try the fallback starting from here
|
|
tries = 0;
|
|
|
|
// method, url and body are fallback dependent
|
|
reqOpts.method = initialOpts.fallback.method;
|
|
reqOpts.url = initialOpts.fallback.url;
|
|
reqOpts.jsonBody = initialOpts.fallback.body;
|
|
if (reqOpts.jsonBody) {
|
|
reqOpts.body = safeJSONStringify(reqOpts.jsonBody);
|
|
}
|
|
// re-compute headers, they could be omitting the API KEY
|
|
headers = client._computeRequestHeaders({
|
|
additionalUA: additionalUA,
|
|
headers: initialOpts.headers
|
|
});
|
|
|
|
reqOpts.timeouts = client._getTimeoutsForRequest(initialOpts.hostType);
|
|
client._setHostIndexByType(0, initialOpts.hostType);
|
|
usingFallback = true; // the current request is now using fallback
|
|
return doRequest(client._request.fallback, reqOpts);
|
|
}
|
|
|
|
var currentHost = client._getHostByType(initialOpts.hostType);
|
|
|
|
var url = currentHost + reqOpts.url;
|
|
var options = {
|
|
body: reqOpts.body,
|
|
jsonBody: reqOpts.jsonBody,
|
|
method: reqOpts.method,
|
|
headers: headers,
|
|
timeouts: reqOpts.timeouts,
|
|
debug: requestDebug,
|
|
forceAuthHeaders: reqOpts.forceAuthHeaders
|
|
};
|
|
|
|
requestDebug('method: %s, url: %s, headers: %j, timeouts: %d',
|
|
options.method, url, options.headers, options.timeouts);
|
|
|
|
if (requester === client._request.fallback) {
|
|
requestDebug('using fallback');
|
|
}
|
|
|
|
// `requester` is any of this._request or this._request.fallback
|
|
// thus it needs to be called using the client as context
|
|
return requester.call(client, url, options).then(success, tryFallback);
|
|
|
|
function success(httpResponse) {
|
|
// compute the status of the response,
|
|
//
|
|
// When in browser mode, using XDR or JSONP, we have no statusCode available
|
|
// So we rely on our API response `status` property.
|
|
// But `waitTask` can set a `status` property which is not the statusCode (it's the task status)
|
|
// So we check if there's a `message` along `status` and it means it's an error
|
|
//
|
|
// That's the only case where we have a response.status that's not the http statusCode
|
|
var status = httpResponse && httpResponse.body && httpResponse.body.message && httpResponse.body.status ||
|
|
|
|
// this is important to check the request statusCode AFTER the body eventual
|
|
// statusCode because some implementations (jQuery XDomainRequest transport) may
|
|
// send statusCode 200 while we had an error
|
|
httpResponse.statusCode ||
|
|
|
|
// When in browser mode, using XDR or JSONP
|
|
// we default to success when no error (no response.status && response.message)
|
|
// If there was a JSON.parse() error then body is null and it fails
|
|
httpResponse && httpResponse.body && 200;
|
|
|
|
requestDebug('received response: statusCode: %s, computed statusCode: %d, headers: %j',
|
|
httpResponse.statusCode, status, httpResponse.headers);
|
|
|
|
var httpResponseOk = Math.floor(status / 100) === 2;
|
|
|
|
var endTime = new Date();
|
|
debugData.push({
|
|
currentHost: currentHost,
|
|
headers: removeCredentials(headers),
|
|
content: body || null,
|
|
contentLength: body !== undefined ? body.length : null,
|
|
method: reqOpts.method,
|
|
timeouts: reqOpts.timeouts,
|
|
url: reqOpts.url,
|
|
startTime: startTime,
|
|
endTime: endTime,
|
|
duration: endTime - startTime,
|
|
statusCode: status
|
|
});
|
|
|
|
if (httpResponseOk) {
|
|
if (client._useCache && !client._useRequestCache && cache) {
|
|
cache[cacheID] = httpResponse.responseText;
|
|
}
|
|
|
|
return {
|
|
responseText: httpResponse.responseText,
|
|
body: httpResponse.body
|
|
};
|
|
}
|
|
|
|
var shouldRetry = Math.floor(status / 100) !== 4;
|
|
|
|
if (shouldRetry) {
|
|
tries += 1;
|
|
return retryRequest();
|
|
}
|
|
|
|
requestDebug('unrecoverable error');
|
|
|
|
// no success and no retry => fail
|
|
var unrecoverableError = new errors.AlgoliaSearchError(
|
|
httpResponse.body && httpResponse.body.message, {debugData: debugData, statusCode: status}
|
|
);
|
|
|
|
return client._promise.reject(unrecoverableError);
|
|
}
|
|
|
|
function tryFallback(err) {
|
|
// error cases:
|
|
// While not in fallback mode:
|
|
// - CORS not supported
|
|
// - network error
|
|
// While in fallback mode:
|
|
// - timeout
|
|
// - network error
|
|
// - badly formatted JSONP (script loaded, did not call our callback)
|
|
// In both cases:
|
|
// - uncaught exception occurs (TypeError)
|
|
requestDebug('error: %s, stack: %s', err.message, err.stack);
|
|
|
|
var endTime = new Date();
|
|
debugData.push({
|
|
currentHost: currentHost,
|
|
headers: removeCredentials(headers),
|
|
content: body || null,
|
|
contentLength: body !== undefined ? body.length : null,
|
|
method: reqOpts.method,
|
|
timeouts: reqOpts.timeouts,
|
|
url: reqOpts.url,
|
|
startTime: startTime,
|
|
endTime: endTime,
|
|
duration: endTime - startTime
|
|
});
|
|
|
|
if (!(err instanceof errors.AlgoliaSearchError)) {
|
|
err = new errors.Unknown(err && err.message, err);
|
|
}
|
|
|
|
tries += 1;
|
|
|
|
// stop the request implementation when:
|
|
if (
|
|
// we did not generate this error,
|
|
// it comes from a throw in some other piece of code
|
|
err instanceof errors.Unknown ||
|
|
|
|
// server sent unparsable JSON
|
|
err instanceof errors.UnparsableJSON ||
|
|
|
|
// max tries and already using fallback or no fallback
|
|
tries >= client.hosts[initialOpts.hostType].length &&
|
|
(usingFallback || !hasFallback)) {
|
|
// stop request implementation for this command
|
|
err.debugData = debugData;
|
|
return client._promise.reject(err);
|
|
}
|
|
|
|
// When a timeout occurred, retry by raising timeout
|
|
if (err instanceof errors.RequestTimeout) {
|
|
return retryRequestWithHigherTimeout();
|
|
}
|
|
|
|
return retryRequest();
|
|
}
|
|
|
|
function retryRequest() {
|
|
requestDebug('retrying request');
|
|
client._incrementHostIndex(initialOpts.hostType);
|
|
return doRequest(requester, reqOpts);
|
|
}
|
|
|
|
function retryRequestWithHigherTimeout() {
|
|
requestDebug('retrying request with higher timeout');
|
|
client._incrementHostIndex(initialOpts.hostType);
|
|
client._incrementTimeoutMultipler();
|
|
reqOpts.timeouts = client._getTimeoutsForRequest(initialOpts.hostType);
|
|
return doRequest(requester, reqOpts);
|
|
}
|
|
}
|
|
|
|
function isCacheValidWithCurrentID(
|
|
useRequestCache,
|
|
currentCache,
|
|
currentCacheID
|
|
) {
|
|
return (
|
|
client._useCache &&
|
|
useRequestCache &&
|
|
currentCache &&
|
|
currentCache[currentCacheID] !== undefined
|
|
);
|
|
}
|
|
|
|
|
|
function interopCallbackReturn(request, callback) {
|
|
if (isCacheValidWithCurrentID(client._useRequestCache, cache, cacheID)) {
|
|
request.catch(function() {
|
|
// Release the cache on error
|
|
delete cache[cacheID];
|
|
});
|
|
}
|
|
|
|
if (typeof initialOpts.callback === 'function') {
|
|
// either we have a callback
|
|
request.then(function okCb(content) {
|
|
exitPromise(function() {
|
|
initialOpts.callback(null, callback(content));
|
|
}, client._setTimeout || setTimeout);
|
|
}, function nookCb(err) {
|
|
exitPromise(function() {
|
|
initialOpts.callback(err);
|
|
}, client._setTimeout || setTimeout);
|
|
});
|
|
} else {
|
|
// either we are using promises
|
|
return request.then(callback);
|
|
}
|
|
}
|
|
|
|
if (client._useCache && client._useRequestCache) {
|
|
cacheID = initialOpts.url;
|
|
}
|
|
|
|
// as we sometime use POST requests to pass parameters (like query='aa'),
|
|
// the cacheID must also include the body to be different between calls
|
|
if (client._useCache && client._useRequestCache && body) {
|
|
cacheID += '_body_' + body;
|
|
}
|
|
|
|
if (isCacheValidWithCurrentID(client._useRequestCache, cache, cacheID)) {
|
|
requestDebug('serving request from cache');
|
|
|
|
var maybePromiseForCache = cache[cacheID];
|
|
|
|
// In case the cache is warmup with value that is not a promise
|
|
var promiseForCache = typeof maybePromiseForCache.then !== 'function'
|
|
? client._promise.resolve({responseText: maybePromiseForCache})
|
|
: maybePromiseForCache;
|
|
|
|
return interopCallbackReturn(promiseForCache, function(content) {
|
|
// In case of the cache request, return the original value
|
|
return JSON.parse(content.responseText);
|
|
});
|
|
}
|
|
|
|
var request = doRequest(
|
|
client._request, {
|
|
url: initialOpts.url,
|
|
method: initialOpts.method,
|
|
body: body,
|
|
jsonBody: initialOpts.body,
|
|
timeouts: client._getTimeoutsForRequest(initialOpts.hostType),
|
|
forceAuthHeaders: initialOpts.forceAuthHeaders
|
|
}
|
|
);
|
|
|
|
if (client._useCache && client._useRequestCache && cache) {
|
|
cache[cacheID] = request;
|
|
}
|
|
|
|
return interopCallbackReturn(request, function(content) {
|
|
// In case of the first request, return the JSON value
|
|
return content.body;
|
|
});
|
|
};
|
|
|
|
/*
|
|
* Transform search param object in query string
|
|
* @param {object} args arguments to add to the current query string
|
|
* @param {string} params current query string
|
|
* @return {string} the final query string
|
|
*/
|
|
AlgoliaSearchCore.prototype._getSearchParams = function(args, params) {
|
|
if (args === undefined || args === null) {
|
|
return params;
|
|
}
|
|
for (var key in args) {
|
|
if (key !== null && args[key] !== undefined && args.hasOwnProperty(key)) {
|
|
params += params === '' ? '' : '&';
|
|
params += key + '=' + encodeURIComponent(Object.prototype.toString.call(args[key]) === '[object Array]' ? safeJSONStringify(args[key]) : args[key]);
|
|
}
|
|
}
|
|
return params;
|
|
};
|
|
|
|
/**
|
|
* Compute the headers for a request
|
|
*
|
|
* @param [string] options.additionalUA semi-colon separated string with other user agents to add
|
|
* @param [boolean=true] options.withApiKey Send the api key as a header
|
|
* @param [Object] options.headers Extra headers to send
|
|
*/
|
|
AlgoliaSearchCore.prototype._computeRequestHeaders = function(options) {
|
|
var forEach = __webpack_require__(3);
|
|
|
|
var ua = options.additionalUA ?
|
|
this._ua + '; ' + options.additionalUA :
|
|
this._ua;
|
|
|
|
var requestHeaders = {
|
|
'x-algolia-agent': ua,
|
|
'x-algolia-application-id': this.applicationID
|
|
};
|
|
|
|
// browser will inline headers in the url, node.js will use http headers
|
|
// but in some situations, the API KEY will be too long (big secured API keys)
|
|
// so if the request is a POST and the KEY is very long, we will be asked to not put
|
|
// it into headers but in the JSON body
|
|
if (options.withApiKey !== false) {
|
|
requestHeaders['x-algolia-api-key'] = this.apiKey;
|
|
}
|
|
|
|
if (this.userToken) {
|
|
requestHeaders['x-algolia-usertoken'] = this.userToken;
|
|
}
|
|
|
|
if (this.securityTags) {
|
|
requestHeaders['x-algolia-tagfilters'] = this.securityTags;
|
|
}
|
|
|
|
forEach(this.extraHeaders, function addToRequestHeaders(value, key) {
|
|
requestHeaders[key] = value;
|
|
});
|
|
|
|
if (options.headers) {
|
|
forEach(options.headers, function addToRequestHeaders(value, key) {
|
|
requestHeaders[key] = value;
|
|
});
|
|
}
|
|
|
|
return requestHeaders;
|
|
};
|
|
|
|
/**
|
|
* Search through multiple indices at the same time
|
|
* @param {Object[]} queries An array of queries you want to run.
|
|
* @param {string} queries[].indexName The index name you want to target
|
|
* @param {string} [queries[].query] The query to issue on this index. Can also be passed into `params`
|
|
* @param {Object} queries[].params Any search param like hitsPerPage, ..
|
|
* @param {Function} callback Callback to be called
|
|
* @return {Promise|undefined} Returns a promise if no callback given
|
|
*/
|
|
AlgoliaSearchCore.prototype.search = function(queries, opts, callback) {
|
|
var isArray = __webpack_require__(12);
|
|
var map = __webpack_require__(13);
|
|
|
|
var usage = 'Usage: client.search(arrayOfQueries[, callback])';
|
|
|
|
if (!isArray(queries)) {
|
|
throw new Error(usage);
|
|
}
|
|
|
|
if (typeof opts === 'function') {
|
|
callback = opts;
|
|
opts = {};
|
|
} else if (opts === undefined) {
|
|
opts = {};
|
|
}
|
|
|
|
var client = this;
|
|
|
|
var postObj = {
|
|
requests: map(queries, function prepareRequest(query) {
|
|
var params = '';
|
|
|
|
// allow query.query
|
|
// so we are mimicing the index.search(query, params) method
|
|
// {indexName:, query:, params:}
|
|
if (query.query !== undefined) {
|
|
params += 'query=' + encodeURIComponent(query.query);
|
|
}
|
|
|
|
return {
|
|
indexName: query.indexName,
|
|
params: client._getSearchParams(query.params, params)
|
|
};
|
|
})
|
|
};
|
|
|
|
var JSONPParams = map(postObj.requests, function prepareJSONPParams(request, requestId) {
|
|
return requestId + '=' +
|
|
encodeURIComponent(
|
|
'/1/indexes/' + encodeURIComponent(request.indexName) + '?' +
|
|
request.params
|
|
);
|
|
}).join('&');
|
|
|
|
var url = '/1/indexes/*/queries';
|
|
|
|
if (opts.strategy !== undefined) {
|
|
postObj.strategy = opts.strategy;
|
|
}
|
|
|
|
return this._jsonRequest({
|
|
cache: this.cache,
|
|
method: 'POST',
|
|
url: url,
|
|
body: postObj,
|
|
hostType: 'read',
|
|
fallback: {
|
|
method: 'GET',
|
|
url: '/1/indexes/*',
|
|
body: {
|
|
params: JSONPParams
|
|
}
|
|
},
|
|
callback: callback
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Search for facet values
|
|
* https://www.algolia.com/doc/rest-api/search#search-for-facet-values
|
|
* This is the top-level API for SFFV.
|
|
*
|
|
* @param {object[]} queries An array of queries to run.
|
|
* @param {string} queries[].indexName Index name, name of the index to search.
|
|
* @param {object} queries[].params Query parameters.
|
|
* @param {string} queries[].params.facetName Facet name, name of the attribute to search for values in.
|
|
* Must be declared as a facet
|
|
* @param {string} queries[].params.facetQuery Query for the facet search
|
|
* @param {string} [queries[].params.*] Any search parameter of Algolia,
|
|
* see https://www.algolia.com/doc/api-client/javascript/search#search-parameters
|
|
* Pagination is not supported. The page and hitsPerPage parameters will be ignored.
|
|
*/
|
|
AlgoliaSearchCore.prototype.searchForFacetValues = function(queries) {
|
|
var isArray = __webpack_require__(12);
|
|
var map = __webpack_require__(13);
|
|
|
|
var usage = 'Usage: client.searchForFacetValues([{indexName, params: {facetName, facetQuery, ...params}}, ...queries])'; // eslint-disable-line max-len
|
|
|
|
if (!isArray(queries)) {
|
|
throw new Error(usage);
|
|
}
|
|
|
|
var client = this;
|
|
|
|
return client._promise.all(map(queries, function performQuery(query) {
|
|
if (
|
|
!query ||
|
|
query.indexName === undefined ||
|
|
query.params.facetName === undefined ||
|
|
query.params.facetQuery === undefined
|
|
) {
|
|
throw new Error(usage);
|
|
}
|
|
|
|
var clone = __webpack_require__(4);
|
|
var omit = __webpack_require__(23);
|
|
|
|
var indexName = query.indexName;
|
|
var params = query.params;
|
|
|
|
var facetName = params.facetName;
|
|
var filteredParams = omit(clone(params), function(keyName) {
|
|
return keyName === 'facetName';
|
|
});
|
|
var searchParameters = client._getSearchParams(filteredParams, '');
|
|
|
|
return client._jsonRequest({
|
|
cache: client.cache,
|
|
method: 'POST',
|
|
url:
|
|
'/1/indexes/' +
|
|
encodeURIComponent(indexName) +
|
|
'/facets/' +
|
|
encodeURIComponent(facetName) +
|
|
'/query',
|
|
hostType: 'read',
|
|
body: {params: searchParameters}
|
|
});
|
|
}));
|
|
};
|
|
|
|
/**
|
|
* Set the extra security tagFilters header
|
|
* @param {string|array} tags The list of tags defining the current security filters
|
|
*/
|
|
AlgoliaSearchCore.prototype.setSecurityTags = function(tags) {
|
|
if (Object.prototype.toString.call(tags) === '[object Array]') {
|
|
var strTags = [];
|
|
for (var i = 0; i < tags.length; ++i) {
|
|
if (Object.prototype.toString.call(tags[i]) === '[object Array]') {
|
|
var oredTags = [];
|
|
for (var j = 0; j < tags[i].length; ++j) {
|
|
oredTags.push(tags[i][j]);
|
|
}
|
|
strTags.push('(' + oredTags.join(',') + ')');
|
|
} else {
|
|
strTags.push(tags[i]);
|
|
}
|
|
}
|
|
tags = strTags.join(',');
|
|
}
|
|
|
|
this.securityTags = tags;
|
|
};
|
|
|
|
/**
|
|
* Set the extra user token header
|
|
* @param {string} userToken The token identifying a uniq user (used to apply rate limits)
|
|
*/
|
|
AlgoliaSearchCore.prototype.setUserToken = function(userToken) {
|
|
this.userToken = userToken;
|
|
};
|
|
|
|
/**
|
|
* Clear all queries in client's cache
|
|
* @return undefined
|
|
*/
|
|
AlgoliaSearchCore.prototype.clearCache = function() {
|
|
this.cache = {};
|
|
};
|
|
|
|
/**
|
|
* Set the number of milliseconds a request can take before automatically being terminated.
|
|
* @deprecated
|
|
* @param {Number} milliseconds
|
|
*/
|
|
AlgoliaSearchCore.prototype.setRequestTimeout = function(milliseconds) {
|
|
if (milliseconds) {
|
|
this._timeouts.connect = this._timeouts.read = this._timeouts.write = milliseconds;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Set the three different (connect, read, write) timeouts to be used when requesting
|
|
* @param {Object} timeouts
|
|
*/
|
|
AlgoliaSearchCore.prototype.setTimeouts = function(timeouts) {
|
|
this._timeouts = timeouts;
|
|
};
|
|
|
|
/**
|
|
* Get the three different (connect, read, write) timeouts to be used when requesting
|
|
* @param {Object} timeouts
|
|
*/
|
|
AlgoliaSearchCore.prototype.getTimeouts = function() {
|
|
return this._timeouts;
|
|
};
|
|
|
|
AlgoliaSearchCore.prototype._getAppIdData = function() {
|
|
var data = store.get(this.applicationID);
|
|
if (data !== null) this._cacheAppIdData(data);
|
|
return data;
|
|
};
|
|
|
|
AlgoliaSearchCore.prototype._setAppIdData = function(data) {
|
|
data.lastChange = (new Date()).getTime();
|
|
this._cacheAppIdData(data);
|
|
return store.set(this.applicationID, data);
|
|
};
|
|
|
|
AlgoliaSearchCore.prototype._checkAppIdData = function() {
|
|
var data = this._getAppIdData();
|
|
var now = (new Date()).getTime();
|
|
if (data === null || now - data.lastChange > RESET_APP_DATA_TIMER) {
|
|
return this._resetInitialAppIdData(data);
|
|
}
|
|
|
|
return data;
|
|
};
|
|
|
|
AlgoliaSearchCore.prototype._resetInitialAppIdData = function(data) {
|
|
var newData = data || {};
|
|
newData.hostIndexes = {read: 0, write: 0};
|
|
newData.timeoutMultiplier = 1;
|
|
newData.shuffleResult = newData.shuffleResult || shuffle([1, 2, 3]);
|
|
return this._setAppIdData(newData);
|
|
};
|
|
|
|
AlgoliaSearchCore.prototype._cacheAppIdData = function(data) {
|
|
this._hostIndexes = data.hostIndexes;
|
|
this._timeoutMultiplier = data.timeoutMultiplier;
|
|
this._shuffleResult = data.shuffleResult;
|
|
};
|
|
|
|
AlgoliaSearchCore.prototype._partialAppIdDataUpdate = function(newData) {
|
|
var foreach = __webpack_require__(3);
|
|
var currentData = this._getAppIdData();
|
|
foreach(newData, function(value, key) {
|
|
currentData[key] = value;
|
|
});
|
|
|
|
return this._setAppIdData(currentData);
|
|
};
|
|
|
|
AlgoliaSearchCore.prototype._getHostByType = function(hostType) {
|
|
return this.hosts[hostType][this._getHostIndexByType(hostType)];
|
|
};
|
|
|
|
AlgoliaSearchCore.prototype._getTimeoutMultiplier = function() {
|
|
return this._timeoutMultiplier;
|
|
};
|
|
|
|
AlgoliaSearchCore.prototype._getHostIndexByType = function(hostType) {
|
|
return this._hostIndexes[hostType];
|
|
};
|
|
|
|
AlgoliaSearchCore.prototype._setHostIndexByType = function(hostIndex, hostType) {
|
|
var clone = __webpack_require__(4);
|
|
var newHostIndexes = clone(this._hostIndexes);
|
|
newHostIndexes[hostType] = hostIndex;
|
|
this._partialAppIdDataUpdate({hostIndexes: newHostIndexes});
|
|
return hostIndex;
|
|
};
|
|
|
|
AlgoliaSearchCore.prototype._incrementHostIndex = function(hostType) {
|
|
return this._setHostIndexByType(
|
|
(this._getHostIndexByType(hostType) + 1) % this.hosts[hostType].length, hostType
|
|
);
|
|
};
|
|
|
|
AlgoliaSearchCore.prototype._incrementTimeoutMultipler = function() {
|
|
var timeoutMultiplier = Math.max(this._timeoutMultiplier + 1, 4);
|
|
return this._partialAppIdDataUpdate({timeoutMultiplier: timeoutMultiplier});
|
|
};
|
|
|
|
AlgoliaSearchCore.prototype._getTimeoutsForRequest = function(hostType) {
|
|
return {
|
|
connect: this._timeouts.connect * this._timeoutMultiplier,
|
|
complete: this._timeouts[hostType] * this._timeoutMultiplier
|
|
};
|
|
};
|
|
|
|
function prepareHost(protocol) {
|
|
return function prepare(host) {
|
|
return protocol + '//' + host.toLowerCase();
|
|
};
|
|
}
|
|
|
|
// Prototype.js < 1.7, a widely used library, defines a weird
|
|
// Array.prototype.toJSON function that will fail to stringify our content
|
|
// appropriately
|
|
// refs:
|
|
// - https://groups.google.com/forum/#!topic/prototype-core/E-SAVvV_V9Q
|
|
// - https://github.com/sstephenson/prototype/commit/038a2985a70593c1a86c230fadbdfe2e4898a48c
|
|
// - http://stackoverflow.com/a/3148441/147079
|
|
function safeJSONStringify(obj) {
|
|
/* eslint no-extend-native:0 */
|
|
|
|
if (Array.prototype.toJSON === undefined) {
|
|
return JSON.stringify(obj);
|
|
}
|
|
|
|
var toJSON = Array.prototype.toJSON;
|
|
delete Array.prototype.toJSON;
|
|
var out = JSON.stringify(obj);
|
|
Array.prototype.toJSON = toJSON;
|
|
|
|
return out;
|
|
}
|
|
|
|
function shuffle(array) {
|
|
var currentIndex = array.length;
|
|
var temporaryValue;
|
|
var randomIndex;
|
|
|
|
// While there remain elements to shuffle...
|
|
while (currentIndex !== 0) {
|
|
// Pick a remaining element...
|
|
randomIndex = Math.floor(Math.random() * currentIndex);
|
|
currentIndex -= 1;
|
|
|
|
// And swap it with the current element.
|
|
temporaryValue = array[currentIndex];
|
|
array[currentIndex] = array[randomIndex];
|
|
array[randomIndex] = temporaryValue;
|
|
}
|
|
|
|
return array;
|
|
}
|
|
|
|
function removeCredentials(headers) {
|
|
var newHeaders = {};
|
|
|
|
for (var headerName in headers) {
|
|
if (Object.prototype.hasOwnProperty.call(headers, headerName)) {
|
|
var value;
|
|
|
|
if (headerName === 'x-algolia-api-key' || headerName === 'x-algolia-application-id') {
|
|
value = '**hidden for security purposes**';
|
|
} else {
|
|
value = headers[headerName];
|
|
}
|
|
|
|
newHeaders[headerName] = value;
|
|
}
|
|
}
|
|
|
|
return newHeaders;
|
|
}
|
|
|
|
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(10)))
|
|
|
|
/***/ }),
|
|
/* 35 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// Parse cloud does not supports setTimeout
|
|
// We do not store a setTimeout reference in the client everytime
|
|
// We only fallback to a fake setTimeout when not available
|
|
// setTimeout cannot be override globally sadly
|
|
module.exports = function exitPromise(fn, _setTimeout) {
|
|
_setTimeout(fn, 0);
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 36 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var buildSearchMethod = __webpack_require__(22);
|
|
var deprecate = __webpack_require__(37);
|
|
var deprecatedMessage = __webpack_require__(38);
|
|
|
|
module.exports = IndexCore;
|
|
|
|
/*
|
|
* Index class constructor.
|
|
* You should not use this method directly but use initIndex() function
|
|
*/
|
|
function IndexCore(algoliasearch, indexName) {
|
|
this.indexName = indexName;
|
|
this.as = algoliasearch;
|
|
this.typeAheadArgs = null;
|
|
this.typeAheadValueOption = null;
|
|
|
|
// make sure every index instance has it's own cache
|
|
this.cache = {};
|
|
}
|
|
|
|
/*
|
|
* Clear all queries in cache
|
|
*/
|
|
IndexCore.prototype.clearCache = function() {
|
|
this.cache = {};
|
|
};
|
|
|
|
/*
|
|
* Search inside the index using XMLHttpRequest request (Using a POST query to
|
|
* minimize number of OPTIONS queries: Cross-Origin Resource Sharing).
|
|
*
|
|
* @param {string} [query] the full text query
|
|
* @param {object} [args] (optional) if set, contains an object with query parameters:
|
|
* - page: (integer) Pagination parameter used to select the page to retrieve.
|
|
* Page is zero-based and defaults to 0. Thus,
|
|
* to retrieve the 10th page you need to set page=9
|
|
* - hitsPerPage: (integer) Pagination parameter used to select the number of hits per page. Defaults to 20.
|
|
* - attributesToRetrieve: a string that contains the list of object attributes
|
|
* you want to retrieve (let you minimize the answer size).
|
|
* Attributes are separated with a comma (for example "name,address").
|
|
* You can also use an array (for example ["name","address"]).
|
|
* By default, all attributes are retrieved. You can also use '*' to retrieve all
|
|
* values when an attributesToRetrieve setting is specified for your index.
|
|
* - attributesToHighlight: a string that contains the list of attributes you
|
|
* want to highlight according to the query.
|
|
* Attributes are separated by a comma. You can also use an array (for example ["name","address"]).
|
|
* If an attribute has no match for the query, the raw value is returned.
|
|
* By default all indexed text attributes are highlighted.
|
|
* You can use `*` if you want to highlight all textual attributes.
|
|
* Numerical attributes are not highlighted.
|
|
* A matchLevel is returned for each highlighted attribute and can contain:
|
|
* - full: if all the query terms were found in the attribute,
|
|
* - partial: if only some of the query terms were found,
|
|
* - none: if none of the query terms were found.
|
|
* - attributesToSnippet: a string that contains the list of attributes to snippet alongside
|
|
* the number of words to return (syntax is `attributeName:nbWords`).
|
|
* Attributes are separated by a comma (Example: attributesToSnippet=name:10,content:10).
|
|
* You can also use an array (Example: attributesToSnippet: ['name:10','content:10']).
|
|
* By default no snippet is computed.
|
|
* - minWordSizefor1Typo: the minimum number of characters in a query word to accept one typo in this word.
|
|
* Defaults to 3.
|
|
* - minWordSizefor2Typos: the minimum number of characters in a query word
|
|
* to accept two typos in this word. Defaults to 7.
|
|
* - getRankingInfo: if set to 1, the result hits will contain ranking
|
|
* information in _rankingInfo attribute.
|
|
* - aroundLatLng: search for entries around a given
|
|
* latitude/longitude (specified as two floats separated by a comma).
|
|
* For example aroundLatLng=47.316669,5.016670).
|
|
* You can specify the maximum distance in meters with the aroundRadius parameter (in meters)
|
|
* and the precision for ranking with aroundPrecision
|
|
* (for example if you set aroundPrecision=100, two objects that are distant of
|
|
* less than 100m will be considered as identical for "geo" ranking parameter).
|
|
* At indexing, you should specify geoloc of an object with the _geoloc attribute
|
|
* (in the form {"_geoloc":{"lat":48.853409, "lng":2.348800}})
|
|
* - insideBoundingBox: search entries inside a given area defined by the two extreme points
|
|
* of a rectangle (defined by 4 floats: p1Lat,p1Lng,p2Lat,p2Lng).
|
|
* For example insideBoundingBox=47.3165,4.9665,47.3424,5.0201).
|
|
* At indexing, you should specify geoloc of an object with the _geoloc attribute
|
|
* (in the form {"_geoloc":{"lat":48.853409, "lng":2.348800}})
|
|
* - numericFilters: a string that contains the list of numeric filters you want to
|
|
* apply separated by a comma.
|
|
* The syntax of one filter is `attributeName` followed by `operand` followed by `value`.
|
|
* Supported operands are `<`, `<=`, `=`, `>` and `>=`.
|
|
* You can have multiple conditions on one attribute like for example numericFilters=price>100,price<1000.
|
|
* You can also use an array (for example numericFilters: ["price>100","price<1000"]).
|
|
* - tagFilters: filter the query by a set of tags. You can AND tags by separating them by commas.
|
|
* To OR tags, you must add parentheses. For example, tags=tag1,(tag2,tag3) means tag1 AND (tag2 OR tag3).
|
|
* You can also use an array, for example tagFilters: ["tag1",["tag2","tag3"]]
|
|
* means tag1 AND (tag2 OR tag3).
|
|
* At indexing, tags should be added in the _tags** attribute
|
|
* of objects (for example {"_tags":["tag1","tag2"]}).
|
|
* - facetFilters: filter the query by a list of facets.
|
|
* Facets are separated by commas and each facet is encoded as `attributeName:value`.
|
|
* For example: `facetFilters=category:Book,author:John%20Doe`.
|
|
* You can also use an array (for example `["category:Book","author:John%20Doe"]`).
|
|
* - facets: List of object attributes that you want to use for faceting.
|
|
* Comma separated list: `"category,author"` or array `['category','author']`
|
|
* Only attributes that have been added in **attributesForFaceting** index setting
|
|
* can be used in this parameter.
|
|
* You can also use `*` to perform faceting on all attributes specified in **attributesForFaceting**.
|
|
* - queryType: select how the query words are interpreted, it can be one of the following value:
|
|
* - prefixAll: all query words are interpreted as prefixes,
|
|
* - prefixLast: only the last word is interpreted as a prefix (default behavior),
|
|
* - prefixNone: no query word is interpreted as a prefix. This option is not recommended.
|
|
* - optionalWords: a string that contains the list of words that should
|
|
* be considered as optional when found in the query.
|
|
* Comma separated and array are accepted.
|
|
* - distinct: If set to 1, enable the distinct feature (disabled by default)
|
|
* if the attributeForDistinct index setting is set.
|
|
* This feature is similar to the SQL "distinct" keyword: when enabled
|
|
* in a query with the distinct=1 parameter,
|
|
* all hits containing a duplicate value for the attributeForDistinct attribute are removed from results.
|
|
* For example, if the chosen attribute is show_name and several hits have
|
|
* the same value for show_name, then only the best
|
|
* one is kept and others are removed.
|
|
* - restrictSearchableAttributes: List of attributes you want to use for
|
|
* textual search (must be a subset of the attributesToIndex index setting)
|
|
* either comma separated or as an array
|
|
* @param {function} [callback] the result callback called with two arguments:
|
|
* error: null or Error('message'). If false, the content contains the error.
|
|
* content: the server answer that contains the list of results.
|
|
*/
|
|
IndexCore.prototype.search = buildSearchMethod('query');
|
|
|
|
/*
|
|
* -- BETA --
|
|
* Search a record similar to the query inside the index using XMLHttpRequest request (Using a POST query to
|
|
* minimize number of OPTIONS queries: Cross-Origin Resource Sharing).
|
|
*
|
|
* @param {string} [query] the similar query
|
|
* @param {object} [args] (optional) if set, contains an object with query parameters.
|
|
* All search parameters are supported (see search function), restrictSearchableAttributes and facetFilters
|
|
* are the two most useful to restrict the similar results and get more relevant content
|
|
*/
|
|
IndexCore.prototype.similarSearch = deprecate(
|
|
buildSearchMethod('similarQuery'),
|
|
deprecatedMessage(
|
|
'index.similarSearch(query[, callback])',
|
|
'index.search({ similarQuery: query }[, callback])'
|
|
)
|
|
);
|
|
|
|
/*
|
|
* Browse index content. The response content will have a `cursor` property that you can use
|
|
* to browse subsequent pages for this query. Use `index.browseFrom(cursor)` when you want.
|
|
*
|
|
* @param {string} query - The full text query
|
|
* @param {Object} [queryParameters] - Any search query parameter
|
|
* @param {Function} [callback] - The result callback called with two arguments
|
|
* error: null or Error('message')
|
|
* content: the server answer with the browse result
|
|
* @return {Promise|undefined} Returns a promise if no callback given
|
|
* @example
|
|
* index.browse('cool songs', {
|
|
* tagFilters: 'public,comments',
|
|
* hitsPerPage: 500
|
|
* }, callback);
|
|
* @see {@link https://www.algolia.com/doc/rest_api#Browse|Algolia REST API Documentation}
|
|
*/
|
|
IndexCore.prototype.browse = function(query, queryParameters, callback) {
|
|
var merge = __webpack_require__(39);
|
|
|
|
var indexObj = this;
|
|
|
|
var page;
|
|
var hitsPerPage;
|
|
|
|
// we check variadic calls that are not the one defined
|
|
// .browse()/.browse(fn)
|
|
// => page = 0
|
|
if (arguments.length === 0 || arguments.length === 1 && typeof arguments[0] === 'function') {
|
|
page = 0;
|
|
callback = arguments[0];
|
|
query = undefined;
|
|
} else if (typeof arguments[0] === 'number') {
|
|
// .browse(2)/.browse(2, 10)/.browse(2, fn)/.browse(2, 10, fn)
|
|
page = arguments[0];
|
|
if (typeof arguments[1] === 'number') {
|
|
hitsPerPage = arguments[1];
|
|
} else if (typeof arguments[1] === 'function') {
|
|
callback = arguments[1];
|
|
hitsPerPage = undefined;
|
|
}
|
|
query = undefined;
|
|
queryParameters = undefined;
|
|
} else if (typeof arguments[0] === 'object') {
|
|
// .browse(queryParameters)/.browse(queryParameters, cb)
|
|
if (typeof arguments[1] === 'function') {
|
|
callback = arguments[1];
|
|
}
|
|
queryParameters = arguments[0];
|
|
query = undefined;
|
|
} else if (typeof arguments[0] === 'string' && typeof arguments[1] === 'function') {
|
|
// .browse(query, cb)
|
|
callback = arguments[1];
|
|
queryParameters = undefined;
|
|
}
|
|
|
|
// otherwise it's a .browse(query)/.browse(query, queryParameters)/.browse(query, queryParameters, cb)
|
|
|
|
// get search query parameters combining various possible calls
|
|
// to .browse();
|
|
queryParameters = merge({}, queryParameters || {}, {
|
|
page: page,
|
|
hitsPerPage: hitsPerPage,
|
|
query: query
|
|
});
|
|
|
|
var params = this.as._getSearchParams(queryParameters, '');
|
|
|
|
return this.as._jsonRequest({
|
|
method: 'POST',
|
|
url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/browse',
|
|
body: {params: params},
|
|
hostType: 'read',
|
|
callback: callback
|
|
});
|
|
};
|
|
|
|
/*
|
|
* Continue browsing from a previous position (cursor), obtained via a call to `.browse()`.
|
|
*
|
|
* @param {string} query - The full text query
|
|
* @param {Object} [queryParameters] - Any search query parameter
|
|
* @param {Function} [callback] - The result callback called with two arguments
|
|
* error: null or Error('message')
|
|
* content: the server answer with the browse result
|
|
* @return {Promise|undefined} Returns a promise if no callback given
|
|
* @example
|
|
* index.browseFrom('14lkfsakl32', callback);
|
|
* @see {@link https://www.algolia.com/doc/rest_api#Browse|Algolia REST API Documentation}
|
|
*/
|
|
IndexCore.prototype.browseFrom = function(cursor, callback) {
|
|
return this.as._jsonRequest({
|
|
method: 'POST',
|
|
url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/browse',
|
|
body: {cursor: cursor},
|
|
hostType: 'read',
|
|
callback: callback
|
|
});
|
|
};
|
|
|
|
/*
|
|
* Search for facet values
|
|
* https://www.algolia.com/doc/rest-api/search#search-for-facet-values
|
|
*
|
|
* @param {string} params.facetName Facet name, name of the attribute to search for values in.
|
|
* Must be declared as a facet
|
|
* @param {string} params.facetQuery Query for the facet search
|
|
* @param {string} [params.*] Any search parameter of Algolia,
|
|
* see https://www.algolia.com/doc/api-client/javascript/search#search-parameters
|
|
* Pagination is not supported. The page and hitsPerPage parameters will be ignored.
|
|
* @param callback (optional)
|
|
*/
|
|
IndexCore.prototype.searchForFacetValues = function(params, callback) {
|
|
var clone = __webpack_require__(4);
|
|
var omit = __webpack_require__(23);
|
|
var usage = 'Usage: index.searchForFacetValues({facetName, facetQuery, ...params}[, callback])';
|
|
|
|
if (params.facetName === undefined || params.facetQuery === undefined) {
|
|
throw new Error(usage);
|
|
}
|
|
|
|
var facetName = params.facetName;
|
|
var filteredParams = omit(clone(params), function(keyName) {
|
|
return keyName === 'facetName';
|
|
});
|
|
var searchParameters = this.as._getSearchParams(filteredParams, '');
|
|
|
|
return this.as._jsonRequest({
|
|
method: 'POST',
|
|
url: '/1/indexes/' +
|
|
encodeURIComponent(this.indexName) + '/facets/' + encodeURIComponent(facetName) + '/query',
|
|
hostType: 'read',
|
|
body: {params: searchParameters},
|
|
callback: callback
|
|
});
|
|
};
|
|
|
|
IndexCore.prototype.searchFacet = deprecate(function(params, callback) {
|
|
return this.searchForFacetValues(params, callback);
|
|
}, deprecatedMessage(
|
|
'index.searchFacet(params[, callback])',
|
|
'index.searchForFacetValues(params[, callback])'
|
|
));
|
|
|
|
IndexCore.prototype._search = function(params, url, callback, additionalUA) {
|
|
return this.as._jsonRequest({
|
|
cache: this.cache,
|
|
method: 'POST',
|
|
url: url || '/1/indexes/' + encodeURIComponent(this.indexName) + '/query',
|
|
body: {params: params},
|
|
hostType: 'read',
|
|
fallback: {
|
|
method: 'GET',
|
|
url: '/1/indexes/' + encodeURIComponent(this.indexName),
|
|
body: {params: params}
|
|
},
|
|
callback: callback,
|
|
additionalUA: additionalUA
|
|
});
|
|
};
|
|
|
|
/*
|
|
* Get an object from this index
|
|
*
|
|
* @param objectID the unique identifier of the object to retrieve
|
|
* @param attrs (optional) if set, contains the array of attribute names to retrieve
|
|
* @param callback (optional) the result callback called with two arguments
|
|
* error: null or Error('message')
|
|
* content: the object to retrieve or the error message if a failure occurred
|
|
*/
|
|
IndexCore.prototype.getObject = function(objectID, attrs, callback) {
|
|
var indexObj = this;
|
|
|
|
if (arguments.length === 1 || typeof attrs === 'function') {
|
|
callback = attrs;
|
|
attrs = undefined;
|
|
}
|
|
|
|
var params = '';
|
|
if (attrs !== undefined) {
|
|
params = '?attributes=';
|
|
for (var i = 0; i < attrs.length; ++i) {
|
|
if (i !== 0) {
|
|
params += ',';
|
|
}
|
|
params += attrs[i];
|
|
}
|
|
}
|
|
|
|
return this.as._jsonRequest({
|
|
method: 'GET',
|
|
url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/' + encodeURIComponent(objectID) + params,
|
|
hostType: 'read',
|
|
callback: callback
|
|
});
|
|
};
|
|
|
|
/*
|
|
* Get several objects from this index
|
|
*
|
|
* @param objectIDs the array of unique identifier of objects to retrieve
|
|
*/
|
|
IndexCore.prototype.getObjects = function(objectIDs, attributesToRetrieve, callback) {
|
|
var isArray = __webpack_require__(12);
|
|
var map = __webpack_require__(13);
|
|
|
|
var usage = 'Usage: index.getObjects(arrayOfObjectIDs[, callback])';
|
|
|
|
if (!isArray(objectIDs)) {
|
|
throw new Error(usage);
|
|
}
|
|
|
|
var indexObj = this;
|
|
|
|
if (arguments.length === 1 || typeof attributesToRetrieve === 'function') {
|
|
callback = attributesToRetrieve;
|
|
attributesToRetrieve = undefined;
|
|
}
|
|
|
|
var body = {
|
|
requests: map(objectIDs, function prepareRequest(objectID) {
|
|
var request = {
|
|
indexName: indexObj.indexName,
|
|
objectID: objectID
|
|
};
|
|
|
|
if (attributesToRetrieve) {
|
|
request.attributesToRetrieve = attributesToRetrieve.join(',');
|
|
}
|
|
|
|
return request;
|
|
})
|
|
};
|
|
|
|
return this.as._jsonRequest({
|
|
method: 'POST',
|
|
url: '/1/indexes/*/objects',
|
|
hostType: 'read',
|
|
body: body,
|
|
callback: callback
|
|
});
|
|
};
|
|
|
|
IndexCore.prototype.as = null;
|
|
IndexCore.prototype.indexName = null;
|
|
IndexCore.prototype.typeAheadArgs = null;
|
|
IndexCore.prototype.typeAheadValueOption = null;
|
|
|
|
|
|
/***/ }),
|
|
/* 37 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = function deprecate(fn, message) {
|
|
var warned = false;
|
|
|
|
function deprecated() {
|
|
if (!warned) {
|
|
/* eslint no-console:0 */
|
|
console.warn(message);
|
|
warned = true;
|
|
}
|
|
|
|
return fn.apply(this, arguments);
|
|
}
|
|
|
|
return deprecated;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 38 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = function deprecatedMessage(previousUsage, newUsage) {
|
|
var githubAnchorLink = previousUsage.toLowerCase()
|
|
.replace(/[\.\(\)]/g, '');
|
|
|
|
return 'algoliasearch: `' + previousUsage + '` was replaced by `' + newUsage +
|
|
'`. Please see https://github.com/algolia/algoliasearch-client-javascript/wiki/Deprecated#' + githubAnchorLink;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 39 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var foreach = __webpack_require__(3);
|
|
|
|
module.exports = function merge(destination/* , sources */) {
|
|
var sources = Array.prototype.slice.call(arguments);
|
|
|
|
foreach(sources, function(source) {
|
|
for (var keyName in source) {
|
|
if (source.hasOwnProperty(keyName)) {
|
|
if (typeof destination[keyName] === 'object' && typeof source[keyName] === 'object') {
|
|
destination[keyName] = merge({}, destination[keyName], source[keyName]);
|
|
} else if (source[keyName] !== undefined) {
|
|
destination[keyName] = source[keyName];
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
return destination;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 40 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var slice = Array.prototype.slice;
|
|
var isArgs = __webpack_require__(24);
|
|
|
|
var origKeys = Object.keys;
|
|
var keysShim = origKeys ? function keys(o) { return origKeys(o); } : __webpack_require__(41);
|
|
|
|
var originalKeys = Object.keys;
|
|
|
|
keysShim.shim = function shimObjectKeys() {
|
|
if (Object.keys) {
|
|
var keysWorksWithArguments = (function () {
|
|
// Safari 5.0 bug
|
|
var args = Object.keys(arguments);
|
|
return args && args.length === arguments.length;
|
|
}(1, 2));
|
|
if (!keysWorksWithArguments) {
|
|
Object.keys = function keys(object) { // eslint-disable-line func-name-matching
|
|
if (isArgs(object)) {
|
|
return originalKeys(slice.call(object));
|
|
}
|
|
return originalKeys(object);
|
|
};
|
|
}
|
|
} else {
|
|
Object.keys = keysShim;
|
|
}
|
|
return Object.keys || keysShim;
|
|
};
|
|
|
|
module.exports = keysShim;
|
|
|
|
|
|
/***/ }),
|
|
/* 41 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var keysShim;
|
|
if (!Object.keys) {
|
|
// modified from https://github.com/es-shims/es5-shim
|
|
var has = Object.prototype.hasOwnProperty;
|
|
var toStr = Object.prototype.toString;
|
|
var isArgs = __webpack_require__(24); // eslint-disable-line global-require
|
|
var isEnumerable = Object.prototype.propertyIsEnumerable;
|
|
var hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');
|
|
var hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');
|
|
var dontEnums = [
|
|
'toString',
|
|
'toLocaleString',
|
|
'valueOf',
|
|
'hasOwnProperty',
|
|
'isPrototypeOf',
|
|
'propertyIsEnumerable',
|
|
'constructor'
|
|
];
|
|
var equalsConstructorPrototype = function (o) {
|
|
var ctor = o.constructor;
|
|
return ctor && ctor.prototype === o;
|
|
};
|
|
var excludedKeys = {
|
|
$applicationCache: true,
|
|
$console: true,
|
|
$external: true,
|
|
$frame: true,
|
|
$frameElement: true,
|
|
$frames: true,
|
|
$innerHeight: true,
|
|
$innerWidth: true,
|
|
$onmozfullscreenchange: true,
|
|
$onmozfullscreenerror: true,
|
|
$outerHeight: true,
|
|
$outerWidth: true,
|
|
$pageXOffset: true,
|
|
$pageYOffset: true,
|
|
$parent: true,
|
|
$scrollLeft: true,
|
|
$scrollTop: true,
|
|
$scrollX: true,
|
|
$scrollY: true,
|
|
$self: true,
|
|
$webkitIndexedDB: true,
|
|
$webkitStorageInfo: true,
|
|
$window: true
|
|
};
|
|
var hasAutomationEqualityBug = (function () {
|
|
/* global window */
|
|
if (typeof window === 'undefined') { return false; }
|
|
for (var k in window) {
|
|
try {
|
|
if (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
|
|
try {
|
|
equalsConstructorPrototype(window[k]);
|
|
} catch (e) {
|
|
return true;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}());
|
|
var equalsConstructorPrototypeIfNotBuggy = function (o) {
|
|
/* global window */
|
|
if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
|
|
return equalsConstructorPrototype(o);
|
|
}
|
|
try {
|
|
return equalsConstructorPrototype(o);
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
keysShim = function keys(object) {
|
|
var isObject = object !== null && typeof object === 'object';
|
|
var isFunction = toStr.call(object) === '[object Function]';
|
|
var isArguments = isArgs(object);
|
|
var isString = isObject && toStr.call(object) === '[object String]';
|
|
var theKeys = [];
|
|
|
|
if (!isObject && !isFunction && !isArguments) {
|
|
throw new TypeError('Object.keys called on a non-object');
|
|
}
|
|
|
|
var skipProto = hasProtoEnumBug && isFunction;
|
|
if (isString && object.length > 0 && !has.call(object, 0)) {
|
|
for (var i = 0; i < object.length; ++i) {
|
|
theKeys.push(String(i));
|
|
}
|
|
}
|
|
|
|
if (isArguments && object.length > 0) {
|
|
for (var j = 0; j < object.length; ++j) {
|
|
theKeys.push(String(j));
|
|
}
|
|
} else {
|
|
for (var name in object) {
|
|
if (!(skipProto && name === 'prototype') && has.call(object, name)) {
|
|
theKeys.push(String(name));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hasDontEnumBug) {
|
|
var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
|
|
|
|
for (var k = 0; k < dontEnums.length; ++k) {
|
|
if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
|
|
theKeys.push(dontEnums[k]);
|
|
}
|
|
}
|
|
}
|
|
return theKeys;
|
|
};
|
|
}
|
|
module.exports = keysShim;
|
|
|
|
|
|
/***/ }),
|
|
/* 42 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/* WEBPACK VAR INJECTION */(function(global) {var debug = __webpack_require__(14)('algoliasearch:src/hostIndexState.js');
|
|
var localStorageNamespace = 'algoliasearch-client-js';
|
|
|
|
var store;
|
|
var moduleStore = {
|
|
state: {},
|
|
set: function(key, data) {
|
|
this.state[key] = data;
|
|
return this.state[key];
|
|
},
|
|
get: function(key) {
|
|
return this.state[key] || null;
|
|
}
|
|
};
|
|
|
|
var localStorageStore = {
|
|
set: function(key, data) {
|
|
moduleStore.set(key, data); // always replicate localStorageStore to moduleStore in case of failure
|
|
|
|
try {
|
|
var namespace = JSON.parse(global.localStorage[localStorageNamespace]);
|
|
namespace[key] = data;
|
|
global.localStorage[localStorageNamespace] = JSON.stringify(namespace);
|
|
return namespace[key];
|
|
} catch (e) {
|
|
return localStorageFailure(key, e);
|
|
}
|
|
},
|
|
get: function(key) {
|
|
try {
|
|
return JSON.parse(global.localStorage[localStorageNamespace])[key] || null;
|
|
} catch (e) {
|
|
return localStorageFailure(key, e);
|
|
}
|
|
}
|
|
};
|
|
|
|
function localStorageFailure(key, e) {
|
|
debug('localStorage failed with', e);
|
|
cleanup();
|
|
store = moduleStore;
|
|
return store.get(key);
|
|
}
|
|
|
|
store = supportsLocalStorage() ? localStorageStore : moduleStore;
|
|
|
|
module.exports = {
|
|
get: getOrSet,
|
|
set: getOrSet,
|
|
supportsLocalStorage: supportsLocalStorage
|
|
};
|
|
|
|
function getOrSet(key, data) {
|
|
if (arguments.length === 1) {
|
|
return store.get(key);
|
|
}
|
|
|
|
return store.set(key, data);
|
|
}
|
|
|
|
function supportsLocalStorage() {
|
|
try {
|
|
if ('localStorage' in global &&
|
|
global.localStorage !== null) {
|
|
if (!global.localStorage[localStorageNamespace]) {
|
|
// actual creation of the namespace
|
|
global.localStorage.setItem(localStorageNamespace, JSON.stringify({}));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
} catch (_) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// In case of any error on localStorage, we clean our own namespace, this should handle
|
|
// quota errors when a lot of keys + data are used
|
|
function cleanup() {
|
|
try {
|
|
global.localStorage.removeItem(localStorageNamespace);
|
|
} catch (_) {
|
|
// nothing to do
|
|
}
|
|
}
|
|
|
|
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(5)))
|
|
|
|
/***/ }),
|
|
/* 43 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
/**
|
|
* This is the common logic for both the Node.js and web browser
|
|
* implementations of `debug()`.
|
|
*
|
|
* Expose `debug()` as the module.
|
|
*/
|
|
|
|
exports = module.exports = createDebug.debug = createDebug['default'] = createDebug;
|
|
exports.coerce = coerce;
|
|
exports.disable = disable;
|
|
exports.enable = enable;
|
|
exports.enabled = enabled;
|
|
exports.humanize = __webpack_require__(44);
|
|
|
|
/**
|
|
* The currently active debug mode names, and names to skip.
|
|
*/
|
|
|
|
exports.names = [];
|
|
exports.skips = [];
|
|
|
|
/**
|
|
* Map of special "%n" handling functions, for the debug "format" argument.
|
|
*
|
|
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
|
|
*/
|
|
|
|
exports.formatters = {};
|
|
|
|
/**
|
|
* Previous log timestamp.
|
|
*/
|
|
|
|
var prevTime;
|
|
|
|
/**
|
|
* Select a color.
|
|
* @param {String} namespace
|
|
* @return {Number}
|
|
* @api private
|
|
*/
|
|
|
|
function selectColor(namespace) {
|
|
var hash = 0, i;
|
|
|
|
for (i in namespace) {
|
|
hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
|
|
hash |= 0; // Convert to 32bit integer
|
|
}
|
|
|
|
return exports.colors[Math.abs(hash) % exports.colors.length];
|
|
}
|
|
|
|
/**
|
|
* Create a debugger with the given `namespace`.
|
|
*
|
|
* @param {String} namespace
|
|
* @return {Function}
|
|
* @api public
|
|
*/
|
|
|
|
function createDebug(namespace) {
|
|
|
|
function debug() {
|
|
// disabled?
|
|
if (!debug.enabled) return;
|
|
|
|
var self = debug;
|
|
|
|
// set `diff` timestamp
|
|
var curr = +new Date();
|
|
var ms = curr - (prevTime || curr);
|
|
self.diff = ms;
|
|
self.prev = prevTime;
|
|
self.curr = curr;
|
|
prevTime = curr;
|
|
|
|
// turn the `arguments` into a proper Array
|
|
var args = new Array(arguments.length);
|
|
for (var i = 0; i < args.length; i++) {
|
|
args[i] = arguments[i];
|
|
}
|
|
|
|
args[0] = exports.coerce(args[0]);
|
|
|
|
if ('string' !== typeof args[0]) {
|
|
// anything else let's inspect with %O
|
|
args.unshift('%O');
|
|
}
|
|
|
|
// apply any `formatters` transformations
|
|
var index = 0;
|
|
args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) {
|
|
// if we encounter an escaped % then don't increase the array index
|
|
if (match === '%%') return match;
|
|
index++;
|
|
var formatter = exports.formatters[format];
|
|
if ('function' === typeof formatter) {
|
|
var val = args[index];
|
|
match = formatter.call(self, val);
|
|
|
|
// now we need to remove `args[index]` since it's inlined in the `format`
|
|
args.splice(index, 1);
|
|
index--;
|
|
}
|
|
return match;
|
|
});
|
|
|
|
// apply env-specific formatting (colors, etc.)
|
|
exports.formatArgs.call(self, args);
|
|
|
|
var logFn = debug.log || exports.log || console.log.bind(console);
|
|
logFn.apply(self, args);
|
|
}
|
|
|
|
debug.namespace = namespace;
|
|
debug.enabled = exports.enabled(namespace);
|
|
debug.useColors = exports.useColors();
|
|
debug.color = selectColor(namespace);
|
|
|
|
// env-specific initialization logic for debug instances
|
|
if ('function' === typeof exports.init) {
|
|
exports.init(debug);
|
|
}
|
|
|
|
return debug;
|
|
}
|
|
|
|
/**
|
|
* Enables a debug mode by namespaces. This can include modes
|
|
* separated by a colon and wildcards.
|
|
*
|
|
* @param {String} namespaces
|
|
* @api public
|
|
*/
|
|
|
|
function enable(namespaces) {
|
|
exports.save(namespaces);
|
|
|
|
exports.names = [];
|
|
exports.skips = [];
|
|
|
|
var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
|
|
var len = split.length;
|
|
|
|
for (var i = 0; i < len; i++) {
|
|
if (!split[i]) continue; // ignore empty strings
|
|
namespaces = split[i].replace(/\*/g, '.*?');
|
|
if (namespaces[0] === '-') {
|
|
exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
|
|
} else {
|
|
exports.names.push(new RegExp('^' + namespaces + '$'));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Disable debug output.
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
function disable() {
|
|
exports.enable('');
|
|
}
|
|
|
|
/**
|
|
* Returns true if the given mode name is enabled, false otherwise.
|
|
*
|
|
* @param {String} name
|
|
* @return {Boolean}
|
|
* @api public
|
|
*/
|
|
|
|
function enabled(name) {
|
|
var i, len;
|
|
for (i = 0, len = exports.skips.length; i < len; i++) {
|
|
if (exports.skips[i].test(name)) {
|
|
return false;
|
|
}
|
|
}
|
|
for (i = 0, len = exports.names.length; i < len; i++) {
|
|
if (exports.names[i].test(name)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Coerce `val`.
|
|
*
|
|
* @param {Mixed} val
|
|
* @return {Mixed}
|
|
* @api private
|
|
*/
|
|
|
|
function coerce(val) {
|
|
if (val instanceof Error) return val.stack || val.message;
|
|
return val;
|
|
}
|
|
|
|
|
|
/***/ }),
|
|
/* 44 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* Helpers.
|
|
*/
|
|
|
|
var s = 1000;
|
|
var m = s * 60;
|
|
var h = m * 60;
|
|
var d = h * 24;
|
|
var y = d * 365.25;
|
|
|
|
/**
|
|
* Parse or format the given `val`.
|
|
*
|
|
* Options:
|
|
*
|
|
* - `long` verbose formatting [false]
|
|
*
|
|
* @param {String|Number} val
|
|
* @param {Object} [options]
|
|
* @throws {Error} throw an error if val is not a non-empty string or a number
|
|
* @return {String|Number}
|
|
* @api public
|
|
*/
|
|
|
|
module.exports = function(val, options) {
|
|
options = options || {};
|
|
var type = typeof val;
|
|
if (type === 'string' && val.length > 0) {
|
|
return parse(val);
|
|
} else if (type === 'number' && isNaN(val) === false) {
|
|
return options.long ? fmtLong(val) : fmtShort(val);
|
|
}
|
|
throw new Error(
|
|
'val is not a non-empty string or a valid number. val=' +
|
|
JSON.stringify(val)
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Parse the given `str` and return milliseconds.
|
|
*
|
|
* @param {String} str
|
|
* @return {Number}
|
|
* @api private
|
|
*/
|
|
|
|
function parse(str) {
|
|
str = String(str);
|
|
if (str.length > 100) {
|
|
return;
|
|
}
|
|
var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(
|
|
str
|
|
);
|
|
if (!match) {
|
|
return;
|
|
}
|
|
var n = parseFloat(match[1]);
|
|
var type = (match[2] || 'ms').toLowerCase();
|
|
switch (type) {
|
|
case 'years':
|
|
case 'year':
|
|
case 'yrs':
|
|
case 'yr':
|
|
case 'y':
|
|
return n * y;
|
|
case 'days':
|
|
case 'day':
|
|
case 'd':
|
|
return n * d;
|
|
case 'hours':
|
|
case 'hour':
|
|
case 'hrs':
|
|
case 'hr':
|
|
case 'h':
|
|
return n * h;
|
|
case 'minutes':
|
|
case 'minute':
|
|
case 'mins':
|
|
case 'min':
|
|
case 'm':
|
|
return n * m;
|
|
case 'seconds':
|
|
case 'second':
|
|
case 'secs':
|
|
case 'sec':
|
|
case 's':
|
|
return n * s;
|
|
case 'milliseconds':
|
|
case 'millisecond':
|
|
case 'msecs':
|
|
case 'msec':
|
|
case 'ms':
|
|
return n;
|
|
default:
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Short format for `ms`.
|
|
*
|
|
* @param {Number} ms
|
|
* @return {String}
|
|
* @api private
|
|
*/
|
|
|
|
function fmtShort(ms) {
|
|
if (ms >= d) {
|
|
return Math.round(ms / d) + 'd';
|
|
}
|
|
if (ms >= h) {
|
|
return Math.round(ms / h) + 'h';
|
|
}
|
|
if (ms >= m) {
|
|
return Math.round(ms / m) + 'm';
|
|
}
|
|
if (ms >= s) {
|
|
return Math.round(ms / s) + 's';
|
|
}
|
|
return ms + 'ms';
|
|
}
|
|
|
|
/**
|
|
* Long format for `ms`.
|
|
*
|
|
* @param {Number} ms
|
|
* @return {String}
|
|
* @api private
|
|
*/
|
|
|
|
function fmtLong(ms) {
|
|
return plural(ms, d, 'day') ||
|
|
plural(ms, h, 'hour') ||
|
|
plural(ms, m, 'minute') ||
|
|
plural(ms, s, 'second') ||
|
|
ms + ' ms';
|
|
}
|
|
|
|
/**
|
|
* Pluralization helper.
|
|
*/
|
|
|
|
function plural(ms, n, name) {
|
|
if (ms < n) {
|
|
return;
|
|
}
|
|
if (ms < n * 1.5) {
|
|
return Math.floor(ms / n) + ' ' + name;
|
|
}
|
|
return Math.ceil(ms / n) + ' ' + name + 's';
|
|
}
|
|
|
|
|
|
/***/ }),
|
|
/* 45 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var global = __webpack_require__(46);
|
|
var Promise = global.Promise || __webpack_require__(47).Promise;
|
|
|
|
// This is the standalone browser build entry point
|
|
// Browser implementation of the Algolia Search JavaScript client,
|
|
// using XMLHttpRequest, XDomainRequest and JSONP as fallback
|
|
module.exports = function createAlgoliasearch(AlgoliaSearch, uaSuffix) {
|
|
var inherits = __webpack_require__(21);
|
|
var errors = __webpack_require__(11);
|
|
var inlineHeaders = __webpack_require__(48);
|
|
var jsonpRequest = __webpack_require__(49);
|
|
var places = __webpack_require__(50);
|
|
uaSuffix = uaSuffix || '';
|
|
|
|
if (false) {}
|
|
|
|
function algoliasearch(applicationID, apiKey, opts) {
|
|
var cloneDeep = __webpack_require__(4);
|
|
|
|
opts = cloneDeep(opts || {});
|
|
|
|
opts._ua = opts._ua || algoliasearch.ua;
|
|
|
|
return new AlgoliaSearchBrowser(applicationID, apiKey, opts);
|
|
}
|
|
|
|
algoliasearch.version = __webpack_require__(53);
|
|
|
|
algoliasearch.ua =
|
|
'Algolia for JavaScript (' + algoliasearch.version + '); ' + uaSuffix;
|
|
|
|
algoliasearch.initPlaces = places(algoliasearch);
|
|
|
|
// we expose into window no matter how we are used, this will allow
|
|
// us to easily debug any website running algolia
|
|
global.__algolia = {
|
|
debug: __webpack_require__(14),
|
|
algoliasearch: algoliasearch
|
|
};
|
|
|
|
var support = {
|
|
hasXMLHttpRequest: 'XMLHttpRequest' in global,
|
|
hasXDomainRequest: 'XDomainRequest' in global
|
|
};
|
|
|
|
if (support.hasXMLHttpRequest) {
|
|
support.cors = 'withCredentials' in new XMLHttpRequest();
|
|
}
|
|
|
|
function AlgoliaSearchBrowser() {
|
|
// call AlgoliaSearch constructor
|
|
AlgoliaSearch.apply(this, arguments);
|
|
}
|
|
|
|
inherits(AlgoliaSearchBrowser, AlgoliaSearch);
|
|
|
|
AlgoliaSearchBrowser.prototype._request = function request(url, opts) {
|
|
return new Promise(function wrapRequest(resolve, reject) {
|
|
// no cors or XDomainRequest, no request
|
|
if (!support.cors && !support.hasXDomainRequest) {
|
|
// very old browser, not supported
|
|
reject(new errors.Network('CORS not supported'));
|
|
return;
|
|
}
|
|
|
|
url = inlineHeaders(url, opts.headers);
|
|
|
|
var body = opts.body;
|
|
var req = support.cors ? new XMLHttpRequest() : new XDomainRequest();
|
|
var reqTimeout;
|
|
var timedOut;
|
|
var connected = false;
|
|
|
|
reqTimeout = setTimeout(onTimeout, opts.timeouts.connect);
|
|
// we set an empty onprogress listener
|
|
// so that XDomainRequest on IE9 is not aborted
|
|
// refs:
|
|
// - https://github.com/algolia/algoliasearch-client-js/issues/76
|
|
// - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment
|
|
req.onprogress = onProgress;
|
|
if ('onreadystatechange' in req) req.onreadystatechange = onReadyStateChange;
|
|
req.onload = onLoad;
|
|
req.onerror = onError;
|
|
|
|
// do not rely on default XHR async flag, as some analytics code like hotjar
|
|
// breaks it and set it to false by default
|
|
if (req instanceof XMLHttpRequest) {
|
|
req.open(opts.method, url, true);
|
|
|
|
// The Analytics API never accepts Auth headers as query string
|
|
// this option exists specifically for them.
|
|
if (opts.forceAuthHeaders) {
|
|
req.setRequestHeader(
|
|
'x-algolia-application-id',
|
|
opts.headers['x-algolia-application-id']
|
|
);
|
|
req.setRequestHeader(
|
|
'x-algolia-api-key',
|
|
opts.headers['x-algolia-api-key']
|
|
);
|
|
}
|
|
} else {
|
|
req.open(opts.method, url);
|
|
}
|
|
|
|
// headers are meant to be sent after open
|
|
if (support.cors) {
|
|
if (body) {
|
|
if (opts.method === 'POST') {
|
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Simple_requests
|
|
req.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
|
|
} else {
|
|
req.setRequestHeader('content-type', 'application/json');
|
|
}
|
|
}
|
|
req.setRequestHeader('accept', 'application/json');
|
|
}
|
|
|
|
if (body) {
|
|
req.send(body);
|
|
} else {
|
|
req.send();
|
|
}
|
|
|
|
// event object not received in IE8, at least
|
|
// but we do not use it, still important to note
|
|
function onLoad(/* event */) {
|
|
// When browser does not supports req.timeout, we can
|
|
// have both a load and timeout event, since handled by a dumb setTimeout
|
|
if (timedOut) {
|
|
return;
|
|
}
|
|
|
|
clearTimeout(reqTimeout);
|
|
|
|
var out;
|
|
|
|
try {
|
|
out = {
|
|
body: JSON.parse(req.responseText),
|
|
responseText: req.responseText,
|
|
statusCode: req.status,
|
|
// XDomainRequest does not have any response headers
|
|
headers: req.getAllResponseHeaders && req.getAllResponseHeaders() || {}
|
|
};
|
|
} catch (e) {
|
|
out = new errors.UnparsableJSON({
|
|
more: req.responseText
|
|
});
|
|
}
|
|
|
|
if (out instanceof errors.UnparsableJSON) {
|
|
reject(out);
|
|
} else {
|
|
resolve(out);
|
|
}
|
|
}
|
|
|
|
function onError(event) {
|
|
if (timedOut) {
|
|
return;
|
|
}
|
|
|
|
clearTimeout(reqTimeout);
|
|
|
|
// error event is trigerred both with XDR/XHR on:
|
|
// - DNS error
|
|
// - unallowed cross domain request
|
|
reject(
|
|
new errors.Network({
|
|
more: event
|
|
})
|
|
);
|
|
}
|
|
|
|
function onTimeout() {
|
|
timedOut = true;
|
|
req.abort();
|
|
|
|
reject(new errors.RequestTimeout());
|
|
}
|
|
|
|
function onConnect() {
|
|
connected = true;
|
|
clearTimeout(reqTimeout);
|
|
reqTimeout = setTimeout(onTimeout, opts.timeouts.complete);
|
|
}
|
|
|
|
function onProgress() {
|
|
if (!connected) onConnect();
|
|
}
|
|
|
|
function onReadyStateChange() {
|
|
if (!connected && req.readyState > 1) onConnect();
|
|
}
|
|
});
|
|
};
|
|
|
|
AlgoliaSearchBrowser.prototype._request.fallback = function requestFallback(url, opts) {
|
|
url = inlineHeaders(url, opts.headers);
|
|
|
|
return new Promise(function wrapJsonpRequest(resolve, reject) {
|
|
jsonpRequest(url, opts, function jsonpRequestDone(err, content) {
|
|
if (err) {
|
|
reject(err);
|
|
return;
|
|
}
|
|
|
|
resolve(content);
|
|
});
|
|
});
|
|
};
|
|
|
|
AlgoliaSearchBrowser.prototype._promise = {
|
|
reject: function rejectPromise(val) {
|
|
return Promise.reject(val);
|
|
},
|
|
resolve: function resolvePromise(val) {
|
|
return Promise.resolve(val);
|
|
},
|
|
delay: function delayPromise(ms) {
|
|
return new Promise(function resolveOnTimeout(resolve/* , reject*/) {
|
|
setTimeout(resolve, ms);
|
|
});
|
|
},
|
|
all: function all(promises) {
|
|
return Promise.all(promises);
|
|
}
|
|
};
|
|
|
|
return algoliasearch;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 46 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/* WEBPACK VAR INJECTION */(function(global) {var win;
|
|
|
|
if (typeof window !== "undefined") {
|
|
win = window;
|
|
} else if (typeof global !== "undefined") {
|
|
win = global;
|
|
} else if (typeof self !== "undefined"){
|
|
win = self;
|
|
} else {
|
|
win = {};
|
|
}
|
|
|
|
module.exports = win;
|
|
|
|
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(5)))
|
|
|
|
/***/ }),
|
|
/* 47 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/* WEBPACK VAR INJECTION */(function(process, global) {/*!
|
|
* @overview es6-promise - a tiny implementation of Promises/A+.
|
|
* @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
|
|
* @license Licensed under MIT license
|
|
* See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE
|
|
* @version v4.2.8+1e68dce6
|
|
*/
|
|
|
|
(function (global, factory) {
|
|
true ? module.exports = factory() :
|
|
undefined;
|
|
}(this, (function () { 'use strict';
|
|
|
|
function objectOrFunction(x) {
|
|
var type = typeof x;
|
|
return x !== null && (type === 'object' || type === 'function');
|
|
}
|
|
|
|
function isFunction(x) {
|
|
return typeof x === 'function';
|
|
}
|
|
|
|
|
|
|
|
var _isArray = void 0;
|
|
if (Array.isArray) {
|
|
_isArray = Array.isArray;
|
|
} else {
|
|
_isArray = function (x) {
|
|
return Object.prototype.toString.call(x) === '[object Array]';
|
|
};
|
|
}
|
|
|
|
var isArray = _isArray;
|
|
|
|
var len = 0;
|
|
var vertxNext = void 0;
|
|
var customSchedulerFn = void 0;
|
|
|
|
var asap = function asap(callback, arg) {
|
|
queue[len] = callback;
|
|
queue[len + 1] = arg;
|
|
len += 2;
|
|
if (len === 2) {
|
|
// If len is 2, that means that we need to schedule an async flush.
|
|
// If additional callbacks are queued before the queue is flushed, they
|
|
// will be processed by this flush that we are scheduling.
|
|
if (customSchedulerFn) {
|
|
customSchedulerFn(flush);
|
|
} else {
|
|
scheduleFlush();
|
|
}
|
|
}
|
|
};
|
|
|
|
function setScheduler(scheduleFn) {
|
|
customSchedulerFn = scheduleFn;
|
|
}
|
|
|
|
function setAsap(asapFn) {
|
|
asap = asapFn;
|
|
}
|
|
|
|
var browserWindow = typeof window !== 'undefined' ? window : undefined;
|
|
var browserGlobal = browserWindow || {};
|
|
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
|
|
var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
|
|
|
|
// test for web worker but not in IE10
|
|
var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
|
|
|
|
// node
|
|
function useNextTick() {
|
|
// node version 0.10.x displays a deprecation warning when nextTick is used recursively
|
|
// see https://github.com/cujojs/when/issues/410 for details
|
|
return function () {
|
|
return process.nextTick(flush);
|
|
};
|
|
}
|
|
|
|
// vertx
|
|
function useVertxTimer() {
|
|
if (typeof vertxNext !== 'undefined') {
|
|
return function () {
|
|
vertxNext(flush);
|
|
};
|
|
}
|
|
|
|
return useSetTimeout();
|
|
}
|
|
|
|
function useMutationObserver() {
|
|
var iterations = 0;
|
|
var observer = new BrowserMutationObserver(flush);
|
|
var node = document.createTextNode('');
|
|
observer.observe(node, { characterData: true });
|
|
|
|
return function () {
|
|
node.data = iterations = ++iterations % 2;
|
|
};
|
|
}
|
|
|
|
// web worker
|
|
function useMessageChannel() {
|
|
var channel = new MessageChannel();
|
|
channel.port1.onmessage = flush;
|
|
return function () {
|
|
return channel.port2.postMessage(0);
|
|
};
|
|
}
|
|
|
|
function useSetTimeout() {
|
|
// Store setTimeout reference so es6-promise will be unaffected by
|
|
// other code modifying setTimeout (like sinon.useFakeTimers())
|
|
var globalSetTimeout = setTimeout;
|
|
return function () {
|
|
return globalSetTimeout(flush, 1);
|
|
};
|
|
}
|
|
|
|
var queue = new Array(1000);
|
|
function flush() {
|
|
for (var i = 0; i < len; i += 2) {
|
|
var callback = queue[i];
|
|
var arg = queue[i + 1];
|
|
|
|
callback(arg);
|
|
|
|
queue[i] = undefined;
|
|
queue[i + 1] = undefined;
|
|
}
|
|
|
|
len = 0;
|
|
}
|
|
|
|
function attemptVertx() {
|
|
try {
|
|
var vertx = Function('return this')().require('vertx');
|
|
vertxNext = vertx.runOnLoop || vertx.runOnContext;
|
|
return useVertxTimer();
|
|
} catch (e) {
|
|
return useSetTimeout();
|
|
}
|
|
}
|
|
|
|
var scheduleFlush = void 0;
|
|
// Decide what async method to use to triggering processing of queued callbacks:
|
|
if (isNode) {
|
|
scheduleFlush = useNextTick();
|
|
} else if (BrowserMutationObserver) {
|
|
scheduleFlush = useMutationObserver();
|
|
} else if (isWorker) {
|
|
scheduleFlush = useMessageChannel();
|
|
} else if (browserWindow === undefined && "function" === 'function') {
|
|
scheduleFlush = attemptVertx();
|
|
} else {
|
|
scheduleFlush = useSetTimeout();
|
|
}
|
|
|
|
function then(onFulfillment, onRejection) {
|
|
var parent = this;
|
|
|
|
var child = new this.constructor(noop);
|
|
|
|
if (child[PROMISE_ID] === undefined) {
|
|
makePromise(child);
|
|
}
|
|
|
|
var _state = parent._state;
|
|
|
|
|
|
if (_state) {
|
|
var callback = arguments[_state - 1];
|
|
asap(function () {
|
|
return invokeCallback(_state, child, callback, parent._result);
|
|
});
|
|
} else {
|
|
subscribe(parent, child, onFulfillment, onRejection);
|
|
}
|
|
|
|
return child;
|
|
}
|
|
|
|
/**
|
|
`Promise.resolve` returns a promise that will become resolved with the
|
|
passed `value`. It is shorthand for the following:
|
|
|
|
```javascript
|
|
let promise = new Promise(function(resolve, reject){
|
|
resolve(1);
|
|
});
|
|
|
|
promise.then(function(value){
|
|
// value === 1
|
|
});
|
|
```
|
|
|
|
Instead of writing the above, your code now simply becomes the following:
|
|
|
|
```javascript
|
|
let promise = Promise.resolve(1);
|
|
|
|
promise.then(function(value){
|
|
// value === 1
|
|
});
|
|
```
|
|
|
|
@method resolve
|
|
@static
|
|
@param {Any} value value that the returned promise will be resolved with
|
|
Useful for tooling.
|
|
@return {Promise} a promise that will become fulfilled with the given
|
|
`value`
|
|
*/
|
|
function resolve$1(object) {
|
|
/*jshint validthis:true */
|
|
var Constructor = this;
|
|
|
|
if (object && typeof object === 'object' && object.constructor === Constructor) {
|
|
return object;
|
|
}
|
|
|
|
var promise = new Constructor(noop);
|
|
resolve(promise, object);
|
|
return promise;
|
|
}
|
|
|
|
var PROMISE_ID = Math.random().toString(36).substring(2);
|
|
|
|
function noop() {}
|
|
|
|
var PENDING = void 0;
|
|
var FULFILLED = 1;
|
|
var REJECTED = 2;
|
|
|
|
function selfFulfillment() {
|
|
return new TypeError("You cannot resolve a promise with itself");
|
|
}
|
|
|
|
function cannotReturnOwn() {
|
|
return new TypeError('A promises callback cannot return that same promise.');
|
|
}
|
|
|
|
function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) {
|
|
try {
|
|
then$$1.call(value, fulfillmentHandler, rejectionHandler);
|
|
} catch (e) {
|
|
return e;
|
|
}
|
|
}
|
|
|
|
function handleForeignThenable(promise, thenable, then$$1) {
|
|
asap(function (promise) {
|
|
var sealed = false;
|
|
var error = tryThen(then$$1, thenable, function (value) {
|
|
if (sealed) {
|
|
return;
|
|
}
|
|
sealed = true;
|
|
if (thenable !== value) {
|
|
resolve(promise, value);
|
|
} else {
|
|
fulfill(promise, value);
|
|
}
|
|
}, function (reason) {
|
|
if (sealed) {
|
|
return;
|
|
}
|
|
sealed = true;
|
|
|
|
reject(promise, reason);
|
|
}, 'Settle: ' + (promise._label || ' unknown promise'));
|
|
|
|
if (!sealed && error) {
|
|
sealed = true;
|
|
reject(promise, error);
|
|
}
|
|
}, promise);
|
|
}
|
|
|
|
function handleOwnThenable(promise, thenable) {
|
|
if (thenable._state === FULFILLED) {
|
|
fulfill(promise, thenable._result);
|
|
} else if (thenable._state === REJECTED) {
|
|
reject(promise, thenable._result);
|
|
} else {
|
|
subscribe(thenable, undefined, function (value) {
|
|
return resolve(promise, value);
|
|
}, function (reason) {
|
|
return reject(promise, reason);
|
|
});
|
|
}
|
|
}
|
|
|
|
function handleMaybeThenable(promise, maybeThenable, then$$1) {
|
|
if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) {
|
|
handleOwnThenable(promise, maybeThenable);
|
|
} else {
|
|
if (then$$1 === undefined) {
|
|
fulfill(promise, maybeThenable);
|
|
} else if (isFunction(then$$1)) {
|
|
handleForeignThenable(promise, maybeThenable, then$$1);
|
|
} else {
|
|
fulfill(promise, maybeThenable);
|
|
}
|
|
}
|
|
}
|
|
|
|
function resolve(promise, value) {
|
|
if (promise === value) {
|
|
reject(promise, selfFulfillment());
|
|
} else if (objectOrFunction(value)) {
|
|
var then$$1 = void 0;
|
|
try {
|
|
then$$1 = value.then;
|
|
} catch (error) {
|
|
reject(promise, error);
|
|
return;
|
|
}
|
|
handleMaybeThenable(promise, value, then$$1);
|
|
} else {
|
|
fulfill(promise, value);
|
|
}
|
|
}
|
|
|
|
function publishRejection(promise) {
|
|
if (promise._onerror) {
|
|
promise._onerror(promise._result);
|
|
}
|
|
|
|
publish(promise);
|
|
}
|
|
|
|
function fulfill(promise, value) {
|
|
if (promise._state !== PENDING) {
|
|
return;
|
|
}
|
|
|
|
promise._result = value;
|
|
promise._state = FULFILLED;
|
|
|
|
if (promise._subscribers.length !== 0) {
|
|
asap(publish, promise);
|
|
}
|
|
}
|
|
|
|
function reject(promise, reason) {
|
|
if (promise._state !== PENDING) {
|
|
return;
|
|
}
|
|
promise._state = REJECTED;
|
|
promise._result = reason;
|
|
|
|
asap(publishRejection, promise);
|
|
}
|
|
|
|
function subscribe(parent, child, onFulfillment, onRejection) {
|
|
var _subscribers = parent._subscribers;
|
|
var length = _subscribers.length;
|
|
|
|
|
|
parent._onerror = null;
|
|
|
|
_subscribers[length] = child;
|
|
_subscribers[length + FULFILLED] = onFulfillment;
|
|
_subscribers[length + REJECTED] = onRejection;
|
|
|
|
if (length === 0 && parent._state) {
|
|
asap(publish, parent);
|
|
}
|
|
}
|
|
|
|
function publish(promise) {
|
|
var subscribers = promise._subscribers;
|
|
var settled = promise._state;
|
|
|
|
if (subscribers.length === 0) {
|
|
return;
|
|
}
|
|
|
|
var child = void 0,
|
|
callback = void 0,
|
|
detail = promise._result;
|
|
|
|
for (var i = 0; i < subscribers.length; i += 3) {
|
|
child = subscribers[i];
|
|
callback = subscribers[i + settled];
|
|
|
|
if (child) {
|
|
invokeCallback(settled, child, callback, detail);
|
|
} else {
|
|
callback(detail);
|
|
}
|
|
}
|
|
|
|
promise._subscribers.length = 0;
|
|
}
|
|
|
|
function invokeCallback(settled, promise, callback, detail) {
|
|
var hasCallback = isFunction(callback),
|
|
value = void 0,
|
|
error = void 0,
|
|
succeeded = true;
|
|
|
|
if (hasCallback) {
|
|
try {
|
|
value = callback(detail);
|
|
} catch (e) {
|
|
succeeded = false;
|
|
error = e;
|
|
}
|
|
|
|
if (promise === value) {
|
|
reject(promise, cannotReturnOwn());
|
|
return;
|
|
}
|
|
} else {
|
|
value = detail;
|
|
}
|
|
|
|
if (promise._state !== PENDING) {
|
|
// noop
|
|
} else if (hasCallback && succeeded) {
|
|
resolve(promise, value);
|
|
} else if (succeeded === false) {
|
|
reject(promise, error);
|
|
} else if (settled === FULFILLED) {
|
|
fulfill(promise, value);
|
|
} else if (settled === REJECTED) {
|
|
reject(promise, value);
|
|
}
|
|
}
|
|
|
|
function initializePromise(promise, resolver) {
|
|
try {
|
|
resolver(function resolvePromise(value) {
|
|
resolve(promise, value);
|
|
}, function rejectPromise(reason) {
|
|
reject(promise, reason);
|
|
});
|
|
} catch (e) {
|
|
reject(promise, e);
|
|
}
|
|
}
|
|
|
|
var id = 0;
|
|
function nextId() {
|
|
return id++;
|
|
}
|
|
|
|
function makePromise(promise) {
|
|
promise[PROMISE_ID] = id++;
|
|
promise._state = undefined;
|
|
promise._result = undefined;
|
|
promise._subscribers = [];
|
|
}
|
|
|
|
function validationError() {
|
|
return new Error('Array Methods must be provided an Array');
|
|
}
|
|
|
|
var Enumerator = function () {
|
|
function Enumerator(Constructor, input) {
|
|
this._instanceConstructor = Constructor;
|
|
this.promise = new Constructor(noop);
|
|
|
|
if (!this.promise[PROMISE_ID]) {
|
|
makePromise(this.promise);
|
|
}
|
|
|
|
if (isArray(input)) {
|
|
this.length = input.length;
|
|
this._remaining = input.length;
|
|
|
|
this._result = new Array(this.length);
|
|
|
|
if (this.length === 0) {
|
|
fulfill(this.promise, this._result);
|
|
} else {
|
|
this.length = this.length || 0;
|
|
this._enumerate(input);
|
|
if (this._remaining === 0) {
|
|
fulfill(this.promise, this._result);
|
|
}
|
|
}
|
|
} else {
|
|
reject(this.promise, validationError());
|
|
}
|
|
}
|
|
|
|
Enumerator.prototype._enumerate = function _enumerate(input) {
|
|
for (var i = 0; this._state === PENDING && i < input.length; i++) {
|
|
this._eachEntry(input[i], i);
|
|
}
|
|
};
|
|
|
|
Enumerator.prototype._eachEntry = function _eachEntry(entry, i) {
|
|
var c = this._instanceConstructor;
|
|
var resolve$$1 = c.resolve;
|
|
|
|
|
|
if (resolve$$1 === resolve$1) {
|
|
var _then = void 0;
|
|
var error = void 0;
|
|
var didError = false;
|
|
try {
|
|
_then = entry.then;
|
|
} catch (e) {
|
|
didError = true;
|
|
error = e;
|
|
}
|
|
|
|
if (_then === then && entry._state !== PENDING) {
|
|
this._settledAt(entry._state, i, entry._result);
|
|
} else if (typeof _then !== 'function') {
|
|
this._remaining--;
|
|
this._result[i] = entry;
|
|
} else if (c === Promise$1) {
|
|
var promise = new c(noop);
|
|
if (didError) {
|
|
reject(promise, error);
|
|
} else {
|
|
handleMaybeThenable(promise, entry, _then);
|
|
}
|
|
this._willSettleAt(promise, i);
|
|
} else {
|
|
this._willSettleAt(new c(function (resolve$$1) {
|
|
return resolve$$1(entry);
|
|
}), i);
|
|
}
|
|
} else {
|
|
this._willSettleAt(resolve$$1(entry), i);
|
|
}
|
|
};
|
|
|
|
Enumerator.prototype._settledAt = function _settledAt(state, i, value) {
|
|
var promise = this.promise;
|
|
|
|
|
|
if (promise._state === PENDING) {
|
|
this._remaining--;
|
|
|
|
if (state === REJECTED) {
|
|
reject(promise, value);
|
|
} else {
|
|
this._result[i] = value;
|
|
}
|
|
}
|
|
|
|
if (this._remaining === 0) {
|
|
fulfill(promise, this._result);
|
|
}
|
|
};
|
|
|
|
Enumerator.prototype._willSettleAt = function _willSettleAt(promise, i) {
|
|
var enumerator = this;
|
|
|
|
subscribe(promise, undefined, function (value) {
|
|
return enumerator._settledAt(FULFILLED, i, value);
|
|
}, function (reason) {
|
|
return enumerator._settledAt(REJECTED, i, reason);
|
|
});
|
|
};
|
|
|
|
return Enumerator;
|
|
}();
|
|
|
|
/**
|
|
`Promise.all` accepts an array of promises, and returns a new promise which
|
|
is fulfilled with an array of fulfillment values for the passed promises, or
|
|
rejected with the reason of the first passed promise to be rejected. It casts all
|
|
elements of the passed iterable to promises as it runs this algorithm.
|
|
|
|
Example:
|
|
|
|
```javascript
|
|
let promise1 = resolve(1);
|
|
let promise2 = resolve(2);
|
|
let promise3 = resolve(3);
|
|
let promises = [ promise1, promise2, promise3 ];
|
|
|
|
Promise.all(promises).then(function(array){
|
|
// The array here would be [ 1, 2, 3 ];
|
|
});
|
|
```
|
|
|
|
If any of the `promises` given to `all` are rejected, the first promise
|
|
that is rejected will be given as an argument to the returned promises's
|
|
rejection handler. For example:
|
|
|
|
Example:
|
|
|
|
```javascript
|
|
let promise1 = resolve(1);
|
|
let promise2 = reject(new Error("2"));
|
|
let promise3 = reject(new Error("3"));
|
|
let promises = [ promise1, promise2, promise3 ];
|
|
|
|
Promise.all(promises).then(function(array){
|
|
// Code here never runs because there are rejected promises!
|
|
}, function(error) {
|
|
// error.message === "2"
|
|
});
|
|
```
|
|
|
|
@method all
|
|
@static
|
|
@param {Array} entries array of promises
|
|
@param {String} label optional string for labeling the promise.
|
|
Useful for tooling.
|
|
@return {Promise} promise that is fulfilled when all `promises` have been
|
|
fulfilled, or rejected if any of them become rejected.
|
|
@static
|
|
*/
|
|
function all(entries) {
|
|
return new Enumerator(this, entries).promise;
|
|
}
|
|
|
|
/**
|
|
`Promise.race` returns a new promise which is settled in the same way as the
|
|
first passed promise to settle.
|
|
|
|
Example:
|
|
|
|
```javascript
|
|
let promise1 = new Promise(function(resolve, reject){
|
|
setTimeout(function(){
|
|
resolve('promise 1');
|
|
}, 200);
|
|
});
|
|
|
|
let promise2 = new Promise(function(resolve, reject){
|
|
setTimeout(function(){
|
|
resolve('promise 2');
|
|
}, 100);
|
|
});
|
|
|
|
Promise.race([promise1, promise2]).then(function(result){
|
|
// result === 'promise 2' because it was resolved before promise1
|
|
// was resolved.
|
|
});
|
|
```
|
|
|
|
`Promise.race` is deterministic in that only the state of the first
|
|
settled promise matters. For example, even if other promises given to the
|
|
`promises` array argument are resolved, but the first settled promise has
|
|
become rejected before the other promises became fulfilled, the returned
|
|
promise will become rejected:
|
|
|
|
```javascript
|
|
let promise1 = new Promise(function(resolve, reject){
|
|
setTimeout(function(){
|
|
resolve('promise 1');
|
|
}, 200);
|
|
});
|
|
|
|
let promise2 = new Promise(function(resolve, reject){
|
|
setTimeout(function(){
|
|
reject(new Error('promise 2'));
|
|
}, 100);
|
|
});
|
|
|
|
Promise.race([promise1, promise2]).then(function(result){
|
|
// Code here never runs
|
|
}, function(reason){
|
|
// reason.message === 'promise 2' because promise 2 became rejected before
|
|
// promise 1 became fulfilled
|
|
});
|
|
```
|
|
|
|
An example real-world use case is implementing timeouts:
|
|
|
|
```javascript
|
|
Promise.race([ajax('foo.json'), timeout(5000)])
|
|
```
|
|
|
|
@method race
|
|
@static
|
|
@param {Array} promises array of promises to observe
|
|
Useful for tooling.
|
|
@return {Promise} a promise which settles in the same way as the first passed
|
|
promise to settle.
|
|
*/
|
|
function race(entries) {
|
|
/*jshint validthis:true */
|
|
var Constructor = this;
|
|
|
|
if (!isArray(entries)) {
|
|
return new Constructor(function (_, reject) {
|
|
return reject(new TypeError('You must pass an array to race.'));
|
|
});
|
|
} else {
|
|
return new Constructor(function (resolve, reject) {
|
|
var length = entries.length;
|
|
for (var i = 0; i < length; i++) {
|
|
Constructor.resolve(entries[i]).then(resolve, reject);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
`Promise.reject` returns a promise rejected with the passed `reason`.
|
|
It is shorthand for the following:
|
|
|
|
```javascript
|
|
let promise = new Promise(function(resolve, reject){
|
|
reject(new Error('WHOOPS'));
|
|
});
|
|
|
|
promise.then(function(value){
|
|
// Code here doesn't run because the promise is rejected!
|
|
}, function(reason){
|
|
// reason.message === 'WHOOPS'
|
|
});
|
|
```
|
|
|
|
Instead of writing the above, your code now simply becomes the following:
|
|
|
|
```javascript
|
|
let promise = Promise.reject(new Error('WHOOPS'));
|
|
|
|
promise.then(function(value){
|
|
// Code here doesn't run because the promise is rejected!
|
|
}, function(reason){
|
|
// reason.message === 'WHOOPS'
|
|
});
|
|
```
|
|
|
|
@method reject
|
|
@static
|
|
@param {Any} reason value that the returned promise will be rejected with.
|
|
Useful for tooling.
|
|
@return {Promise} a promise rejected with the given `reason`.
|
|
*/
|
|
function reject$1(reason) {
|
|
/*jshint validthis:true */
|
|
var Constructor = this;
|
|
var promise = new Constructor(noop);
|
|
reject(promise, reason);
|
|
return promise;
|
|
}
|
|
|
|
function needsResolver() {
|
|
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
|
|
}
|
|
|
|
function needsNew() {
|
|
throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
|
|
}
|
|
|
|
/**
|
|
Promise objects represent the eventual result of an asynchronous operation. The
|
|
primary way of interacting with a promise is through its `then` method, which
|
|
registers callbacks to receive either a promise's eventual value or the reason
|
|
why the promise cannot be fulfilled.
|
|
|
|
Terminology
|
|
-----------
|
|
|
|
- `promise` is an object or function with a `then` method whose behavior conforms to this specification.
|
|
- `thenable` is an object or function that defines a `then` method.
|
|
- `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
|
|
- `exception` is a value that is thrown using the throw statement.
|
|
- `reason` is a value that indicates why a promise was rejected.
|
|
- `settled` the final resting state of a promise, fulfilled or rejected.
|
|
|
|
A promise can be in one of three states: pending, fulfilled, or rejected.
|
|
|
|
Promises that are fulfilled have a fulfillment value and are in the fulfilled
|
|
state. Promises that are rejected have a rejection reason and are in the
|
|
rejected state. A fulfillment value is never a thenable.
|
|
|
|
Promises can also be said to *resolve* a value. If this value is also a
|
|
promise, then the original promise's settled state will match the value's
|
|
settled state. So a promise that *resolves* a promise that rejects will
|
|
itself reject, and a promise that *resolves* a promise that fulfills will
|
|
itself fulfill.
|
|
|
|
|
|
Basic Usage:
|
|
------------
|
|
|
|
```js
|
|
let promise = new Promise(function(resolve, reject) {
|
|
// on success
|
|
resolve(value);
|
|
|
|
// on failure
|
|
reject(reason);
|
|
});
|
|
|
|
promise.then(function(value) {
|
|
// on fulfillment
|
|
}, function(reason) {
|
|
// on rejection
|
|
});
|
|
```
|
|
|
|
Advanced Usage:
|
|
---------------
|
|
|
|
Promises shine when abstracting away asynchronous interactions such as
|
|
`XMLHttpRequest`s.
|
|
|
|
```js
|
|
function getJSON(url) {
|
|
return new Promise(function(resolve, reject){
|
|
let xhr = new XMLHttpRequest();
|
|
|
|
xhr.open('GET', url);
|
|
xhr.onreadystatechange = handler;
|
|
xhr.responseType = 'json';
|
|
xhr.setRequestHeader('Accept', 'application/json');
|
|
xhr.send();
|
|
|
|
function handler() {
|
|
if (this.readyState === this.DONE) {
|
|
if (this.status === 200) {
|
|
resolve(this.response);
|
|
} else {
|
|
reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
|
|
}
|
|
}
|
|
};
|
|
});
|
|
}
|
|
|
|
getJSON('/posts.json').then(function(json) {
|
|
// on fulfillment
|
|
}, function(reason) {
|
|
// on rejection
|
|
});
|
|
```
|
|
|
|
Unlike callbacks, promises are great composable primitives.
|
|
|
|
```js
|
|
Promise.all([
|
|
getJSON('/posts'),
|
|
getJSON('/comments')
|
|
]).then(function(values){
|
|
values[0] // => postsJSON
|
|
values[1] // => commentsJSON
|
|
|
|
return values;
|
|
});
|
|
```
|
|
|
|
@class Promise
|
|
@param {Function} resolver
|
|
Useful for tooling.
|
|
@constructor
|
|
*/
|
|
|
|
var Promise$1 = function () {
|
|
function Promise(resolver) {
|
|
this[PROMISE_ID] = nextId();
|
|
this._result = this._state = undefined;
|
|
this._subscribers = [];
|
|
|
|
if (noop !== resolver) {
|
|
typeof resolver !== 'function' && needsResolver();
|
|
this instanceof Promise ? initializePromise(this, resolver) : needsNew();
|
|
}
|
|
}
|
|
|
|
/**
|
|
The primary way of interacting with a promise is through its `then` method,
|
|
which registers callbacks to receive either a promise's eventual value or the
|
|
reason why the promise cannot be fulfilled.
|
|
```js
|
|
findUser().then(function(user){
|
|
// user is available
|
|
}, function(reason){
|
|
// user is unavailable, and you are given the reason why
|
|
});
|
|
```
|
|
Chaining
|
|
--------
|
|
The return value of `then` is itself a promise. This second, 'downstream'
|
|
promise is resolved with the return value of the first promise's fulfillment
|
|
or rejection handler, or rejected if the handler throws an exception.
|
|
```js
|
|
findUser().then(function (user) {
|
|
return user.name;
|
|
}, function (reason) {
|
|
return 'default name';
|
|
}).then(function (userName) {
|
|
// If `findUser` fulfilled, `userName` will be the user's name, otherwise it
|
|
// will be `'default name'`
|
|
});
|
|
findUser().then(function (user) {
|
|
throw new Error('Found user, but still unhappy');
|
|
}, function (reason) {
|
|
throw new Error('`findUser` rejected and we're unhappy');
|
|
}).then(function (value) {
|
|
// never reached
|
|
}, function (reason) {
|
|
// if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
|
|
// If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
|
|
});
|
|
```
|
|
If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
|
|
```js
|
|
findUser().then(function (user) {
|
|
throw new PedagogicalException('Upstream error');
|
|
}).then(function (value) {
|
|
// never reached
|
|
}).then(function (value) {
|
|
// never reached
|
|
}, function (reason) {
|
|
// The `PedgagocialException` is propagated all the way down to here
|
|
});
|
|
```
|
|
Assimilation
|
|
------------
|
|
Sometimes the value you want to propagate to a downstream promise can only be
|
|
retrieved asynchronously. This can be achieved by returning a promise in the
|
|
fulfillment or rejection handler. The downstream promise will then be pending
|
|
until the returned promise is settled. This is called *assimilation*.
|
|
```js
|
|
findUser().then(function (user) {
|
|
return findCommentsByAuthor(user);
|
|
}).then(function (comments) {
|
|
// The user's comments are now available
|
|
});
|
|
```
|
|
If the assimliated promise rejects, then the downstream promise will also reject.
|
|
```js
|
|
findUser().then(function (user) {
|
|
return findCommentsByAuthor(user);
|
|
}).then(function (comments) {
|
|
// If `findCommentsByAuthor` fulfills, we'll have the value here
|
|
}, function (reason) {
|
|
// If `findCommentsByAuthor` rejects, we'll have the reason here
|
|
});
|
|
```
|
|
Simple Example
|
|
--------------
|
|
Synchronous Example
|
|
```javascript
|
|
let result;
|
|
try {
|
|
result = findResult();
|
|
// success
|
|
} catch(reason) {
|
|
// failure
|
|
}
|
|
```
|
|
Errback Example
|
|
```js
|
|
findResult(function(result, err){
|
|
if (err) {
|
|
// failure
|
|
} else {
|
|
// success
|
|
}
|
|
});
|
|
```
|
|
Promise Example;
|
|
```javascript
|
|
findResult().then(function(result){
|
|
// success
|
|
}, function(reason){
|
|
// failure
|
|
});
|
|
```
|
|
Advanced Example
|
|
--------------
|
|
Synchronous Example
|
|
```javascript
|
|
let author, books;
|
|
try {
|
|
author = findAuthor();
|
|
books = findBooksByAuthor(author);
|
|
// success
|
|
} catch(reason) {
|
|
// failure
|
|
}
|
|
```
|
|
Errback Example
|
|
```js
|
|
function foundBooks(books) {
|
|
}
|
|
function failure(reason) {
|
|
}
|
|
findAuthor(function(author, err){
|
|
if (err) {
|
|
failure(err);
|
|
// failure
|
|
} else {
|
|
try {
|
|
findBoooksByAuthor(author, function(books, err) {
|
|
if (err) {
|
|
failure(err);
|
|
} else {
|
|
try {
|
|
foundBooks(books);
|
|
} catch(reason) {
|
|
failure(reason);
|
|
}
|
|
}
|
|
});
|
|
} catch(error) {
|
|
failure(err);
|
|
}
|
|
// success
|
|
}
|
|
});
|
|
```
|
|
Promise Example;
|
|
```javascript
|
|
findAuthor().
|
|
then(findBooksByAuthor).
|
|
then(function(books){
|
|
// found books
|
|
}).catch(function(reason){
|
|
// something went wrong
|
|
});
|
|
```
|
|
@method then
|
|
@param {Function} onFulfilled
|
|
@param {Function} onRejected
|
|
Useful for tooling.
|
|
@return {Promise}
|
|
*/
|
|
|
|
/**
|
|
`catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
|
|
as the catch block of a try/catch statement.
|
|
```js
|
|
function findAuthor(){
|
|
throw new Error('couldn't find that author');
|
|
}
|
|
// synchronous
|
|
try {
|
|
findAuthor();
|
|
} catch(reason) {
|
|
// something went wrong
|
|
}
|
|
// async with promises
|
|
findAuthor().catch(function(reason){
|
|
// something went wrong
|
|
});
|
|
```
|
|
@method catch
|
|
@param {Function} onRejection
|
|
Useful for tooling.
|
|
@return {Promise}
|
|
*/
|
|
|
|
|
|
Promise.prototype.catch = function _catch(onRejection) {
|
|
return this.then(null, onRejection);
|
|
};
|
|
|
|
/**
|
|
`finally` will be invoked regardless of the promise's fate just as native
|
|
try/catch/finally behaves
|
|
|
|
Synchronous example:
|
|
|
|
```js
|
|
findAuthor() {
|
|
if (Math.random() > 0.5) {
|
|
throw new Error();
|
|
}
|
|
return new Author();
|
|
}
|
|
|
|
try {
|
|
return findAuthor(); // succeed or fail
|
|
} catch(error) {
|
|
return findOtherAuther();
|
|
} finally {
|
|
// always runs
|
|
// doesn't affect the return value
|
|
}
|
|
```
|
|
|
|
Asynchronous example:
|
|
|
|
```js
|
|
findAuthor().catch(function(reason){
|
|
return findOtherAuther();
|
|
}).finally(function(){
|
|
// author was either found, or not
|
|
});
|
|
```
|
|
|
|
@method finally
|
|
@param {Function} callback
|
|
@return {Promise}
|
|
*/
|
|
|
|
|
|
Promise.prototype.finally = function _finally(callback) {
|
|
var promise = this;
|
|
var constructor = promise.constructor;
|
|
|
|
if (isFunction(callback)) {
|
|
return promise.then(function (value) {
|
|
return constructor.resolve(callback()).then(function () {
|
|
return value;
|
|
});
|
|
}, function (reason) {
|
|
return constructor.resolve(callback()).then(function () {
|
|
throw reason;
|
|
});
|
|
});
|
|
}
|
|
|
|
return promise.then(callback, callback);
|
|
};
|
|
|
|
return Promise;
|
|
}();
|
|
|
|
Promise$1.prototype.then = then;
|
|
Promise$1.all = all;
|
|
Promise$1.race = race;
|
|
Promise$1.resolve = resolve$1;
|
|
Promise$1.reject = reject$1;
|
|
Promise$1._setScheduler = setScheduler;
|
|
Promise$1._setAsap = setAsap;
|
|
Promise$1._asap = asap;
|
|
|
|
/*global self*/
|
|
function polyfill() {
|
|
var local = void 0;
|
|
|
|
if (typeof global !== 'undefined') {
|
|
local = global;
|
|
} else if (typeof self !== 'undefined') {
|
|
local = self;
|
|
} else {
|
|
try {
|
|
local = Function('return this')();
|
|
} catch (e) {
|
|
throw new Error('polyfill failed because global object is unavailable in this environment');
|
|
}
|
|
}
|
|
|
|
var P = local.Promise;
|
|
|
|
if (P) {
|
|
var promiseToString = null;
|
|
try {
|
|
promiseToString = Object.prototype.toString.call(P.resolve());
|
|
} catch (e) {
|
|
// silently ignored
|
|
}
|
|
|
|
if (promiseToString === '[object Promise]' && !P.cast) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
local.Promise = Promise$1;
|
|
}
|
|
|
|
// Strange compat..
|
|
Promise$1.polyfill = polyfill;
|
|
Promise$1.Promise = Promise$1;
|
|
|
|
return Promise$1;
|
|
|
|
})));
|
|
|
|
|
|
|
|
//# sourceMappingURL=es6-promise.map
|
|
|
|
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(10), __webpack_require__(5)))
|
|
|
|
/***/ }),
|
|
/* 48 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
module.exports = inlineHeaders;
|
|
|
|
var encode = __webpack_require__(25);
|
|
|
|
function inlineHeaders(url, headers) {
|
|
if (/\?/.test(url)) {
|
|
url += '&';
|
|
} else {
|
|
url += '?';
|
|
}
|
|
|
|
return url + encode(headers);
|
|
}
|
|
|
|
|
|
/***/ }),
|
|
/* 49 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
module.exports = jsonpRequest;
|
|
|
|
var errors = __webpack_require__(11);
|
|
|
|
var JSONPCounter = 0;
|
|
|
|
function jsonpRequest(url, opts, cb) {
|
|
if (opts.method !== 'GET') {
|
|
cb(new Error('Method ' + opts.method + ' ' + url + ' is not supported by JSONP.'));
|
|
return;
|
|
}
|
|
|
|
opts.debug('JSONP: start');
|
|
|
|
var cbCalled = false;
|
|
var timedOut = false;
|
|
|
|
JSONPCounter += 1;
|
|
var head = document.getElementsByTagName('head')[0];
|
|
var script = document.createElement('script');
|
|
var cbName = 'algoliaJSONP_' + JSONPCounter;
|
|
var done = false;
|
|
|
|
window[cbName] = function(data) {
|
|
removeGlobals();
|
|
|
|
if (timedOut) {
|
|
opts.debug('JSONP: Late answer, ignoring');
|
|
return;
|
|
}
|
|
|
|
cbCalled = true;
|
|
|
|
clean();
|
|
|
|
cb(null, {
|
|
body: data,
|
|
responseText: JSON.stringify(data)/* ,
|
|
// We do not send the statusCode, there's no statusCode in JSONP, it will be
|
|
// computed using data.status && data.message like with XDR
|
|
statusCode*/
|
|
});
|
|
};
|
|
|
|
// add callback by hand
|
|
url += '&callback=' + cbName;
|
|
|
|
// add body params manually
|
|
if (opts.jsonBody && opts.jsonBody.params) {
|
|
url += '&' + opts.jsonBody.params;
|
|
}
|
|
|
|
var ontimeout = setTimeout(timeout, opts.timeouts.complete);
|
|
|
|
// script onreadystatechange needed only for
|
|
// <= IE8
|
|
// https://github.com/angular/angular.js/issues/4523
|
|
script.onreadystatechange = readystatechange;
|
|
script.onload = success;
|
|
script.onerror = error;
|
|
|
|
script.async = true;
|
|
script.defer = true;
|
|
script.src = url;
|
|
head.appendChild(script);
|
|
|
|
function success() {
|
|
opts.debug('JSONP: success');
|
|
|
|
if (done || timedOut) {
|
|
return;
|
|
}
|
|
|
|
done = true;
|
|
|
|
// script loaded but did not call the fn => script loading error
|
|
if (!cbCalled) {
|
|
opts.debug('JSONP: Fail. Script loaded but did not call the callback');
|
|
clean();
|
|
cb(new errors.JSONPScriptFail());
|
|
}
|
|
}
|
|
|
|
function readystatechange() {
|
|
if (this.readyState === 'loaded' || this.readyState === 'complete') {
|
|
success();
|
|
}
|
|
}
|
|
|
|
function clean() {
|
|
clearTimeout(ontimeout);
|
|
script.onload = null;
|
|
script.onreadystatechange = null;
|
|
script.onerror = null;
|
|
head.removeChild(script);
|
|
}
|
|
|
|
function removeGlobals() {
|
|
try {
|
|
delete window[cbName];
|
|
delete window[cbName + '_loaded'];
|
|
} catch (e) {
|
|
window[cbName] = window[cbName + '_loaded'] = undefined;
|
|
}
|
|
}
|
|
|
|
function timeout() {
|
|
opts.debug('JSONP: Script timeout');
|
|
timedOut = true;
|
|
clean();
|
|
cb(new errors.RequestTimeout());
|
|
}
|
|
|
|
function error() {
|
|
opts.debug('JSONP: Script error');
|
|
|
|
if (done || timedOut) {
|
|
return;
|
|
}
|
|
|
|
clean();
|
|
cb(new errors.JSONPScriptError());
|
|
}
|
|
}
|
|
|
|
|
|
/***/ }),
|
|
/* 50 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
module.exports = createPlacesClient;
|
|
|
|
var qs3 = __webpack_require__(51);
|
|
var buildSearchMethod = __webpack_require__(22);
|
|
|
|
function createPlacesClient(algoliasearch) {
|
|
return function places(appID, apiKey, opts) {
|
|
var cloneDeep = __webpack_require__(4);
|
|
|
|
opts = opts && cloneDeep(opts) || {};
|
|
opts.hosts = opts.hosts || [
|
|
'places-dsn.algolia.net',
|
|
'places-1.algolianet.com',
|
|
'places-2.algolianet.com',
|
|
'places-3.algolianet.com'
|
|
];
|
|
|
|
// allow initPlaces() no arguments => community rate limited
|
|
if (arguments.length === 0 || typeof appID === 'object' || appID === undefined) {
|
|
appID = '';
|
|
apiKey = '';
|
|
opts._allowEmptyCredentials = true;
|
|
}
|
|
|
|
var client = algoliasearch(appID, apiKey, opts);
|
|
var index = client.initIndex('places');
|
|
index.search = buildSearchMethod('query', '/1/places/query');
|
|
index.reverse = function(options, callback) {
|
|
var encoded = qs3.encode(options);
|
|
|
|
return this.as._jsonRequest({
|
|
method: 'GET',
|
|
url: '/1/places/reverse?' + encoded,
|
|
hostType: 'read',
|
|
callback: callback
|
|
});
|
|
};
|
|
|
|
index.getObject = function(objectID, callback) {
|
|
return this.as._jsonRequest({
|
|
method: 'GET',
|
|
url: '/1/places/' + encodeURIComponent(objectID),
|
|
hostType: 'read',
|
|
callback: callback
|
|
});
|
|
};
|
|
return index;
|
|
};
|
|
}
|
|
|
|
|
|
/***/ }),
|
|
/* 51 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.decode = exports.parse = __webpack_require__(52);
|
|
exports.encode = exports.stringify = __webpack_require__(25);
|
|
|
|
|
|
/***/ }),
|
|
/* 52 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
// If obj.hasOwnProperty has been overridden, then calling
|
|
// obj.hasOwnProperty(prop) will break.
|
|
// See: https://github.com/joyent/node/issues/1707
|
|
function hasOwnProperty(obj, prop) {
|
|
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
}
|
|
|
|
module.exports = function(qs, sep, eq, options) {
|
|
sep = sep || '&';
|
|
eq = eq || '=';
|
|
var obj = {};
|
|
|
|
if (typeof qs !== 'string' || qs.length === 0) {
|
|
return obj;
|
|
}
|
|
|
|
var regexp = /\+/g;
|
|
qs = qs.split(sep);
|
|
|
|
var maxKeys = 1000;
|
|
if (options && typeof options.maxKeys === 'number') {
|
|
maxKeys = options.maxKeys;
|
|
}
|
|
|
|
var len = qs.length;
|
|
// maxKeys <= 0 means that we should not limit keys count
|
|
if (maxKeys > 0 && len > maxKeys) {
|
|
len = maxKeys;
|
|
}
|
|
|
|
for (var i = 0; i < len; ++i) {
|
|
var x = qs[i].replace(regexp, '%20'),
|
|
idx = x.indexOf(eq),
|
|
kstr, vstr, k, v;
|
|
|
|
if (idx >= 0) {
|
|
kstr = x.substr(0, idx);
|
|
vstr = x.substr(idx + 1);
|
|
} else {
|
|
kstr = x;
|
|
vstr = '';
|
|
}
|
|
|
|
k = decodeURIComponent(kstr);
|
|
v = decodeURIComponent(vstr);
|
|
|
|
if (!hasOwnProperty(obj, k)) {
|
|
obj[k] = v;
|
|
} else if (isArray(obj[k])) {
|
|
obj[k].push(v);
|
|
} else {
|
|
obj[k] = [obj[k], v];
|
|
}
|
|
}
|
|
|
|
return obj;
|
|
};
|
|
|
|
var isArray = Array.isArray || function (xs) {
|
|
return Object.prototype.toString.call(xs) === '[object Array]';
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 53 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
module.exports = '3.35.1';
|
|
|
|
|
|
/***/ }),
|
|
/* 54 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
// this will inject Zepto in window, unfortunately no easy commonJS zepto build
|
|
var zepto = __webpack_require__(55);
|
|
|
|
// setup DOM element
|
|
var DOM = __webpack_require__(2);
|
|
DOM.element = zepto;
|
|
|
|
// setup utils functions
|
|
var _ = __webpack_require__(0);
|
|
_.isArray = zepto.isArray;
|
|
_.isFunction = zepto.isFunction;
|
|
_.isObject = zepto.isPlainObject;
|
|
_.bind = zepto.proxy;
|
|
_.each = function(collection, cb) {
|
|
// stupid argument order for jQuery.each
|
|
zepto.each(collection, reverseArgs);
|
|
function reverseArgs(index, value) {
|
|
return cb(value, index);
|
|
}
|
|
};
|
|
_.map = zepto.map;
|
|
_.mixin = zepto.extend;
|
|
_.Event = zepto.Event;
|
|
|
|
var typeaheadKey = 'aaAutocomplete';
|
|
var Typeahead = __webpack_require__(56);
|
|
var EventBus = __webpack_require__(26);
|
|
|
|
function autocomplete(selector, options, datasets, typeaheadObject) {
|
|
datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 2);
|
|
|
|
var inputs = zepto(selector).each(function(i, input) {
|
|
var $input = zepto(input);
|
|
var eventBus = new EventBus({el: $input});
|
|
var typeahead = typeaheadObject || new Typeahead({
|
|
input: $input,
|
|
eventBus: eventBus,
|
|
dropdownMenuContainer: options.dropdownMenuContainer,
|
|
hint: options.hint === undefined ? true : !!options.hint,
|
|
minLength: options.minLength,
|
|
autoselect: options.autoselect,
|
|
autoselectOnBlur: options.autoselectOnBlur,
|
|
tabAutocomplete: options.tabAutocomplete,
|
|
openOnFocus: options.openOnFocus,
|
|
templates: options.templates,
|
|
debug: options.debug,
|
|
clearOnSelected: options.clearOnSelected,
|
|
cssClasses: options.cssClasses,
|
|
datasets: datasets,
|
|
keyboardShortcuts: options.keyboardShortcuts,
|
|
appendTo: options.appendTo,
|
|
autoWidth: options.autoWidth,
|
|
ariaLabel: options.ariaLabel || input.getAttribute('aria-label')
|
|
});
|
|
$input.data(typeaheadKey, typeahead);
|
|
});
|
|
|
|
// expose all methods in the `autocomplete` attribute
|
|
inputs.autocomplete = {};
|
|
_.each(['open', 'close', 'getVal', 'setVal', 'destroy', 'getWrapper'], function(method) {
|
|
inputs.autocomplete[method] = function() {
|
|
var methodArguments = arguments;
|
|
var result;
|
|
inputs.each(function(j, input) {
|
|
var typeahead = zepto(input).data(typeaheadKey);
|
|
result = typeahead[method].apply(typeahead, methodArguments);
|
|
});
|
|
return result;
|
|
};
|
|
});
|
|
|
|
return inputs;
|
|
}
|
|
|
|
autocomplete.sources = Typeahead.sources;
|
|
autocomplete.escapeHighlightedString = _.escapeHighlightedString;
|
|
|
|
var wasAutocompleteSet = 'autocomplete' in window;
|
|
var oldAutocomplete = window.autocomplete;
|
|
autocomplete.noConflict = function noConflict() {
|
|
if (wasAutocompleteSet) {
|
|
window.autocomplete = oldAutocomplete;
|
|
} else {
|
|
delete window.autocomplete;
|
|
}
|
|
return autocomplete;
|
|
};
|
|
|
|
module.exports = autocomplete;
|
|
|
|
|
|
/***/ }),
|
|
/* 55 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/* istanbul ignore next */
|
|
/* Zepto v1.2.0 - zepto event assets data - zeptojs.com/license */
|
|
(function(global, factory) {
|
|
module.exports = factory(global);
|
|
}(/* this ##### UPDATED: here we want to use window/global instead of this which is the current file context ##### */ window, function(window) {
|
|
var Zepto = (function() {
|
|
var undefined, key, $, classList, emptyArray = [], concat = emptyArray.concat, filter = emptyArray.filter, slice = emptyArray.slice,
|
|
document = window.document,
|
|
elementDisplay = {}, classCache = {},
|
|
cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 },
|
|
fragmentRE = /^\s*<(\w+|!)[^>]*>/,
|
|
singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
|
|
tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
|
|
rootNodeRE = /^(?:body|html)$/i,
|
|
capitalRE = /([A-Z])/g,
|
|
|
|
// special attributes that should be get/set via method calls
|
|
methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],
|
|
|
|
adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ],
|
|
table = document.createElement('table'),
|
|
tableRow = document.createElement('tr'),
|
|
containers = {
|
|
'tr': document.createElement('tbody'),
|
|
'tbody': table, 'thead': table, 'tfoot': table,
|
|
'td': tableRow, 'th': tableRow,
|
|
'*': document.createElement('div')
|
|
},
|
|
readyRE = /complete|loaded|interactive/,
|
|
simpleSelectorRE = /^[\w-]*$/,
|
|
class2type = {},
|
|
toString = class2type.toString,
|
|
zepto = {},
|
|
camelize, uniq,
|
|
tempParent = document.createElement('div'),
|
|
propMap = {
|
|
'tabindex': 'tabIndex',
|
|
'readonly': 'readOnly',
|
|
'for': 'htmlFor',
|
|
'class': 'className',
|
|
'maxlength': 'maxLength',
|
|
'cellspacing': 'cellSpacing',
|
|
'cellpadding': 'cellPadding',
|
|
'rowspan': 'rowSpan',
|
|
'colspan': 'colSpan',
|
|
'usemap': 'useMap',
|
|
'frameborder': 'frameBorder',
|
|
'contenteditable': 'contentEditable'
|
|
},
|
|
isArray = Array.isArray ||
|
|
function(object){ return object instanceof Array }
|
|
|
|
zepto.matches = function(element, selector) {
|
|
if (!selector || !element || element.nodeType !== 1) return false
|
|
var matchesSelector = element.matches || element.webkitMatchesSelector ||
|
|
element.mozMatchesSelector || element.oMatchesSelector ||
|
|
element.matchesSelector
|
|
if (matchesSelector) return matchesSelector.call(element, selector)
|
|
// fall back to performing a selector:
|
|
var match, parent = element.parentNode, temp = !parent
|
|
if (temp) (parent = tempParent).appendChild(element)
|
|
match = ~zepto.qsa(parent, selector).indexOf(element)
|
|
temp && tempParent.removeChild(element)
|
|
return match
|
|
}
|
|
|
|
function type(obj) {
|
|
return obj == null ? String(obj) :
|
|
class2type[toString.call(obj)] || "object"
|
|
}
|
|
|
|
function isFunction(value) { return type(value) == "function" }
|
|
function isWindow(obj) { return obj != null && obj == obj.window }
|
|
function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE }
|
|
function isObject(obj) { return type(obj) == "object" }
|
|
function isPlainObject(obj) {
|
|
return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype
|
|
}
|
|
|
|
function likeArray(obj) {
|
|
var length = !!obj && 'length' in obj && obj.length,
|
|
type = $.type(obj)
|
|
|
|
return 'function' != type && !isWindow(obj) && (
|
|
'array' == type || length === 0 ||
|
|
(typeof length == 'number' && length > 0 && (length - 1) in obj)
|
|
)
|
|
}
|
|
|
|
function compact(array) { return filter.call(array, function(item){ return item != null }) }
|
|
function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array }
|
|
camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) }
|
|
function dasherize(str) {
|
|
return str.replace(/::/g, '/')
|
|
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
|
|
.replace(/([a-z\d])([A-Z])/g, '$1_$2')
|
|
.replace(/_/g, '-')
|
|
.toLowerCase()
|
|
}
|
|
uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) }
|
|
|
|
function classRE(name) {
|
|
return name in classCache ?
|
|
classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)'))
|
|
}
|
|
|
|
function maybeAddPx(name, value) {
|
|
return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value
|
|
}
|
|
|
|
function defaultDisplay(nodeName) {
|
|
var element, display
|
|
if (!elementDisplay[nodeName]) {
|
|
element = document.createElement(nodeName)
|
|
document.body.appendChild(element)
|
|
display = getComputedStyle(element, '').getPropertyValue("display")
|
|
element.parentNode.removeChild(element)
|
|
display == "none" && (display = "block")
|
|
elementDisplay[nodeName] = display
|
|
}
|
|
return elementDisplay[nodeName]
|
|
}
|
|
|
|
function children(element) {
|
|
return 'children' in element ?
|
|
slice.call(element.children) :
|
|
$.map(element.childNodes, function(node){ if (node.nodeType == 1) return node })
|
|
}
|
|
|
|
function Z(dom, selector) {
|
|
var i, len = dom ? dom.length : 0
|
|
for (i = 0; i < len; i++) this[i] = dom[i]
|
|
this.length = len
|
|
this.selector = selector || ''
|
|
}
|
|
|
|
// `$.zepto.fragment` takes a html string and an optional tag name
|
|
// to generate DOM nodes from the given html string.
|
|
// The generated DOM nodes are returned as an array.
|
|
// This function can be overridden in plugins for example to make
|
|
// it compatible with browsers that don't support the DOM fully.
|
|
zepto.fragment = function(html, name, properties) {
|
|
var dom, nodes, container
|
|
|
|
// A special case optimization for a single tag
|
|
if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1))
|
|
|
|
if (!dom) {
|
|
if (html.replace) html = html.replace(tagExpanderRE, "<$1></$2>")
|
|
if (name === undefined) name = fragmentRE.test(html) && RegExp.$1
|
|
if (!(name in containers)) name = '*'
|
|
|
|
container = containers[name]
|
|
container.innerHTML = '' + html
|
|
dom = $.each(slice.call(container.childNodes), function(){
|
|
container.removeChild(this)
|
|
})
|
|
}
|
|
|
|
if (isPlainObject(properties)) {
|
|
nodes = $(dom)
|
|
$.each(properties, function(key, value) {
|
|
if (methodAttributes.indexOf(key) > -1) nodes[key](value)
|
|
else nodes.attr(key, value)
|
|
})
|
|
}
|
|
|
|
return dom
|
|
}
|
|
|
|
// `$.zepto.Z` swaps out the prototype of the given `dom` array
|
|
// of nodes with `$.fn` and thus supplying all the Zepto functions
|
|
// to the array. This method can be overridden in plugins.
|
|
zepto.Z = function(dom, selector) {
|
|
return new Z(dom, selector)
|
|
}
|
|
|
|
// `$.zepto.isZ` should return `true` if the given object is a Zepto
|
|
// collection. This method can be overridden in plugins.
|
|
zepto.isZ = function(object) {
|
|
return object instanceof zepto.Z
|
|
}
|
|
|
|
// `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and
|
|
// takes a CSS selector and an optional context (and handles various
|
|
// special cases).
|
|
// This method can be overridden in plugins.
|
|
zepto.init = function(selector, context) {
|
|
var dom
|
|
// If nothing given, return an empty Zepto collection
|
|
if (!selector) return zepto.Z()
|
|
// Optimize for string selectors
|
|
else if (typeof selector == 'string') {
|
|
selector = selector.trim()
|
|
// If it's a html fragment, create nodes from it
|
|
// Note: In both Chrome 21 and Firefox 15, DOM error 12
|
|
// is thrown if the fragment doesn't begin with <
|
|
if (selector[0] == '<' && fragmentRE.test(selector))
|
|
dom = zepto.fragment(selector, RegExp.$1, context), selector = null
|
|
// If there's a context, create a collection on that context first, and select
|
|
// nodes from there
|
|
else if (context !== undefined) return $(context).find(selector)
|
|
// If it's a CSS selector, use it to select nodes.
|
|
else dom = zepto.qsa(document, selector)
|
|
}
|
|
// If a function is given, call it when the DOM is ready
|
|
else if (isFunction(selector)) return $(document).ready(selector)
|
|
// If a Zepto collection is given, just return it
|
|
else if (zepto.isZ(selector)) return selector
|
|
else {
|
|
// normalize array if an array of nodes is given
|
|
if (isArray(selector)) dom = compact(selector)
|
|
// Wrap DOM nodes.
|
|
else if (isObject(selector))
|
|
dom = [selector], selector = null
|
|
// If it's a html fragment, create nodes from it
|
|
else if (fragmentRE.test(selector))
|
|
dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null
|
|
// If there's a context, create a collection on that context first, and select
|
|
// nodes from there
|
|
else if (context !== undefined) return $(context).find(selector)
|
|
// And last but no least, if it's a CSS selector, use it to select nodes.
|
|
else dom = zepto.qsa(document, selector)
|
|
}
|
|
// create a new Zepto collection from the nodes found
|
|
return zepto.Z(dom, selector)
|
|
}
|
|
|
|
// `$` will be the base `Zepto` object. When calling this
|
|
// function just call `$.zepto.init, which makes the implementation
|
|
// details of selecting nodes and creating Zepto collections
|
|
// patchable in plugins.
|
|
$ = function(selector, context){
|
|
return zepto.init(selector, context)
|
|
}
|
|
|
|
function extend(target, source, deep) {
|
|
for (key in source)
|
|
if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
|
|
if (isPlainObject(source[key]) && !isPlainObject(target[key]))
|
|
target[key] = {}
|
|
if (isArray(source[key]) && !isArray(target[key]))
|
|
target[key] = []
|
|
extend(target[key], source[key], deep)
|
|
}
|
|
else if (source[key] !== undefined) target[key] = source[key]
|
|
}
|
|
|
|
// Copy all but undefined properties from one or more
|
|
// objects to the `target` object.
|
|
$.extend = function(target){
|
|
var deep, args = slice.call(arguments, 1)
|
|
if (typeof target == 'boolean') {
|
|
deep = target
|
|
target = args.shift()
|
|
}
|
|
args.forEach(function(arg){ extend(target, arg, deep) })
|
|
return target
|
|
}
|
|
|
|
// `$.zepto.qsa` is Zepto's CSS selector implementation which
|
|
// uses `document.querySelectorAll` and optimizes for some special cases, like `#id`.
|
|
// This method can be overridden in plugins.
|
|
zepto.qsa = function(element, selector){
|
|
var found,
|
|
maybeID = selector[0] == '#',
|
|
maybeClass = !maybeID && selector[0] == '.',
|
|
nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked
|
|
isSimple = simpleSelectorRE.test(nameOnly)
|
|
return (element.getElementById && isSimple && maybeID) ? // Safari DocumentFragment doesn't have getElementById
|
|
( (found = element.getElementById(nameOnly)) ? [found] : [] ) :
|
|
(element.nodeType !== 1 && element.nodeType !== 9 && element.nodeType !== 11) ? [] :
|
|
slice.call(
|
|
isSimple && !maybeID && element.getElementsByClassName ? // DocumentFragment doesn't have getElementsByClassName/TagName
|
|
maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class
|
|
element.getElementsByTagName(selector) : // Or a tag
|
|
element.querySelectorAll(selector) // Or it's not simple, and we need to query all
|
|
)
|
|
}
|
|
|
|
function filtered(nodes, selector) {
|
|
return selector == null ? $(nodes) : $(nodes).filter(selector)
|
|
}
|
|
|
|
$.contains = document.documentElement.contains ?
|
|
function(parent, node) {
|
|
return parent !== node && parent.contains(node)
|
|
} :
|
|
function(parent, node) {
|
|
while (node && (node = node.parentNode))
|
|
if (node === parent) return true
|
|
return false
|
|
}
|
|
|
|
function funcArg(context, arg, idx, payload) {
|
|
return isFunction(arg) ? arg.call(context, idx, payload) : arg
|
|
}
|
|
|
|
function setAttribute(node, name, value) {
|
|
value == null ? node.removeAttribute(name) : node.setAttribute(name, value)
|
|
}
|
|
|
|
// access className property while respecting SVGAnimatedString
|
|
function className(node, value){
|
|
var klass = node.className || '',
|
|
svg = klass && klass.baseVal !== undefined
|
|
|
|
if (value === undefined) return svg ? klass.baseVal : klass
|
|
svg ? (klass.baseVal = value) : (node.className = value)
|
|
}
|
|
|
|
// "true" => true
|
|
// "false" => false
|
|
// "null" => null
|
|
// "42" => 42
|
|
// "42.5" => 42.5
|
|
// "08" => "08"
|
|
// JSON => parse if valid
|
|
// String => self
|
|
function deserializeValue(value) {
|
|
try {
|
|
return value ?
|
|
value == "true" ||
|
|
( value == "false" ? false :
|
|
value == "null" ? null :
|
|
+value + "" == value ? +value :
|
|
/^[\[\{]/.test(value) ? $.parseJSON(value) :
|
|
value )
|
|
: value
|
|
} catch(e) {
|
|
return value
|
|
}
|
|
}
|
|
|
|
$.type = type
|
|
$.isFunction = isFunction
|
|
$.isWindow = isWindow
|
|
$.isArray = isArray
|
|
$.isPlainObject = isPlainObject
|
|
|
|
$.isEmptyObject = function(obj) {
|
|
var name
|
|
for (name in obj) return false
|
|
return true
|
|
}
|
|
|
|
$.isNumeric = function(val) {
|
|
var num = Number(val), type = typeof val
|
|
return val != null && type != 'boolean' &&
|
|
(type != 'string' || val.length) &&
|
|
!isNaN(num) && isFinite(num) || false
|
|
}
|
|
|
|
$.inArray = function(elem, array, i){
|
|
return emptyArray.indexOf.call(array, elem, i)
|
|
}
|
|
|
|
$.camelCase = camelize
|
|
$.trim = function(str) {
|
|
return str == null ? "" : String.prototype.trim.call(str)
|
|
}
|
|
|
|
// plugin compatibility
|
|
$.uuid = 0
|
|
$.support = { }
|
|
$.expr = { }
|
|
$.noop = function() {}
|
|
|
|
$.map = function(elements, callback){
|
|
var value, values = [], i, key
|
|
if (likeArray(elements))
|
|
for (i = 0; i < elements.length; i++) {
|
|
value = callback(elements[i], i)
|
|
if (value != null) values.push(value)
|
|
}
|
|
else
|
|
for (key in elements) {
|
|
value = callback(elements[key], key)
|
|
if (value != null) values.push(value)
|
|
}
|
|
return flatten(values)
|
|
}
|
|
|
|
$.each = function(elements, callback){
|
|
var i, key
|
|
if (likeArray(elements)) {
|
|
for (i = 0; i < elements.length; i++)
|
|
if (callback.call(elements[i], i, elements[i]) === false) return elements
|
|
} else {
|
|
for (key in elements)
|
|
if (callback.call(elements[key], key, elements[key]) === false) return elements
|
|
}
|
|
|
|
return elements
|
|
}
|
|
|
|
$.grep = function(elements, callback){
|
|
return filter.call(elements, callback)
|
|
}
|
|
|
|
if (window.JSON) $.parseJSON = JSON.parse
|
|
|
|
// Populate the class2type map
|
|
$.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
|
|
class2type[ "[object " + name + "]" ] = name.toLowerCase()
|
|
})
|
|
|
|
// Define methods that will be available on all
|
|
// Zepto collections
|
|
$.fn = {
|
|
constructor: zepto.Z,
|
|
length: 0,
|
|
|
|
// Because a collection acts like an array
|
|
// copy over these useful array functions.
|
|
forEach: emptyArray.forEach,
|
|
reduce: emptyArray.reduce,
|
|
push: emptyArray.push,
|
|
sort: emptyArray.sort,
|
|
splice: emptyArray.splice,
|
|
indexOf: emptyArray.indexOf,
|
|
concat: function(){
|
|
var i, value, args = []
|
|
for (i = 0; i < arguments.length; i++) {
|
|
value = arguments[i]
|
|
args[i] = zepto.isZ(value) ? value.toArray() : value
|
|
}
|
|
return concat.apply(zepto.isZ(this) ? this.toArray() : this, args)
|
|
},
|
|
|
|
// `map` and `slice` in the jQuery API work differently
|
|
// from their array counterparts
|
|
map: function(fn){
|
|
return $($.map(this, function(el, i){ return fn.call(el, i, el) }))
|
|
},
|
|
slice: function(){
|
|
return $(slice.apply(this, arguments))
|
|
},
|
|
|
|
ready: function(callback){
|
|
// need to check if document.body exists for IE as that browser reports
|
|
// document ready when it hasn't yet created the body element
|
|
if (readyRE.test(document.readyState) && document.body) callback($)
|
|
else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false)
|
|
return this
|
|
},
|
|
get: function(idx){
|
|
return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length]
|
|
},
|
|
toArray: function(){ return this.get() },
|
|
size: function(){
|
|
return this.length
|
|
},
|
|
remove: function(){
|
|
return this.each(function(){
|
|
if (this.parentNode != null)
|
|
this.parentNode.removeChild(this)
|
|
})
|
|
},
|
|
each: function(callback){
|
|
emptyArray.every.call(this, function(el, idx){
|
|
return callback.call(el, idx, el) !== false
|
|
})
|
|
return this
|
|
},
|
|
filter: function(selector){
|
|
if (isFunction(selector)) return this.not(this.not(selector))
|
|
return $(filter.call(this, function(element){
|
|
return zepto.matches(element, selector)
|
|
}))
|
|
},
|
|
add: function(selector,context){
|
|
return $(uniq(this.concat($(selector,context))))
|
|
},
|
|
is: function(selector){
|
|
return this.length > 0 && zepto.matches(this[0], selector)
|
|
},
|
|
not: function(selector){
|
|
var nodes=[]
|
|
if (isFunction(selector) && selector.call !== undefined)
|
|
this.each(function(idx){
|
|
if (!selector.call(this,idx)) nodes.push(this)
|
|
})
|
|
else {
|
|
var excludes = typeof selector == 'string' ? this.filter(selector) :
|
|
(likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector)
|
|
this.forEach(function(el){
|
|
if (excludes.indexOf(el) < 0) nodes.push(el)
|
|
})
|
|
}
|
|
return $(nodes)
|
|
},
|
|
has: function(selector){
|
|
return this.filter(function(){
|
|
return isObject(selector) ?
|
|
$.contains(this, selector) :
|
|
$(this).find(selector).size()
|
|
})
|
|
},
|
|
eq: function(idx){
|
|
return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1)
|
|
},
|
|
first: function(){
|
|
var el = this[0]
|
|
return el && !isObject(el) ? el : $(el)
|
|
},
|
|
last: function(){
|
|
var el = this[this.length - 1]
|
|
return el && !isObject(el) ? el : $(el)
|
|
},
|
|
find: function(selector){
|
|
var result, $this = this
|
|
if (!selector) result = $()
|
|
else if (typeof selector == 'object')
|
|
result = $(selector).filter(function(){
|
|
var node = this
|
|
return emptyArray.some.call($this, function(parent){
|
|
return $.contains(parent, node)
|
|
})
|
|
})
|
|
else if (this.length == 1) result = $(zepto.qsa(this[0], selector))
|
|
else result = this.map(function(){ return zepto.qsa(this, selector) })
|
|
return result
|
|
},
|
|
closest: function(selector, context){
|
|
var nodes = [], collection = typeof selector == 'object' && $(selector)
|
|
this.each(function(_, node){
|
|
while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector)))
|
|
node = node !== context && !isDocument(node) && node.parentNode
|
|
if (node && nodes.indexOf(node) < 0) nodes.push(node)
|
|
})
|
|
return $(nodes)
|
|
},
|
|
parents: function(selector){
|
|
var ancestors = [], nodes = this
|
|
while (nodes.length > 0)
|
|
nodes = $.map(nodes, function(node){
|
|
if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) {
|
|
ancestors.push(node)
|
|
return node
|
|
}
|
|
})
|
|
return filtered(ancestors, selector)
|
|
},
|
|
parent: function(selector){
|
|
return filtered(uniq(this.pluck('parentNode')), selector)
|
|
},
|
|
children: function(selector){
|
|
return filtered(this.map(function(){ return children(this) }), selector)
|
|
},
|
|
contents: function() {
|
|
return this.map(function() { return this.contentDocument || slice.call(this.childNodes) })
|
|
},
|
|
siblings: function(selector){
|
|
return filtered(this.map(function(i, el){
|
|
return filter.call(children(el.parentNode), function(child){ return child!==el })
|
|
}), selector)
|
|
},
|
|
empty: function(){
|
|
return this.each(function(){ this.innerHTML = '' })
|
|
},
|
|
// `pluck` is borrowed from Prototype.js
|
|
pluck: function(property){
|
|
return $.map(this, function(el){ return el[property] })
|
|
},
|
|
show: function(){
|
|
return this.each(function(){
|
|
this.style.display == "none" && (this.style.display = '')
|
|
if (getComputedStyle(this, '').getPropertyValue("display") == "none")
|
|
this.style.display = defaultDisplay(this.nodeName)
|
|
})
|
|
},
|
|
replaceWith: function(newContent){
|
|
return this.before(newContent).remove()
|
|
},
|
|
wrap: function(structure){
|
|
var func = isFunction(structure)
|
|
if (this[0] && !func)
|
|
var dom = $(structure).get(0),
|
|
clone = dom.parentNode || this.length > 1
|
|
|
|
return this.each(function(index){
|
|
$(this).wrapAll(
|
|
func ? structure.call(this, index) :
|
|
clone ? dom.cloneNode(true) : dom
|
|
)
|
|
})
|
|
},
|
|
wrapAll: function(structure){
|
|
if (this[0]) {
|
|
$(this[0]).before(structure = $(structure))
|
|
var children
|
|
// drill down to the inmost element
|
|
while ((children = structure.children()).length) structure = children.first()
|
|
$(structure).append(this)
|
|
}
|
|
return this
|
|
},
|
|
wrapInner: function(structure){
|
|
var func = isFunction(structure)
|
|
return this.each(function(index){
|
|
var self = $(this), contents = self.contents(),
|
|
dom = func ? structure.call(this, index) : structure
|
|
contents.length ? contents.wrapAll(dom) : self.append(dom)
|
|
})
|
|
},
|
|
unwrap: function(){
|
|
this.parent().each(function(){
|
|
$(this).replaceWith($(this).children())
|
|
})
|
|
return this
|
|
},
|
|
clone: function(){
|
|
return this.map(function(){ return this.cloneNode(true) })
|
|
},
|
|
hide: function(){
|
|
return this.css("display", "none")
|
|
},
|
|
toggle: function(setting){
|
|
return this.each(function(){
|
|
var el = $(this)
|
|
;(setting === undefined ? el.css("display") == "none" : setting) ? el.show() : el.hide()
|
|
})
|
|
},
|
|
prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') },
|
|
next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') },
|
|
html: function(html){
|
|
return 0 in arguments ?
|
|
this.each(function(idx){
|
|
var originHtml = this.innerHTML
|
|
$(this).empty().append( funcArg(this, html, idx, originHtml) )
|
|
}) :
|
|
(0 in this ? this[0].innerHTML : null)
|
|
},
|
|
text: function(text){
|
|
return 0 in arguments ?
|
|
this.each(function(idx){
|
|
var newText = funcArg(this, text, idx, this.textContent)
|
|
this.textContent = newText == null ? '' : ''+newText
|
|
}) :
|
|
(0 in this ? this.pluck('textContent').join("") : null)
|
|
},
|
|
attr: function(name, value){
|
|
var result
|
|
return (typeof name == 'string' && !(1 in arguments)) ?
|
|
(0 in this && this[0].nodeType == 1 && (result = this[0].getAttribute(name)) != null ? result : undefined) :
|
|
this.each(function(idx){
|
|
if (this.nodeType !== 1) return
|
|
if (isObject(name)) for (key in name) setAttribute(this, key, name[key])
|
|
else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name)))
|
|
})
|
|
},
|
|
removeAttr: function(name){
|
|
return this.each(function(){ this.nodeType === 1 && name.split(' ').forEach(function(attribute){
|
|
setAttribute(this, attribute)
|
|
}, this)})
|
|
},
|
|
prop: function(name, value){
|
|
name = propMap[name] || name
|
|
return (1 in arguments) ?
|
|
this.each(function(idx){
|
|
this[name] = funcArg(this, value, idx, this[name])
|
|
}) :
|
|
(this[0] && this[0][name])
|
|
},
|
|
removeProp: function(name){
|
|
name = propMap[name] || name
|
|
return this.each(function(){ delete this[name] })
|
|
},
|
|
data: function(name, value){
|
|
var attrName = 'data-' + name.replace(capitalRE, '-$1').toLowerCase()
|
|
|
|
var data = (1 in arguments) ?
|
|
this.attr(attrName, value) :
|
|
this.attr(attrName)
|
|
|
|
return data !== null ? deserializeValue(data) : undefined
|
|
},
|
|
val: function(value){
|
|
if (0 in arguments) {
|
|
if (value == null) value = ""
|
|
return this.each(function(idx){
|
|
this.value = funcArg(this, value, idx, this.value)
|
|
})
|
|
} else {
|
|
return this[0] && (this[0].multiple ?
|
|
$(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') :
|
|
this[0].value)
|
|
}
|
|
},
|
|
offset: function(coordinates){
|
|
if (coordinates) return this.each(function(index){
|
|
var $this = $(this),
|
|
coords = funcArg(this, coordinates, index, $this.offset()),
|
|
parentOffset = $this.offsetParent().offset(),
|
|
props = {
|
|
top: coords.top - parentOffset.top,
|
|
left: coords.left - parentOffset.left
|
|
}
|
|
|
|
if ($this.css('position') == 'static') props['position'] = 'relative'
|
|
$this.css(props)
|
|
})
|
|
if (!this.length) return null
|
|
if (document.documentElement !== this[0] && !$.contains(document.documentElement, this[0]))
|
|
return {top: 0, left: 0}
|
|
var obj = this[0].getBoundingClientRect()
|
|
return {
|
|
left: obj.left + window.pageXOffset,
|
|
top: obj.top + window.pageYOffset,
|
|
width: Math.round(obj.width),
|
|
height: Math.round(obj.height)
|
|
}
|
|
},
|
|
css: function(property, value){
|
|
if (arguments.length < 2) {
|
|
var element = this[0]
|
|
if (typeof property == 'string') {
|
|
if (!element) return
|
|
return element.style[camelize(property)] || getComputedStyle(element, '').getPropertyValue(property)
|
|
} else if (isArray(property)) {
|
|
if (!element) return
|
|
var props = {}
|
|
var computedStyle = getComputedStyle(element, '')
|
|
$.each(property, function(_, prop){
|
|
props[prop] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop))
|
|
})
|
|
return props
|
|
}
|
|
}
|
|
|
|
var css = ''
|
|
if (type(property) == 'string') {
|
|
if (!value && value !== 0)
|
|
this.each(function(){ this.style.removeProperty(dasherize(property)) })
|
|
else
|
|
css = dasherize(property) + ":" + maybeAddPx(property, value)
|
|
} else {
|
|
for (key in property)
|
|
if (!property[key] && property[key] !== 0)
|
|
this.each(function(){ this.style.removeProperty(dasherize(key)) })
|
|
else
|
|
css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';'
|
|
}
|
|
|
|
return this.each(function(){ this.style.cssText += ';' + css })
|
|
},
|
|
index: function(element){
|
|
return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0])
|
|
},
|
|
hasClass: function(name){
|
|
if (!name) return false
|
|
return emptyArray.some.call(this, function(el){
|
|
return this.test(className(el))
|
|
}, classRE(name))
|
|
},
|
|
addClass: function(name){
|
|
if (!name) return this
|
|
return this.each(function(idx){
|
|
if (!('className' in this)) return
|
|
classList = []
|
|
var cls = className(this), newName = funcArg(this, name, idx, cls)
|
|
newName.split(/\s+/g).forEach(function(klass){
|
|
if (!$(this).hasClass(klass)) classList.push(klass)
|
|
}, this)
|
|
classList.length && className(this, cls + (cls ? " " : "") + classList.join(" "))
|
|
})
|
|
},
|
|
removeClass: function(name){
|
|
return this.each(function(idx){
|
|
if (!('className' in this)) return
|
|
if (name === undefined) return className(this, '')
|
|
classList = className(this)
|
|
funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){
|
|
classList = classList.replace(classRE(klass), " ")
|
|
})
|
|
className(this, classList.trim())
|
|
})
|
|
},
|
|
toggleClass: function(name, when){
|
|
if (!name) return this
|
|
return this.each(function(idx){
|
|
var $this = $(this), names = funcArg(this, name, idx, className(this))
|
|
names.split(/\s+/g).forEach(function(klass){
|
|
(when === undefined ? !$this.hasClass(klass) : when) ?
|
|
$this.addClass(klass) : $this.removeClass(klass)
|
|
})
|
|
})
|
|
},
|
|
scrollTop: function(value){
|
|
if (!this.length) return
|
|
var hasScrollTop = 'scrollTop' in this[0]
|
|
if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffset
|
|
return this.each(hasScrollTop ?
|
|
function(){ this.scrollTop = value } :
|
|
function(){ this.scrollTo(this.scrollX, value) })
|
|
},
|
|
scrollLeft: function(value){
|
|
if (!this.length) return
|
|
var hasScrollLeft = 'scrollLeft' in this[0]
|
|
if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset
|
|
return this.each(hasScrollLeft ?
|
|
function(){ this.scrollLeft = value } :
|
|
function(){ this.scrollTo(value, this.scrollY) })
|
|
},
|
|
position: function() {
|
|
if (!this.length) return
|
|
|
|
var elem = this[0],
|
|
// Get *real* offsetParent
|
|
offsetParent = this.offsetParent(),
|
|
// Get correct offsets
|
|
offset = this.offset(),
|
|
parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset()
|
|
|
|
// Subtract element margins
|
|
// note: when an element has margin: auto the offsetLeft and marginLeft
|
|
// are the same in Safari causing offset.left to incorrectly be 0
|
|
offset.top -= parseFloat( $(elem).css('margin-top') ) || 0
|
|
offset.left -= parseFloat( $(elem).css('margin-left') ) || 0
|
|
|
|
// Add offsetParent borders
|
|
parentOffset.top += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0
|
|
parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0
|
|
|
|
// Subtract the two offsets
|
|
return {
|
|
top: offset.top - parentOffset.top,
|
|
left: offset.left - parentOffset.left
|
|
}
|
|
},
|
|
offsetParent: function() {
|
|
return this.map(function(){
|
|
var parent = this.offsetParent || document.body
|
|
while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css("position") == "static")
|
|
parent = parent.offsetParent
|
|
return parent
|
|
})
|
|
}
|
|
}
|
|
|
|
// for now
|
|
$.fn.detach = $.fn.remove
|
|
|
|
// Generate the `width` and `height` functions
|
|
;['width', 'height'].forEach(function(dimension){
|
|
var dimensionProperty =
|
|
dimension.replace(/./, function(m){ return m[0].toUpperCase() })
|
|
|
|
$.fn[dimension] = function(value){
|
|
var offset, el = this[0]
|
|
if (value === undefined) return isWindow(el) ? el['inner' + dimensionProperty] :
|
|
isDocument(el) ? el.documentElement['scroll' + dimensionProperty] :
|
|
(offset = this.offset()) && offset[dimension]
|
|
else return this.each(function(idx){
|
|
el = $(this)
|
|
el.css(dimension, funcArg(this, value, idx, el[dimension]()))
|
|
})
|
|
}
|
|
})
|
|
|
|
function traverseNode(node, fun) {
|
|
fun(node)
|
|
for (var i = 0, len = node.childNodes.length; i < len; i++)
|
|
traverseNode(node.childNodes[i], fun)
|
|
}
|
|
|
|
// Generate the `after`, `prepend`, `before`, `append`,
|
|
// `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods.
|
|
adjacencyOperators.forEach(function(operator, operatorIndex) {
|
|
var inside = operatorIndex % 2 //=> prepend, append
|
|
|
|
$.fn[operator] = function(){
|
|
// arguments can be nodes, arrays of nodes, Zepto objects and HTML strings
|
|
var argType, nodes = $.map(arguments, function(arg) {
|
|
var arr = []
|
|
argType = type(arg)
|
|
if (argType == "array") {
|
|
arg.forEach(function(el) {
|
|
if (el.nodeType !== undefined) return arr.push(el)
|
|
else if ($.zepto.isZ(el)) return arr = arr.concat(el.get())
|
|
arr = arr.concat(zepto.fragment(el))
|
|
})
|
|
return arr
|
|
}
|
|
return argType == "object" || arg == null ?
|
|
arg : zepto.fragment(arg)
|
|
}),
|
|
parent, copyByClone = this.length > 1
|
|
if (nodes.length < 1) return this
|
|
|
|
return this.each(function(_, target){
|
|
parent = inside ? target : target.parentNode
|
|
|
|
// convert all methods to a "before" operation
|
|
target = operatorIndex == 0 ? target.nextSibling :
|
|
operatorIndex == 1 ? target.firstChild :
|
|
operatorIndex == 2 ? target :
|
|
null
|
|
|
|
var parentInDocument = $.contains(document.documentElement, parent)
|
|
|
|
nodes.forEach(function(node){
|
|
if (copyByClone) node = node.cloneNode(true)
|
|
else if (!parent) return $(node).remove()
|
|
|
|
parent.insertBefore(node, target)
|
|
if (parentInDocument) traverseNode(node, function(el){
|
|
if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' &&
|
|
(!el.type || el.type === 'text/javascript') && !el.src){
|
|
var target = el.ownerDocument ? el.ownerDocument.defaultView : window
|
|
target['eval'].call(target, el.innerHTML)
|
|
}
|
|
})
|
|
})
|
|
})
|
|
}
|
|
|
|
// after => insertAfter
|
|
// prepend => prependTo
|
|
// before => insertBefore
|
|
// append => appendTo
|
|
$.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){
|
|
$(html)[operator](this)
|
|
return this
|
|
}
|
|
})
|
|
|
|
zepto.Z.prototype = Z.prototype = $.fn
|
|
|
|
// Export internal API functions in the `$.zepto` namespace
|
|
zepto.uniq = uniq
|
|
zepto.deserializeValue = deserializeValue
|
|
$.zepto = zepto
|
|
|
|
return $
|
|
})()
|
|
|
|
;(function($){
|
|
var _zid = 1, undefined,
|
|
slice = Array.prototype.slice,
|
|
isFunction = $.isFunction,
|
|
isString = function(obj){ return typeof obj == 'string' },
|
|
handlers = {},
|
|
specialEvents={},
|
|
focusinSupported = 'onfocusin' in window,
|
|
focus = { focus: 'focusin', blur: 'focusout' },
|
|
hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' }
|
|
|
|
specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents'
|
|
|
|
function zid(element) {
|
|
return element._zid || (element._zid = _zid++)
|
|
}
|
|
function findHandlers(element, event, fn, selector) {
|
|
event = parse(event)
|
|
if (event.ns) var matcher = matcherFor(event.ns)
|
|
return (handlers[zid(element)] || []).filter(function(handler) {
|
|
return handler
|
|
&& (!event.e || handler.e == event.e)
|
|
&& (!event.ns || matcher.test(handler.ns))
|
|
&& (!fn || zid(handler.fn) === zid(fn))
|
|
&& (!selector || handler.sel == selector)
|
|
})
|
|
}
|
|
function parse(event) {
|
|
var parts = ('' + event).split('.')
|
|
return {e: parts[0], ns: parts.slice(1).sort().join(' ')}
|
|
}
|
|
function matcherFor(ns) {
|
|
return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)')
|
|
}
|
|
|
|
function eventCapture(handler, captureSetting) {
|
|
return handler.del &&
|
|
(!focusinSupported && (handler.e in focus)) ||
|
|
!!captureSetting
|
|
}
|
|
|
|
function realEvent(type) {
|
|
return hover[type] || (focusinSupported && focus[type]) || type
|
|
}
|
|
|
|
function add(element, events, fn, data, selector, delegator, capture){
|
|
var id = zid(element), set = (handlers[id] || (handlers[id] = []))
|
|
events.split(/\s/).forEach(function(event){
|
|
if (event == 'ready') return $(document).ready(fn)
|
|
var handler = parse(event)
|
|
handler.fn = fn
|
|
handler.sel = selector
|
|
// emulate mouseenter, mouseleave
|
|
if (handler.e in hover) fn = function(e){
|
|
var related = e.relatedTarget
|
|
if (!related || (related !== this && !$.contains(this, related)))
|
|
return handler.fn.apply(this, arguments)
|
|
}
|
|
handler.del = delegator
|
|
var callback = delegator || fn
|
|
handler.proxy = function(e){
|
|
e = compatible(e)
|
|
if (e.isImmediatePropagationStopped()) return
|
|
try {
|
|
var dataPropDescriptor = Object.getOwnPropertyDescriptor(e, 'data')
|
|
if (!dataPropDescriptor || dataPropDescriptor.writable)
|
|
e.data = data
|
|
} catch (e) {} // when using strict mode dataPropDescriptor will be undefined when e is InputEvent (even though data property exists). So we surround with try/catch
|
|
var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args))
|
|
if (result === false) e.preventDefault(), e.stopPropagation()
|
|
return result
|
|
}
|
|
handler.i = set.length
|
|
set.push(handler)
|
|
if ('addEventListener' in element)
|
|
element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
|
|
})
|
|
}
|
|
function remove(element, events, fn, selector, capture){
|
|
var id = zid(element)
|
|
;(events || '').split(/\s/).forEach(function(event){
|
|
findHandlers(element, event, fn, selector).forEach(function(handler){
|
|
delete handlers[id][handler.i]
|
|
if ('removeEventListener' in element)
|
|
element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
|
|
})
|
|
})
|
|
}
|
|
|
|
$.event = { add: add, remove: remove }
|
|
|
|
$.proxy = function(fn, context) {
|
|
var args = (2 in arguments) && slice.call(arguments, 2)
|
|
if (isFunction(fn)) {
|
|
var proxyFn = function(){ return fn.apply(context, args ? args.concat(slice.call(arguments)) : arguments) }
|
|
proxyFn._zid = zid(fn)
|
|
return proxyFn
|
|
} else if (isString(context)) {
|
|
if (args) {
|
|
args.unshift(fn[context], fn)
|
|
return $.proxy.apply(null, args)
|
|
} else {
|
|
return $.proxy(fn[context], fn)
|
|
}
|
|
} else {
|
|
throw new TypeError("expected function")
|
|
}
|
|
}
|
|
|
|
$.fn.bind = function(event, data, callback){
|
|
return this.on(event, data, callback)
|
|
}
|
|
$.fn.unbind = function(event, callback){
|
|
return this.off(event, callback)
|
|
}
|
|
$.fn.one = function(event, selector, data, callback){
|
|
return this.on(event, selector, data, callback, 1)
|
|
}
|
|
|
|
var returnTrue = function(){return true},
|
|
returnFalse = function(){return false},
|
|
ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/,
|
|
eventMethods = {
|
|
preventDefault: 'isDefaultPrevented',
|
|
stopImmediatePropagation: 'isImmediatePropagationStopped',
|
|
stopPropagation: 'isPropagationStopped'
|
|
}
|
|
|
|
function compatible(event, source) {
|
|
if (source || !event.isDefaultPrevented) {
|
|
source || (source = event)
|
|
|
|
$.each(eventMethods, function(name, predicate) {
|
|
var sourceMethod = source[name]
|
|
event[name] = function(){
|
|
this[predicate] = returnTrue
|
|
return sourceMethod && sourceMethod.apply(source, arguments)
|
|
}
|
|
event[predicate] = returnFalse
|
|
})
|
|
|
|
try {
|
|
event.timeStamp || (event.timeStamp = Date.now())
|
|
} catch (ignored) { }
|
|
|
|
if (source.defaultPrevented !== undefined ? source.defaultPrevented :
|
|
'returnValue' in source ? source.returnValue === false :
|
|
source.getPreventDefault && source.getPreventDefault())
|
|
event.isDefaultPrevented = returnTrue
|
|
}
|
|
return event
|
|
}
|
|
|
|
function createProxy(event) {
|
|
var key, proxy = { originalEvent: event }
|
|
for (key in event)
|
|
if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key]
|
|
|
|
return compatible(proxy, event)
|
|
}
|
|
|
|
$.fn.delegate = function(selector, event, callback){
|
|
return this.on(event, selector, callback)
|
|
}
|
|
$.fn.undelegate = function(selector, event, callback){
|
|
return this.off(event, selector, callback)
|
|
}
|
|
|
|
$.fn.live = function(event, callback){
|
|
$(document.body).delegate(this.selector, event, callback)
|
|
return this
|
|
}
|
|
$.fn.die = function(event, callback){
|
|
$(document.body).undelegate(this.selector, event, callback)
|
|
return this
|
|
}
|
|
|
|
$.fn.on = function(event, selector, data, callback, one){
|
|
var autoRemove, delegator, $this = this
|
|
if (event && !isString(event)) {
|
|
$.each(event, function(type, fn){
|
|
$this.on(type, selector, data, fn, one)
|
|
})
|
|
return $this
|
|
}
|
|
|
|
if (!isString(selector) && !isFunction(callback) && callback !== false)
|
|
callback = data, data = selector, selector = undefined
|
|
if (callback === undefined || data === false)
|
|
callback = data, data = undefined
|
|
|
|
if (callback === false) callback = returnFalse
|
|
|
|
return $this.each(function(_, element){
|
|
if (one) autoRemove = function(e){
|
|
remove(element, e.type, callback)
|
|
return callback.apply(this, arguments)
|
|
}
|
|
|
|
if (selector) delegator = function(e){
|
|
var evt, match = $(e.target).closest(selector, element).get(0)
|
|
if (match && match !== element) {
|
|
evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element})
|
|
return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1)))
|
|
}
|
|
}
|
|
|
|
add(element, event, callback, data, selector, delegator || autoRemove)
|
|
})
|
|
}
|
|
$.fn.off = function(event, selector, callback){
|
|
var $this = this
|
|
if (event && !isString(event)) {
|
|
$.each(event, function(type, fn){
|
|
$this.off(type, selector, fn)
|
|
})
|
|
return $this
|
|
}
|
|
|
|
if (!isString(selector) && !isFunction(callback) && callback !== false)
|
|
callback = selector, selector = undefined
|
|
|
|
if (callback === false) callback = returnFalse
|
|
|
|
return $this.each(function(){
|
|
remove(this, event, callback, selector)
|
|
})
|
|
}
|
|
|
|
$.fn.trigger = function(event, args){
|
|
event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event)
|
|
event._args = args
|
|
return this.each(function(){
|
|
// handle focus(), blur() by calling them directly
|
|
if (event.type in focus && typeof this[event.type] == "function") this[event.type]()
|
|
// items in the collection might not be DOM elements
|
|
else if ('dispatchEvent' in this) this.dispatchEvent(event)
|
|
else $(this).triggerHandler(event, args)
|
|
})
|
|
}
|
|
|
|
// triggers event handlers on current element just as if an event occurred,
|
|
// doesn't trigger an actual event, doesn't bubble
|
|
$.fn.triggerHandler = function(event, args){
|
|
var e, result
|
|
this.each(function(i, element){
|
|
e = createProxy(isString(event) ? $.Event(event) : event)
|
|
e._args = args
|
|
e.target = element
|
|
$.each(findHandlers(element, event.type || event), function(i, handler){
|
|
result = handler.proxy(e)
|
|
if (e.isImmediatePropagationStopped()) return false
|
|
})
|
|
})
|
|
return result
|
|
}
|
|
|
|
// shortcut methods for `.bind(event, fn)` for each event type
|
|
;('focusin focusout focus blur load resize scroll unload click dblclick '+
|
|
'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+
|
|
'change select keydown keypress keyup error').split(' ').forEach(function(event) {
|
|
$.fn[event] = function(callback) {
|
|
return (0 in arguments) ?
|
|
this.bind(event, callback) :
|
|
this.trigger(event)
|
|
}
|
|
})
|
|
|
|
$.Event = function(type, props) {
|
|
if (!isString(type)) props = type, type = props.type
|
|
var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true
|
|
if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name])
|
|
event.initEvent(type, bubbles, true)
|
|
return compatible(event)
|
|
}
|
|
|
|
})(Zepto)
|
|
|
|
;(function($){
|
|
var cache = [], timeout
|
|
|
|
$.fn.remove = function(){
|
|
return this.each(function(){
|
|
if(this.parentNode){
|
|
if(this.tagName === 'IMG'){
|
|
cache.push(this)
|
|
this.src = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs='
|
|
if (timeout) clearTimeout(timeout)
|
|
timeout = setTimeout(function(){ cache = [] }, 60000)
|
|
}
|
|
this.parentNode.removeChild(this)
|
|
}
|
|
})
|
|
}
|
|
})(Zepto)
|
|
|
|
;(function($){
|
|
var data = {}, dataAttr = $.fn.data, camelize = $.camelCase,
|
|
exp = $.expando = 'Zepto' + (+new Date()), emptyArray = []
|
|
|
|
// Get value from node:
|
|
// 1. first try key as given,
|
|
// 2. then try camelized key,
|
|
// 3. fall back to reading "data-*" attribute.
|
|
function getData(node, name) {
|
|
var id = node[exp], store = id && data[id]
|
|
if (name === undefined) return store || setData(node)
|
|
else {
|
|
if (store) {
|
|
if (name in store) return store[name]
|
|
var camelName = camelize(name)
|
|
if (camelName in store) return store[camelName]
|
|
}
|
|
return dataAttr.call($(node), name)
|
|
}
|
|
}
|
|
|
|
// Store value under camelized key on node
|
|
function setData(node, name, value) {
|
|
var id = node[exp] || (node[exp] = ++$.uuid),
|
|
store = data[id] || (data[id] = attributeData(node))
|
|
if (name !== undefined) store[camelize(name)] = value
|
|
return store
|
|
}
|
|
|
|
// Read all "data-*" attributes from a node
|
|
function attributeData(node) {
|
|
var store = {}
|
|
$.each(node.attributes || emptyArray, function(i, attr){
|
|
if (attr.name.indexOf('data-') == 0)
|
|
store[camelize(attr.name.replace('data-', ''))] =
|
|
$.zepto.deserializeValue(attr.value)
|
|
})
|
|
return store
|
|
}
|
|
|
|
$.fn.data = function(name, value) {
|
|
return value === undefined ?
|
|
// set multiple values via object
|
|
$.isPlainObject(name) ?
|
|
this.each(function(i, node){
|
|
$.each(name, function(key, value){ setData(node, key, value) })
|
|
}) :
|
|
// get value from first element
|
|
(0 in this ? getData(this[0], name) : undefined) :
|
|
// set value on all elements
|
|
this.each(function(){ setData(this, name, value) })
|
|
}
|
|
|
|
$.data = function(elem, name, value) {
|
|
return $(elem).data(name, value)
|
|
}
|
|
|
|
$.hasData = function(elem) {
|
|
var id = elem[exp], store = id && data[id]
|
|
return store ? !$.isEmptyObject(store) : false
|
|
}
|
|
|
|
$.fn.removeData = function(names) {
|
|
if (typeof names == 'string') names = names.split(/\s+/)
|
|
return this.each(function(){
|
|
var id = this[exp], store = id && data[id]
|
|
if (store) $.each(names || store, function(key){
|
|
delete store[names ? camelize(this) : key]
|
|
})
|
|
})
|
|
}
|
|
|
|
// Generate extended `remove` and `empty` functions
|
|
;['remove', 'empty'].forEach(function(methodName){
|
|
var origFn = $.fn[methodName]
|
|
$.fn[methodName] = function() {
|
|
var elements = this.find('*')
|
|
if (methodName === 'remove') elements = elements.add(this)
|
|
elements.removeData()
|
|
return origFn.call(this)
|
|
}
|
|
})
|
|
})(Zepto)
|
|
return Zepto
|
|
}))
|
|
|
|
|
|
/***/ }),
|
|
/* 56 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var attrsKey = 'aaAttrs';
|
|
|
|
var _ = __webpack_require__(0);
|
|
var DOM = __webpack_require__(2);
|
|
var EventBus = __webpack_require__(26);
|
|
var Input = __webpack_require__(57);
|
|
var Dropdown = __webpack_require__(64);
|
|
var html = __webpack_require__(27);
|
|
var css = __webpack_require__(17);
|
|
|
|
// constructor
|
|
// -----------
|
|
|
|
// THOUGHT: what if datasets could dynamically be added/removed?
|
|
function Typeahead(o) {
|
|
var $menu;
|
|
var $hint;
|
|
|
|
o = o || {};
|
|
|
|
if (!o.input) {
|
|
_.error('missing input');
|
|
}
|
|
|
|
this.isActivated = false;
|
|
this.debug = !!o.debug;
|
|
this.autoselect = !!o.autoselect;
|
|
this.autoselectOnBlur = !!o.autoselectOnBlur;
|
|
this.openOnFocus = !!o.openOnFocus;
|
|
this.minLength = _.isNumber(o.minLength) ? o.minLength : 1;
|
|
this.autoWidth = (o.autoWidth === undefined) ? true : !!o.autoWidth;
|
|
this.clearOnSelected = !!o.clearOnSelected;
|
|
this.tabAutocomplete = (o.tabAutocomplete === undefined) ? true : !!o.tabAutocomplete;
|
|
|
|
o.hint = !!o.hint;
|
|
|
|
if (o.hint && o.appendTo) {
|
|
throw new Error('[autocomplete.js] hint and appendTo options can\'t be used at the same time');
|
|
}
|
|
|
|
this.css = o.css = _.mixin({}, css, o.appendTo ? css.appendTo : {});
|
|
this.cssClasses = o.cssClasses = _.mixin({}, css.defaultClasses, o.cssClasses || {});
|
|
this.cssClasses.prefix =
|
|
o.cssClasses.formattedPrefix = _.formatPrefix(this.cssClasses.prefix, this.cssClasses.noPrefix);
|
|
this.listboxId = o.listboxId = [this.cssClasses.root, 'listbox', _.getUniqueId()].join('-');
|
|
|
|
var domElts = buildDom(o);
|
|
|
|
this.$node = domElts.wrapper;
|
|
var $input = this.$input = domElts.input;
|
|
$menu = domElts.menu;
|
|
$hint = domElts.hint;
|
|
|
|
if (o.dropdownMenuContainer) {
|
|
DOM.element(o.dropdownMenuContainer)
|
|
.css('position', 'relative') // ensure the container has a relative position
|
|
.append($menu.css('top', '0')); // override the top: 100%
|
|
}
|
|
|
|
// #705: if there's scrollable overflow, ie doesn't support
|
|
// blur cancellations when the scrollbar is clicked
|
|
//
|
|
// #351: preventDefault won't cancel blurs in ie <= 8
|
|
$input.on('blur.aa', function($e) {
|
|
var active = document.activeElement;
|
|
if (_.isMsie() && ($menu[0] === active || $menu[0].contains(active))) {
|
|
$e.preventDefault();
|
|
// stop immediate in order to prevent Input#_onBlur from
|
|
// getting exectued
|
|
$e.stopImmediatePropagation();
|
|
_.defer(function() { $input.focus(); });
|
|
}
|
|
});
|
|
|
|
// #351: prevents input blur due to clicks within dropdown menu
|
|
$menu.on('mousedown.aa', function($e) { $e.preventDefault(); });
|
|
|
|
this.eventBus = o.eventBus || new EventBus({el: $input});
|
|
|
|
this.dropdown = new Typeahead.Dropdown({
|
|
appendTo: o.appendTo,
|
|
wrapper: this.$node,
|
|
menu: $menu,
|
|
datasets: o.datasets,
|
|
templates: o.templates,
|
|
cssClasses: o.cssClasses,
|
|
minLength: this.minLength
|
|
})
|
|
.onSync('suggestionClicked', this._onSuggestionClicked, this)
|
|
.onSync('cursorMoved', this._onCursorMoved, this)
|
|
.onSync('cursorRemoved', this._onCursorRemoved, this)
|
|
.onSync('opened', this._onOpened, this)
|
|
.onSync('closed', this._onClosed, this)
|
|
.onSync('shown', this._onShown, this)
|
|
.onSync('empty', this._onEmpty, this)
|
|
.onSync('redrawn', this._onRedrawn, this)
|
|
.onAsync('datasetRendered', this._onDatasetRendered, this);
|
|
|
|
this.input = new Typeahead.Input({input: $input, hint: $hint})
|
|
.onSync('focused', this._onFocused, this)
|
|
.onSync('blurred', this._onBlurred, this)
|
|
.onSync('enterKeyed', this._onEnterKeyed, this)
|
|
.onSync('tabKeyed', this._onTabKeyed, this)
|
|
.onSync('escKeyed', this._onEscKeyed, this)
|
|
.onSync('upKeyed', this._onUpKeyed, this)
|
|
.onSync('downKeyed', this._onDownKeyed, this)
|
|
.onSync('leftKeyed', this._onLeftKeyed, this)
|
|
.onSync('rightKeyed', this._onRightKeyed, this)
|
|
.onSync('queryChanged', this._onQueryChanged, this)
|
|
.onSync('whitespaceChanged', this._onWhitespaceChanged, this);
|
|
|
|
this._bindKeyboardShortcuts(o);
|
|
|
|
this._setLanguageDirection();
|
|
}
|
|
|
|
// instance methods
|
|
// ----------------
|
|
|
|
_.mixin(Typeahead.prototype, {
|
|
// ### private
|
|
|
|
_bindKeyboardShortcuts: function(options) {
|
|
if (!options.keyboardShortcuts) {
|
|
return;
|
|
}
|
|
var $input = this.$input;
|
|
var keyboardShortcuts = [];
|
|
_.each(options.keyboardShortcuts, function(key) {
|
|
if (typeof key === 'string') {
|
|
key = key.toUpperCase().charCodeAt(0);
|
|
}
|
|
keyboardShortcuts.push(key);
|
|
});
|
|
DOM.element(document).keydown(function(event) {
|
|
var elt = (event.target || event.srcElement);
|
|
var tagName = elt.tagName;
|
|
if (elt.isContentEditable || tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA') {
|
|
// already in an input
|
|
return;
|
|
}
|
|
|
|
var which = event.which || event.keyCode;
|
|
if (keyboardShortcuts.indexOf(which) === -1) {
|
|
// not the right shortcut
|
|
return;
|
|
}
|
|
|
|
$input.focus();
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
});
|
|
},
|
|
|
|
_onSuggestionClicked: function onSuggestionClicked(type, $el) {
|
|
var datum;
|
|
var context = {selectionMethod: 'click'};
|
|
|
|
if (datum = this.dropdown.getDatumForSuggestion($el)) {
|
|
this._select(datum, context);
|
|
}
|
|
},
|
|
|
|
_onCursorMoved: function onCursorMoved(event, updateInput) {
|
|
var datum = this.dropdown.getDatumForCursor();
|
|
var currentCursorId = this.dropdown.getCurrentCursor().attr('id');
|
|
this.input.setActiveDescendant(currentCursorId);
|
|
|
|
if (datum) {
|
|
if (updateInput) {
|
|
this.input.setInputValue(datum.value, true);
|
|
}
|
|
|
|
this.eventBus.trigger('cursorchanged', datum.raw, datum.datasetName);
|
|
}
|
|
},
|
|
|
|
_onCursorRemoved: function onCursorRemoved() {
|
|
this.input.resetInputValue();
|
|
this._updateHint();
|
|
this.eventBus.trigger('cursorremoved');
|
|
},
|
|
|
|
_onDatasetRendered: function onDatasetRendered() {
|
|
this._updateHint();
|
|
|
|
this.eventBus.trigger('updated');
|
|
},
|
|
|
|
_onOpened: function onOpened() {
|
|
this._updateHint();
|
|
this.input.expand();
|
|
|
|
this.eventBus.trigger('opened');
|
|
},
|
|
|
|
_onEmpty: function onEmpty() {
|
|
this.eventBus.trigger('empty');
|
|
},
|
|
|
|
_onRedrawn: function onRedrawn() {
|
|
this.$node.css('top', 0 + 'px');
|
|
this.$node.css('left', 0 + 'px');
|
|
|
|
var inputRect = this.$input[0].getBoundingClientRect();
|
|
|
|
if (this.autoWidth) {
|
|
this.$node.css('width', inputRect.width + 'px');
|
|
}
|
|
|
|
var wrapperRect = this.$node[0].getBoundingClientRect();
|
|
|
|
var top = inputRect.bottom - wrapperRect.top;
|
|
this.$node.css('top', top + 'px');
|
|
var left = inputRect.left - wrapperRect.left;
|
|
this.$node.css('left', left + 'px');
|
|
|
|
this.eventBus.trigger('redrawn');
|
|
},
|
|
|
|
_onShown: function onShown() {
|
|
this.eventBus.trigger('shown');
|
|
if (this.autoselect) {
|
|
this.dropdown.cursorTopSuggestion();
|
|
}
|
|
},
|
|
|
|
_onClosed: function onClosed() {
|
|
this.input.clearHint();
|
|
this.input.removeActiveDescendant();
|
|
this.input.collapse();
|
|
|
|
this.eventBus.trigger('closed');
|
|
},
|
|
|
|
_onFocused: function onFocused() {
|
|
this.isActivated = true;
|
|
|
|
if (this.openOnFocus) {
|
|
var query = this.input.getQuery();
|
|
if (query.length >= this.minLength) {
|
|
this.dropdown.update(query);
|
|
} else {
|
|
this.dropdown.empty();
|
|
}
|
|
|
|
this.dropdown.open();
|
|
}
|
|
},
|
|
|
|
_onBlurred: function onBlurred() {
|
|
var cursorDatum;
|
|
var topSuggestionDatum;
|
|
|
|
cursorDatum = this.dropdown.getDatumForCursor();
|
|
topSuggestionDatum = this.dropdown.getDatumForTopSuggestion();
|
|
var context = {selectionMethod: 'blur'};
|
|
|
|
if (!this.debug) {
|
|
if (this.autoselectOnBlur && cursorDatum) {
|
|
this._select(cursorDatum, context);
|
|
} else if (this.autoselectOnBlur && topSuggestionDatum) {
|
|
this._select(topSuggestionDatum, context);
|
|
} else {
|
|
this.isActivated = false;
|
|
this.dropdown.empty();
|
|
this.dropdown.close();
|
|
}
|
|
}
|
|
},
|
|
|
|
_onEnterKeyed: function onEnterKeyed(type, $e) {
|
|
var cursorDatum;
|
|
var topSuggestionDatum;
|
|
|
|
cursorDatum = this.dropdown.getDatumForCursor();
|
|
topSuggestionDatum = this.dropdown.getDatumForTopSuggestion();
|
|
var context = {selectionMethod: 'enterKey'};
|
|
|
|
if (cursorDatum) {
|
|
this._select(cursorDatum, context);
|
|
$e.preventDefault();
|
|
} else if (this.autoselect && topSuggestionDatum) {
|
|
this._select(topSuggestionDatum, context);
|
|
$e.preventDefault();
|
|
}
|
|
},
|
|
|
|
_onTabKeyed: function onTabKeyed(type, $e) {
|
|
if (!this.tabAutocomplete) {
|
|
// Closing the dropdown enables further tabbing
|
|
this.dropdown.close();
|
|
return;
|
|
}
|
|
|
|
var datum;
|
|
var context = {selectionMethod: 'tabKey'};
|
|
|
|
if (datum = this.dropdown.getDatumForCursor()) {
|
|
this._select(datum, context);
|
|
$e.preventDefault();
|
|
} else {
|
|
this._autocomplete(true);
|
|
}
|
|
},
|
|
|
|
_onEscKeyed: function onEscKeyed() {
|
|
this.dropdown.close();
|
|
this.input.resetInputValue();
|
|
},
|
|
|
|
_onUpKeyed: function onUpKeyed() {
|
|
var query = this.input.getQuery();
|
|
|
|
if (this.dropdown.isEmpty && query.length >= this.minLength) {
|
|
this.dropdown.update(query);
|
|
} else {
|
|
this.dropdown.moveCursorUp();
|
|
}
|
|
|
|
this.dropdown.open();
|
|
},
|
|
|
|
_onDownKeyed: function onDownKeyed() {
|
|
var query = this.input.getQuery();
|
|
|
|
if (this.dropdown.isEmpty && query.length >= this.minLength) {
|
|
this.dropdown.update(query);
|
|
} else {
|
|
this.dropdown.moveCursorDown();
|
|
}
|
|
|
|
this.dropdown.open();
|
|
},
|
|
|
|
_onLeftKeyed: function onLeftKeyed() {
|
|
if (this.dir === 'rtl') {
|
|
this._autocomplete();
|
|
}
|
|
},
|
|
|
|
_onRightKeyed: function onRightKeyed() {
|
|
if (this.dir === 'ltr') {
|
|
this._autocomplete();
|
|
}
|
|
},
|
|
|
|
_onQueryChanged: function onQueryChanged(e, query) {
|
|
this.input.clearHintIfInvalid();
|
|
|
|
if (query.length >= this.minLength) {
|
|
this.dropdown.update(query);
|
|
} else {
|
|
this.dropdown.empty();
|
|
}
|
|
|
|
this.dropdown.open();
|
|
this._setLanguageDirection();
|
|
},
|
|
|
|
_onWhitespaceChanged: function onWhitespaceChanged() {
|
|
this._updateHint();
|
|
this.dropdown.open();
|
|
},
|
|
|
|
_setLanguageDirection: function setLanguageDirection() {
|
|
var dir = this.input.getLanguageDirection();
|
|
|
|
if (this.dir !== dir) {
|
|
this.dir = dir;
|
|
this.$node.css('direction', dir);
|
|
this.dropdown.setLanguageDirection(dir);
|
|
}
|
|
},
|
|
|
|
_updateHint: function updateHint() {
|
|
var datum;
|
|
var val;
|
|
var query;
|
|
var escapedQuery;
|
|
var frontMatchRegEx;
|
|
var match;
|
|
|
|
datum = this.dropdown.getDatumForTopSuggestion();
|
|
|
|
if (datum && this.dropdown.isVisible() && !this.input.hasOverflow()) {
|
|
val = this.input.getInputValue();
|
|
query = Input.normalizeQuery(val);
|
|
escapedQuery = _.escapeRegExChars(query);
|
|
|
|
// match input value, then capture trailing text
|
|
frontMatchRegEx = new RegExp('^(?:' + escapedQuery + ')(.+$)', 'i');
|
|
match = frontMatchRegEx.exec(datum.value);
|
|
|
|
// clear hint if there's no trailing text
|
|
if (match) {
|
|
this.input.setHint(val + match[1]);
|
|
} else {
|
|
this.input.clearHint();
|
|
}
|
|
} else {
|
|
this.input.clearHint();
|
|
}
|
|
},
|
|
|
|
_autocomplete: function autocomplete(laxCursor) {
|
|
var hint;
|
|
var query;
|
|
var isCursorAtEnd;
|
|
var datum;
|
|
|
|
hint = this.input.getHint();
|
|
query = this.input.getQuery();
|
|
isCursorAtEnd = laxCursor || this.input.isCursorAtEnd();
|
|
|
|
if (hint && query !== hint && isCursorAtEnd) {
|
|
datum = this.dropdown.getDatumForTopSuggestion();
|
|
if (datum) {
|
|
this.input.setInputValue(datum.value);
|
|
}
|
|
|
|
this.eventBus.trigger('autocompleted', datum.raw, datum.datasetName);
|
|
}
|
|
},
|
|
|
|
_select: function select(datum, context) {
|
|
if (typeof datum.value !== 'undefined') {
|
|
this.input.setQuery(datum.value);
|
|
}
|
|
if (this.clearOnSelected) {
|
|
this.setVal('');
|
|
} else {
|
|
this.input.setInputValue(datum.value, true);
|
|
}
|
|
|
|
this._setLanguageDirection();
|
|
|
|
var event = this.eventBus.trigger('selected', datum.raw, datum.datasetName, context);
|
|
if (event.isDefaultPrevented() === false) {
|
|
this.dropdown.close();
|
|
|
|
// #118: allow click event to bubble up to the body before removing
|
|
// the suggestions otherwise we break event delegation
|
|
_.defer(_.bind(this.dropdown.empty, this.dropdown));
|
|
}
|
|
},
|
|
|
|
// ### public
|
|
|
|
open: function open() {
|
|
// if the menu is not activated yet, we need to update
|
|
// the underlying dropdown menu to trigger the search
|
|
// otherwise we're not gonna see anything
|
|
if (!this.isActivated) {
|
|
var query = this.input.getInputValue();
|
|
if (query.length >= this.minLength) {
|
|
this.dropdown.update(query);
|
|
} else {
|
|
this.dropdown.empty();
|
|
}
|
|
}
|
|
this.dropdown.open();
|
|
},
|
|
|
|
close: function close() {
|
|
this.dropdown.close();
|
|
},
|
|
|
|
setVal: function setVal(val) {
|
|
// expect val to be a string, so be safe, and coerce
|
|
val = _.toStr(val);
|
|
|
|
if (this.isActivated) {
|
|
this.input.setInputValue(val);
|
|
} else {
|
|
this.input.setQuery(val);
|
|
this.input.setInputValue(val, true);
|
|
}
|
|
|
|
this._setLanguageDirection();
|
|
},
|
|
|
|
getVal: function getVal() {
|
|
return this.input.getQuery();
|
|
},
|
|
|
|
destroy: function destroy() {
|
|
this.input.destroy();
|
|
this.dropdown.destroy();
|
|
|
|
destroyDomStructure(this.$node, this.cssClasses);
|
|
|
|
this.$node = null;
|
|
},
|
|
|
|
getWrapper: function getWrapper() {
|
|
return this.dropdown.$container[0];
|
|
}
|
|
});
|
|
|
|
function buildDom(options) {
|
|
var $input;
|
|
var $wrapper;
|
|
var $dropdown;
|
|
var $hint;
|
|
|
|
$input = DOM.element(options.input);
|
|
$wrapper = DOM
|
|
.element(html.wrapper.replace('%ROOT%', options.cssClasses.root))
|
|
.css(options.css.wrapper);
|
|
|
|
// override the display property with the table-cell value
|
|
// if the parent element is a table and the original input was a block
|
|
// -> https://github.com/algolia/autocomplete.js/issues/16
|
|
if (!options.appendTo && $input.css('display') === 'block' && $input.parent().css('display') === 'table') {
|
|
$wrapper.css('display', 'table-cell');
|
|
}
|
|
var dropdownHtml = html.dropdown.
|
|
replace('%PREFIX%', options.cssClasses.prefix).
|
|
replace('%DROPDOWN_MENU%', options.cssClasses.dropdownMenu);
|
|
$dropdown = DOM.element(dropdownHtml)
|
|
.css(options.css.dropdown)
|
|
.attr({
|
|
role: 'listbox',
|
|
id: options.listboxId
|
|
});
|
|
if (options.templates && options.templates.dropdownMenu) {
|
|
$dropdown.html(_.templatify(options.templates.dropdownMenu)());
|
|
}
|
|
$hint = $input.clone().css(options.css.hint).css(getBackgroundStyles($input));
|
|
|
|
$hint
|
|
.val('')
|
|
.addClass(_.className(options.cssClasses.prefix, options.cssClasses.hint, true))
|
|
.removeAttr('id name placeholder required')
|
|
.prop('readonly', true)
|
|
.attr({
|
|
'aria-hidden': 'true',
|
|
autocomplete: 'off',
|
|
spellcheck: 'false',
|
|
tabindex: -1
|
|
});
|
|
if ($hint.removeData) {
|
|
$hint.removeData();
|
|
}
|
|
|
|
// store the original values of the attrs that get modified
|
|
// so modifications can be reverted on destroy
|
|
$input.data(attrsKey, {
|
|
'aria-autocomplete': $input.attr('aria-autocomplete'),
|
|
'aria-expanded': $input.attr('aria-expanded'),
|
|
'aria-owns': $input.attr('aria-owns'),
|
|
autocomplete: $input.attr('autocomplete'),
|
|
dir: $input.attr('dir'),
|
|
role: $input.attr('role'),
|
|
spellcheck: $input.attr('spellcheck'),
|
|
style: $input.attr('style'),
|
|
type: $input.attr('type')
|
|
});
|
|
|
|
$input
|
|
.addClass(_.className(options.cssClasses.prefix, options.cssClasses.input, true))
|
|
.attr({
|
|
autocomplete: 'off',
|
|
spellcheck: false,
|
|
|
|
// Accessibility features
|
|
// Give the field a presentation of a "select".
|
|
// Combobox is the combined presentation of a single line textfield
|
|
// with a listbox popup.
|
|
// https://www.w3.org/WAI/PF/aria/roles#combobox
|
|
role: 'combobox',
|
|
// Let the screen reader know the field has an autocomplete
|
|
// feature to it.
|
|
'aria-autocomplete': (options.datasets &&
|
|
options.datasets[0] && options.datasets[0].displayKey ? 'both' : 'list'),
|
|
// Indicates whether the dropdown it controls is currently expanded or collapsed
|
|
'aria-expanded': 'false',
|
|
'aria-label': options.ariaLabel,
|
|
// Explicitly point to the listbox,
|
|
// which is a list of suggestions (aka options)
|
|
'aria-owns': options.listboxId
|
|
})
|
|
.css(options.hint ? options.css.input : options.css.inputWithNoHint);
|
|
|
|
// ie7 does not like it when dir is set to auto
|
|
try {
|
|
if (!$input.attr('dir')) {
|
|
$input.attr('dir', 'auto');
|
|
}
|
|
} catch (e) {
|
|
// ignore
|
|
}
|
|
|
|
$wrapper = options.appendTo
|
|
? $wrapper.appendTo(DOM.element(options.appendTo).eq(0)).eq(0)
|
|
: $input.wrap($wrapper).parent();
|
|
|
|
$wrapper
|
|
.prepend(options.hint ? $hint : null)
|
|
.append($dropdown);
|
|
|
|
return {
|
|
wrapper: $wrapper,
|
|
input: $input,
|
|
hint: $hint,
|
|
menu: $dropdown
|
|
};
|
|
}
|
|
|
|
function getBackgroundStyles($el) {
|
|
return {
|
|
backgroundAttachment: $el.css('background-attachment'),
|
|
backgroundClip: $el.css('background-clip'),
|
|
backgroundColor: $el.css('background-color'),
|
|
backgroundImage: $el.css('background-image'),
|
|
backgroundOrigin: $el.css('background-origin'),
|
|
backgroundPosition: $el.css('background-position'),
|
|
backgroundRepeat: $el.css('background-repeat'),
|
|
backgroundSize: $el.css('background-size')
|
|
};
|
|
}
|
|
|
|
function destroyDomStructure($node, cssClasses) {
|
|
var $input = $node.find(_.className(cssClasses.prefix, cssClasses.input));
|
|
|
|
// need to remove attrs that weren't previously defined and
|
|
// revert attrs that originally had a value
|
|
_.each($input.data(attrsKey), function(val, key) {
|
|
if (val === undefined) {
|
|
$input.removeAttr(key);
|
|
} else {
|
|
$input.attr(key, val);
|
|
}
|
|
});
|
|
|
|
$input
|
|
.detach()
|
|
.removeClass(_.className(cssClasses.prefix, cssClasses.input, true))
|
|
.insertAfter($node);
|
|
if ($input.removeData) {
|
|
$input.removeData(attrsKey);
|
|
}
|
|
|
|
$node.remove();
|
|
}
|
|
|
|
Typeahead.Dropdown = Dropdown;
|
|
Typeahead.Input = Input;
|
|
Typeahead.sources = __webpack_require__(66);
|
|
|
|
module.exports = Typeahead;
|
|
|
|
|
|
/***/ }),
|
|
/* 57 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var specialKeyCodeMap;
|
|
|
|
specialKeyCodeMap = {
|
|
9: 'tab',
|
|
27: 'esc',
|
|
37: 'left',
|
|
39: 'right',
|
|
13: 'enter',
|
|
38: 'up',
|
|
40: 'down'
|
|
};
|
|
|
|
var _ = __webpack_require__(0);
|
|
var DOM = __webpack_require__(2);
|
|
var EventEmitter = __webpack_require__(16);
|
|
|
|
// constructor
|
|
// -----------
|
|
|
|
function Input(o) {
|
|
var that = this;
|
|
var onBlur;
|
|
var onFocus;
|
|
var onKeydown;
|
|
var onInput;
|
|
|
|
o = o || {};
|
|
|
|
if (!o.input) {
|
|
_.error('input is missing');
|
|
}
|
|
|
|
// bound functions
|
|
onBlur = _.bind(this._onBlur, this);
|
|
onFocus = _.bind(this._onFocus, this);
|
|
onKeydown = _.bind(this._onKeydown, this);
|
|
onInput = _.bind(this._onInput, this);
|
|
|
|
this.$hint = DOM.element(o.hint);
|
|
this.$input = DOM.element(o.input)
|
|
.on('blur.aa', onBlur)
|
|
.on('focus.aa', onFocus)
|
|
.on('keydown.aa', onKeydown);
|
|
|
|
// if no hint, noop all the hint related functions
|
|
if (this.$hint.length === 0) {
|
|
this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop;
|
|
}
|
|
|
|
// ie7 and ie8 don't support the input event
|
|
// ie9 doesn't fire the input event when characters are removed
|
|
// not sure if ie10 is compatible
|
|
if (!_.isMsie()) {
|
|
this.$input.on('input.aa', onInput);
|
|
} else {
|
|
this.$input.on('keydown.aa keypress.aa cut.aa paste.aa', function($e) {
|
|
// if a special key triggered this, ignore it
|
|
if (specialKeyCodeMap[$e.which || $e.keyCode]) {
|
|
return;
|
|
}
|
|
|
|
// give the browser a chance to update the value of the input
|
|
// before checking to see if the query changed
|
|
_.defer(_.bind(that._onInput, that, $e));
|
|
});
|
|
}
|
|
|
|
// the query defaults to whatever the value of the input is
|
|
// on initialization, it'll most likely be an empty string
|
|
this.query = this.$input.val();
|
|
|
|
// helps with calculating the width of the input's value
|
|
this.$overflowHelper = buildOverflowHelper(this.$input);
|
|
}
|
|
|
|
// static methods
|
|
// --------------
|
|
|
|
Input.normalizeQuery = function(str) {
|
|
// strips leading whitespace and condenses all whitespace
|
|
return (str || '').replace(/^\s*/g, '').replace(/\s{2,}/g, ' ');
|
|
};
|
|
|
|
// instance methods
|
|
// ----------------
|
|
|
|
_.mixin(Input.prototype, EventEmitter, {
|
|
|
|
// ### private
|
|
|
|
_onBlur: function onBlur() {
|
|
this.resetInputValue();
|
|
this.$input.removeAttr('aria-activedescendant');
|
|
this.trigger('blurred');
|
|
},
|
|
|
|
_onFocus: function onFocus() {
|
|
this.trigger('focused');
|
|
},
|
|
|
|
_onKeydown: function onKeydown($e) {
|
|
// which is normalized and consistent (but not for ie)
|
|
var keyName = specialKeyCodeMap[$e.which || $e.keyCode];
|
|
|
|
this._managePreventDefault(keyName, $e);
|
|
if (keyName && this._shouldTrigger(keyName, $e)) {
|
|
this.trigger(keyName + 'Keyed', $e);
|
|
}
|
|
},
|
|
|
|
_onInput: function onInput() {
|
|
this._checkInputValue();
|
|
},
|
|
|
|
_managePreventDefault: function managePreventDefault(keyName, $e) {
|
|
var preventDefault;
|
|
var hintValue;
|
|
var inputValue;
|
|
|
|
switch (keyName) {
|
|
case 'tab':
|
|
hintValue = this.getHint();
|
|
inputValue = this.getInputValue();
|
|
|
|
preventDefault = hintValue &&
|
|
hintValue !== inputValue &&
|
|
!withModifier($e);
|
|
break;
|
|
|
|
case 'up':
|
|
case 'down':
|
|
preventDefault = !withModifier($e);
|
|
break;
|
|
|
|
default:
|
|
preventDefault = false;
|
|
}
|
|
|
|
if (preventDefault) {
|
|
$e.preventDefault();
|
|
}
|
|
},
|
|
|
|
_shouldTrigger: function shouldTrigger(keyName, $e) {
|
|
var trigger;
|
|
|
|
switch (keyName) {
|
|
case 'tab':
|
|
trigger = !withModifier($e);
|
|
break;
|
|
|
|
default:
|
|
trigger = true;
|
|
}
|
|
|
|
return trigger;
|
|
},
|
|
|
|
_checkInputValue: function checkInputValue() {
|
|
var inputValue;
|
|
var areEquivalent;
|
|
var hasDifferentWhitespace;
|
|
|
|
inputValue = this.getInputValue();
|
|
areEquivalent = areQueriesEquivalent(inputValue, this.query);
|
|
hasDifferentWhitespace = areEquivalent && this.query ?
|
|
this.query.length !== inputValue.length : false;
|
|
|
|
this.query = inputValue;
|
|
|
|
if (!areEquivalent) {
|
|
this.trigger('queryChanged', this.query);
|
|
} else if (hasDifferentWhitespace) {
|
|
this.trigger('whitespaceChanged', this.query);
|
|
}
|
|
},
|
|
|
|
// ### public
|
|
|
|
focus: function focus() {
|
|
this.$input.focus();
|
|
},
|
|
|
|
blur: function blur() {
|
|
this.$input.blur();
|
|
},
|
|
|
|
getQuery: function getQuery() {
|
|
return this.query;
|
|
},
|
|
|
|
setQuery: function setQuery(query) {
|
|
this.query = query;
|
|
},
|
|
|
|
getInputValue: function getInputValue() {
|
|
return this.$input.val();
|
|
},
|
|
|
|
setInputValue: function setInputValue(value, silent) {
|
|
if (typeof value === 'undefined') {
|
|
value = this.query;
|
|
}
|
|
this.$input.val(value);
|
|
|
|
// silent prevents any additional events from being triggered
|
|
if (silent) {
|
|
this.clearHint();
|
|
} else {
|
|
this._checkInputValue();
|
|
}
|
|
},
|
|
|
|
expand: function expand() {
|
|
this.$input.attr('aria-expanded', 'true');
|
|
},
|
|
|
|
collapse: function collapse() {
|
|
this.$input.attr('aria-expanded', 'false');
|
|
},
|
|
|
|
setActiveDescendant: function setActiveDescendant(activedescendantId) {
|
|
this.$input.attr('aria-activedescendant', activedescendantId);
|
|
},
|
|
|
|
removeActiveDescendant: function removeActiveDescendant() {
|
|
this.$input.removeAttr('aria-activedescendant');
|
|
},
|
|
|
|
resetInputValue: function resetInputValue() {
|
|
this.setInputValue(this.query, true);
|
|
},
|
|
|
|
getHint: function getHint() {
|
|
return this.$hint.val();
|
|
},
|
|
|
|
setHint: function setHint(value) {
|
|
this.$hint.val(value);
|
|
},
|
|
|
|
clearHint: function clearHint() {
|
|
this.setHint('');
|
|
},
|
|
|
|
clearHintIfInvalid: function clearHintIfInvalid() {
|
|
var val;
|
|
var hint;
|
|
var valIsPrefixOfHint;
|
|
var isValid;
|
|
|
|
val = this.getInputValue();
|
|
hint = this.getHint();
|
|
valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0;
|
|
isValid = val !== '' && valIsPrefixOfHint && !this.hasOverflow();
|
|
|
|
if (!isValid) {
|
|
this.clearHint();
|
|
}
|
|
},
|
|
|
|
getLanguageDirection: function getLanguageDirection() {
|
|
return (this.$input.css('direction') || 'ltr').toLowerCase();
|
|
},
|
|
|
|
hasOverflow: function hasOverflow() {
|
|
// 2 is arbitrary, just picking a small number to handle edge cases
|
|
var constraint = this.$input.width() - 2;
|
|
|
|
this.$overflowHelper.text(this.getInputValue());
|
|
|
|
return this.$overflowHelper.width() >= constraint;
|
|
},
|
|
|
|
isCursorAtEnd: function() {
|
|
var valueLength;
|
|
var selectionStart;
|
|
var range;
|
|
|
|
valueLength = this.$input.val().length;
|
|
selectionStart = this.$input[0].selectionStart;
|
|
|
|
if (_.isNumber(selectionStart)) {
|
|
return selectionStart === valueLength;
|
|
} else if (document.selection) {
|
|
// NOTE: this won't work unless the input has focus, the good news
|
|
// is this code should only get called when the input has focus
|
|
range = document.selection.createRange();
|
|
range.moveStart('character', -valueLength);
|
|
|
|
return valueLength === range.text.length;
|
|
}
|
|
|
|
return true;
|
|
},
|
|
|
|
destroy: function destroy() {
|
|
this.$hint.off('.aa');
|
|
this.$input.off('.aa');
|
|
|
|
this.$hint = this.$input = this.$overflowHelper = null;
|
|
}
|
|
});
|
|
|
|
// helper functions
|
|
// ----------------
|
|
|
|
function buildOverflowHelper($input) {
|
|
return DOM.element('<pre aria-hidden="true"></pre>')
|
|
.css({
|
|
// position helper off-screen
|
|
position: 'absolute',
|
|
visibility: 'hidden',
|
|
// avoid line breaks and whitespace collapsing
|
|
whiteSpace: 'pre',
|
|
// use same font css as input to calculate accurate width
|
|
fontFamily: $input.css('font-family'),
|
|
fontSize: $input.css('font-size'),
|
|
fontStyle: $input.css('font-style'),
|
|
fontVariant: $input.css('font-variant'),
|
|
fontWeight: $input.css('font-weight'),
|
|
wordSpacing: $input.css('word-spacing'),
|
|
letterSpacing: $input.css('letter-spacing'),
|
|
textIndent: $input.css('text-indent'),
|
|
textRendering: $input.css('text-rendering'),
|
|
textTransform: $input.css('text-transform')
|
|
})
|
|
.insertAfter($input);
|
|
}
|
|
|
|
function areQueriesEquivalent(a, b) {
|
|
return Input.normalizeQuery(a) === Input.normalizeQuery(b);
|
|
}
|
|
|
|
function withModifier($e) {
|
|
return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey;
|
|
}
|
|
|
|
module.exports = Input;
|
|
|
|
|
|
/***/ }),
|
|
/* 58 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var types = [
|
|
__webpack_require__(59),
|
|
__webpack_require__(60),
|
|
__webpack_require__(61),
|
|
__webpack_require__(62),
|
|
__webpack_require__(63)
|
|
];
|
|
var draining;
|
|
var currentQueue;
|
|
var queueIndex = -1;
|
|
var queue = [];
|
|
var scheduled = false;
|
|
function cleanUpNextTick() {
|
|
if (!draining || !currentQueue) {
|
|
return;
|
|
}
|
|
draining = false;
|
|
if (currentQueue.length) {
|
|
queue = currentQueue.concat(queue);
|
|
} else {
|
|
queueIndex = -1;
|
|
}
|
|
if (queue.length) {
|
|
nextTick();
|
|
}
|
|
}
|
|
|
|
//named nextTick for less confusing stack traces
|
|
function nextTick() {
|
|
if (draining) {
|
|
return;
|
|
}
|
|
scheduled = false;
|
|
draining = true;
|
|
var len = queue.length;
|
|
var timeout = setTimeout(cleanUpNextTick);
|
|
while (len) {
|
|
currentQueue = queue;
|
|
queue = [];
|
|
while (currentQueue && ++queueIndex < len) {
|
|
currentQueue[queueIndex].run();
|
|
}
|
|
queueIndex = -1;
|
|
len = queue.length;
|
|
}
|
|
currentQueue = null;
|
|
queueIndex = -1;
|
|
draining = false;
|
|
clearTimeout(timeout);
|
|
}
|
|
var scheduleDrain;
|
|
var i = -1;
|
|
var len = types.length;
|
|
while (++i < len) {
|
|
if (types[i] && types[i].test && types[i].test()) {
|
|
scheduleDrain = types[i].install(nextTick);
|
|
break;
|
|
}
|
|
}
|
|
// v8 likes predictible objects
|
|
function Item(fun, array) {
|
|
this.fun = fun;
|
|
this.array = array;
|
|
}
|
|
Item.prototype.run = function () {
|
|
var fun = this.fun;
|
|
var array = this.array;
|
|
switch (array.length) {
|
|
case 0:
|
|
return fun();
|
|
case 1:
|
|
return fun(array[0]);
|
|
case 2:
|
|
return fun(array[0], array[1]);
|
|
case 3:
|
|
return fun(array[0], array[1], array[2]);
|
|
default:
|
|
return fun.apply(null, array);
|
|
}
|
|
|
|
};
|
|
module.exports = immediate;
|
|
function immediate(task) {
|
|
var args = new Array(arguments.length - 1);
|
|
if (arguments.length > 1) {
|
|
for (var i = 1; i < arguments.length; i++) {
|
|
args[i - 1] = arguments[i];
|
|
}
|
|
}
|
|
queue.push(new Item(task, args));
|
|
if (!scheduled && !draining) {
|
|
scheduled = true;
|
|
scheduleDrain();
|
|
}
|
|
}
|
|
|
|
|
|
/***/ }),
|
|
/* 59 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
/* WEBPACK VAR INJECTION */(function(process) {
|
|
exports.test = function () {
|
|
// Don't get fooled by e.g. browserify environments.
|
|
return (typeof process !== 'undefined') && !process.browser;
|
|
};
|
|
|
|
exports.install = function (func) {
|
|
return function () {
|
|
process.nextTick(func);
|
|
};
|
|
};
|
|
|
|
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(10)))
|
|
|
|
/***/ }),
|
|
/* 60 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
/* WEBPACK VAR INJECTION */(function(global) {
|
|
//based off rsvp https://github.com/tildeio/rsvp.js
|
|
//license https://github.com/tildeio/rsvp.js/blob/master/LICENSE
|
|
//https://github.com/tildeio/rsvp.js/blob/master/lib/rsvp/asap.js
|
|
|
|
var Mutation = global.MutationObserver || global.WebKitMutationObserver;
|
|
|
|
exports.test = function () {
|
|
return Mutation;
|
|
};
|
|
|
|
exports.install = function (handle) {
|
|
var called = 0;
|
|
var observer = new Mutation(handle);
|
|
var element = global.document.createTextNode('');
|
|
observer.observe(element, {
|
|
characterData: true
|
|
});
|
|
return function () {
|
|
element.data = (called = ++called % 2);
|
|
};
|
|
};
|
|
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(5)))
|
|
|
|
/***/ }),
|
|
/* 61 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
/* WEBPACK VAR INJECTION */(function(global) {
|
|
|
|
exports.test = function () {
|
|
if (global.setImmediate) {
|
|
// we can only get here in IE10
|
|
// which doesn't handel postMessage well
|
|
return false;
|
|
}
|
|
return typeof global.MessageChannel !== 'undefined';
|
|
};
|
|
|
|
exports.install = function (func) {
|
|
var channel = new global.MessageChannel();
|
|
channel.port1.onmessage = func;
|
|
return function () {
|
|
channel.port2.postMessage(0);
|
|
};
|
|
};
|
|
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(5)))
|
|
|
|
/***/ }),
|
|
/* 62 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
/* WEBPACK VAR INJECTION */(function(global) {
|
|
|
|
exports.test = function () {
|
|
return 'document' in global && 'onreadystatechange' in global.document.createElement('script');
|
|
};
|
|
|
|
exports.install = function (handle) {
|
|
return function () {
|
|
|
|
// Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
|
|
// into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
|
|
var scriptEl = global.document.createElement('script');
|
|
scriptEl.onreadystatechange = function () {
|
|
handle();
|
|
|
|
scriptEl.onreadystatechange = null;
|
|
scriptEl.parentNode.removeChild(scriptEl);
|
|
scriptEl = null;
|
|
};
|
|
global.document.documentElement.appendChild(scriptEl);
|
|
|
|
return handle;
|
|
};
|
|
};
|
|
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(5)))
|
|
|
|
/***/ }),
|
|
/* 63 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
exports.test = function () {
|
|
return true;
|
|
};
|
|
|
|
exports.install = function (t) {
|
|
return function () {
|
|
setTimeout(t, 0);
|
|
};
|
|
};
|
|
|
|
/***/ }),
|
|
/* 64 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _ = __webpack_require__(0);
|
|
var DOM = __webpack_require__(2);
|
|
var EventEmitter = __webpack_require__(16);
|
|
var Dataset = __webpack_require__(65);
|
|
var css = __webpack_require__(17);
|
|
|
|
// constructor
|
|
// -----------
|
|
|
|
function Dropdown(o) {
|
|
var that = this;
|
|
var onSuggestionClick;
|
|
var onSuggestionMouseEnter;
|
|
var onSuggestionMouseLeave;
|
|
|
|
o = o || {};
|
|
|
|
if (!o.menu) {
|
|
_.error('menu is required');
|
|
}
|
|
|
|
if (!_.isArray(o.datasets) && !_.isObject(o.datasets)) {
|
|
_.error('1 or more datasets required');
|
|
}
|
|
if (!o.datasets) {
|
|
_.error('datasets is required');
|
|
}
|
|
|
|
this.isOpen = false;
|
|
this.isEmpty = true;
|
|
this.minLength = o.minLength || 0;
|
|
this.templates = {};
|
|
this.appendTo = o.appendTo || false;
|
|
this.css = _.mixin({}, css, o.appendTo ? css.appendTo : {});
|
|
this.cssClasses = o.cssClasses = _.mixin({}, css.defaultClasses, o.cssClasses || {});
|
|
this.cssClasses.prefix =
|
|
o.cssClasses.formattedPrefix || _.formatPrefix(this.cssClasses.prefix, this.cssClasses.noPrefix);
|
|
|
|
// bound functions
|
|
onSuggestionClick = _.bind(this._onSuggestionClick, this);
|
|
onSuggestionMouseEnter = _.bind(this._onSuggestionMouseEnter, this);
|
|
onSuggestionMouseLeave = _.bind(this._onSuggestionMouseLeave, this);
|
|
|
|
var cssClass = _.className(this.cssClasses.prefix, this.cssClasses.suggestion);
|
|
this.$menu = DOM.element(o.menu)
|
|
.on('mouseenter.aa', cssClass, onSuggestionMouseEnter)
|
|
.on('mouseleave.aa', cssClass, onSuggestionMouseLeave)
|
|
.on('click.aa', cssClass, onSuggestionClick);
|
|
|
|
this.$container = o.appendTo ? o.wrapper : this.$menu;
|
|
|
|
if (o.templates && o.templates.header) {
|
|
this.templates.header = _.templatify(o.templates.header);
|
|
this.$menu.prepend(this.templates.header());
|
|
}
|
|
|
|
if (o.templates && o.templates.empty) {
|
|
this.templates.empty = _.templatify(o.templates.empty);
|
|
this.$empty = DOM.element('<div class="' +
|
|
_.className(this.cssClasses.prefix, this.cssClasses.empty, true) + '">' +
|
|
'</div>');
|
|
this.$menu.append(this.$empty);
|
|
this.$empty.hide();
|
|
}
|
|
|
|
this.datasets = _.map(o.datasets, function(oDataset) {
|
|
return initializeDataset(that.$menu, oDataset, o.cssClasses);
|
|
});
|
|
_.each(this.datasets, function(dataset) {
|
|
var root = dataset.getRoot();
|
|
if (root && root.parent().length === 0) {
|
|
that.$menu.append(root);
|
|
}
|
|
dataset.onSync('rendered', that._onRendered, that);
|
|
});
|
|
|
|
if (o.templates && o.templates.footer) {
|
|
this.templates.footer = _.templatify(o.templates.footer);
|
|
this.$menu.append(this.templates.footer());
|
|
}
|
|
|
|
var self = this;
|
|
DOM.element(window).resize(function() {
|
|
self._redraw();
|
|
});
|
|
}
|
|
|
|
// instance methods
|
|
// ----------------
|
|
|
|
_.mixin(Dropdown.prototype, EventEmitter, {
|
|
|
|
// ### private
|
|
|
|
_onSuggestionClick: function onSuggestionClick($e) {
|
|
this.trigger('suggestionClicked', DOM.element($e.currentTarget));
|
|
},
|
|
|
|
_onSuggestionMouseEnter: function onSuggestionMouseEnter($e) {
|
|
var elt = DOM.element($e.currentTarget);
|
|
if (elt.hasClass(_.className(this.cssClasses.prefix, this.cssClasses.cursor, true))) {
|
|
// we're already on the cursor
|
|
// => we're probably entering it again after leaving it for a nested div
|
|
return;
|
|
}
|
|
this._removeCursor();
|
|
|
|
// Fixes iOS double tap behaviour, by modifying the DOM right before the
|
|
// native href clicks happens, iOS will requires another tap to follow
|
|
// a suggestion that has an <a href> element inside
|
|
// https://www.google.com/search?q=ios+double+tap+bug+href
|
|
var suggestion = this;
|
|
setTimeout(function() {
|
|
// this exact line, when inside the main loop, will trigger a double tap bug
|
|
// on iOS devices
|
|
suggestion._setCursor(elt, false);
|
|
}, 0);
|
|
},
|
|
|
|
_onSuggestionMouseLeave: function onSuggestionMouseLeave($e) {
|
|
// $e.relatedTarget is the `EventTarget` the pointing device entered to
|
|
if ($e.relatedTarget) {
|
|
var elt = DOM.element($e.relatedTarget);
|
|
if (elt.closest('.' + _.className(this.cssClasses.prefix, this.cssClasses.cursor, true)).length > 0) {
|
|
// our father is a cursor
|
|
// => it means we're just leaving the suggestion for a nested div
|
|
return;
|
|
}
|
|
}
|
|
this._removeCursor();
|
|
this.trigger('cursorRemoved');
|
|
},
|
|
|
|
_onRendered: function onRendered(e, query) {
|
|
this.isEmpty = _.every(this.datasets, isDatasetEmpty);
|
|
|
|
if (this.isEmpty) {
|
|
if (query.length >= this.minLength) {
|
|
this.trigger('empty');
|
|
}
|
|
|
|
if (this.$empty) {
|
|
if (query.length < this.minLength) {
|
|
this._hide();
|
|
} else {
|
|
var html = this.templates.empty({
|
|
query: this.datasets[0] && this.datasets[0].query
|
|
});
|
|
this.$empty.html(html);
|
|
this.$empty.show();
|
|
this._show();
|
|
}
|
|
} else if (_.any(this.datasets, hasEmptyTemplate)) {
|
|
if (query.length < this.minLength) {
|
|
this._hide();
|
|
} else {
|
|
this._show();
|
|
}
|
|
} else {
|
|
this._hide();
|
|
}
|
|
} else if (this.isOpen) {
|
|
if (this.$empty) {
|
|
this.$empty.empty();
|
|
this.$empty.hide();
|
|
}
|
|
|
|
if (query.length >= this.minLength) {
|
|
this._show();
|
|
} else {
|
|
this._hide();
|
|
}
|
|
}
|
|
|
|
this.trigger('datasetRendered');
|
|
|
|
function isDatasetEmpty(dataset) {
|
|
return dataset.isEmpty();
|
|
}
|
|
|
|
function hasEmptyTemplate(dataset) {
|
|
return dataset.templates && dataset.templates.empty;
|
|
}
|
|
},
|
|
|
|
_hide: function() {
|
|
this.$container.hide();
|
|
},
|
|
|
|
_show: function() {
|
|
// can't use jQuery#show because $menu is a span element we want
|
|
// display: block; not dislay: inline;
|
|
this.$container.css('display', 'block');
|
|
|
|
this._redraw();
|
|
|
|
this.trigger('shown');
|
|
},
|
|
|
|
_redraw: function redraw() {
|
|
if (!this.isOpen || !this.appendTo) return;
|
|
|
|
this.trigger('redrawn');
|
|
},
|
|
|
|
_getSuggestions: function getSuggestions() {
|
|
return this.$menu.find(_.className(this.cssClasses.prefix, this.cssClasses.suggestion));
|
|
},
|
|
|
|
_getCursor: function getCursor() {
|
|
return this.$menu.find(_.className(this.cssClasses.prefix, this.cssClasses.cursor)).first();
|
|
},
|
|
|
|
_setCursor: function setCursor($el, updateInput) {
|
|
$el.first()
|
|
.addClass(_.className(this.cssClasses.prefix, this.cssClasses.cursor, true))
|
|
.attr('aria-selected', 'true');
|
|
this.trigger('cursorMoved', updateInput);
|
|
},
|
|
|
|
_removeCursor: function removeCursor() {
|
|
this._getCursor()
|
|
.removeClass(_.className(this.cssClasses.prefix, this.cssClasses.cursor, true))
|
|
.removeAttr('aria-selected');
|
|
},
|
|
|
|
_moveCursor: function moveCursor(increment) {
|
|
var $suggestions;
|
|
var $oldCursor;
|
|
var newCursorIndex;
|
|
var $newCursor;
|
|
|
|
if (!this.isOpen) {
|
|
return;
|
|
}
|
|
|
|
$oldCursor = this._getCursor();
|
|
$suggestions = this._getSuggestions();
|
|
|
|
this._removeCursor();
|
|
|
|
// shifting before and after modulo to deal with -1 index
|
|
newCursorIndex = $suggestions.index($oldCursor) + increment;
|
|
newCursorIndex = (newCursorIndex + 1) % ($suggestions.length + 1) - 1;
|
|
|
|
if (newCursorIndex === -1) {
|
|
this.trigger('cursorRemoved');
|
|
|
|
return;
|
|
} else if (newCursorIndex < -1) {
|
|
newCursorIndex = $suggestions.length - 1;
|
|
}
|
|
|
|
this._setCursor($newCursor = $suggestions.eq(newCursorIndex), true);
|
|
|
|
// in the case of scrollable overflow
|
|
// make sure the cursor is visible in the menu
|
|
this._ensureVisible($newCursor);
|
|
},
|
|
|
|
_ensureVisible: function ensureVisible($el) {
|
|
var elTop;
|
|
var elBottom;
|
|
var menuScrollTop;
|
|
var menuHeight;
|
|
|
|
elTop = $el.position().top;
|
|
elBottom = elTop + $el.height() +
|
|
parseInt($el.css('margin-top'), 10) +
|
|
parseInt($el.css('margin-bottom'), 10);
|
|
menuScrollTop = this.$menu.scrollTop();
|
|
menuHeight = this.$menu.height() +
|
|
parseInt(this.$menu.css('padding-top'), 10) +
|
|
parseInt(this.$menu.css('padding-bottom'), 10);
|
|
|
|
if (elTop < 0) {
|
|
this.$menu.scrollTop(menuScrollTop + elTop);
|
|
} else if (menuHeight < elBottom) {
|
|
this.$menu.scrollTop(menuScrollTop + (elBottom - menuHeight));
|
|
}
|
|
},
|
|
|
|
// ### public
|
|
|
|
close: function close() {
|
|
if (this.isOpen) {
|
|
this.isOpen = false;
|
|
|
|
this._removeCursor();
|
|
this._hide();
|
|
|
|
this.trigger('closed');
|
|
}
|
|
},
|
|
|
|
open: function open() {
|
|
if (!this.isOpen) {
|
|
this.isOpen = true;
|
|
|
|
if (!this.isEmpty) {
|
|
this._show();
|
|
}
|
|
|
|
this.trigger('opened');
|
|
}
|
|
},
|
|
|
|
setLanguageDirection: function setLanguageDirection(dir) {
|
|
this.$menu.css(dir === 'ltr' ? this.css.ltr : this.css.rtl);
|
|
},
|
|
|
|
moveCursorUp: function moveCursorUp() {
|
|
this._moveCursor(-1);
|
|
},
|
|
|
|
moveCursorDown: function moveCursorDown() {
|
|
this._moveCursor(+1);
|
|
},
|
|
|
|
getDatumForSuggestion: function getDatumForSuggestion($el) {
|
|
var datum = null;
|
|
|
|
if ($el.length) {
|
|
datum = {
|
|
raw: Dataset.extractDatum($el),
|
|
value: Dataset.extractValue($el),
|
|
datasetName: Dataset.extractDatasetName($el)
|
|
};
|
|
}
|
|
|
|
return datum;
|
|
},
|
|
|
|
getCurrentCursor: function getCurrentCursor() {
|
|
return this._getCursor().first();
|
|
},
|
|
|
|
getDatumForCursor: function getDatumForCursor() {
|
|
return this.getDatumForSuggestion(this._getCursor().first());
|
|
},
|
|
|
|
getDatumForTopSuggestion: function getDatumForTopSuggestion() {
|
|
return this.getDatumForSuggestion(this._getSuggestions().first());
|
|
},
|
|
|
|
cursorTopSuggestion: function cursorTopSuggestion() {
|
|
this._setCursor(this._getSuggestions().first(), false);
|
|
},
|
|
|
|
update: function update(query) {
|
|
_.each(this.datasets, updateDataset);
|
|
|
|
function updateDataset(dataset) {
|
|
dataset.update(query);
|
|
}
|
|
},
|
|
|
|
empty: function empty() {
|
|
_.each(this.datasets, clearDataset);
|
|
this.isEmpty = true;
|
|
|
|
function clearDataset(dataset) {
|
|
dataset.clear();
|
|
}
|
|
},
|
|
|
|
isVisible: function isVisible() {
|
|
return this.isOpen && !this.isEmpty;
|
|
},
|
|
|
|
destroy: function destroy() {
|
|
this.$menu.off('.aa');
|
|
|
|
this.$menu = null;
|
|
|
|
_.each(this.datasets, destroyDataset);
|
|
|
|
function destroyDataset(dataset) {
|
|
dataset.destroy();
|
|
}
|
|
}
|
|
});
|
|
|
|
// helper functions
|
|
// ----------------
|
|
Dropdown.Dataset = Dataset;
|
|
|
|
function initializeDataset($menu, oDataset, cssClasses) {
|
|
return new Dropdown.Dataset(_.mixin({$menu: $menu, cssClasses: cssClasses}, oDataset));
|
|
}
|
|
|
|
module.exports = Dropdown;
|
|
|
|
|
|
/***/ }),
|
|
/* 65 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var datasetKey = 'aaDataset';
|
|
var valueKey = 'aaValue';
|
|
var datumKey = 'aaDatum';
|
|
|
|
var _ = __webpack_require__(0);
|
|
var DOM = __webpack_require__(2);
|
|
var html = __webpack_require__(27);
|
|
var css = __webpack_require__(17);
|
|
var EventEmitter = __webpack_require__(16);
|
|
|
|
// constructor
|
|
// -----------
|
|
|
|
function Dataset(o) {
|
|
o = o || {};
|
|
o.templates = o.templates || {};
|
|
|
|
if (!o.source) {
|
|
_.error('missing source');
|
|
}
|
|
|
|
if (o.name && !isValidName(o.name)) {
|
|
_.error('invalid dataset name: ' + o.name);
|
|
}
|
|
|
|
// tracks the last query the dataset was updated for
|
|
this.query = null;
|
|
this._isEmpty = true;
|
|
|
|
this.highlight = !!o.highlight;
|
|
this.name = typeof o.name === 'undefined' || o.name === null ? _.getUniqueId() : o.name;
|
|
|
|
this.source = o.source;
|
|
this.displayFn = getDisplayFn(o.display || o.displayKey);
|
|
|
|
this.debounce = o.debounce;
|
|
|
|
this.cache = o.cache !== false;
|
|
|
|
this.templates = getTemplates(o.templates, this.displayFn);
|
|
|
|
this.css = _.mixin({}, css, o.appendTo ? css.appendTo : {});
|
|
this.cssClasses = o.cssClasses = _.mixin({}, css.defaultClasses, o.cssClasses || {});
|
|
this.cssClasses.prefix =
|
|
o.cssClasses.formattedPrefix || _.formatPrefix(this.cssClasses.prefix, this.cssClasses.noPrefix);
|
|
|
|
var clazz = _.className(this.cssClasses.prefix, this.cssClasses.dataset);
|
|
this.$el = o.$menu && o.$menu.find(clazz + '-' + this.name).length > 0 ?
|
|
DOM.element(o.$menu.find(clazz + '-' + this.name)[0]) :
|
|
DOM.element(
|
|
html.dataset.replace('%CLASS%', this.name)
|
|
.replace('%PREFIX%', this.cssClasses.prefix)
|
|
.replace('%DATASET%', this.cssClasses.dataset)
|
|
);
|
|
|
|
this.$menu = o.$menu;
|
|
this.clearCachedSuggestions();
|
|
}
|
|
|
|
// static methods
|
|
// --------------
|
|
|
|
Dataset.extractDatasetName = function extractDatasetName(el) {
|
|
return DOM.element(el).data(datasetKey);
|
|
};
|
|
|
|
Dataset.extractValue = function extractValue(el) {
|
|
return DOM.element(el).data(valueKey);
|
|
};
|
|
|
|
Dataset.extractDatum = function extractDatum(el) {
|
|
var datum = DOM.element(el).data(datumKey);
|
|
if (typeof datum === 'string') {
|
|
// Zepto has an automatic deserialization of the
|
|
// JSON encoded data attribute
|
|
datum = JSON.parse(datum);
|
|
}
|
|
return datum;
|
|
};
|
|
|
|
// instance methods
|
|
// ----------------
|
|
|
|
_.mixin(Dataset.prototype, EventEmitter, {
|
|
|
|
// ### private
|
|
|
|
_render: function render(query, suggestions) {
|
|
if (!this.$el) {
|
|
return;
|
|
}
|
|
var that = this;
|
|
|
|
var hasSuggestions;
|
|
var renderArgs = [].slice.call(arguments, 2);
|
|
this.$el.empty();
|
|
|
|
hasSuggestions = suggestions && suggestions.length;
|
|
this._isEmpty = !hasSuggestions;
|
|
|
|
if (!hasSuggestions && this.templates.empty) {
|
|
this.$el
|
|
.html(getEmptyHtml.apply(this, renderArgs))
|
|
.prepend(that.templates.header ? getHeaderHtml.apply(this, renderArgs) : null)
|
|
.append(that.templates.footer ? getFooterHtml.apply(this, renderArgs) : null);
|
|
} else if (hasSuggestions) {
|
|
this.$el
|
|
.html(getSuggestionsHtml.apply(this, renderArgs))
|
|
.prepend(that.templates.header ? getHeaderHtml.apply(this, renderArgs) : null)
|
|
.append(that.templates.footer ? getFooterHtml.apply(this, renderArgs) : null);
|
|
} else if (suggestions && !Array.isArray(suggestions)) {
|
|
throw new TypeError('suggestions must be an array');
|
|
}
|
|
|
|
if (this.$menu) {
|
|
this.$menu.addClass(
|
|
this.cssClasses.prefix + (hasSuggestions ? 'with' : 'without') + '-' + this.name
|
|
).removeClass(
|
|
this.cssClasses.prefix + (hasSuggestions ? 'without' : 'with') + '-' + this.name
|
|
);
|
|
}
|
|
|
|
this.trigger('rendered', query);
|
|
|
|
function getEmptyHtml() {
|
|
var args = [].slice.call(arguments, 0);
|
|
args = [{query: query, isEmpty: true}].concat(args);
|
|
return that.templates.empty.apply(this, args);
|
|
}
|
|
|
|
function getSuggestionsHtml() {
|
|
var args = [].slice.call(arguments, 0);
|
|
var $suggestions;
|
|
var nodes;
|
|
var self = this;
|
|
|
|
var suggestionsHtml = html.suggestions.
|
|
replace('%PREFIX%', this.cssClasses.prefix).
|
|
replace('%SUGGESTIONS%', this.cssClasses.suggestions);
|
|
$suggestions = DOM
|
|
.element(suggestionsHtml)
|
|
.css(this.css.suggestions);
|
|
|
|
// jQuery#append doesn't support arrays as the first argument
|
|
// until version 1.8, see http://bugs.jquery.com/ticket/11231
|
|
nodes = _.map(suggestions, getSuggestionNode);
|
|
$suggestions.append.apply($suggestions, nodes);
|
|
|
|
return $suggestions;
|
|
|
|
function getSuggestionNode(suggestion) {
|
|
var $el;
|
|
|
|
var suggestionHtml = html.suggestion.
|
|
replace('%PREFIX%', self.cssClasses.prefix).
|
|
replace('%SUGGESTION%', self.cssClasses.suggestion);
|
|
$el = DOM.element(suggestionHtml)
|
|
.attr({
|
|
role: 'option',
|
|
id: ['option', Math.floor(Math.random() * 100000000)].join('-')
|
|
})
|
|
.append(that.templates.suggestion.apply(this, [suggestion].concat(args)));
|
|
|
|
$el.data(datasetKey, that.name);
|
|
$el.data(valueKey, that.displayFn(suggestion) || undefined); // this led to undefined return value
|
|
$el.data(datumKey, JSON.stringify(suggestion));
|
|
$el.children().each(function() { DOM.element(this).css(self.css.suggestionChild); });
|
|
|
|
return $el;
|
|
}
|
|
}
|
|
|
|
function getHeaderHtml() {
|
|
var args = [].slice.call(arguments, 0);
|
|
args = [{query: query, isEmpty: !hasSuggestions}].concat(args);
|
|
return that.templates.header.apply(this, args);
|
|
}
|
|
|
|
function getFooterHtml() {
|
|
var args = [].slice.call(arguments, 0);
|
|
args = [{query: query, isEmpty: !hasSuggestions}].concat(args);
|
|
return that.templates.footer.apply(this, args);
|
|
}
|
|
},
|
|
|
|
// ### public
|
|
|
|
getRoot: function getRoot() {
|
|
return this.$el;
|
|
},
|
|
|
|
update: function update(query) {
|
|
function handleSuggestions(suggestions) {
|
|
// if the update has been canceled or if the query has changed
|
|
// do not render the suggestions as they've become outdated
|
|
if (!this.canceled && query === this.query) {
|
|
// concat all the other arguments that could have been passed
|
|
// to the render function, and forward them to _render
|
|
var extraArgs = [].slice.call(arguments, 1);
|
|
this.cacheSuggestions(query, suggestions, extraArgs);
|
|
this._render.apply(this, [query, suggestions].concat(extraArgs));
|
|
}
|
|
}
|
|
|
|
this.query = query;
|
|
this.canceled = false;
|
|
|
|
if (this.shouldFetchFromCache(query)) {
|
|
handleSuggestions.apply(this, [this.cachedSuggestions].concat(this.cachedRenderExtraArgs));
|
|
} else {
|
|
var that = this;
|
|
var execSource = function() {
|
|
// When the call is debounced the condition avoid to do a useless
|
|
// request with the last character when the input has been cleared
|
|
if (!that.canceled) {
|
|
that.source(query, handleSuggestions.bind(that));
|
|
}
|
|
};
|
|
|
|
if (this.debounce) {
|
|
var later = function() {
|
|
that.debounceTimeout = null;
|
|
execSource();
|
|
};
|
|
clearTimeout(this.debounceTimeout);
|
|
this.debounceTimeout = setTimeout(later, this.debounce);
|
|
} else {
|
|
execSource();
|
|
}
|
|
}
|
|
},
|
|
|
|
cacheSuggestions: function cacheSuggestions(query, suggestions, extraArgs) {
|
|
this.cachedQuery = query;
|
|
this.cachedSuggestions = suggestions;
|
|
this.cachedRenderExtraArgs = extraArgs;
|
|
},
|
|
|
|
shouldFetchFromCache: function shouldFetchFromCache(query) {
|
|
return this.cache &&
|
|
this.cachedQuery === query &&
|
|
this.cachedSuggestions &&
|
|
this.cachedSuggestions.length;
|
|
},
|
|
|
|
clearCachedSuggestions: function clearCachedSuggestions() {
|
|
delete this.cachedQuery;
|
|
delete this.cachedSuggestions;
|
|
delete this.cachedRenderExtraArgs;
|
|
},
|
|
|
|
cancel: function cancel() {
|
|
this.canceled = true;
|
|
},
|
|
|
|
clear: function clear() {
|
|
if (this.$el) {
|
|
this.cancel();
|
|
this.$el.empty();
|
|
this.trigger('rendered', '');
|
|
}
|
|
},
|
|
|
|
isEmpty: function isEmpty() {
|
|
return this._isEmpty;
|
|
},
|
|
|
|
destroy: function destroy() {
|
|
this.clearCachedSuggestions();
|
|
this.$el = null;
|
|
}
|
|
});
|
|
|
|
// helper functions
|
|
// ----------------
|
|
|
|
function getDisplayFn(display) {
|
|
display = display || 'value';
|
|
|
|
return _.isFunction(display) ? display : displayFn;
|
|
|
|
function displayFn(obj) {
|
|
return obj[display];
|
|
}
|
|
}
|
|
|
|
function getTemplates(templates, displayFn) {
|
|
return {
|
|
empty: templates.empty && _.templatify(templates.empty),
|
|
header: templates.header && _.templatify(templates.header),
|
|
footer: templates.footer && _.templatify(templates.footer),
|
|
suggestion: templates.suggestion || suggestionTemplate
|
|
};
|
|
|
|
function suggestionTemplate(context) {
|
|
return '<p>' + displayFn(context) + '</p>';
|
|
}
|
|
}
|
|
|
|
function isValidName(str) {
|
|
// dashes, underscores, letters, and numbers
|
|
return (/^[_a-zA-Z0-9-]+$/).test(str);
|
|
}
|
|
|
|
module.exports = Dataset;
|
|
|
|
|
|
/***/ }),
|
|
/* 66 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
module.exports = {
|
|
hits: __webpack_require__(67),
|
|
popularIn: __webpack_require__(68)
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 67 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _ = __webpack_require__(0);
|
|
var version = __webpack_require__(28);
|
|
var parseAlgoliaClientVersion = __webpack_require__(29);
|
|
|
|
module.exports = function search(index, params) {
|
|
var algoliaVersion = parseAlgoliaClientVersion(index.as._ua);
|
|
if (algoliaVersion && algoliaVersion[0] >= 3 && algoliaVersion[1] > 20) {
|
|
params = params || {};
|
|
params.additionalUA = 'autocomplete.js ' + version;
|
|
}
|
|
return sourceFn;
|
|
|
|
function sourceFn(query, cb) {
|
|
index.search(query, params, function(error, content) {
|
|
if (error) {
|
|
_.error(error.message);
|
|
return;
|
|
}
|
|
cb(content.hits, content);
|
|
});
|
|
}
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 68 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _ = __webpack_require__(0);
|
|
var version = __webpack_require__(28);
|
|
var parseAlgoliaClientVersion = __webpack_require__(29);
|
|
|
|
module.exports = function popularIn(index, params, details, options) {
|
|
var algoliaVersion = parseAlgoliaClientVersion(index.as._ua);
|
|
if (algoliaVersion && algoliaVersion[0] >= 3 && algoliaVersion[1] > 20) {
|
|
params = params || {};
|
|
params.additionalUA = 'autocomplete.js ' + version;
|
|
}
|
|
if (!details.source) {
|
|
return _.error("Missing 'source' key");
|
|
}
|
|
var source = _.isFunction(details.source) ? details.source : function(hit) { return hit[details.source]; };
|
|
|
|
if (!details.index) {
|
|
return _.error("Missing 'index' key");
|
|
}
|
|
var detailsIndex = details.index;
|
|
|
|
options = options || {};
|
|
|
|
return sourceFn;
|
|
|
|
function sourceFn(query, cb) {
|
|
index.search(query, params, function(error, content) {
|
|
if (error) {
|
|
_.error(error.message);
|
|
return;
|
|
}
|
|
|
|
if (content.hits.length > 0) {
|
|
var first = content.hits[0];
|
|
|
|
var detailsParams = _.mixin({hitsPerPage: 0}, details);
|
|
delete detailsParams.source; // not a query parameter
|
|
delete detailsParams.index; // not a query parameter
|
|
|
|
var detailsAlgoliaVersion = parseAlgoliaClientVersion(detailsIndex.as._ua);
|
|
if (detailsAlgoliaVersion && detailsAlgoliaVersion[0] >= 3 && detailsAlgoliaVersion[1] > 20) {
|
|
params.additionalUA = 'autocomplete.js ' + version;
|
|
}
|
|
|
|
detailsIndex.search(source(first), detailsParams, function(error2, content2) {
|
|
if (error2) {
|
|
_.error(error2.message);
|
|
return;
|
|
}
|
|
|
|
var suggestions = [];
|
|
|
|
// add the 'all department' entry before others
|
|
if (options.includeAll) {
|
|
var label = options.allTitle || 'All departments';
|
|
suggestions.push(_.mixin({
|
|
facet: {value: label, count: content2.nbHits}
|
|
}, _.cloneDeep(first)));
|
|
}
|
|
|
|
// enrich the first hit iterating over the facets
|
|
_.each(content2.facets, function(values, facet) {
|
|
_.each(values, function(count, value) {
|
|
suggestions.push(_.mixin({
|
|
facet: {facet: facet, value: value, count: count}
|
|
}, _.cloneDeep(first)));
|
|
});
|
|
});
|
|
|
|
// append all other hits
|
|
for (var i = 1; i < content.hits.length; ++i) {
|
|
suggestions.push(content.hits[i]);
|
|
}
|
|
|
|
cb(suggestions, content);
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
cb([]);
|
|
});
|
|
}
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 69 */,
|
|
/* 70 */,
|
|
/* 71 */,
|
|
/* 72 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// we need to export using commonjs for ease of usage in all
|
|
// JavaScript environments
|
|
// We therefore need to import in commonjs too. see:
|
|
// https://github.com/webpack/webpack/issues/4039
|
|
|
|
/* eslint-disable import/no-commonjs */
|
|
var widget = __webpack_require__(73);
|
|
|
|
module.exports = widget["default"];
|
|
/* eslint-enable import/no-commonjs */
|
|
|
|
/***/ }),
|
|
/* 73 */
|
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return makeAlgoliaPlacesWidget; });
|
|
/* harmony import */ var _places__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33);
|
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
|
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
|
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
|
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
|
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
|
|
|
|
|
/**
|
|
* The underlying structure for the Algolia Places instantsearch widget.
|
|
*/
|
|
|
|
var AlgoliaPlacesWidget = /*#__PURE__*/function () {
|
|
function AlgoliaPlacesWidget() {
|
|
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
|
defaultPosition = _ref.defaultPosition,
|
|
placesOptions = _objectWithoutProperties(_ref, ["defaultPosition"]);
|
|
|
|
_classCallCheck(this, AlgoliaPlacesWidget);
|
|
|
|
if (Array.isArray(defaultPosition) && defaultPosition.length === 2) {
|
|
this.defaultPosition = defaultPosition.join(',');
|
|
}
|
|
|
|
this.placesOptions = placesOptions;
|
|
this.placesAutocomplete = Object(_places__WEBPACK_IMPORTED_MODULE_0__["default"])(this.placesOptions);
|
|
this.query = '';
|
|
this.initialLatLngViaIP = null;
|
|
}
|
|
|
|
_createClass(AlgoliaPlacesWidget, [{
|
|
key: "getConfiguration",
|
|
value: function getConfiguration() {
|
|
var configuration = {};
|
|
|
|
if (this.defaultPosition) {
|
|
configuration.insideBoundingBox = undefined;
|
|
configuration.aroundLatLngViaIP = false;
|
|
configuration.aroundLatLng = this.defaultPosition;
|
|
}
|
|
|
|
return configuration;
|
|
}
|
|
}, {
|
|
key: "init",
|
|
value: function init(_ref2) {
|
|
var _this = this;
|
|
|
|
var helper = _ref2.helper;
|
|
|
|
// Get the initial value only when it's not already set via URLSync
|
|
// see: getWidgetSearchParameters
|
|
if (this.initialLatLngViaIP === null) {
|
|
// The value is retrieved in the `init` rather than `getConfiguration`
|
|
// because the widget that set `aroundLatLngViaIP` might be registered
|
|
// after this one. We wait until we have the full configuration to save
|
|
// the initial value.
|
|
this.initialLatLngViaIP = helper.getQueryParameter('aroundLatLngViaIP');
|
|
}
|
|
|
|
this.placesAutocomplete.on('change', function (opts) {
|
|
var _opts$suggestion = opts.suggestion,
|
|
_opts$suggestion$latl = _opts$suggestion.latlng,
|
|
lat = _opts$suggestion$latl.lat,
|
|
lng = _opts$suggestion$latl.lng,
|
|
value = _opts$suggestion.value;
|
|
_this.query = value;
|
|
helper.setQueryParameter('insideBoundingBox').setQueryParameter('aroundLatLngViaIP', false).setQueryParameter('aroundLatLng', "".concat(lat, ",").concat(lng)).search();
|
|
});
|
|
this.placesAutocomplete.on('clear', function () {
|
|
_this.query = '';
|
|
helper.setQueryParameter('insideBoundingBox');
|
|
|
|
if (_this.defaultPosition) {
|
|
helper.setQueryParameter('aroundLatLngViaIP', false).setQueryParameter('aroundLatLng', _this.defaultPosition);
|
|
} else {
|
|
helper.setQueryParameter('aroundLatLngViaIP', _this.initialLatLngViaIP).setQueryParameter('aroundLatLng');
|
|
}
|
|
|
|
helper.search();
|
|
});
|
|
}
|
|
}, {
|
|
key: "getWidgetSearchParameters",
|
|
value: function getWidgetSearchParameters(searchParameters, _ref3) {
|
|
var uiState = _ref3.uiState;
|
|
|
|
if (!uiState.places) {
|
|
this.placesAutocomplete.setVal('');
|
|
this.placesAutocomplete.close();
|
|
return searchParameters;
|
|
}
|
|
|
|
var _uiState$places = uiState.places,
|
|
query = _uiState$places.query,
|
|
position = _uiState$places.position;
|
|
this.query = query;
|
|
this.initialLatLngViaIP = searchParameters.getQueryParameter('aroundLatLngViaIP');
|
|
this.placesAutocomplete.setVal(query || '');
|
|
this.placesAutocomplete.close();
|
|
return searchParameters.setQueryParameter('insideBoundingBox').setQueryParameter('aroundLatLngViaIP', false).setQueryParameter('aroundLatLng', position);
|
|
}
|
|
}, {
|
|
key: "getWidgetState",
|
|
value: function getWidgetState(uiState, _ref4) {
|
|
var searchParameters = _ref4.searchParameters;
|
|
|
|
if (uiState.places && this.query === uiState.places.query && searchParameters.aroundLatLng === uiState.places.position) {
|
|
return uiState;
|
|
}
|
|
|
|
if (searchParameters.aroundLatLng === undefined && !this.query) {
|
|
var newUiState = _objectSpread({}, uiState);
|
|
|
|
delete newUiState.places;
|
|
return newUiState;
|
|
}
|
|
|
|
return _objectSpread(_objectSpread({}, uiState), {}, {
|
|
places: {
|
|
query: this.query,
|
|
position: searchParameters.aroundLatLng
|
|
}
|
|
});
|
|
}
|
|
}]);
|
|
|
|
return AlgoliaPlacesWidget;
|
|
}();
|
|
/**
|
|
* Creates a new instance of the Algolia Places widget. This widget
|
|
* sets the geolocation value for the search based on the selected
|
|
* result in the Algolia Places autocomplete. If the input is cleared,
|
|
* the position is result to the default position.
|
|
* @function
|
|
* @param {object} opts configuration object
|
|
* @param {number[]} opts.defaultPosition=[0,0] default position as an array of the form [lat, lng]
|
|
* @returns {Widget} the algolia places widget
|
|
*/
|
|
|
|
|
|
function makeAlgoliaPlacesWidget(opts) {
|
|
return new AlgoliaPlacesWidget(opts);
|
|
}
|
|
|
|
/***/ })
|
|
/******/ ]);
|
|
});
|
|
//# sourceMappingURL=placesInstantsearchWidget.js.map
|