Skip to content
This repository has been archived by the owner on Aug 1, 2024. It is now read-only.

Adding support for calling back from phantom to node #55

Open
wants to merge 20 commits into
base: master
Choose a base branch
from

Conversation

reflectiz
Copy link

I want to be able to call from the phantom code to the node module.
The code added a function calls "nodeCallback" at the phantom side and property calls "onCallback" on the "page" object.

@reflectiz reflectiz changed the title Addin support for calling back from phantom to node Adding support for calling back from phantom to node Aug 21, 2016
@coveralls
Copy link

coveralls commented Aug 21, 2016

Coverage Status

Coverage decreased (-1.7%) to 98.328% when pulling 397b6f2 on ad-venture:master into 0aa95f8 on peerigon:master.

@coveralls
Copy link

coveralls commented Aug 26, 2016

Coverage Status

Coverage decreased (-1.7%) to 98.328% when pulling ff308e2 on ad-venture:master into 0aa95f8 on peerigon:master.

@jhnns
Copy link
Member

jhnns commented Aug 29, 2016

Thank you for your pull-request.

Can you describe a use-case where this nodeCallback is necessary and cannot be solved in other ways?

@reflectiz
Copy link
Author

reflectiz commented Aug 30, 2016

Hi jhnns

I've added this functionally because I needed to initiate an action base options for events triggered at the phantomjs client side code.
I'm using MutationObserver to monitor changes on the page, and when change occurs, the nodeJS server need to react.
I haven't found any other option in phridge current code.

Thanks
Ysrael

@jhnns
Copy link
Member

jhnns commented Sep 6, 2016

You're right. There is currently no way to achieve this.

However, there are some problems with your implementation. What happens if I have multiple instances of Page and I would like to install event listeners individually. We somehow need to have a record so that we now where "to call back".

For instance, we could have a third argument emit:

phantom.run(function (resolve, reject, emit) {
    setInterval(() => {
        emit("hi");
    }, 100);
    resolve();
});

somePage.run(function (resolve, reject, emit) {
    setInterval(() => {
        emit("hi");
    }, 100);
});

phantom.on("hi", function () { ... });
somePage.on("hi", function () { ... });

This way...

  • we don't have a "magical" nodeCallback variable in the upper scope
  • we can collate the callbacks to their respective instance in node

However, there might be another problem: When we're inside PhantomJS, we are not inside the actual page context. When using the evaluate function provided by PhantomJS, we're not allowed to access the scope either. Hence, this code will not work:

page.run(function (resolve, reject, emit) {
    this.evaluate(function () {
        // emit is not defined because we're in the actual page context now
        emit("hi");
    });
    resolve();
});

We would need to use the onCallback mechanism as described here:

page.run(function (resolve, reject, emit) {
    this.onCallback(function (message) {
        emit(message);
    });
    this.evaluate(function () {
        window.callPhantom('hi');
    });
    resolve();
});

This is very ugly – and again, we have the same problem that we need to collate callbacks from different sources...

I totally see the use-case and I wish, phridge would provide an easy API for this. But a proper implementation takes a lot of effort...

For instance, it would be cool to have a evaluate method on our page instance that mitigates all the cruft around it. This is probably what you would like to use:

page.evaluate(function (resolve, reject, emit) {
    var observer = new MutationObserver(function(mutations) {
      mutations.forEach(function(mutation) {
        emit("mutation", mutation.type);
      });    
    });

    observer.observe(document.body, {
      attributes: true,
      childList: true,
      characterData: true
    });
});

page.on("mutation", function (mutationType) {

});

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants