@breakside/jskit 2021.52.0 → 2022.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/JS/JSColor.js +9 -0
- package/Frameworks/Foundation.jsframework/JS/JSColorSpace.js +106 -20
- package/Frameworks/Foundation.jsframework/JS/JSMediaType.js +1 -1
- package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
- package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
- package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
- package/Info.json +2 -2
- package/Node/io.breakside.jskit-bundle.js +2 -2
- package/Root/Frameworks/APIKit/APIRequest.js +99 -0
- package/Root/Frameworks/APIKit/Info.yaml +1 -1
- package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
- package/Root/Frameworks/AuthKit/Info.yaml +1 -1
- package/Root/Frameworks/CSSOM/Info.yaml +1 -1
- package/Root/Frameworks/ChartKit/Info.yaml +1 -1
- package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
- package/Root/Frameworks/DBKit/DBMongoStore.js +1 -0
- package/Root/Frameworks/DBKit/DBRedisStore.js +136 -117
- package/Root/Frameworks/DBKit/Info.yaml +1 -1
- package/Root/Frameworks/DOM/Info.yaml +1 -1
- package/Root/Frameworks/Dispatch/Info.yaml +1 -1
- package/Root/Frameworks/FontKit/Info.yaml +1 -1
- package/Root/Frameworks/Foundation/Info.yaml +1 -1
- package/Root/Frameworks/Foundation/JSColor.js +9 -0
- package/Root/Frameworks/Foundation/JSColorSpace.js +106 -20
- package/Root/Frameworks/Foundation/JSMediaType.js +1 -1
- package/Root/Frameworks/ImageKit/IKColorProfile.js +1091 -0
- package/Root/Frameworks/ImageKit/IKColorSpace.js +49 -198
- package/Root/Frameworks/ImageKit/IKMatrix.js +124 -0
- package/Root/Frameworks/ImageKit/ImageKit.js +2 -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/ServerKit/SKHTTPRequest.js +44 -0
- package/Root/Frameworks/ServerKit/SKJobQueue.js +1 -1
- package/Root/Frameworks/ServerKit/SKRedisJobQueue.js +7 -3
- package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
- package/Root/Frameworks/TestKit/Info.yaml +1 -1
- package/Root/Frameworks/TestKit/TKMock.js +1 -1
- package/Root/Frameworks/UIKit/Info.yaml +1 -1
- package/Root/Frameworks/UIKit/UIBrowserViewController.js +2 -6
- package/Root/Frameworks/UIKit/UICollectionReusableView.js +91 -0
- package/Root/Frameworks/UIKit/UICollectionView.js +1254 -0
- package/Root/Frameworks/UIKit/UICollectionViewCell.js +121 -0
- package/Root/Frameworks/UIKit/UICollectionViewGridLayout.js +425 -0
- package/Root/Frameworks/UIKit/UICollectionViewLayout.js +82 -0
- package/Root/Frameworks/UIKit/UIColorWell.js +12 -1
- package/Root/Frameworks/UIKit/UIDisplayServer.js +5 -1
- package/Root/Frameworks/UIKit/UIKit.js +7 -0
- package/Root/Frameworks/UIKit/UILayer.js +3 -0
- package/Root/Frameworks/UIKit/UIListView.js +8 -9
- package/Root/Frameworks/UIKit/UIMenu.js +1 -1
- package/Root/Frameworks/UIKit/UIMenuView.js +5 -1
- package/Root/Frameworks/UIKit/UINavigationBar.js +9 -3
- package/Root/Frameworks/UIKit/UINavigationController.js +228 -112
- package/Root/Frameworks/UIKit/UINavigationItem.js +4 -0
- package/Root/Frameworks/UIKit/UIPopupButton.js +39 -3
- package/Root/Frameworks/UIKit/UIScrollView.js +2 -0
- package/Root/Frameworks/UIKit/UISplitViewController.js +215 -73
- package/Root/Frameworks/UIKit/UITabViewController.js +4 -10
- package/Root/Frameworks/UIKit/UITextField.js +3 -0
- package/Root/Frameworks/UIKit/UIView.js +3 -0
- package/Root/Frameworks/UIKit/UIViewController.js +141 -50
- package/Root/Frameworks/UIKit/UIWindow.js +4 -15
- package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
- package/Root/Frameworks/UIKitTesting/UIMockApplication.js +6 -0
- package/Root/Templates/http/${PROJECT_NAME}/Dockerfile +1 -1
- package/Root/Templates/node/${PROJECT_NAME}/Dockerfile +4 -2
- package/package.json +1 -1
|
@@ -41,7 +41,7 @@ JSClass("DBRedisStore", DBObjectStore, {
|
|
|
41
41
|
|
|
42
42
|
open: function(completion){
|
|
43
43
|
logger.info("Redis client connecting to %{public}:%d...", this.url.host, this.url.port || 6379);
|
|
44
|
-
this.client = this.redis.createClient({url: this.url.encodedString});
|
|
44
|
+
this.client = this.redis.createClient({url: this.url.encodedString, legacyMode: true});
|
|
45
45
|
var store = this;
|
|
46
46
|
var errorHandler = function(error){
|
|
47
47
|
logger.info("Failed to open Redis connection: %{error}", error);
|
|
@@ -67,8 +67,12 @@ JSClass("DBRedisStore", DBObjectStore, {
|
|
|
67
67
|
store.close(fn);
|
|
68
68
|
}
|
|
69
69
|
};
|
|
70
|
-
this.client.
|
|
71
|
-
|
|
70
|
+
if (this.client.connect){
|
|
71
|
+
this.client.connect().then(readyHandler, errorHandler);
|
|
72
|
+
}else{
|
|
73
|
+
this.client.on("error", errorHandler);
|
|
74
|
+
this.client.on("ready", readyHandler);
|
|
75
|
+
}
|
|
72
76
|
},
|
|
73
77
|
|
|
74
78
|
closeCallback: null,
|
|
@@ -233,7 +237,7 @@ JSClass("DBRedisStore", DBObjectStore, {
|
|
|
233
237
|
|
|
234
238
|
watchClientQueue: null,
|
|
235
239
|
|
|
236
|
-
dequeueReusableWatchClient: function(){
|
|
240
|
+
dequeueReusableWatchClient: function(completion, target){
|
|
237
241
|
if (this.watchClientQueue === null){
|
|
238
242
|
this.watchClientQueue = [];
|
|
239
243
|
}
|
|
@@ -245,7 +249,17 @@ JSClass("DBRedisStore", DBObjectStore, {
|
|
|
245
249
|
return this.watchClientQueue.shift();
|
|
246
250
|
}
|
|
247
251
|
logger.info("opening watch client to %{public}:%d", this.url.host, this.url.port || 6379);
|
|
248
|
-
|
|
252
|
+
var client = this.redis.createClient({url: this.url.encodedString, legacyMode: true});
|
|
253
|
+
if (client.connect){
|
|
254
|
+
client.connect().then(function(){
|
|
255
|
+
completion.call(target, client);
|
|
256
|
+
}, function(error){
|
|
257
|
+
logger.error("Error connecting to watch client: %{error}", error);
|
|
258
|
+
completion.call(target, null);
|
|
259
|
+
});
|
|
260
|
+
}else{
|
|
261
|
+
completion.call(target, client);
|
|
262
|
+
}
|
|
249
263
|
},
|
|
250
264
|
|
|
251
265
|
enqueueReusableWatchClient: function(client){
|
|
@@ -277,120 +291,125 @@ JSClass("DBRedisStore", DBObjectStore, {
|
|
|
277
291
|
},
|
|
278
292
|
|
|
279
293
|
exclusiveSave: function(id, change, completion){
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
var waitInterval = JSTimeInterval.milliseconds(20);
|
|
283
|
-
var retires = 0;
|
|
284
|
-
var store = this;
|
|
285
|
-
var trySave = function(){
|
|
286
|
-
try{
|
|
287
|
-
watchClient.watch(id, function(error){
|
|
288
|
-
if (error !== null){
|
|
289
|
-
logger.error("Failure calling redis watch: %{error}", error);
|
|
290
|
-
watchClient.quit();
|
|
291
|
-
completion(false);
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
try{
|
|
295
|
-
watchClient.get(id, function(error, json){
|
|
296
|
-
if (error !== null){
|
|
297
|
-
logger.error("Failure calling redis get: %{error}", error);
|
|
298
|
-
watchClient.quit();
|
|
299
|
-
completion(false);
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
var object = null;
|
|
303
|
-
try{
|
|
304
|
-
object = JSON.parse(json);
|
|
305
|
-
}catch (e){
|
|
306
|
-
logger.error("Failure parsing object json: %{error}", error);
|
|
307
|
-
watchClient.quit();
|
|
308
|
-
completion(false);
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
try{
|
|
312
|
-
watchClient.ttl(id, function(error, ttl){
|
|
313
|
-
if (error !== null){
|
|
314
|
-
logger.error("Failure calling redis ttl: %{error}", error);
|
|
315
|
-
watchClient.quit();
|
|
316
|
-
completion(false);
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
|
-
try{
|
|
320
|
-
change(object, function(changedObject){
|
|
321
|
-
if (changedObject === null){
|
|
322
|
-
watchClient.quit();
|
|
323
|
-
completion(false);
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
|
-
var changedJSON = null;
|
|
327
|
-
try{
|
|
328
|
-
changedJSON = JSON.stringify(changedObject);
|
|
329
|
-
}catch (e){
|
|
330
|
-
logger.error("Failed to serialize object for redis: %{error}", e);
|
|
331
|
-
watchClient.quit();
|
|
332
|
-
completion(false);
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
|
-
var args = [id, changedJSON];
|
|
336
|
-
if (ttl > 0){
|
|
337
|
-
args.push("EX");
|
|
338
|
-
args.push(ttl);
|
|
339
|
-
}
|
|
340
|
-
try{
|
|
341
|
-
watchClient.multi().set(args).exec(function(error, results){
|
|
342
|
-
if (error !== null){
|
|
343
|
-
logger.error("Failure calling redis multi/set/exec: %{error}", error);
|
|
344
|
-
watchClient.quit();
|
|
345
|
-
completion(false);
|
|
346
|
-
return;
|
|
347
|
-
}
|
|
348
|
-
if (results === null){
|
|
349
|
-
// null results means the transaction failed, so it's our signal to retry
|
|
350
|
-
++retires;
|
|
351
|
-
if (retires > maxRetires){
|
|
352
|
-
store.enqueueReusableWatchClient(watchClient);
|
|
353
|
-
completion(true);
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
JSTimer.scheduledTimerWithInterval(waitInterval, trySave);
|
|
357
|
-
waitInterval = Math.min(1, waitInterval * 2);
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
store.enqueueReusableWatchClient(watchClient);
|
|
361
|
-
completion(true);
|
|
362
|
-
});
|
|
363
|
-
}catch (e){
|
|
364
|
-
logger.error("Error thrown calling redis multi/set/exec: %{error}", e);
|
|
365
|
-
watchClient.quit();
|
|
366
|
-
completion(false);
|
|
367
|
-
}
|
|
368
|
-
});
|
|
369
|
-
}catch (e){
|
|
370
|
-
logger.error("Error thrown calling change function: %{error}", e);
|
|
371
|
-
watchClient.quit();
|
|
372
|
-
completion(false);
|
|
373
|
-
}
|
|
374
|
-
});
|
|
375
|
-
}catch (e){
|
|
376
|
-
logger.error("Error thrown calling redis ttl: %{error}", error);
|
|
377
|
-
watchClient.quit();
|
|
378
|
-
completion(false);
|
|
379
|
-
}
|
|
380
|
-
});
|
|
381
|
-
}catch (e){
|
|
382
|
-
logger.error("Error thrown calling redis get: %{error}", error);
|
|
383
|
-
watchClient.quit();
|
|
384
|
-
completion(false);
|
|
385
|
-
}
|
|
386
|
-
});
|
|
387
|
-
}catch (e){
|
|
388
|
-
logger.error("Error thrown calling redis watch: %{error}", e);
|
|
389
|
-
watchClient.quit();
|
|
294
|
+
this.dequeueReusableWatchClient(function(watchClient){
|
|
295
|
+
if (watchClient === null){
|
|
390
296
|
completion(false);
|
|
297
|
+
return;
|
|
391
298
|
}
|
|
392
|
-
|
|
393
|
-
|
|
299
|
+
var maxRetires = 30;
|
|
300
|
+
var waitInterval = JSTimeInterval.milliseconds(20);
|
|
301
|
+
var retires = 0;
|
|
302
|
+
var store = this;
|
|
303
|
+
var trySave = function(){
|
|
304
|
+
try{
|
|
305
|
+
watchClient.watch(id, function(error){
|
|
306
|
+
if (error !== null){
|
|
307
|
+
logger.error("Failure calling redis watch: %{error}", error);
|
|
308
|
+
watchClient.quit();
|
|
309
|
+
completion(false);
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
try{
|
|
313
|
+
watchClient.get(id, function(error, json){
|
|
314
|
+
if (error !== null){
|
|
315
|
+
logger.error("Failure calling redis get: %{error}", error);
|
|
316
|
+
watchClient.quit();
|
|
317
|
+
completion(false);
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
var object = null;
|
|
321
|
+
try{
|
|
322
|
+
object = JSON.parse(json);
|
|
323
|
+
}catch (e){
|
|
324
|
+
logger.error("Failure parsing object json: %{error}", error);
|
|
325
|
+
watchClient.quit();
|
|
326
|
+
completion(false);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
try{
|
|
330
|
+
watchClient.ttl(id, function(error, ttl){
|
|
331
|
+
if (error !== null){
|
|
332
|
+
logger.error("Failure calling redis ttl: %{error}", error);
|
|
333
|
+
watchClient.quit();
|
|
334
|
+
completion(false);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
try{
|
|
338
|
+
change(object, function(changedObject){
|
|
339
|
+
if (changedObject === null){
|
|
340
|
+
watchClient.quit();
|
|
341
|
+
completion(false);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
var changedJSON = null;
|
|
345
|
+
try{
|
|
346
|
+
changedJSON = JSON.stringify(changedObject);
|
|
347
|
+
}catch (e){
|
|
348
|
+
logger.error("Failed to serialize object for redis: %{error}", e);
|
|
349
|
+
watchClient.quit();
|
|
350
|
+
completion(false);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
var args = [id, changedJSON];
|
|
354
|
+
if (ttl > 0){
|
|
355
|
+
args.push("EX");
|
|
356
|
+
args.push(ttl);
|
|
357
|
+
}
|
|
358
|
+
try{
|
|
359
|
+
watchClient.multi().set(args).exec(function(error, results){
|
|
360
|
+
if (error !== null){
|
|
361
|
+
logger.error("Failure calling redis multi/set/exec: %{error}", error);
|
|
362
|
+
watchClient.quit();
|
|
363
|
+
completion(false);
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
if (results === null){
|
|
367
|
+
// null results means the transaction failed, so it's our signal to retry
|
|
368
|
+
++retires;
|
|
369
|
+
if (retires > maxRetires){
|
|
370
|
+
store.enqueueReusableWatchClient(watchClient);
|
|
371
|
+
completion(true);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
JSTimer.scheduledTimerWithInterval(waitInterval, trySave);
|
|
375
|
+
waitInterval = Math.min(1, waitInterval * 2);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
store.enqueueReusableWatchClient(watchClient);
|
|
379
|
+
completion(true);
|
|
380
|
+
});
|
|
381
|
+
}catch (e){
|
|
382
|
+
logger.error("Error thrown calling redis multi/set/exec: %{error}", e);
|
|
383
|
+
watchClient.quit();
|
|
384
|
+
completion(false);
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
}catch (e){
|
|
388
|
+
logger.error("Error thrown calling change function: %{error}", e);
|
|
389
|
+
watchClient.quit();
|
|
390
|
+
completion(false);
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
}catch (e){
|
|
394
|
+
logger.error("Error thrown calling redis ttl: %{error}", error);
|
|
395
|
+
watchClient.quit();
|
|
396
|
+
completion(false);
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
}catch (e){
|
|
400
|
+
logger.error("Error thrown calling redis get: %{error}", error);
|
|
401
|
+
watchClient.quit();
|
|
402
|
+
completion(false);
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
}catch (e){
|
|
406
|
+
logger.error("Error thrown calling redis watch: %{error}", e);
|
|
407
|
+
watchClient.quit();
|
|
408
|
+
completion(false);
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
trySave();
|
|
412
|
+
}, this);
|
|
394
413
|
},
|
|
395
414
|
|
|
396
415
|
saveChange: function(change, completion){
|
|
@@ -300,6 +300,15 @@ JSClass('JSColor', JSObject, {
|
|
|
300
300
|
return JSColor.initWithSpaceAndComponents(JSColorSpace.gray, gray);
|
|
301
301
|
},
|
|
302
302
|
|
|
303
|
+
colorInSpace: function(space){
|
|
304
|
+
if (space === this._space){
|
|
305
|
+
return this;
|
|
306
|
+
}
|
|
307
|
+
var components = space.componentsFromSpace(this._space, this._components);
|
|
308
|
+
components.push(this._components[this._components.length - 1]);
|
|
309
|
+
return JSColor.initWithSpaceAndComponents(space, components);
|
|
310
|
+
},
|
|
311
|
+
|
|
303
312
|
rgbaHexStringRepresentation: function(){
|
|
304
313
|
var color = this.rgbaColor();
|
|
305
314
|
var r = Math.round(color.red * 255);
|
|
@@ -88,14 +88,14 @@ JSClass("JSXYZColorSpace", JSColorSpace, {
|
|
|
88
88
|
|
|
89
89
|
name: "xyz",
|
|
90
90
|
|
|
91
|
-
initWithWhitepoint: function(mediaWhitepoint
|
|
92
|
-
if (mediaWhitepoint ===
|
|
91
|
+
initWithWhitepoint: function(mediaWhitepoint){
|
|
92
|
+
if (mediaWhitepoint === JSColorSpace.Whitepoint.profileConnection){
|
|
93
93
|
return JSColorSpace.xyz;
|
|
94
94
|
}
|
|
95
|
-
if (mediaWhitepoint[0] ===
|
|
95
|
+
if (mediaWhitepoint[0] === JSColorSpace.Whitepoint.profileConnection[0] && mediaWhitepoint[1] === JSColorSpace.Whitepoint.profileConnection[1] && mediaWhitepoint[2] === JSColorSpace.Whitepoint.profileConnection[2]){
|
|
96
96
|
return JSColorSpace.xyz;
|
|
97
97
|
}
|
|
98
|
-
return JSXYZScaledColorSpace.initWithWhitepoint(mediaWhitepoint
|
|
98
|
+
return JSXYZScaledColorSpace.initWithWhitepoint(mediaWhitepoint);
|
|
99
99
|
},
|
|
100
100
|
|
|
101
101
|
initWithScale: function(scale){
|
|
@@ -125,11 +125,11 @@ JSClass("JSXYZScaledColorSpace", JSXYZColorSpace, {
|
|
|
125
125
|
_scale: null,
|
|
126
126
|
_inverseScale: null,
|
|
127
127
|
|
|
128
|
-
initWithWhitepoint: function(mediaWhitepoint
|
|
128
|
+
initWithWhitepoint: function(mediaWhitepoint){
|
|
129
129
|
this.initWithScale([
|
|
130
|
-
mediaWhitepoint[0] /
|
|
131
|
-
mediaWhitepoint[1] /
|
|
132
|
-
mediaWhitepoint[2] /
|
|
130
|
+
mediaWhitepoint[0] / JSColorSpace.Whitepoint.profileConnection[0],
|
|
131
|
+
mediaWhitepoint[1] / JSColorSpace.Whitepoint.profileConnection[1],
|
|
132
|
+
mediaWhitepoint[2] / JSColorSpace.Whitepoint.profileConnection[2]
|
|
133
133
|
]);
|
|
134
134
|
},
|
|
135
135
|
|
|
@@ -164,10 +164,7 @@ JSClass("JSLabColorSpace", JSColorSpace, {
|
|
|
164
164
|
|
|
165
165
|
name: "lab",
|
|
166
166
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
initWithWhitepoint: function(mediaWhitepoint){
|
|
170
|
-
this.mediaWhitepoint = mediaWhitepoint;
|
|
167
|
+
init: function(){
|
|
171
168
|
},
|
|
172
169
|
|
|
173
170
|
xyzFromComponents: function(components){
|
|
@@ -181,9 +178,9 @@ JSClass("JSLabColorSpace", JSColorSpace, {
|
|
|
181
178
|
var fx = components[1] / 500.0 + fy;
|
|
182
179
|
var fz = fy - components[2] / 200.0;
|
|
183
180
|
return [
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
181
|
+
JSColorSpace.Whitepoint.profileConnection[0] * fi(fx),
|
|
182
|
+
JSColorSpace.Whitepoint.profileConnection[1] * fi(fy),
|
|
183
|
+
JSColorSpace.Whitepoint.profileConnection[2] * fi(fz)
|
|
187
184
|
];
|
|
188
185
|
},
|
|
189
186
|
|
|
@@ -194,9 +191,9 @@ JSClass("JSLabColorSpace", JSColorSpace, {
|
|
|
194
191
|
}
|
|
195
192
|
return (841.0 / 108.0) * x + 4.0 / 29.0;
|
|
196
193
|
};
|
|
197
|
-
var fx = f(xyz[0] /
|
|
198
|
-
var fy = f(xyz[1] /
|
|
199
|
-
var fz = f(xyz[2] /
|
|
194
|
+
var fx = f(xyz[0] / JSColorSpace.Whitepoint.profileConnection[0]);
|
|
195
|
+
var fy = f(xyz[1] / JSColorSpace.Whitepoint.profileConnection[1]);
|
|
196
|
+
var fz = f(xyz[2] / JSColorSpace.Whitepoint.profileConnection[2]);
|
|
200
197
|
return [
|
|
201
198
|
116.0 * fy - 16.0,
|
|
202
199
|
500.0 * (fx - fy),
|
|
@@ -239,10 +236,52 @@ JSClass("JSRGBColorSpace", JSColorSpace, {
|
|
|
239
236
|
|
|
240
237
|
// MARK: - Lab conversions
|
|
241
238
|
|
|
239
|
+
xyzMatrix: [
|
|
240
|
+
[0.4360, 0.3851, 0.1431],
|
|
241
|
+
[0.2225, 0.7169, 0.0606],
|
|
242
|
+
[0.0139, 0.09710, 0.7139]
|
|
243
|
+
],
|
|
244
|
+
|
|
245
|
+
xyzInverseMatrix: [
|
|
246
|
+
[3.13458, -1.61731, -0.491034],
|
|
247
|
+
[-0.978957, 1.91622, 0.0335704],
|
|
248
|
+
[0.0721194, -0.229142, 1.40575]
|
|
249
|
+
],
|
|
250
|
+
|
|
251
|
+
g: 2.4,
|
|
252
|
+
a: 1.0 / 1.055,
|
|
253
|
+
b: 0.055 / 1.055,
|
|
254
|
+
c: 1.0 / 12.92,
|
|
255
|
+
d: 0.04045,
|
|
256
|
+
|
|
257
|
+
curve: function(x){
|
|
258
|
+
return parametricCurve3(x, this.g, this.a, this.b, this.c, this.d);
|
|
259
|
+
},
|
|
260
|
+
|
|
261
|
+
inverseCurve: function(y){
|
|
262
|
+
y = Math.max(0, Math.min(1, y));
|
|
263
|
+
return inverseParametricCurve3(y, this.g, this.a, this.b, this.c, this.d);
|
|
264
|
+
},
|
|
265
|
+
|
|
242
266
|
xyzFromComponents: function(components){
|
|
267
|
+
var rgb = [
|
|
268
|
+
this.curve(components[0]),
|
|
269
|
+
this.curve(components[1]),
|
|
270
|
+
this.curve(components[2])
|
|
271
|
+
];
|
|
272
|
+
return [
|
|
273
|
+
this.xyzMatrix[0][0] * rgb[0] + this.xyzMatrix[0][1] * rgb[1] + this.xyzMatrix[0][2] * rgb[2],
|
|
274
|
+
this.xyzMatrix[1][0] * rgb[0] + this.xyzMatrix[1][1] * rgb[1] + this.xyzMatrix[1][2] * rgb[2],
|
|
275
|
+
this.xyzMatrix[2][0] * rgb[0] + this.xyzMatrix[2][1] * rgb[1] + this.xyzMatrix[2][2] * rgb[2]
|
|
276
|
+
];
|
|
243
277
|
},
|
|
244
278
|
|
|
245
279
|
componentsFromXYZ: function(xyz){
|
|
280
|
+
return [
|
|
281
|
+
this.inverseCurve(this.xyzInverseMatrix[0][0] * xyz[0] + this.xyzInverseMatrix[0][1] * xyz[1] + this.xyzInverseMatrix[0][2] * xyz[2]),
|
|
282
|
+
this.inverseCurve(this.xyzInverseMatrix[1][0] * xyz[0] + this.xyzInverseMatrix[1][1] * xyz[1] + this.xyzInverseMatrix[1][2] * xyz[2]),
|
|
283
|
+
this.inverseCurve(this.xyzInverseMatrix[2][0] * xyz[0] + this.xyzInverseMatrix[2][1] * xyz[1] + this.xyzInverseMatrix[2][2] * xyz[2])
|
|
284
|
+
];
|
|
246
285
|
},
|
|
247
286
|
|
|
248
287
|
// MARK: - rgb <-> hsl
|
|
@@ -425,7 +464,38 @@ JSClass("JSGrayColorSpace", JSColorSpace, {
|
|
|
425
464
|
return [
|
|
426
465
|
components[0] + (1.0 - components[0]) * percentage
|
|
427
466
|
];
|
|
428
|
-
}
|
|
467
|
+
},
|
|
468
|
+
|
|
469
|
+
g: 2.4,
|
|
470
|
+
a: 1.0 / 1.055,
|
|
471
|
+
b: 0.055 / 1.055,
|
|
472
|
+
c: 1.0 / 12.92,
|
|
473
|
+
d: 0.04045,
|
|
474
|
+
|
|
475
|
+
curve: function(x){
|
|
476
|
+
return parametricCurve3(x, this.g, this.a, this.b, this.c, this.d);
|
|
477
|
+
},
|
|
478
|
+
|
|
479
|
+
inverseCurve: function(y){
|
|
480
|
+
y = Math.max(0, Math.min(1, y));
|
|
481
|
+
return inverseParametricCurve3(y, this.g, this.a, this.b, this.c, this.d);
|
|
482
|
+
},
|
|
483
|
+
|
|
484
|
+
// MARK: - Lab conversions
|
|
485
|
+
|
|
486
|
+
xyzFromComponents: function(components){
|
|
487
|
+
var w = this.curve(components[0]);
|
|
488
|
+
return [
|
|
489
|
+
JSColorSpace.Whitepoint.profileConnection[0] * w,
|
|
490
|
+
JSColorSpace.Whitepoint.profileConnection[1] * w,
|
|
491
|
+
JSColorSpace.Whitepoint.profileConnection[2] * w
|
|
492
|
+
];
|
|
493
|
+
},
|
|
494
|
+
|
|
495
|
+
componentsFromXYZ: function(xyz){
|
|
496
|
+
var y = Math.min(JSColorSpace.Whitepoint.profileConnection[1], Math.max(0, xyz[1])) / JSColorSpace.Whitepoint.profileConnection[1];
|
|
497
|
+
return [this.inverseCurve(y)];
|
|
498
|
+
},
|
|
429
499
|
|
|
430
500
|
});
|
|
431
501
|
|
|
@@ -622,7 +692,7 @@ Object.defineProperties(JSColorSpace, {
|
|
|
622
692
|
lab: {
|
|
623
693
|
configurable: true,
|
|
624
694
|
get: function(){
|
|
625
|
-
var space = JSLabColorSpace.
|
|
695
|
+
var space = JSLabColorSpace.init();
|
|
626
696
|
Object.defineProperty(this, "lab", {value: space});
|
|
627
697
|
return space;
|
|
628
698
|
}
|
|
@@ -635,4 +705,20 @@ JSColorSpace.Whitepoint = {
|
|
|
635
705
|
D65: [0.9505, 1.0, 1.08883]
|
|
636
706
|
};
|
|
637
707
|
|
|
708
|
+
JSColorSpace.Whitepoint.profileConnection = JSColorSpace.Whitepoint.D50;
|
|
709
|
+
|
|
710
|
+
var parametricCurve3 = function(x, g, a, b, c, d){
|
|
711
|
+
if (x >= d){
|
|
712
|
+
return Math.pow(a * x + b, g);
|
|
713
|
+
}
|
|
714
|
+
return c * x;
|
|
715
|
+
};
|
|
716
|
+
|
|
717
|
+
var inverseParametricCurve3 = function(y, g, a, b, c, d){
|
|
718
|
+
if (y < c * d){
|
|
719
|
+
return y / c;
|
|
720
|
+
}
|
|
721
|
+
return (Math.pow(y, 1.0 / g) - b) / a;
|
|
722
|
+
};
|
|
723
|
+
|
|
638
724
|
})();
|