@breakside/jskit 2026.9.0 → 2026.10.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 (60) 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 +5 -0
  7. package/Frameworks/Foundation.jsframework/JS/JSPath.js +482 -49
  8. package/Frameworks/Foundation.jsframework/JS/JSSpec.js +5 -1
  9. package/Frameworks/Foundation.jsframework/JS/String+JS.js +78 -2
  10. package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
  11. package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
  12. package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
  13. package/Info.json +2 -2
  14. package/Node/DocCommand.js +5 -2
  15. package/Node/Docs/DocClass.js +2 -2
  16. package/Node/Docs/DocComponent.js +6 -4
  17. package/Node/Docs/DocDictionaryProperty.js +2 -2
  18. package/Node/Docs/DocEnumOption.js +2 -2
  19. package/Node/Docs/DocFunction.js +2 -2
  20. package/Node/Docs/DocProperty.js +2 -2
  21. package/Node/Docs/DocProtocol.js +1 -1
  22. package/Node/Docs/DocSpec.js +1 -1
  23. package/Node/Docs/DocSpecProperty.js +2 -2
  24. package/Node/Docs/DocTopicBasedComponent.js +2 -2
  25. package/Node/Documentation.js +10 -2
  26. package/Node/HTMLBuilder.js +3 -1
  27. package/Node/HTMLProjectServer.js +39 -1
  28. package/Node/io.breakside.jskit-bundle.js +4 -4
  29. package/Resources/doc-default.css +1 -9
  30. package/Root/Frameworks/APIKit/Info.yaml +1 -1
  31. package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
  32. package/Root/Frameworks/AuthKit/Info.yaml +1 -1
  33. package/Root/Frameworks/CSSOM/Info.yaml +1 -1
  34. package/Root/Frameworks/ChartKit/Info.yaml +1 -1
  35. package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
  36. package/Root/Frameworks/DBKit/Info.yaml +1 -1
  37. package/Root/Frameworks/DOM/Info.yaml +1 -1
  38. package/Root/Frameworks/Dispatch/Info.yaml +1 -1
  39. package/Root/Frameworks/FontKit/Info.yaml +1 -1
  40. package/Root/Frameworks/Foundation/Info.yaml +1 -1
  41. package/Root/Frameworks/Foundation/JSColor.js +5 -0
  42. package/Root/Frameworks/Foundation/JSPath.js +482 -49
  43. package/Root/Frameworks/Foundation/JSSpec.js +5 -1
  44. package/Root/Frameworks/Foundation/String+JS.js +78 -2
  45. package/Root/Frameworks/ImageKit/Info.yaml +1 -1
  46. package/Root/Frameworks/MediaKit/Info.yaml +1 -1
  47. package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
  48. package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
  49. package/Root/Frameworks/PDFKit/Info.yaml +1 -1
  50. package/Root/Frameworks/QRKit/Info.yaml +1 -1
  51. package/Root/Frameworks/SearchKit/Info.yaml +1 -1
  52. package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
  53. package/Root/Frameworks/ServerKit/Info.yaml +1 -1
  54. package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
  55. package/Root/Frameworks/TestKit/Info.yaml +1 -1
  56. package/Root/Frameworks/UIKit/Info.yaml +1 -1
  57. package/Root/Frameworks/UIKit/UIListView.js +11 -3
  58. package/Root/Frameworks/UIKit/UIOutlineView.js +65 -5
  59. package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
  60. package/package.json +1 -1
