/** * Copyright (c) Nicolas Gallagher. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @noflow */ import setValueForStyles from '../../modules/setValueForStyles'; declare var getRect: (node: any) => any; declare var measureLayout: (node: any, relativeToNativeNode: any, callback: any) => any; const elementsToIgnore = { A: true, BODY: true, INPUT: true, SELECT: true, TEXTAREA: true }; const UIManager = { blur(node) { try { node.blur(); } catch (err) {} }, focus(node) { try { const name = node.nodeName; // A tabIndex of -1 allows element to be programmatically focused but // prevents keyboard focus. We don't want to set the tabindex value on // elements that should not prevent keyboard focus. if (node.getAttribute('tabIndex') == null && node.isContentEditable !== true && elementsToIgnore[name] == null) { node.setAttribute('tabIndex', '-1'); } node.focus(); } catch (err) {} }, measure(node, callback) { measureLayout(node, null, callback); }, measureInWindow(node, callback) { if (node) { setTimeout(() => { const { height, left, top, width } = getRect(node); callback(left, top, width, height); }, 0); } }, measureLayout(node, relativeToNativeNode, onFail, onSuccess) { measureLayout(node, relativeToNativeNode, onSuccess); }, updateView(node, props) { for (const prop in props) { if (!Object.prototype.hasOwnProperty.call(props, prop)) { continue; } const value = props[prop]; switch (prop) { case 'style': { setValueForStyles(node, value); break; } case 'class': case 'className': { node.setAttribute('class', value); break; } case 'text': case 'value': // native platforms use `text` prop to replace text input value node.value = value; break; default: node.setAttribute(prop, value); } } }, configureNextLayoutAnimation(config, onAnimationDidEnd) { onAnimationDidEnd(); }, // mocks setLayoutAnimationEnabledExperimental() {} }; export default UIManager;