@@ -70,9 +70,8 @@ type Frame struct {
70
70
71
71
documentHandle * ElementHandle
72
72
73
- executionContextMu sync.RWMutex
74
- mainExecutionContext frameExecutionContext
75
- utilityExecutionContext frameExecutionContext
73
+ executionContextMu sync.RWMutex
74
+ executionContexts map [executionWorld ]frameExecutionContext
76
75
77
76
loadingStartedTime time.Time
78
77
@@ -112,6 +111,7 @@ func NewFrame(ctx context.Context, m *FrameManager, parentFrame *Frame, frameID
112
111
lifecycleEvents : make (map [LifecycleEvent ]bool ),
113
112
subtreeLifecycleEvents : make (map [LifecycleEvent ]bool ),
114
113
inflightRequests : make (map [network.RequestID ]bool ),
114
+ executionContexts : make (map [executionWorld ]frameExecutionContext ),
115
115
currentDocument : & DocumentInfo {},
116
116
networkIdleCh : make (chan struct {}),
117
117
log : log ,
@@ -341,7 +341,7 @@ func (f *Frame) hasContext(world executionWorld) bool {
341
341
f .executionContextMu .RLock ()
342
342
defer f .executionContextMu .RUnlock ()
343
343
344
- return f .getExecCtx ( world ) != nil
344
+ return f .executionContexts [ world ] != nil
345
345
}
346
346
347
347
func (f * Frame ) hasLifecycleEventFired (event LifecycleEvent ) bool {
@@ -375,11 +375,13 @@ func (f *Frame) nullContext(execCtxID runtime.ExecutionContextID) {
375
375
f .executionContextMu .Lock ()
376
376
defer f .executionContextMu .Unlock ()
377
377
378
- if f . mainExecutionContext != nil && f . mainExecutionContext .ID () == execCtxID {
379
- f .mainExecutionContext = nil
378
+ if ec := f . executionContexts [ mainWorld ]; ec != nil && ec .ID () == execCtxID {
379
+ f .executionContexts [ mainWorld ] = nil
380
380
f .documentHandle = nil
381
- } else if f .utilityExecutionContext != nil && f .utilityExecutionContext .ID () == execCtxID {
382
- f .utilityExecutionContext = nil
381
+ return
382
+ }
383
+ if ec := f .executionContexts [utilityWorld ]; ec != nil && ec .ID () == execCtxID {
384
+ f .executionContexts [utilityWorld ] = nil
383
385
}
384
386
}
385
387
@@ -450,19 +452,20 @@ func (f *Frame) setContext(world executionWorld, execCtx frameExecutionContext)
450
452
f .log .Debugf ("Frame:setContext" , "fid:%s furl:%q ectxid:%d world:%s" ,
451
453
f .ID (), f .URL (), execCtx .ID (), world )
452
454
453
- switch world {
454
- case mainWorld :
455
- if f .mainExecutionContext == nil {
456
- f .mainExecutionContext = execCtx
457
- }
458
- case utilityWorld :
459
- if f .utilityExecutionContext == nil {
460
- f .utilityExecutionContext = execCtx
461
- }
462
- default :
455
+ if ! world .valid () {
463
456
err := fmt .Errorf ("unknown world: %q, it should be either main or utility" , world )
464
457
panic (err )
465
458
}
459
+
460
+ if f .executionContexts [world ] != nil {
461
+ f .log .Debugf ("Frame:setContext" , "fid:%s furl:%q ectxid:%d world:%s, world exists" ,
462
+ f .ID (), f .URL (), execCtx .ID (), world )
463
+ return
464
+ }
465
+
466
+ f .executionContexts [world ] = execCtx
467
+ f .log .Debugf ("Frame:setContext" , "fid:%s furl:%q ectxid:%d world:%s, world set" ,
468
+ f .ID (), f .URL (), execCtx .ID (), world )
466
469
}
467
470
468
471
func (f * Frame ) setID (id cdp.FrameID ) {
@@ -501,7 +504,7 @@ func (f *Frame) waitForFunction(apiCtx context.Context, world executionWorld, pr
501
504
f .executionContextMu .RLock ()
502
505
defer f .executionContextMu .RUnlock ()
503
506
504
- execCtx := f .getExecCtx ( world )
507
+ execCtx := f .executionContexts [ world ]
505
508
injected , err := execCtx .getInjectedScript (apiCtx )
506
509
if err != nil {
507
510
return nil , err
@@ -556,10 +559,9 @@ func (f *Frame) waitForSelector(selector string, opts *FrameWaitForSelectorOptio
556
559
f .executionContextMu .RLock ()
557
560
defer f .executionContextMu .RUnlock ()
558
561
559
- if handle .execCtx != f . mainExecutionContext {
562
+ if ec := f . executionContexts [ mainWorld ]; handle .execCtx != ec {
560
563
defer handle .Dispose ()
561
- handle , err = f .mainExecutionContext .adoptElementHandle (handle )
562
- if err != nil {
564
+ if handle , err = ec .adoptElementHandle (handle ); err != nil {
563
565
return nil , err
564
566
}
565
567
}
@@ -730,7 +732,8 @@ func (f *Frame) EvaluateHandle(pageFunc goja.Value, args ...goja.Value) (handle
730
732
var err error
731
733
f .executionContextMu .RLock ()
732
734
{
733
- handle , err = f .mainExecutionContext .EvaluateHandle (f .ctx , pageFunc , args ... )
735
+ ec := f .executionContexts [mainWorld ]
736
+ handle , err = ec .EvaluateHandle (f .ctx , pageFunc , args ... )
734
737
}
735
738
f .executionContextMu .RUnlock ()
736
739
if err != nil {
@@ -1438,28 +1441,18 @@ func (f *Frame) adoptBackendNodeID(world executionWorld, id cdp.BackendNodeID) (
1438
1441
f .executionContextMu .RLock ()
1439
1442
defer f .executionContextMu .RUnlock ()
1440
1443
1441
- ec := f .getExecCtx ( world )
1444
+ ec := f .executionContexts [ world ]
1442
1445
return ec .adoptBackendNodeID (id )
1443
1446
}
1444
1447
1445
1448
func (f * Frame ) evaluate (world executionWorld , apiCtx context.Context , opts evaluateOptions , pageFunc goja.Value , args ... goja.Value ) (res interface {}, err error ) {
1446
1449
f .executionContextMu .RLock ()
1447
1450
defer f .executionContextMu .RUnlock ()
1448
1451
1449
- ec := f .getExecCtx ( world )
1452
+ ec := f .executionContexts [ world ]
1450
1453
return ec .evaluate (apiCtx , opts , pageFunc , args ... )
1451
1454
}
1452
1455
1453
- // getExecCtx returns an execution context using a given world name.
1454
- // Unsafe to use concurrently.
1455
- func (f * Frame ) getExecCtx (world executionWorld ) frameExecutionContext {
1456
- ec := f .mainExecutionContext
1457
- if world == utilityWorld {
1458
- ec = f .utilityExecutionContext
1459
- }
1460
- return ec
1461
- }
1462
-
1463
1456
// frameExecutionContext represents a JS execution context that belongs to Frame.
1464
1457
type frameExecutionContext interface {
1465
1458
// adoptBackendNodeID adopts specified backend node into this execution
0 commit comments