@@ -1592,7 +1592,7 @@ String.printf_formatter = {
1592
1592
 
1593
1593
  x: function(arg, options){
1594
1594
  // TODO: obey any other options
1595
- var str = arg.toString(16);
1595
+ var str = Math.floor(arg).toString(16);
1596
1596
  if (options.width){
1597
1597
  if (options.zero){
1598
1598
  str = str.leftPaddedString('0', options.width);
@@ -1633,7 +1633,83 @@ String.printf_formatter = {
1633
1633
  if (Math.abs(arg) < 0.000001){
1634
1634
  arg = 0;
1635
1635
  }
1636
- return (arg !== null && arg !== undefined && arg.toString) ? arg.toString() : arg;
1636
+ var n = arg;
1637
+ if (n === null){
1638
+ return "null";
1639
+ }
1640
+ if (n === undefined){
1641
+ return "undefined";
1642
+ }
1643
+ if (isNaN(n)){
1644
+ return "NaN";
1645
+ }
1646
+ if (!isFinite(n)){
1647
+ if (n < 0){
1648
+ return "-Inf";
1649
+ }
1650
+ return "Inf";
1651
+ }
1652
+
1653
+ // Prefix & Suffix
1654
+ var negative = n < 0;
1655
+ var prefix = "";
1656
+ if (negative){
1657
+ n = -n;
1658
+ prefix = "-";
1659
+ }
1660
+
1661
+ // Integer
1662
+ var maximumFractionDigits = options.precision || 6;
1663
+ var minimumFractionDigits = options.precision || 0;
1664
+ var minimumIntegerDigits = options.zero ? 1 : 0;
1665
+ var integer = Math.floor(n);
1666
+ var fraction = n - integer;
1667
+ var maximumFraction = Math.pow(10, maximumFractionDigits);
1668
+ fraction = Math.round(fraction * maximumFraction);
1669
+ if (fraction >= maximumFraction){
1670
+ integer += 1;
1671
+ fraction = 0;
1672
+ }
1673
+ var str = (integer !== 0 || (minimumIntegerDigits === 0 && minimumFractionDigits === 0)) ? integer.toString() : "";
1674
+ var zeroFillCount = minimumIntegerDigits - str.length;
1675
+ var i, l;
1676
+ if (zeroFillCount > 0){
1677
+ var fill = "";
1678
+ for (i = 0; i < zeroFillCount; ++i){
1679
+ fill += "0";
1680
+ }
1681
+ str = fill + str;
1682
+ }
1683
+
1684
+ // Decimal
1685
+ if (maximumFraction > 0){
1686
+ if (minimumFractionDigits > 0 || fraction !== 0){
1687
+ if (minimumFractionDigits > 0 || fraction !== 0){
1688
+ str += ".";
1689
+ var fractionString = fraction.toString();
1690
+ while (fractionString.length < maximumFractionDigits){
1691
+ fractionString = "0" + fractionString;
1692
+ }
1693
+ while (fractionString.length > minimumFractionDigits && fractionString[fractionString.length - 1] === "0"){
1694
+ fractionString = fractionString.substr(0, fractionString.length - 1);
1695
+ }
1696
+ str += fractionString;
1697
+ }
1698
+ }
1699
+ }
1700
+ str = prefix + str;
1701
+ if (options.width){
1702
+ if (options.zero){
1703
+ str = str.leftPaddedString('0', options.width);
1704
+ }else if (options.left_justified){
1705
+ str = str.rightPaddedString(' ', options.width);
1706
+ }else{
1707
+ str = str.leftPaddedString(' ', options.width);
1708
+ }
1709
+ }else if (str === ""){
1710
+ str = "0";
1711
+ }
1712
+ return str;
1637
1713
  },
1638
1714
 
1639
1715
  b: function(arg, options){
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ImageKit
3
- JSBundleVersion: 2026.9.0
3
+ JSBundleVersion: 2026.10.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: 2026.9.0
3
+ JSBundleVersion: 2026.10.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: 2026.9.0
3
+ JSBundleVersion: 2026.10.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: 2026.9.0
3
+ JSBundleVersion: 2026.10.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: 2026.9.0
3
+ JSBundleVersion: 2026.10.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: 2026.9.0
3
+ JSBundleVersion: 2026.10.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: 2026.9.0
3
+ JSBundleVersion: 2026.10.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: 2026.9.0
3
+ JSBundleVersion: 2026.10.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: 2026.9.0
3
+ JSBundleVersion: 2026.10.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.ServerKitTesting
3
- JSBundleVersion: 2026.9.0
3
+ JSBundleVersion: 2026.10.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: 2026.9.0
3
+ JSBundleVersion: 2026.10.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: 2026.9.0
3
+ JSBundleVersion: 2026.10.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -175,6 +175,7 @@ JSClass("UIListView", UIScrollView, {
175
175
 
176
176
  delegate: null,
177
177
  dataSource: null,
178
+ _dataSourceIsValid: false,
178
179
 
179
180
  // --------------------------------------------------------------------
180
181
  // MARK: - Styling
@@ -325,6 +326,7 @@ JSClass("UIListView", UIScrollView, {
325
326
  return;
326
327
  }
327
328
  this._needsReload = true;
329
+ this._dataSourceIsValid = false;
328
330
  this.setNeedsLayout();
329
331
  },
330
332
 
@@ -579,6 +581,7 @@ JSClass("UIListView", UIScrollView, {
579
581
  selectionChanged: false,
580
582
  };
581
583
  this._needsUpdate = true;
584
+ this._dataSourceIsValid = false;
582
585
  this.setNeedsLayout();
583
586
  }
584
587
  if (animation != UIListView.RowAnimation.none && this._edit.animator === null){
@@ -655,6 +658,7 @@ JSClass("UIListView", UIScrollView, {
655
658
 
656
659
  layoutSubviews: function(){
657
660
  UIListView.$super.layoutSubviews.call(this);
661
+ this._dataSourceIsValid = true;
658
662
  var origin = JSPoint.Zero;
659
663
  var fitSize = JSSize(this.bounds.size.width, Number.MAX_VALUE);
660
664
  // We have to size the header and footer first, so a reloadDuringLayout
@@ -1121,6 +1125,7 @@ JSClass("UIListView", UIScrollView, {
1121
1125
  this.__numberOfSections = this.__numberOfSections + edit.insertedSections.length - edit.deletedSections.length;
1122
1126
  this._updateVisibleIndexPathsForEdit(edit);
1123
1127
  this._updateSelectedIndexPathsForEdit(edit);
1128
+ this._updateOtherIndexPathsForEdit(edit);
1124
1129
  if (edit.didDeleteSelectedItem){
1125
1130
  this._updateSelectedIndexPaths({notifyDelegate: true});
1126
1131
  }
@@ -1466,6 +1471,9 @@ JSClass("UIListView", UIScrollView, {
1466
1471
  }
1467
1472
  },
1468
1473
 
1474
+ _updateOtherIndexPathsForEdit: function(edit){
1475
+ },
1476
+
1469
1477
  _createViewsForEdit: function(edit, anchorIndex, anchorY, rect){
1470
1478
  var diff = {offset: 0, height: 0};
1471
1479
  var items = this._visibleItems;
@@ -1597,7 +1605,7 @@ JSClass("UIListView", UIScrollView, {
1597
1605
  cell.position = JSPoint(rect.origin.x + cell.bounds.size.width * cell.anchorPoint.x, rect.origin.y + cell.bounds.size.height * cell.anchorPoint.y);
1598
1606
  cell.active = false;
1599
1607
  cell.over = false;
1600
- this._updateCellState(cell);
1608
+ this._updateCellState(cell, true);
1601
1609
  cell.update();
1602
1610
  cell.setNeedsLayout();
1603
1611
  return cell;
@@ -2002,12 +2010,12 @@ JSClass("UIListView", UIScrollView, {
2002
2010
  for (var i = 0, l = this._visibleItems.length; i < l; ++i){
2003
2011
  item = this._visibleItems[i];
2004
2012
  if (item.kind === VisibleItem.Kind.cell){
2005
- this._updateCellState(item.view);
2013
+ this._updateCellState(item.view, this._dataSourceIsValid && item.indexPath !== null);
2006
2014
  }
2007
2015
  }
2008
2016
  },
2009
2017
 
2010
- _updateCellState: function(cell){
2018
+ _updateCellState: function(cell, dataSourceIsValid){
2011
2019
  cell.selected = this._selectionContainsIndexPath(cell.indexPath);
2012
2020
  cell.contextSelected = this._contextSelectionContainsIndexPath(cell.indexPath);
2013
2021
  },
@@ -102,7 +102,7 @@ JSClass("UIOutlineView", UIListView, {
102
102
  this._edit.insertedIndexPaths.push({indexPath: JSIndexPath(iterator.indexPath), animation:this.expandRowAnimation});
103
103
  }
104
104
  if (visibleCell){
105
- this._updateCellState(visibleCell);
105
+ this._updateCellState(visibleCell, true);
106
106
  visibleCell.postAccessibilityNotification(UIAccessibility.Notification.rowExpanded);
107
107
  }
108
108
  this.postAccessibilityNotification(UIAccessibility.Notification.rowCountChanged);
@@ -139,7 +139,7 @@ JSClass("UIOutlineView", UIListView, {
139
139
  }
140
140
  }
141
141
  if (visibleCell){
142
- this._updateCellState(visibleCell);
142
+ this._updateCellState(visibleCell, true);
143
143
  visibleCell.postAccessibilityNotification(UIAccessibility.Notification.rowCollapsed);
144
144
  }
145
145
  this.postAccessibilityNotification(UIAccessibility.Notification.rowCountChanged);
@@ -220,9 +220,11 @@ JSClass("UIOutlineView", UIListView, {
220
220
  UIOutlineView.$super.keyUp.call(this, event);
221
221
  },
222
222
 
223
- _updateCellState: function(cell){
224
- UIOutlineView.$super._updateCellState.call(this, cell);
225
- cell.expandable = this.dataSource.outlineViewIsExandableAtIndexPath(this, cell.indexPath);
223
+ _updateCellState: function(cell, dataSourceIsValid){
224
+ UIOutlineView.$super._updateCellState.call(this, cell, dataSourceIsValid);
225
+ if (dataSourceIsValid){
226
+ cell.expandable = this.dataSource.outlineViewIsExandableAtIndexPath(this, cell.indexPath);
227
+ }
226
228
  cell.expanded = cell.expandable && this._isIndexPathExpanded(cell.indexPath);
227
229
  },
228
230
 
@@ -252,6 +254,64 @@ JSClass("UIOutlineView", UIListView, {
252
254
  return row;
253
255
  },
254
256
 
257
+ _updateOtherIndexPathsForEdit: function(edit){
258
+ UIOutlineView.$super._updateOtherIndexPathsForEdit.call(this, edit);
259
+ var expandedIndexPaths = Array.from(this._expandedIndexPaths).map(function(indexPathString){
260
+ var indexes = indexPathString.split(".").map(function(indexString){
261
+ return parseInt(indexString);
262
+ });
263
+ return JSIndexPath(indexes);
264
+ });
265
+ expandedIndexPaths.sort(JSIndexPath.compare);
266
+ var i, l;
267
+ var section, indexPath;
268
+ var index;
269
+ var searcher = JSBinarySearcher(expandedIndexPaths, JSIndexPath.compare);
270
+ var parent;
271
+ var selectedLength = expandedIndexPaths.length;
272
+ for (i = edit.deletedIndexPaths.length - 1; i >= 0; --i){
273
+ indexPath = edit.deletedIndexPaths[i].indexPath;
274
+ parent = indexPath.removingLastIndex();
275
+ index = searcher.insertionIndexForValue(indexPath);
276
+ if (index < selectedLength && expandedIndexPaths[index].isEqual(indexPath)){
277
+ expandedIndexPaths.splice(index, 1);
278
+ --selectedLength;
279
+ }
280
+ for (; index < selectedLength && expandedIndexPaths[index].startsWith(parent); ++index){
281
+ expandedIndexPaths[index][parent.length]--;
282
+ }
283
+ }
284
+ for (i = edit.deletedSections.length - 1; i >= 0; --i){
285
+ section = edit.deletedSections[i].section;
286
+ index = searcher.insertionIndexForValue(JSIndexPath(section, 0));
287
+ for (; index < selectedLength && expandedIndexPaths[index].section == section; --selectedLength){
288
+ expandedIndexPaths.splice(index, 1);
289
+ }
290
+ for (; index < selectedLength; ++index){
291
+ expandedIndexPaths[index].section--;
292
+ }
293
+ }
294
+ for (i = 0, l = edit.insertedSections.length; i < l; ++i){
295
+ section = edit.insertedSections[i].section;
296
+ index = searcher.insertionIndexForValue(JSIndexPath(section, 0));
297
+ for (; index < selectedLength && expandedIndexPaths[index].section >= section; ++index){
298
+ expandedIndexPaths[index].section++;
299
+ }
300
+ }
301
+ for (i = 0, l = edit.insertedIndexPaths.length; i < l; ++i){
302
+ indexPath = edit.insertedIndexPaths[i].indexPath;
303
+ parent = indexPath.removingLastIndex();
304
+ index = searcher.insertionIndexForValue(indexPath);
305
+ for (; index < selectedLength && expandedIndexPaths[index].startsWith(parent); ++index){
306
+ expandedIndexPaths[index][parent.length]++;
307
+ }
308
+ }
309
+ this._expandedIndexPaths = new Set();
310
+ for (i = 0, l = expandedIndexPaths.length; i < l; ++i){
311
+ this._expandedIndexPaths.add(expandedIndexPaths[i].toString());
312
+ }
313
+ },
314
+
255
315
  // --------------------------------------------------------------------
256
316
  // MARK: - Acessibility
257
317
 
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.UIKitTesting
3
- JSBundleVersion: 2026.9.0
3
+ JSBundleVersion: 2026.10.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "node": ">=10.10.0"
13
13
  },
14
14
  "name": "@breakside/jskit",
15
- "version": "2026.9.0",
15
+ "version": "2026.10.0",
16
16
  "license": "SEE LICENSE IN LICENSE.txt",
17
17
  "files": [
18
18
  "*"