New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add exposefunc feature #1222
base: master
Are you sure you want to change the base?
add exposefunc feature #1222
Conversation
Thank you! Can you add some tests for the new feature? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will take a careful look later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the second round. Please take a look. Thank you!
According to your suggestion, the implementation method has been modified.
Please review it again |
I'm sorry that it takes a little long to review. I just want to let you know that I'm still working on it. I'm confusing by this feature. IIUC, Do you have a real world use case to share? Thank you! |
@ZekeLu Yes, I think so, too.
Scenario 1, in order to ensure that the function must exist, it usually needs to be exposed before the page js is loaded. (AddScriptToEvaluateOnNewDocument) does this, but it needs to take effect after navigation. My business scenario is cloud Web game rendering.
The two most important points for this feature:
|
Thank you for the explanation! I'm not sure I understand it. But it seems that in the use cases, the js environment does not need the returned value from the Go environment. If this is the case, |
In my scenario, I don't need a return value and
I'm sorry that my example is not very accurate , more examples can search for puppeteer-related usage Finally, I think this feature is similar to JSBridge, a means of communication, but not necessary. |
I have put the suggested changes into this commit: ZekeLu@feef44e. The tests could be improved too, but I haven't touched it yet. Please take a look. If you agree with the suggested changes, please apply them to your commit. Please note that I'm still not sure whether this function is useful enough to be shipped by |
Thank you for the code optimization. It's more elegant.😊 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your hard work too!
I have added some more comments.
I think some of them are hard to address.
I'm inclined to convert this feature to an example and add it to https://github.com/chromedp/examples instead. If we provide it as an example, we don't have to address the reminding issues. And we can add it back to the package if someone find it useful and there are attracting use cases. What do you think?
expose.go
Outdated
// Note: | ||
// 1. This is the lite version of puppeteer's [page.exposeFunction]. | ||
// 2. It adds "chromedpExposeFunc" to the page's window object too. | ||
// 3. The exposed function survives page navigation until the tab is closed? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// 3. The exposed function survives page navigation until the tab is closed?
I think we have to answer this question.
There is not way to revert this action. I think we should mention this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, no way to revert this action.
`Runtime.removeBinding` does not remove binding function from global object
but unsubscribes current runtime agent from Runtime.bindingCalled notifications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not only the binding, but also the scripts that will be evaluated on new document (page.AddScriptToEvaluateOnNewDocument
). I know that we can store the ScriptIdentifier
and remove it later, but it will make the code complicated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It only takes effect on the page after navigation. The target(Page) hasn't changed. this kind of behavior should be understood
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most state does not survive page navigation. But the scripts that the expose action uses survive page navigation and there is no way to stop that (unless the tab is closed), so this behavior should be documented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get it.
expose the function to all frames
}) | ||
} | ||
|
||
func evaluateOnAllFrames(script string) Action { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ZekeLu expose the function to all frames. please check this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need a test case to cover it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test cases have been added and a bug has been fixed
fix closure bug && add exposeToAllFrames test case
modify note
) | ||
|
||
// ExposedFunc is the function type that can be exposed to the browser env. | ||
type ExposedFunc func(args string) (string, error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be more flexible if the args parameter was defined as an interface{} type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason for this design is that it is consistent with the cdp bindingCalled event parameter, which can only pass string.
Refer to Runtime.bindingCalled
https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#event-bindingCalled
PARAMETERS
name string
payload string
var payload struct {
Type string `json:"type"`
Name string `json:"name"`
Seq int64 `json:"seq"`
Args string `json:"args"`
}```
In some scenarios, need to bind go func to the browser environment. when js called, the function executes in go process and returns a Promise
refer https://pptr.dev/api/puppeteer.page.exposefunction/