@breakside/jskit 2026.8.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.
- package/Frameworks/DOM.jsframework/Info.json +2 -2
- package/Frameworks/DOM.jsframework/io.breakside.JSKit.DOM-bundle.js +2 -2
- package/Frameworks/FontKit.jsframework/Info.json +2 -2
- package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
- package/Frameworks/Foundation.jsframework/Info.json +2 -2
- package/Frameworks/Foundation.jsframework/JS/JSColor.js +5 -0
- package/Frameworks/Foundation.jsframework/JS/JSPath.js +482 -49
- package/Frameworks/Foundation.jsframework/JS/JSRect.js +12 -0
- package/Frameworks/Foundation.jsframework/JS/JSSpec.js +5 -1
- package/Frameworks/Foundation.jsframework/JS/String+JS.js +78 -2
- package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
- package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
- package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
- package/Info.json +2 -2
- package/Node/DocCommand.js +5 -2
- package/Node/Docs/DocClass.js +2 -2
- package/Node/Docs/DocComponent.js +6 -4
- package/Node/Docs/DocDictionaryProperty.js +2 -2
- package/Node/Docs/DocEnumOption.js +2 -2
- package/Node/Docs/DocFunction.js +2 -2
- package/Node/Docs/DocProperty.js +2 -2
- package/Node/Docs/DocProtocol.js +1 -1
- package/Node/Docs/DocSpec.js +1 -1
- package/Node/Docs/DocSpecProperty.js +2 -2
- package/Node/Docs/DocTopicBasedComponent.js +2 -2
- package/Node/Documentation.js +10 -2
- package/Node/HTMLBuilder.js +3 -1
- package/Node/HTMLProjectServer.js +39 -1
- package/Node/io.breakside.jskit-bundle.js +4 -4
- package/Resources/doc-default.css +4 -4
- package/Root/Frameworks/APIKit/Info.yaml +1 -1
- package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
- package/Root/Frameworks/AuthKit/Info.yaml +1 -1
- package/Root/Frameworks/CSSOM/Info.yaml +1 -1
- package/Root/Frameworks/ChartKit/Info.yaml +1 -1
- package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
- package/Root/Frameworks/DBKit/Info.yaml +1 -1
- package/Root/Frameworks/DOM/Info.yaml +1 -1
- package/Root/Frameworks/Dispatch/Info.yaml +1 -1
- package/Root/Frameworks/FontKit/Info.yaml +1 -1
- package/Root/Frameworks/Foundation/Info.yaml +1 -1
- package/Root/Frameworks/Foundation/JSColor.js +5 -0
- package/Root/Frameworks/Foundation/JSPath.js +482 -49
- package/Root/Frameworks/Foundation/JSRect.js +12 -0
- package/Root/Frameworks/Foundation/JSSpec.js +5 -1
- package/Root/Frameworks/Foundation/String+JS.js +78 -2
- package/Root/Frameworks/ImageKit/Info.yaml +1 -1
- package/Root/Frameworks/MediaKit/Info.yaml +1 -1
- package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
- package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
- package/Root/Frameworks/PDFKit/Info.yaml +1 -1
- package/Root/Frameworks/QRKit/Info.yaml +1 -1
- package/Root/Frameworks/SearchKit/Info.yaml +1 -1
- package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
- package/Root/Frameworks/ServerKit/Info.yaml +1 -1
- package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
- package/Root/Frameworks/TestKit/Info.yaml +1 -1
- package/Root/Frameworks/UIKit/Info.yaml +1 -1
- package/Root/Frameworks/UIKit/UIApplication.js +5 -1
- package/Root/Frameworks/UIKit/UIHTMLApplication.js +24 -0
- package/Root/Frameworks/UIKit/UIHTMLWindowServer.js +17 -3
- package/Root/Frameworks/UIKit/UIKit.js +2 -0
- package/Root/Frameworks/UIKit/UIListView.js +11 -3
- package/Root/Frameworks/UIKit/UIOutlineView.js +65 -5
- package/Root/Frameworks/UIKit/UIPopupWindow.js +15 -5
- package/Root/Frameworks/UIKit/UITextAction.js +16 -0
- package/Root/Frameworks/UIKit/UITextActionsMenu.js +95 -0
- package/Root/Frameworks/UIKit/UITextEditor.js +57 -7
- package/Root/Frameworks/UIKit/UITextField.js +102 -0
- package/Root/Frameworks/UIKit/en.lproj/Localizable.strings.yaml +4 -1
- package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
- 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
|
-
|
|
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){
|
|
@@ -438,11 +438,15 @@ JSClass('UIApplication', UIResponder, {
|
|
|
438
438
|
target = this.firstTargetForAction(action, target, sender);
|
|
439
439
|
if (target !== null){
|
|
440
440
|
actionLogger.debug("sendAction " + action + " to %{public}#%d from %{public}#%d", target.$class.className, target.objectID, sender.$class.className, sender.objectID);
|
|
441
|
-
target
|
|
441
|
+
this._sendAction(action, target, sender, event);
|
|
442
442
|
}
|
|
443
443
|
}
|
|
444
444
|
},
|
|
445
445
|
|
|
446
|
+
_sendAction: function(action, target, sender, event){
|
|
447
|
+
target[action](sender, event);
|
|
448
|
+
},
|
|
449
|
+
|
|
446
450
|
targetForAction: function(action, sender){
|
|
447
451
|
var target = UIApplication.$super.targetForAction.call(this, action, sender);
|
|
448
452
|
if (target !== null){
|
|
@@ -140,6 +140,30 @@ JSClass("UIHTMLApplication", UIApplication, {
|
|
|
140
140
|
return url;
|
|
141
141
|
},
|
|
142
142
|
|
|
143
|
+
_sendAction: function(action, target, sender, event){
|
|
144
|
+
var application = this;
|
|
145
|
+
var window = this.domWindow;
|
|
146
|
+
if (action === "paste" && sender !== this.windowServer){
|
|
147
|
+
if (this.domWindow.navigator.clipboard){
|
|
148
|
+
logger.info("sending paste action with clipboard.readText");
|
|
149
|
+
window.navigator.clipboard.readText().then(function(text){
|
|
150
|
+
var strings = {};
|
|
151
|
+
strings[UIPasteboard.ContentType.plainText] = text;
|
|
152
|
+
UIPasteboard.general.withStrings(strings, function(){
|
|
153
|
+
UIHTMLApplication.$super._sendAction.call(application, action, target, sender, event);
|
|
154
|
+
});
|
|
155
|
+
}, function(e){
|
|
156
|
+
logger.warn("could not readText() from clipboard: %{error}", e);
|
|
157
|
+
});
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
logger.info("sending paste action with document.execCommand");
|
|
161
|
+
this.domWindow.document.execCommand("paste");
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
UIHTMLApplication.$super._sendAction.call(this, action, target, sender, event);
|
|
165
|
+
},
|
|
166
|
+
|
|
143
167
|
addEventListeners: function(){
|
|
144
168
|
this.domWindow.addEventListener("error", this);
|
|
145
169
|
this.domWindow.addEventListener("unhandledrejection", this);
|
|
@@ -690,7 +690,7 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
|
|
|
690
690
|
return;
|
|
691
691
|
}
|
|
692
692
|
UIPasteboard.general.withDataTransfer(e.clipboardData, function(){
|
|
693
|
-
this.keyWindow.application.sendAction('cut');
|
|
693
|
+
this.keyWindow.application.sendAction('cut', null, this);
|
|
694
694
|
}, this);
|
|
695
695
|
},
|
|
696
696
|
|
|
@@ -702,7 +702,7 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
|
|
|
702
702
|
return;
|
|
703
703
|
}
|
|
704
704
|
UIPasteboard.general.withDataTransfer(e.clipboardData, function(){
|
|
705
|
-
this.keyWindow.application.sendAction('copy');
|
|
705
|
+
this.keyWindow.application.sendAction('copy', null, this);
|
|
706
706
|
}, this);
|
|
707
707
|
},
|
|
708
708
|
|
|
@@ -714,7 +714,7 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
|
|
|
714
714
|
return;
|
|
715
715
|
}
|
|
716
716
|
UIPasteboard.general.withDataTransfer(e.clipboardData, function(){
|
|
717
|
-
this.keyWindow.application.sendAction('paste');
|
|
717
|
+
this.keyWindow.application.sendAction('paste', null, this);
|
|
718
718
|
}, this);
|
|
719
719
|
},
|
|
720
720
|
|
|
@@ -1513,6 +1513,20 @@ JSClass("UIHTMLDataTransferPasteboard", UIPasteboard, {
|
|
|
1513
1513
|
}
|
|
1514
1514
|
return UIHTMLDataTransferPasteboard.$super.containsType.call(this, type);
|
|
1515
1515
|
},
|
|
1516
|
+
|
|
1517
|
+
withStrings: function(strings, action, target){
|
|
1518
|
+
var locallySetTypes = JSCopy(this._locallySetTypes);
|
|
1519
|
+
try{
|
|
1520
|
+
for (var type in strings){
|
|
1521
|
+
this.setStringForType(strings[type], type);
|
|
1522
|
+
}
|
|
1523
|
+
action.call(target);
|
|
1524
|
+
}finally{
|
|
1525
|
+
this._locallySetTypes = locallySetTypes;
|
|
1526
|
+
this.dataTransfer = null;
|
|
1527
|
+
}
|
|
1528
|
+
},
|
|
1529
|
+
|
|
1516
1530
|
});
|
|
1517
1531
|
|
|
1518
1532
|
|
|
@@ -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
|
-
|
|
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
|
|
|
@@ -116,17 +116,27 @@ JSClass("UIPopupWindow", UIWindow, {
|
|
|
116
116
|
},
|
|
117
117
|
|
|
118
118
|
openAdjacentToView: function(view, preferredPlacement, animated){
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
var rect = view.bounds;
|
|
120
|
+
if (view.sourceRectForPopupWindow){
|
|
121
|
+
rect = view.sourceRectForPopupWindow(this);
|
|
121
122
|
}
|
|
123
|
+
this.openAdjacentToRectInView(rect, view, preferredPlacement, animated);
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
openAtLocationInView: function(location, view, preferredPlacement, animated){
|
|
127
|
+
var rect = JSRect(location, JSSize.Zero);
|
|
128
|
+
this.openAdjacentToRectInView(rect, view, preferredPlacement, animated);
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
openAdjacentToRectInView: function(rect, view, preferredPlacement, animated){
|
|
122
132
|
if (view.window === null || view.window.screen === null){
|
|
123
133
|
JSNotificationCenter.shared.post("UIWindowWillClose", this);
|
|
124
134
|
return;
|
|
125
135
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
sourceBounds = view.sourceRectForPopupWindow(this);
|
|
136
|
+
if (animated === undefined){
|
|
137
|
+
animated = true;
|
|
129
138
|
}
|
|
139
|
+
var sourceBounds = rect;
|
|
130
140
|
var sourceFrame = view.convertRectToScreen(sourceBounds).rectWithInsets(-this._sourceSpacing);
|
|
131
141
|
var safeFrame = view.window.screen.availableFrame.rectWithInsets(20);
|
|
132
142
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// #import Foundation
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
JSClass("UITextAction", JSObject, {
|
|
5
|
+
|
|
6
|
+
title: null,
|
|
7
|
+
action: null,
|
|
8
|
+
target: null,
|
|
9
|
+
|
|
10
|
+
initWithTitle: function(title, action, target){
|
|
11
|
+
this.title = title;
|
|
12
|
+
this.action = action;
|
|
13
|
+
this.target = target || null;
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
});
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// #import "UIPopupWindow.js"
|
|
2
|
+
// #import "UIButton.js"
|
|
3
|
+
// #import "UIStackView.js"
|
|
4
|
+
"use strict";
|
|
5
|
+
|
|
6
|
+
JSClass("UITextActionsMenu", JSObject, {
|
|
7
|
+
|
|
8
|
+
delegate: null,
|
|
9
|
+
|
|
10
|
+
initWithActions: function(actions){
|
|
11
|
+
this.actions = actions;
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
openAtLocationInView: function(location, sourceView){
|
|
15
|
+
if (this._window !== null){
|
|
16
|
+
this._window.orderFront();
|
|
17
|
+
}else{
|
|
18
|
+
var window = UITextActionsMenuWindow.init(UITextActionsMenu.Styler.default);
|
|
19
|
+
window.contentInsets = JSInsets.Zero;
|
|
20
|
+
var buttons = [];
|
|
21
|
+
var button;
|
|
22
|
+
var action;
|
|
23
|
+
for (var i = 0, l = this.actions.length; i < l; ++i){
|
|
24
|
+
action = this.actions[i];
|
|
25
|
+
button = UIButton.initWithStyler(UITextActionsMenu.ButtonStyler.default);
|
|
26
|
+
button.titleLabel.text = action.title;
|
|
27
|
+
button.addAction(action.action, action.target);
|
|
28
|
+
button.addAction("close", this);
|
|
29
|
+
buttons.push(button);
|
|
30
|
+
}
|
|
31
|
+
var stackView = UIStackView.initWithArrangedSubviews(buttons);
|
|
32
|
+
stackView.cornerRadius = window.cornerRadius;
|
|
33
|
+
stackView.clipsToBounds = true;
|
|
34
|
+
stackView.backgroundColor = JSColor.separator;
|
|
35
|
+
stackView.viewSpacing = 1;
|
|
36
|
+
stackView.axis = UIStackView.Axis.horizontal;
|
|
37
|
+
window.contentView = stackView;
|
|
38
|
+
window.openAtLocationInView(location, sourceView, UIPopupWindow.Placement.above, false);
|
|
39
|
+
this._window = window;
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
close: function(){
|
|
44
|
+
if (this._window !== null){
|
|
45
|
+
this._window.close();
|
|
46
|
+
this._window = null;
|
|
47
|
+
if (this.delegate && this.delegate.textActionsMenuDidClose){
|
|
48
|
+
this.delegate.textActionsMenuDidClose(this);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
_window: null,
|
|
54
|
+
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
UITextActionsMenu.Styler = Object.create({}, {
|
|
58
|
+
|
|
59
|
+
default: {
|
|
60
|
+
configurable: true,
|
|
61
|
+
get: function(){
|
|
62
|
+
var styler = UIPopupWindowStyler.init();
|
|
63
|
+
styler.cornerRadius = 7;
|
|
64
|
+
Object.defineProperty(this, "default", {value: styler, writable: true});
|
|
65
|
+
return styler;
|
|
66
|
+
},
|
|
67
|
+
set: function(value){
|
|
68
|
+
Object.defineProperty(this, "default", {value: value, writable: true});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
UITextActionsMenu.ButtonStyler = Object.create({}, {
|
|
75
|
+
|
|
76
|
+
default: {
|
|
77
|
+
configurable: true,
|
|
78
|
+
get: function(){
|
|
79
|
+
var styler = UIButtonCustomStyler.initWithBackgroundColor(JSColor.background, JSColor.highlight);
|
|
80
|
+
styler.titleInsets = JSInsets(10, 10, 10, 10);
|
|
81
|
+
Object.defineProperty(this, "default", {value: styler, writable: true});
|
|
82
|
+
return styler;
|
|
83
|
+
},
|
|
84
|
+
set: function(value){
|
|
85
|
+
Object.defineProperty(this, "default", {value: value, writable: true});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
JSClass("UITextActionsMenuWindow", UIPopupWindow, {
|
|
92
|
+
|
|
93
|
+
canBecomeKey: false,
|
|
94
|
+
|
|
95
|
+
});
|