@breakside/jskit 2026.26.0 → 2026.28.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/JS/FNTOpenTypeFont.js +44 -25
- 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 +43 -0
- package/Frameworks/Foundation.jsframework/JS/JSPath.js +2 -3
- 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/io.breakside.jskit-bundle.js +2 -2
- 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/CSSTokenizer.js +633 -470
- 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/FNTOpenTypeFont.js +44 -25
- package/Root/Frameworks/FontKit/Info.yaml +1 -1
- package/Root/Frameworks/Foundation/Info.yaml +1 -1
- package/Root/Frameworks/Foundation/JSAttributedString.js +43 -0
- package/Root/Frameworks/Foundation/JSPath.js +2 -3
- 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/UITextEditor.js +17 -0
- package/Root/Frameworks/UIKit/UITextField.js +7 -0
- package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
- package/package.json +1 -1
|
@@ -1958,43 +1958,62 @@ JSClass("FNTOpenTypeSimpleGlyph", FNTOpenTypeGlyph, {
|
|
|
1958
1958
|
}
|
|
1959
1959
|
var flags;
|
|
1960
1960
|
var point;
|
|
1961
|
-
var i
|
|
1961
|
+
var i;
|
|
1962
1962
|
var p0;
|
|
1963
1963
|
var path = JSPath.init();
|
|
1964
1964
|
var cp = null;
|
|
1965
|
-
|
|
1965
|
+
var pointIndex;
|
|
1966
|
+
var startPointIndex;
|
|
1967
|
+
var endPointIndex;
|
|
1968
|
+
var pointCount;
|
|
1969
|
+
var pointCounter;
|
|
1966
1970
|
var points = this.points;
|
|
1971
|
+
pointIndex = 0;
|
|
1967
1972
|
for (i = 0; i < this.numberOfCountours; ++i){
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
+
startPointIndex = pointIndex;
|
|
1974
|
+
endPointIndex = this.endPointIndexes[i];
|
|
1975
|
+
pointCount = endPointIndex - startPointIndex;
|
|
1976
|
+
// The specs aren't totally clear here, but some contours
|
|
1977
|
+
// start with a point that is off-curve. In order to draw
|
|
1978
|
+
// a path, we want to start with a `moveToPoint()` for a
|
|
1979
|
+
// point that is on-curve. Therefore, we'll loop until we
|
|
1980
|
+
// find the first on-curve point, and use it as our starting point.
|
|
1981
|
+
while (pointIndex <= endPointIndex && ((this.flags[pointIndex] & 0x01) === 0)){
|
|
1982
|
+
++pointIndex;
|
|
1973
1983
|
}
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
point
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1984
|
+
if (pointIndex <= endPointIndex){
|
|
1985
|
+
flags = this.flags[pointIndex];
|
|
1986
|
+
point = points[pointIndex];
|
|
1987
|
+
p0 = point;
|
|
1988
|
+
path.moveToPoint(point, transform);
|
|
1989
|
+
++pointIndex;
|
|
1990
|
+
for (pointCounter = 1; pointCounter <= pointCount; ++pointCounter, ++pointIndex){
|
|
1991
|
+
if (pointIndex > endPointIndex){
|
|
1992
|
+
pointIndex = startPointIndex;
|
|
1982
1993
|
}
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
if (
|
|
1986
|
-
|
|
1994
|
+
flags = this.flags[pointIndex];
|
|
1995
|
+
point = points[pointIndex];
|
|
1996
|
+
if ((flags & 0x01) === 0){
|
|
1997
|
+
if (cp !== null){
|
|
1998
|
+
path.addQuadraticCurveToPoint(cp.interpolation(point, 0.5), cp, transform);
|
|
1999
|
+
}
|
|
2000
|
+
cp = point;
|
|
1987
2001
|
}else{
|
|
1988
|
-
|
|
2002
|
+
if (cp !== null){
|
|
2003
|
+
path.addQuadraticCurveToPoint(point, cp, transform);
|
|
2004
|
+
}else{
|
|
2005
|
+
path.addLineToPoint(point, transform);
|
|
2006
|
+
}
|
|
2007
|
+
cp = null;
|
|
1989
2008
|
}
|
|
2009
|
+
}
|
|
2010
|
+
if (cp !== null){
|
|
2011
|
+
path.addQuadraticCurveToPoint(p0, cp, transform);
|
|
1990
2012
|
cp = null;
|
|
1991
2013
|
}
|
|
2014
|
+
path.closeSubpath();
|
|
1992
2015
|
}
|
|
1993
|
-
|
|
1994
|
-
path.addQuadraticCurveToPoint(p0, cp, transform);
|
|
1995
|
-
cp = null;
|
|
1996
|
-
}
|
|
1997
|
-
path.closeSubpath();
|
|
2016
|
+
pointIndex = endPointIndex + 1;
|
|
1998
2017
|
}
|
|
1999
2018
|
return path;
|
|
2000
2019
|
},
|
|
@@ -395,6 +395,49 @@ JSClass("JSAttributedString", JSObject, {
|
|
|
395
395
|
this._fixParagraphAttributesAtIndex(range.location + attributedString.string.length);
|
|
396
396
|
},
|
|
397
397
|
|
|
398
|
+
stringWithFallbackFonts: function(fallbackFontDescriptors, defaultFont, usedDescriptors){
|
|
399
|
+
var attributedString = this;
|
|
400
|
+
var runIterator = attributedString.runIterator();
|
|
401
|
+
var unicodeIterator;
|
|
402
|
+
var end = attributedString.string.length;
|
|
403
|
+
var font;
|
|
404
|
+
var glyph;
|
|
405
|
+
var descriptor;
|
|
406
|
+
var i, l;
|
|
407
|
+
var descriptorFonts = [];
|
|
408
|
+
for (i = 0, l = fallbackFontDescriptors.length; i < l; ++i){
|
|
409
|
+
descriptorFonts.push({});
|
|
410
|
+
}
|
|
411
|
+
for (; runIterator.range.location < end; runIterator.increment()){
|
|
412
|
+
font = runIterator.attributes.font || defaultFont;
|
|
413
|
+
unicodeIterator = attributedString.string.unicodeIterator(0);
|
|
414
|
+
for (; unicodeIterator.character !== null; unicodeIterator.increment()){
|
|
415
|
+
glyph = font.glyphForCharacter(unicodeIterator.character);
|
|
416
|
+
if (glyph === 0){
|
|
417
|
+
for (i = 0, l = fallbackFontDescriptors.length && glyph === 0; i < l; ++i){
|
|
418
|
+
descriptor = fallbackFontDescriptors[i];
|
|
419
|
+
glyph = descriptor.glyphForCharacter(unicodeIterator.character);
|
|
420
|
+
if (glyph !== 0){
|
|
421
|
+
if (usedDescriptors !== undefined){
|
|
422
|
+
if (usedDescriptors.indexOf(descriptor) < 0){
|
|
423
|
+
usedDescriptors.push(descriptor);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
if (attributedString === this){
|
|
427
|
+
attributedString = JSAttributedString.initWithAttributedString(attributedString);
|
|
428
|
+
}
|
|
429
|
+
if (descriptorFonts[i][font.pointSize] === undefined){
|
|
430
|
+
descriptorFonts[i][font.pointSize] = JSFont.initWithDescriptor(descriptor, font.pointSize);
|
|
431
|
+
}
|
|
432
|
+
attributedString.addAttributeInRange("font", descriptorFonts[i][font.pointSize], JSRange(unicodeIterator.index, unicodeIterator.nextIndex - unicodeIterator.index));
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return attributedString;
|
|
439
|
+
},
|
|
440
|
+
|
|
398
441
|
// MARK: - Attribute mutations
|
|
399
442
|
|
|
400
443
|
setAttributesInRange: function(attributes, range){
|
|
@@ -571,9 +571,6 @@ JSClass("JSPath", JSObject, {
|
|
|
571
571
|
}else{
|
|
572
572
|
clockwise = endAngle - startAngle <= Math.PI;
|
|
573
573
|
}
|
|
574
|
-
if (Math.abs(t1.x - this._currentPoint.x) > 0.00001 || Math.abs(t1.y - this._currentPoint.y) > 0.00001){
|
|
575
|
-
this.moveToPoint(t1);
|
|
576
|
-
}
|
|
577
574
|
this.addArc(center, radius, startAngle, endAngle, clockwise);
|
|
578
575
|
},
|
|
579
576
|
|
|
@@ -1188,6 +1185,8 @@ JSClass("JSPath", JSObject, {
|
|
|
1188
1185
|
if (
|
|
1189
1186
|
c === "M" || c === "m" ||
|
|
1190
1187
|
c === "L" || c === "l" ||
|
|
1188
|
+
c === "H" || c === "h" ||
|
|
1189
|
+
c === "V" || c === "v" ||
|
|
1191
1190
|
c === "C" || c === "c" ||
|
|
1192
1191
|
c === "S" || c === "s" ||
|
|
1193
1192
|
c === "Z" || c === "z" ||
|
|
@@ -44,6 +44,7 @@ JSClass("UITextEditor", JSObject, {
|
|
|
44
44
|
_selectionHighlightColor: null,
|
|
45
45
|
_draggingSelectionIndex: null,
|
|
46
46
|
_showsSelectionWhenNotFirstResponder: false,
|
|
47
|
+
_fallbackFontDescriptors: null,
|
|
47
48
|
|
|
48
49
|
initWithTextLayer: function(textLayer){
|
|
49
50
|
this.layoutLayer = textLayer;
|
|
@@ -809,14 +810,27 @@ JSClass("UITextEditor", JSObject, {
|
|
|
809
810
|
this.undoManager.setActionName("Typing");
|
|
810
811
|
},
|
|
811
812
|
|
|
813
|
+
_usedFallbackFontDescriptors: false,
|
|
814
|
+
|
|
812
815
|
_replaceTextStorageRangeAllowingUndo: function(textStorage, range, attributedString){
|
|
813
816
|
var replacedString = null;
|
|
814
817
|
var insertedLength = 0;
|
|
815
818
|
if (range.length > 0){
|
|
816
819
|
replacedString = textStorage.attributedSubstringInRange(range);
|
|
817
820
|
}
|
|
821
|
+
this._usedFallbackFontDescriptors = false;
|
|
818
822
|
if (attributedString !== null){
|
|
819
823
|
insertedLength = attributedString.string.length;
|
|
824
|
+
if (this._fallbackFontDescriptors !== null && insertedLength > 0){
|
|
825
|
+
var usedDescriptors = [];
|
|
826
|
+
attributedString = attributedString.stringWithFallbackFonts(this._fallbackFontDescriptors, this.layoutLayer.font, usedDescriptors);
|
|
827
|
+
if (usedDescriptors.length > 0){
|
|
828
|
+
this._usedFallbackFontDescriptors = true;
|
|
829
|
+
if (this.delegate && this.delegate.textEditorDidUseFallbackFontDescriptors){
|
|
830
|
+
this.delegate.textEditorDidUseFallbackFontDescriptors(this, usedDescriptors);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
820
834
|
}
|
|
821
835
|
this.undoManager.registerUndo(this, this._replaceTextStorageRangeAllowingUndo, textStorage, JSRange(range.location, insertedLength), replacedString);
|
|
822
836
|
this._isHandlingSelectionAdjustments = true;
|
|
@@ -922,6 +936,9 @@ JSClass("UITextEditor", JSObject, {
|
|
|
922
936
|
this._replaceTextStorageRangeAllowingUndo(textStorage, adjustedRange, JSAttributedString.initWithString(text, insertAttributes));
|
|
923
937
|
selection.range = JSRange(adjustedRange.location + textLength, 0);
|
|
924
938
|
selection.affinity = UITextInput.SelectionAffinity.beforeCurrentCharacter;
|
|
939
|
+
if (this._usedFallbackFontDescriptors){
|
|
940
|
+
selection.attributes = insertAttributes;
|
|
941
|
+
}
|
|
925
942
|
locationAdjustment += textLength - adjustedRange.length;
|
|
926
943
|
}
|
|
927
944
|
this._setSelectionsAllowingUndo(selections);
|
|
@@ -332,6 +332,13 @@ JSClass("UITextField", UIControl, {
|
|
|
332
332
|
return this._localEditor.cursorColor;
|
|
333
333
|
},
|
|
334
334
|
|
|
335
|
+
addFallbackFontDescriptor: function(fontDescriptor){
|
|
336
|
+
if (this._localEditor._fallbackFontDescriptors === null){
|
|
337
|
+
this._localEditor._fallbackFontDescriptors = [];
|
|
338
|
+
}
|
|
339
|
+
this._localEditor._fallbackFontDescriptors.push(fontDescriptor);
|
|
340
|
+
},
|
|
341
|
+
|
|
335
342
|
// --------------------------------------------------------------------
|
|
336
343
|
// MARK: - Undo Manager
|
|
337
344
|
|