@@ -458,10 +458,10 @@ index 5de630a1db847a09651b310928bb7bc4d4f66f29..0268bc2bdfb3bfda2ef6e01a5dd24209
458
458
nsCOMPtr<nsIPrincipal> principal =
459
459
diff --git a/juggler/BrowserContextManager.js b/juggler/BrowserContextManager.js
460
460
new file mode 100644
461
- index 0000000000000000000000000000000000000000..670ffa0bf10b3bdc98a732b740c41c217f0bc720
461
+ index 0000000000000000000000000000000000000000..6c3d918022f0e8ff84083cb20266c97902cd04d4
462
462
--- /dev/null
463
463
+++ b/juggler/BrowserContextManager.js
464
- @@ -0,0 +1,199 @@
464
+ @@ -0,0 +1,214 @@
465
465
+ "use strict";
466
466
+
467
467
+ const {ContextualIdentityService} = ChromeUtils.import("resource://gre/modules/ContextualIdentityService.jsm");
@@ -541,6 +541,8 @@ index 0000000000000000000000000000000000000000..670ffa0bf10b3bdc98a732b740c41c21
541
541
+ this.userContextId = identity.userContextId;
542
542
+ }
543
543
+ this._principals = [];
544
+ + // Maps origins to the permission lists.
545
+ + this._permissions = new Map();
544
546
+ this._manager._browserContextIdToBrowserContext.set(this.browserContextId, this);
545
547
+ this._manager._userContextIdToBrowserContext.set(this.userContextId, this);
546
548
+ this.options = options || {};
@@ -562,13 +564,7 @@ index 0000000000000000000000000000000000000000..670ffa0bf10b3bdc98a732b740c41c21
562
564
+ }
563
565
+
564
566
+ grantPermissions(origin, permissions) {
565
- + const attrs = { userContextId: this.userContextId || undefined };
566
- + const principal = Services.scriptSecurityManager.createContentPrincipal(NetUtil.newURI(origin), attrs);
567
- + this._principals.push(principal);
568
- + for (const permission of ALL_PERMISSIONS) {
569
- + const action = permissions.includes(permission) ? Ci.nsIPermissionManager.ALLOW_ACTION : Ci.nsIPermissionManager.DENY_ACTION;
570
- + Services.perms.addFromPrincipal(principal, permission, action, Ci.nsIPermissionManager.EXPIRE_NEVER, 0 /* expireTime */);
571
- + }
567
+ + this._permissions.set(origin, permissions);
572
568
+ }
573
569
+
574
570
+ resetPermissions() {
@@ -577,6 +573,25 @@ index 0000000000000000000000000000000000000000..670ffa0bf10b3bdc98a732b740c41c21
577
573
+ Services.perms.removeFromPrincipal(principal, permission);
578
574
+ }
579
575
+ this._principals = [];
576
+ + this._permissions.clear();
577
+ + }
578
+ +
579
+ + grantPermissionsToOrigin(url) {
580
+ + let origin = Array.from(this._permissions.keys()).find(key => url.startsWith(key));
581
+ + if (!origin)
582
+ + origin = '*';
583
+ +
584
+ + const permissions = this._permissions.get(origin);
585
+ + if (!permissions)
586
+ + return;
587
+ +
588
+ + const attrs = { userContextId: this.userContextId || undefined };
589
+ + const principal = Services.scriptSecurityManager.createContentPrincipal(NetUtil.newURI(url), attrs);
590
+ + this._principals.push(principal);
591
+ + for (const permission of ALL_PERMISSIONS) {
592
+ + const action = permissions.includes(permission) ? Ci.nsIPermissionManager.ALLOW_ACTION : Ci.nsIPermissionManager.DENY_ACTION;
593
+ + Services.perms.addFromPrincipal(principal, permission, action, Ci.nsIPermissionManager.EXPIRE_NEVER, 0 /* expireTime */);
594
+ + }
580
595
+ }
581
596
+
582
597
+ setCookies(cookies) {
@@ -1612,10 +1627,10 @@ index 0000000000000000000000000000000000000000..ba34976ad05e7f5f1a99777f76ac08b1
1612
1627
+ this.SimpleChannel = SimpleChannel;
1613
1628
diff --git a/juggler/TargetRegistry.js b/juggler/TargetRegistry.js
1614
1629
new file mode 100644
1615
- index 0000000000000000000000000000000000000000..98071c0e2c5429cfe8f29c390de3944f7f6e52a9
1630
+ index 0000000000000000000000000000000000000000..eab73deee89cc7c8ab0a304f79126264de5c4f8e
1616
1631
--- /dev/null
1617
1632
+++ b/juggler/TargetRegistry.js
1618
- @@ -0,0 +1,250 @@
1633
+ @@ -0,0 +1,264 @@
1619
1634
+ const {EventEmitter} = ChromeUtils.import('resource://gre/modules/EventEmitter.jsm');
1620
1635
+ const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
1621
1636
+ const {SimpleChannel} = ChromeUtils.import('chrome://juggler/content/SimpleChannel.js');
@@ -1673,11 +1688,10 @@ index 0000000000000000000000000000000000000000..98071c0e2c5429cfe8f29c390de3944f
1673
1688
+ Services.obs.addObserver(this, 'oop-frameloader-crashed');
1674
1689
+ }
1675
1690
+
1676
- + async ensurePermissionsInContextPages (browserContextId, permissions ) {
1691
+ + pageTargets (browserContextId) {
1677
1692
+ const browserContext = this._contextManager.browserContextForId(browserContextId);
1678
1693
+ const pageTargets = [...this._targets.values()].filter(target => target instanceof PageTarget);
1679
- + const contextPages = pageTargets.filter(target => target._browserContext === browserContext);
1680
- + await Promise.all(contextPages.map(page => page._channel.connect('').send('ensurePermissions', permissions).catch(e => void e)));
1694
+ + return pageTargets.filter(target => target._browserContext === browserContext);
1681
1695
+ }
1682
1696
+
1683
1697
+ async newPage({browserContextId}) {
@@ -1775,10 +1789,16 @@ index 0000000000000000000000000000000000000000..98071c0e2c5429cfe8f29c390de3944f
1775
1789
+ this._registry = registry;
1776
1790
+ this._tab = tab;
1777
1791
+ this._browserContext = browserContext;
1792
+ + this._url = '';
1778
1793
+ this._openerId = opener ? opener.id() : undefined;
1779
1794
+ this._channel = SimpleChannel.createForMessageManager(`browser::page[${this._targetId}]`, tab.linkedBrowser.messageManager);
1780
1795
+
1796
+ + const navigationListener = {
1797
+ + QueryInterface: ChromeUtils.generateQI([ Ci.nsIWebProgressListener]),
1798
+ + onLocationChange: (aWebProgress, aRequest, aLocation) => this._onNavigated(aLocation),
1799
+ + };
1781
1800
+ this._eventListeners = [
1801
+ + helper.addProgressListener(tab.linkedBrowser, navigationListener, Ci.nsIWebProgress.NOTIFY_LOCATION),
1782
1802
+ helper.addMessageListener(tab.linkedBrowser.messageManager, 'juggler:content-ready', {
1783
1803
+ receiveMessage: () => this._onContentReady()
1784
1804
+ }),
@@ -1839,6 +1859,15 @@ index 0000000000000000000000000000000000000000..98071c0e2c5429cfe8f29c390de3944f
1839
1859
+ };
1840
1860
+ }
1841
1861
+
1862
+ + _onNavigated(aLocation) {
1863
+ + this._url = aLocation.spec;
1864
+ + this._browserContext.grantPermissionsToOrigin(this._url);
1865
+ + }
1866
+ +
1867
+ + async ensurePermissions(permissions) {
1868
+ + await this._channel.connect('').send('ensurePermissions', permissions).catch(e => void e);
1869
+ + }
1870
+ +
1842
1871
+ dispose() {
1843
1872
+ helper.removeListeners(this._eventListeners);
1844
1873
+ }
@@ -4146,7 +4175,7 @@ index 0000000000000000000000000000000000000000..3a386425d3796d0a6786dea193b3402d
4146
4175
+
4147
4176
diff --git a/juggler/content/main.js b/juggler/content/main.js
4148
4177
new file mode 100644
4149
- index 0000000000000000000000000000000000000000..212f1c1a218efebe8685b019e79fb553db720453
4178
+ index 0000000000000000000000000000000000000000..6ce6eff8dc8852d7fbbac907421de6de39d8ed0e
4150
4179
--- /dev/null
4151
4180
+++ b/juggler/content/main.js
4152
4181
@@ -0,0 +1,129 @@
@@ -4163,7 +4192,7 @@ index 0000000000000000000000000000000000000000..212f1c1a218efebe8685b019e79fb553
4163
4192
+ 'geo',
4164
4193
+ 'microphone',
4165
4194
+ 'camera',
4166
- + 'desktop-notifications ',
4195
+ + 'desktop-notification ',
4167
4196
+ ];
4168
4197
+
4169
4198
+ const scrollbarManager = new ScrollbarManager(docShell);
@@ -4360,10 +4389,10 @@ index 0000000000000000000000000000000000000000..2f2b7ca247f6b6dff396fb4b644654de
4360
4389
+ this.AccessibilityHandler = AccessibilityHandler;
4361
4390
diff --git a/juggler/protocol/BrowserHandler.js b/juggler/protocol/BrowserHandler.js
4362
4391
new file mode 100644
4363
- index 0000000000000000000000000000000000000000..060174f997f4a607c9e6d7bf4e1e204f07fe86c7
4392
+ index 0000000000000000000000000000000000000000..a5f050cd024dfdd3d7b1366600273744f82c5cbb
4364
4393
--- /dev/null
4365
4394
+++ b/juggler/protocol/BrowserHandler.js
4366
- @@ -0,0 +1,163 @@
4395
+ @@ -0,0 +1,172 @@
4367
4396
+ "use strict";
4368
4397
+
4369
4398
+ const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
@@ -4481,8 +4510,17 @@ index 0000000000000000000000000000000000000000..060174f997f4a607c9e6d7bf4e1e204f
4481
4510
+ }
4482
4511
+
4483
4512
+ async grantPermissions({browserContextId, origin, permissions}) {
4484
- + this._contextManager.browserContextForId(browserContextId).grantPermissions(origin, permissions);
4485
- + await this._targetRegistry.ensurePermissionsInContextPages(browserContextId, permissions);
4513
+ + const browserContext = this._contextManager.browserContextForId(browserContextId);
4514
+ + browserContext.grantPermissions(origin, permissions);
4515
+ + const contextPages = this._targetRegistry.pageTargets(browserContextId);
4516
+ + const promises = [];
4517
+ + for (const page of contextPages) {
4518
+ + if (origin === '*' || page._url.startsWith(origin)) {
4519
+ + browserContext.grantPermissionsToOrigin(page._url);
4520
+ + promises.push(page.ensurePermissions(permissions));
4521
+ + }
4522
+ + }
4523
+ + await Promise.all(promises);
4486
4524
+ }
4487
4525
+
4488
4526
+ resetPermissions({browserContextId}) {
@@ -5398,10 +5436,10 @@ index 0000000000000000000000000000000000000000..78b6601b91d0b7fcda61114e6846aa07
5398
5436
+ this.EXPORTED_SYMBOLS = ['t', 'checkScheme'];
5399
5437
diff --git a/juggler/protocol/Protocol.js b/juggler/protocol/Protocol.js
5400
5438
new file mode 100644
5401
- index 0000000000000000000000000000000000000000..9f7f4ce40454257ff83e8d39b278c1dbc1353991
5439
+ index 0000000000000000000000000000000000000000..9b636b045df0737039d94b5a6efc8c4f004eb58a
5402
5440
--- /dev/null
5403
5441
+++ b/juggler/protocol/Protocol.js
5404
- @@ -0,0 +1,747 @@
5442
+ @@ -0,0 +1,745 @@
5405
5443
+ const {t, checkScheme} = ChromeUtils.import('chrome://juggler/content/protocol/PrimitiveTypes.js');
5406
5444
+
5407
5445
+ // Protocol-specific types.
@@ -5662,9 +5700,7 @@ index 0000000000000000000000000000000000000000..9f7f4ce40454257ff83e8d39b278c1db
5662
5700
+ params: {
5663
5701
+ origin: t.String,
5664
5702
+ browserContextId: t.Optional(t.String),
5665
- + permissions: t.Array(t.Enum([
5666
- + 'geo', 'microphone', 'camera', 'desktop-notifications'
5667
- + ])),
5703
+ + permissions: t.Array(t.String),
5668
5704
+ },
5669
5705
+ },
5670
5706
+ 'resetPermissions': {
0 commit comments