UNPKG

@ideal-postcodes/jsutil

Version:

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

142 lines (141 loc) 4.48 kB
import { toHtmlElem, getAnchors, getParent } from "./dom"; export const getTargets = (parent, selectors) => { const line_1 = toHtmlElem(parent, selectors.line_1); if (line_1 === null) return null; const post_town = toHtmlElem(parent, selectors.post_town); if (post_town === null) return null; const postcode = parent.querySelector(selectors.postcode); if (postcode === null) return null; const line_2 = toHtmlElem(parent, selectors.line_2); const line_3 = toHtmlElem(parent, selectors.line_3); const country = toHtmlElem(parent, selectors.country); const county = toHtmlElem(parent, selectors.county); const organisation = toHtmlElem(parent, selectors.organisation); return { line_1, line_2, line_3, post_town, county, postcode, organisation, country, }; }; export const relevantPage = (bindings) => bindings.some((b) => b.pageTest()); export const defaults = { enabled: true, apiKey: "", populateCounty: false, autocomplete: true, autocompleteOverride: {}, postcodeLookup: true, postcodeLookupOverride: {}, }; export const config = () => { const c = window.idpcConfig; if (c === undefined) return; return { ...defaults, ...c }; }; export const generateTimer = ({ pageTest, bind, interval = 1000, }) => { let timer = null; const start = (config) => { if (!pageTest()) return null; timer = window.setInterval(() => { try { bind(config); } catch (e) { stop(); console.log(e); } }, interval); return timer; }; const stop = () => { if (timer === null) return; window.clearInterval(timer); timer = null; }; return { start, stop }; }; const NOOP = () => { }; export const setup = ({ bindings, callback = NOOP }) => { const c = config(); if (c === undefined) return callback(); if (!relevantPage(bindings)) return callback(); const result = bindings.reduce((prev, binding) => { const { pageTest, bind } = binding; if (!pageTest()) return prev; const { start, stop } = generateTimer({ pageTest, bind }); start(c); prev.push({ binding, start, stop }); return prev; }, []); return callback(result); }; const DEFAULT_SCOPE = "form"; const DEFAULT_ANCHOR = "line_1"; export const setupBind = ({ selectors, anchorSelector, parentScope, doc, parentTest, }) => { const anchors = getAnchors(anchorSelector || selectors[DEFAULT_ANCHOR], doc); return anchors.reduce((prev, anchor) => { const parent = getParent(anchor, parentScope || DEFAULT_SCOPE, parentTest); if (!parent) return prev; const targets = getTargets(parent, selectors); if (targets === null) return prev; prev.push({ targets, parent, anchor }); return prev; }, []); }; export const toId = (elem) => `#${elem.id}`; export const cssEscape = (value) => { value = String(value); const length = value.length; let index = -1; let codeUnit; let result = ""; const firstCodeUnit = value.charCodeAt(0); while (++index < length) { codeUnit = value.charCodeAt(index); if (codeUnit == 0x0000) { result += "\uFFFD"; continue; } if ((codeUnit >= 0x0001 && codeUnit <= 0x001f) || codeUnit == 0x007f || (index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) || (index == 1 && codeUnit >= 0x0030 && codeUnit <= 0x0039 && firstCodeUnit == 0x002d)) { result += "\\" + codeUnit.toString(16) + " "; continue; } if (index == 0 && length == 1 && codeUnit == 0x002d) { result += "\\" + value.charAt(index); continue; } if (codeUnit >= 0x0080 || codeUnit == 0x002d || codeUnit == 0x005f || (codeUnit >= 0x0030 && codeUnit <= 0x0039) || (codeUnit >= 0x0041 && codeUnit <= 0x005a) || (codeUnit >= 0x0061 && codeUnit <= 0x007a)) { result += value.charAt(index); continue; } result += "\\" + value.charAt(index); } return result; };