@breakside/jskit 2023.40.0 → 2023.48.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.
Files changed (59) hide show
  1. package/Frameworks/DOM.jsframework/Info.json +2 -2
  2. package/Frameworks/DOM.jsframework/io.breakside.JSKit.DOM-bundle.js +2 -2
  3. package/Frameworks/FontKit.jsframework/Info.json +2 -2
  4. package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
  5. package/Frameworks/Foundation.jsframework/Info.json +2 -2
  6. package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
  7. package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
  8. package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
  9. package/Info.json +2 -2
  10. package/Node/io.breakside.jskit-bundle.js +2 -2
  11. package/Root/Frameworks/APIKit/Info.yaml +1 -1
  12. package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
  13. package/Root/Frameworks/AuthKit/Info.yaml +1 -1
  14. package/Root/Frameworks/CSSOM/Info.yaml +1 -1
  15. package/Root/Frameworks/ChartKit/Info.yaml +1 -1
  16. package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
  17. package/Root/Frameworks/DBKit/Info.yaml +1 -1
  18. package/Root/Frameworks/DOM/Info.yaml +1 -1
  19. package/Root/Frameworks/Dispatch/Info.yaml +1 -1
  20. package/Root/Frameworks/FontKit/Info.yaml +1 -1
  21. package/Root/Frameworks/Foundation/Info.yaml +1 -1
  22. package/Root/Frameworks/ImageKit/Info.yaml +1 -1
  23. package/Root/Frameworks/MediaKit/Info.yaml +1 -1
  24. package/Root/Frameworks/MediaKit/MediaKit.js +16 -1
  25. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTime.js +216 -0
  26. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeAtom.js +157 -0
  27. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeFileType.js +45 -0
  28. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMedia.js +127 -0
  29. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMediaHandler.js +68 -0
  30. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMediaHeader.js +50 -0
  31. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMediaInformation.js +67 -0
  32. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMeta.js +19 -0
  33. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMovie.js +78 -0
  34. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeMovieHeader.js +62 -0
  35. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeSampleDescription.js +72 -0
  36. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeSampleTable.js +84 -0
  37. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeTimeToSample.js +57 -0
  38. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeTrack.js +133 -0
  39. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeTrackHeader.js +82 -0
  40. package/Root/Frameworks/MediaKit/QuickTime/MKQuickTimeUserData.js +19 -0
  41. package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
  42. package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
  43. package/Root/Frameworks/PDFKit/Info.yaml +1 -1
  44. package/Root/Frameworks/QRKit/Info.yaml +1 -1
  45. package/Root/Frameworks/SearchKit/Info.yaml +1 -1
  46. package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
  47. package/Root/Frameworks/ServerKit/Info.yaml +1 -1
  48. package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
  49. package/Root/Frameworks/TestKit/Info.yaml +1 -1
  50. package/Root/Frameworks/UIKit/Info.yaml +1 -1
  51. package/Root/Frameworks/UIKit/UIButton.js +29 -10
  52. package/Root/Frameworks/UIKit/UIColorPanel.js +1 -4
  53. package/Root/Frameworks/UIKit/UIDisplayServer.js +3 -0
  54. package/Root/Frameworks/UIKit/UIMenuView.js +6 -0
  55. package/Root/Frameworks/UIKit/UIPopupButton.js +1 -1
  56. package/Root/Frameworks/UIKit/UIStackView.js +43 -0
  57. package/Root/Frameworks/UIKit/UITextField.js +1 -0
  58. package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
  59. package/package.json +1 -1
