@breakside/jskit 2022.23.0 → 2022.24.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/JSAttributedString.js +139 -10
- package/Frameworks/Foundation.jsframework/JS/JSParagraphStyle.js +71 -0
- package/Frameworks/Foundation.jsframework/JS/JSTextAttachment.js +1 -1
- package/Frameworks/Foundation.jsframework/JS/JSTextContainer.js +56 -29
- package/Frameworks/Foundation.jsframework/JS/JSTextFrame.js +2 -32
- package/Frameworks/Foundation.jsframework/JS/JSTextFramesetter.js +125 -22
- package/Frameworks/Foundation.jsframework/JS/JSTextLayoutManager.js +11 -3
- package/Frameworks/Foundation.jsframework/JS/JSTextLine.js +4 -3
- package/Frameworks/Foundation.jsframework/JS/JSTextRun.js +5 -3
- package/Frameworks/Foundation.jsframework/JS/JSTextTypesetter.js +41 -25
- package/Frameworks/Foundation.jsframework/JS/String+JS.js +35 -0
- package/Frameworks/Foundation.jsframework/JS/UnicodeChar.js +8 -0
- package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
- package/Frameworks/Foundation.jsframework/sources.json +3 -0
- 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/io.breakside.jskit-bundle.js +2 -2
- package/Node/jskit +1 -0
- 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/CHAxis.js +5 -5
- package/Root/Frameworks/ChartKit/CHPieChart.js +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/JSAttributedString.js +139 -10
- package/Root/Frameworks/Foundation/JSParagraphStyle.js +71 -0
- package/Root/Frameworks/Foundation/JSTextAttachment.js +1 -1
- package/Root/Frameworks/Foundation/JSTextContainer.js +56 -29
- package/Root/Frameworks/Foundation/JSTextFrame.js +2 -32
- package/Root/Frameworks/Foundation/JSTextFramesetter.js +125 -22
- package/Root/Frameworks/Foundation/JSTextLayoutManager.js +11 -3
- package/Root/Frameworks/Foundation/JSTextLine.js +4 -3
- package/Root/Frameworks/Foundation/JSTextRun.js +5 -3
- package/Root/Frameworks/Foundation/JSTextTypesetter.js +41 -25
- package/Root/Frameworks/Foundation/String+JS.js +35 -0
- package/Root/Frameworks/Foundation/UnicodeChar.js +8 -0
- 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/UIHTMLContentEditableTextInputManager.js +36 -0
- package/Root/Frameworks/UIKit/UIHTMLDisplayServer.js +1 -1
- package/Root/Frameworks/UIKit/UIHTMLTextField.js +1 -1
- package/Root/Frameworks/UIKit/UIHTMLTextFrame.js +19 -91
- package/Root/Frameworks/UIKit/UIHTMLTextFramesetter.js +52 -9
- package/Root/Frameworks/UIKit/UIHTMLTextLine.js +95 -30
- package/Root/Frameworks/UIKit/UIHTMLTextRun.js +22 -9
- package/Root/Frameworks/UIKit/UIHTMLTextTypesetter.js +334 -459
- package/Root/Frameworks/UIKit/UIHTMLWindowServer.js +16 -0
- package/Root/Frameworks/UIKit/UIScrollView.js +12 -0
- package/Root/Frameworks/UIKit/UISegmentedControl.js +6 -6
- package/Root/Frameworks/UIKit/UITextAttachmentView.js +1 -1
- package/Root/Frameworks/UIKit/UITextEditor.js +210 -25
- package/Root/Frameworks/UIKit/UITextField.js +58 -31
- package/Root/Frameworks/UIKit/UITextInput.js +3 -1
- package/Root/Frameworks/UIKit/UITextInputManager.js +2 -2
- package/Root/Frameworks/UIKit/UITextLayer.js +39 -26
- package/Root/Frameworks/UIKit/UITokenField.js +4 -4
- package/Root/Frameworks/UIKit/UIView.js +3 -1
- package/Root/Frameworks/UIKit/UIWindow.js +16 -3
- package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
- package/package.json +1 -1
|
@@ -498,6 +498,14 @@ JSClass("UIHTMLWindowServer", UIWindowServer, {
|
|
|
498
498
|
preventDefault = true;
|
|
499
499
|
}
|
|
500
500
|
break;
|
|
501
|
+
case 66: // b
|
|
502
|
+
case 73: // i
|
|
503
|
+
case 85: // u
|
|
504
|
+
// For common formatting commands, we should prevent
|
|
505
|
+
// the browser's default behavior even if the text input
|
|
506
|
+
// system hinted that there was input.
|
|
507
|
+
preventDefault = true;
|
|
508
|
+
break;
|
|
501
509
|
}
|
|
502
510
|
}
|
|
503
511
|
if (preventDefault){
|
|
@@ -1146,10 +1154,18 @@ JSClass("UIHTMLDataTransferPasteboard", UIPasteboard, {
|
|
|
1146
1154
|
},
|
|
1147
1155
|
|
|
1148
1156
|
withDataTransfer: function(dataTransfer, action, target){
|
|
1157
|
+
var locallySetTypes = JSCopy(this._locallySetTypes);
|
|
1149
1158
|
try{
|
|
1150
1159
|
this.dataTransfer = dataTransfer;
|
|
1160
|
+
this._updateDataTransferTypeSet();
|
|
1161
|
+
for (var type in this._dataTransferTypeSet){
|
|
1162
|
+
if (type in this._locallySetTypes){
|
|
1163
|
+
delete this._locallySetTypes[type];
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1151
1166
|
action.call(target);
|
|
1152
1167
|
}finally{
|
|
1168
|
+
this._locallySetTypes = locallySetTypes;
|
|
1153
1169
|
this.dataTransfer = null;
|
|
1154
1170
|
}
|
|
1155
1171
|
},
|
|
@@ -476,6 +476,18 @@ JSClass('UIScrollView', UIView, {
|
|
|
476
476
|
},
|
|
477
477
|
|
|
478
478
|
_didScroll: function(){
|
|
479
|
+
if (this.window !== null){
|
|
480
|
+
var responder = this.window.firstResponder;
|
|
481
|
+
if (responder && responder.isKindOfClass(UIView) && responder.focusRingPath !== null){
|
|
482
|
+
var superview = responder.superview;
|
|
483
|
+
while (superview !== null && superview !== this){
|
|
484
|
+
superview = superview.superview;
|
|
485
|
+
}
|
|
486
|
+
if (superview === this){
|
|
487
|
+
this.window.invalidateFocusRing(false);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
479
491
|
if (this.delegate && this.delegate.scrollViewDidScroll){
|
|
480
492
|
this.delegate.scrollViewDidScroll(this);
|
|
481
493
|
}
|
|
@@ -26,13 +26,13 @@ JSClass("UISegmentedControl", UIControl, {
|
|
|
26
26
|
// MARK: - Creating a segment control
|
|
27
27
|
|
|
28
28
|
initWithSpec: function(spec){
|
|
29
|
+
UISegmentedControl.$super.initWithSpec.call(this, spec);
|
|
29
30
|
if (spec.containsKey('font')){
|
|
30
31
|
this._font = spec.valueForKey("font", JSFont);
|
|
31
32
|
}
|
|
32
33
|
if (spec.containsKey('titleInsets')){
|
|
33
34
|
this._titleInsets = spec.valueForKey("titleInsets", JSInsets);
|
|
34
35
|
}
|
|
35
|
-
UISegmentedControl.$super.initWithSpec.call(this, spec);
|
|
36
36
|
var i, l;
|
|
37
37
|
if (spec.containsKey('items')){
|
|
38
38
|
var items = spec.valueForKey('items');
|
|
@@ -771,15 +771,15 @@ JSClass("UISegmentedControlDefaultStyler", UISegmentedControlStyler, {
|
|
|
771
771
|
|
|
772
772
|
sizeControlToFitSize: function(control, maxSize){
|
|
773
773
|
var intrinsicSize = this.intrinsicSizeOfControl(control);
|
|
774
|
-
var size = JSSize(
|
|
774
|
+
var size = JSSize(intrinsicSize);
|
|
775
775
|
if (maxSize.width < Number.MAX_VALUE){
|
|
776
776
|
size.width = maxSize.width;
|
|
777
777
|
}
|
|
778
|
-
if (
|
|
779
|
-
size.width =
|
|
778
|
+
if (maxSize.width < size.width){
|
|
779
|
+
size.width = maxSize.width;
|
|
780
780
|
}
|
|
781
|
-
if (
|
|
782
|
-
size.height =
|
|
781
|
+
if (maxSize.height < size.height){
|
|
782
|
+
size.height = maxSize.height;
|
|
783
783
|
}
|
|
784
784
|
control.bounds = JSRect(JSPoint.Zero, size);
|
|
785
785
|
},
|
|
@@ -31,7 +31,7 @@ JSClass("UITextAttachmentView", JSTextAttachment, {
|
|
|
31
31
|
|
|
32
32
|
layout: function(font, lineWidth){
|
|
33
33
|
this.view.sizeToFitSize(JSSize(lineWidth, Number.MAX_VALUE));
|
|
34
|
-
this.baselineAdjustment =
|
|
34
|
+
this.baselineAdjustment = this.view.lastBaselineOffsetFromBottom;
|
|
35
35
|
},
|
|
36
36
|
|
|
37
37
|
drawInContextAtPoint: function(context, point){
|
|
@@ -31,7 +31,6 @@ JSClass("UITextEditor", JSObject, {
|
|
|
31
31
|
delegate: null,
|
|
32
32
|
cursorColor: JSDynamicProperty('_cursorColor', null),
|
|
33
33
|
cursorWidth: 2.0,
|
|
34
|
-
insertAttributes: null,
|
|
35
34
|
_isFirstResponder: false,
|
|
36
35
|
_isWindowKey: false,
|
|
37
36
|
_cursorBlinkRate: 0.5,
|
|
@@ -207,6 +206,10 @@ JSClass("UITextEditor", JSObject, {
|
|
|
207
206
|
this._setSingleSelectionAtLocation(location);
|
|
208
207
|
},
|
|
209
208
|
|
|
209
|
+
handleTouchesEndedAtLocation: function(location, touches, event){
|
|
210
|
+
this._setSingleSelectionAtLocation(location);
|
|
211
|
+
},
|
|
212
|
+
|
|
210
213
|
handleTouchesEnded: function(touches, event){
|
|
211
214
|
},
|
|
212
215
|
|
|
@@ -416,6 +419,147 @@ JSClass("UITextEditor", JSObject, {
|
|
|
416
419
|
// -------------------------------------------------------------------------
|
|
417
420
|
// MARK: - Common editing operations
|
|
418
421
|
|
|
422
|
+
bold: function(sender){
|
|
423
|
+
this._toggleBooleanAttribute("bold", "Bold");
|
|
424
|
+
},
|
|
425
|
+
|
|
426
|
+
italic: function(sender){
|
|
427
|
+
this._toggleBooleanAttribute("italic", "Italic");
|
|
428
|
+
},
|
|
429
|
+
|
|
430
|
+
underline: function(sender){
|
|
431
|
+
this._toggleBooleanAttribute("underline", "Underline");
|
|
432
|
+
},
|
|
433
|
+
|
|
434
|
+
removeParagraphAttribute: function(name, undoName){
|
|
435
|
+
this.setParagraphAttribute(name, undefined, undoName);
|
|
436
|
+
},
|
|
437
|
+
|
|
438
|
+
setParagraphAttributes: function(attributes, undoName){
|
|
439
|
+
this.undoManager.beginUndoGrouping();
|
|
440
|
+
var name, value;
|
|
441
|
+
var i, l;
|
|
442
|
+
var selection;
|
|
443
|
+
var selections = this._selectionsCopy();
|
|
444
|
+
for (name in attributes){
|
|
445
|
+
value = attributes[name];
|
|
446
|
+
for (i = 0, l = selections.length; i < l; ++i){
|
|
447
|
+
selection = selections[i];
|
|
448
|
+
this._setParagraphAttributeForSelection(name, value, selection);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
this._setSelectionsAllowingUndo(selections);
|
|
452
|
+
this.undoManager.endUndoGrouping();
|
|
453
|
+
this.undoManager.setActionName(undoName);
|
|
454
|
+
},
|
|
455
|
+
|
|
456
|
+
setParagraphAttribute: function(name, value, undoName){
|
|
457
|
+
this.undoManager.beginUndoGrouping();
|
|
458
|
+
var i, l;
|
|
459
|
+
var selection;
|
|
460
|
+
var selections = this._selectionsCopy();
|
|
461
|
+
for (i = 0, l = selections.length; i < l; ++i){
|
|
462
|
+
selection = selections[i];
|
|
463
|
+
this._setParagraphAttributeForSelection(name, value, selection);
|
|
464
|
+
}
|
|
465
|
+
this._setSelectionsAllowingUndo(selections);
|
|
466
|
+
this.undoManager.endUndoGrouping();
|
|
467
|
+
this.undoManager.setActionName(undoName);
|
|
468
|
+
},
|
|
469
|
+
|
|
470
|
+
_setParagraphAttributeForSelection: function(name, value, selection){
|
|
471
|
+
var textStorage = this.textLayoutManager.textStorage;
|
|
472
|
+
var replacementString;
|
|
473
|
+
var replacementRange;
|
|
474
|
+
var paragraphRange;
|
|
475
|
+
paragraphRange = textStorage.string.rangeForParagraphAtIndex(selection.range.location);
|
|
476
|
+
replacementRange = JSRange(paragraphRange);
|
|
477
|
+
while (paragraphRange.length > 0 && paragraphRange.end < selection.range.end){
|
|
478
|
+
paragraphRange = textStorage.string.rangeForParagraphAtIndex(replacementRange.end);
|
|
479
|
+
replacementRange.length += paragraphRange.length;
|
|
480
|
+
}
|
|
481
|
+
if (replacementRange.length > 0){
|
|
482
|
+
replacementString = textStorage.attributedSubstringInRange(replacementRange);
|
|
483
|
+
if (value !== undefined){
|
|
484
|
+
replacementString.addAttributeInRange(name, value, JSRange(0, replacementString.string.length));
|
|
485
|
+
}else{
|
|
486
|
+
replacementString.removeAttributeInRange(name, JSRange(0, replacementString.string.length));
|
|
487
|
+
}
|
|
488
|
+
this._replaceTextStorageRangeAllowingUndo(textStorage, replacementRange, replacementString);
|
|
489
|
+
}else{
|
|
490
|
+
selection.attributes = this._insertAttributesForSelection(selection);
|
|
491
|
+
this.undoManager.registerUndo(this, this._setParagraphAttributeForSelection, name, selection.attributes[name], selection);
|
|
492
|
+
if (value !== undefined){
|
|
493
|
+
selection.attributes[name] = value;
|
|
494
|
+
}else{
|
|
495
|
+
delete selection.attributes[name];
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
},
|
|
499
|
+
|
|
500
|
+
_toggleBooleanAttribute: function(name, undoName){
|
|
501
|
+
var selection;
|
|
502
|
+
var textStorage = this.textLayoutManager.textStorage;
|
|
503
|
+
var locationAdjustment = 0;
|
|
504
|
+
var attributes;
|
|
505
|
+
var i, l;
|
|
506
|
+
var currentValue = true;
|
|
507
|
+
var runIterator;
|
|
508
|
+
for (i = 0, l = this.selections.length; i < l && currentValue === true; ++i){
|
|
509
|
+
selection = this.selections[i];
|
|
510
|
+
if (selection.range.length > 0){
|
|
511
|
+
runIterator = textStorage.runIterator(selection.range.location);
|
|
512
|
+
var j = 0;
|
|
513
|
+
while (runIterator.range.location < selection.range.end && currentValue === true && j < 10000){
|
|
514
|
+
if (!runIterator.attributes[name]){
|
|
515
|
+
currentValue = false;
|
|
516
|
+
}
|
|
517
|
+
runIterator.increment();
|
|
518
|
+
}
|
|
519
|
+
if (j === 10000){
|
|
520
|
+
throw new Error("infinite loop");
|
|
521
|
+
}
|
|
522
|
+
}else{
|
|
523
|
+
attributes = this._insertAttributesForSelection(selection);
|
|
524
|
+
if (!attributes[name]){
|
|
525
|
+
currentValue = false;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
this.undoManager.beginUndoGrouping();
|
|
530
|
+
var selections = this._selectionsCopy();
|
|
531
|
+
for (i = 0, l = selections.length; i < l; ++i){
|
|
532
|
+
selection = selections[i];
|
|
533
|
+
this._setBooleanAttributeForSelection(name, !currentValue, selection);
|
|
534
|
+
}
|
|
535
|
+
this._setSelectionsAllowingUndo(selections);
|
|
536
|
+
this.undoManager.endUndoGrouping();
|
|
537
|
+
this.undoManager.setActionName(undoName);
|
|
538
|
+
this._resetSelectionAffinity();
|
|
539
|
+
},
|
|
540
|
+
|
|
541
|
+
_setBooleanAttributeForSelection: function(name, value, selection){
|
|
542
|
+
var textStorage = this.textLayoutManager.textStorage;
|
|
543
|
+
var replacementString;
|
|
544
|
+
if (selection.range.length > 0){
|
|
545
|
+
replacementString = textStorage.attributedSubstringInRange(selection.range);
|
|
546
|
+
if (value){
|
|
547
|
+
replacementString.addAttributeInRange(name, true, JSRange(0, replacementString.string.length));
|
|
548
|
+
}else{
|
|
549
|
+
replacementString.removeAttributeInRange(name, JSRange(0, replacementString.string.length));
|
|
550
|
+
}
|
|
551
|
+
this._replaceTextStorageRangeAllowingUndo(textStorage, selection.range, replacementString);
|
|
552
|
+
}else{
|
|
553
|
+
selection.attributes = this._insertAttributesForSelection(selection);
|
|
554
|
+
if (value){
|
|
555
|
+
selection.attributes[name] = true;
|
|
556
|
+
}else{
|
|
557
|
+
delete selection.attributes[name];
|
|
558
|
+
}
|
|
559
|
+
this.undoManager.registerUndo(this, this._setBooleanAttributeForSelection, name, !value, selection);
|
|
560
|
+
}
|
|
561
|
+
},
|
|
562
|
+
|
|
419
563
|
_createSelectionAtLocation: function(location){
|
|
420
564
|
var index = this.textLayoutManager.characterIndexAtPoint(location);
|
|
421
565
|
var rect = this.textLayoutManager.rectForCharacterAtIndex(index);
|
|
@@ -462,6 +606,20 @@ JSClass("UITextEditor", JSObject, {
|
|
|
462
606
|
this.layout();
|
|
463
607
|
},
|
|
464
608
|
|
|
609
|
+
_selectionsCopy: function(){
|
|
610
|
+
var selections = [];
|
|
611
|
+
var i, l;
|
|
612
|
+
for (i = 0, l = this.selections.length; i < l; ++i){
|
|
613
|
+
selections.push(UITextInputSelection(this.selections[i]));
|
|
614
|
+
}
|
|
615
|
+
return selections;
|
|
616
|
+
},
|
|
617
|
+
|
|
618
|
+
_setSelectionsAllowingUndo: function(selections){
|
|
619
|
+
this.undoManager.registerUndo(this, this._setSelectionsAllowingUndo, this._selectionsCopy());
|
|
620
|
+
this.setSelections(selections);
|
|
621
|
+
},
|
|
622
|
+
|
|
465
623
|
_insertSelection: function(selection){
|
|
466
624
|
var searcher = JSBinarySearcher(this.selections, function(a, b){
|
|
467
625
|
return a.range.location - b.range.location;
|
|
@@ -489,8 +647,8 @@ JSClass("UITextEditor", JSObject, {
|
|
|
489
647
|
var adjustedRange;
|
|
490
648
|
var locationAdjustment = 0;
|
|
491
649
|
var textStorage = this.textLayoutManager.textStorage;
|
|
492
|
-
this._isHandlingSelectionAdjustments = true;
|
|
493
650
|
this.undoManager.beginUndoGrouping();
|
|
651
|
+
var selections = this._selectionsCopy();
|
|
494
652
|
for (i = 0, l = ranges.length; i < l; ++i){
|
|
495
653
|
range = ranges[i];
|
|
496
654
|
adjustedRange = JSRange(range.location + locationAdjustment, range.length);
|
|
@@ -498,19 +656,20 @@ JSClass("UITextEditor", JSObject, {
|
|
|
498
656
|
this._replaceTextStorageRangeAllowingUndo(textStorage, adjustedRange, null);
|
|
499
657
|
}
|
|
500
658
|
locationAdjustment -= range.length;
|
|
501
|
-
if (i ==
|
|
502
|
-
|
|
659
|
+
if (i == selections.length){
|
|
660
|
+
selections.push(this._createSelection(JSRange(0, 0)));
|
|
503
661
|
}
|
|
504
|
-
|
|
662
|
+
selections[i].range = JSRange(adjustedRange.location, 0);
|
|
505
663
|
}
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
this.selections.splice(j, 1);
|
|
664
|
+
for (var j = selections.length - 1; j >= i; --j){
|
|
665
|
+
selections.splice(j, 1);
|
|
509
666
|
}
|
|
667
|
+
for (i = 0, l = selections.length; i < l; ++i){
|
|
668
|
+
selections[i].affinity = UITextInput.SelectionAffinity.beforeCurrentCharacter;
|
|
669
|
+
}
|
|
670
|
+
this._setSelectionsAllowingUndo(selections);
|
|
510
671
|
this.undoManager.endUndoGrouping();
|
|
511
672
|
this.undoManager.setActionName("Typing");
|
|
512
|
-
this._collapseOverlappingSelections();
|
|
513
|
-
this._resetSelectionAffinity();
|
|
514
673
|
},
|
|
515
674
|
|
|
516
675
|
_replaceTextStorageRangeAllowingUndo: function(textStorage, range, attributedString){
|
|
@@ -523,10 +682,12 @@ JSClass("UITextEditor", JSObject, {
|
|
|
523
682
|
insertedLength = attributedString.string.length;
|
|
524
683
|
}
|
|
525
684
|
this.undoManager.registerUndo(this, this._replaceTextStorageRangeAllowingUndo, textStorage, JSRange(range.location, insertedLength), replacedString);
|
|
685
|
+
this._isHandlingSelectionAdjustments = true;
|
|
526
686
|
textStorage.replaceCharactersInRangeWithAttributedString(range, attributedString);
|
|
687
|
+
this._isHandlingSelectionAdjustments = false;
|
|
527
688
|
},
|
|
528
689
|
|
|
529
|
-
_collapseOverlappingSelections: function(){
|
|
690
|
+
_collapseOverlappingSelections: function(sections){
|
|
530
691
|
var removed = [];
|
|
531
692
|
for (var i = this.selections.length - 1; i > 0; --i){
|
|
532
693
|
if (this.selections[i - 1].range.end >= this.selections[i].range.location){
|
|
@@ -545,10 +706,20 @@ JSClass("UITextEditor", JSObject, {
|
|
|
545
706
|
},
|
|
546
707
|
|
|
547
708
|
_insertAttributesForSelection: function(selection){
|
|
548
|
-
|
|
549
|
-
|
|
709
|
+
if (selection.attributes){
|
|
710
|
+
return selection.attributes;
|
|
711
|
+
}
|
|
712
|
+
var index = selection.range.location;
|
|
713
|
+
var iterator;
|
|
714
|
+
if (index > 0){
|
|
715
|
+
iterator = this.textLayoutManager.textStorage.string.userPerceivedCharacterIterator(index);
|
|
716
|
+
iterator.decrement();
|
|
717
|
+
if (!iterator.isParagraphBreak){
|
|
718
|
+
index = iterator.range.location;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
var attributes = JSCopy(this.textLayoutManager.textStorage.attributesAtIndex(index));
|
|
550
722
|
if (JSAttributedString.Attribute.attachment in attributes){
|
|
551
|
-
attributes = JSCopy(attributes);
|
|
552
723
|
delete attributes[JSAttributedString.Attribute.attachment];
|
|
553
724
|
}
|
|
554
725
|
return attributes;
|
|
@@ -587,23 +758,21 @@ JSClass("UITextEditor", JSObject, {
|
|
|
587
758
|
var locationAdjustment = 0;
|
|
588
759
|
var adjustedRange;
|
|
589
760
|
var insertAttributes;
|
|
590
|
-
|
|
761
|
+
var i, l;
|
|
762
|
+
var selections = this._selectionsCopy();
|
|
591
763
|
this.undoManager.beginUndoGrouping();
|
|
592
|
-
for (
|
|
593
|
-
selection =
|
|
594
|
-
insertAttributes = this.
|
|
595
|
-
if (insertAttributes === null){
|
|
596
|
-
insertAttributes = this._insertAttributesForSelection(selection);
|
|
597
|
-
}
|
|
764
|
+
for (i = 0, l = selections.length; i < l; ++i){
|
|
765
|
+
selection = selections[i];
|
|
766
|
+
insertAttributes = this._insertAttributesForSelection(selection);
|
|
598
767
|
adjustedRange = JSRange(selection.range.location + locationAdjustment, selection.range.length);
|
|
599
768
|
this._replaceTextStorageRangeAllowingUndo(textStorage, adjustedRange, JSAttributedString.initWithString(text, insertAttributes));
|
|
600
769
|
selection.range = JSRange(adjustedRange.location + textLength, 0);
|
|
770
|
+
selection.affinity = UITextInput.SelectionAffinity.beforeCurrentCharacter;
|
|
601
771
|
locationAdjustment += textLength - adjustedRange.length;
|
|
602
772
|
}
|
|
773
|
+
this._setSelectionsAllowingUndo(selections);
|
|
603
774
|
this.undoManager.endUndoGrouping();
|
|
604
775
|
this.undoManager.setActionName("Typing");
|
|
605
|
-
this._isHandlingSelectionAdjustments = false;
|
|
606
|
-
this._resetSelectionAffinity();
|
|
607
776
|
},
|
|
608
777
|
|
|
609
778
|
setMarkedText: function(text){
|
|
@@ -631,7 +800,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
631
800
|
},
|
|
632
801
|
|
|
633
802
|
insertLineBreak: function(){
|
|
634
|
-
this.insertText("\
|
|
803
|
+
this.insertText("\u2028");
|
|
635
804
|
},
|
|
636
805
|
|
|
637
806
|
insertTab: function(){
|
|
@@ -812,6 +981,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
812
981
|
var perceivedCharacterRange;
|
|
813
982
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
814
983
|
selection = this.selections[i];
|
|
984
|
+
selection.attributes = null;
|
|
815
985
|
if (selection.range.length === 0){
|
|
816
986
|
if (selection.range.location > 0){
|
|
817
987
|
perceivedCharacterRange = textStorage.string.rangeForUserPerceivedCharacterAtIndex(selection.range.location - 1);
|
|
@@ -834,6 +1004,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
834
1004
|
var indexOfPreviousWord;
|
|
835
1005
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
836
1006
|
selection = this.selections[i];
|
|
1007
|
+
selection.attributes = null;
|
|
837
1008
|
indexOfPreviousWord = textStorage.string.indexOfWordStartBeforeIndex(selection.range.location);
|
|
838
1009
|
selection.range = JSRange(indexOfPreviousWord, 0);
|
|
839
1010
|
}
|
|
@@ -849,6 +1020,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
849
1020
|
var line;
|
|
850
1021
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
851
1022
|
selection = this.selections[i];
|
|
1023
|
+
selection.attributes = null;
|
|
852
1024
|
line = this._lineForSelectionStart(selection);
|
|
853
1025
|
if (line !== null){
|
|
854
1026
|
selection.range = JSRange(line.range.location, 0);
|
|
@@ -872,6 +1044,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
872
1044
|
var cursorX;
|
|
873
1045
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
874
1046
|
selection = this.selections[i];
|
|
1047
|
+
selection.attributes = null;
|
|
875
1048
|
selection.insertionPoint = UITextInput.SelectionInsertionPoint.start;
|
|
876
1049
|
cursorRect = this._cursorRectForSelection(selection);
|
|
877
1050
|
cursorX = cursorRect.origin.x + Math.floor(cursorRect.size.width / 2.0);
|
|
@@ -915,6 +1088,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
915
1088
|
var perceivedCharacterRange;
|
|
916
1089
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
917
1090
|
selection = this.selections[i];
|
|
1091
|
+
selection.attributes = null;
|
|
918
1092
|
if (selection.range.length === 0){
|
|
919
1093
|
if (selection.range.location < textStorage.string.length){
|
|
920
1094
|
perceivedCharacterRange = textStorage.string.rangeForUserPerceivedCharacterAtIndex(selection.range.location);
|
|
@@ -937,6 +1111,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
937
1111
|
var nextWordIndex;
|
|
938
1112
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
939
1113
|
selection = this.selections[i];
|
|
1114
|
+
selection.attributes = null;
|
|
940
1115
|
nextWordIndex = textStorage.string.indexOfWordEndAfterIndex(selection.range.end);
|
|
941
1116
|
selection.range = JSRange(nextWordIndex, 0);
|
|
942
1117
|
}
|
|
@@ -952,6 +1127,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
952
1127
|
var line;
|
|
953
1128
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
954
1129
|
selection = this.selections[i];
|
|
1130
|
+
selection.attributes = null;
|
|
955
1131
|
line = this._lineForSelectionEnd(selection);
|
|
956
1132
|
if (line !== null && line.range.end > selection.range.location){
|
|
957
1133
|
var iterator = textStorage.string.userPerceivedCharacterIterator(line.range.end - 1);
|
|
@@ -981,6 +1157,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
981
1157
|
var lineEnumerator;
|
|
982
1158
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
983
1159
|
selection = this.selections[i];
|
|
1160
|
+
selection.attributes = null;
|
|
984
1161
|
selection.insertionPoint = UITextInput.SelectionInsertionPoint.end;
|
|
985
1162
|
cursorRect = this._cursorRectForSelection(selection);
|
|
986
1163
|
cursorX = cursorRect.origin.x + Math.floor(cursorRect.size.width / 2.0);
|
|
@@ -1025,6 +1202,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
1025
1202
|
var perceivedCharacterRange;
|
|
1026
1203
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
1027
1204
|
selection = this.selections[i];
|
|
1205
|
+
selection.attributes = null;
|
|
1028
1206
|
if (selection.range.length > 0 && selection.insertionPoint == UITextInput.SelectionInsertionPoint.end){
|
|
1029
1207
|
perceivedCharacterRange = textStorage.string.rangeForUserPerceivedCharacterAtIndex(selection.range.end - 1);
|
|
1030
1208
|
selection.range.length -= perceivedCharacterRange.length;
|
|
@@ -1050,6 +1228,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
1050
1228
|
var end;
|
|
1051
1229
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
1052
1230
|
selection = this.selections[i];
|
|
1231
|
+
selection.attributes = null;
|
|
1053
1232
|
if (selection.insertionPoint == UITextInput.SelectionInsertionPoint.start){
|
|
1054
1233
|
end = selection.range.end;
|
|
1055
1234
|
}else{
|
|
@@ -1072,6 +1251,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
1072
1251
|
var end;
|
|
1073
1252
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
1074
1253
|
selection = this.selections[i];
|
|
1254
|
+
selection.attributes = null;
|
|
1075
1255
|
line = this._lineForSelectionStart(selection);
|
|
1076
1256
|
if (line !== null){
|
|
1077
1257
|
if (selection.insertionPoint == UITextInput.SelectionInsertionPoint.start){
|
|
@@ -1101,6 +1281,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
1101
1281
|
var lineEnumerator;
|
|
1102
1282
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
1103
1283
|
selection = this.selections[i];
|
|
1284
|
+
selection.attributes = null;
|
|
1104
1285
|
cursorRect = this._cursorRectForSelection(selection);
|
|
1105
1286
|
cursorX = cursorRect.origin.x + Math.floor(cursorRect.size.width / 2.0);
|
|
1106
1287
|
lineEnumerator = this.textLayoutManager.lineEnumerator((selection.insertionPoint == UITextInput.SelectionInsertionPoint.start ? selection.range.location : selection.range.end) - (selection.affinity === UITextInput.SelectionAffinity.afterPreviousCharacter ? 1 : 0));
|
|
@@ -1166,6 +1347,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
1166
1347
|
var perceivedCharacterRange;
|
|
1167
1348
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
1168
1349
|
selection = this.selections[i];
|
|
1350
|
+
selection.attributes = null;
|
|
1169
1351
|
if (selection.range.length > 0 && selection.insertionPoint == UITextInput.SelectionInsertionPoint.start){
|
|
1170
1352
|
perceivedCharacterRange = textStorage.string.rangeForUserPerceivedCharacterAtIndex(selection.range.location);
|
|
1171
1353
|
selection.range.advance(perceivedCharacterRange.length);
|
|
@@ -1191,6 +1373,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
1191
1373
|
var start;
|
|
1192
1374
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
1193
1375
|
selection = this.selections[i];
|
|
1376
|
+
selection.attributes = null;
|
|
1194
1377
|
if (selection.insertionPoint == UITextInput.SelectionInsertionPoint.start){
|
|
1195
1378
|
start = selection.range.end;
|
|
1196
1379
|
}else{
|
|
@@ -1213,6 +1396,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
1213
1396
|
var start;
|
|
1214
1397
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
1215
1398
|
selection = this.selections[i];
|
|
1399
|
+
selection.attributes = null;
|
|
1216
1400
|
line = this._lineForSelectionEnd(selection);
|
|
1217
1401
|
if (selection.insertionPoint == UITextInput.SelectionInsertionPoint.start){
|
|
1218
1402
|
start = selection.range.end;
|
|
@@ -1248,6 +1432,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
1248
1432
|
var cursorX;
|
|
1249
1433
|
for (var i = 0, l = this.selections.length; i < l; ++i){
|
|
1250
1434
|
selection = this.selections[i];
|
|
1435
|
+
selection.attributes = null;
|
|
1251
1436
|
cursorRect = this._cursorRectForSelection(selection);
|
|
1252
1437
|
cursorX = cursorRect.origin.x + Math.floor(cursorRect.size.width / 2.0);
|
|
1253
1438
|
lineEnumerator = this.textLayoutManager.lineEnumerator((selection.insertionPoint == UITextInput.SelectionInsertionPoint.start ? selection.range.location : selection.range.end) - (selection.affinity === UITextInput.SelectionAffinity.afterPreviousCharacter ? 1 : 0));
|
|
@@ -1334,7 +1519,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
1334
1519
|
return this.textLayoutManager.lineForCharacterAtIndex(selection.range.end - 1);
|
|
1335
1520
|
}
|
|
1336
1521
|
return this.textLayoutManager.lineForCharacterAtIndex(selection.range.end);
|
|
1337
|
-
}
|
|
1522
|
+
},
|
|
1338
1523
|
|
|
1339
1524
|
});
|
|
1340
1525
|
|