UNPKG

@ideal-postcodes/jsutil

Version:

Browser Address Autocomplete for api.ideal-postcodes.co.uk

352 lines (351 loc) 12.6 kB
"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;