@@ -0,0 +1,72 @@
1
+ // #import "MKQuickTimeAtom.js"
2
+ "use strict";
3
+
4
+ (function(){
5
+
6
+ var logger = JSLog("medikit", "quicktime");
7
+
8
+ JSClass("MKQuickTimeSampleDescription", MKQuickTimeAtom, {
9
+
10
+ type: MKQuickTimeAtom.Type.stsd,
11
+ version: JSReadOnlyProperty(),
12
+ flags: JSReadOnlyProperty(),
13
+ numberOfEntries: JSReadOnlyProperty(),
14
+
15
+ getVersion: function(){
16
+ return this.data[8];
17
+ },
18
+
19
+ getFlags: function(){
20
+ return this.dataView.getUint32(8) & 0x00FFFFFF;
21
+ },
22
+
23
+ initWithData: function(data){
24
+ MKQuickTimeSampleDescription.$super.initWithData.call(this, data);
25
+ if (data.length < 16){
26
+ throw new Error("expecting at least 16 bytes for stts atom");
27
+ }
28
+ },
29
+
30
+ getNumberOfEntries: function(){
31
+ return this.dataView.getUint32(12);
32
+ },
33
+
34
+ formats: JSReadOnlyProperty(),
35
+
36
+ getFormats: function(){
37
+ var formats = [];
38
+ var i = 16;
39
+ var l = this.data.length;
40
+ var n = this.numberOfEntries;
41
+ var index = 0;
42
+ var size;
43
+ while (index < n && i < l - 16){
44
+ size = this.dataView.getUint32(i);
45
+ formats.push(this.dataView.getUint32(i + 4));
46
+ i += size;
47
+ }
48
+ return formats;
49
+ },
50
+
51
+ audioSampleRates: JSReadOnlyProperty(),
52
+
53
+ getAudioSampleRates: function(){
54
+ var rates = [];
55
+ var i = 16;
56
+ var l = this.data.length;
57
+ var n = this.numberOfEntries;
58
+ var index = 0;
59
+ var size;
60
+ while (index < n && i < l - 16){
61
+ size = this.dataView.getUint32(i);
62
+ if (size >= 36){
63
+ rates.push(this.dataView.getUint16(i + 32) + this.dataView.getUint16(i + 34) / 0xFFFF);
64
+ }
65
+ i += size;
66
+ }
67
+ return rates;
68
+ }
69
+
70
+ });
71
+
72
+ })();
@@ -0,0 +1,84 @@
1
+ // #import "MKQuickTimeAtom.js"
2
+ // #import "MKQuickTimeTimeToSample.js"
3
+ // #import "MKQuickTimeSampleDescription.js"
4
+ "use strict";
5
+
6
+ (function(){
7
+
8
+ var logger = JSLog("medikit", "quicktime");
9
+
10
+
11
+ JSClass("MKQuickTimeSampleTable", MKQuickTimeAtom, {
12
+
13
+ type: MKQuickTimeAtom.Type.stbl,
14
+
15
+ initWithData: function(data){
16
+ MKQuickTimeSampleTable.$super.initWithData.call(this, data);
17
+ this.registerAtomClass(MKQuickTimeTimeToSample);
18
+ this.registerAtomClass(MKQuickTimeSampleDescription);
19
+ this.readAtoms(8);
20
+ },
21
+
22
+ timeToSample: JSReadOnlyProperty(),
23
+
24
+ getTimeToSample: function(){
25
+ return this.atomOfType(MKQuickTimeAtom.Type.stts);
26
+ },
27
+
28
+ sampleDescription: JSReadOnlyProperty(),
29
+
30
+ getSampleDescription: function(){
31
+ return this.atomOfType(MKQuickTimeAtom.Type.stsd);
32
+ },
33
+
34
+ sampleDurations: JSReadOnlyProperty(),
35
+
36
+ getSampleDurations: function(){
37
+ var timeToSample = this.timeToSample;
38
+ var durations = [];
39
+ if (timeToSample !== null){
40
+ var i, l;
41
+ for (i = 0, l = timeToSample.numberOfEntries; i < l; ++i){
42
+ durations.push(timeToSample.durationAtIndex(i));
43
+ }
44
+ }
45
+ return durations;
46
+ },
47
+
48
+ sampleCounts: JSReadOnlyProperty(),
49
+
50
+ getSampleCounts: function(){
51
+ var timeToSample = this.timeToSample;
52
+ var counts = [];
53
+ if (timeToSample !== null){
54
+ var i, l;
55
+ for (i = 0, l = timeToSample.numberOfEntries; i < l; ++i){
56
+ counts.push(timeToSample.countAtIndex(i));
57
+ }
58
+ }
59
+ return counts;
60
+ },
61
+
62
+ audioSampleRates: JSReadOnlyProperty(),
63
+
64
+ getAudioSampleRates: function(){
65
+ var description = this.sampleDescription;
66
+ if (description === null){
67
+ return [];
68
+ }
69
+ return description.audioSampleRates;
70
+ },
71
+
72
+ sampleFormats: JSReadOnlyProperty(),
73
+
74
+ getSampleFormats: function(){
75
+ var description = this.sampleDescription;
76
+ if (description === null){
77
+ return [];
78
+ }
79
+ return description.formats;
80
+ }
81
+
82
+ });
83
+
84
+ })();
@@ -0,0 +1,57 @@
1
+ // #import "MKQuickTimeAtom.js"
2
+ "use strict";
3
+
4
+ (function(){
5
+
6
+ var logger = JSLog("medikit", "quicktime");
7
+
8
+ JSClass("MKQuickTimeTimeToSample", MKQuickTimeAtom, {
9
+
10
+ type: MKQuickTimeAtom.Type.stts,
11
+ version: JSReadOnlyProperty(),
12
+ flags: JSReadOnlyProperty(),
13
+ numberOfEntries: JSReadOnlyProperty(),
14
+
15
+ getVersion: function(){
16
+ return this.data[8];
17
+ },
18
+
19
+ getFlags: function(){
20
+ return this.dataView.getUint32(8) & 0x00FFFFFF;
21
+ },
22
+
23
+ initWithData: function(data){
24
+ MKQuickTimeTimeToSample.$super.initWithData.call(this, data);
25
+ if (data.length < 16){
26
+ throw new Error("expecting at least 16 bytes for stts atom");
27
+ }
28
+ var n = this.numberOfEntries;
29
+ var l = 16 + 8 * n;
30
+ if (data.length < l){
31
+ throw new Error("expecting at least %d bytes for stts atom with %d entries".sprintf(l, n));
32
+ }
33
+ },
34
+
35
+ getNumberOfEntries: function(){
36
+ return this.dataView.getUint32(12);
37
+ },
38
+
39
+ countAtIndex: function(index){
40
+ var i = 16 + index * 8;
41
+ if (i >= 16 && i < this.data.length){
42
+ return this.dataView.getUint32(i);
43
+ }
44
+ return null;
45
+ },
46
+
47
+ durationAtIndex: function(index){
48
+ var i = 16 + index * 8;
49
+ if (i >= 16 && i < this.data.length){
50
+ return this.dataView.getUint32(i + 4);
51
+ }
52
+ return null;
53
+ }
54
+
55
+ });
56
+
57
+ })();
@@ -0,0 +1,133 @@
1
+ // #import "MKQuickTimeAtom.js"
2
+ // #import "MKQuickTimeTrackHeader.js"
3
+ // #import "MKQuickTimeMedia.js"
4
+ "use strict";
5
+
6
+ (function(){
7
+
8
+ var logger = JSLog("medikit", "quicktime");
9
+
10
+ JSClass("MKQuickTimeTrack", MKQuickTimeAtom, {
11
+
12
+ type: MKQuickTimeAtom.Type.trak,
13
+
14
+ initWithData: function(data){
15
+ MKQuickTimeTrack.$super.initWithData.call(this, data);
16
+ this.registerAtomClass(MKQuickTimeTrackHeader);
17
+ this.registerAtomClass(MKQuickTimeMedia);
18
+ this.readAtoms(8);
19
+ },
20
+
21
+ trackHeader: JSReadOnlyProperty(),
22
+
23
+ getTrackHeader: function(){
24
+ return this.atomOfType(MKQuickTimeAtom.Type.tkhd);
25
+ },
26
+
27
+ media: JSReadOnlyProperty(),
28
+
29
+ getMedia: function(){
30
+ return this.atomOfType(MKQuickTimeAtom.Type.mdia);
31
+ },
32
+
33
+ isVideo: JSReadOnlyProperty(),
34
+
35
+ getIsVideo: function(){
36
+ var media = this.media;
37
+ if (media === null){
38
+ return false;
39
+ }
40
+ var handler = media.mediaHandler;
41
+ if (handler === null){
42
+ return false;
43
+ }
44
+ return (handler.componentType === MKQuickTimeMediaHandler.ComponentType.unspecified || handler.componentType === MKQuickTimeMediaHandler.ComponentType.mhlr) && handler.componentSubtype === MKQuickTimeMediaHandler.ComponentSubtype.vide;
45
+ },
46
+
47
+ isAudio: JSReadOnlyProperty(),
48
+
49
+ getIsAudio: function(){
50
+ var media = this.media;
51
+ if (media === null){
52
+ return false;
53
+ }
54
+ var handler = media.mediaHandler;
55
+ if (handler === null){
56
+ return false;
57
+ }
58
+ return (handler.componentType === MKQuickTimeMediaHandler.ComponentType.unspecified || handler.componentType === MKQuickTimeMediaHandler.ComponentType.mhlr) && handler.componentSubtype === MKQuickTimeMediaHandler.ComponentSubtype.soun;
59
+ },
60
+
61
+ inMovie: JSReadOnlyProperty(),
62
+
63
+ getInMovie: function(){
64
+ var header = this.trackHeader;
65
+ if (header === null){
66
+ return false;
67
+ }
68
+ return header.inMovie;
69
+ },
70
+
71
+ enabled: JSReadOnlyProperty(),
72
+
73
+ getEnabled: function(){
74
+ var header = this.trackHeader;
75
+ if (header === null){
76
+ return false;
77
+ }
78
+ return header.enabled;
79
+ },
80
+
81
+ videoResolution: JSReadOnlyProperty(),
82
+
83
+ getVideoResolution: function(){
84
+ var header = this.trackHeader;
85
+ if (header === null){
86
+ return null;
87
+ }
88
+ return header.videoResolution;
89
+ },
90
+
91
+ videoFrameRates: JSReadOnlyProperty(),
92
+
93
+ getVideoFrameRates: function(){
94
+ var media = this.media;
95
+ if (media === null){
96
+ return [];
97
+ }
98
+ return media.videoFrameRates;
99
+ },
100
+
101
+ averageVideoFrameRate: JSReadOnlyProperty(),
102
+
103
+ getAverageVideoFrameRate: function(){
104
+ var media = this.media;
105
+ if (media === null){
106
+ return [];
107
+ }
108
+ return media.averageVideoFrameRate;
109
+ },
110
+
111
+ audioSampleRates: JSReadOnlyProperty(),
112
+
113
+ getAudioSampleRates: function(){
114
+ var media = this.media;
115
+ if (media === null){
116
+ return [];
117
+ }
118
+ return media.audioSampleRates;
119
+ },
120
+
121
+ sampleFormats: JSReadOnlyProperty(),
122
+
123
+ getSampleFormats: function(){
124
+ var media = this.media;
125
+ if (media === null){
126
+ return [];
127
+ }
128
+ return media.sampleFormats;
129
+ }
130
+
131
+ });
132
+
133
+ })();
@@ -0,0 +1,82 @@
1
+ // #import "MKQuickTimeAtom.js"
2
+ "use strict";
3
+
4
+ (function(){
5
+
6
+ var logger = JSLog("medikit", "quicktime");
7
+
8
+ JSClass("MKQuickTimeTrackHeader", MKQuickTimeAtom, {
9
+
10
+ type: MKQuickTimeAtom.Type.tkhd,
11
+ version: JSReadOnlyProperty(),
12
+ flags: JSReadOnlyProperty(),
13
+ trackID: JSReadOnlyProperty(),
14
+ duration: JSReadOnlyProperty(),
15
+ width: JSReadOnlyProperty(),
16
+ height: JSReadOnlyProperty(),
17
+
18
+ getVersion: function(){
19
+ return this.data[8];
20
+ },
21
+
22
+ getFlags: function(){
23
+ return this.dataView.getUint32(8) & 0x00FFFFFF;
24
+ },
25
+
26
+ enabled: JSReadOnlyProperty(),
27
+
28
+ getEnabled: function(){
29
+ return (this.flags & 0x0001) === 0x0001;
30
+ },
31
+
32
+ inMovie: JSReadOnlyProperty(),
33
+
34
+ getInMovie: function(){
35
+ return (this.flags & 0x0001) === 0x0001;
36
+ },
37
+
38
+ getTrackID: function(){
39
+ return this.dataView.getUint32(20);
40
+ },
41
+
42
+ getDuration: function(){
43
+ return this.dataView.getUint32(28);
44
+ },
45
+
46
+ getWidth: function(){
47
+ return this.dataView.getUint16(84) + this.dataView.getUint16(86) / 0xFFFF;
48
+ },
49
+
50
+ getHeight: function(){
51
+ return this.dataView.getUint16(88) + this.dataView.getUint16(90) / 0xFFFF;
52
+ },
53
+
54
+ videoResolution: JSReadOnlyProperty(),
55
+
56
+ getVideoResolution: function(){
57
+ return JSSize(this.width, this.height);
58
+ },
59
+
60
+ initWithData: function(data){
61
+ if (data.length < 92){
62
+ throw new Error("expecting at least 92 bytes for tkhd atom");
63
+ }
64
+ MKQuickTimeTrackHeader.$super.initWithData.call(this, data);
65
+ },
66
+
67
+ dictionaryRepresentation: function(){
68
+ return {
69
+ type: MKQuickTimeAtom.stringForType(this.type),
70
+ version: this.version,
71
+ enabled: this.enabled,
72
+ inMovie: this.inMovie,
73
+ trackID: this.trackID,
74
+ duration: this.duration,
75
+ width: this.width,
76
+ height: this.height
77
+ };
78
+ },
79
+
80
+ });
81
+
82
+ })();
@@ -0,0 +1,19 @@
1
+ // #import "MKQuickTimeAtom.js"
2
+ "use strict";
3
+
4
+ (function(){
5
+
6
+ var logger = JSLog("medikit", "quicktime");
7
+
8
+ JSClass("MKQuickTimeUserData", MKQuickTimeAtom, {
9
+
10
+ type: MKQuickTimeAtom.Type.udta,
11
+
12
+ initWithData: function(data){
13
+ MKQuickTimeUserData.$super.initWithData.call(this, data);
14
+ this.readAtoms(8);
15
+ },
16
+
17
+ });
18
+
19
+ })();
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.MediaKitUI
3
- JSBundleVersion: 2023.40.0
3
+ JSBundleVersion: 2023.48.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.NotificationKit
3
- JSBundleVersion: 2023.40.0
3
+ JSBundleVersion: 2023.48.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2021 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.PDFKit
3
- JSBundleVersion: 2023.40.0
3
+ JSBundleVersion: 2023.48.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.QRKit
3
- JSBundleVersion: 2023.40.0
3
+ JSBundleVersion: 2023.48.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.SearchKit
3
- JSBundleVersion: 2023.40.0
3
+ JSBundleVersion: 2023.48.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.SecurityKit
3
- JSBundleVersion: 2023.40.0
3
+ JSBundleVersion: 2023.48.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ServerKit
3
- JSBundleVersion: 2023.40.0
3
+ JSBundleVersion: 2023.48.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ServerKitTesting
3
- JSBundleVersion: 2023.40.0
3
+ JSBundleVersion: 2023.48.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.TestKit
3
- JSBundleVersion: 2023.40.0
3
+ JSBundleVersion: 2023.48.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.UIKit
3
- JSBundleVersion: 2023.40.0
3
+ JSBundleVersion: 2023.48.0
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -350,10 +350,16 @@ UIButton.Styler = Object.create({}, {
350
350
  }
351
351
  });
