@breakside/jskit 2021.52.0 → 2022.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/Frameworks/DOM.jsframework/Info.json +2 -2
  2. package/Frameworks/DOM.jsframework/io.breakside.JSKit.DOM-bundle.js +2 -2
  3. package/Frameworks/FontKit.jsframework/Info.json +2 -2
  4. package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
  5. package/Frameworks/Foundation.jsframework/Info.json +2 -2
  6. package/Frameworks/Foundation.jsframework/JS/JSColor.js +9 -0
  7. package/Frameworks/Foundation.jsframework/JS/JSColorSpace.js +106 -20
  8. package/Frameworks/Foundation.jsframework/JS/JSMediaType.js +1 -1
  9. package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
  10. package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
  11. package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
  12. package/Info.json +2 -2
  13. package/Node/io.breakside.jskit-bundle.js +2 -2
  14. package/Root/Frameworks/APIKit/APIRequest.js +99 -0
  15. package/Root/Frameworks/APIKit/Info.yaml +1 -1
  16. package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
  17. package/Root/Frameworks/AuthKit/Info.yaml +1 -1
  18. package/Root/Frameworks/CSSOM/Info.yaml +1 -1
  19. package/Root/Frameworks/ChartKit/Info.yaml +1 -1
  20. package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
  21. package/Root/Frameworks/DBKit/DBMongoStore.js +1 -0
  22. package/Root/Frameworks/DBKit/DBRedisStore.js +136 -117
  23. package/Root/Frameworks/DBKit/Info.yaml +1 -1
  24. package/Root/Frameworks/DOM/Info.yaml +1 -1
  25. package/Root/Frameworks/Dispatch/Info.yaml +1 -1
  26. package/Root/Frameworks/FontKit/Info.yaml +1 -1
  27. package/Root/Frameworks/Foundation/Info.yaml +1 -1
  28. package/Root/Frameworks/Foundation/JSColor.js +9 -0
  29. package/Root/Frameworks/Foundation/JSColorSpace.js +106 -20
  30. package/Root/Frameworks/Foundation/JSMediaType.js +1 -1
  31. package/Root/Frameworks/ImageKit/IKColorProfile.js +1091 -0
  32. package/Root/Frameworks/ImageKit/IKColorSpace.js +49 -198
  33. package/Root/Frameworks/ImageKit/IKMatrix.js +124 -0
  34. package/Root/Frameworks/ImageKit/ImageKit.js +2 -0
  35. package/Root/Frameworks/ImageKit/Info.yaml +1 -1
  36. package/Root/Frameworks/MediaKit/Info.yaml +1 -1
  37. package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
  38. package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
  39. package/Root/Frameworks/PDFKit/Info.yaml +1 -1
  40. package/Root/Frameworks/QRKit/Info.yaml +1 -1
  41. package/Root/Frameworks/SearchKit/Info.yaml +1 -1
  42. package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
  43. package/Root/Frameworks/ServerKit/Info.yaml +1 -1
  44. package/Root/Frameworks/ServerKit/SKHTTPRequest.js +44 -0
  45. package/Root/Frameworks/ServerKit/SKJobQueue.js +1 -1
  46. package/Root/Frameworks/ServerKit/SKRedisJobQueue.js +7 -3
  47. package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
  48. package/Root/Frameworks/TestKit/Info.yaml +1 -1
  49. package/Root/Frameworks/TestKit/TKMock.js +1 -1
  50. package/Root/Frameworks/UIKit/Info.yaml +1 -1
  51. package/Root/Frameworks/UIKit/UIBrowserViewController.js +2 -6
  52. package/Root/Frameworks/UIKit/UICollectionReusableView.js +91 -0
  53. package/Root/Frameworks/UIKit/UICollectionView.js +1254 -0
  54. package/Root/Frameworks/UIKit/UICollectionViewCell.js +121 -0
  55. package/Root/Frameworks/UIKit/UICollectionViewGridLayout.js +425 -0
  56. package/Root/Frameworks/UIKit/UICollectionViewLayout.js +82 -0
  57. package/Root/Frameworks/UIKit/UIColorWell.js +12 -1
  58. package/Root/Frameworks/UIKit/UIDisplayServer.js +5 -1
  59. package/Root/Frameworks/UIKit/UIKit.js +7 -0
  60. package/Root/Frameworks/UIKit/UILayer.js +3 -0
  61. package/Root/Frameworks/UIKit/UIListView.js +8 -9
  62. package/Root/Frameworks/UIKit/UIMenu.js +1 -1
  63. package/Root/Frameworks/UIKit/UIMenuView.js +5 -1
  64. package/Root/Frameworks/UIKit/UINavigationBar.js +9 -3
  65. package/Root/Frameworks/UIKit/UINavigationController.js +228 -112
  66. package/Root/Frameworks/UIKit/UINavigationItem.js +4 -0
  67. package/Root/Frameworks/UIKit/UIPopupButton.js +39 -3
  68. package/Root/Frameworks/UIKit/UIScrollView.js +2 -0
  69. package/Root/Frameworks/UIKit/UISplitViewController.js +215 -73
  70. package/Root/Frameworks/UIKit/UITabViewController.js +4 -10
  71. package/Root/Frameworks/UIKit/UITextField.js +3 -0
  72. package/Root/Frameworks/UIKit/UIView.js +3 -0
  73. package/Root/Frameworks/UIKit/UIViewController.js +141 -50
  74. package/Root/Frameworks/UIKit/UIWindow.js +4 -15
  75. package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
  76. package/Root/Frameworks/UIKitTesting/UIMockApplication.js +6 -0
  77. package/Root/Templates/http/${PROJECT_NAME}/Dockerfile +1 -1
  78. package/Root/Templates/node/${PROJECT_NAME}/Dockerfile +4 -2
  79. package/package.json +1 -1
