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.

2268 lines
68 KiB

3 years ago
3 years ago
3 years ago
  1. /******/ (function(modules) { // webpackBootstrap
  2. /******/ // The module cache
  3. /******/ var installedModules = {};
  4. /******/
  5. /******/ // The require function
  6. /******/ function __webpack_require__(moduleId) {
  7. /******/
  8. /******/ // Check if module is in cache
  9. /******/ if(installedModules[moduleId]) {
  10. /******/ return installedModules[moduleId].exports;
  11. /******/ }
  12. /******/ // Create a new module (and put it into the cache)
  13. /******/ var module = installedModules[moduleId] = {
  14. /******/ i: moduleId,
  15. /******/ l: false,
  16. /******/ exports: {}
  17. /******/ };
  18. /******/
  19. /******/ // Execute the module function
  20. /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  21. /******/
  22. /******/ // Flag the module as loaded
  23. /******/ module.l = true;
  24. /******/
  25. /******/ // Return the exports of the module
  26. /******/ return module.exports;
  27. /******/ }
  28. /******/
  29. /******/
  30. /******/ // expose the modules object (__webpack_modules__)
  31. /******/ __webpack_require__.m = modules;
  32. /******/
  33. /******/ // expose the module cache
  34. /******/ __webpack_require__.c = installedModules;
  35. /******/
  36. /******/ // define getter function for harmony exports
  37. /******/ __webpack_require__.d = function(exports, name, getter) {
  38. /******/ if(!__webpack_require__.o(exports, name)) {
  39. /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
  40. /******/ }
  41. /******/ };
  42. /******/
  43. /******/ // define __esModule on exports
  44. /******/ __webpack_require__.r = function(exports) {
  45. /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
  46. /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
  47. /******/ }
  48. /******/ Object.defineProperty(exports, '__esModule', { value: true });
  49. /******/ };
  50. /******/
  51. /******/ // create a fake namespace object
  52. /******/ // mode & 1: value is a module id, require it
  53. /******/ // mode & 2: merge all properties of value into the ns
  54. /******/ // mode & 4: return value when already ns object
  55. /******/ // mode & 8|1: behave like require
  56. /******/ __webpack_require__.t = function(value, mode) {
  57. /******/ if(mode & 1) value = __webpack_require__(value);
  58. /******/ if(mode & 8) return value;
  59. /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
  60. /******/ var ns = Object.create(null);
  61. /******/ __webpack_require__.r(ns);
  62. /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
  63. /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
  64. /******/ return ns;
  65. /******/ };
  66. /******/
  67. /******/ // getDefaultExport function for compatibility with non-harmony modules
  68. /******/ __webpack_require__.n = function(module) {
  69. /******/ var getter = module && module.__esModule ?
  70. /******/ function getDefault() { return module['default']; } :
  71. /******/ function getModuleExports() { return module; };
  72. /******/ __webpack_require__.d(getter, 'a', getter);
  73. /******/ return getter;
  74. /******/ };
  75. /******/
  76. /******/ // Object.prototype.hasOwnProperty.call
  77. /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
  78. /******/
  79. /******/ // __webpack_public_path__
  80. /******/ __webpack_require__.p = "/";
  81. /******/
  82. /******/
  83. /******/ // Load entry module and return exports
  84. /******/ return __webpack_require__(__webpack_require__.s = 2);
  85. /******/ })
  86. /************************************************************************/
  87. /******/ ({
  88. /***/ "./node_modules/@tentakelfabrik/tiny-validator/src/validator.js":
  89. /*!**********************************************************************!*\
  90. !*** ./node_modules/@tentakelfabrik/tiny-validator/src/validator.js ***!
  91. \**********************************************************************/
  92. /*! exports provided: default */
  93. /***/ (function(module, __webpack_exports__, __webpack_require__) {
  94. "use strict";
  95. __webpack_require__.r(__webpack_exports__);
  96. /* harmony import */ var validate_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! validate.js */ "./node_modules/validate.js/validate.js");
  97. /* harmony import */ var validate_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(validate_js__WEBPACK_IMPORTED_MODULE_0__);
  98. /* harmony import */ var form_serialize__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! form-serialize */ "./node_modules/form-serialize/index.js");
  99. /* harmony import */ var form_serialize__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(form_serialize__WEBPACK_IMPORTED_MODULE_1__);
  100. /**
  101. * Validate entire Form or a single Element
  102. *
  103. * Using validator.js
  104. *
  105. * @author Björn Hase, Tentakelfabrik, me@tentakelfabrik.de
  106. *
  107. */
  108. class Validator {
  109. /**
  110. *
  111. * @param {array} rules
  112. */
  113. constructor(rules, component) {
  114. this._rules = rules
  115. this._component = component
  116. this._errors = {
  117. }
  118. }
  119. /**
  120. * handle validation
  121. *
  122. * if key not set,
  123. *
  124. * @param {object} event
  125. * @param {object} key
  126. *
  127. */
  128. handle(event, key) {
  129. event.preventDefault()
  130. let data = null, rules, errors
  131. if (key) {
  132. if (event.target.value) {
  133. data = event.target.value
  134. }
  135. } else {
  136. data = form_serialize__WEBPACK_IMPORTED_MODULE_1___default()(event.target, {
  137. hash: true
  138. })
  139. }
  140. // validate single
  141. if (key) {
  142. rules = this._rules[key]
  143. errors = validate_js__WEBPACK_IMPORTED_MODULE_0___default.a.single(data, rules, {
  144. flat: true
  145. })
  146. if (errors) {
  147. this._errors[key] = errors
  148. } else {
  149. delete this._errors[key]
  150. }
  151. // validate entire form
  152. } else {
  153. this._errors = validate_js__WEBPACK_IMPORTED_MODULE_0___default()(data, this._rules)
  154. }
  155. // update component
  156. this._component.update()
  157. }
  158. /**
  159. *
  160. *
  161. * @param {[type]} key
  162. * @return {[type]}
  163. */
  164. errors(key) {
  165. if (key) {
  166. return this._errors[key]
  167. }
  168. return this._errors
  169. }
  170. }
  171. /* harmony default export */ __webpack_exports__["default"] = (Validator);
  172. /***/ }),
  173. /***/ "./node_modules/form-serialize/index.js":
  174. /*!**********************************************!*\
  175. !*** ./node_modules/form-serialize/index.js ***!
  176. \**********************************************/
  177. /*! no static exports found */
  178. /***/ (function(module, exports) {
  179. // get successful control from form and assemble into object
  180. // http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2
  181. // types which indicate a submit action and are not successful controls
  182. // these will be ignored
  183. var k_r_submitter = /^(?:submit|button|image|reset|file)$/i;
  184. // node names which could be successful controls
  185. var k_r_success_contrls = /^(?:input|select|textarea|keygen)/i;
  186. // Matches bracket notation.
  187. var brackets = /(\[[^\[\]]*\])/g;
  188. // serializes form fields
  189. // @param form MUST be an HTMLForm element
  190. // @param options is an optional argument to configure the serialization. Default output
  191. // with no options specified is a url encoded string
  192. // - hash: [true | false] Configure the output type. If true, the output will
  193. // be a js object.
  194. // - serializer: [function] Optional serializer function to override the default one.
  195. // The function takes 3 arguments (result, key, value) and should return new result
  196. // hash and url encoded str serializers are provided with this module
  197. // - disabled: [true | false]. If true serialize disabled fields.
  198. // - empty: [true | false]. If true serialize empty fields
  199. function serialize(form, options) {
  200. if (typeof options != 'object') {
  201. options = { hash: !!options };
  202. }
  203. else if (options.hash === undefined) {
  204. options.hash = true;
  205. }
  206. var result = (options.hash) ? {} : '';
  207. var serializer = options.serializer || ((options.hash) ? hash_serializer : str_serialize);
  208. var elements = form && form.elements ? form.elements : [];
  209. //Object store each radio and set if it's empty or not
  210. var radio_store = Object.create(null);
  211. for (var i=0 ; i<elements.length ; ++i) {
  212. var element = elements[i];
  213. // ingore disabled fields
  214. if ((!options.disabled && element.disabled) || !element.name) {
  215. continue;
  216. }
  217. // ignore anyhting that is not considered a success field
  218. if (!k_r_success_contrls.test(element.nodeName) ||
  219. k_r_submitter.test(element.type)) {
  220. continue;
  221. }
  222. var key = element.name;
  223. var val = element.value;
  224. // we can't just use element.value for checkboxes cause some browsers lie to us
  225. // they say "on" for value when the box isn't checked
  226. if ((element.type === 'checkbox' || element.type === 'radio') && !element.checked) {
  227. val = undefined;
  228. }
  229. // If we want empty elements
  230. if (options.empty) {
  231. // for checkbox
  232. if (element.type === 'checkbox' && !element.checked) {
  233. val = '';
  234. }
  235. // for radio
  236. if (element.type === 'radio') {
  237. if (!radio_store[element.name] && !element.checked) {
  238. radio_store[element.name] = false;
  239. }
  240. else if (element.checked) {
  241. radio_store[element.name] = true;
  242. }
  243. }
  244. // if options empty is true, continue only if its radio
  245. if (val == undefined && element.type == 'radio') {
  246. continue;
  247. }
  248. }
  249. else {
  250. // value-less fields are ignored unless options.empty is true
  251. if (!val) {
  252. continue;
  253. }
  254. }
  255. // multi select boxes
  256. if (element.type === 'select-multiple') {
  257. val = [];
  258. var selectOptions = element.options;
  259. var isSelectedOptions = false;
  260. for (var j=0 ; j<selectOptions.length ; ++j) {
  261. var option = selectOptions[j];
  262. var allowedEmpty = options.empty && !option.value;
  263. var hasValue = (option.value || allowedEmpty);
  264. if (option.selected && hasValue) {
  265. isSelectedOptions = true;
  266. // If using a hash serializer be sure to add the
  267. // correct notation for an array in the multi-select
  268. // context. Here the name attribute on the select element
  269. // might be missing the trailing bracket pair. Both names
  270. // "foo" and "foo[]" should be arrays.
  271. if (options.hash && key.slice(key.length - 2) !== '[]') {
  272. result = serializer(result, key + '[]', option.value);
  273. }
  274. else {
  275. result = serializer(result, key, option.value);
  276. }
  277. }
  278. }
  279. // Serialize if no selected options and options.empty is true
  280. if (!isSelectedOptions && options.empty) {
  281. result = serializer(result, key, '');
  282. }
  283. continue;
  284. }
  285. result = serializer(result, key, val);
  286. }
  287. // Check for all empty radio buttons and serialize them with key=""
  288. if (options.empty) {
  289. for (var key in radio_store) {
  290. if (!radio_store[key]) {
  291. result = serializer(result, key, '');
  292. }
  293. }
  294. }
  295. return result;
  296. }
  297. function parse_keys(string) {
  298. var keys = [];
  299. var prefix = /^([^\[\]]*)/;
  300. var children = new RegExp(brackets);
  301. var match = prefix.exec(string);
  302. if (match[1]) {
  303. keys.push(match[1]);
  304. }
  305. while ((match = children.exec(string)) !== null) {
  306. keys.push(match[1]);
  307. }
  308. return keys;
  309. }
  310. function hash_assign(result, keys, value) {
  311. if (keys.length === 0) {
  312. result = value;
  313. return result;
  314. }
  315. var key = keys.shift();
  316. var between = key.match(/^\[(.+?)\]$/);
  317. if (key === '[]') {
  318. result = result || [];
  319. if (Array.isArray(result)) {
  320. result.push(hash_assign(null, keys, value));
  321. }
  322. else {
  323. // This might be the result of bad name attributes like "[][foo]",
  324. // in this case the original `result` object will already be
  325. // assigned to an object literal. Rather than coerce the object to
  326. // an array, or cause an exception the attribute "_values" is
  327. // assigned as an array.
  328. result._values = result._values || [];
  329. result._values.push(hash_assign(null, keys, value));
  330. }
  331. return result;
  332. }
  333. // Key is an attribute name and can be assigned directly.
  334. if (!between) {
  335. result[key] = hash_assign(result[key], keys, value);
  336. }
  337. else {
  338. var string = between[1];
  339. // +var converts the variable into a number
  340. // better than parseInt because it doesn't truncate away trailing
  341. // letters and actually fails if whole thing is not a number
  342. var index = +string;
  343. // If the characters between the brackets is not a number it is an
  344. // attribute name and can be assigned directly.
  345. if (isNaN(index)) {
  346. result = result || {};
  347. result[string] = hash_assign(result[string], keys, value);
  348. }
  349. else {
  350. result = result || [];
  351. result[index] = hash_assign(result[index], keys, value);
  352. }
  353. }
  354. return result;
  355. }
  356. // Object/hash encoding serializer.
  357. function hash_serializer(result, key, value) {
  358. var matches = key.match(brackets);
  359. // Has brackets? Use the recursive assignment function to walk the keys,
  360. // construct any missing objects in the result tree and make the assignment
  361. // at the end of the chain.
  362. if (matches) {
  363. var keys = parse_keys(key);
  364. hash_assign(result, keys, value);
  365. }
  366. else {
  367. // Non bracket notation can make assignments directly.
  368. var existing = result[key];
  369. // If the value has been assigned already (for instance when a radio and
  370. // a checkbox have the same name attribute) convert the previous value
  371. // into an array before pushing into it.
  372. //
  373. // NOTE: If this requirement were removed all hash creation and
  374. // assignment could go through `hash_assign`.
  375. if (existing) {
  376. if (!Array.isArray(existing)) {
  377. result[key] = [ existing ];
  378. }
  379. result[key].push(value);
  380. }
  381. else {
  382. result[key] = value;
  383. }
  384. }
  385. return result;
  386. }
  387. // urlform encoding serializer
  388. function str_serialize(result, key, value) {
  389. // encode newlines as \r\n cause the html spec says so
  390. value = value.replace(/(\r)?\n/g, '\r\n');
  391. value = encodeURIComponent(value);
  392. // spaces should be '+' rather than '%20'.
  393. value = value.replace(/%20/g, '+');
  394. return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + value;
  395. }
  396. module.exports = serialize;
  397. /***/ }),
  398. /***/ "./node_modules/validate.js/validate.js":
  399. /*!**********************************************!*\
  400. !*** ./node_modules/validate.js/validate.js ***!
  401. \**********************************************/
  402. /*! no static exports found */
  403. /***/ (function(module, exports, __webpack_require__) {
  404. /* WEBPACK VAR INJECTION */(function(module) {/*!
  405. * validate.js 0.13.1
  406. *
  407. * (c) 2013-2019 Nicklas Ansman, 2013 Wrapp
  408. * Validate.js may be freely distributed under the MIT license.
  409. * For all details and documentation:
  410. * http://validatejs.org/
  411. */
  412. (function(exports, module, define) {
  413. "use strict";
  414. // The main function that calls the validators specified by the constraints.
  415. // The options are the following:
  416. // - format (string) - An option that controls how the returned value is formatted
  417. // * flat - Returns a flat array of just the error messages
  418. // * grouped - Returns the messages grouped by attribute (default)
  419. // * detailed - Returns an array of the raw validation data
  420. // - fullMessages (boolean) - If `true` (default) the attribute name is prepended to the error.
  421. //
  422. // Please note that the options are also passed to each validator.
  423. var validate = function(attributes, constraints, options) {
  424. options = v.extend({}, v.options, options);
  425. var results = v.runValidations(attributes, constraints, options)
  426. , attr
  427. , validator;
  428. if (results.some(function(r) { return v.isPromise(r.error); })) {
  429. throw new Error("Use validate.async if you want support for promises");
  430. }
  431. return validate.processValidationResults(results, options);
  432. };
  433. var v = validate;
  434. // Copies over attributes from one or more sources to a single destination.
  435. // Very much similar to underscore's extend.
  436. // The first argument is the target object and the remaining arguments will be
  437. // used as sources.
  438. v.extend = function(obj) {
  439. [].slice.call(arguments, 1).forEach(function(source) {
  440. for (var attr in source) {
  441. obj[attr] = source[attr];
  442. }
  443. });
  444. return obj;
  445. };
  446. v.extend(validate, {
  447. // This is the version of the library as a semver.
  448. // The toString function will allow it to be coerced into a string
  449. version: {
  450. major: 0,
  451. minor: 13,
  452. patch: 1,
  453. metadata: null,
  454. toString: function() {
  455. var version = v.format("%{major}.%{minor}.%{patch}", v.version);
  456. if (!v.isEmpty(v.version.metadata)) {
  457. version += "+" + v.version.metadata;
  458. }
  459. return version;
  460. }
  461. },
  462. // Below is the dependencies that are used in validate.js
  463. // The constructor of the Promise implementation.
  464. // If you are using Q.js, RSVP or any other A+ compatible implementation
  465. // override this attribute to be the constructor of that promise.
  466. // Since jQuery promises aren't A+ compatible they won't work.
  467. Promise: typeof Promise !== "undefined" ? Promise : /* istanbul ignore next */ null,
  468. EMPTY_STRING_REGEXP: /^\s*$/,
  469. // Runs the validators specified by the constraints object.
  470. // Will return an array of the format:
  471. // [{attribute: "<attribute name>", error: "<validation result>"}, ...]
  472. runValidations: function(attributes, constraints, options) {
  473. var results = []
  474. , attr
  475. , validatorName
  476. , value
  477. , validators
  478. , validator
  479. , validatorOptions
  480. , error;
  481. if (v.isDomElement(attributes) || v.isJqueryElement(attributes)) {
  482. attributes = v.collectFormValues(attributes);
  483. }
  484. // Loops through each constraints, finds the correct validator and run it.
  485. for (attr in constraints) {
  486. value = v.getDeepObjectValue(attributes, attr);
  487. // This allows the constraints for an attribute to be a function.
  488. // The function will be called with the value, attribute name, the complete dict of
  489. // attributes as well as the options and constraints passed in.
  490. // This is useful when you want to have different
  491. // validations depending on the attribute value.
  492. validators = v.result(constraints[attr], value, attributes, attr, options, constraints);
  493. for (validatorName in validators) {
  494. validator = v.validators[validatorName];
  495. if (!validator) {
  496. error = v.format("Unknown validator %{name}", {name: validatorName});
  497. throw new Error(error);
  498. }
  499. validatorOptions = validators[validatorName];
  500. // This allows the options to be a function. The function will be
  501. // called with the value, attribute name, the complete dict of
  502. // attributes as well as the options and constraints passed in.
  503. // This is useful when you want to have different
  504. // validations depending on the attribute value.
  505. validatorOptions = v.result(validatorOptions, value, attributes, attr, options, constraints);
  506. if (!validatorOptions) {
  507. continue;
  508. }
  509. results.push({
  510. attribute: attr,
  511. value: value,
  512. validator: validatorName,
  513. globalOptions: options,
  514. attributes: attributes,
  515. options: validatorOptions,
  516. error: validator.call(validator,
  517. value,
  518. validatorOptions,
  519. attr,
  520. attributes,
  521. options)
  522. });
  523. }
  524. }
  525. return results;
  526. },
  527. // Takes the output from runValidations and converts it to the correct
  528. // output format.
  529. processValidationResults: function(errors, options) {
  530. errors = v.pruneEmptyErrors(errors, options);
  531. errors = v.expandMultipleErrors(errors, options);
  532. errors = v.convertErrorMessages(errors, options);
  533. var format = options.format || "grouped";
  534. if (typeof v.formatters[format] === 'function') {
  535. errors = v.formatters[format](errors);
  536. } else {
  537. throw new Error(v.format("Unknown format %{format}", options));
  538. }
  539. return v.isEmpty(errors) ? undefined : errors;
  540. },
  541. // Runs the validations with support for promises.
  542. // This function will return a promise that is settled when all the
  543. // validation promises have been completed.
  544. // It can be called even if no validations returned a promise.
  545. async: function(attributes, constraints, options) {
  546. options = v.extend({}, v.async.options, options);
  547. var WrapErrors = options.wrapErrors || function(errors) {
  548. return errors;
  549. };
  550. // Removes unknown attributes
  551. if (options.cleanAttributes !== false) {
  552. attributes = v.cleanAttributes(attributes, constraints);
  553. }
  554. var results = v.runValidations(attributes, constraints, options);
  555. return new v.Promise(function(resolve, reject) {
  556. v.waitForResults(results).then(function() {
  557. var errors = v.processValidationResults(results, options);
  558. if (errors) {
  559. reject(new WrapErrors(errors, options, attributes, constraints));
  560. } else {
  561. resolve(attributes);
  562. }
  563. }, function(err) {
  564. reject(err);
  565. });
  566. });
  567. },
  568. single: function(value, constraints, options) {
  569. options = v.extend({}, v.single.options, options, {
  570. format: "flat",
  571. fullMessages: false
  572. });
  573. return v({single: value}, {single: constraints}, options);
  574. },
  575. // Returns a promise that is resolved when all promises in the results array
  576. // are settled. The promise returned from this function is always resolved,
  577. // never rejected.
  578. // This function modifies the input argument, it replaces the promises
  579. // with the value returned from the promise.
  580. waitForResults: function(results) {
  581. // Create a sequence of all the results starting with a resolved promise.
  582. return results.reduce(function(memo, result) {
  583. // If this result isn't a promise skip it in the sequence.
  584. if (!v.isPromise(result.error)) {
  585. return memo;
  586. }
  587. return memo.then(function() {
  588. return result.error.then(function(error) {
  589. result.error = error || null;
  590. });
  591. });
  592. }, new v.Promise(function(r) { r(); })); // A resolved promise
  593. },
  594. // If the given argument is a call: function the and: function return the value
  595. // otherwise just return the value. Additional arguments will be passed as
  596. // arguments to the function.
  597. // Example:
  598. // ```
  599. // result('foo') // 'foo'
  600. // result(Math.max, 1, 2) // 2
  601. // ```
  602. result: function(value) {
  603. var args = [].slice.call(arguments, 1);
  604. if (typeof value === 'function') {
  605. value = value.apply(null, args);
  606. }
  607. return value;
  608. },
  609. // Checks if the value is a number. This function does not consider NaN a
  610. // number like many other `isNumber` functions do.
  611. isNumber: function(value) {
  612. return typeof value === 'number' && !isNaN(value);
  613. },
  614. // Returns false if the object is not a function
  615. isFunction: function(value) {
  616. return typeof value === 'function';
  617. },
  618. // A simple check to verify that the value is an integer. Uses `isNumber`
  619. // and a simple modulo check.
  620. isInteger: function(value) {
  621. return v.isNumber(value) && value % 1 === 0;
  622. },
  623. // Checks if the value is a boolean
  624. isBoolean: function(value) {
  625. return typeof value === 'boolean';
  626. },
  627. // Uses the `Object` function to check if the given argument is an object.
  628. isObject: function(obj) {
  629. return obj === Object(obj);
  630. },
  631. // Simply checks if the object is an instance of a date
  632. isDate: function(obj) {
  633. return obj instanceof Date;
  634. },
  635. // Returns false if the object is `null` of `undefined`
  636. isDefined: function(obj) {
  637. return obj !== null && obj !== undefined;
  638. },
  639. // Checks if the given argument is a promise. Anything with a `then`
  640. // function is considered a promise.
  641. isPromise: function(p) {
  642. return !!p && v.isFunction(p.then);
  643. },
  644. isJqueryElement: function(o) {
  645. return o && v.isString(o.jquery);
  646. },
  647. isDomElement: function(o) {
  648. if (!o) {
  649. return false;
  650. }
  651. if (!o.querySelectorAll || !o.querySelector) {
  652. return false;
  653. }
  654. if (v.isObject(document) && o === document) {
  655. return true;
  656. }
  657. // http://stackoverflow.com/a/384380/699304
  658. /* istanbul ignore else */
  659. if (typeof HTMLElement === "object") {
  660. return o instanceof HTMLElement;
  661. } else {
  662. return o &&
  663. typeof o === "object" &&
  664. o !== null &&
  665. o.nodeType === 1 &&
  666. typeof o.nodeName === "string";
  667. }
  668. },
  669. isEmpty: function(value) {
  670. var attr;
  671. // Null and undefined are empty
  672. if (!v.isDefined(value)) {
  673. return true;
  674. }
  675. // functions are non empty
  676. if (v.isFunction(value)) {
  677. return false;
  678. }
  679. // Whitespace only strings are empty
  680. if (v.isString(value)) {
  681. return v.EMPTY_STRING_REGEXP.test(value);
  682. }
  683. // For arrays we use the length property
  684. if (v.isArray(value)) {
  685. return value.length === 0;
  686. }
  687. // Dates have no attributes but aren't empty
  688. if (v.isDate(value)) {
  689. return false;
  690. }
  691. // If we find at least one property we consider it non empty
  692. if (v.isObject(value)) {
  693. for (attr in value) {
  694. return false;
  695. }
  696. return true;
  697. }
  698. return false;
  699. },
  700. // Formats the specified strings with the given values like so:
  701. // ```
  702. // format("Foo: %{foo}", {foo: "bar"}) // "Foo bar"
  703. // ```
  704. // If you want to write %{...} without having it replaced simply
  705. // prefix it with % like this `Foo: %%{foo}` and it will be returned
  706. // as `"Foo: %{foo}"`
  707. format: v.extend(function(str, vals) {
  708. if (!v.isString(str)) {
  709. return str;
  710. }
  711. return str.replace(v.format.FORMAT_REGEXP, function(m0, m1, m2) {
  712. if (m1 === '%') {
  713. return "%{" + m2 + "}";
  714. } else {
  715. return String(vals[m2]);
  716. }
  717. });
  718. }, {
  719. // Finds %{key} style patterns in the given string
  720. FORMAT_REGEXP: /(%?)%\{([^\}]+)\}/g
  721. }),
  722. // "Prettifies" the given string.
  723. // Prettifying means replacing [.\_-] with spaces as well as splitting
  724. // camel case words.
  725. prettify: function(str) {
  726. if (v.isNumber(str)) {
  727. // If there are more than 2 decimals round it to two
  728. if ((str * 100) % 1 === 0) {
  729. return "" + str;
  730. } else {
  731. return parseFloat(Math.round(str * 100) / 100).toFixed(2);
  732. }
  733. }
  734. if (v.isArray(str)) {
  735. return str.map(function(s) { return v.prettify(s); }).join(", ");
  736. }
  737. if (v.isObject(str)) {
  738. if (!v.isDefined(str.toString)) {
  739. return JSON.stringify(str);
  740. }
  741. return str.toString();
  742. }
  743. // Ensure the string is actually a string
  744. str = "" + str;
  745. return str
  746. // Splits keys separated by periods
  747. .replace(/([^\s])\.([^\s])/g, '$1 $2')
  748. // Removes backslashes
  749. .replace(/\\+/g, '')
  750. // Replaces - and - with space
  751. .replace(/[_-]/g, ' ')
  752. // Splits camel cased words
  753. .replace(/([a-z])([A-Z])/g, function(m0, m1, m2) {
  754. return "" + m1 + " " + m2.toLowerCase();
  755. })
  756. .toLowerCase();
  757. },
  758. stringifyValue: function(value, options) {
  759. var prettify = options && options.prettify || v.prettify;
  760. return prettify(value);
  761. },
  762. isString: function(value) {
  763. return typeof value === 'string';
  764. },
  765. isArray: function(value) {
  766. return {}.toString.call(value) === '[object Array]';
  767. },
  768. // Checks if the object is a hash, which is equivalent to an object that
  769. // is neither an array nor a function.
  770. isHash: function(value) {
  771. return v.isObject(value) && !v.isArray(value) && !v.isFunction(value);
  772. },
  773. contains: function(obj, value) {
  774. if (!v.isDefined(obj)) {
  775. return false;
  776. }
  777. if (v.isArray(obj)) {
  778. return obj.indexOf(value) !== -1;
  779. }
  780. return value in obj;
  781. },
  782. unique: function(array) {
  783. if (!v.isArray(array)) {
  784. return array;
  785. }
  786. return array.filter(function(el, index, array) {
  787. return array.indexOf(el) == index;
  788. });
  789. },
  790. forEachKeyInKeypath: function(object, keypath, callback) {
  791. if (!v.isString(keypath)) {
  792. return undefined;
  793. }
  794. var key = ""
  795. , i
  796. , escape = false;
  797. for (i = 0; i < keypath.length; ++i) {
  798. switch (keypath[i]) {
  799. case '.':
  800. if (escape) {
  801. escape = false;
  802. key += '.';
  803. } else {
  804. object = callback(object, key, false);
  805. key = "";
  806. }
  807. break;
  808. case '\\':
  809. if (escape) {
  810. escape = false;
  811. key += '\\';
  812. } else {
  813. escape = true;
  814. }
  815. break;
  816. default:
  817. escape = false;
  818. key += keypath[i];
  819. break;
  820. }
  821. }
  822. return callback(object, key, true);
  823. },
  824. getDeepObjectValue: function(obj, keypath) {
  825. if (!v.isObject(obj)) {
  826. return undefined;
  827. }
  828. return v.forEachKeyInKeypath(obj, keypath, function(obj, key) {
  829. if (v.isObject(obj)) {
  830. return obj[key];
  831. }
  832. });
  833. },
  834. // This returns an object with all the values of the form.
  835. // It uses the input name as key and the value as value
  836. // So for example this:
  837. // <input type="text" name="email" value="foo@bar.com" />
  838. // would return:
  839. // {email: "foo@bar.com"}
  840. collectFormValues: function(form, options) {
  841. var values = {}
  842. , i
  843. , j
  844. , input
  845. , inputs
  846. , option
  847. , value;
  848. if (v.isJqueryElement(form)) {
  849. form = form[0];
  850. }
  851. if (!form) {
  852. return values;
  853. }
  854. options = options || {};
  855. inputs = form.querySelectorAll("input[name], textarea[name]");
  856. for (i = 0; i < inputs.length; ++i) {
  857. input = inputs.item(i);
  858. if (v.isDefined(input.getAttribute("data-ignored"))) {
  859. continue;
  860. }
  861. var name = input.name.replace(/\./g, "\\\\.");
  862. value = v.sanitizeFormValue(input.value, options);
  863. if (input.type === "number") {
  864. value = value ? +value : null;
  865. } else if (input.type === "checkbox") {
  866. if (input.attributes.value) {
  867. if (!input.checked) {
  868. value = values[name] || null;
  869. }
  870. } else {
  871. value = input.checked;
  872. }
  873. } else if (input.type === "radio") {
  874. if (!input.checked) {
  875. value = values[name] || null;
  876. }
  877. }
  878. values[name] = value;
  879. }
  880. inputs = form.querySelectorAll("select[name]");
  881. for (i = 0; i < inputs.length; ++i) {
  882. input = inputs.item(i);
  883. if (v.isDefined(input.getAttribute("data-ignored"))) {
  884. continue;
  885. }
  886. if (input.multiple) {
  887. value = [];
  888. for (j in input.options) {
  889. option = input.options[j];
  890. if (option && option.selected) {
  891. value.push(v.sanitizeFormValue(option.value, options));
  892. }
  893. }
  894. } else {
  895. var _val = typeof input.options[input.selectedIndex] !== 'undefined' ? input.options[input.selectedIndex].value : /* istanbul ignore next */ '';
  896. value = v.sanitizeFormValue(_val, options);
  897. }
  898. values[input.name] = value;
  899. }
  900. return values;
  901. },
  902. sanitizeFormValue: function(value, options) {
  903. if (options.trim && v.isString(value)) {
  904. value = value.trim();
  905. }
  906. if (options.nullify !== false && value === "") {
  907. return null;
  908. }
  909. return value;
  910. },
  911. capitalize: function(str) {
  912. if (!v.isString(str)) {
  913. return str;
  914. }
  915. return str[0].toUpperCase() + str.slice(1);
  916. },
  917. // Remove all errors who's error attribute is empty (null or undefined)
  918. pruneEmptyErrors: function(errors) {
  919. return errors.filter(function(error) {
  920. return !v.isEmpty(error.error);
  921. });
  922. },
  923. // In
  924. // [{error: ["err1", "err2"], ...}]
  925. // Out
  926. // [{error: "err1", ...}, {error: "err2", ...}]
  927. //
  928. // All attributes in an error with multiple messages are duplicated
  929. // when expanding the errors.
  930. expandMultipleErrors: function(errors) {
  931. var ret = [];
  932. errors.forEach(function(error) {
  933. // Removes errors without a message
  934. if (v.isArray(error.error)) {
  935. error.error.forEach(function(msg) {
  936. ret.push(v.extend({}, error, {error: msg}));
  937. });
  938. } else {
  939. ret.push(error);
  940. }
  941. });
  942. return ret;
  943. },
  944. // Converts the error mesages by prepending the attribute name unless the
  945. // message is prefixed by ^
  946. convertErrorMessages: function(errors, options) {
  947. options = options || {};
  948. var ret = []
  949. , prettify = options.prettify || v.prettify;
  950. errors.forEach(function(errorInfo) {
  951. var error = v.result(errorInfo.error,
  952. errorInfo.value,
  953. errorInfo.attribute,
  954. errorInfo.options,
  955. errorInfo.attributes,
  956. errorInfo.globalOptions);
  957. if (!v.isString(error)) {
  958. ret.push(errorInfo);
  959. return;
  960. }
  961. if (error[0] === '^') {
  962. error = error.slice(1);
  963. } else if (options.fullMessages !== false) {
  964. error = v.capitalize(prettify(errorInfo.attribute)) + " " + error;
  965. }
  966. error = error.replace(/\\\^/g, "^");
  967. error = v.format(error, {
  968. value: v.stringifyValue(errorInfo.value, options)
  969. });
  970. ret.push(v.extend({}, errorInfo, {error: error}));
  971. });
  972. return ret;
  973. },
  974. // In:
  975. // [{attribute: "<attributeName>", ...}]
  976. // Out:
  977. // {"<attributeName>": [{attribute: "<attributeName>", ...}]}
  978. groupErrorsByAttribute: function(errors) {
  979. var ret = {};
  980. errors.forEach(function(error) {
  981. var list = ret[error.attribute];
  982. if (list) {
  983. list.push(error);
  984. } else {
  985. ret[error.attribute] = [error];
  986. }
  987. });
  988. return ret;
  989. },
  990. // In:
  991. // [{error: "<message 1>", ...}, {error: "<message 2>", ...}]
  992. // Out:
  993. // ["<message 1>", "<message 2>"]
  994. flattenErrorsToArray: function(errors) {
  995. return errors
  996. .map(function(error) { return error.error; })
  997. .filter(function(value, index, self) {
  998. return self.indexOf(value) === index;
  999. });
  1000. },
  1001. cleanAttributes: function(attributes, whitelist) {
  1002. function whitelistCreator(obj, key, last) {
  1003. if (v.isObject(obj[key])) {
  1004. return obj[key];
  1005. }
  1006. return (obj[key] = last ? true : {});
  1007. }
  1008. function buildObjectWhitelist(whitelist) {
  1009. var ow = {}
  1010. , lastObject
  1011. , attr;
  1012. for (attr in whitelist) {
  1013. if (!whitelist[attr]) {
  1014. continue;
  1015. }
  1016. v.forEachKeyInKeypath(ow, attr, whitelistCreator);
  1017. }
  1018. return ow;
  1019. }
  1020. function cleanRecursive(attributes, whitelist) {
  1021. if (!v.isObject(attributes)) {
  1022. return attributes;
  1023. }
  1024. var ret = v.extend({}, attributes)
  1025. , w
  1026. , attribute;
  1027. for (attribute in attributes) {
  1028. w = whitelist[attribute];
  1029. if (v.isObject(w)) {
  1030. ret[attribute] = cleanRecursive(ret[attribute], w);
  1031. } else if (!w) {
  1032. delete ret[attribute];
  1033. }
  1034. }
  1035. return ret;
  1036. }
  1037. if (!v.isObject(whitelist) || !v.isObject(attributes)) {
  1038. return {};
  1039. }
  1040. whitelist = buildObjectWhitelist(whitelist);
  1041. return cleanRecursive(attributes, whitelist);
  1042. },
  1043. exposeModule: function(validate, root, exports, module, define) {
  1044. if (exports) {
  1045. if (module && module.exports) {
  1046. exports = module.exports = validate;
  1047. }
  1048. exports.validate = validate;
  1049. } else {
  1050. root.validate = validate;
  1051. if (validate.isFunction(define) && define.amd) {
  1052. define([], function () { return validate; });
  1053. }
  1054. }
  1055. },
  1056. warn: function(msg) {
  1057. if (typeof console !== "undefined" && console.warn) {
  1058. console.warn("[validate.js] " + msg);
  1059. }
  1060. },
  1061. error: function(msg) {
  1062. if (typeof console !== "undefined" && console.error) {
  1063. console.error("[validate.js] " + msg);
  1064. }
  1065. }
  1066. });
  1067. validate.validators = {
  1068. // Presence validates that the value isn't empty
  1069. presence: function(value, options) {
  1070. options = v.extend({}, this.options, options);
  1071. if (options.allowEmpty !== false ? !v.isDefined(value) : v.isEmpty(value)) {
  1072. return options.message || this.message || "can't be blank";
  1073. }
  1074. },
  1075. length: function(value, options, attribute) {
  1076. // Empty values are allowed
  1077. if (!v.isDefined(value)) {
  1078. return;
  1079. }
  1080. options = v.extend({}, this.options, options);
  1081. var is = options.is
  1082. , maximum = options.maximum
  1083. , minimum = options.minimum
  1084. , tokenizer = options.tokenizer || function(val) { return val; }
  1085. , err
  1086. , errors = [];
  1087. value = tokenizer(value);
  1088. var length = value.length;
  1089. if(!v.isNumber(length)) {
  1090. return options.message || this.notValid || "has an incorrect length";
  1091. }
  1092. // Is checks
  1093. if (v.isNumber(is) && length !== is) {
  1094. err = options.wrongLength ||
  1095. this.wrongLength ||
  1096. "is the wrong length (should be %{count} characters)";
  1097. errors.push(v.format(err, {count: is}));
  1098. }
  1099. if (v.isNumber(minimum) && length < minimum) {
  1100. err = options.tooShort ||
  1101. this.tooShort ||
  1102. "is too short (minimum is %{count} characters)";
  1103. errors.push(v.format(err, {count: minimum}));
  1104. }
  1105. if (v.isNumber(maximum) && length > maximum) {
  1106. err = options.tooLong ||
  1107. this.tooLong ||
  1108. "is too long (maximum is %{count} characters)";
  1109. errors.push(v.format(err, {count: maximum}));
  1110. }
  1111. if (errors.length > 0) {
  1112. return options.message || errors;
  1113. }
  1114. },
  1115. numericality: function(value, options, attribute, attributes, globalOptions) {
  1116. // Empty values are fine
  1117. if (!v.isDefined(value)) {
  1118. return;
  1119. }
  1120. options = v.extend({}, this.options, options);
  1121. var errors = []
  1122. , name
  1123. , count
  1124. , checks = {
  1125. greaterThan: function(v, c) { return v > c; },
  1126. greaterThanOrEqualTo: function(v, c) { return v >= c; },
  1127. equalTo: function(v, c) { return v === c; },
  1128. lessThan: function(v, c) { return v < c; },
  1129. lessThanOrEqualTo: function(v, c) { return v <= c; },
  1130. divisibleBy: function(v, c) { return v % c === 0; }
  1131. }
  1132. , prettify = options.prettify ||
  1133. (globalOptions && globalOptions.prettify) ||
  1134. v.prettify;
  1135. // Strict will check that it is a valid looking number
  1136. if (v.isString(value) && options.strict) {
  1137. var pattern = "^-?(0|[1-9]\\d*)";
  1138. if (!options.onlyInteger) {
  1139. pattern += "(\\.\\d+)?";
  1140. }
  1141. pattern += "$";
  1142. if (!(new RegExp(pattern).test(value))) {
  1143. return options.message ||
  1144. options.notValid ||
  1145. this.notValid ||
  1146. this.message ||
  1147. "must be a valid number";
  1148. }
  1149. }
  1150. // Coerce the value to a number unless we're being strict.
  1151. if (options.noStrings !== true && v.isString(value) && !v.isEmpty(value)) {
  1152. value = +value;
  1153. }
  1154. // If it's not a number we shouldn't continue since it will compare it.
  1155. if (!v.isNumber(value)) {
  1156. return options.message ||
  1157. options.notValid ||
  1158. this.notValid ||
  1159. this.message ||
  1160. "is not a number";
  1161. }
  1162. // Same logic as above, sort of. Don't bother with comparisons if this
  1163. // doesn't pass.
  1164. if (options.onlyInteger && !v.isInteger(value)) {
  1165. return options.message ||
  1166. options.notInteger ||
  1167. this.notInteger ||
  1168. this.message ||
  1169. "must be an integer";
  1170. }
  1171. for (name in checks) {
  1172. count = options[name];
  1173. if (v.isNumber(count) && !checks[name](value, count)) {
  1174. // This picks the default message if specified
  1175. // For example the greaterThan check uses the message from
  1176. // this.notGreaterThan so we capitalize the name and prepend "not"
  1177. var key = "not" + v.capitalize(name);
  1178. var msg = options[key] ||
  1179. this[key] ||
  1180. this.message ||
  1181. "must be %{type} %{count}";
  1182. errors.push(v.format(msg, {
  1183. count: count,
  1184. type: prettify(name)
  1185. }));
  1186. }
  1187. }
  1188. if (options.odd && value % 2 !== 1) {
  1189. errors.push(options.notOdd ||
  1190. this.notOdd ||
  1191. this.message ||
  1192. "must be odd");
  1193. }
  1194. if (options.even && value % 2 !== 0) {
  1195. errors.push(options.notEven ||
  1196. this.notEven ||
  1197. this.message ||
  1198. "must be even");
  1199. }
  1200. if (errors.length) {
  1201. return options.message || errors;
  1202. }
  1203. },
  1204. datetime: v.extend(function(value, options) {
  1205. if (!v.isFunction(this.parse) || !v.isFunction(this.format)) {
  1206. throw new Error("Both the parse and format functions needs to be set to use the datetime/date validator");
  1207. }
  1208. // Empty values are fine
  1209. if (!v.isDefined(value)) {
  1210. return;
  1211. }
  1212. options = v.extend({}, this.options, options);
  1213. var err
  1214. , errors = []
  1215. , earliest = options.earliest ? this.parse(options.earliest, options) : NaN
  1216. , latest = options.latest ? this.parse(options.latest, options) : NaN;
  1217. value = this.parse(value, options);
  1218. // 86400000 is the number of milliseconds in a day, this is used to remove
  1219. // the time from the date
  1220. if (isNaN(value) || options.dateOnly && value % 86400000 !== 0) {
  1221. err = options.notValid ||
  1222. options.message ||
  1223. this.notValid ||
  1224. "must be a valid date";
  1225. return v.format(err, {value: arguments[0]});
  1226. }
  1227. if (!isNaN(earliest) && value < earliest) {
  1228. err = options.tooEarly ||
  1229. options.message ||
  1230. this.tooEarly ||
  1231. "must be no earlier than %{date}";
  1232. err = v.format(err, {
  1233. value: this.format(value, options),
  1234. date: this.format(earliest, options)
  1235. });
  1236. errors.push(err);
  1237. }
  1238. if (!isNaN(latest) && value > latest) {
  1239. err = options.tooLate ||
  1240. options.message ||
  1241. this.tooLate ||
  1242. "must be no later than %{date}";
  1243. err = v.format(err, {
  1244. date: this.format(latest, options),
  1245. value: this.format(value, options)
  1246. });
  1247. errors.push(err);
  1248. }
  1249. if (errors.length) {
  1250. return v.unique(errors);
  1251. }
  1252. }, {
  1253. parse: null,
  1254. format: null
  1255. }),
  1256. date: function(value, options) {
  1257. options = v.extend({}, options, {dateOnly: true});
  1258. return v.validators.datetime.call(v.validators.datetime, value, options);
  1259. },
  1260. format: function(value, options) {
  1261. if (v.isString(options) || (options instanceof RegExp)) {
  1262. options = {pattern: options};
  1263. }
  1264. options = v.extend({}, this.options, options);
  1265. var message = options.message || this.message || "is invalid"
  1266. , pattern = options.pattern
  1267. , match;
  1268. // Empty values are allowed
  1269. if (!v.isDefined(value)) {
  1270. return;
  1271. }
  1272. if (!v.isString(value)) {
  1273. return message;
  1274. }
  1275. if (v.isString(pattern)) {
  1276. pattern = new RegExp(options.pattern, options.flags);
  1277. }
  1278. match = pattern.exec(value);
  1279. if (!match || match[0].length != value.length) {
  1280. return message;
  1281. }
  1282. },
  1283. inclusion: function(value, options) {
  1284. // Empty values are fine
  1285. if (!v.isDefined(value)) {
  1286. return;
  1287. }
  1288. if (v.isArray(options)) {
  1289. options = {within: options};
  1290. }
  1291. options = v.extend({}, this.options, options);
  1292. if (v.contains(options.within, value)) {
  1293. return;
  1294. }
  1295. var message = options.message ||
  1296. this.message ||
  1297. "^%{value} is not included in the list";
  1298. return v.format(message, {value: value});
  1299. },
  1300. exclusion: function(value, options) {
  1301. // Empty values are fine
  1302. if (!v.isDefined(value)) {
  1303. return;
  1304. }
  1305. if (v.isArray(options)) {
  1306. options = {within: options};
  1307. }
  1308. options = v.extend({}, this.options, options);
  1309. if (!v.contains(options.within, value)) {
  1310. return;
  1311. }
  1312. var message = options.message || this.message || "^%{value} is restricted";
  1313. if (v.isString(options.within[value])) {
  1314. value = options.within[value];
  1315. }
  1316. return v.format(message, {value: value});
  1317. },
  1318. email: v.extend(function(value, options) {
  1319. options = v.extend({}, this.options, options);
  1320. var message = options.message || this.message || "is not a valid email";
  1321. // Empty values are fine
  1322. if (!v.isDefined(value)) {
  1323. return;
  1324. }
  1325. if (!v.isString(value)) {
  1326. return message;
  1327. }
  1328. if (!this.PATTERN.exec(value)) {
  1329. return message;
  1330. }
  1331. }, {
  1332. PATTERN: /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/i
  1333. }),
  1334. equality: function(value, options, attribute, attributes, globalOptions) {
  1335. if (!v.isDefined(value)) {
  1336. return;
  1337. }
  1338. if (v.isString(options)) {
  1339. options = {attribute: options};
  1340. }
  1341. options = v.extend({}, this.options, options);
  1342. var message = options.message ||
  1343. this.message ||
  1344. "is not equal to %{attribute}";
  1345. if (v.isEmpty(options.attribute) || !v.isString(options.attribute)) {
  1346. throw new Error("The attribute must be a non empty string");
  1347. }
  1348. var otherValue = v.getDeepObjectValue(attributes, options.attribute)
  1349. , comparator = options.comparator || function(v1, v2) {
  1350. return v1 === v2;
  1351. }
  1352. , prettify = options.prettify ||
  1353. (globalOptions && globalOptions.prettify) ||
  1354. v.prettify;
  1355. if (!comparator(value, otherValue, options, attribute, attributes)) {
  1356. return v.format(message, {attribute: prettify(options.attribute)});
  1357. }
  1358. },
  1359. // A URL validator that is used to validate URLs with the ability to
  1360. // restrict schemes and some domains.
  1361. url: function(value, options) {
  1362. if (!v.isDefined(value)) {
  1363. return;
  1364. }
  1365. options = v.extend({}, this.options, options);
  1366. var message = options.message || this.message || "is not a valid url"
  1367. , schemes = options.schemes || this.schemes || ['http', 'https']
  1368. , allowLocal = options.allowLocal || this.allowLocal || false
  1369. , allowDataUrl = options.allowDataUrl || this.allowDataUrl || false;
  1370. if (!v.isString(value)) {
  1371. return message;
  1372. }
  1373. // https://gist.github.com/dperini/729294
  1374. var regex =
  1375. "^" +
  1376. // protocol identifier
  1377. "(?:(?:" + schemes.join("|") + ")://)" +
  1378. // user:pass authentication
  1379. "(?:\\S+(?::\\S*)?@)?" +
  1380. "(?:";
  1381. var tld = "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))";
  1382. if (allowLocal) {
  1383. tld += "?";
  1384. } else {
  1385. regex +=
  1386. // IP address exclusion
  1387. // private & local networks
  1388. "(?!(?:10|127)(?:\\.\\d{1,3}){3})" +
  1389. "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +
  1390. "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})";
  1391. }
  1392. regex +=
  1393. // IP address dotted notation octets
  1394. // excludes loopback network 0.0.0.0
  1395. // excludes reserved space >= 224.0.0.0
  1396. // excludes network & broacast addresses
  1397. // (first & last IP address of each class)
  1398. "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
  1399. "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
  1400. "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
  1401. "|" +
  1402. // host name
  1403. "(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)" +
  1404. // domain name
  1405. "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*" +
  1406. tld +
  1407. ")" +
  1408. // port number
  1409. "(?::\\d{2,5})?" +
  1410. // resource path
  1411. "(?:[/?#]\\S*)?" +
  1412. "$";
  1413. if (allowDataUrl) {
  1414. // RFC 2397
  1415. var mediaType = "\\w+\\/[-+.\\w]+(?:;[\\w=]+)*";
  1416. var urlchar = "[A-Za-z0-9-_.!~\\*'();\\/?:@&=+$,%]*";
  1417. var dataurl = "data:(?:"+mediaType+")?(?:;base64)?,"+urlchar;
  1418. regex = "(?:"+regex+")|(?:^"+dataurl+"$)";
  1419. }
  1420. var PATTERN = new RegExp(regex, 'i');
  1421. if (!PATTERN.exec(value)) {
  1422. return message;
  1423. }
  1424. },
  1425. type: v.extend(function(value, originalOptions, attribute, attributes, globalOptions) {
  1426. if (v.isString(originalOptions)) {
  1427. originalOptions = {type: originalOptions};
  1428. }
  1429. if (!v.isDefined(value)) {
  1430. return;
  1431. }
  1432. var options = v.extend({}, this.options, originalOptions);
  1433. var type = options.type;
  1434. if (!v.isDefined(type)) {
  1435. throw new Error("No type was specified");
  1436. }
  1437. var check;
  1438. if (v.isFunction(type)) {
  1439. check = type;
  1440. } else {
  1441. check = this.types[type];
  1442. }
  1443. if (!v.isFunction(check)) {
  1444. throw new Error("validate.validators.type.types." + type + " must be a function.");
  1445. }
  1446. if (!check(value, options, attribute, attributes, globalOptions)) {
  1447. var message = originalOptions.message ||
  1448. this.messages[type] ||
  1449. this.message ||
  1450. options.message ||
  1451. (v.isFunction(type) ? "must be of the correct type" : "must be of type %{type}");
  1452. if (v.isFunction(message)) {
  1453. message = message(value, originalOptions, attribute, attributes, globalOptions);
  1454. }
  1455. return v.format(message, {attribute: v.prettify(attribute), type: type});
  1456. }
  1457. }, {
  1458. types: {
  1459. object: function(value) {
  1460. return v.isObject(value) && !v.isArray(value);
  1461. },
  1462. array: v.isArray,
  1463. integer: v.isInteger,
  1464. number: v.isNumber,
  1465. string: v.isString,
  1466. date: v.isDate,
  1467. boolean: v.isBoolean
  1468. },
  1469. messages: {}
  1470. })
  1471. };
  1472. validate.formatters = {
  1473. detailed: function(errors) {return errors;},
  1474. flat: v.flattenErrorsToArray,
  1475. grouped: function(errors) {
  1476. var attr;
  1477. errors = v.groupErrorsByAttribute(errors);
  1478. for (attr in errors) {
  1479. errors[attr] = v.flattenErrorsToArray(errors[attr]);
  1480. }
  1481. return errors;
  1482. },
  1483. constraint: function(errors) {
  1484. var attr;
  1485. errors = v.groupErrorsByAttribute(errors);
  1486. for (attr in errors) {
  1487. errors[attr] = errors[attr].map(function(result) {
  1488. return result.validator;
  1489. }).sort();
  1490. }
  1491. return errors;
  1492. }
  1493. };
  1494. validate.exposeModule(validate, this, exports, module, __webpack_require__(/*! !webpack amd define */ "./node_modules/webpack/buildin/amd-define.js"));
  1495. }).call(this,
  1496. true ? /* istanbul ignore next */ exports : undefined,
  1497. true ? /* istanbul ignore next */ module : undefined,
  1498. __webpack_require__(/*! !webpack amd define */ "./node_modules/webpack/buildin/amd-define.js"));
  1499. /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/module.js */ "./node_modules/webpack/buildin/module.js")(module)))
  1500. /***/ }),
  1501. /***/ "./node_modules/webpack/buildin/amd-define.js":
  1502. /*!***************************************!*\
  1503. !*** (webpack)/buildin/amd-define.js ***!
  1504. \***************************************/
  1505. /*! no static exports found */
  1506. /***/ (function(module, exports) {
  1507. module.exports = function() {
  1508. throw new Error("define cannot be used indirect");
  1509. };
  1510. /***/ }),
  1511. /***/ "./node_modules/webpack/buildin/module.js":
  1512. /*!***********************************!*\
  1513. !*** (webpack)/buildin/module.js ***!
  1514. \***********************************/
  1515. /*! no static exports found */
  1516. /***/ (function(module, exports) {
  1517. module.exports = function(module) {
  1518. if (!module.webpackPolyfill) {
  1519. module.deprecate = function() {};
  1520. module.paths = [];
  1521. // module.parent = undefined by default
  1522. if (!module.children) module.children = [];
  1523. Object.defineProperty(module, "loaded", {
  1524. enumerable: true,
  1525. get: function() {
  1526. return module.l;
  1527. }
  1528. });
  1529. Object.defineProperty(module, "id", {
  1530. enumerable: true,
  1531. get: function() {
  1532. return module.i;
  1533. }
  1534. });
  1535. module.webpackPolyfill = 1;
  1536. }
  1537. return module;
  1538. };
  1539. /***/ }),
  1540. /***/ "./resources/js/components/bucket/form.riot":
  1541. /*!**************************************************!*\
  1542. !*** ./resources/js/components/bucket/form.riot ***!
  1543. \**************************************************/
  1544. /*! exports provided: default */
  1545. /***/ (function(module, __webpack_exports__, __webpack_require__) {
  1546. "use strict";
  1547. __webpack_require__.r(__webpack_exports__);
  1548. /* harmony import */ var _tentakelfabrik_tiny_validator_src_validator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tentakelfabrik/tiny-validator/src/validator */ "./node_modules/@tentakelfabrik/tiny-validator/src/validator.js");
  1549. /* harmony import */ var _field_error_riot__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../field-error.riot */ "./resources/js/components/field-error.riot");
  1550. riot.register('field-error', _field_error_riot__WEBPACK_IMPORTED_MODULE_1__["default"])
  1551. /* harmony default export */ __webpack_exports__["default"] = ({
  1552. 'css': null,
  1553. 'exports': {
  1554. /**
  1555. *
  1556. * @param {[type]} props [description]
  1557. * @param {[type]} state [description]
  1558. *
  1559. */
  1560. onBeforeMount(props, state) {
  1561. state.validator = new _tentakelfabrik_tiny_validator_src_validator__WEBPACK_IMPORTED_MODULE_0__["default"]({
  1562. name: {
  1563. presence: true,
  1564. length: {
  1565. maximum: 255
  1566. }
  1567. },
  1568. description: {
  1569. length: {
  1570. maximum: 255
  1571. }
  1572. }
  1573. }, this)
  1574. //
  1575. const meta = document.querySelector("meta[name='csrf-token']")
  1576. if (meta) {
  1577. state.csrfToken = meta.getAttribute("content")
  1578. }
  1579. },
  1580. /**
  1581. *
  1582. *
  1583. * @param {[type]} key
  1584. * @param {[type]} defaultClass
  1585. * @return {[type]}
  1586. *
  1587. */
  1588. getClasses(key, defaultClass) {
  1589. const classes = [
  1590. defaultClass
  1591. ]
  1592. const errors = this.state.validator.errors(key)
  1593. if (errors && errors.length > 0) {
  1594. classes.push('is-danger')
  1595. }
  1596. return classes.join(' ')
  1597. }
  1598. },
  1599. 'template': function(
  1600. template,
  1601. expressionTypes,
  1602. bindingTypes,
  1603. getComponent
  1604. ) {
  1605. return template(
  1606. '<div class="form"><form method="POST"><input expr8="expr8" type="hidden" name="_token"/><div class="field is-horizontal"><div class="field-label is-normal"><label class="label required" for="name">\n name\n </label></div><div class="field-body"><div class="field"><p class="control"><input expr9="expr9" id="name" type="text" name="name"/><field-error expr10="expr10"></field-error></p></div></div></div><div class="field is-horizontal"><div class="field-label is-normal"><label class="label" for="description">\n description\n </label></div><div class="field-body"><div class="field"><p class="control"><textarea expr11="expr11" id="description" name="description"></textarea><field-error expr12="expr12"></field-error></p></div></div></div><div class="field is-horizontal"><div class="field-label is-normal"><label class="label" for="name">\n path\n </label></div><div class="field-body"><div class="field"><p class="control"><input expr13="expr13" id="path" type="text" name="path"/><field-error expr14="expr14"></field-error><span class="help">\n path for storage files, if empty default path will be used\n </span></p></div></div></div><div class="field is-horizontal"><div class="field-label is-normal"><label class="label" for="public">\n public\n </label></div><div class="field-body"><div class="field"><input expr15="expr15" id="public" type="checkbox" name="public" value="1"/><span class="help">\n everyone can see bucket, files and download them\n </span></div></div></div><div class="field"><div class="control"><button expr16="expr16" class="button is-primary" type="submit">\n Create\n </button></div></div></form></div>',
  1607. [
  1608. {
  1609. 'type': bindingTypes.IF,
  1610. 'evaluate': function(
  1611. scope
  1612. ) {
  1613. return scope.state.csrfToken;
  1614. },
  1615. 'redundantAttribute': 'expr8',
  1616. 'selector': '[expr8]',
  1617. 'template': template(
  1618. null,
  1619. [
  1620. {
  1621. 'expressions': [
  1622. {
  1623. 'type': expressionTypes.ATTRIBUTE,
  1624. 'name': 'value',
  1625. 'evaluate': function(
  1626. scope
  1627. ) {
  1628. return scope.state.csrfToken;
  1629. }
  1630. }
  1631. ]
  1632. }
  1633. ]
  1634. )
  1635. },
  1636. {
  1637. 'redundantAttribute': 'expr9',
  1638. 'selector': '[expr9]',
  1639. 'expressions': [
  1640. {
  1641. 'type': expressionTypes.ATTRIBUTE,
  1642. 'name': 'class',
  1643. 'evaluate': function(
  1644. scope
  1645. ) {
  1646. return scope.getClasses('name', 'input');
  1647. }
  1648. },
  1649. {
  1650. 'type': expressionTypes.VALUE,
  1651. 'evaluate': function(
  1652. scope
  1653. ) {
  1654. return scope.props.name;
  1655. }
  1656. },
  1657. {
  1658. 'type': expressionTypes.EVENT,
  1659. 'name': 'onkeyup',
  1660. 'evaluate': function(
  1661. scope
  1662. ) {
  1663. return (event) => { scope.state.validator.handle(event, 'name') };
  1664. }
  1665. }
  1666. ]
  1667. },
  1668. {
  1669. 'type': bindingTypes.TAG,
  1670. 'getComponent': getComponent,
  1671. 'evaluate': function(
  1672. scope
  1673. ) {
  1674. return 'field-error';
  1675. },
  1676. 'slots': [],
  1677. 'attributes': [
  1678. {
  1679. 'type': expressionTypes.ATTRIBUTE,
  1680. 'name': 'errors',
  1681. 'evaluate': function(
  1682. scope
  1683. ) {
  1684. return scope.state.validator.errors('name');
  1685. }
  1686. }
  1687. ],
  1688. 'redundantAttribute': 'expr10',
  1689. 'selector': '[expr10]'
  1690. },
  1691. {
  1692. 'redundantAttribute': 'expr11',
  1693. 'selector': '[expr11]',
  1694. 'expressions': [
  1695. {
  1696. 'type': expressionTypes.ATTRIBUTE,
  1697. 'name': 'class',
  1698. 'evaluate': function(
  1699. scope
  1700. ) {
  1701. return scope.getClasses('description', 'textarea');
  1702. }
  1703. },
  1704. {
  1705. 'type': expressionTypes.VALUE,
  1706. 'evaluate': function(
  1707. scope
  1708. ) {
  1709. return scope.props.description;
  1710. }
  1711. },
  1712. {
  1713. 'type': expressionTypes.EVENT,
  1714. 'name': 'onkeyup',
  1715. 'evaluate': function(
  1716. scope
  1717. ) {
  1718. return (event) => { scope.state.validator.handle(event, 'description') };
  1719. }
  1720. }
  1721. ]
  1722. },
  1723. {
  1724. 'type': bindingTypes.TAG,
  1725. 'getComponent': getComponent,
  1726. 'evaluate': function(
  1727. scope
  1728. ) {
  1729. return 'field-error';
  1730. },
  1731. 'slots': [],
  1732. 'attributes': [
  1733. {
  1734. 'type': expressionTypes.ATTRIBUTE,
  1735. 'name': 'errors',
  1736. 'evaluate': function(
  1737. scope
  1738. ) {
  1739. return scope.state.validator.errors('description');
  1740. }
  1741. }
  1742. ],
  1743. 'redundantAttribute': 'expr12',
  1744. 'selector': '[expr12]'
  1745. },
  1746. {
  1747. 'redundantAttribute': 'expr13',
  1748. 'selector': '[expr13]',
  1749. 'expressions': [
  1750. {
  1751. 'type': expressionTypes.ATTRIBUTE,
  1752. 'name': 'class',
  1753. 'evaluate': function(
  1754. scope
  1755. ) {
  1756. return scope.getClasses('path', 'input');
  1757. }
  1758. },
  1759. {
  1760. 'type': expressionTypes.VALUE,
  1761. 'evaluate': function(
  1762. scope
  1763. ) {
  1764. return scope.props.path;
  1765. }
  1766. },
  1767. {
  1768. 'type': expressionTypes.EVENT,
  1769. 'name': 'onkeyup',
  1770. 'evaluate': function(
  1771. scope
  1772. ) {
  1773. return (event) => { scope.state.validator.handle(event, 'path') };
  1774. }
  1775. }
  1776. ]
  1777. },
  1778. {
  1779. 'type': bindingTypes.TAG,
  1780. 'getComponent': getComponent,
  1781. 'evaluate': function(
  1782. scope
  1783. ) {
  1784. return 'field-error';
  1785. },
  1786. 'slots': [],
  1787. 'attributes': [
  1788. {
  1789. 'type': expressionTypes.ATTRIBUTE,
  1790. 'name': 'errors',
  1791. 'evaluate': function(
  1792. scope
  1793. ) {
  1794. return scope.state.validator.errors('path');
  1795. }
  1796. }
  1797. ],
  1798. 'redundantAttribute': 'expr14',
  1799. 'selector': '[expr14]'
  1800. },
  1801. {
  1802. 'redundantAttribute': 'expr15',
  1803. 'selector': '[expr15]',
  1804. 'expressions': [
  1805. {
  1806. 'type': expressionTypes.ATTRIBUTE,
  1807. 'name': 'checked',
  1808. 'evaluate': function(
  1809. scope
  1810. ) {
  1811. return scope.props.public;
  1812. }
  1813. }
  1814. ]
  1815. },
  1816. {
  1817. 'redundantAttribute': 'expr16',
  1818. 'selector': '[expr16]',
  1819. 'expressions': [
  1820. {
  1821. 'type': expressionTypes.ATTRIBUTE,
  1822. 'name': 'disabled',
  1823. 'evaluate': function(
  1824. scope
  1825. ) {
  1826. return scope.state.validator.errors().length > 0;
  1827. }
  1828. }
  1829. ]
  1830. }
  1831. ]
  1832. );
  1833. },
  1834. 'name': 'urban-bucket-form'
  1835. });
  1836. /***/ }),
  1837. /***/ "./resources/js/components/field-error.riot":
  1838. /*!**************************************************!*\
  1839. !*** ./resources/js/components/field-error.riot ***!
  1840. \**************************************************/
  1841. /*! exports provided: default */
  1842. /***/ (function(module, __webpack_exports__, __webpack_require__) {
  1843. "use strict";
  1844. __webpack_require__.r(__webpack_exports__);
  1845. /* harmony default export */ __webpack_exports__["default"] = ({
  1846. 'css': null,
  1847. 'exports': {
  1848. state: {
  1849. errors: [
  1850. ]
  1851. },
  1852. /**
  1853. * check if errors from props has an error, if not reset errors in state
  1854. *
  1855. * @param {object} props
  1856. * @param {object} state
  1857. *
  1858. */
  1859. onBeforeUpdate(props, state) {
  1860. if (props.errors && props.errors.length > 0) {
  1861. state.errors = props.errors
  1862. } else {
  1863. state.errors = []
  1864. }
  1865. }
  1866. },
  1867. 'template': function(
  1868. template,
  1869. expressionTypes,
  1870. bindingTypes,
  1871. getComponent
  1872. ) {
  1873. return template(
  1874. '<div expr21="expr21" class="field-error"></div>',
  1875. [
  1876. {
  1877. 'type': bindingTypes.IF,
  1878. 'evaluate': function(
  1879. scope
  1880. ) {
  1881. return scope.state.errors.length > 0;
  1882. },
  1883. 'redundantAttribute': 'expr21',
  1884. 'selector': '[expr21]',
  1885. 'template': template(
  1886. '<ul><li expr22="expr22" class="help is-danger"></li></ul>',
  1887. [
  1888. {
  1889. 'type': bindingTypes.EACH,
  1890. 'getKey': null,
  1891. 'condition': null,
  1892. 'template': template(
  1893. ' ',
  1894. [
  1895. {
  1896. 'expressions': [
  1897. {
  1898. 'type': expressionTypes.TEXT,
  1899. 'childNodeIndex': 0,
  1900. 'evaluate': function(
  1901. scope
  1902. ) {
  1903. return scope.error;
  1904. }
  1905. }
  1906. ]
  1907. }
  1908. ]
  1909. ),
  1910. 'redundantAttribute': 'expr22',
  1911. 'selector': '[expr22]',
  1912. 'itemName': 'error',
  1913. 'indexName': null,
  1914. 'evaluate': function(
  1915. scope
  1916. ) {
  1917. return scope.state.errors;
  1918. }
  1919. }
  1920. ]
  1921. )
  1922. }
  1923. ]
  1924. );
  1925. },
  1926. 'name': 'field-error'
  1927. });
  1928. /***/ }),
  1929. /***/ "./resources/js/views/bucket.js":
  1930. /*!**************************************!*\
  1931. !*** ./resources/js/views/bucket.js ***!
  1932. \**************************************/
  1933. /*! no exports provided */
  1934. /***/ (function(module, __webpack_exports__, __webpack_require__) {
  1935. "use strict";
  1936. __webpack_require__.r(__webpack_exports__);
  1937. /* harmony import */ var _components_bucket_form_riot__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./../components/bucket/form.riot */ "./resources/js/components/bucket/form.riot");
  1938. /**
  1939. * Bucket
  1940. *
  1941. *
  1942. */
  1943. // register components
  1944. riot.register('urban-bucket-form', _components_bucket_form_riot__WEBPACK_IMPORTED_MODULE_0__["default"]);
  1945. /***/ }),
  1946. /***/ 2:
  1947. /*!********************************************!*\
  1948. !*** multi ./resources/js/views/bucket.js ***!
  1949. \********************************************/
  1950. /*! no static exports found */
  1951. /***/ (function(module, exports, __webpack_require__) {
  1952. module.exports = __webpack_require__(/*! /home/herrhase/Workspace/herrhase/urban-filehub/resources/js/views/bucket.js */"./resources/js/views/bucket.js");
  1953. /***/ })
  1954. /******/ });