@breakside/jskit 2022.22.3 → 2022.25.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/JS/XMLSerializer.js +9 -4
- 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 +279 -6
- package/Frameworks/Foundation.jsframework/JS/JSFileManager+Node.js +2 -2
- package/Frameworks/Foundation.jsframework/JS/JSFont.js +39 -15
- package/Frameworks/Foundation.jsframework/JS/JSFontDescriptor+HTML.js +8 -0
- package/Frameworks/Foundation.jsframework/JS/JSFontDescriptor.js +105 -27
- 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/JSZip.js +97 -76
- package/Frameworks/Foundation.jsframework/JS/String+JS.js +69 -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 +26 -22
- 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 +8 -7
- 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/DOM/XMLSerializer.js +9 -4
- 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 +279 -6
- package/Root/Frameworks/Foundation/JSFileManager+Node.js +2 -2
- package/Root/Frameworks/Foundation/JSFont.js +39 -15
- package/Root/Frameworks/Foundation/JSFontDescriptor+HTML.js +8 -0
- package/Root/Frameworks/Foundation/JSFontDescriptor.js +105 -27
- 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/JSZip.js +97 -76
- package/Root/Frameworks/Foundation/String+JS.js +69 -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/UIBasicAnimation.js +1 -1
- package/Root/Frameworks/UIKit/UIHTMLApplication.js +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/UIImageLayer.js +14 -7
- 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
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
// limitations under the License.
|
|
15
15
|
|
|
16
16
|
// #import "JSObject.js"
|
|
17
|
+
// #import "JSProtocol.js"
|
|
17
18
|
// #import "CoreTypes.js"
|
|
18
19
|
// #import "JSAttributedString.js"
|
|
19
20
|
// #import "JSFont.js"
|
|
@@ -26,6 +27,12 @@
|
|
|
26
27
|
|
|
27
28
|
var logger = JSLog("foundation", "text");
|
|
28
29
|
|
|
30
|
+
JSProtocol("JSTextTypesetterDelegate", JSProtocol, {
|
|
31
|
+
|
|
32
|
+
typesetterAttributesForStringAttributes: function(typesetter, stringAttributes){}
|
|
33
|
+
|
|
34
|
+
});
|
|
35
|
+
|
|
29
36
|
JSClass("JSTextTypesetter", JSObject, {
|
|
30
37
|
|
|
31
38
|
attributedString: JSDynamicProperty('_attributedString'),
|
|
@@ -68,7 +75,8 @@ JSClass("JSTextTypesetter", JSObject, {
|
|
|
68
75
|
|
|
69
76
|
_createEmptyLine: function(range){
|
|
70
77
|
var attributes = this._attributedString.attributesAtIndex(range.location);
|
|
71
|
-
|
|
78
|
+
attributes = this.resolveAttributes(attributes);
|
|
79
|
+
var font = attributes.font;
|
|
72
80
|
return JSTextLine.initWithHeight(font.lineHeight, -font.descender, range.location);
|
|
73
81
|
},
|
|
74
82
|
|
|
@@ -129,16 +137,18 @@ JSClass("JSTextTypesetter", JSObject, {
|
|
|
129
137
|
|
|
130
138
|
var iterator = this._attributedString.string.userPerceivedCharacterIterator(range.location);
|
|
131
139
|
var runIterator = this._attributedString.runIterator(range.location);
|
|
132
|
-
var initialLineAttributes = runIterator.attributes;
|
|
133
140
|
var codeIterator;
|
|
134
141
|
var attachment;
|
|
142
|
+
var attributes;
|
|
135
143
|
// TODO: support mask character (only important if we need to rasterize a password field, which isn't a major use case)
|
|
136
144
|
// Create run descriptors that at fill the line, maybe going a bit over
|
|
137
145
|
do {
|
|
138
146
|
|
|
147
|
+
attributes = this.resolveAttributes(runIterator.attributes);
|
|
148
|
+
|
|
139
149
|
// If we're at the start of a new run, make a new run descriptor
|
|
140
150
|
if (runDescriptor === null){
|
|
141
|
-
runDescriptor = JSTextTypesetterRunDescriptor(remainingRange.location,
|
|
151
|
+
runDescriptor = JSTextTypesetterRunDescriptor(remainingRange.location, attributes);
|
|
142
152
|
runDescriptors.push(runDescriptor);
|
|
143
153
|
preferredFont = runDescriptor.font;
|
|
144
154
|
}
|
|
@@ -146,9 +156,10 @@ JSClass("JSTextTypesetter", JSObject, {
|
|
|
146
156
|
// Check some properties of this character
|
|
147
157
|
newline = iterator.isMandatoryLineBreak;
|
|
148
158
|
printable = !newline && !iterator.isWhiteSpace;
|
|
159
|
+
attachment = runIterator.attachment;
|
|
149
160
|
|
|
150
161
|
// Adjust the run's font if needed
|
|
151
|
-
if (
|
|
162
|
+
if (attachment !== null){
|
|
152
163
|
// 1. Attachment font:
|
|
153
164
|
// Attachment runs use a special "attachment font" that can draw the attachment rather
|
|
154
165
|
// than draw a glyph. It's perhaps a little strange to call an attachment a font, but
|
|
@@ -156,7 +167,6 @@ JSClass("JSTextTypesetter", JSObject, {
|
|
|
156
167
|
// here is actually a specially drawn attachment. The attachment font has a single glyph
|
|
157
168
|
// that corresponds to the 0xFFFC attachment character code, whose width matches the
|
|
158
169
|
// attachment's width
|
|
159
|
-
attachment = runIterator.attributes[JSAttributedString.Attribute.attachment];
|
|
160
170
|
attachment.layout(preferredFont, width);
|
|
161
171
|
usedWidth += attachment.size.width;
|
|
162
172
|
runDescriptor.glyphs.push(0);
|
|
@@ -169,7 +179,7 @@ JSClass("JSTextTypesetter", JSObject, {
|
|
|
169
179
|
// If our preferred font has a glyph for the character, but we're in a run
|
|
170
180
|
// that is using a fallback font, create a new run, switching back to the preferred font
|
|
171
181
|
if (runDescriptor.font !== preferredFont){
|
|
172
|
-
runDescriptor = JSTextTypesetterRunDescriptor(remainingRange.location,
|
|
182
|
+
runDescriptor = JSTextTypesetterRunDescriptor(remainingRange.location, attributes);
|
|
173
183
|
runDescriptors.push(runDescriptor);
|
|
174
184
|
}
|
|
175
185
|
}else{
|
|
@@ -179,7 +189,7 @@ JSClass("JSTextTypesetter", JSObject, {
|
|
|
179
189
|
// If the fallback doesn't match our run, adjust the run or create a new run depending on if it's emtpy
|
|
180
190
|
if (fallbackFont !== runDescriptor.font){
|
|
181
191
|
if (runDescriptor.length > 0){
|
|
182
|
-
runDescriptor = JSTextTypesetterRunDescriptor(remainingRange.location,
|
|
192
|
+
runDescriptor = JSTextTypesetterRunDescriptor(remainingRange.location, attributes);
|
|
183
193
|
runDescriptors.push(runDescriptor);
|
|
184
194
|
}
|
|
185
195
|
runDescriptor.font = fallbackFont;
|
|
@@ -317,7 +327,27 @@ JSClass("JSTextTypesetter", JSObject, {
|
|
|
317
327
|
if (ranges.length === 0){
|
|
318
328
|
ranges.push(JSTextTypesetterPrintableRange(location, 0, 0));
|
|
319
329
|
}
|
|
320
|
-
}
|
|
330
|
+
},
|
|
331
|
+
|
|
332
|
+
delegate: null,
|
|
333
|
+
|
|
334
|
+
resolveAttributes: function(attributes){
|
|
335
|
+
if (attributes.font){
|
|
336
|
+
if (attributes.bold || attributes.italic){
|
|
337
|
+
attributes = JSCopy(attributes);
|
|
338
|
+
if (attributes.bold){
|
|
339
|
+
attributes.font = attributes.font.fontWithWeight(JSFont.Weight.bold);
|
|
340
|
+
}
|
|
341
|
+
if (attributes.italic){
|
|
342
|
+
attributes.font = attributes.font.fontWithStyle(JSFont.Style.italic);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
if (this.delegate && this.delegate.typesetterAttributesForStringAttributes){
|
|
347
|
+
attributes = this.delegate.typesetterAttributesForStringAttributes(this, attributes);
|
|
348
|
+
}
|
|
349
|
+
return attributes;
|
|
350
|
+
},
|
|
321
351
|
|
|
322
352
|
});
|
|
323
353
|
|
|
@@ -329,8 +359,8 @@ var JSTextTypesetterRunDescriptor = function(location, attributes){
|
|
|
329
359
|
this.location = location.location;
|
|
330
360
|
this.attributes = location.attributes;
|
|
331
361
|
this.length = location.length;
|
|
332
|
-
this.glyphs = location.glyphs;
|
|
333
|
-
this.glyphCharacterLengths = location.glyphCharacterLengths;
|
|
362
|
+
this.glyphs = JSCopy(location.glyphs);
|
|
363
|
+
this.glyphCharacterLengths = JSCopy(location.glyphCharacterLengths);
|
|
334
364
|
this.font = location.font;
|
|
335
365
|
}else{
|
|
336
366
|
this.location = location;
|
|
@@ -338,7 +368,7 @@ var JSTextTypesetterRunDescriptor = function(location, attributes){
|
|
|
338
368
|
this.length = 0;
|
|
339
369
|
this.glyphs = [];
|
|
340
370
|
this.glyphCharacterLengths = [];
|
|
341
|
-
this.font =
|
|
371
|
+
this.font = attributes.font || null;
|
|
342
372
|
}
|
|
343
373
|
};
|
|
344
374
|
|
|
@@ -357,18 +387,4 @@ var JSTextTypesetterPrintableRange = function(location, length, width){
|
|
|
357
387
|
}
|
|
358
388
|
};
|
|
359
389
|
|
|
360
|
-
JSTextTypesetter.FontFromAttributes = function(attributes){
|
|
361
|
-
var font = attributes[JSAttributedString.Attribute.font];
|
|
362
|
-
if (!font){
|
|
363
|
-
return null;
|
|
364
|
-
}
|
|
365
|
-
if (attributes[JSAttributedString.Attribute.bold]){
|
|
366
|
-
font = font.fontWithWeight(JSFont.Weight.bold);
|
|
367
|
-
}
|
|
368
|
-
if (attributes[JSAttributedString.Attribute.italic]){
|
|
369
|
-
font = font.fontWithStyle(JSFont.Style.italic);
|
|
370
|
-
}
|
|
371
|
-
return font;
|
|
372
|
-
};
|
|
373
|
-
|
|
374
390
|
})();
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
// #import "JSObject.js"
|
|
2
2
|
// #import "Promise+JS.js"
|
|
3
3
|
// #import "JSCRC32.js"
|
|
4
|
+
// #import "JSDate.js"
|
|
5
|
+
// #import "JSCalendar.js"
|
|
6
|
+
// #import "Deflate.js"
|
|
4
7
|
"use strict";
|
|
5
8
|
|
|
6
9
|
JSClass("JSZip", JSObject, {
|
|
@@ -14,61 +17,89 @@ JSClass("JSZip", JSObject, {
|
|
|
14
17
|
offset: 0,
|
|
15
18
|
|
|
16
19
|
addFile: function(file, completion, target){
|
|
20
|
+
return this.addFileInDirectory(file, "", {}, completion, target);
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
addFileInDirectory: function(file, directory, attributes, completion, target){
|
|
17
24
|
if (!completion){
|
|
18
25
|
completion = Promise.completion(Promise.resolveNull);
|
|
19
26
|
}
|
|
27
|
+
if (directory.startsWith("/")){
|
|
28
|
+
directory = directory.substr(1);
|
|
29
|
+
}
|
|
30
|
+
if (directory.length > 1 && !directory.endsWith("/")){
|
|
31
|
+
directory = directory + "/";
|
|
32
|
+
}
|
|
20
33
|
file.readData(function(data){
|
|
21
34
|
if (data === null){
|
|
22
35
|
completion.call(target, new Error("Failed to read file data"));
|
|
23
36
|
return;
|
|
24
37
|
}
|
|
25
|
-
|
|
38
|
+
var error = null;
|
|
39
|
+
try{
|
|
40
|
+
this.addDataForFilename(data, directory + file.name, attributes);
|
|
41
|
+
}catch (e){
|
|
42
|
+
error = e;
|
|
43
|
+
}
|
|
44
|
+
completion.call(target, error);
|
|
26
45
|
}, this);
|
|
27
46
|
return completion.promise;
|
|
28
47
|
},
|
|
29
48
|
|
|
30
|
-
addDataForFilename: function(data, name,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
var
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
dataView.setUint16(26, encodedName.length, true);
|
|
50
|
-
dataView.setUint16(28, 0, true);
|
|
51
|
-
encodedName.copyTo(header, 30);
|
|
52
|
-
this.directory.push({
|
|
53
|
-
name: name,
|
|
54
|
-
offset: this.offset,
|
|
55
|
-
header: header
|
|
56
|
-
});
|
|
57
|
-
this.addChunk(header);
|
|
58
|
-
this.addChunk(data);
|
|
59
|
-
}catch (e){
|
|
60
|
-
error = e;
|
|
49
|
+
addDataForFilename: function(data, name, attributes, deflate){
|
|
50
|
+
var encodedName = name.utf8();
|
|
51
|
+
var header = JSData.initWithLength(30 + encodedName.length);
|
|
52
|
+
var dataView = header.dataView();
|
|
53
|
+
var crc = JSCRC32(data);
|
|
54
|
+
var dateComponents = JSCalendar.gregorian.componentsFromDate(JSCalendar.Unit.day | JSCalendar.Unit.month | JSCalendar.Unit.year | JSCalendar.Unit.hour | JSCalendar.Unit.minute | JSCalendar.Unit.second, attributes.updated !== undefined ? JSDate.initWithTimeIntervalSince1970(attributes.updated) : JSDate.now, JSTimeZone.local || JSTimeZone.utc);
|
|
55
|
+
var dosDate = ((dateComponents.year - 1980) << 9) | ((dateComponents.month) << 5) | (dateComponents.day);
|
|
56
|
+
var dosTime = ((dateComponents.hour) << 11) | ((dateComponents.minute) << 5) | (Math.floor(dateComponents.second / 2));
|
|
57
|
+
var storedData = data;
|
|
58
|
+
var method = 0;
|
|
59
|
+
if (deflate){
|
|
60
|
+
var stream = DeflateStream();
|
|
61
|
+
stream.input = data;
|
|
62
|
+
stream.output = JSData.initWithLength(data.length);
|
|
63
|
+
stream.deflate(true);
|
|
64
|
+
if (stream.state === DeflateStream.State.done){
|
|
65
|
+
storedData = stream.output.subdataInRange(JSRange(0, stream.outputOffset));
|
|
66
|
+
method = 8;
|
|
67
|
+
}
|
|
61
68
|
}
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
// Local File Header (APPNOTE.txt 4.3.7)
|
|
70
|
+
// Everything is little-endian
|
|
71
|
+
dataView.setUint32(0, 0x04034b50, true); // signtature
|
|
72
|
+
dataView.setUint16(4, 0x0014, true); // version needed to extract (2.0)
|
|
73
|
+
dataView.setUint16(6, 0, true); // general purpose flags
|
|
74
|
+
dataView.setUint16(8, method, true); // compression method (0=none, 8=deflate)
|
|
75
|
+
dataView.setUint16(10, dosTime, true); // last modified time (MS-DOS)
|
|
76
|
+
dataView.setUint16(12, dosDate, true); // last modified date (MS-DOS)
|
|
77
|
+
dataView.setUint32(14, crc, true); // crc-32 (magic number 0xdebb20e3, preconditioned to 0xffffffff, post-conditioned by one's compliment)
|
|
78
|
+
dataView.setUint32(18, storedData.length, true); // compressed size
|
|
79
|
+
dataView.setUint32(22, data.length, true); // uncompressed size
|
|
80
|
+
dataView.setUint16(26, encodedName.length, true); // name length
|
|
81
|
+
dataView.setUint16(28, 0, true); // extra field length
|
|
82
|
+
encodedName.copyTo(header, 30); // name (NOT null-terminated)
|
|
83
|
+
this.directory.push({
|
|
84
|
+
name: name,
|
|
85
|
+
offset: this.offset,
|
|
86
|
+
header: header
|
|
87
|
+
});
|
|
88
|
+
this.chunks.push(header);
|
|
89
|
+
this.chunks.push(storedData);
|
|
90
|
+
this.offset += header.length + storedData.length;
|
|
91
|
+
this._data = null;
|
|
64
92
|
},
|
|
65
93
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
94
|
+
directory: null,
|
|
95
|
+
|
|
96
|
+
chunks: null,
|
|
97
|
+
|
|
98
|
+
data: JSReadOnlyProperty("_data", null),
|
|
99
|
+
|
|
100
|
+
getData: function(){
|
|
101
|
+
if (this._data === null){
|
|
102
|
+
var chunks = JSCopy(this.chunks);
|
|
72
103
|
var i, l;
|
|
73
104
|
var centralDirectoryOffset = this.offset;
|
|
74
105
|
var centralDirectorySize = 0;
|
|
@@ -77,49 +108,39 @@ JSClass("JSZip", JSObject, {
|
|
|
77
108
|
var dataView;
|
|
78
109
|
var file;
|
|
79
110
|
for (i = 0, l = this.directory.length; i < l; ++i){
|
|
111
|
+
// Central Directory File Header (APPNOTE.txt 4.3.12)
|
|
112
|
+
// Everything is little-endian
|
|
80
113
|
file = this.directory[i];
|
|
81
114
|
header = JSData.initWithLength(46 + (file.header.length - 30));
|
|
82
115
|
dataView = header.dataView();
|
|
83
|
-
dataView.setUint32(0, 0x02014b50, true);
|
|
84
|
-
dataView.setUint16(4,
|
|
85
|
-
file.header.subdataInRange(JSRange(4, 26)).copyTo(header, 6);
|
|
86
|
-
dataView.setUint16(32, 0, true);
|
|
87
|
-
dataView.setUint16(34, 0, true);
|
|
88
|
-
dataView.setUint16(36, 0, true);
|
|
89
|
-
dataView.setUint32(38, 0, true);
|
|
90
|
-
dataView.setUint32(42, file.offset, true);
|
|
91
|
-
file.header.subdataInRange(JSRange(30, file.header.length - 30)).copyTo(header, 46);
|
|
116
|
+
dataView.setUint32(0, 0x02014b50, true); // signature
|
|
117
|
+
dataView.setUint16(4, 0x0314, true); // version made by (UNIX=3, 2.0)
|
|
118
|
+
file.header.subdataInRange(JSRange(4, 26)).copyTo(header, 6); // copy from local header
|
|
119
|
+
dataView.setUint16(32, 0, true); // commenet length
|
|
120
|
+
dataView.setUint16(34, 0, true); // disk number start
|
|
121
|
+
dataView.setUint16(36, 0, true); // internal file attributes
|
|
122
|
+
dataView.setUint32(38, 0, true); // external file attributes
|
|
123
|
+
dataView.setUint32(42, file.offset, true); // offset of local header relative to first disk
|
|
124
|
+
file.header.subdataInRange(JSRange(30, file.header.length - 30)).copyTo(header, 46); // name (ALWAYS forward slashes for directories)
|
|
92
125
|
centralDirectorySize += header.length;
|
|
93
|
-
|
|
126
|
+
chunks.push(header);
|
|
94
127
|
}
|
|
128
|
+
// End of Central Directory Record (APPNOTE.txt 4.3.16)
|
|
129
|
+
// everything is little-endian
|
|
95
130
|
var end = JSData.initWithLength(22);
|
|
96
131
|
dataView = end.dataView();
|
|
97
|
-
dataView.setUint32(0, 0x06054b50, true);
|
|
98
|
-
dataView.setUint16(4, 0, true);
|
|
99
|
-
dataView.setUint16(6, 0, true);
|
|
100
|
-
dataView.setUint16(8, this.directory.length, true);
|
|
101
|
-
dataView.setUint16(10, this.directory.length, true);
|
|
102
|
-
dataView.setUint32(12, centralDirectorySize, true);
|
|
103
|
-
dataView.setUint32(16, centralDirectoryOffset, true);
|
|
104
|
-
dataView.setUint16(20, 0, true);
|
|
105
|
-
|
|
106
|
-
this._data = JSData.initWithChunks(
|
|
107
|
-
}catch (e){
|
|
108
|
-
error = e;
|
|
132
|
+
dataView.setUint32(0, 0x06054b50, true); // signature
|
|
133
|
+
dataView.setUint16(4, 0, true); // number of this disk
|
|
134
|
+
dataView.setUint16(6, 0, true); // number of the disk with the start of central directory
|
|
135
|
+
dataView.setUint16(8, this.directory.length, true); // number of central directory items on this disk
|
|
136
|
+
dataView.setUint16(10, this.directory.length, true); // number of central directory items total
|
|
137
|
+
dataView.setUint32(12, centralDirectorySize, true); // size of central directory
|
|
138
|
+
dataView.setUint32(16, centralDirectoryOffset, true); // offset to central directory with respect to starting disk
|
|
139
|
+
dataView.setUint16(20, 0, true); // zip file comemnt length
|
|
140
|
+
chunks.push(end);
|
|
141
|
+
this._data = JSData.initWithChunks(chunks);
|
|
109
142
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
},
|
|
113
|
-
|
|
114
|
-
addChunk: function(chunk){
|
|
115
|
-
this.chunks.push(chunk);
|
|
116
|
-
this.offset += chunk.length;
|
|
117
|
-
},
|
|
118
|
-
|
|
119
|
-
directory: null,
|
|
120
|
-
|
|
121
|
-
chunks: null,
|
|
122
|
-
|
|
123
|
-
data: JSReadOnlyProperty("_data", null),
|
|
143
|
+
return this._data;
|
|
144
|
+
}
|
|
124
145
|
|
|
125
146
|
});
|
|
@@ -244,6 +244,25 @@ Object.defineProperties(String.prototype, {
|
|
|
244
244
|
}
|
|
245
245
|
},
|
|
246
246
|
|
|
247
|
+
rangeForParagraphAtIndex: {
|
|
248
|
+
enumerable: false,
|
|
249
|
+
value: function String_rangeForParagraphAtIndex(index){
|
|
250
|
+
var iterator1 = this.userPerceivedCharacterIterator(index);
|
|
251
|
+
var startIndex = iterator1.range.location;
|
|
252
|
+
var iterator2 = UserPerceivedCharacterIterator(iterator1);
|
|
253
|
+
iterator1.decrement();
|
|
254
|
+
while (!iterator1.isParagraphBreak){
|
|
255
|
+
startIndex = iterator1.range.location;
|
|
256
|
+
iterator1.decrement();
|
|
257
|
+
}
|
|
258
|
+
while (!iterator2.isParagraphBreak){
|
|
259
|
+
iterator2.increment();
|
|
260
|
+
}
|
|
261
|
+
var endIndex = iterator2.range.end;
|
|
262
|
+
return JSRange(startIndex, endIndex - startIndex);
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
|
|
247
266
|
// -------------------------------------------------------------------------
|
|
248
267
|
// MARK: - Changing a String
|
|
249
268
|
|
|
@@ -359,6 +378,34 @@ Object.defineProperties(String.prototype, {
|
|
|
359
378
|
}
|
|
360
379
|
},
|
|
361
380
|
|
|
381
|
+
utf16be: {
|
|
382
|
+
configurable: true,
|
|
383
|
+
enumerable: false,
|
|
384
|
+
value: function String_utf16be(){
|
|
385
|
+
var utf16 = JSData.initWithLength(this.length * 2);
|
|
386
|
+
var dataView = utf16.dataView();
|
|
387
|
+
var j = 0;
|
|
388
|
+
for (var i = 0, l = this.length; i < l; ++i, j += 2){
|
|
389
|
+
dataView.setUint16(j, this.charCodeAt(i));
|
|
390
|
+
}
|
|
391
|
+
return utf16;
|
|
392
|
+
}
|
|
393
|
+
},
|
|
394
|
+
|
|
395
|
+
utf16le: {
|
|
396
|
+
configurable: true,
|
|
397
|
+
enumerable: false,
|
|
398
|
+
value: function String_utf16le(){
|
|
399
|
+
var utf16 = JSData.initWithLength(this.length * 2);
|
|
400
|
+
var dataView = utf16.dataView();
|
|
401
|
+
var j = 0;
|
|
402
|
+
for (var i = 0, l = this.length; i < l; ++i, j += 2){
|
|
403
|
+
dataView.setUint16(j, this.charCodeAt(i), true);
|
|
404
|
+
}
|
|
405
|
+
return utf16;
|
|
406
|
+
}
|
|
407
|
+
},
|
|
408
|
+
|
|
362
409
|
latin1: {
|
|
363
410
|
enumerable: false,
|
|
364
411
|
value: function String_latin1(){
|
|
@@ -387,6 +434,12 @@ Object.defineProperties(String.prototype, {
|
|
|
387
434
|
if (encoding == String.Encoding.latin1){
|
|
388
435
|
return this.latin1();
|
|
389
436
|
}
|
|
437
|
+
if (encoding == String.Encoding.utf16be){
|
|
438
|
+
return this.utf16be();
|
|
439
|
+
}
|
|
440
|
+
if (encoding == String.Encoding.utf16le){
|
|
441
|
+
return this.utf16le();
|
|
442
|
+
}
|
|
390
443
|
return null;
|
|
391
444
|
}
|
|
392
445
|
},
|
|
@@ -1125,6 +1178,22 @@ Object.defineProperties(UserPerceivedCharacterIterator.prototype, {
|
|
|
1125
1178
|
// can start with CR, we know the second character must be LF.
|
|
1126
1179
|
return this._unicodeIterator.character.isLineBreak;
|
|
1127
1180
|
}
|
|
1181
|
+
},
|
|
1182
|
+
|
|
1183
|
+
isParagraphBreak: {
|
|
1184
|
+
enumerable: true,
|
|
1185
|
+
configurable: false,
|
|
1186
|
+
get: function UserPerceivedCharacterIterator_isMandatoryLineBreak(){
|
|
1187
|
+
if (this._unicodeIterator.character === null){
|
|
1188
|
+
return true;
|
|
1189
|
+
}
|
|
1190
|
+
// Note that even though we're only checking the first character,
|
|
1191
|
+
// it will match the multi-char CRLF sequence, which is considered
|
|
1192
|
+
// to be a single user perceived character. In this case, only
|
|
1193
|
+
// the CR is checked, but since no other user perceived character
|
|
1194
|
+
// can start with CR, we know the second character must be LF.
|
|
1195
|
+
return this._unicodeIterator.character.isParagraphBreak;
|
|
1196
|
+
}
|
|
1128
1197
|
}
|
|
1129
1198
|
|
|
1130
1199
|
});
|
|
@@ -778,6 +778,14 @@ UnicodeChar.prototype = Object.create(Object.prototype, {
|
|
|
778
778
|
Object.defineProperty(this, 'isLineBreak', {value: this.code === UnicodeChar.LineBreaks.newLine || this.code === UnicodeChar.LineBreaks.formFeed || this.code === UnicodeChar.LineBreaks.carriageReturn || this.code === UnicodeChar.LineBreaks.nextLine || this.code === UnicodeChar.LineBreaks.lineSeparator || this.code === UnicodeChar.LineBreaks.paragraphSeparator});
|
|
779
779
|
return this.isLineBreak;
|
|
780
780
|
}
|
|
781
|
+
},
|
|
782
|
+
|
|
783
|
+
isParagraphBreak: {
|
|
784
|
+
configurable: true,
|
|
785
|
+
get: function UnicodeChar_lazy_isParagraphBreak(){
|
|
786
|
+
Object.defineProperty(this, 'isParagraphBreak', {value: this.code === UnicodeChar.LineBreaks.newLine || this.code === UnicodeChar.LineBreaks.formFeed || this.code === UnicodeChar.LineBreaks.carriageReturn || this.code === UnicodeChar.LineBreaks.nextLine || this.code === UnicodeChar.LineBreaks.paragraphSeparator});
|
|
787
|
+
return this.isParagraphBreak;
|
|
788
|
+
}
|
|
781
789
|
}
|
|
782
790
|
|
|
783
791
|
});
|
|
@@ -88,7 +88,7 @@ JSClass('UIBasicAnimation', UIPropertyAnimation, {
|
|
|
88
88
|
var progress = this.timingFunction(this._state.currentPercentage);
|
|
89
89
|
this.isComplete = this._state.isComplete();
|
|
90
90
|
this._updateContext[this._updateProperty] = this.interpolation(this._fromValue, this._toValue, progress);
|
|
91
|
-
if (this._updateContext === this._layer.presentation && this._updateProperty === "bounds"){
|
|
91
|
+
if (this._updateContext === this._layer.presentation && (this._updateProperty === "bounds" || this._updateProperty === "imageFrame")){
|
|
92
92
|
this._layer.setNeedsDisplay();
|
|
93
93
|
}
|
|
94
94
|
},
|
|
@@ -69,7 +69,7 @@ JSClass("UIHTMLApplication", UIApplication, {
|
|
|
69
69
|
if (options === undefined){
|
|
70
70
|
options = {};
|
|
71
71
|
}
|
|
72
|
-
if (options.replacingApplication){
|
|
72
|
+
if (options.replacingApplication || url.scheme === "mailto" || url.scheme === "tel"){
|
|
73
73
|
var application = this;
|
|
74
74
|
var open = function(){
|
|
75
75
|
application.domWindow.location.href = url.encodedString;
|