Phantomjs: How can PhantomJS take a JavaScript file and use it to drive the WebKit?

Created on 6 May 2016  路  5Comments  路  Source: ariya/phantomjs

Take the code from PhantomJS Quick Start for example:

var page = require('webpage').create();
page.open('http://example.com', function(status) {
  console.log("Status: " + status);
  if(status === "success") {
    page.render('example.png');
  }
  phantom.exit();
});

The JS code is about to open a new page. But how could PhantomJS do that? It can't evaluate it inside the browser(How can the browser take the JS code to open a new page or make a child process to call system command?). Does it interpret the JS first then call WebKit API? But I can't find the C code in PhantomJS for interpreting JavaScript...

So how could PhantomJS take the input JavaScript code to drive the WebKit?

PS:

I post it to programmers.stackexchange also, so you can answer my question there.

Most helpful comment

TL;DR: All JavaScript code runs inside the main execution context aka WebPage's object. This object represents a special running QWebPage object.

Let's start from beginning:
image

PhantomJS uses QtWebkit API to do the work. QtWebKit is a platform layer around WebKit. Because WebKit is an abstract platform. It doesn't know anything about your working environment (it doesn't know how or where to render the page and its content, it doesn't know how to process media elements, etc.)

But how it works under the hood? It's pretty simple:
image

Here is the workflow for hello.js:
1) Initialize QtWebkit and WebKit
2) Create the primary execution context - create a special QWebPage object. This object holds all our JavaScript API and the content of the script. They evaluated inside the global content of this web page.
3) By using the power of QtWebKit bridge, we can call the native code from JavaScript code. For example, when we have this line in the code var page = webpage.create(). It translated to a native call to our API.

All 5 comments

TL;DR: All JavaScript code runs inside the main execution context aka WebPage's object. This object represents a special running QWebPage object.

Let's start from beginning:
image

PhantomJS uses QtWebkit API to do the work. QtWebKit is a platform layer around WebKit. Because WebKit is an abstract platform. It doesn't know anything about your working environment (it doesn't know how or where to render the page and its content, it doesn't know how to process media elements, etc.)

But how it works under the hood? It's pretty simple:
image

Here is the workflow for hello.js:
1) Initialize QtWebkit and WebKit
2) Create the primary execution context - create a special QWebPage object. This object holds all our JavaScript API and the content of the script. They evaluated inside the global content of this web page.
3) By using the power of QtWebKit bridge, we can call the native code from JavaScript code. For example, when we have this line in the code var page = webpage.create(). It translated to a native call to our API.

@Vitallium A great thanks to your kind explanation. As you said:

var page = webpage.create(). It translated to a native call to our API.

I checked the source code in the webpage.cpp, and I only found a member function void WebPage::openUrl(const QString& address, const QVariant& op, const QVariantMap& settings). There is not a member function named open.

So what the C++ API JS page.open translated to?

We use the same approach as Node.js. Each native module has a JavaScript wrapper that injects into the main execution context (main WebPage)
So, for WebPage it will be: WebPage -> https://github.com/ariya/phantomjs/blob/master/src/modules/webpage.js

@Vitallium Thanks for your reply... These days I'm keep learning JS and read the source code of PhantomJS. Now I'm confused with the exports object. You can find it in every PhantomJS module but I found no where to define the exports object. Could give me some suggestion about the place where defined the exports object?

@Sayalic0 For learning module loading, check out Phantom::loadModule in src/phantomjs.cpp.

In all cases, it's better to continue the discussion in another forum, e.g. our mailing-list or discussion forum. We want to keep using this issue tracker to track defects and development tasks.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

simplegroupware picture simplegroupware  路  5Comments

Snowlav picture Snowlav  路  3Comments

maboiteaspam picture maboiteaspam  路  3Comments

mz3 picture mz3  路  5Comments

qaDream77 picture qaDream77  路  4Comments