braintree-web
Version:
A suite of tools for integrating Braintree in the browser
108 lines (91 loc) • 3.13 kB
JavaScript
;
var browserDetection = require("./browser-detection");
var constants = require("./constants");
var allowedFields = Object.keys(constants.allowedFields);
var directions = constants.navigationDirections;
var focusIntercept = {
generate: function (hostedFieldsId, type, direction, handler) {
var input = document.createElement("input");
var focusInterceptStyles = {
border: "none !important",
display: "block !important",
height: "1px !important",
left: "-1px !important",
opacity: "0 !important",
position: "absolute !important",
top: "-1px !important",
width: "1px !important",
};
var shouldCreateFocusIntercept =
browserDetection.hasSoftwareKeyboard() || browserDetection.isFirefox();
if (!shouldCreateFocusIntercept) {
return document.createDocumentFragment();
}
input.setAttribute("aria-hidden", "true");
input.setAttribute("autocomplete", "off");
input.setAttribute("data-braintree-direction", direction);
input.setAttribute("data-braintree-type", type);
input.setAttribute(
"id",
"bt-" + type + "-" + direction + "-" + hostedFieldsId
);
input.setAttribute(
"style",
JSON.stringify(focusInterceptStyles)
.replace(/[{}"]/g, "")
.replace(/,/g, ";")
);
input.classList.add("focus-intercept");
input.addEventListener("focus", function (event) {
handler(event);
/*
Certain browsers without software keyboards (Firefox, Internet
Explorer) need the focus intercept inputs that get inserted
around the actual input to blur themselves, otherwise the
browser gets confused about what should have focus. Can't
apply this to browsers with software keyboards however,
because it blurs everything, and focus on the actual input is
also lost.
*/
if (!browserDetection.hasSoftwareKeyboard()) {
input.blur();
}
});
return input;
},
destroy: function (idString) {
var focusInputs;
if (!idString) {
focusInputs = document.querySelectorAll("[data-braintree-direction]");
focusInputs = [].slice.call(focusInputs);
} else {
focusInputs = [document.getElementById(idString)];
}
focusInputs.forEach(function (node) {
if (
node &&
node.nodeType === 1 &&
focusIntercept.matchFocusElement(node.getAttribute("id"))
) {
node.parentNode.removeChild(node);
}
});
},
matchFocusElement: function (idString) {
var idComponents, hasBTPrefix, isAllowedType, isValidDirection;
if (!idString) {
return false;
}
idComponents = idString.split("-");
if (idComponents.length < 4) {
return false;
}
hasBTPrefix = idComponents[0] === "bt";
isAllowedType = allowedFields.indexOf(idComponents[1]) > -1;
isValidDirection =
idComponents[2] === directions.BACK ||
idComponents[2] === directions.FORWARD;
return Boolean(hasBTPrefix && isAllowedType && isValidDirection);
},
};
module.exports = focusIntercept;