Thursday, 16 March 2017

How to post events in Node.js PhantomJS wrapper from page to Node?

I started off with this example from the wrapper repository.

const instance = await phantom.create();
const page = await instance.createPage();

To post an action from Node.js to PhantomJS - including emitting an event - I can do this:

await page.evaluate(function() {
     // Code
}

But how about the other way around. I want to listen on an event from the page in nodeJS. I wrote this promise to wait for an event:

class PageEventPromise extends Promise {
    constructor(page, event) {
        super(function(resolve, reject) {
            let callback = function() {
                let args = [];
                args.push.apply(args, arguments);
                page.off(event, callback);
                resolve(args);
            }
            page.on(event, callback);
        });
    }
}

I want to listen for DOM changes on particular element. I set up a MutationObserver in the webpage context:

await page.evaluate(function() {
    var observer = new MutationObserver(function(mutations) {
      mutations.forEach(function(mutation) {
         if(mutation.type != "childList")
             return;
         for (var i=0,l=mutation.addedNodes.length; i<l; i++)
         {
             const node = mutation.addedNodes[i];
             self.dispatchEvent(new Event("logEntry", {text: node.innerHTML}));
         }
      });    
    });
    var config = { attributes: !true, childList: true, characterData: !true };
    observer.observe(document.querySelector("div.ace_layer.ace_text-layer"), config);
});

Therefore this line:

self.dispatchEvent(new Event("logEntry", {text: node.innerHTML}));

does not trigger events assigned to page instance.

So if I assign arbitrary event:

page.on("eventName", function() {/* callback**/});

How do I trigger it from the webpage context?



via Tomáš Zato

No comments:

Post a Comment