formsquare
Version:
Serialize html5 forms the smart way
595 lines (481 loc) • 15.1 kB
JavaScript
var formsquare = (function () {
'use strict';
function _typeof(obj) {
"@babel/helpers - typeof";
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
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 _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
}
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 _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(n);
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 _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
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.");
}
/* eslint no-use-before-define: ["error", { "functions": false }] */
function all(p, arr) {
var len = arr.length;
for (var i = 0; i < len; i += 1) {
if (!p(arr[i])) {
return false;
}
}
return true;
}
function allPass(ps) {
return function (x) {
return all(function (p) {
return p(x);
}, ps);
};
}
function any(p, arr) {
var len = arr.length;
for (var i = 0; i < len; i += 1) {
if (p(arr[i])) {
return true;
}
}
return false;
}
function contains(el, arr) {
var len = arr.length;
for (var i = 0; i < len; i += 1) {
if (arr[i] === el) {
return true;
}
}
return false;
}
function extendUniq(a, b) {
var len = b.length;
for (var i = 0; i < len; i += 1) {
if (!contains(b[i], a)) {
a.push(b[i]);
}
}
return a;
}
function filter(p, arr) {
var filtered = [];
var len = arr.length;
for (var i = 0; i < len; i += 1) {
if (p(arr[i])) {
filtered.push(arr[i]);
}
}
return filtered;
}
function flatMap(fn, arr) {
return reduce(function (acc, el) {
var collection = fn(el);
var len = collection.length;
for (var i = 0; i < len; i += 1) {
acc.push(collection[i]);
}
return acc;
}, [], arr);
}
function isObject(value) {
if (!value) {
return false;
}
if (value instanceof Date || value instanceof Promise || Array.isArray(value)) {
return false;
}
var type = _typeof(value);
return type !== "bigint" && type !== "boolean" && type !== "number" && type !== "string" && type !== "symbol";
}
function map(fn, arr) {
var mapped = [];
var len = arr.length;
for (var i = 0; i < len; i += 1) {
mapped.push(fn(arr[i]));
}
return mapped;
}
function reduce(fn, init, arr) {
var acc = init;
var len = arr.length;
for (var i = 0; i < len; i += 1) {
acc = fn(acc, arr[i]);
}
return acc;
}
function selectedValues(select) {
var options = select.selectedOptions || filter(function (option) {
return option.selected;
}, select.options);
return map(function (option) {
return option.value;
}, options);
}
function startsWith(match, string) {
return string.slice(0, match.length) === match;
}
function formElements(form) {
if (form instanceof NodeList || Array.isArray(form)) {
return flatMap(formElements, form);
}
var elements = form.elements;
if (!form.id || typeof window.HTMLFormControlsCollection === "function" && elements instanceof window.HTMLFormControlsCollection) {
return elements;
} // Polyfill for browsers that don't support html5 form attribute.
var outside = document.querySelectorAll("[form=\"".concat(form.id, "\"]"));
var inside = filter(function (el) {
return contains(el.getAttribute("form"), ["", null, form.id]);
}, elements);
return extendUniq(inside, outside);
}
function splitDataURL(str) {
var protocolIndex = str.indexOf(":");
var mimeIndex = str.indexOf(";", protocolIndex);
var startIndex = str.indexOf(",", mimeIndex);
return {
type: str.slice(protocolIndex + 1, mimeIndex),
body: str.slice(startIndex + 1)
};
} // eslint-disable-next-line import/prefer-default-export
function readFile(file) {
if (!file) {
return Promise.resolve(null);
}
var reader = new FileReader();
var loaded = new Promise(function (resolve, reject) {
reader.addEventListener("load", resolve, false);
reader.addEventListener("error", reject, false);
reader.addEventListener("abort", reject, false);
});
reader.readAsDataURL(file);
return loaded.then(function (event) {
// data:text/plain;base64,Zm9vCg
var _splitDataURL = splitDataURL(event.target.result),
type = _splitDataURL.type,
body = _splitDataURL.body;
return {
body: body,
type: type,
name: file.name
};
});
}
var DIGIT_RE = /^\s*\d+\s*$/;
function initialize(obj, path) {
if (obj === null) {
return typeof path[0] === "number" ? [] : Object.create(null);
}
return obj;
}
function getPath(name) {
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
if (name.length === 0) {
return path;
}
var open = name.indexOf("[");
var close = name.indexOf("]");
if (open <= 0 && close === -1) {
path.push(name);
return path;
}
while (close < open && close !== -1) {
close = name.slice(close).indexOf("]");
}
if (close === -1) {
path.push(name);
return path;
}
if (open > 0) {
path.push(name.slice(0, open));
return getPath(name.slice(open), path);
}
var next = name.slice(open + 1, close);
if (next === "") {
path.push(-1);
} else if (next.match(DIGIT_RE)) {
path.push(Number.parseInt(next, 10));
} else {
path.push(next);
}
return getPath(name.slice(close + 1), path);
}
// eslint-disable-next-line import/prefer-default-export
function getWeek(value) {
// Get the date that starts this week.
if (!value.match(/^\s*\d+\s*-W\s*\d+\s*$/)) {
// Invalid week string.
return value;
}
var _value$split = value.split("-W"),
_value$split2 = _slicedToArray(_value$split, 2),
year = _value$split2[0],
week = _value$split2[1];
year = parseInt(year, 10);
week = parseInt(week, 10);
if (week <= 0 || week > 53) {
// Invalid week string.
return value;
}
var naive = new Date(Date.UTC(year, 0, 1 + (week - 1) * 7));
var dayOfWeek = naive.getUTCDay();
var date = naive;
if (dayOfWeek <= 4) {
date.setUTCDate(naive.getUTCDate() - naive.getUTCDay() + 1);
} else {
date.setUTCDate(naive.getUTCDate() + 8 - naive.getUTCDay());
}
if (date.toString() === "Invalid Date") {
return value;
}
return date;
}
function getValue(input) {
var maps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
if (input.type === "select-multiple") {
return selectedValues(input);
}
if (input.type === "number" || input.type === "range") {
return Number.parseFloat(input.value);
}
if (contains(input.getAttribute("type"), ["date", "datetime-local", "month"])) {
var date = new Date(input.value);
if (date.toString() === "Invalid Date") {
return input.value;
}
return date;
}
if (input.getAttribute("type") === "week") {
return getWeek(input.value) || input.getAttribute("value");
}
if (input.type === "file") {
if (input.multiple) {
if (input.files.length === 0) {
return Promise.resolve([]);
}
return Promise.all(map(readFile, input.files));
}
return readFile(input.files[0]);
}
var value = input.value;
maps.forEach(function (fn) {
value = fn(value, input);
});
return value;
}
function fillSparse(node, attr) {
if (Array.isArray(node) && typeof attr === "number" && node.length < attr) {
for (var i = node.length; i < attr; i += 1) {
if (typeof node[i] === "undefined") {
Object.assign(node, _defineProperty({}, i, null));
}
}
}
}
function setLeaf(leaf, name, value, asObject) {
var attr = name === -1 ? leaf.length : name;
if (typeof leaf[attr] !== "undefined" && leaf[attr] !== null) {
if (!Array.isArray(leaf[attr])) {
Object.assign(leaf, _defineProperty({}, attr, [leaf[attr]]));
}
leaf[attr].push(asObject ? {
"": value
} : value);
} else {
fillSparse(leaf, attr);
Object.assign(leaf, _defineProperty({}, attr, asObject ? {
"": value
} : value));
}
}
function branch(path, node) {
if (path.length <= 1) {
return node;
}
var first = path[0];
var rest = path.slice(1);
var attr = first === -1 ? node.length : first;
var next = node[attr];
if (typeof next === "undefined") {
var nextBranch = typeof rest[0] === "number" ? [] : Object.create(null);
if (Array.isArray(node) && attr === -1) {
node.push(nextBranch);
return branch(rest, nextBranch);
}
fillSparse(node, attr);
Object.assign(node, _defineProperty({}, attr, nextBranch));
}
return branch(rest, node[attr]);
}
function hasArrayLeaf(path) {
return typeof path.slice(-1)[0] === "number";
}
function nonMember(obj, path) {
// This is a non-member of an array.
var node = obj;
if (node === null) {
// The array hasn't been initialized yet.
if (path.length === 0 || typeof path[0] === "number") {
return [];
} // The array will go under a new branch.
node = Object.create(null);
}
var leaf = branch(path, node);
var attr = path.slice(-1)[0];
if (path.length > 0 && typeof leaf[attr] === "undefined" && !hasArrayLeaf(path)) {
leaf[attr] = [];
}
return node;
}
function parse(elements, maps) {
function setValue(obj, input) {
var name = input.name,
type = input.type;
var value = input.value;
var path = getPath(name);
if (type === "radio" && !input.checked) {
// Do nothing.
return obj;
}
if (type === "checkbox" && input.getAttribute("value") === null) {
value = input.checked;
} else if (type === "checkbox" && !input.checked) {
if (hasArrayLeaf(path) || any(function (other) {
return other.name === name && other !== input;
}, elements)) {
return nonMember(obj, path);
}
value = null;
} else {
value = getValue(input, maps);
}
if (path.length === 0) {
if (obj === null) {
// A singleton value
return value;
}
if (!Array.isArray(obj)) {
if (!isObject(obj)) {
return [obj, value];
}
Object.assign(obj, _defineProperty({}, Object.keys(obj).length, value));
return obj;
}
obj.push(value);
return obj;
}
var tree = initialize(obj, path);
var leaf = branch(path, tree);
var attr = path.slice(-1)[0];
var asObject = typeof attr !== "number" && any(function (other) {
return startsWith(name, other.name) && other !== input && other.name.slice(name.length).match(/\[[^\]]\]/);
}, elements);
setLeaf(leaf, attr, value, asObject);
return tree;
}
return reduce(setValue, null, elements);
}
function newFormsquare() {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref$filters = _ref.filters,
filters = _ref$filters === void 0 ? [] : _ref$filters,
_ref$maps = _ref.maps,
maps = _ref$maps === void 0 ? [] : _ref$maps;
var formsquare = Object.create(null);
Object.defineProperty(formsquare, "filter", {
value: function value(p) {
return newFormsquare({
filters: [].concat(_toConsumableArray(filters), [p]),
maps: maps
});
}
});
Object.defineProperty(formsquare, "map", {
value: function value(p) {
return newFormsquare({
maps: [].concat(_toConsumableArray(maps), [p]),
filters: filters
});
}
});
Object.defineProperty(formsquare, "parse", {
value: function value(form) {
var elements = filter(allPass(filters), formElements(form));
return parse(elements, maps);
}
});
return formsquare;
}
var formsquare = newFormsquare();
return formsquare;
}());
//# sourceMappingURL=formsquare.js.map