1"use strict"; 2 3Object.defineProperty(exports, "__esModule", { 4 value: true 5}); 6exports.applyImageToSplashScreenXML = applyImageToSplashScreenXML; 7exports.createConstraint = createConstraint; 8exports.createConstraintId = createConstraintId; 9exports.ensureUniquePush = ensureUniquePush; 10exports.removeExisting = removeExisting; 11exports.removeImageFromSplashScreen = removeImageFromSplashScreen; 12exports.toObjectAsync = toObjectAsync; 13exports.toString = toString; 14function _crypto() { 15 const data = _interopRequireDefault(require("crypto")); 16 _crypto = function () { 17 return data; 18 }; 19 return data; 20} 21function _xml2js() { 22 const data = require("xml2js"); 23 _xml2js = function () { 24 return data; 25 }; 26 return data; 27} 28function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 29const debug = require('debug')('expo:prebuild-config:expo-splash-screen:ios:InterfaceBuilder'); 30function createConstraint([firstItem, firstAttribute], [secondItem, secondAttribute], constant) { 31 return { 32 $: { 33 firstItem, 34 firstAttribute, 35 secondItem, 36 secondAttribute, 37 constant, 38 // Prevent updating between runs 39 id: createConstraintId(firstItem, firstAttribute, secondItem, secondAttribute) 40 } 41 }; 42} 43function createConstraintId(...attributes) { 44 return _crypto().default.createHash('sha1').update(attributes.join('-')).digest('hex'); 45} 46const IMAGE_ID = 'EXPO-SplashScreen'; 47const CONTAINER_ID = 'EXPO-ContainerView'; 48function removeImageFromSplashScreen(xml, { 49 imageName 50}) { 51 const mainView = xml.document.scenes[0].scene[0].objects[0].viewController[0].view[0]; 52 debug(`Remove all splash screen image elements`); 53 removeExisting(mainView.subviews[0].imageView, IMAGE_ID); 54 55 // Add Constraints 56 getAbsoluteConstraints(IMAGE_ID, CONTAINER_ID).forEach(constraint => { 57 // <constraint firstItem="EXPO-SplashScreen" firstAttribute="top" secondItem="EXPO-ContainerView" secondAttribute="top" id="2VS-Uz-0LU"/> 58 const constrainsArray = mainView.constraints[0].constraint; 59 removeExisting(constrainsArray, constraint); 60 }); 61 62 // Add resource 63 const imageSection = xml.document.resources[0].image; 64 const existingImageIndex = imageSection.findIndex(image => image.$.name === imageName); 65 if (existingImageIndex > -1) { 66 imageSection.splice(existingImageIndex, 1); 67 } 68 return xml; 69} 70function getAbsoluteConstraints(childId, parentId) { 71 return [createConstraint([childId, 'top'], [parentId, 'top']), createConstraint([childId, 'leading'], [parentId, 'leading']), createConstraint([childId, 'trailing'], [parentId, 'trailing']), createConstraint([childId, 'bottom'], [parentId, 'bottom'])]; 72} 73function applyImageToSplashScreenXML(xml, { 74 imageName, 75 contentMode 76}) { 77 const width = 414; 78 const height = 736; 79 const imageView = { 80 $: { 81 id: IMAGE_ID, 82 userLabel: imageName, 83 image: imageName, 84 contentMode, 85 horizontalHuggingPriority: 251, 86 verticalHuggingPriority: 251, 87 clipsSubviews: true, 88 userInteractionEnabled: false, 89 translatesAutoresizingMaskIntoConstraints: false 90 }, 91 rect: [{ 92 $: { 93 key: 'frame', 94 x: 0.0, 95 y: 0.0, 96 width, 97 height 98 } 99 }] 100 }; 101 const mainView = xml.document.scenes[0].scene[0].objects[0].viewController[0].view[0]; 102 103 // Add ImageView 104 ensureUniquePush(mainView.subviews[0].imageView, imageView); 105 106 // Add Constraints 107 getAbsoluteConstraints(IMAGE_ID, CONTAINER_ID).forEach(constraint => { 108 // <constraint firstItem="EXPO-SplashScreen" firstAttribute="top" secondItem="EXPO-ContainerView" secondAttribute="top" id="2VS-Uz-0LU"/> 109 const constrainsArray = mainView.constraints[0].constraint; 110 ensureUniquePush(constrainsArray, constraint); 111 }); 112 113 // Add resource 114 const imageSection = xml.document.resources[0].image; 115 const existingImageIndex = imageSection.findIndex(image => image.$.name === imageName); 116 if (existingImageIndex > -1) { 117 debug(`Removing existing IB image asset at index ${existingImageIndex}`); 118 imageSection.splice(existingImageIndex, 1); 119 } 120 imageSection.push({ 121 // <image name="SplashScreen" width="414" height="736"/> 122 $: { 123 name: imageName, 124 width, 125 height 126 } 127 }); 128 return xml; 129} 130 131/** 132 * IB does not allow two items to have the same ID. 133 * This method will add an item by first removing any existing item with the same `$.id`. 134 */ 135function ensureUniquePush(array, item) { 136 if (!array) return array; 137 removeExisting(array, item); 138 array.push(item); 139 return array; 140} 141function removeExisting(array, item) { 142 var _item$$; 143 const id = typeof item === 'string' ? item : (_item$$ = item.$) === null || _item$$ === void 0 ? void 0 : _item$$.id; 144 const existingItem = array === null || array === void 0 ? void 0 : array.findIndex(existingItem => existingItem.$.id === id); 145 if (existingItem > -1) { 146 debug(`Removing existing IB item with id ${id}, from: %O`, array); 147 array.splice(existingItem, 1); 148 } 149 return array; 150} 151 152// Attempt to copy Xcode formatting. 153function toString(xml) { 154 const builder = new (_xml2js().Builder)({ 155 // @ts-expect-error: untyped 156 preserveChildrenOrder: true, 157 xmldec: { 158 version: '1.0', 159 encoding: 'UTF-8' 160 }, 161 renderOpts: { 162 pretty: true, 163 indent: ' ' 164 } 165 }); 166 return builder.buildObject(xml); 167} 168 169/** Parse string contents into an object. */ 170function toObjectAsync(contents) { 171 return new (_xml2js().Parser)().parseStringPromise(contents); 172} 173//# sourceMappingURL=InterfaceBuilder.js.map