Embedding Gecko in Python with custom Javascript bindings - javascript

Is it possible to embed Gecko in Python so that I can display HTML documents. And then possibly create custom Javascript bindings so that, I can call my own Javascript functions in the HTML document that will do some task that are not normally allowed in the browser, like making system calls. This will be done by the underlying python program.

There are a variety of ways to do this, actually. First, are you using another GUI library (e.g. wxPython, Tkinter, PyGTK, etc.) and you want to embed Gekco into a window that you create in one of those frameworks? i.e. Are you trying to embed a Gecko frame into a Tkinter (or wxPython, or PyGTK, or...) window?
Is using ONLY Gecko for the GUI a viable alternative? If so, you might want to take a look at XUL (and xulrunner). Gecko can interface with the outside world via XPCOM, and there is some integration of Python with XPCOM (see pythonext at Google Code). So, it's possible to write a mixed application where the UI elements are described in XUL with active javascript and signals are sent to/from the UI and your python code (which runs locally and can execute arbitrary system calls, etc.)
Along the same lines, but somewhat more straightforward, you can create a python script that launches a xulrunner app AND a locally running webserver. The xulrunner app hosts the GUI, along with active javascript code, while your locally running webserver executes arbitrary python code (including local system calls). I've used the ("batteries included") BaseHTTPServer many times to do something similar and I'm confident that you'll find it relatively straightforward to do so.

Related

Is it possible to design GUI with HTML+CSS+JavaScript but it will actually run python script?

I've built a very simple assistant app in python which can do very basic tasks like taking notes, reminding you, stopwatch, timer, web scrape for news feeds etc. tkinter seems confusing and looks oldish to me. On the other hand, css js seems much easier to design gui side and way more elegant looking. Is it possible to design a desktop gui app (may be with electron?) using HTML+CSS+JavaScript but it will run my old python codes?
I've been coding for only two months and i suck at it. Please excuse my newbiness.
TLDR: Simply, i want to make the gui side using HTML+CSS+JavaScript to take user input but then it will run python scripts and shows output in the gui app. Is it possible?
It can't be done, you'd have to make it like a web app (although with local webserver serving python responses)
EDIT:
if you don't mind running it in webbrowser, you can make quite easily webserver, that will evaluate your queries...
The popular form of Javascript or ES6 (which you are talking about) is designed to run in browser, so, the limitations are that it can only make calls via browser, i.e. it cannot directly interact with the OS like python's OS module. This means you will need a web-service in your computer that would run a specific python code and return you the responses, this requires a web-service/web-framework, preferably python's like Django, Flask which will run the python script for you because they can make OS calls on the server machine. I do think other non-python web-services are cacpable to do so, but of course, the natural preference would be 'Python-based services'.
Sidenote:
If the case was with Node.js(i.e. the server-side js) and not ES6(client-side browser-run) you would have an upperhand i.e. you could invoke python scripts on your server because node.js like the python-based web-servers do support os calls.
Kinda, but its real ugly. If you can host your data and whatnot the other approaches will work.
You have to build your project around nw.js. Essentially it is a Chromium build that adds local file system access back in. You can build an HTML+JS Front end and access a node.js backend running in the same thread. Via node you can shellout to call your python program, or run a local python web server.
I built a mapping app that allowed the user to select a local file, process it on the local machine with python and display the results in an interactive D3 app with geojson based layers of the UnitedStates. Since the data was proprietary I could not host it outside the company. Since I was not IT, I could not host it inside the company. nw.js allowed me to package everything into an installer and deploy to other people within the company as a standalone app.
See here for more information:
Official site: http://nwjs.io
Official documentation: http://docs.nwjs.io/
Introduction
NW.js is an app runtime based on Chromium and node.js. You can write native apps in HTML and JavaScript with NW.js. It also lets you call Node.js modules directly from the DOM and enables a new way of writing native applications with all Web technologies.
It was created in the Intel Open Source Technology Center.
Features
Apps written in modern HTML5, CSS3, JS and WebGL.
Complete supportfor Node.js APIs and all its third party modules.
Good performance: Node and WebKit run in the same thread: Function
calls are made straightforward; objects are in the same heap and
can just reference each other;
Easy to package and distribute apps. Available on Linux, Mac OS X
and Windows

Is Javascript the only choice for DOM interaction when embedding a web browser?

