@breakside/jskit 2022.7.0 → 2022.11.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 (56) 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/JS/FNTFontDescriptor.js +9 -6
  5. package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
  6. package/Frameworks/Foundation.jsframework/Info.json +2 -2
  7. package/Frameworks/Foundation.jsframework/JS/JSHTMLHTTPClient.js +9 -1
  8. package/Frameworks/Foundation.jsframework/JS/JSImage.js +12 -5
  9. package/Frameworks/Foundation.jsframework/JS/JSURLResponse.js +10 -0
  10. package/Frameworks/Foundation.jsframework/JS/JSXMLParser.js +81 -8
  11. package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
  12. package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
  13. package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
  14. package/Info.json +2 -2
  15. package/Node/io.breakside.jskit-bundle.js +2 -2
  16. package/Root/Frameworks/APIKit/Info.yaml +1 -1
  17. package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
  18. package/Root/Frameworks/AuthKit/Info.yaml +1 -1
  19. package/Root/Frameworks/CSSOM/Info.yaml +1 -1
  20. package/Root/Frameworks/ChartKit/Info.yaml +1 -1
  21. package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
  22. package/Root/Frameworks/DBKit/DBRedisStore.js +2 -1
  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/Dispatch/JSHTMLDispatchQueue.js +4 -2
  27. package/Root/Frameworks/FontKit/FNTFontDescriptor.js +9 -6
  28. package/Root/Frameworks/FontKit/Info.yaml +1 -1
  29. package/Root/Frameworks/Foundation/Info.yaml +1 -1
  30. package/Root/Frameworks/Foundation/JSHTMLHTTPClient.js +9 -1
  31. package/Root/Frameworks/Foundation/JSImage.js +12 -5
  32. package/Root/Frameworks/Foundation/JSURLResponse.js +10 -0
  33. package/Root/Frameworks/Foundation/JSXMLParser.js +81 -8
  34. package/Root/Frameworks/ImageKit/Info.yaml +1 -1
  35. package/Root/Frameworks/MediaKit/Info.yaml +1 -1
  36. package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
  37. package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
  38. package/Root/Frameworks/PDFKit/Info.yaml +1 -1
  39. package/Root/Frameworks/QRKit/Info.yaml +1 -1
  40. package/Root/Frameworks/SearchKit/Info.yaml +1 -1
  41. package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
  42. package/Root/Frameworks/ServerKit/Info.yaml +1 -1
  43. package/Root/Frameworks/ServerKit/SKHTTPServer+Node.js +8 -0
  44. package/Root/Frameworks/ServerKit/SKHTTPServer.js +1 -1
  45. package/Root/Frameworks/ServerKit/SKNodeHTTPRequest.js +3 -0
  46. package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
  47. package/Root/Frameworks/TestKit/Info.yaml +1 -1
  48. package/Root/Frameworks/UIKit/Info.yaml +1 -1
  49. package/Root/Frameworks/UIKit/UIApplication.js +15 -1
  50. package/Root/Frameworks/UIKit/UICollectionView.js +21 -32
  51. package/Root/Frameworks/UIKit/UIScene.js +5 -1
  52. package/Root/Frameworks/UIKit/UIScrollView.js +15 -12
  53. package/Root/Frameworks/UIKit/UISegmentedControl.js +15 -0
  54. package/Root/Frameworks/UIKit/UITabView.js +5 -6
  55. package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
  56. package/package.json +1 -1
