@breakside/jskit 2026.4.0 → 2026.6.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/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/TestCommand.js +1 -1
- 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/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/ImageKit/Info.yaml +1 -1
- package/Root/Frameworks/MediaKit/Info.yaml +1 -1
- package/Root/Frameworks/MediaKit/QuickTime/MKQuickTime.js +1 -31
- package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeAtom.js +13 -7
- package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeEditList.js +33 -3
- package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeFileType.js +1 -1
- package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMedia.js +3 -62
- package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMediaHandler.js +4 -1
- package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMediaHeader.js +20 -1
- package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMovieHeader.js +28 -1
- package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeSampleDescription.js +5 -1
- package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeSampleSize.js +4 -1
- package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeTimeToSample.js +3 -0
- package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeTrackHeader.js +28 -1
- package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeVideoMediaInformationHeader.js +3 -0
- 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/UICollectionViewGridLayout.js +59 -19
- package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.DOM",
|
|
4
|
-
"JSBundleVersion": "2026.
|
|
4
|
+
"JSBundleVersion": "2026.6.0",
|
|
5
5
|
"JSDevelopmentLanguage": "en",
|
|
6
6
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
7
7
|
"JSBundleEnvironments": {
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
"node": "DOM+Node.js"
|
|
10
10
|
},
|
|
11
11
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
12
|
-
"GitRevision": "
|
|
12
|
+
"GitRevision": "4d2276988e1dc6a50451389c84f740a16249d16e"
|
|
13
13
|
}
|
|
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.DOM'] = {
|
|
|
3
3
|
"Info": {
|
|
4
4
|
"JSBundleType": "framework",
|
|
5
5
|
"JSBundleIdentifier": "io.breakside.JSKit.DOM",
|
|
6
|
-
"JSBundleVersion": "2026.
|
|
6
|
+
"JSBundleVersion": "2026.6.0",
|
|
7
7
|
"JSDevelopmentLanguage": "en",
|
|
8
8
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
9
9
|
"JSBundleEnvironments": {
|
|
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.DOM'] = {
|
|
|
11
11
|
"node": "DOM+Node.js"
|
|
12
12
|
},
|
|
13
13
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
14
|
-
"GitRevision": "
|
|
14
|
+
"GitRevision": "4d2276988e1dc6a50451389c84f740a16249d16e"
|
|
15
15
|
},
|
|
16
16
|
"Resources": [],
|
|
17
17
|
"ResourceLookup": {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.FontKit",
|
|
4
|
-
"JSBundleVersion": "2026.
|
|
4
|
+
"JSBundleVersion": "2026.6.0",
|
|
5
5
|
"JSDevelopmentLanguage": "en",
|
|
6
6
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
7
7
|
"JSBundleEnvironments": {
|
|
8
8
|
"html": "FontKit+HTML.js"
|
|
9
9
|
},
|
|
10
10
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
11
|
-
"GitRevision": "
|
|
11
|
+
"GitRevision": "4d2276988e1dc6a50451389c84f740a16249d16e"
|
|
12
12
|
}
|
|
@@ -3,14 +3,14 @@ JSBundle.bundles['io.breakside.JSKit.FontKit'] = {
|
|
|
3
3
|
"Info": {
|
|
4
4
|
"JSBundleType": "framework",
|
|
5
5
|
"JSBundleIdentifier": "io.breakside.JSKit.FontKit",
|
|
6
|
-
"JSBundleVersion": "2026.
|
|
6
|
+
"JSBundleVersion": "2026.6.0",
|
|
7
7
|
"JSDevelopmentLanguage": "en",
|
|
8
8
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
9
9
|
"JSBundleEnvironments": {
|
|
10
10
|
"html": "FontKit+HTML.js"
|
|
11
11
|
},
|
|
12
12
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
13
|
-
"GitRevision": "
|
|
13
|
+
"GitRevision": "4d2276988e1dc6a50451389c84f740a16249d16e"
|
|
14
14
|
},
|
|
15
15
|
"Resources": [],
|
|
16
16
|
"ResourceLookup": {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.Foundation",
|
|
4
|
-
"JSBundleVersion": "2026.
|
|
4
|
+
"JSBundleVersion": "2026.6.0",
|
|
5
5
|
"JSDevelopmentLanguage": "en",
|
|
6
6
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
7
7
|
"JSBundleEnvironments": {
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
"node": "Foundation+Node.js"
|
|
10
10
|
},
|
|
11
11
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
12
|
-
"GitRevision": "
|
|
12
|
+
"GitRevision": "4d2276988e1dc6a50451389c84f740a16249d16e"
|
|
13
13
|
}
|
|
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.Foundation'] = {
|
|
|
3
3
|
"Info": {
|
|
4
4
|
"JSBundleType": "framework",
|
|
5
5
|
"JSBundleIdentifier": "io.breakside.JSKit.Foundation",
|
|
6
|
-
"JSBundleVersion": "2026.
|
|
6
|
+
"JSBundleVersion": "2026.6.0",
|
|
7
7
|
"JSDevelopmentLanguage": "en",
|
|
8
8
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
9
9
|
"JSBundleEnvironments": {
|
|
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.Foundation'] = {
|
|
|
11
11
|
"node": "Foundation+Node.js"
|
|
12
12
|
},
|
|
13
13
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
14
|
-
"GitRevision": "
|
|
14
|
+
"GitRevision": "4d2276988e1dc6a50451389c84f740a16249d16e"
|
|
15
15
|
},
|
|
16
16
|
"Resources": [
|
|
17
17
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "framework",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.JSKit.SecurityKit",
|
|
4
|
-
"JSBundleVersion": "2026.
|
|
4
|
+
"JSBundleVersion": "2026.6.0",
|
|
5
5
|
"JSDevelopmentLanguage": "en",
|
|
6
6
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
7
7
|
"JSBundleEnvironments": {
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
"node": "SecurityKit+Node.js"
|
|
10
10
|
},
|
|
11
11
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
12
|
-
"GitRevision": "
|
|
12
|
+
"GitRevision": "4d2276988e1dc6a50451389c84f740a16249d16e"
|
|
13
13
|
}
|
|
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.SecurityKit'] = {
|
|
|
3
3
|
"Info": {
|
|
4
4
|
"JSBundleType": "framework",
|
|
5
5
|
"JSBundleIdentifier": "io.breakside.JSKit.SecurityKit",
|
|
6
|
-
"JSBundleVersion": "2026.
|
|
6
|
+
"JSBundleVersion": "2026.6.0",
|
|
7
7
|
"JSDevelopmentLanguage": "en",
|
|
8
8
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
9
9
|
"JSBundleEnvironments": {
|
|
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.SecurityKit'] = {
|
|
|
11
11
|
"node": "SecurityKit+Node.js"
|
|
12
12
|
},
|
|
13
13
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
14
|
-
"GitRevision": "
|
|
14
|
+
"GitRevision": "4d2276988e1dc6a50451389c84f740a16249d16e"
|
|
15
15
|
},
|
|
16
16
|
"Resources": [],
|
|
17
17
|
"ResourceLookup": {
|
package/Info.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"JSBundleType": "node",
|
|
3
3
|
"JSBundleIdentifier": "io.breakside.jskit",
|
|
4
|
-
"JSBundleVersion": "2026.
|
|
4
|
+
"JSBundleVersion": "2026.6.0",
|
|
5
5
|
"JSExecutableName": "jskit",
|
|
6
6
|
"NPMOrganization": "breakside",
|
|
7
7
|
"JSResources": [
|
|
8
8
|
"Tests/HTMLTestRunner.js",
|
|
9
9
|
"Tests/NodeTestRunner.js"
|
|
10
10
|
],
|
|
11
|
-
"GitRevision": "
|
|
11
|
+
"GitRevision": "4d2276988e1dc6a50451389c84f740a16249d16e"
|
|
12
12
|
}
|
package/Node/TestCommand.js
CHANGED
|
@@ -239,7 +239,7 @@ JSClass("TestCommand", Command, {
|
|
|
239
239
|
var query = url.query;
|
|
240
240
|
query.add("headless");
|
|
241
241
|
url.query = query;
|
|
242
|
-
var page = await browser.newPage();
|
|
242
|
+
var page = await browser.newPage({locale: Intl.DateTimeFormat().resolvedOptions().locale});
|
|
243
243
|
var cmd = this;
|
|
244
244
|
await new Promise(function(resolve, reject){
|
|
245
245
|
page.exposeFunction("headlessPrint", function(text, ttyOnly){
|
|
@@ -3,14 +3,14 @@ JSBundle.bundles['io.breakside.jskit'] = {
|
|
|
3
3
|
"Info": {
|
|
4
4
|
"JSBundleType": "node",
|
|
5
5
|
"JSBundleIdentifier": "io.breakside.jskit",
|
|
6
|
-
"JSBundleVersion": "2026.
|
|
6
|
+
"JSBundleVersion": "2026.6.0",
|
|
7
7
|
"JSExecutableName": "jskit",
|
|
8
8
|
"NPMOrganization": "breakside",
|
|
9
9
|
"JSResources": [
|
|
10
10
|
"Tests/HTMLTestRunner.js",
|
|
11
11
|
"Tests/NodeTestRunner.js"
|
|
12
12
|
],
|
|
13
|
-
"GitRevision": "
|
|
13
|
+
"GitRevision": "4d2276988e1dc6a50451389c84f740a16249d16e"
|
|
14
14
|
},
|
|
15
15
|
"Resources": [
|
|
16
16
|
{
|
|
@@ -31,39 +31,9 @@ JSClass("MKQuickTime", MKQuickTimeAtom, {
|
|
|
31
31
|
}
|
|
32
32
|
if (header.timeScale === 0){
|
|
33
33
|
logger.warn("mvhd timeScale = 0");
|
|
34
|
-
// Seen some videos in the wild with timeScale = 0
|
|
35
|
-
// That messes up our ability to calcualte things using timeScale,
|
|
36
|
-
// but those videos are still playable by QuickTime, so there's
|
|
37
|
-
// gotta be something else we can do. Documentation doesn't really
|
|
38
|
-
// say anything, so we'll look to tracks for an answer.
|
|
39
|
-
return this.durationCalculatedFromTracks;
|
|
40
|
-
}
|
|
41
|
-
return header.duration / header.timeScale;
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
durationCalculatedFromTracks: JSReadOnlyProperty(),
|
|
45
|
-
|
|
46
|
-
getDurationCalculatedFromTracks: function(){
|
|
47
|
-
var movie = this.movie;
|
|
48
|
-
if (movie === null){
|
|
49
34
|
return -1;
|
|
50
35
|
}
|
|
51
|
-
|
|
52
|
-
var media;
|
|
53
|
-
var i, l;
|
|
54
|
-
var longestTrackDuration = -1;
|
|
55
|
-
var duration;
|
|
56
|
-
for (i = 0, l = movie.tracks.length; i < l; ++i){
|
|
57
|
-
track = movie.tracks[i];
|
|
58
|
-
media = track.media;
|
|
59
|
-
if (media !== null){
|
|
60
|
-
duration = media.duration;
|
|
61
|
-
if (duration > longestTrackDuration){
|
|
62
|
-
longestTrackDuration = duration;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return longestTrackDuration;
|
|
36
|
+
return header.duration / header.timeScale;
|
|
67
37
|
},
|
|
68
38
|
|
|
69
39
|
posterTime: JSReadOnlyProperty(),
|
|
@@ -30,19 +30,15 @@ JSClass("MKQuickTimeAtom", JSObject, {
|
|
|
30
30
|
var l = this.data.length;
|
|
31
31
|
var size;
|
|
32
32
|
var type;
|
|
33
|
-
var a, b;
|
|
34
33
|
var atomClass, atom;
|
|
35
34
|
while (i < l - 8){
|
|
36
35
|
size = this.dataView.getUint32(i);
|
|
37
36
|
type = this.dataView.getUint32(i + 4);
|
|
38
37
|
if (size === 0x00000001){
|
|
39
38
|
if (i < l - 16){
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (size > Number.MAX_SAFE_INTEGER){
|
|
44
|
-
throw new Error("cannot retain full precision of 64 bit integer for atom at byte %d".sprintf(i));
|
|
45
|
-
}
|
|
39
|
+
size = this._getUint64(i + 8);
|
|
40
|
+
}else{
|
|
41
|
+
throw new Error("not enough bytes at %d for a 64bit size".sprintf(i));
|
|
46
42
|
}
|
|
47
43
|
}else{
|
|
48
44
|
if (size === 0x00000000){
|
|
@@ -113,6 +109,16 @@ JSClass("MKQuickTimeAtom", JSObject, {
|
|
|
113
109
|
}
|
|
114
110
|
}
|
|
115
111
|
return dictionary;
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
_getUint64: function(offset){
|
|
115
|
+
var a = this.dataView.getUint32(offset);
|
|
116
|
+
var b = this.dataView.getUint32(offset + 4);
|
|
117
|
+
var size = Math.pow(2, 32) * a + b;
|
|
118
|
+
if (size > Number.MAX_SAFE_INTEGER){
|
|
119
|
+
throw new Error("cannot retain full precision of 64 bit integer for atom at byte %d".sprintf(offset));
|
|
120
|
+
}
|
|
121
|
+
return size;
|
|
116
122
|
}
|
|
117
123
|
|
|
118
124
|
});
|
|
@@ -25,6 +25,9 @@ JSClass("MKQuickTimeEditList", MKQuickTimeAtom, {
|
|
|
25
25
|
if (data.length < 16){
|
|
26
26
|
throw new Error("expecting at least 16 bytes for elst atom");
|
|
27
27
|
}
|
|
28
|
+
if (this.version > 1){
|
|
29
|
+
throw new Error("Unsupported elst version: %d".sprintf(this.version));
|
|
30
|
+
}
|
|
28
31
|
},
|
|
29
32
|
|
|
30
33
|
getNumberOfEntries: function(){
|
|
@@ -32,7 +35,16 @@ JSClass("MKQuickTimeEditList", MKQuickTimeAtom, {
|
|
|
32
35
|
},
|
|
33
36
|
|
|
34
37
|
durationAtIndex: function(index){
|
|
35
|
-
var i
|
|
38
|
+
var i;
|
|
39
|
+
if (this.version === 1){
|
|
40
|
+
i = 16 + index * 20;
|
|
41
|
+
if (i >= 16 && i < this.data.length){
|
|
42
|
+
return this._getUint64(i);
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
// version 0
|
|
47
|
+
i = 16 + index * 12;
|
|
36
48
|
if (i >= 16 && i < this.data.length){
|
|
37
49
|
return this.dataView.getUint32(i);
|
|
38
50
|
}
|
|
@@ -40,7 +52,16 @@ JSClass("MKQuickTimeEditList", MKQuickTimeAtom, {
|
|
|
40
52
|
},
|
|
41
53
|
|
|
42
54
|
mediaTimeAtIndex: function(index){
|
|
43
|
-
var i
|
|
55
|
+
var i;
|
|
56
|
+
if (this.version === 1){
|
|
57
|
+
i = 16 + index * 20;
|
|
58
|
+
if (i >= 16 && i < this.data.length){
|
|
59
|
+
return this._getUint64(i + 8);
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
// version 0
|
|
64
|
+
i = 16 + index * 12;
|
|
44
65
|
if (i >= 16 && i < this.data.length){
|
|
45
66
|
return this.dataView.getUint32(i + 4);
|
|
46
67
|
}
|
|
@@ -48,7 +69,16 @@ JSClass("MKQuickTimeEditList", MKQuickTimeAtom, {
|
|
|
48
69
|
},
|
|
49
70
|
|
|
50
71
|
mediaRateAtIndex: function(index){
|
|
51
|
-
var i
|
|
72
|
+
var i;
|
|
73
|
+
if (this.version === 1){
|
|
74
|
+
i = 16 + index * 20;
|
|
75
|
+
if (i >= 16 && i < this.data.length){
|
|
76
|
+
return this.dataView.getUint16(i + 16) + this.dataView.getUint16(i + 18) / 0x10000;
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
// version 0
|
|
81
|
+
i = 16 + index * 12;
|
|
52
82
|
if (i >= 16 && i < this.data.length){
|
|
53
83
|
return this.dataView.getUint16(i + 8) + this.dataView.getUint16(i + 10) / 0x10000;
|
|
54
84
|
}
|
|
@@ -21,10 +21,10 @@ JSClass("MKQuickTimeFileType", MKQuickTimeAtom, {
|
|
|
21
21
|
},
|
|
22
22
|
|
|
23
23
|
initWithData: function(data){
|
|
24
|
+
MKQuickTimeFileType.$super.initWithData.call(this, data);
|
|
24
25
|
if (data.length < 16){
|
|
25
26
|
throw new Error("expecting at least 16 bytes for ftyp atom");
|
|
26
27
|
}
|
|
27
|
-
MKQuickTimeFileType.$super.initWithData.call(this, data);
|
|
28
28
|
},
|
|
29
29
|
|
|
30
30
|
dictionaryRepresentation: function(){
|
|
@@ -46,43 +46,9 @@ JSClass("MKQuickTimeMedia", MKQuickTimeAtom, {
|
|
|
46
46
|
return -1;
|
|
47
47
|
}
|
|
48
48
|
if (header.timeScale === 0){
|
|
49
|
-
// Seen some videos in the wild with timeScale = 0
|
|
50
|
-
// That messes up our ability to calcualte things using timeScale,
|
|
51
|
-
// but those videos are still playable by QuickTime, so there's
|
|
52
|
-
// gotta be something else we can do. Documentation doesn't really
|
|
53
|
-
// say what to do, so we'll try to use sample counts and a guessed fps.
|
|
54
|
-
return this.durationCalculatedFromSamples;
|
|
55
|
-
}
|
|
56
|
-
return header.duration / header.timeScale;
|
|
57
|
-
},
|
|
58
|
-
|
|
59
|
-
durationCalculatedFromSamples: JSReadOnlyProperty(),
|
|
60
|
-
|
|
61
|
-
getDurationCalculatedFromSamples: function(){
|
|
62
|
-
var handler = this.mediaHandler;
|
|
63
|
-
if (handler === null){
|
|
64
|
-
return -1;
|
|
65
|
-
}
|
|
66
|
-
if (handler.componentSubtype !== MKQuickTimeMediaHandler.ComponentSubtype.vide){
|
|
67
|
-
return -1;
|
|
68
|
-
}
|
|
69
|
-
var info = this.mediaInformation;
|
|
70
|
-
if (info === null){
|
|
71
49
|
return -1;
|
|
72
50
|
}
|
|
73
|
-
|
|
74
|
-
if (header === null){
|
|
75
|
-
return -1;
|
|
76
|
-
}
|
|
77
|
-
var counts = info.sampleCounts;
|
|
78
|
-
var totalCount = 0;
|
|
79
|
-
var i, l;
|
|
80
|
-
for (i = 0, l = counts.length; i < l; ++i){
|
|
81
|
-
totalCount += counts[i];
|
|
82
|
-
}
|
|
83
|
-
// We're only calling this method when timeScale is 0, in which case
|
|
84
|
-
// `averageVideoFrameRate` will be hard-coded to 30fps
|
|
85
|
-
return totalCount / this.averageVideoFrameRate;
|
|
51
|
+
return header.duration / header.timeScale;
|
|
86
52
|
},
|
|
87
53
|
|
|
88
54
|
videoFrameRates: JSReadOnlyProperty(),
|
|
@@ -107,17 +73,8 @@ JSClass("MKQuickTimeMedia", MKQuickTimeAtom, {
|
|
|
107
73
|
var durations = info.sampleDurations;
|
|
108
74
|
var i, l;
|
|
109
75
|
var timeScale = header.timeScale;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
// That messes up our ability to calcualte things using timeScale,
|
|
113
|
-
// but those videos are still playable by QuickTime, so there's
|
|
114
|
-
// gotta be something else we can do. Documentation doesn't really
|
|
115
|
-
// say what to do, so we'll go with a guess: 30fps.
|
|
116
|
-
rates.push(30);
|
|
117
|
-
}else{
|
|
118
|
-
for (i = 0, l = durations.length; i < l; ++i){
|
|
119
|
-
rates.push(timeScale / durations[i]);
|
|
120
|
-
}
|
|
76
|
+
for (i = 0, l = durations.length; i < l; ++i){
|
|
77
|
+
rates.push(timeScale / durations[i]);
|
|
121
78
|
}
|
|
122
79
|
return rates;
|
|
123
80
|
},
|
|
@@ -141,14 +98,6 @@ JSClass("MKQuickTimeMedia", MKQuickTimeAtom, {
|
|
|
141
98
|
return null;
|
|
142
99
|
}
|
|
143
100
|
var timeScale = header.timeScale;
|
|
144
|
-
if (timeScale === 0){
|
|
145
|
-
// Seen some videos in the wild with timeScale = 0
|
|
146
|
-
// That messes up our ability to calcualte things using timeScale,
|
|
147
|
-
// but those videos are still playable by QuickTime, so there's
|
|
148
|
-
// gotta be something else we can do. Documentation doesn't really
|
|
149
|
-
// say what to do, so we'll go with a guess: 30fps.
|
|
150
|
-
return 30;
|
|
151
|
-
}
|
|
152
101
|
var counts = info.sampleCounts;
|
|
153
102
|
var durations = info.sampleDurations;
|
|
154
103
|
var totalCount = 0;
|
|
@@ -208,14 +157,6 @@ JSClass("MKQuickTimeMedia", MKQuickTimeAtom, {
|
|
|
208
157
|
return null;
|
|
209
158
|
}
|
|
210
159
|
var timeScale = header.timeScale;
|
|
211
|
-
if (timeScale === 0){
|
|
212
|
-
// Seen some videos in the wild with timeScale = 0
|
|
213
|
-
// That messes up our ability to calcualte things using timeScale,
|
|
214
|
-
// but those videos are still playable by QuickTime, so there's
|
|
215
|
-
// gotta be something else we can do. Documentation doesn't really
|
|
216
|
-
// say what to do, so we'll just bail and say 0.
|
|
217
|
-
return 0;
|
|
218
|
-
}
|
|
219
160
|
var counts = info.sampleCounts;
|
|
220
161
|
var durations = info.sampleDurations;
|
|
221
162
|
var totalSeconds = 0;
|
|
@@ -30,10 +30,13 @@ JSClass("MKQuickTimeMediaHandler", MKQuickTimeAtom, {
|
|
|
30
30
|
},
|
|
31
31
|
|
|
32
32
|
initWithData: function(data){
|
|
33
|
+
MKQuickTimeMediaHandler.$super.initWithData.call(this, data);
|
|
33
34
|
if (data.length < 20){
|
|
34
35
|
throw new Error("expecting at least 20 bytes for hdlr atom");
|
|
35
36
|
}
|
|
36
|
-
|
|
37
|
+
if (this.version > 0){
|
|
38
|
+
throw new Error("Unsupported hdlr version: %d".sprintf(this.version));
|
|
39
|
+
}
|
|
37
40
|
},
|
|
38
41
|
|
|
39
42
|
dictionaryRepresentation: function(){
|
|
@@ -22,18 +22,37 @@ JSClass("MKQuickTimeMediaHeader", MKQuickTimeAtom, {
|
|
|
22
22
|
},
|
|
23
23
|
|
|
24
24
|
getTimeScale: function(){
|
|
25
|
+
if (this.version === 1){
|
|
26
|
+
return this.dataView.getUint32(28);
|
|
27
|
+
}
|
|
28
|
+
// version 0
|
|
25
29
|
return this.dataView.getUint32(20);
|
|
26
30
|
},
|
|
27
31
|
|
|
28
32
|
getDuration: function(){
|
|
33
|
+
if (this.version === 1){
|
|
34
|
+
return this._getUint64(32);
|
|
35
|
+
}
|
|
36
|
+
// version 0
|
|
29
37
|
return this.dataView.getUint32(24);
|
|
30
38
|
},
|
|
31
39
|
|
|
32
40
|
initWithData: function(data){
|
|
41
|
+
MKQuickTimeMediaHeader.$super.initWithData.call(this, data);
|
|
42
|
+
if (data.length < 12){
|
|
43
|
+
Error("expecting at least 12 bytes for mdhd atom");
|
|
44
|
+
}
|
|
45
|
+
if (this.version > 1){
|
|
46
|
+
throw new Error("Unsupported mdhd version: %d".sprintf(this.version));
|
|
47
|
+
}
|
|
48
|
+
if (this.version === 1){
|
|
49
|
+
if (data.length < 40){
|
|
50
|
+
throw new Error("expecting at least 40 bytes for mdhd v1 atom");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
33
53
|
if (data.length < 28){
|
|
34
54
|
throw new Error("expecting at least 28 bytes for mdhd atom");
|
|
35
55
|
}
|
|
36
|
-
MKQuickTimeMediaHeader.$super.initWithData.call(this, data);
|
|
37
56
|
},
|
|
38
57
|
|
|
39
58
|
dictionaryRepresentation: function(){
|
|
@@ -24,26 +24,53 @@ JSClass("MKQuickTimeMovieHeader", MKQuickTimeAtom, {
|
|
|
24
24
|
},
|
|
25
25
|
|
|
26
26
|
getTimeScale: function(){
|
|
27
|
+
if (this.version === 1){
|
|
28
|
+
return this.dataView.getUint32(28);
|
|
29
|
+
}
|
|
30
|
+
// version 0
|
|
27
31
|
return this.dataView.getUint32(20);
|
|
28
32
|
},
|
|
29
33
|
|
|
30
34
|
getDuration: function(){
|
|
35
|
+
if (this.version === 1){
|
|
36
|
+
return this._getUint64(32);
|
|
37
|
+
}
|
|
38
|
+
// version 0
|
|
31
39
|
return this.dataView.getUint32(24);
|
|
32
40
|
},
|
|
33
41
|
|
|
34
42
|
getPreferredRate: function(){
|
|
43
|
+
if (this.version === 1){
|
|
44
|
+
return this.dataView.getUint16(40) + this.dataView.getUint16(42) / 0x10000;
|
|
45
|
+
}
|
|
46
|
+
// version 0
|
|
35
47
|
return this.dataView.getUint16(28) + this.dataView.getUint16(30) / 0x10000;
|
|
36
48
|
},
|
|
37
49
|
|
|
38
50
|
getPosterTime: function(){
|
|
51
|
+
if (this.version === 1){
|
|
52
|
+
return this.dataView.getUint32(90);
|
|
53
|
+
}
|
|
54
|
+
// version 0
|
|
39
55
|
return this.dataView.getUint32(78);
|
|
40
56
|
},
|
|
41
57
|
|
|
42
58
|
initWithData: function(data){
|
|
59
|
+
MKQuickTimeMovieHeader.$super.initWithData.call(this, data);
|
|
60
|
+
if (data.length < 12){
|
|
61
|
+
Error("expecting at least 12 bytes for mvhd atom");
|
|
62
|
+
}
|
|
63
|
+
if (this.version > 1){
|
|
64
|
+
throw new Error("Unsupported mvhd version: %d".sprintf(this.version));
|
|
65
|
+
}
|
|
66
|
+
if (this.version === 1){
|
|
67
|
+
if (data.length < 110){
|
|
68
|
+
throw new Error("expecting at least 110 bytes for mvhd v1 atom");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
43
71
|
if (data.length < 98){
|
|
44
72
|
throw new Error("expecting at least 98 bytes for mvhd atom");
|
|
45
73
|
}
|
|
46
|
-
MKQuickTimeMovieHeader.$super.initWithData.call(this, data);
|
|
47
74
|
},
|
|
48
75
|
|
|
49
76
|
dictionaryRepresentation: function(){
|
|
@@ -23,7 +23,11 @@ JSClass("MKQuickTimeSampleDescription", MKQuickTimeAtom, {
|
|
|
23
23
|
initWithData: function(data){
|
|
24
24
|
MKQuickTimeSampleDescription.$super.initWithData.call(this, data);
|
|
25
25
|
if (data.length < 16){
|
|
26
|
-
throw new Error("expecting at least 16 bytes for
|
|
26
|
+
throw new Error("expecting at least 16 bytes for stsd atom");
|
|
27
|
+
}
|
|
28
|
+
// version 1 is allowed, but treated like version 0
|
|
29
|
+
if (this.version > 1){
|
|
30
|
+
throw new Error("Unsupported stsd version: %d".sprintf(this.version));
|
|
27
31
|
}
|
|
28
32
|
},
|
|
29
33
|
|
|
@@ -24,7 +24,10 @@ JSClass("MKQuickTimeSampleSize", MKQuickTimeAtom, {
|
|
|
24
24
|
initWithData: function(data){
|
|
25
25
|
MKQuickTimeSampleSize.$super.initWithData.call(this, data);
|
|
26
26
|
if (data.length < 20){
|
|
27
|
-
throw new Error("expecting at least 20 bytes for
|
|
27
|
+
throw new Error("expecting at least 20 bytes for stsz atom");
|
|
28
|
+
}
|
|
29
|
+
if (this.version > 0){
|
|
30
|
+
throw new Error("Unsupported stsz version: %d".sprintf(this.version));
|
|
28
31
|
}
|
|
29
32
|
},
|
|
30
33
|
|
|
@@ -30,6 +30,9 @@ JSClass("MKQuickTimeTimeToSample", MKQuickTimeAtom, {
|
|
|
30
30
|
if (data.length < l){
|
|
31
31
|
throw new Error("expecting at least %d bytes for stts atom with %d entries".sprintf(l, n));
|
|
32
32
|
}
|
|
33
|
+
if (this.version > 0){
|
|
34
|
+
throw new Error("Unsupported stts version: %d".sprintf(this.version));
|
|
35
|
+
}
|
|
33
36
|
},
|
|
34
37
|
|
|
35
38
|
getNumberOfEntries: function(){
|
|
@@ -36,18 +36,34 @@ JSClass("MKQuickTimeTrackHeader", MKQuickTimeAtom, {
|
|
|
36
36
|
},
|
|
37
37
|
|
|
38
38
|
getTrackID: function(){
|
|
39
|
+
if (this.version === 1){
|
|
40
|
+
return this.dataView.getUint32(28);
|
|
41
|
+
}
|
|
42
|
+
// version 0
|
|
39
43
|
return this.dataView.getUint32(20);
|
|
40
44
|
},
|
|
41
45
|
|
|
42
46
|
getDuration: function(){
|
|
47
|
+
if (this.version === 1){
|
|
48
|
+
return this.dataView.getUint32(40);
|
|
49
|
+
}
|
|
50
|
+
// version 0
|
|
43
51
|
return this.dataView.getUint32(28);
|
|
44
52
|
},
|
|
45
53
|
|
|
46
54
|
getWidth: function(){
|
|
55
|
+
if (this.version === 1){
|
|
56
|
+
return this.dataView.getUint16(96) + this.dataView.getUint16(98) / 0x10000;
|
|
57
|
+
}
|
|
58
|
+
// version 0
|
|
47
59
|
return this.dataView.getUint16(84) + this.dataView.getUint16(86) / 0x10000;
|
|
48
60
|
},
|
|
49
61
|
|
|
50
62
|
getHeight: function(){
|
|
63
|
+
if (this.version === 1){
|
|
64
|
+
return this.dataView.getUint16(100) + this.dataView.getUint16(102) / 0x10000;
|
|
65
|
+
}
|
|
66
|
+
// version 0
|
|
51
67
|
return this.dataView.getUint16(88) + this.dataView.getUint16(90) / 0x10000;
|
|
52
68
|
},
|
|
53
69
|
|
|
@@ -58,10 +74,21 @@ JSClass("MKQuickTimeTrackHeader", MKQuickTimeAtom, {
|
|
|
58
74
|
},
|
|
59
75
|
|
|
60
76
|
initWithData: function(data){
|
|
77
|
+
MKQuickTimeTrackHeader.$super.initWithData.call(this, data);
|
|
78
|
+
if (data.length < 12){
|
|
79
|
+
Error("expecting at least 12 bytes for tkhd atom");
|
|
80
|
+
}
|
|
81
|
+
if (this.version > 1){
|
|
82
|
+
throw new Error("Unsupported tkhd version: %d".sprintf(this.version));
|
|
83
|
+
}
|
|
84
|
+
if (this.version === 1){
|
|
85
|
+
if (data.length < 104){
|
|
86
|
+
throw new Error("expecting at least 104 bytes for tkhd v1 atom");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
61
89
|
if (data.length < 92){
|
|
62
90
|
throw new Error("expecting at least 92 bytes for tkhd atom");
|
|
63
91
|
}
|
|
64
|
-
MKQuickTimeTrackHeader.$super.initWithData.call(this, data);
|
|
65
92
|
},
|
|
66
93
|
|
|
67
94
|
dictionaryRepresentation: function(){
|
|
@@ -24,6 +24,9 @@ JSClass("MKQuickTimeVideoMediaInformationHeader", MKQuickTimeAtom, {
|
|
|
24
24
|
if (data.length < 20){
|
|
25
25
|
throw new Error("expecting at least 20 bytes for vmhd atom");
|
|
26
26
|
}
|
|
27
|
+
if (this.version > 0){
|
|
28
|
+
throw new Error("Unsupported vmhd version: %d".sprintf(this.version));
|
|
29
|
+
}
|
|
27
30
|
},
|
|
28
31
|
|
|
29
32
|
graphicsMode: JSReadOnlyProperty(),
|
|
@@ -17,6 +17,14 @@
|
|
|
17
17
|
/* global UICollectionView */
|
|
18
18
|
"use strict";
|
|
19
19
|
|
|
20
|
+
JSProtocol("UICollectionViewGridLayoutDelegate", JSProtocol, {
|
|
21
|
+
|
|
22
|
+
heightForCollectionViewHeaderInSection: function(collectionView, sectionIndex){},
|
|
23
|
+
heightForCollectionViewFooterInSection: function(collectionView, sectionIndex){},
|
|
24
|
+
cellSizeForCollectionViewInSection: function(collectionView, sectionIndex){},
|
|
25
|
+
|
|
26
|
+
});
|
|
27
|
+
|
|
20
28
|
JSClass("UICollectionViewGridLayout", UICollectionViewLayout, {
|
|
21
29
|
|
|
22
30
|
init: function(){
|
|
@@ -228,33 +236,63 @@ JSClass("UICollectionViewGridLayout", UICollectionViewLayout, {
|
|
|
228
236
|
var rowOffset = 0;
|
|
229
237
|
var sectionHeaderAndSpacingHeight = 0;
|
|
230
238
|
var sectionFooterAndSpacingHeight = 0;
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
sectionFooterAndSpacingHeight= this._sectionFooterHeight + this._sectionFooterSpacing;
|
|
236
|
-
}
|
|
239
|
+
var sectionHeaderHeight;
|
|
240
|
+
var sectionFooterHeight;
|
|
241
|
+
var sectionCellSize;
|
|
242
|
+
var sectionColumns;
|
|
237
243
|
for (sectionIndex = 0; sectionIndex < sectionCount; ++sectionIndex){
|
|
244
|
+
sectionHeaderHeight = this._sectionHeaderHeight;
|
|
245
|
+
sectionFooterHeight = this._sectionFooterHeight;
|
|
246
|
+
sectionCellSize = this._cellSize;
|
|
247
|
+
if (this.collectionView.delegate && this.collectionView.delegate.heightForCollectionViewHeaderInSection){
|
|
248
|
+
sectionHeaderHeight = this.collectionView.delegate.heightForCollectionViewHeaderInSection(this.collectionView, sectionIndex);
|
|
249
|
+
}
|
|
250
|
+
if (this.collectionView.delegate && this.collectionView.delegate.heightForCollectionViewFooterInSection){
|
|
251
|
+
sectionFooterHeight = this.collectionView.delegate.heightForCollectionViewFooterInSection(this.collectionView, sectionIndex);
|
|
252
|
+
}
|
|
253
|
+
if (this.collectionView.delegate && this.collectionView.delegate.cellSizeForCollectionViewInSection){
|
|
254
|
+
sectionCellSize = this.collectionView.delegate.cellSizeForCollectionViewInSection(this.collectionView, sectionIndex);
|
|
255
|
+
}
|
|
256
|
+
if (sectionHeaderHeight > 0){
|
|
257
|
+
sectionHeaderAndSpacingHeight = sectionHeaderHeight + this._sectionHeaderSpacing;
|
|
258
|
+
}
|
|
259
|
+
if (sectionFooterHeight > 0){
|
|
260
|
+
sectionFooterAndSpacingHeight= sectionFooterHeight + this._sectionFooterSpacing;
|
|
261
|
+
}
|
|
262
|
+
if (sectionCellSize.width != this._cellSize.width){
|
|
263
|
+
columnCount = Math.max(1, Math.floor((availableWidth + this._columnSpacing) / (sectionCellSize.width + this._columnSpacing)));
|
|
264
|
+
x = this._collectionInsets.left + this._sectionInsets.left;
|
|
265
|
+
sectionColumns = [];
|
|
266
|
+
for (columnIndex = 0; columnIndex < columnCount; ++columnIndex){
|
|
267
|
+
sectionColumns.push({x: x});
|
|
268
|
+
x += sectionCellSize.width + this._columnSpacing;
|
|
269
|
+
}
|
|
270
|
+
}else{
|
|
271
|
+
columnCount = this._cachedLayout.columns.length;
|
|
272
|
+
sectionColumns = this._cachedLayout.columns;
|
|
273
|
+
}
|
|
238
274
|
cellCount = this.collectionView.dataSource.numberOfCellsInCollectionViewSection(this.collectionView, sectionIndex);
|
|
239
275
|
rowCount = Math.ceil(cellCount / columnCount);
|
|
240
276
|
size.height = this._sectionInsets.height + sectionHeaderAndSpacingHeight + sectionFooterAndSpacingHeight;
|
|
241
|
-
size.height += rowCount *
|
|
277
|
+
size.height += rowCount * sectionCellSize.height + (rowCount - 1) * this._rowSpacing;
|
|
242
278
|
this._cachedLayout.sections.push({
|
|
243
279
|
rowOffset: rowOffset,
|
|
244
280
|
cellCount: cellCount,
|
|
245
281
|
rowCount: rowCount,
|
|
246
282
|
frame: JSRect(origin, size),
|
|
283
|
+
columns: sectionColumns,
|
|
284
|
+
cellSize: sectionCellSize,
|
|
247
285
|
headerFrame: JSRect(
|
|
248
286
|
origin.x + this._sectionInsets.left,
|
|
249
287
|
origin.y + this._sectionInsets.top,
|
|
250
288
|
availableWidth,
|
|
251
|
-
|
|
289
|
+
sectionHeaderHeight
|
|
252
290
|
),
|
|
253
291
|
footerFrame: JSRect(
|
|
254
292
|
origin.x + this._sectionInsets.left,
|
|
255
|
-
origin.y + size.height - this._sectionInsets.bottom -
|
|
293
|
+
origin.y + size.height - this._sectionInsets.bottom - sectionFooterHeight,
|
|
256
294
|
availableWidth,
|
|
257
|
-
|
|
295
|
+
sectionFooterHeight
|
|
258
296
|
),
|
|
259
297
|
cellsFrame: JSRect(
|
|
260
298
|
origin.x + this._sectionInsets.left,
|
|
@@ -295,7 +333,7 @@ JSClass("UICollectionViewGridLayout", UICollectionViewLayout, {
|
|
|
295
333
|
if (this._cachedLayout.headerFrame.size.height > 0 && (this._headersStickToTop || rect.intersectsRect(this._cachedLayout.headerFrame))){
|
|
296
334
|
attributes.push(this.layoutAttributesForSupplimentaryViewAtIndexPath(JSIndexPath([]), UICollectionViewGridLayout.SupplimentaryKind.header));
|
|
297
335
|
}
|
|
298
|
-
var columnCount
|
|
336
|
+
var columnCount;
|
|
299
337
|
var columnIndex;
|
|
300
338
|
var sectionIndex;
|
|
301
339
|
var sectionCount = this._cachedLayout.sections.length;
|
|
@@ -304,12 +342,14 @@ JSClass("UICollectionViewGridLayout", UICollectionViewLayout, {
|
|
|
304
342
|
var y;
|
|
305
343
|
var y0 = rect.origin.y;
|
|
306
344
|
var y1 = rect.origin.y + rect.size.height;
|
|
307
|
-
var rowHeight
|
|
345
|
+
var rowHeight;
|
|
308
346
|
var rowIndex;
|
|
309
347
|
var attrs;
|
|
310
348
|
// FIXME: can do a more efficient search of sections
|
|
311
349
|
for (sectionIndex = 0; sectionIndex < sectionCount; ++sectionIndex){
|
|
312
350
|
sectionLayout = this._cachedLayout.sections[sectionIndex];
|
|
351
|
+
columnCount = sectionLayout.columns.length;
|
|
352
|
+
rowHeight = sectionLayout.cellSize.height + this._rowSpacing;
|
|
313
353
|
if (sectionLayout.frame.size.height > 0 && rect.intersectsRect(sectionLayout.frame)){
|
|
314
354
|
if (this._showsSectionBackgroundViews){
|
|
315
355
|
attributes.push(this.layoutAttributesForSupplimentaryViewAtIndexPath(JSIndexPath([sectionIndex]), UICollectionViewGridLayout.SupplimentaryKind.background));
|
|
@@ -326,10 +366,10 @@ JSClass("UICollectionViewGridLayout", UICollectionViewLayout, {
|
|
|
326
366
|
for (; rowIndex < sectionLayout.rowCount && y < y1; ++rowIndex, y += rowHeight){
|
|
327
367
|
for (columnIndex = 0; columnIndex < columnCount && indexPath.row < sectionLayout.cellCount; ++columnIndex, ++indexPath.row){
|
|
328
368
|
attrs = UICollectionViewLayoutAttributes.initCellAtIndexPath(indexPath, JSRect(
|
|
329
|
-
|
|
369
|
+
sectionLayout.columns[columnIndex].x,
|
|
330
370
|
y,
|
|
331
|
-
|
|
332
|
-
|
|
371
|
+
sectionLayout.cellSize.width,
|
|
372
|
+
sectionLayout.cellSize.height
|
|
333
373
|
));
|
|
334
374
|
attrs.rowIndex = sectionLayout.rowOffset + rowIndex;
|
|
335
375
|
attrs.columnIndex = columnIndex;
|
|
@@ -350,16 +390,16 @@ JSClass("UICollectionViewGridLayout", UICollectionViewLayout, {
|
|
|
350
390
|
|
|
351
391
|
layoutAttributesForCellAtIndexPath: function(indexPath){
|
|
352
392
|
var sectionLayout = this._cachedLayout.sections[indexPath.section];
|
|
353
|
-
var columnCount =
|
|
393
|
+
var columnCount = sectionLayout.columns.length;
|
|
354
394
|
var rowIndex = Math.floor(indexPath.row / columnCount);
|
|
355
395
|
var columnIndex = indexPath.row % columnCount;
|
|
356
396
|
var origin = JSPoint(
|
|
357
|
-
|
|
358
|
-
sectionLayout.cellsFrame.origin.y + rowIndex * (
|
|
397
|
+
sectionLayout.columns[columnIndex].x,
|
|
398
|
+
sectionLayout.cellsFrame.origin.y + rowIndex * (sectionLayout.cellSize.height + this._rowSpacing)
|
|
359
399
|
);
|
|
360
400
|
var frame = JSRect(
|
|
361
401
|
origin,
|
|
362
|
-
|
|
402
|
+
sectionLayout.cellSize
|
|
363
403
|
);
|
|
364
404
|
var attributes = UICollectionViewLayoutAttributes.initCellAtIndexPath(indexPath, frame);
|
|
365
405
|
attributes.rowIndex = sectionLayout.rowOffset + rowIndex;
|