352
352
 
353
+ UIButton.ImagePlacement = {
354
+ leading: 0,
355
+ trailing: 1,
356
+ };
357
+
353
358
  JSClass("UIButtonStyler", UIControlStyler, {
354
359
 
355
360
  titleInsets: null,
356
361
  titleImageSpacing: 4,
362
+ imagePlacement: UIButton.ImagePlacement.leading,
357
363
  font: null,
358
364
 
359
365
  init: function(){
@@ -369,6 +375,9 @@ JSClass("UIButtonStyler", UIControlStyler, {
369
375
  if (spec.containsKey('titleImageSpacing')){
370
376
  this.titleImageSpacing = spec.valueForKey("titleImageSpacing", Number);
371
377
  }
378
+ if (spec.containsKey('imagePlacement')){
379
+ this.imagePlacement = spec.valueForKey("imagePlacement", UIButton.ImagePlacement);
380
+ }
372
381
  if (spec.containsKey('font')){
373
382
  this.font = spec.valueForKey("font", JSFont);
374
383
  }else{
@@ -441,19 +450,29 @@ JSClass("UIButtonStyler", UIControlStyler, {
441
450
  var contentRect = button.bounds.rectWithInsets(button._titleInsets);
442
451
  if (button._titleLabel !== null){
443
452
  var titleSize = button._titleLabel.intrinsicSize;
444
- var x, y;
453
+ var titleFrame = JSRect(
454
+ contentRect.origin.x,
455
+ contentRect.origin.y + (contentRect.size.height - titleSize.height) / 2,
456
+ contentRect.size.width,
457
+ titleSize.height
458
+ );
445
459
  if (image !== null){
446
460
  var imageScale = contentRect.size.height / image.size.height;
447
- var imageSize = JSSize(image.size.width * imageScale, contentRect.size.height);
448
- button._imageView.frame = JSRect(contentRect.origin, imageSize);
449
- x = contentRect.origin.x + imageSize.width + this.titleImageSpacing;
450
- y = (contentRect.size.height - titleSize.height) / 2;
451
- }else{
452
- x = contentRect.origin.x;
453
- y = (contentRect.size.height - titleSize.height) / 2;
461
+ var imageFrame = JSRect(
462
+ contentRect.origin.x,
463
+ contentRect.origin.y,
464
+ image.size.width * imageScale,
465
+ contentRect.size.height
466
+ );
467
+ titleFrame.size.width = Math.max(0, titleFrame.size.width - imageFrame.size.width - this.titleImageSpacing);
468
+ if (this.imagePlacement === UIButton.ImagePlacement.leading){
469
+ titleFrame.origin.x += imageFrame.size.width + this.titleImageSpacing;
470
+ }else{
471
+ imageFrame.origin.x = Math.max(0, contentRect.origin.x + contentRect.size.width - imageFrame.size.width);
472
+ }
473
+ button._imageView.frame = imageFrame;
454
474
  }
455
- var w = Math.max(0, contentRect.origin.x + contentRect.size.width - x);
456
- button._titleLabel.frame = JSRect(x, contentRect.origin.y + y, w, titleSize.height);
475
+ button._titleLabel.frame = titleFrame;
457
476
  }else if (image !== null){
458
477
  button._imageView.frame = contentRect;
459
478
  }
@@ -29,6 +29,7 @@ JSProtocol("UIColorPanelDelegate", JSProtocol, {
29
29
  JSClass("UIColorPanel", UIPopupWindow, {
30
30
 
31
31
  escapeClosesWindow: true,
32
+ modalIndicationClosesWindow: true,
32
33
 
33
34
  init: function(){
34
35
  UIColorPanel.$super.init.call(this);
@@ -75,10 +76,6 @@ JSClass("UIColorPanel", UIPopupWindow, {
75
76
  this.contentViewController.componentModel = componentModel;
76
77
  },
77
78
 
78
- indicateModalStatus: function(){
79
- this.close();
80
- }
81
-
82
79
  });
83
80
 
84
81
  UIColorPanel.Model = {
@@ -294,6 +294,9 @@ JSClass("UIDisplayServer", JSObject, {
294
294
  animation = layer.animationsByKey[key];
295
295
  animation.updateForTime(t);
296
296
  if (this.reducedMotionEnabled || animation.isComplete){
297
+ if (this.reducedMotionEnabled){
298
+ animation.percentComplete = 1;
299
+ }
297
300
  completedAnimationKeys.push(key);
298
301
  }else{
299
302
  parts = key.split('.');
@@ -877,6 +877,7 @@ JSClass("UIMenuItemView", UIView, {
877
877
 
878
878
  _createImageView: function(){
879
879
  this._imageView = UIImageView.init();
880
+ this._imageView.scaleMode = UIImageView.ScaleMode.aspectFit;
880
881
  this.insertSubviewBelowSibling(this._imageView, this.titleLabel);
881
882
  return this._imageView;
882
883
  },
@@ -952,6 +953,11 @@ JSClass("UIMenuItemView", UIView, {
952
953
  this.titleLabel.textColor = textColor;
953
954
  if (this._imageView !== null){
954
955
  this._imageView.templateColor = textColor;
956
+ if (!item.enabled && this._imageView.image !== null && this._imageView.image.renderMode === JSImage.RenderMode.original){
957
+ this._imageView.alpha = 0.4;
958
+ }else{
959
+ this._imageView.alpha = 1;
960
+ }
955
961
  }
956
962
  if (this._submenuImageView !== null){
957
963
  this.submenuImageView.templateColor = textColor;
@@ -74,6 +74,7 @@ JSClass("UIPopupButton", UIControl, {
74
74
  UIPopupButton.$super.commonUIControlInit.call(this);
75
75
  this._imageView = UIImageView.init();
76
76
  this._imageView.hidden = true;
77
+ this._imageView.scaleMode = UIImageView.ScaleMode.aspectFit;
77
78
  this._titleLabel = UILabel.init();
78
79
  this._titleLabel.backgroundColor = JSColor.clear;
79
80
  this._titleLabel.font = JSFont.systemFontOfSize(JSFont.Size.normal).fontWithWeight(JSFont.Weight.regular);
@@ -854,7 +855,6 @@ JSClass("UIPopupButtonImageStyler", UIPopupButtonStyler, {
854
855
 
855
856
  initializeControl: function(button){
856
857
  button._imageView.automaticRenderMode = JSImage.RenderMode.template;
857
- button._imageView.scaleMode = UIImageView.ScaleMode.center;
858
858
  button._titleLabel.hidden = true;
859
859
  button._indicatorView.hidden = true;
860
860
  button._titleLabel.frame = JSRect.Zero;