@@ -36,6 +36,7 @@ JSClass("JSXMLParser", JSObject, {
36
36
  var c;
37
37
  var lineNumber = 1;
38
38
  var lineOffset;
39
+ var entityMap = JSCopy(defaultEntityMap);
39
40
  var readToken = function(){
40
41
  if (offset >= length){
41
42
  return null;
@@ -131,8 +132,77 @@ JSClass("JSXMLParser", JSObject, {
131
132
  return {kind: 'PI', name: name, value: readUntil('?>')};
132
133
  }
133
134
  if (token == '<!DOCTYPE'){
134
- var parts = readUntil('>').trim().split(' ');
135
- return {kind: 'Doctype', name: parts[0], publicId: parts[1], systemId: parts[2]};
135
+ readWhitespace();
136
+ name = readName();
137
+ readWhitespace();
138
+ var doctype = {kind: 'Doctype', name: name, publicId: null, systemId: null, entities: {}};
139
+ if (offset < length && input[offset] !== '>'){
140
+ if (input[offset] != '['){
141
+ name = readName();
142
+ readWhitespace();
143
+ if (name == "SYSTEM"){
144
+ if (offset < length && (input[offset] == "'" || input[offset] == '"')){
145
+ doctype.systemId = readAttributeValue();
146
+ readWhitespace();
147
+ }else{
148
+ throw new Error("Expecting quote at " + lineNumber + ':' + (offset - lineOffset));
149
+ }
150
+ }else if (name === "PUBLIC"){
151
+ if (offset < length && (input[offset] == "'" || input[offset] == '"')){
152
+ doctype.publicId = readAttributeValue();
153
+ readWhitespace();
154
+ if (offset < length && (input[offset] == "'" || input[offset] == '"')){
155
+ doctype.systemId = readAttributeValue();
156
+ readWhitespace();
157
+ }else{
158
+ throw new Error("Expecting quote at " + lineNumber + ':' + (offset - lineOffset));
159
+ }
160
+ }else{
161
+ throw new Error("Expecting quote at " + lineNumber + ':' + (offset - lineOffset));
162
+ }
163
+ }else{
164
+ throw new Error("Expecting SYSTEM or PUBLIC at " + lineNumber + ':' + (offset - lineOffset));
165
+ }
166
+ }
167
+ if (offset < length && input[offset] == '['){
168
+ ++offset;
169
+ readWhitespace();
170
+ while (offset < length && input[offset] !== ']'){
171
+ token = readToken();
172
+ if (token == '<!'){
173
+ name = readName();
174
+ if (name === "ENTITY"){
175
+ readWhitespace();
176
+ if (offset >= length){
177
+ throw new Error("Expecting ENTITY name at " + lineNumber + ':' + (offset - lineOffset));
178
+ }
179
+ name = readName();
180
+ readWhitespace();
181
+ if (offset >= length){
182
+ throw new Error("Expecting ENTITY value at " + lineNumber + ':' + (offset - lineOffset));
183
+ }
184
+ entityMap[name] = readAttributeValue();
185
+ }
186
+ readUntil('>');
187
+ }else if (token == '<?'){
188
+ readUntil('?>');
189
+ }else if (token == '<!--'){
190
+ readUntil('-->');
191
+ }
192
+ readWhitespace();
193
+ }
194
+ if (offset >= length || input[offset] !== ']'){
195
+ throw new Error("Expecting ] at end of DOCTYPE at " + lineNumber + ':' + (offset - lineOffset));
196
+ }
197
+ ++offset;
198
+ readWhitespace();
199
+ }
200
+ }
201
+ if (offset >= length || input[offset] !== '>'){
202
+ throw new Error("Expecting > at end of DOCTYPE at " + lineNumber + ':' + (offset - lineOffset));
203
+ }
204
+ ++offset;
205
+ return doctype;
136
206
  }
137
207
  if (token == '<![CDATA['){
138
208
  return {kind: 'CDATA', value: readUntil(']]>')};
@@ -154,7 +224,7 @@ JSClass("JSXMLParser", JSObject, {
154
224
  if (offset < length && input[offset] == '='){
155
225
  ++offset;
156
226
  readWhitespace();
157
- attributes.push({name: attrName, value: textByDecodingEntities(readAttributeValue())});
227
+ attributes.push({name: attrName, value: textByDecodingEntities(readAttributeValue(), entityMap)});
158
228
  }else{
159
229
  attributes.push({name: attrName, value: null});
160
230
  }
@@ -189,7 +259,7 @@ JSClass("JSXMLParser", JSObject, {
189
259
  ++offset;
190
260
  return {kind: 'ElementEnd', name: name};
191
261
  }
192
- return {kind: 'Text', value: textByDecodingEntities(token)};
262
+ return {kind: 'Text', value: textByDecodingEntities(token, entityMap)};
193
263
  };
194
264
  var readUntil = function(token){
195
265
  var index = input.indexOf(token, offset);
@@ -267,7 +337,10 @@ JSClass("JSXMLParser", JSObject, {
267
337
  }
268
338
  obj = readObject();
269
339
  var elementNameStack = [];
270
- var namespaces = {':default:': null};
340
+ var namespaces = {
341
+ ':default:': null,
342
+ 'xml': 'http://www.w3.org/XML/1998/namespace'
343
+ };
271
344
  var namespacesStack = [];
272
345
  var hasDocumentElement = false;
273
346
  var hasSentDoctype = false;
@@ -361,7 +434,7 @@ JSClass("JSXMLParser", JSObject, {
361
434
 
362
435
  });
363
436
 
364
- var textByDecodingEntities = function(text){
437
+ var textByDecodingEntities = function(text, map){
365
438
  var index = text.indexOf('&');
366
439
  var length = text.length;
367
440
  var end;
@@ -390,7 +463,7 @@ var textByDecodingEntities = function(text){
390
463
  value = String.fromCharCode(code);
391
464
  }
392
465
  }else{
393
- value = entityMap[entity] || null;
466
+ value = map[entity] || null;
394
467
  if (value === null){
395
468
  throw new Error("Cannot lookup entity: &" + entity + ';');
396
469
  }
@@ -404,7 +477,7 @@ var textByDecodingEntities = function(text){
404
477
  return text;
405
478
  };
406
479
 
407
- var entityMap = {
480
+ var defaultEntityMap = {
408
481
  'lt': '<',
409
482
  'LT': '<',
410
483
  'gt': '>',
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ImageKit
3
- JSBundleVersion: 2022.7.0
3
+ JSBundleVersion: 2022.11.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.MediaKit
3
- JSBundleVersion: 2022.7.0
3
+ JSBundleVersion: 2022.11.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.MediaKitUI
3
- JSBundleVersion: 2022.7.0
3
+ JSBundleVersion: 2022.11.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.NotificationKit
3
- JSBundleVersion: 2022.7.0
3
+ JSBundleVersion: 2022.11.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2021 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.PDFKit
3
- JSBundleVersion: 2022.7.0
3
+ JSBundleVersion: 2022.11.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.QRKit
3
- JSBundleVersion: 2022.7.0
3
+ JSBundleVersion: 2022.11.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.SearchKit
3
- JSBundleVersion: 2022.7.0
3
+ JSBundleVersion: 2022.11.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.SecurityKit
3
- JSBundleVersion: 2022.7.0
3
+ JSBundleVersion: 2022.11.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ServerKit
3
- JSBundleVersion: 2022.7.0
3
+ JSBundleVersion: 2022.11.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -85,6 +85,10 @@ SKHTTPServer.definePropertiesFromExtensions({
85
85
  _handleNodeRequest: function(nodeRequest, nodeResponse){
86
86
  try{
87
87
  var request = SKNodeHTTPRequest.initWithNodeRequest(nodeRequest, nodeResponse);
88
+ if (request === null){
89
+ nodeRequest.socket.destroy();
90
+ return;
91
+ }
88
92
  if (this.tlsCertificate && this.tlsPrivateKey){
89
93
  request.url.scheme = "https";
90
94
  }
@@ -98,6 +102,10 @@ SKHTTPServer.definePropertiesFromExtensions({
98
102
  _handleNodeUpgrade: function(nodeRequest, socket, headPacket){
99
103
  try{
100
104
  var request = SKNodeHTTPRequest.initWithNodeRequest(nodeRequest, null);
105
+ if (request === null){
106
+ nodeRequest.socket.destroy();
107
+ return;
108
+ }
101
109
  this.handleUpgrade(request);
102
110
  }catch(e){
103
111
  nodeRequest.socket.destroy();
@@ -148,7 +148,7 @@ JSClass("SKHTTPServer", JSObject, {
148
148
  if (this.delegate && this.delegate.serverRouteNotFoundForRequest){
149
149
  this.delegate.serverRouteNotFoundForRequest(this, request);
150
150
  }
151
- request.logger.warn("%{public} %{public} No route for request", request.method, request.url.path);
151
+ request.logger.info("%{public} %{public} No route for request", request.method, request.url.path);
152
152
  throw new SKHTTPError(SKHTTPResponse.StatusCode.notFound);
153
153
  }
154
154
 
@@ -25,6 +25,9 @@ JSClass("SKNodeHTTPRequest", SKHTTPRequest, {
25
25
 
26
26
  initWithNodeRequest: function(nodeRequest, nodeResponse){
27
27
  var url = JSURL.initWithString(nodeRequest.url);
28
+ if (url === null){
29
+ return null;
30
+ }
28
31
  if (url.pathComponents.length === 0){
29
32
  url.path = "/";
30
33
  }
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ServerKitTesting
3
- JSBundleVersion: 2022.7.0
3
+ JSBundleVersion: 2022.11.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.TestKit
3
- JSBundleVersion: 2022.7.0
3
+ JSBundleVersion: 2022.11.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.UIKit
3
- JSBundleVersion: 2022.7.0
3
+ JSBundleVersion: 2022.11.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -126,7 +126,7 @@ JSClass('UIApplication', UIResponder, {
126
126
  JSFont.Size[size] = Math.round(JSFont.Size[size] * 1.2);
127
127
  }
128
128
  }
129
- this.windowServer.displayServer.registerFontDescriptors(descriptors, function(error){
129
+ this.registerFontDescriptors(descriptors, function(error){
130
130
  completion.call(target, error);
131
131
  }, this);
132
132
  },
@@ -427,9 +427,23 @@ JSClass('UIApplication', UIResponder, {
427
427
  this.windowServer.createMouseEvent(UIEvent.Type.leftMouseUp, event.timestamp, location);
428
428
  },
429
429
 
430
+ // MARK: - Fonts
431
+
432
+ registerFontDescriptor: function(descriptor, completion, target){
433
+ return this.registerFontDescriptors([descriptor], completion, target);
434
+ },
435
+
436
+ registerFontDescriptors: function(descriptors, completion, target){
437
+ return this.windowServer.displayServer.registerFontDescriptors(descriptors, completion, target);
438
+ },
439
+
440
+ // MARK: - URLs
441
+
430
442
  openURL: function(url, options){
431
443
  },
432
444
 
445
+ // MARK: - Environment
446
+
433
447
  getenv: function(name, defaultValue){
434
448
  return this.environment.get(name, defaultValue);
435
449
  },
@@ -19,6 +19,8 @@
19
19
  // #import "UICollectionViewLayout.js"
20
20
  "use strict";
21
21
 
22
+ (function(){
23
+
22
24
  JSProtocol("UICollectionViewDelegate", JSProtocol, {
23
25
 
24
26
  // Selection
@@ -286,12 +288,12 @@ JSClass("UICollectionView", UIScrollView, {
286
288
  },
287
289
 
288
290
  reloadCellsAtIndexPaths: function(indexPaths, animator){
291
+ if (this._needsReload){
292
+ return;
293
+ }
289
294
  if (this._visibleElements.length === 0){
290
295
  return;
291
296
  }
292
- var firstVisibleElement = this._visibleElements[0];
293
- var lastVisibleElement = this._visibleElements[this._visibleElements.length - 1];
294
- var searcher = JSBinarySearcher(this._visibleElements, VisibleElement.indexPathCompare);
295
297
 
296
298
  indexPaths = JSCopy(indexPaths);
297
299
  indexPaths.sort(function(a, b){
@@ -301,28 +303,25 @@ JSClass("UICollectionView", UIScrollView, {
301
303
  var i, l;
302
304
  var indexPath;
303
305
  var comparison;
304
- var elementIndex;
306
+ var elementIndex = 0;
307
+ var elementCount = this._visibleElements.length;
305
308
  var cell;
306
309
  var element;
307
310
 
308
311
  for (i = 0, l = indexPaths.length; i < l; ++i){
309
312
  indexPath = indexPaths[i];
310
- comparison = VisibleElement.indexPathCompare(indexPath, lastVisibleElement);
311
- if (comparison <= 0){
312
- comparison = VisibleElement.indexPathCompare(indexPath, firstVisibleElement);
313
- if (comparison >= 0){
314
- elementIndex = searcher.indexMatchingValue(indexPath);
315
- if (elementIndex !== null){
316
- element = this._visibleElements[elementIndex];
317
- cell = element.view;
318
- this._enqueueReusableCell(cell);
319
- cell = this._createCellWithAttributes(element.attributes);
320
- if (cell !== element.view){
321
- this._elementsContainerView.insertSubviewBelowSibling(cell, element.view);
322
- element.view.removeFromSuperview();
323
- element.view = cell;
324
- }
325
- }
313
+ while (elementIndex < elementCount && !this._visibleElements[elementIndex].indexPath.isEqual(indexPath)){
314
+ ++elementIndex;
315
+ }
316
+ if (elementIndex < elementCount){
317
+ element = this._visibleElements[elementIndex];
318
+ cell = element.view;
319
+ this._enqueueReusableCell(cell);
320
+ cell = this._createCellWithAttributes(element.attributes);
321
+ if (cell !== element.view){
322
+ this._elementsContainerView.insertSubviewBelowSibling(cell, element.view);
323
+ element.view.removeFromSuperview();
324
+ element.view = cell;
326
325
  }
327
326
  }
328
327
  }
@@ -1226,15 +1225,7 @@ VisibleElement.prototype = Object.create(Function.prototype, {
1226
1225
  indexPath: { value: null, writable: true },
1227
1226
  rect: { value: null, writable: true, configurable: true },
1228
1227
  kind: { value: null, writable: true },
1229
- view: {
1230
- configurable: true,
1231
- set: function(view){
1232
- Object.defineProperty(this, 'view', {value: view});
1233
- },
1234
- get: function(){
1235
- return null;
1236
- }
1237
- },
1228
+ view: { value: null, writable: true },
1238
1229
  state: { value: null, writable: true },
1239
1230
  animation: { value: null, writable: true },
1240
1231
 
@@ -1249,6 +1240,4 @@ VisibleElement.prototype = Object.create(Function.prototype, {
1249
1240
 
1250
1241
  });
1251
1242
 
1252
- VisibleElement.indexPathCompare = function VisibleElement_indexPathCompare(indexPath, element){
1253
- return indexPath.compare(element.indexPath);
1254
- };
1243
+ })();
@@ -56,6 +56,10 @@ JSClass("UIScene", JSObject, {
56
56
  },
57
57
 
58
58
  show: function(){
59
+ if (UIScene._visible !== null){
60
+ UIScene._visible.close();
61
+ }
62
+ UIScene._visible = this;
59
63
  if (this.menuBar){
60
64
  this.application.windowServer.menuBar = this.menuBar;
61
65
  }
@@ -67,7 +71,6 @@ JSClass("UIScene", JSObject, {
67
71
  if (window !== null){
68
72
  window.makeKey();
69
73
  }
70
- UIScene._visible = this;
71
74
  },
72
75
 
73
76
  close: function(){
@@ -80,6 +83,7 @@ JSClass("UIScene", JSObject, {
80
83
  window = windowServer.windowStack[i];
81
84
  window.close();
82
85
  }
86
+ UIScene._visible = null;
83
87
  },
84
88
 
85
89
  });
@@ -37,16 +37,19 @@ JSClass('UIScrollView', UIView, {
37
37
  initWithSpec: function(spec){
38
38
  UIScrollView.$super.initWithSpec.call(this, spec);
39
39
 
40
- // 1. If any subviews were added directly to this view, we'll move them
41
- // to the contentView once it's ready
42
- var contentSubviews = JSCopy(this.subviews);
43
-
44
- // 2. If the content view and scrollers are specified in the spec, create them
45
- // before doing the _commonScrollViewInit, so it won't try to create them itself.
46
- // These properties are optional in the spec, and are typically only provided if
47
- // the user wants to provide specialized customization
40
+ var contentSubviews = [];
41
+
42
+ // If the content view and scrollers are specified in the spec, create them
43
+ // before doing the _commonScrollViewInit, so it won't try to create them itself.
44
+ // These properties are optional in the spec, and are typically only provided if
45
+ // the user wants to provide specialized customization
48
46
  if (spec.containsKey('contentView')){
49
47
  this._contentView = spec.valueForKey("contentView", UIView);
48
+ }else{
49
+ // If any subviews were added directly to this view, and a
50
+ // contentView was not provided, treat the subviews as children
51
+ // of the contentView
52
+ contentSubviews = JSCopy(this.subviews);
50
53
  }
51
54
  if (spec.containsKey('verticalScroller')){
52
55
  this._verticalScroller = spec.valueForKey("verticalScroller", UIScroller);
@@ -59,13 +62,13 @@ JSClass('UIScrollView', UIView, {
59
62
  }
60
63
  this._commonScrollViewInit();
61
64
 
62
- // 3. Finish the work from step #1 after _commonScrollViewInit, when we can be sure that
63
- // a contentView has been created
65
+ // Finish the contentSubvies work after _commonScrollViewInit,
66
+ // when we can be sure that a contentView has been created
64
67
  for (var i = 0, l = contentSubviews.length; i < l; ++i){
65
68
  this._contentView.addSubview(contentSubviews[i]);
66
69
  }
67
70
 
68
- // 4. Handle all the other properties
71
+ // Handle all the other properties
69
72
  if (spec.containsKey('contentInsets')){
70
73
  this.contentInsets = spec.valueForKey("contentInsets", JSInsets);
71
74
  }
@@ -105,7 +108,7 @@ JSClass('UIScrollView', UIView, {
105
108
  this._maxContentOffset = JSPoint.Zero;
106
109
  this._horizontalScroller.addAction("_horizontalScrollerValueChanged", this, UIControl.Event.valueChanged);
107
110
  this._verticalScroller.addAction("_verticalScrollerValueChanged", this, UIControl.Event.valueChanged);
108
- this.addSubview(this._contentView);
111
+ this.insertSubviewAtIndex(this._contentView, 0);
109
112
  this.addSubview(this._verticalScroller);
110
113
  this.addSubview(this._horizontalScroller);
111
114
  this._updateScrollers();
@@ -769,6 +769,21 @@ JSClass("UISegmentedControlDefaultStyler", UISegmentedControlStyler, {
769
769
  }
770
770
  },
771
771
 
772
+ sizeControlToFitSize: function(control, maxSize){
773
+ var intrinsicSize = this.intrinsicSizeOfControl(control);
774
+ var size = JSSize(control.bounds.size);
775
+ if (maxSize.width < Number.MAX_VALUE){
776
+ size.width = maxSize.width;
777
+ }
778
+ if (intrinsicSize.width < maxSize.width){
779
+ size.width = intrinsicSize.width;
780
+ }
781
+ if (intrinsicSize.height < maxSize.height){
782
+ size.height = intrinsicSize.height;
783
+ }
784
+ control.bounds = JSRect(JSPoint.Zero, size);
785
+ },
786
+
772
787
  intrinsicSizeOfControl: function(control){
773
788
  var itemView;
774
789
  var size = JSSize.Zero;
@@ -59,16 +59,14 @@ JSClass("UITabView", UIView, {
59
59
  if (spec.containsKey('delegate')){
60
60
  this.delegate = spec.valueForKey("delegate");
61
61
  }
62
+ if (spec.containsKey("font")){
63
+ this.font = spec.valueForKey("font", JSFont);
64
+ }
62
65
  if (spec.containsKey('items')){
63
- var items = [];
64
66
  var specItems = spec.valueForKey('items');
65
67
  for (var i = 0, l = specItems.length; i < l; ++i){
66
- items.push(specItems.valueForKey(i, UITabViewItem));
68
+ this.insertItemAtIndex(specItems.valueForKey(i, UITabViewItem), i);
67
69
  }
68
- this.items = items;
69
- }
70
- if (spec.containsKey("font")){
71
- this.font = spec.valueForKey("font", JSFont);
72
70
  }
73
71
  },
74
72
 
@@ -1067,6 +1065,7 @@ JSClass("UITabViewTablessStyler", UITabViewStyler, {
1067
1065
  showContentViewInTabView: function(contentView, tabView){
1068
1066
  tabView.addSubview(contentView);
1069
1067
  tabView.stylerProperties.contentView = contentView;
1068
+ this.layoutTabView(tabView);
1070
1069
  },
1071
1070
 
1072
1071
  removeContentViewFromTabView: function(contentView, tabView){
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.UIKitTesting
3
- JSBundleVersion: 2022.7.0
3
+ JSBundleVersion: 2022.11.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "node": ">=10.10.0"
10
10
  },
11
11
  "name": "@breakside/jskit",
12
- "version": "2022.7.0",
12
+ "version": "2022.11.0",
13
13
  "license": "SEE LICENSE IN LICENSE.txt",
14
14
  "files": [
15
15
  "*"