I've looked at the various ways to embed a web browser into an application (like IE or Safari via OS-specific means, or Firefox/Mozilla via XULRunner, or Chrome via the Chromium Embedded Framework) and I've managed to integrate CEF with my app up to a point where I'm convinced that it'll all work as expected. Now, it seems to me that whenever I want to modify the DOM (e.g. to add or remove elements), I'll have to do this via Javascript, i.e. my application calls out to Javascript where the actual work is done.
I wonder why this is so. My (naive?) belief is that if for example I call appendChild in Javascript, the actual "work" of appending a child will eventually be performed by a C/C++ function as the browser itself is written in C/C++ and not in Javascript. So, I'm wondering why in an embedded web browser I can't call this C/C++ function directly instead of going through Javascript. I understand that for general scripting you don't want other languages than Javascript for security reasons, but if the browser is embedded into an application I can control anyway this shouldn't be the reason, should it?
What am I missing?
CEF is implemented as a layer between chromium's content api and your application. When using CEF, Chromium is a library inside CEF, and you only have access to CEF's Public API, which is more or less restricted to whatever chromium content api leverages (keep in mind no browser was created as an embeddable plugin and then evolved into an application, it was always the other way around). The content API was the way google engineers had to formalize some forms of introspection, but they aren't completed simply because the browser isn't completely modular by itself. There's work in progress on chromium code to separate specific "do-it-all" components in more general ones that you may pick at will.
Therefore you can't simply hook into chromium's implementation details when using CEF: you'd need to patch it to implement something it doesn't expose by itself. CEF implements a class for DOM traversal (see here), but you can only pick at DOM, not change it.
That said, on the C++ side you can do some arbitrary stuff such as inspecting/mangling http requests (which allows you to inject javascript into pages, for instance), and running arbitrary javascript code straight from C++, which can, by it's own turn, asynchronously call back to C++ code by diverse paths (ajax -> http handling in C++, or V8 extensions which you can code straightly in C++.
See https://bitbucket.org/chromiumembedded/cef/wiki/JavaScriptIntegration for more details.
One could customize CEF or go straightly to chromium source code, but that thing is huge. Other solutions I heard of are more or less alike in terms of API limitations, i.e. Awesomium, Mozilla's Gecko, etc.

Calling C++ from JavaScript / HTML using GTK+ Webkit Webview (and Qt WebKit bridge)