@@ -201,6 +201,9 @@ JSClass("UILayer", JSObject, {
201
201
  },
202
202
 
203
203
  setTransform: function(transform){
204
+ if (transform.isEqual(this.model.transform)){
205
+ return;
206
+ }
204
207
  // When the transform changes, the frame needs to be recalculated. The position, however, does
205
208
  // not change. The transform essentially defines a new relationship between the position and frame
206
209
  this._addImplicitAnimationForKey('transform');
@@ -126,7 +126,7 @@ JSClass("UIListView", UIScrollView, {
126
126
  if (typeof(reuse) === 'string'){
127
127
  this.registerHeaderFooterClassForReuseIdentifier(JSClass.FromName(reuse), identifier);
128
128
  }else{
129
- this.registerCellClassForReuseIdentifier(JSClass.FromName(reuse.valueForKey('className')), identifier);
129
+ this.registerHeaderFooterClassForReuseIdentifier(JSClass.FromName(reuse.valueForKey('className')), identifier);
130
130
  }
131
131
  }
132
132
  }
@@ -140,7 +140,7 @@ JSClass("UIListView", UIScrollView, {
140
140
  this._headersStickToTop = spec.valueForKey("headersStickToTop");
141
141
  }
142
142
  if (spec.containsKey("showsFocusRing")){
143
- this._showsFocusRing = spec.valueForKey("showsFocusRing");
143
+ this.showsFocusRing = spec.valueForKey("showsFocusRing");
144
144
  }
145
145
  if (spec.containsKey("listHeaderView")){
146
146
  this.listHeaderView = spec.valueForKey("listHeaderView", UIView);
@@ -339,7 +339,6 @@ JSClass("UIListView", UIScrollView, {
339
339
  var lastVisibleItem = this._visibleItems[this._visibleItems.length - 1];
340
340
  var searcher = JSBinarySearcher(this._visibleItems, VisibleItem.cellIndexPathCompare);
341
341
  var visibleSizeChanged = false;
342
- var listView = this;
343
342
  var contentSize = JSSize(this.contentSize);
344
343
  var contentOffset = JSPoint(this.contentOffset);
345
344
 
@@ -391,13 +390,13 @@ JSClass("UIListView", UIScrollView, {
391
390
 
392
391
  if (animator && visibleSizeChanged){
393
392
  animator.addAnimations(function(){
394
- listView.contentSize = contentSize;
395
- listView.contentOffset = contentOffset;
396
- listView._layoutVisibleItems(this._visibleItems, y0);
397
- });
393
+ this.contentSize = contentSize;
394
+ this.contentOffset = contentOffset;
395
+ this._layoutVisibleItems(this._visibleItems, y0);
396
+ }, this);
398
397
  }else{
399
- listView.contentSize = contentSize;
400
- listView.contentOffset = contentOffset;
398
+ this.contentSize = contentSize;
399
+ this.contentOffset = contentOffset;
401
400
  }
402
401
 
403
402
  },
@@ -894,7 +894,7 @@ JSClass("UIMenuWindowStyler", UIMenuStyler, {
894
894
  var item = menu.items[itemIndex];
895
895
  var window = this.windowForMenu(menu);
896
896
  if (window !== null){
897
- return window.viewForITem(item);
897
+ return window.viewForItem(item);
898
898
  }
899
899
  return null;
900
900
  }
@@ -214,7 +214,11 @@ JSClass("UIMenuWindow", UIWindow, {
214
214
  },
215
215
 
216
216
  viewForItem: function(item){
217
- return this._itemViewIndexesByItemId[item.objectID] || null;
217
+ var index = this._itemViewIndexesByItemId[item.objectID];
218
+ if (index !== undefined){
219
+ return this.menuView.itemViews[index];
220
+ }
221
+ return null;
218
222
  },
219
223
 
220
224
  // -----------------------------------------------------------------------
@@ -303,6 +303,7 @@ JSClass("UINavigationBarDefaultStyler", UINavigationBarStyler, {
303
303
  contentSeparatorSize: 0,
304
304
  titleColor: null,
305
305
  titleTextAlignment: JSTextAlignment.center,
306
+ titleInsets: null,
306
307
  itemColor: null,
307
308
  activeItemColor: null,
308
309
  disabledItemColor: null,
@@ -347,6 +348,9 @@ JSClass("UINavigationBarDefaultStyler", UINavigationBarStyler, {
347
348
  if (spec.containsKey("titleTextAlignment")){
348
349
  this.titleTextAlignment = spec.valueForKey("titleTextAlignment", JSTextAlignment);
349
350
  }
351
+ if (spec.containsKey("titleInsets")){
352
+ this.titleInsets = spec.valueForKey("titleInsets", JSInsets);
353
+ }
350
354
  if (spec.containsKey("itemColor")){
351
355
  this.itemColor = spec.valueForKey("itemColor", JSColor);
352
356
  }
@@ -490,9 +494,9 @@ JSClass("UINavigationBarDefaultStyler", UINavigationBarStyler, {
490
494
  props.backBarItemView.alpha = 0;
491
495
  var backTitleFrame = props.backBarItemView.titleLabel.convertRectToView(props.backBarItemView.titleLabel.bounds, props.backBarItemView.superview);
492
496
  if (removingCustomView){
493
- props.backBarItemView.titleLabel.transform = JSAffineTransform.Translated(removingCustomView.frame.origin.x - backTitleFrame.origin.x, 0).scaledBy(backToTitleScale);
497
+ props.backBarItemView.titleLabel.transform = JSAffineTransform.Translated(Math.max(0, removingCustomView.frame.origin.x - backTitleFrame.origin.x), 0).scaledBy(backToTitleScale);
494
498
  }else{
495
- props.backBarItemView.titleLabel.transform = JSAffineTransform.Translated(removingTitleLabel.frame.origin.x - backTitleFrame.origin.x, 0).scaledBy(backToTitleScale);
499
+ props.backBarItemView.titleLabel.transform = JSAffineTransform.Translated(Math.max(0, removingTitleLabel.frame.origin.x - backTitleFrame.origin.x), 0).scaledBy(backToTitleScale);
496
500
  }
497
501
  animator.addAnimations(function(){
498
502
  var i, l;
@@ -702,10 +706,13 @@ JSClass("UINavigationBarDefaultStyler", UINavigationBarStyler, {
702
706
  var itemHeight = size.height - this.itemInsets.height;
703
707
  var y = this.itemInsets.top;
704
708
  var barItemView = props.backBarItemView;
709
+ var titleTextAlignment = item ? item.titleTextAlignment || this.titleTextAlignment : this.titleTextAlignment;
705
710
  barItemView.sizeToFitSize(JSSize(xRight - xLeft, itemHeight));
706
711
  barItemView.frame = JSRect(JSPoint(xLeft, y + (itemHeight - barItemView.bounds.size.height) / 2), barItemView.bounds.size);
707
712
  if (!barItemView.hidden){
708
713
  xLeft += barItemView.bounds.size.width;
714
+ }else if (props.leftBarItemViews.length === 0 && titleTextAlignment === JSTextAlignment.left && this.titleInsets !== null){
715
+ xLeft = this.titleInsets.left;
709
716
  }
710
717
  for (i = 0, l = props.leftBarItemViews.length; i < l; ++i){
711
718
  barItemView = props.leftBarItemViews[i];
@@ -738,7 +745,6 @@ JSClass("UINavigationBarDefaultStyler", UINavigationBarStyler, {
738
745
  var maxX = xRight - viewSize.width;
739
746
  var centeredX = (size.width - viewSize.width) / 2;
740
747
  var centeredY = (size.height - viewSize.height) / 2;
741
- var titleTextAlignment = item ? item.titleTextAlignment || this.titleTextAlignment : this.titleTextAlignment;
742
748
  if (titleTextAlignment === JSTextAlignment.center){
743
749
  titleView.frame = JSRect(JSPoint(Math.min(Math.max(minX, centeredX), maxX), centeredY), viewSize);
744
750
  }else if (titleTextAlignment === JSTextAlignment.right){
@@ -35,6 +35,7 @@ JSClass("UINavigationController", UIViewController, {
35
35
  this.addChildViewController(rootViewController);
36
36
  this._viewControllers = [rootViewController];
37
37
  this.navigationBar = UINavigationBar.initWithRootItem(rootViewController.navigationItem, barStyler);
38
+ this.navigationItem.hidesNavigationBar = true;
38
39
  },
39
40
 
40
41
  initWithSpec: function(spec){
@@ -54,10 +55,28 @@ JSClass("UINavigationController", UIViewController, {
54
55
  if (spec.containsKey("delegate")){
55
56
  this.delegate = spec.valueForKey("delegate");
56
57
  }
58
+ this.navigationItem.hidesNavigationBar = true;
57
59
  },
58
60
 
61
+ // --------------------------------------------------------------------
62
+ // MARK: - Delegate
63
+
59
64
  delegate: null,
60
65
 
66
+ scheduleDelegateShowViewController: function(viewController){
67
+ if (this.delegate && this.delegate.navigationControllerWillShowViewController){
68
+ this.delegate.navigationControllerWillShowViewController(this, viewController);
69
+ }
70
+ this.schedule(function(){
71
+ if (this.topViewController === viewController){
72
+ if (this.delegate && this.delegate.navigationControllerDidShowViewController){
73
+ this.delegate.navigationControllerDidShowViewController(this, viewController);
74
+ }
75
+ }
76
+ });
77
+ },
78
+
79
+ // --------------------------------------------------------------------
61
80
  // MARK: - View Lifecycle
62
81
 
63
82
  viewDidLoad: function(){
@@ -87,6 +106,7 @@ JSClass("UINavigationController", UIViewController, {
87
106
  this.topViewController.viewDidDisappear(animated);
88
107
  },
89
108
 
109
+ // --------------------------------------------------------------------
90
110
  // MARK: - Navigation Bar
91
111
 
92
112
  navigationBar: JSDynamicProperty('_navigationBar', null),
@@ -104,34 +124,47 @@ JSClass("UINavigationController", UIViewController, {
104
124
  this._navigationBar.items = items;
105
125
  },
106
126
 
127
+ // --------------------------------------------------------------------
107
128
  // MARK: - View Controllers
108
129
 
109
130
  viewControllers: JSDynamicProperty('_viewControllers', null),
110
131
 
111
132
  setViewControllers: function(viewControllers){
133
+ var oldTopViewController = this.topViewController;
112
134
  var newTopViewController = viewControllers[viewControllers.length - 1];
113
- var newView = newTopViewController.view;
114
- if (newTopViewController !== this.topViewController){
115
- this.topViewController.viewWillDisappear();
116
- newTopViewController.viewWillAppear();
117
- if (this.delegate && this.delegate.navigationControllerWillShowViewController){
118
- this.delegate.navigationControllerWillShowViewController(this, newTopViewController);
119
- }
120
- }
121
- this.topViewController.view.removeFromSuperview();
122
135
  var i, l;
136
+ var viewController;
123
137
  for (i = 0, l = this._viewControllers.length; i < l; ++i){
124
- this._viewControllers[i].removeFromParentViewController();
138
+ viewController = this._viewControllers[i];
139
+ if (viewControllers.indexOf(viewController) < 0){
140
+ viewController.removeFromParentViewController();
141
+ }
125
142
  }
126
143
  this._viewControllers = JSCopy(viewControllers);
127
144
  var items = [];
128
145
  for (i = 0, l = this._viewControllers.length; i < l; ++i){
129
- this.addChildViewController(this._viewControllers[i]);
130
- items.push(this._viewControllers[i].navigationItem);
146
+ viewController = this._viewControllers[i];
147
+ this.addChildViewController(viewController);
148
+ items.push(viewController.navigationItem);
131
149
  }
132
150
  this._navigationBar.items = items;
133
- this.view.insertSubviewBelowSibling(this.topViewController.view, this._navigationBar);
134
- this.view.setNeedsLayout();
151
+ if (this.isViewLoaded){
152
+ if (this.isViewVisible){
153
+ if (newTopViewController !== oldTopViewController){
154
+ oldTopViewController.scheduleDisappearance();
155
+ newTopViewController.scheduleAppearance();
156
+ this.scheduleDelegateShowViewController(newTopViewController);
157
+ }
158
+ }
159
+ oldTopViewController.view.removeFromSuperview();
160
+ if (newTopViewController.navigationItem.hidesNavigationBar){
161
+ this.view.addSubview(newTopViewController.view);
162
+ }else{
163
+ this.view.insertSubviewBelowSibling(newTopViewController.view, this._navigationBar);
164
+ }
165
+ this.navigationBar.hidden = newTopViewController.navigationItem.hidesNavigationBar;
166
+ this.view.setNeedsLayout();
167
+ }
135
168
  },
136
169
 
137
170
  topViewController: JSReadOnlyProperty(),
@@ -163,59 +196,99 @@ JSClass("UINavigationController", UIViewController, {
163
196
  if (this.popAnimator !== null || this.pushAnimator !== null){
164
197
  return;
165
198
  }
166
- if (!this.isViewVisible){
167
- animated = false;
168
- }
169
- if (animated){
170
- this.pushAnimator = this.createPushAnimator();
171
- }
172
199
  var fromViewController = this.topViewController;
200
+ var fromItem = fromViewController.navigationItem;
201
+ var fromView = fromViewController.view;
173
202
  var view = viewController.view;
174
- if (this.isViewVisible){
175
- fromViewController.viewWillDisappear(animated);
176
- viewController.viewWillAppear(animated);
177
- }
178
- if (this.delegate && this.delegate.navigationControllerWillShowViewController){
179
- this.delegate.navigationControllerWillShowViewController(this, viewController);
180
- }
203
+ var item = viewController.navigationItem;
204
+ var navigationBar = this._navigationBar;
181
205
  this.addChildViewController(viewController);
182
206
  this._viewControllers.push(viewController);
183
- this._navigationBar.pushItem(viewController.navigationItem, animated);
184
- this.view.insertSubviewBelowSibling(view, this._navigationBar);
185
- if (!animated){
207
+ if (this.isViewLoaded){
186
208
  if (this.isViewVisible){
187
- fromViewController.enqueueDidDisappear();
188
- viewController.enqueueDidAppear();
189
- }
190
- if (this.delegate && this.delegate.navigationControllerDidShowViewController){
191
- this.delegate.navigationControllerDidShowViewController(this, viewController);
209
+ var isHidingNavigationBar = !fromItem.hidesNavigationBar && item.hidesNavigationBar;
210
+ var isShowingNavigationBar = fromItem.hidesNavigationBar && !item.hidesNavigationBar;
211
+ if (animated){
212
+ this.pushAnimator = this.createPushAnimator();
213
+ fromViewController.beginDisappearanceWithAnimator(this.pushAnimator);
214
+ viewController.beginAppearanceWithAnimator(this.pushAnimator);
215
+ if (this.delegate && this.delegate.navigationControllerWillShowViewController){
216
+ this.delegate.navigationControllerWillShowViewController(this, viewController);
217
+ }
218
+ if (isShowingNavigationBar){
219
+ this.view.addSubview(navigationBar);
220
+ this.view.insertSubviewBelowSibling(view, navigationBar);
221
+ navigationBar.pushItem(item, false);
222
+ }else if (isHidingNavigationBar){
223
+ this.view.addSubview(view);
224
+ }else{
225
+ this.view.insertSubviewAboveSibling(view, fromView);
226
+ navigationBar.pushItem(item, animated);
227
+ }
228
+ this.layoutChildViewController(viewController);
229
+ view.transform = JSAffineTransform.Translated(view.bounds.size.width, 0);
230
+ view.shadowColor = JSColor.windowShadow;
231
+ view.shadowRadius = 20;
232
+ if (isShowingNavigationBar){
233
+ navigationBar.transform = view.transform;
234
+ navigationBar.hidden = false;
235
+ }
236
+ this.pushAnimator.addAnimations(function(){
237
+ view.transform = JSAffineTransform.Identity;
238
+ fromView.transform = JSAffineTransform.Translated(-fromView.bounds.size.width / 2, 0);
239
+ if (isShowingNavigationBar){
240
+ navigationBar.transform = JSAffineTransform.Identity;
241
+ }else if (isHidingNavigationBar){
242
+ navigationBar.transform = fromView.transform;
243
+ }
244
+ });
245
+ this.pushAnimator.addCompletion(function(){
246
+ this.pushAnimator = null;
247
+ navigationBar.hidden = item.hidesNavigationBar;
248
+ if (isHidingNavigationBar){
249
+ navigationBar.transform = JSAffineTransform.Identity;
250
+ navigationBar.pushItem(item, false);
251
+ }
252
+ fromView.removeFromSuperview();
253
+ fromView.transform = JSAffineTransform.Identity;
254
+ view.shadowColor = null;
255
+ if (this.delegate && this.delegate.navigationControllerDidShowViewController){
256
+ this.delegate.navigationControllerDidShowViewController(this, viewController);
257
+ }
258
+ }, this);
259
+ this.pushAnimator.start();
260
+ }else{
261
+ fromViewController.scheduleDisappearance();
262
+ viewController.scheduleAppearance();
263
+ this.scheduleDelegateShowViewController(viewController);
264
+ if (isShowingNavigationBar){
265
+ this.view.addSubview(navigationBar);
266
+ this.view.insertSubviewBelowSibling(view, navigationBar);
267
+ navigationBar.pushItem(item, false);
268
+ }else if (isHidingNavigationBar){
269
+ this.view.addSubview(view);
270
+ }else{
271
+ this.view.insertSubviewAboveSibling(view, fromView);
272
+ navigationBar.pushItem(item, animated);
273
+ }
274
+ fromView.removeFromSuperview();
275
+ this.view.setNeedsLayout();
276
+ navigationBar.hidden = item.hidesNavigationBar;
277
+ }
278
+ }else{
279
+ fromView.removeFromSuperview();
280
+ if (item.hidesNavigationBar){
281
+ this.view.addSubview(view);
282
+ }else{
283
+ this.view.insertSubviewBelowSibling(view, navigationBar);
284
+ }
285
+ navigationBar.pushItem(item, false);
286
+ navigationBar.hidden = item.hidesNavigationBar;
287
+ this.view.setNeedsLayout();
192
288
  }
193
- fromViewController.view.removeFromSuperview();
194
- this.view.setNeedsLayout();
195
289
  }else{
196
- var navController = this;
197
- this.layoutChildView(viewController.view);
198
- viewController.view.transform = JSAffineTransform.Translated(viewController.view.bounds.size.width, 0);
199
- viewController.view.shadowColor = JSColor.windowShadow;
200
- viewController.view.shadowRadius = 20;
201
- this.pushAnimator.addAnimations(function(){
202
- viewController.view.transform = JSAffineTransform.Identity;
203
- fromViewController.view.transform = JSAffineTransform.Translated(-fromViewController.view.bounds.size.width / 2, 0);
204
- });
205
- this.pushAnimator.addCompletion(function(){
206
- navController.pushAnimator = null;
207
- fromViewController.view.removeFromSuperview();
208
- fromViewController.viewDidDisappear(true);
209
- fromViewController.view.transform = JSAffineTransform.Identity;
210
- viewController.shadowColor = null;
211
- viewController.viewDidAppear(true);
212
- if (navController.delegate && navController.delegate.navigationControllerDidShowViewController){
213
- navController.delegate.navigationControllerDidShowViewController(navController, viewController);
214
- }
215
- });
216
- JSRunLoop.main.schedule(function(){
217
- this.pushAnimator.start();
218
- }, this);
290
+ navigationBar.hidden = item.hidesNavigationBar;
291
+ navigationBar.pushItem(item, false);
219
292
  }
220
293
  },
221
294
 
@@ -241,59 +314,100 @@ JSClass("UINavigationController", UIViewController, {
241
314
  if (index === this._viewControllers.length - 1){
242
315
  return;
243
316
  }
244
- if (!this.isViewVisible){
245
- animated = false;
246
- }
247
- if (animated){
248
- this.popAnimator = this.createPopAnimator();
249
- }
250
317
  var fromViewController = this.topViewController;
318
+ var fromView = fromViewController.view;
319
+ var fromItem = fromViewController.navigationItem;
251
320
  var view = viewController.view;
252
- if (this.isViewVisible){
253
- fromViewController.viewWillDisappear(animated);
254
- viewController.viewWillAppear(animated);
255
- }
256
- if (this.delegate && this.delegate.navigationControllerWillShowViewController){
257
- this.delegate.navigationControllerWillShowViewController(this, viewController);
321
+ var item = viewController.navigationItem;
322
+ var navigationBar = this._navigationBar;
323
+ var i, l;
324
+ for (i = this._viewControllers.length - 1; i > index; --i){
325
+ this._viewControllers[i].removeFromParentViewController();
326
+ this._viewControllers.pop();
258
327
  }
259
- this._viewControllers.splice(index + 1, this._viewControllers.length - index);
260
- this._navigationBar.popToItem(viewController.navigationItem, animated);
261
- this.view.insertSubviewBelowSibling(view, fromViewController.view);
262
- if (!animated){
328
+ if (this.isViewLoaded){
263
329
  if (this.isViewVisible){
264
- fromViewController.enqueueDidDisappear();
265
- viewController.enqueueDidAppear();
266
- }
267
- if (this.delegate && this.delegate.navigationControllerDidShowViewController){
268
- this.delegate.navigationControllerDidShowViewController(this, viewController);
330
+ var isHidingNavigationBar = !fromItem.hidesNavigationBar && item.hidesNavigationBar;
331
+ var isShowingNavigationBar = fromItem.hidesNavigationBar && !item.hidesNavigationBar;
332
+ if (animated){
333
+ this.popAnimator = this.createPopAnimator();
334
+ fromViewController.beginDisappearanceWithAnimator(this.popAnimator);
335
+ viewController.beginAppearanceWithAnimator(this.popAnimator);
336
+ if (this.delegate && this.delegate.navigationControllerWillShowViewController){
337
+ this.delegate.navigationControllerWillShowViewController(this, viewController);
338
+ }
339
+ if (isShowingNavigationBar){
340
+ this.view.insertSubviewBelowSibling(view, navigationBar);
341
+ navigationBar.popToItem(item, false);
342
+ }else if (isHidingNavigationBar){
343
+ this.view.insertSubviewBelowSibling(view, fromView);
344
+ }else{
345
+ this.view.insertSubviewBelowSibling(view, fromView);
346
+ navigationBar.popToItem(item, animated);
347
+ }
348
+ this.layoutChildViewController(viewController);
349
+ view.transform = JSAffineTransform.Translated(-view.bounds.size.width / 2, 0);
350
+ fromView.shadowColor = JSColor.windowShadow;
351
+ fromView.shadowRadius = 20;
352
+ if (isShowingNavigationBar){
353
+ navigationBar.transform = view.transform;
354
+ navigationBar.hidden = false;
355
+ }
356
+ this.popAnimator.addAnimations(function(){
357
+ view.transform = JSAffineTransform.Identity;
358
+ fromView.transform = JSAffineTransform.Translated(fromView.bounds.size.width, 0);
359
+ if (isShowingNavigationBar){
360
+ navigationBar.transform = JSAffineTransform.Identity;
361
+ }else if (isHidingNavigationBar){
362
+ navigationBar.transform = fromView.transform;
363
+ }
364
+ });
365
+ this.popAnimator.addCompletion(function(){
366
+ this.popAnimator = null;
367
+ navigationBar.hidden = item.hidesNavigationBar;
368
+ if (isHidingNavigationBar){
369
+ navigationBar.transform = JSAffineTransform.Identity;
370
+ navigationBar.setItem(item, false);
371
+ }
372
+ fromView.removeFromSuperview();
373
+ fromView.shadowColor = null;
374
+ fromView.transform = JSAffineTransform.Identity;
375
+ if (this.delegate && this.delegate.navigationControllerDidShowViewController){
376
+ this.delegate.navigationControllerDidShowViewController(this, viewController);
377
+ }
378
+ }, this);
379
+ this.popAnimator.start();
380
+ }else{
381
+ fromViewController.scheduleDisappearance();
382
+ viewController.scheduleAppearance();
383
+ this.scheduleDelegateShowViewController(viewController);
384
+ if (isShowingNavigationBar){
385
+ this.view.insertSubviewBelowSibling(view, navigationBar);
386
+ navigationBar.popToItem(item, false);
387
+ }else if (isHidingNavigationBar){
388
+ this.view.insertSubviewBelowSibling(view, fromView);
389
+ }else{
390
+ this.view.insertSubviewBelowSibling(view, fromView);
391
+ navigationBar.popToItem(item, animated);
392
+ }
393
+ fromView.removeFromSuperview();
394
+ this.view.setNeedsLayout();
395
+ navigationBar.hidden = item.hidesNavigationBar;
396
+ }
397
+ }else{
398
+ fromView.removeFromSuperview();
399
+ if (item.hidesNavigationBar){
400
+ this.view.addSubview(view);
401
+ }else{
402
+ this.view.insertSubviewBelowSibling(view, navigationBar);
403
+ }
404
+ navigationBar.popToItem(item, false);
405
+ navigationBar.hidden = item.hidesNavigationBar;
406
+ this.view.setNeedsLayout();
269
407
  }
270
- fromViewController.view.removeFromSuperview();
271
- this.view.setNeedsLayout();
272
408
  }else{
273
- var navController = this;
274
- this.layoutChildView(viewController.view);
275
- viewController.view.transform = JSAffineTransform.Translated(-viewController.view.bounds.size.width / 2, 0);
276
- fromViewController.view.shadowColor = JSColor.windowShadow;
277
- fromViewController.view.shadowRadius = 20;
278
- this.popAnimator.addAnimations(function(){
279
- viewController.view.transform = JSAffineTransform.Identity;
280
- fromViewController.view.transform = JSAffineTransform.Translated(fromViewController.view.bounds.size.width, 0);
281
- });
282
- this.popAnimator.addCompletion(function(){
283
- fromViewController.view.removeFromSuperview();
284
- navController.popAnimator = null;
285
- fromViewController.removeFromParentViewController();
286
- fromViewController.shadowColor = null;
287
- viewController.viewDidAppear(animated);
288
- fromViewController.viewDidDisappear(animated);
289
- fromViewController.view.transform = JSAffineTransform.Identity;
290
- if (navController.delegate && navController.delegate.navigationControllerDidShowViewController){
291
- navController.delegate.navigationControllerDidShowViewController(navController, viewController);
292
- }
293
- });
294
- JSRunLoop.main.schedule(function(){
295
- this.popAnimator.start();
296
- }, this);
409
+ navigationBar.hidden = item.hidesNavigationBar;
410
+ navigationBar.popToItem(item, false);
297
411
  }
298
412
  },
299
413
 
@@ -314,6 +428,7 @@ JSClass("UINavigationController", UIViewController, {
314
428
  this.pushViewController(viewController, animated);
315
429
  },
316
430
 
431
+ // --------------------------------------------------------------------
317
432
  // MARK: Layout
318
433
 
319
434
  automaticallyAdjustsInsets: true,
@@ -321,18 +436,19 @@ JSClass("UINavigationController", UIViewController, {
321
436
  viewDidLayoutSubviews: function(){
322
437
  var barHeight = this._navigationBar.intrinsicSize.height;
323
438
  var size = this.view.bounds.size;
324
- var contentView = this.topViewController.view;
325
439
  this._navigationBar.frame = JSRect(0, 0, size.width, barHeight);
326
- this.layoutChildView(contentView);
440
+ this.layoutChildViewController(this.topViewController);
327
441
  },
328
442
 
329
- layoutChildView: function(view){
443
+ layoutChildViewController: function(viewController){
330
444
  var y;
445
+ var view = viewController.view;
331
446
  var size = this.view.bounds.size;
332
447
  var barFrame = this._navigationBar.frame;
333
- if (this._navigationBar.coversContent){
448
+ var barHidden = viewController.navigationItem.hidesNavigationBar;
449
+ if (barHidden || this._navigationBar.coversContent){
334
450
  y = barFrame.origin.y;
335
- if (this.automaticallyAdjustsInsets && view.isKindOfClass(UIScrollView)){
451
+ if (!barHidden && this.automaticallyAdjustsInsets && view.isKindOfClass(UIScrollView)){
336
452
  var insets = JSInsets(view.contentInsets);
337
453
  insets.top = this._navigationBar.coveredContentTopInset;
338
454
  view.contentInsets = insets;
@@ -21,6 +21,7 @@ JSClass("UINavigationItem", JSObject, {
21
21
 
22
22
  title: JSDynamicProperty('_title', null),
23
23
  view: JSDynamicProperty('_view', null),
24
+ hidesNavigationBar: false,
24
25
  backBarButtonItem: JSDynamicProperty('_backBarButtonItem', null),
25
26
  rightBarItems: JSDynamicProperty('_rightBarItems', null),
26
27
  leftBarItems: JSDynamicProperty('_leftBarItems', null),
@@ -40,6 +41,9 @@ JSClass("UINavigationItem", JSObject, {
40
41
  if (spec.containsKey("view")){
41
42
  this._view = spec.valueForKey("view", UIView);
42
43
  }
44
+ if (spec.containsKey("hidesNavigationBar")){
45
+ this.hidesNavigationBar = spec.valueForKey("hidesNavigationBar");
46
+ }
43
47
  if (spec.containsKey("backBarButtonItem")){
44
48
  this._backBarButtonItem = spec.valueForKey("backBarButtonItem", UINavigationItem);
45
49
  }