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