@ideal-postcodes/jsutil
Version:
Browser Address Autocomplete for api.ideal-postcodes.co.uk
352 lines (351 loc) • 12.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCounty = exports.getCountyIso = exports.getCountySelector = exports.getCountyIsoSelector = exports.removeOrganisation = exports.populateAddress = exports.mutateAddress = exports.searchLabels = exports.searchNames = exports.searchFields = exports.getFields = exports.extract = exports.toAddressLines = exports.toMaxLengthLines = exports.charArrayLength = exports.join = exports.numberOfLines = void 0;
const input_1 = require("./input");
const dom_1 = require("./dom");
const country_1 = require("./country");
const types_1 = require("./types");
const string_1 = require("./string");
const util_1 = require("./util");
const numberOfLines = (targets) => {
const { line_2, line_3 } = targets;
if (!line_2)
return 1;
if (!line_3)
return 2;
return 3;
};
exports.numberOfLines = numberOfLines;
const join = (list) => list
.filter((e) => {
if ((0, string_1.isString)(e))
return !!e.trim();
return !!e;
})
.join(", ");
exports.join = join;
const charArrayLength = (arr) => arr.join(" ").trim().length;
exports.charArrayLength = charArrayLength;
const truncate = (line, maxLength) => {
if (line.length <= maxLength)
return [line, ""];
const words = line.split(" ");
let truncated = "";
let remaining = "";
for (let i = 0; i < words.length; i++) {
const word = words[i];
if (truncated.length + word.length > maxLength) {
remaining = words.slice(i).join(" ");
break;
}
truncated += `${word} `;
}
return [truncated.trim(), remaining.trim()];
};
const prependLine = (remaining, nextLine) => {
if (nextLine.length === 0)
return remaining;
return `${remaining}, ${nextLine}`;
};
const toMaxLengthLines = (l, options) => {
const { lineCount, maxLineOne, maxLineTwo, maxLineThree } = options;
const result = ["", "", ""];
const lines = [...l];
if (maxLineOne) {
const [newLineOne, remaining] = truncate(lines[0], maxLineOne);
result[0] = newLineOne;
if (remaining)
lines[1] = prependLine(remaining, lines[1]);
if (lineCount === 1)
return result;
}
else {
result[0] = lines[0];
if (lineCount === 1)
return [(0, exports.join)(lines), "", ""];
}
if (maxLineTwo) {
const [newLineTwo, remaining] = truncate(lines[1], maxLineTwo);
result[1] = newLineTwo;
if (remaining)
lines[2] = prependLine(remaining, lines[2]);
if (lineCount === 2)
return result;
}
else {
result[1] = lines[1];
if (lineCount === 2)
return [result[0], (0, exports.join)(lines.slice(1)), ""];
}
if (maxLineThree) {
const [newLineThree, remaining] = truncate(lines[2], maxLineThree);
result[2] = newLineThree;
if (remaining)
lines[3] = prependLine(remaining, lines[3]);
}
else {
result[2] = lines[2];
}
return result;
};
exports.toMaxLengthLines = toMaxLengthLines;
const toAddressLines = (lineCount, address, options) => {
const { line_1, line_2 } = address;
const line_3 = "line_3" in address ? address.line_3 : "";
if (options.maxLineOne || options.maxLineTwo || options.maxLineThree)
return (0, exports.toMaxLengthLines)([line_1, line_2, line_3], {
lineCount,
...options,
});
if (lineCount === 3)
return [line_1, line_2, line_3];
if (lineCount === 2)
return [line_1, (0, exports.join)([line_2, line_3]), ""];
return [(0, exports.join)([line_1, line_2, line_3]), "", ""];
};
exports.toAddressLines = toAddressLines;
const extract = (a, attr) => {
const result = a[attr];
if (typeof result === "number")
return result.toString();
if (result === undefined)
return "";
return result;
};
exports.extract = extract;
const getFields = (o) => ({
...(0, exports.searchFields)(o.outputFields || {}, o.config.scope),
...(0, exports.searchNames)(o.names || {}, o.config.scope),
...(0, exports.searchLabels)(o.labels || {}, o.config.scope),
});
exports.getFields = getFields;
const searchFields = (outputFields, scope) => {
const fields = {};
let key;
for (key in outputFields) {
const value = outputFields[key];
if (value === undefined)
continue;
const field = (0, dom_1.toElem)(value, scope);
if ((0, input_1.isInputElem)(field))
fields[key] = field;
}
return fields;
};
exports.searchFields = searchFields;
const searchNames = (names, scope) => {
const result = {};
let key;
for (key in names) {
if (!names.hasOwnProperty(key))
continue;
const name = names[key];
const named = (0, dom_1.toElem)(`[name="${name}"]`, scope);
if (named) {
result[key] = named;
continue;
}
const ariaNamed = (0, dom_1.toElem)(`[aria-name="${name}"]`, scope);
if (ariaNamed)
result[key] = ariaNamed;
}
return result;
};
exports.searchNames = searchNames;
const searchLabels = (labels, scope) => {
const result = {};
if (labels === undefined)
return labels;
let key;
for (key in labels) {
if (!labels.hasOwnProperty(key))
continue;
const name = labels[key];
if (!name)
continue;
const first = (0, dom_1.contains)(scope, "label", name);
const label = (0, dom_1.toElem)(first, scope);
if (!label)
continue;
const forEl = label.getAttribute("for");
if (forEl) {
const byId = scope.querySelector(`#${(0, util_1.cssEscape)(forEl)}`);
if (byId) {
result[key] = byId;
continue;
}
}
const inner = label.querySelector("input");
if (inner)
result[key] = inner;
}
return result;
};
exports.searchLabels = searchLabels;
const skipFields = ["country", "country_iso_2", "country_iso"];
const mutateAddress = (address, config) => {
if ((0, types_1.isGbrAddress)(address)) {
if (config.removeOrganisation)
(0, exports.removeOrganisation)(address);
}
const [line_1, line_2, line_3] = (0, exports.toAddressLines)(config.lines || 3, address, config);
address.line_1 = line_1;
address.line_2 = line_2;
if ((0, types_1.isGbrAddress)(address))
address.line_3 = line_3;
return address;
};
exports.mutateAddress = mutateAddress;
const populateAddress = (options) => {
const { config } = options;
const fields = (0, exports.getFields)(options);
if (config.lines === undefined)
config.lines = (0, exports.numberOfLines)(fields);
const address = (0, exports.mutateAddress)({ ...options.address }, config);
const { scope, populateCounty } = config;
const skip = [...skipFields];
if ((0, types_1.isGbrAddress)(address)) {
if (config.removeOrganisation)
(0, exports.removeOrganisation)(address);
if (populateCounty === false)
skip.push("county");
}
(0, country_1.updateCountry)((0, dom_1.toElem)(fields.country || null, scope), address);
const iso2Elem = (0, dom_1.toElem)(fields.country_iso_2 || null, scope);
if ((0, input_1.isSelect)(iso2Elem)) {
if ((0, input_1.hasValue)(iso2Elem, address.country_iso_2)) {
(0, input_1.change)({ e: iso2Elem, value: address.country_iso_2 });
}
else {
let text = (0, input_1.optionsHasText)(iso2Elem, address.country_iso_2);
if (text.length > 0) {
(0, input_1.change)({ e: iso2Elem, value: text[0].value || "" });
}
else {
text = (0, input_1.optionsHasText)(iso2Elem, (0, country_1.toCountry)(address));
if (text.length > 0) {
(0, input_1.change)({ e: iso2Elem, value: text[0].value || "" });
}
}
}
}
if ((0, input_1.isInput)(iso2Elem)) {
(0, input_1.update)(iso2Elem, address.country_iso_2 || "");
}
const iso3Elem = (0, dom_1.toElem)(fields.country_iso || null, scope);
if ((0, input_1.isSelect)(iso3Elem)) {
if ((0, input_1.hasValue)(iso3Elem, address.country_iso)) {
(0, input_1.change)({ e: iso3Elem, value: address.country_iso });
}
else {
let text = (0, input_1.optionsHasText)(iso3Elem, address.country_iso);
if (text.length > 0) {
(0, input_1.change)({ e: iso3Elem, value: text[0].value || "" });
}
else {
text = (0, input_1.optionsHasText)(iso3Elem, (0, country_1.toCountry)(address));
if (text.length > 0) {
(0, input_1.change)({ e: iso3Elem, value: text[0].value || "" });
}
}
}
}
if ((0, input_1.isInput)(iso3Elem))
(0, input_1.update)(iso3Elem, address.country_iso || "");
const countyIso = (0, dom_1.toElem)((0, exports.getCountyIsoSelector)(fields), scope);
const countyIsoValue = (0, exports.getCountyIso)(address);
const countyValue = (0, exports.getCounty)(address);
if ((0, input_1.isSelect)(countyIso)) {
if ((0, input_1.hasValue)(countyIso, countyIsoValue)) {
(0, input_1.change)({ e: countyIso, value: countyIsoValue });
}
else if ((0, input_1.hasValue)(countyIso, countyValue || "")) {
(0, input_1.change)({ e: countyIso, value: countyValue || "" });
}
else {
let text = (0, input_1.optionsHasText)(countyIso, countyValue);
if (text.length > 0) {
(0, input_1.change)({ e: countyIso, value: text[0].value || "" });
}
else {
text = (0, input_1.optionsHasText)(countyIso, countyIsoValue);
if (text)
(0, input_1.change)({ e: countyIso, value: text[0].value || "" });
}
}
}
if ((0, input_1.isInput)(countyIso)) {
(0, input_1.update)(countyIso, countyIsoValue);
}
let e;
for (e in fields) {
if (skip.includes(e))
continue;
if (e.startsWith("native.")) {
updateNative(e, fields, address, scope);
continue;
}
if (address[e] === undefined)
continue;
if (fields.hasOwnProperty(e)) {
const value = fields[e];
if (!value)
continue;
(0, input_1.update)((0, dom_1.toElem)(value, scope), (0, exports.extract)(address, e));
}
}
};
exports.populateAddress = populateAddress;
const updateNative = (nativeAttr, fields, address, scope) => {
const e = nativeAttr.replace("native.", "");
const native = address.native;
if (native === undefined)
return;
const nativeValue = native[e];
if (nativeValue === undefined)
return;
if (fields.hasOwnProperty(nativeAttr)) {
const selector = fields[nativeAttr];
if (!selector)
return;
(0, input_1.update)((0, dom_1.toElem)(selector, scope), (0, exports.extract)(native, e));
}
};
const removeOrganisation = (address) => {
if (address.organisation_name.length === 0)
return address;
if (address.line_2.length === 0 && address.line_3.length === 0)
return address;
if (address.line_1 === address.organisation_name) {
address.line_1 = address.line_2;
address.line_2 = address.line_3;
address.line_3 = "";
}
return address;
};
exports.removeOrganisation = removeOrganisation;
const isUsaOutputFields = (a) => a.hasOwnProperty("state_abbreviation");
const getCountyIsoSelector = (a) => {
if (isUsaOutputFields(a))
return a.state_abbreviation || null;
return a.county_code || null;
};
exports.getCountyIsoSelector = getCountyIsoSelector;
const getCountySelector = (a) => {
if (isUsaOutputFields(a))
return a.state || null;
return a.county || null;
};
exports.getCountySelector = getCountySelector;
const getCountyIso = (a) => {
if ((0, types_1.isGbrAddress)(a))
return a.county_code;
return a.state_abbreviation;
};
exports.getCountyIso = getCountyIso;
const getCounty = (a) => {
if ((0, types_1.isGbrAddress)(a))
return a.county;
return a.state;
};
exports.getCounty = getCounty;