...

Source file src/github.com/playwright-community/playwright-go/page.go

Documentation: github.com/playwright-community/playwright-go

     1  package playwright
     2  
     3  import (
     4  	"encoding/base64"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"reflect"
     8  )
     9  
    10  type pageImpl struct {
    11  	channelOwner
    12  	isClosed        bool
    13  	video           *videoImpl
    14  	mouse           *mouseImpl
    15  	keyboard        *keyboardImpl
    16  	touchscreen     *touchscreenImpl
    17  	timeoutSettings *timeoutSettings
    18  	browserContext  *browserContextImpl
    19  	frames          []Frame
    20  	workers         []Worker
    21  	mainFrame       Frame
    22  	routes          []*routeHandlerEntry
    23  	viewportSize    ViewportSize
    24  	ownedContext    BrowserContext
    25  	bindings        map[string]BindingCallFunction
    26  }
    27  
    28  func (p *pageImpl) Context() BrowserContext {
    29  	return p.browserContext
    30  }
    31  
    32  func (p *pageImpl) Close(options ...PageCloseOptions) error {
    33  	_, err := p.channel.Send("close", options)
    34  	if err != nil {
    35  		return err
    36  	}
    37  	if p.ownedContext != nil {
    38  		return p.ownedContext.Close()
    39  	}
    40  	return nil
    41  }
    42  
    43  func (p *pageImpl) InnerText(selector string, options ...PageInnerTextOptions) (string, error) {
    44  	return p.mainFrame.InnerText(selector, options...)
    45  }
    46  
    47  func (p *pageImpl) InnerHTML(selector string, options ...PageInnerHTMLOptions) (string, error) {
    48  	return p.mainFrame.InnerHTML(selector, options...)
    49  }
    50  
    51  func (p *pageImpl) Opener() (Page, error) {
    52  	channel := p.initializer["opener"]
    53  	channelOwner := fromNullableChannel(channel)
    54  	if channelOwner == nil {
    55  		return nil, nil
    56  	}
    57  	return channelOwner.(*pageImpl), nil
    58  }
    59  
    60  func (p *pageImpl) MainFrame() Frame {
    61  	return p.mainFrame
    62  }
    63  
    64  // PageFrameOptions is the option struct for Page.Frame()
    65  type PageFrameOptions struct {
    66  	Name *string
    67  	URL  interface{}
    68  }
    69  
    70  func (p *pageImpl) Frame(options PageFrameOptions) Frame {
    71  	var matcher *urlMatcher
    72  	if options.URL != nil {
    73  		matcher = newURLMatcher(options.URL)
    74  	}
    75  
    76  	for _, f := range p.frames {
    77  		if options.Name != nil && f.Name() == *options.Name {
    78  			return f
    79  		}
    80  
    81  		if options.URL != nil && matcher != nil && matcher.Matches(f.URL()) {
    82  			return f
    83  		}
    84  	}
    85  
    86  	return nil
    87  }
    88  
    89  func (p *pageImpl) Frames() []Frame {
    90  	return p.frames
    91  }
    92  
    93  func (p *pageImpl) SetDefaultNavigationTimeout(timeout float64) {
    94  	p.timeoutSettings.SetNavigationTimeout(timeout)
    95  	p.channel.SendNoReply("setDefaultNavigationTimeoutNoReply", map[string]interface{}{
    96  		"timeout": timeout,
    97  	})
    98  }
    99  
   100  func (p *pageImpl) SetDefaultTimeout(timeout float64) {
   101  	p.timeoutSettings.SetTimeout(timeout)
   102  	p.channel.SendNoReply("setDefaultTimeoutNoReply", map[string]interface{}{
   103  		"timeout": timeout,
   104  	})
   105  }
   106  
   107  func (p *pageImpl) QuerySelector(selector string) (ElementHandle, error) {
   108  	return p.mainFrame.QuerySelector(selector)
   109  }
   110  
   111  func (p *pageImpl) QuerySelectorAll(selector string) ([]ElementHandle, error) {
   112  	return p.mainFrame.QuerySelectorAll(selector)
   113  }
   114  
   115  func (p *pageImpl) WaitForSelector(selector string, options ...PageWaitForSelectorOptions) (ElementHandle, error) {
   116  	return p.mainFrame.WaitForSelector(selector, options...)
   117  }
   118  
   119  func (p *pageImpl) DispatchEvent(selector string, typ string, options ...PageDispatchEventOptions) error {
   120  	return p.mainFrame.DispatchEvent(selector, typ, nil, options...)
   121  }
   122  
   123  func (p *pageImpl) Evaluate(expression string, options ...interface{}) (interface{}, error) {
   124  	return p.mainFrame.Evaluate(expression, options...)
   125  }
   126  
   127  func (p *pageImpl) EvaluateHandle(expression string, options ...interface{}) (JSHandle, error) {
   128  	return p.mainFrame.EvaluateHandle(expression, options...)
   129  }
   130  
   131  func (p *pageImpl) EvalOnSelector(selector string, expression string, options ...interface{}) (interface{}, error) {
   132  	return p.mainFrame.EvalOnSelector(selector, expression, options...)
   133  }
   134  
   135  func (p *pageImpl) EvalOnSelectorAll(selector string, expression string, options ...interface{}) (interface{}, error) {
   136  	return p.mainFrame.EvalOnSelectorAll(selector, expression, options...)
   137  }
   138  
   139  func (p *pageImpl) AddScriptTag(options PageAddScriptTagOptions) (ElementHandle, error) {
   140  	return p.mainFrame.AddScriptTag(options)
   141  }
   142  
   143  func (p *pageImpl) AddStyleTag(options PageAddStyleTagOptions) (ElementHandle, error) {
   144  	return p.mainFrame.AddStyleTag(options)
   145  }
   146  
   147  func (p *pageImpl) SetExtraHTTPHeaders(headers map[string]string) error {
   148  	_, err := p.channel.Send("setExtraHTTPHeaders", map[string]interface{}{
   149  		"headers": serializeMapToNameAndValue(headers),
   150  	})
   151  	return err
   152  }
   153  
   154  func (p *pageImpl) URL() string {
   155  	return p.mainFrame.URL()
   156  }
   157  
   158  func (p *pageImpl) Unroute(url interface{}, handlers ...routeHandler) error {
   159  	p.Lock()
   160  	defer p.Unlock()
   161  
   162  	routes, err := unroute(p.channel, p.routes, url, handlers...)
   163  	if err != nil {
   164  		return err
   165  	}
   166  	p.routes = routes
   167  
   168  	return nil
   169  }
   170  
   171  func (p *pageImpl) Content() (string, error) {
   172  	return p.mainFrame.Content()
   173  }
   174  
   175  func (p *pageImpl) SetContent(content string, options ...PageSetContentOptions) error {
   176  	return p.mainFrame.SetContent(content, options...)
   177  }
   178  
   179  func (p *pageImpl) Goto(url string, options ...PageGotoOptions) (Response, error) {
   180  	return p.mainFrame.Goto(url, options...)
   181  }
   182  
   183  func (p *pageImpl) Reload(options ...PageReloadOptions) (Response, error) {
   184  	response, err := p.channel.Send("reload", options)
   185  	if err != nil {
   186  		return nil, err
   187  	}
   188  	return fromChannel(response).(*responseImpl), err
   189  }
   190  
   191  func (p *pageImpl) WaitForLoadState(state ...string) {
   192  	p.mainFrame.WaitForLoadState(state...)
   193  }
   194  
   195  func (p *pageImpl) GoBack(options ...PageGoBackOptions) (Response, error) {
   196  	channel, err := p.channel.Send("goBack", options)
   197  	if err != nil {
   198  		return nil, err
   199  	}
   200  	channelOwner := fromNullableChannel(channel)
   201  	if channelOwner == nil {
   202  		return nil, nil
   203  	}
   204  	return channelOwner.(*responseImpl), nil
   205  }
   206  
   207  func (p *pageImpl) GoForward(options ...PageGoForwardOptions) (Response, error) {
   208  	resp, err := p.channel.Send("goForward", options)
   209  	if err != nil {
   210  		return nil, err
   211  	}
   212  	obj := fromNullableChannel(resp)
   213  	if obj == nil {
   214  		return nil, nil
   215  	}
   216  	return obj.(*responseImpl), nil
   217  }
   218  
   219  func (p *pageImpl) EmulateMedia(options ...PageEmulateMediaOptions) error {
   220  	_, err := p.channel.Send("emulateMedia", options)
   221  	if err != nil {
   222  		return err
   223  	}
   224  	return err
   225  }
   226  
   227  // ViewportSize represents the viewport size
   228  type ViewportSize struct {
   229  	Width  int `json:"width"`
   230  	Height int `json:"height"`
   231  }
   232  
   233  func (p *pageImpl) SetViewportSize(width, height int) error {
   234  	_, err := p.channel.Send("setViewportSize", map[string]interface{}{
   235  		"viewportSize": map[string]interface{}{
   236  			"width":  width,
   237  			"height": height,
   238  		},
   239  	})
   240  	if err != nil {
   241  		return err
   242  	}
   243  	p.viewportSize.Width = width
   244  	p.viewportSize.Height = height
   245  	return nil
   246  }
   247  
   248  func (p *pageImpl) ViewportSize() ViewportSize {
   249  	return p.viewportSize
   250  }
   251  
   252  func (p *pageImpl) BringToFront() error {
   253  	_, err := p.channel.Send("bringToFront")
   254  	return err
   255  }
   256  
   257  func (p *pageImpl) Type(selector, text string, options ...PageTypeOptions) error {
   258  	return p.mainFrame.Type(selector, text, options...)
   259  }
   260  
   261  func (p *pageImpl) Fill(selector, text string, options ...FrameFillOptions) error {
   262  	return p.mainFrame.Fill(selector, text, options...)
   263  }
   264  
   265  func (p *pageImpl) Press(selector, key string, options ...PagePressOptions) error {
   266  	return p.mainFrame.Press(selector, key, options...)
   267  }
   268  
   269  func (p *pageImpl) Title() (string, error) {
   270  	return p.mainFrame.Title()
   271  }
   272  
   273  func (p *pageImpl) Workers() []Worker {
   274  	return p.workers
   275  }
   276  
   277  func (p *pageImpl) Screenshot(options ...PageScreenshotOptions) ([]byte, error) {
   278  	var path *string
   279  	if len(options) > 0 {
   280  		path = options[0].Path
   281  	}
   282  	data, err := p.channel.Send("screenshot", options)
   283  	if err != nil {
   284  		return nil, fmt.Errorf("could not send message :%w", err)
   285  	}
   286  	image, err := base64.StdEncoding.DecodeString(data.(string))
   287  	if err != nil {
   288  		return nil, fmt.Errorf("could not decode base64 :%w", err)
   289  	}
   290  	if path != nil {
   291  		if err := ioutil.WriteFile(*path, image, 0644); err != nil {
   292  			return nil, err
   293  		}
   294  	}
   295  	return image, nil
   296  }
   297  
   298  func (p *pageImpl) PDF(options ...PagePdfOptions) ([]byte, error) {
   299  	var path *string
   300  	if len(options) > 0 {
   301  		path = options[0].Path
   302  	}
   303  	data, err := p.channel.Send("pdf", options)
   304  	if err != nil {
   305  		return nil, fmt.Errorf("could not send message :%w", err)
   306  	}
   307  	pdf, err := base64.StdEncoding.DecodeString(data.(string))
   308  	if err != nil {
   309  		return nil, fmt.Errorf("could not decode base64 :%w", err)
   310  	}
   311  	if path != nil {
   312  		if err := ioutil.WriteFile(*path, pdf, 0644); err != nil {
   313  			return nil, err
   314  		}
   315  	}
   316  	return pdf, nil
   317  }
   318  
   319  func (p *pageImpl) Click(selector string, options ...PageClickOptions) error {
   320  	return p.mainFrame.Click(selector, options...)
   321  }
   322  
   323  func (p *pageImpl) WaitForEvent(event string, predicate ...interface{}) interface{} {
   324  	return <-waitForEvent(p, event, predicate...)
   325  }
   326  
   327  func (p *pageImpl) WaitForNavigation(options ...PageWaitForNavigationOptions) (Response, error) {
   328  	return p.mainFrame.WaitForNavigation(options...)
   329  }
   330  
   331  func (p *pageImpl) WaitForRequest(url interface{}, options ...interface{}) Request {
   332  	var matcher *urlMatcher
   333  	if url != nil {
   334  		matcher = newURLMatcher(url)
   335  	}
   336  	predicate := func(req *requestImpl) bool {
   337  		if matcher != nil {
   338  			return matcher.Matches(req.URL())
   339  		}
   340  		if len(options) == 1 {
   341  			return reflect.ValueOf(options[0]).Call([]reflect.Value{reflect.ValueOf(req)})[0].Bool()
   342  		}
   343  		return true
   344  	}
   345  	return p.WaitForEvent("request", predicate).(*requestImpl)
   346  }
   347  
   348  func (p *pageImpl) WaitForResponse(url interface{}, options ...interface{}) Response {
   349  	var matcher *urlMatcher
   350  	if url != nil {
   351  		matcher = newURLMatcher(url)
   352  	}
   353  	predicate := func(req *responseImpl) bool {
   354  		if matcher != nil {
   355  			return matcher.Matches(req.URL())
   356  		}
   357  		if len(options) == 1 {
   358  			return reflect.ValueOf(options[0]).Call([]reflect.Value{reflect.ValueOf(req)})[0].Bool()
   359  		}
   360  		return true
   361  	}
   362  	return p.WaitForEvent("response", predicate).(*responseImpl)
   363  }
   364  
   365  func (p *pageImpl) ExpectEvent(event string, cb func() error, predicates ...interface{}) (interface{}, error) {
   366  	args := []interface{}{event}
   367  	if len(predicates) == 1 {
   368  		args = append(args, predicates[0])
   369  	}
   370  	return newExpectWrapper(p.WaitForEvent, args, cb)
   371  }
   372  
   373  func (p *pageImpl) ExpectNavigation(cb func() error, options ...PageWaitForNavigationOptions) (Response, error) {
   374  	navigationOptions := make([]interface{}, 0)
   375  	for _, option := range options {
   376  		navigationOptions = append(navigationOptions, option)
   377  	}
   378  	response, err := newExpectWrapper(p.WaitForNavigation, navigationOptions, cb)
   379  	if response == nil {
   380  		return nil, err
   381  	}
   382  	return response.(*responseImpl), err
   383  }
   384  
   385  func (p *pageImpl) ExpectConsoleMessage(cb func() error) (ConsoleMessage, error) {
   386  	consoleMessage, err := newExpectWrapper(p.WaitForEvent, []interface{}{"console"}, cb)
   387  	return consoleMessage.(*consoleMessageImpl), err
   388  }
   389  
   390  func (p *pageImpl) ExpectedDialog(cb func() error) (Dialog, error) {
   391  	dialog, err := newExpectWrapper(p.WaitForEvent, []interface{}{"dialog"}, cb)
   392  	return dialog.(*dialogImpl), err
   393  }
   394  
   395  func (p *pageImpl) ExpectDownload(cb func() error) (Download, error) {
   396  	download, err := newExpectWrapper(p.WaitForEvent, []interface{}{"download"}, cb)
   397  	return download.(*downloadImpl), err
   398  }
   399  
   400  func (p *pageImpl) ExpectFileChooser(cb func() error) (FileChooser, error) {
   401  	response, err := newExpectWrapper(p.WaitForEvent, []interface{}{"filechooser"}, cb)
   402  	return response.(*fileChooserImpl), err
   403  }
   404  
   405  func (p *pageImpl) ExpectLoadState(state string, cb func() error) error {
   406  	_, err := newExpectWrapper(p.mainFrame.WaitForLoadState, []interface{}{state}, cb)
   407  	return err
   408  }
   409  
   410  func (p *pageImpl) ExpectPopup(cb func() error) (Page, error) {
   411  	popup, err := newExpectWrapper(p.WaitForEvent, []interface{}{"popup"}, cb)
   412  	return popup.(*pageImpl), err
   413  }
   414  
   415  func (p *pageImpl) ExpectResponse(url interface{}, cb func() error, options ...interface{}) (Response, error) {
   416  	response, err := newExpectWrapper(p.WaitForResponse, append([]interface{}{url}, options...), cb)
   417  	if err != nil {
   418  		return nil, err
   419  	}
   420  	return response.(*responseImpl), err
   421  }
   422  
   423  func (p *pageImpl) ExpectRequest(url interface{}, cb func() error, options ...interface{}) (Request, error) {
   424  	popup, err := newExpectWrapper(p.WaitForRequest, append([]interface{}{url}, options...), cb)
   425  	if err != nil {
   426  		return nil, err
   427  	}
   428  	return popup.(*requestImpl), err
   429  }
   430  
   431  func (p *pageImpl) ExpectWorker(cb func() error) (Worker, error) {
   432  	response, err := newExpectWrapper(p.WaitForEvent, []interface{}{"worker"}, cb)
   433  	return response.(*workerImpl), err
   434  }
   435  
   436  func (p *pageImpl) Route(url interface{}, handler routeHandler) error {
   437  	p.Lock()
   438  	defer p.Unlock()
   439  	p.routes = append(p.routes, newRouteHandlerEntry(newURLMatcher(url), handler))
   440  	if len(p.routes) == 1 {
   441  		_, err := p.channel.Send("setNetworkInterceptionEnabled", map[string]interface{}{
   442  			"enabled": true,
   443  		})
   444  		if err != nil {
   445  			return err
   446  		}
   447  	}
   448  	return nil
   449  }
   450  
   451  func (p *pageImpl) GetAttribute(selector string, name string, options ...PageGetAttributeOptions) (string, error) {
   452  	return p.mainFrame.GetAttribute(selector, name, options...)
   453  }
   454  
   455  func (p *pageImpl) Hover(selector string, options ...PageHoverOptions) error {
   456  	return p.mainFrame.Hover(selector, options...)
   457  }
   458  
   459  func (p *pageImpl) IsClosed() bool {
   460  	return p.isClosed
   461  }
   462  
   463  func (p *pageImpl) AddInitScript(options PageAddInitScriptOptions) error {
   464  	var source string
   465  	if options.Script != nil {
   466  		source = *options.Script
   467  	}
   468  	if options.Path != nil {
   469  		content, err := ioutil.ReadFile(*options.Path)
   470  		if err != nil {
   471  			return err
   472  		}
   473  		source = string(content)
   474  	}
   475  	_, err := p.channel.Send("addInitScript", map[string]interface{}{
   476  		"source": source,
   477  	})
   478  	return err
   479  }
   480  
   481  func (p *pageImpl) Keyboard() Keyboard {
   482  	return p.keyboard
   483  }
   484  func (p *pageImpl) Mouse() Mouse {
   485  	return p.mouse
   486  }
   487  
   488  func (p *pageImpl) Touchscreen() Touchscreen {
   489  	return p.touchscreen
   490  }
   491  
   492  func (p *pageImpl) setBrowserContext(browserContext *browserContextImpl) {
   493  	p.browserContext = browserContext
   494  	p.timeoutSettings = newTimeoutSettings(browserContext.timeoutSettings)
   495  }
   496  
   497  func newPage(parent *channelOwner, objectType string, guid string, initializer map[string]interface{}) *pageImpl {
   498  	viewportSize := &ViewportSize{}
   499  	if _, ok := initializer["viewportSize"].(map[string]interface{}); ok {
   500  		viewportSize.Height = int(initializer["viewportSize"].(map[string]interface{})["height"].(float64))
   501  		viewportSize.Width = int(initializer["viewportSize"].(map[string]interface{})["width"].(float64))
   502  	}
   503  	bt := &pageImpl{
   504  		mainFrame:       fromChannel(initializer["mainFrame"]).(*frameImpl),
   505  		workers:         make([]Worker, 0),
   506  		routes:          make([]*routeHandlerEntry, 0),
   507  		bindings:        make(map[string]BindingCallFunction),
   508  		viewportSize:    *viewportSize,
   509  		timeoutSettings: newTimeoutSettings(nil),
   510  	}
   511  	bt.frames = []Frame{bt.mainFrame}
   512  	bt.mainFrame.(*frameImpl).page = bt
   513  	bt.createChannelOwner(bt, parent, objectType, guid, initializer)
   514  	bt.mouse = newMouse(bt.channel)
   515  	bt.keyboard = newKeyboard(bt.channel)
   516  	bt.touchscreen = newTouchscreen(bt.channel)
   517  	bt.channel.On("bindingCall", func(params map[string]interface{}) {
   518  		bt.onBinding(fromChannel(params["binding"]).(*bindingCallImpl))
   519  	})
   520  	bt.channel.On("close", bt.onClose)
   521  	bt.channel.On("console", func(ev map[string]interface{}) {
   522  		bt.Emit("console", fromChannel(ev["message"]))
   523  	})
   524  	bt.channel.On("crash", func() {
   525  		bt.Emit("crash")
   526  	})
   527  	bt.channel.On("dialog", func(ev map[string]interface{}) {
   528  		go func() {
   529  			bt.Emit("dialog", fromChannel(ev["dialog"]))
   530  		}()
   531  	})
   532  	bt.channel.On("domcontentloaded", func() {
   533  		bt.Emit("domcontentloaded")
   534  	})
   535  	bt.channel.On("fileChooser", func(ev map[string]interface{}) {
   536  		bt.Emit("filechooser", newFileChooser(bt, fromChannel(ev["element"]).(*elementHandleImpl), ev["isMultiple"].(bool)))
   537  	})
   538  	bt.channel.On("frameAttached", func(ev map[string]interface{}) {
   539  		bt.onFrameAttached(fromChannel(ev["frame"]).(*frameImpl))
   540  	})
   541  	bt.channel.On("frameDetached", func(ev map[string]interface{}) {
   542  		bt.onFrameDetached(fromChannel(ev["frame"]).(*frameImpl))
   543  	})
   544  	bt.channel.On(
   545  		"load", func(ev map[string]interface{}) {
   546  			bt.Emit("load")
   547  		},
   548  	)
   549  	bt.channel.On(
   550  		"pageError", func(ev map[string]interface{}) {
   551  			err := errorPayload{}
   552  			remapMapToStruct(ev["error"].(map[string]interface{})["error"], &err)
   553  			bt.Emit("pageerror", parseError(err))
   554  		},
   555  	)
   556  	bt.channel.On("popup", func(ev map[string]interface{}) {
   557  		bt.Emit("popup", fromChannel(ev["page"]))
   558  	})
   559  	bt.channel.On("route", func(ev map[string]interface{}) {
   560  		bt.onRoute(fromChannel(ev["route"]).(*routeImpl), fromChannel(ev["request"]).(*requestImpl))
   561  	})
   562  	bt.channel.On("download", func(ev map[string]interface{}) {
   563  		url := ev["url"].(string)
   564  		suggestedFilename := ev["suggestedFilename"].(string)
   565  		artifact := fromChannel(ev["artifact"]).(*artifactImpl)
   566  		bt.Emit("download", newDownload(bt, url, suggestedFilename, artifact))
   567  	})
   568  	bt.channel.On("video", func(params map[string]interface{}) {
   569  		bt.Video().(*videoImpl).artifact = fromChannel(params["artifact"]).(*artifactImpl)
   570  	})
   571  	bt.channel.On("webSocket", func(ev map[string]interface{}) {
   572  		bt.Emit("websocket", fromChannel(ev["webSocket"]).(*webSocketImpl))
   573  	})
   574  
   575  	bt.channel.On("worker", func(ev map[string]interface{}) {
   576  		bt.onWorker(fromChannel(ev["worker"]).(*workerImpl))
   577  	})
   578  	bt.addEventHandler(func(name string, handler interface{}) {
   579  		if name == "filechooser" && bt.ListenerCount(name) == 0 {
   580  			bt.channel.SendNoReply("setFileChooserInterceptedNoReply", map[string]interface{}{
   581  				"intercepted": true,
   582  			})
   583  		}
   584  	})
   585  	bt.removeEventHandler(func(name string, handler interface{}) {
   586  		if name == "filechooser" && bt.ListenerCount(name) == 0 {
   587  			bt.channel.SendNoReply("setFileChooserInterceptedNoReply", map[string]interface{}{
   588  				"intercepted": false,
   589  			})
   590  		}
   591  	})
   592  
   593  	return bt
   594  }
   595  
   596  func (p *pageImpl) onBinding(binding *bindingCallImpl) {
   597  	function := p.bindings[binding.initializer["name"].(string)]
   598  	if function == nil {
   599  		return
   600  	}
   601  	go binding.Call(function)
   602  }
   603  
   604  func (p *pageImpl) onFrameAttached(frame *frameImpl) {
   605  	frame.page = p
   606  	p.frames = append(p.frames, frame)
   607  	p.Emit("frameattached", frame)
   608  }
   609  
   610  func (p *pageImpl) onFrameDetached(frame *frameImpl) {
   611  	frame.detached = true
   612  	frames := make([]Frame, 0)
   613  	for i := 0; i < len(p.frames); i++ {
   614  		if p.frames[i] != frame {
   615  			frames = append(frames, frame)
   616  		}
   617  	}
   618  	if len(frames) != len(p.frames) {
   619  		p.frames = frames
   620  	}
   621  	p.Emit("framedetached", frame)
   622  }
   623  
   624  func (p *pageImpl) onRoute(route *routeImpl, request *requestImpl) {
   625  	go func() {
   626  		for _, handlerEntry := range p.routes {
   627  			if handlerEntry.matcher.Matches(request.URL()) {
   628  				handlerEntry.handler(route, request)
   629  				return
   630  			}
   631  		}
   632  		p.browserContext.onRoute(route, request)
   633  	}()
   634  }
   635  
   636  func (p *pageImpl) onWorker(worker *workerImpl) {
   637  	p.workers = append(p.workers, worker)
   638  	worker.page = p
   639  	p.Emit("worker", worker)
   640  }
   641  
   642  func (p *pageImpl) onClose() {
   643  	p.isClosed = true
   644  	newPages := []Page{}
   645  	newBackgoundPages := []Page{}
   646  	if p.browserContext != nil {
   647  		p.browserContext.Lock()
   648  		for _, page := range p.browserContext.pages {
   649  			if page != p {
   650  				newPages = append(newPages, page)
   651  			}
   652  		}
   653  		for _, page := range p.browserContext.backgroundPages {
   654  			if page != p {
   655  				newBackgoundPages = append(newBackgoundPages, page)
   656  			}
   657  		}
   658  		p.browserContext.pages = newPages
   659  		p.browserContext.backgroundPages = newBackgoundPages
   660  		p.browserContext.Unlock()
   661  	}
   662  	p.Emit("close")
   663  }
   664  
   665  func (p *pageImpl) SetInputFiles(selector string, files []InputFile, options ...FrameSetInputFilesOptions) error {
   666  	return p.mainFrame.SetInputFiles(selector, files, options...)
   667  }
   668  
   669  func (p *pageImpl) Check(selector string, options ...FrameCheckOptions) error {
   670  	return p.mainFrame.Check(selector, options...)
   671  }
   672  
   673  func (p *pageImpl) Uncheck(selector string, options ...FrameUncheckOptions) error {
   674  	return p.mainFrame.Uncheck(selector, options...)
   675  }
   676  
   677  func (p *pageImpl) WaitForTimeout(timeout float64) {
   678  	p.mainFrame.WaitForTimeout(timeout)
   679  }
   680  
   681  func (p *pageImpl) WaitForFunction(expression string, arg interface{}, options ...FrameWaitForFunctionOptions) (JSHandle, error) {
   682  	return p.mainFrame.WaitForFunction(expression, arg, options...)
   683  }
   684  
   685  func (p *pageImpl) Dblclick(expression string, options ...FrameDblclickOptions) error {
   686  	return p.mainFrame.Dblclick(expression, options...)
   687  }
   688  
   689  func (p *pageImpl) Focus(expression string, options ...FrameFocusOptions) error {
   690  	return p.mainFrame.Focus(expression, options...)
   691  }
   692  
   693  func (p *pageImpl) TextContent(selector string, options ...FrameTextContentOptions) (string, error) {
   694  	return p.mainFrame.TextContent(selector, options...)
   695  }
   696  
   697  func (p *pageImpl) Video() Video {
   698  	if p.video == nil {
   699  		p.video = newVideo(p)
   700  	}
   701  	return p.video
   702  }
   703  
   704  func (p *pageImpl) Tap(selector string, options ...FrameTapOptions) error {
   705  	return p.mainFrame.Tap(selector, options...)
   706  }
   707  
   708  func (p *pageImpl) ExposeFunction(name string, binding ExposedFunction) error {
   709  	return p.ExposeBinding(name, func(source *BindingSource, args ...interface{}) interface{} {
   710  		return binding(args...)
   711  	})
   712  }
   713  func (p *pageImpl) ExposeBinding(name string, binding BindingCallFunction, handle ...bool) error {
   714  	needsHandle := false
   715  	if len(handle) == 1 {
   716  		needsHandle = handle[0]
   717  	}
   718  	if _, ok := p.bindings[name]; ok {
   719  		return fmt.Errorf("Function '%s' has been already registered", name)
   720  	}
   721  	if _, ok := p.browserContext.bindings[name]; ok {
   722  		return fmt.Errorf("Function '%s' has been already registered in the browser context", name)
   723  	}
   724  	p.bindings[name] = binding
   725  	_, err := p.channel.Send("exposeBinding", map[string]interface{}{
   726  		"name":        name,
   727  		"needsHandle": needsHandle,
   728  	})
   729  	return err
   730  }
   731  
   732  func (p *pageImpl) SelectOption(selector string, values SelectOptionValues, options ...FrameSelectOptionOptions) ([]string, error) {
   733  	return p.mainFrame.SelectOption(selector, values, options...)
   734  }
   735  
   736  func (p *pageImpl) IsChecked(selector string, options ...FrameIsCheckedOptions) (bool, error) {
   737  	return p.mainFrame.IsChecked(selector, options...)
   738  }
   739  
   740  func (p *pageImpl) IsDisabled(selector string, options ...FrameIsDisabledOptions) (bool, error) {
   741  	return p.mainFrame.IsDisabled(selector, options...)
   742  }
   743  
   744  func (p *pageImpl) IsEditable(selector string, options ...FrameIsEditableOptions) (bool, error) {
   745  	return p.mainFrame.IsEditable(selector, options...)
   746  }
   747  
   748  func (p *pageImpl) IsEnabled(selector string, options ...FrameIsEnabledOptions) (bool, error) {
   749  	return p.mainFrame.IsEnabled(selector, options...)
   750  }
   751  
   752  func (p *pageImpl) IsHidden(selector string, options ...FrameIsHiddenOptions) (bool, error) {
   753  	return p.mainFrame.IsHidden(selector, options...)
   754  }
   755  
   756  func (p *pageImpl) IsVisible(selector string, options ...FrameIsVisibleOptions) (bool, error) {
   757  	return p.mainFrame.IsVisible(selector, options...)
   758  }
   759  
   760  func (p *pageImpl) DragAndDrop(source, target string, options ...FrameDragAndDropOptions) error {
   761  	return p.mainFrame.DragAndDrop(source, target, options...)
   762  }
   763  
   764  func (p *pageImpl) Pause() error {
   765  	return p.browserContext.Pause()
   766  }
   767  
   768  func (p *pageImpl) InputValue(selector string, options ...FrameInputValueOptions) (string, error) {
   769  	return p.mainFrame.InputValue(selector, options...)
   770  }
   771  
   772  func (p *pageImpl) WaitForURL(url string, options ...FrameWaitForURLOptions) error {
   773  	return p.mainFrame.WaitForURL(url, options...)
   774  }
   775  
   776  func (p *pageImpl) SetChecked(selector string, checked bool, options ...FrameSetCheckedOptions) error {
   777  	return p.mainFrame.SetChecked(selector, checked, options...)
   778  }
   779  
   780  func (p *pageImpl) Locator(selector string, options ...PageLocatorOptions) (Locator, error) {
   781  	var option FrameLocatorOptions
   782  	if len(options) == 1 {
   783  		option = FrameLocatorOptions(options[0])
   784  	}
   785  	return p.mainFrame.Locator(selector, option)
   786  }
   787  

View as plain text