I am currently evaluating different approaches / solutions to call C++ functions from JavaScript code embedded in an HTML page. The application must be run on Ubuntu Server 12.04 LTS.
I am not an expert in Linux based development. This is the first time I am trying to work on something to interface between JavaScript and C++ code.
The C++ code basically resides in the .so files ( dynamic libraries) that would provide interface methods to access certain hardware and file system. The GUI needs to be in HTML and I am searching for different solutions that are possible that can call C++ from HTML. I searched and ended up deciding to try 2 approaches, both using the WebKit engine.
Approach 1: Using Qt 5.0.2 Webkit Bridge - the WebView control
The GUI framework will be on Qt framework, the main application window will contain a webview control that would run an HTML code which in turn contains the JavaScript code.
The interface between Web page and C++ is done using the addToJavaScriptWindowObject() function.
I created a sample application and tested this solution and it seems to works fine.
Approach 2: Using GTK+ WebKit WebView
I downloaded and installed the GTK 3.0 library.
I got the webkitgtk 2.0.1 and have installed it.
I have created a test application with GTK without webkit, it works well.
I am trying to create a webkit webview control using GTK.
When trying my Approach 1 with Qt, there was quite a good set of documentation and samples to do what I wanted to. But after starting with Approach 2 using GTK+, I feel am moving slower comparitively. I personally feel that the documentation part is not that straight forward for the kind of application I am trying to develop.
Other Approaches:
I also want to try to check if either using Applets (to call the .so files directly) or using the V8 JavaScript engine to interface between JavaScript and C++ are viable options(https://code.google.com/p/v8/)
I have tried the following resources:
http://webkitgtk.org/
http://www.webkit.org/
https://live.gnome.org/WebKitGtk/ProgrammingGuide/Tutorial
I want to know how exactly to do this interface part of calling a C++ functions (in .so files) when a button is clicked in a HTML web page containing JavaScript. What kind of signal am I supposed to look for. If I am using a WebkitWebview control, how do I map a button click to a c++ function?
Can someone point me to the right direction?
I would really appreciate your time and knowledge.
Regards.
Webkit GTK 2 changed significantly in terms of API's. So I am not sure if this will work with Webkit GTK 2. However this will definitely work in Webkit GTK 1.* versions. Don't know anything about QT.
For your need of connecting html view with C/C++ side of the world, you can use two approaches. Please take a look at function webkit_dom_event_target_add_event_listener. There is example at https://live.gnome.org/WebKitGtk/ProgrammingGuide/Cookbook
Another approach you can take is to use alert on click of the button and send a string as information. On C side, you can hookup the alert listener and parse the message and decide what needs to be done. I have written lot of code in python which takes this approach since call mentioned above is not exposed to python.
I agree documentation is bit sparse for webkit gtk. However if you know how you can acomplish something in javascript, usually you can map the javascript DOM management and event calls to C side. This includes generating elements dynamically, managing events such onclick etc. You just have to dig through the header files and find matching call.
If you need to use C++ code or native applications in your web application you can try to create a service over the C++ code and access it throught a REST (for example) API.
You can use a common web application framework (Spring/Java, Django/Python, etc.) to develop your web application and use Apache Thrift to interface your library.
the best solution for you is g-xml it is a good solution by GAMA but sorry it is not free.

Separate JavaScript document talk to GWT Application

I have a JavaScript document which I've created with some complex functionality which relies on a couple third party JavaScript libraries being included.
My goal is to have it so that GWT can interact with my script and vice versa. I've tried to create a GWT wrapper which uses JSNI but had problems trying to get communication back from JavaScript (Embedded in my index.html - which is blank apart from the code to inject GWT) to my GWT application.
For my second attempt I've created a servlet on the GWT server side which I can communicate with via JSON although this looks like it will work it seems quite hacky having to rebuild many of the framework technologies which GWT has already fixed.
So my question is what's the easiest way to get two way communication from my JavaScript to GWT without the initial call coming from GWT (If possible)?

Why doesn't Node.js have a native DOM?

When I discovered that Node.js was built using the V8 JavaScript engine, I thought:
Great, web scraping will be easier as the page
will be rendered like in the browser, with a
"native" DOM supporting XPath and any AJAX calls on
the page executed.
Why doesn't it have a native DOM when it uses the same JavaScript engine as Chrome?
Why doesn't it have a mode to run JavaScript in retrieved pages?
What am I not understanding about JavaScript engines vs the engine in a web browser?
Many thanks!
The DOM is the DOM, and the JavaScript implementation is simply a separate entity. The DOM represents a set of facilities that a web browser exposes to the JavaScript environment. There's no requirement however that any particular JavaScript runtime will have any facilities exposed via the global object.
What Node.js is is a stand-alone JavaScript environment completely independent of a web browser. There's no intrinsic link between web browsers and JavaScript; the DOM is not part of the JavaScript language or specification or anything.
I use the old Rhino Java-based JavaScript implementation in my Java-based web server. That environment also has nothing at all to do with any DOM. It's my own application that's responsible for populating the global object with facilities to do what I need it to be able to do, and it's not a DOM.
Note that there are projects like jsdom if you want a virtual DOM in your Node project. Because of its very nature as a server-side platform, a DOM is a facility that Node can do without and still make perfect sense for a wide variety of server applications. That's not to say that a DOM might not be useful to some people, but it's just not in the same category of services as things like process control, I/O, networking, database interop, and so on.
There may be some "official" answer to the question "why?" out there, but it's basically just the business of those who maintain Node (the Node Foundation now). If some intrepid developer out there decides that Node should ship by default with a set of modules to support a virtual DOM, and successfully works and works and makes that happen, then Node will have a DOM.
P.S: When reading this question I was also wondering if V8 (node.js is built on top of this) had a DOM
Why when it uses the same JS engine as Chrome doesn't it have a native
DOM?
But I searched google and found Google's V8 page which recites the following:
JavaScript is most commonly used for client-side scripting in a
browser, being used to manipulate Document Object Model (DOM) objects
for example. The DOM is not, however, typically provided by the
JavaScript engine but instead by a browser. The same is true of
V8—Google Chrome provides the DOM. V8 does however provide all the
data types, operators, objects and functions specified in the ECMA
standard.
node.js uses V8 and not Google Chrome.
Likewise, why doesn't it have a mode to run JS in retrieved pages?
I also think we don't really need it that bad. Ryan Dahl created node.js as one man (single programmer). Maybe now he (his team) will develop this, but I was already extremely amazed by the amount of code he produced (crazy). He wanted to make a non-blocking easy/efficient library, which I think he did a mighty good job at.
But then again, another developer created a module which is pretty good and actively developed (today) at https://github.com/tmpvar/jsdom.
What am I not understanding about Javascript engines vs the engine in
a web browser? :)
Those are different things as is hopefully clear from the quote above.
The Document Object Model (DOM in short) is a programming interface for HTML and XML documents and it represents the page so that programs can change the document structure, style, and content. More on this subject.
The necessary distinction between client-side (browser) and server-side (Node.js) and their main goals:
Client-side: accessing and displaying information of the web
Server-side: providing stable and reliable ways to deliver web information
Why is there no DOM in Node.js be default?
By default, Node.js doesn't have access, nor have any knowledge about the actual DOM in your own browser. Node.js just delivers the data, that will be used by your own browser to process and render the whole website, the DOM included. The server provides the data to your browser to use and process. That is the intended way.
Why wouldn't you want to access the DOM in Node.js?
Accessing your browser's actual DOM using Node.js would be just simply out of the goal of the server. Your own browser's role is to display the data coming from the server. However it is certainly possible and there are multiple solutions in different level of depths and varieties to pre-render, manipulate or change the DOM using AJAX calls. We'll see what future trends will bring.
Why would you want to access the DOM in Node.js?
By default, you shouldn't access your own, actual DOM (at least some data of it) using Node.js. Client-side and server-side are separated in terms of role, functionality, and responsibility based on years of experience and knowledge. Although there are several situations, where there are solid reasons to do so:
Gathering usage data (A/B testing, UI/UX efficiency and feedback)
Headless testing (Development, automation, web-scraping)
How can you access the DOM in Node.js?
jsdom: pure-JavaScript implementation, good for testing your own DOM/browser-related project
cheerio: great solution if you like/often use jQuery
puppeteer: Google's own way to provide headless testing using Google Chrome
own solution (your possible future project link here)
Although these solutions do not provide a way to access your browser's own, actual DOM by default, but you can create a project to send some form of data about your DOM to the server, then use/render/manipulate that data based on your needs.
...and yes, web-scraping and web development in terms of tools and utilities became more sophisticated and certainly easier in several fields.
node.js chose not to include it in their standard library. For any functionality, there is an inevitable tradeoff between comprehensiveness, scalability, and maintainability.
That doesn't mean it's not potentially useful. There is at least one JavaScript DOM implementation intended for NodeJS (among other CommonJS implementations).
You seem to have a flawed assumption that V8 and the DOM are inextricably related, that's not the case. The DOM is actually handled by Webkit, V8 doesn't handle the DOM, it handles Javascript calls to the DOM. Don't let this discourage you, Node.js has carved out a significant niche in the realtime server market, but don't let anybody tell you it's just for servers. Node makes it possible to build almost anything with JavaScript.
It is possible to do what you're talking about. For example there is the very good jsdom library if you really need access to the DOM, and node-htmlparser, there are also some really good scraping libraries that take advantage of these like apricot.
2018 answer: mainly for historical reasons, but this may change in future.
Historically, very little DOM manipulation was done on the server. Addiotinally, as other answers allude, the JS stdlib and the DOM are seperate libraries - if you're using node, for, say, Unix scripting, then HTMLElement and NodeList etc aren't really relevant to that.
However: server-side DOM manipulation is now a very common part of delivering web apps. Web servers need to understand the structure of pages, and, if asked to render a resource as HTML, deliver HTML content that reflects the initial state of a web application. This means web apps load much faster than if the server simply delivers a stub page and has the browsers then do the work of filling in the real content. Currently this is done with JSDom and similar, but in the same way node has Request and Response objects built in, having DOM functions maintained as part of the stdlib would help with this task.
Javascript != browser. Javascript as a language is not tied to browsers; node.js is simply an implementation of Javascript that is intended for servers, not browsers. Hence no DOM.
If you read DOM as 'linked objects immediately accessible from my script' then the answer 'it does, but it's very different from set of objects available from web document script'. The main reason is that node is 'evented I/O for V8', not 'HTML tree objects for V8'
Node is a runtime environment, it does not render a DOM like a browser.
Because there isn't a DOM. DOM stands for Document Object Model. There is no document in Node, so not DOM to manipulate it. That is definitively a browser thing.
You can use a library like cheerio though which gives you some simple DOM manipulation.
Node is server-level JavaScript. It's just the language applied to a basic system API, more like C++ or Java.
It seems people have answered 'why' but not how. A quick answer of how is that in a web browser, a document object is exposed (hence DOM , document object model). On windows this object is called document object. You can refer to this page and look at the methods it exposes which are for handling HTML documents like createElement. I don't use node.js or haven't done COM programming in a while but I'd imagine you could use DOM in node.js by simply calling the COM object IHTMLDocument3. Of course for other platforms like Mac OS X or Linux you would probably have to use something from their OS api. This should allow you to easily build a webpage server side using DOM, or to scrape incoming web pages.
Node.js is for serverside programming. There is no DOM to be rendered in the server.
1) What does it mean for it to have a D ocument O bject M odel? There's no document to represent.
2) You're most of the time you're not retrieving pages. You can, but most Node apps probably won't be.
3) Without a document and a browser, Javascript is just another programming language. So you may ask why there isn't a DOM in C# or Java

Categories

Resources