How to use Oxide in your Ubuntu QML application
Oxide is a Qt5/QML binding based on the Chromium Content API, it's intended to replace qtwebkit for the touch browser, webapps and the UbuntuWebView.
So what does Oxide provide for developers ? It does provide a good chunk a usefull functions :
- Basic navigation
- Incognito mode
- Multiple browser contexts
- User scripts
- Message API
- Dialog support
- Accelerated compositing
WebView
Before you start make sure to add the webview
to your apparmor policy file, to declare a Webview using Oxide you need to use the WebView
component from com.canonical.Oxide
import com.canonical.Oxide 1.0
[...]
WebView {
id: webview
width: parent.width
height: parent.height
Component.onCompleted: {
url = "http://daker.me"
}
}
The WebView
comes with a preferences
property which allows to set a list of attributes :
- allowFileAccessFromFileUrls (bool)
- allowScriptsToCloseWindows (bool)
- allowUniversalAccessFromFileUrls (bool)
- appCacheEnabled (bool)
- canDisplayInsecureContent (bool)
- canRunInsecureContent (bool)
- caretBrowsingEnabled (bool)
- databasesEnabled (bool)
- defaultEncoding (QString)
- defaultFixedFontSize (uint)
- defaultFontSize (uint)
- fixedFontFamily (QString)
- hyperlinkAuditingEnabled (bool)
- javascriptCanAccessClipboard (bool)
- javascriptEnabled (bool)
- loadsImagesAutomatically (bool)
- localStorageEnabled (bool)
- minimumFontSize (uint)
- objectName (QString)
- passwordEchoEnabled (bool)
- remoteFontsEnabled(bool)
- sanSerifFontFamily (QString)
- serifFontFamily (QString)
- shrinksStandaloneImagesToFit (bool)
- standardFontFamily (QString)
- tabsToLinks (bool)
- textAreasAreResizable (bool)
- touchEnabled (bool)
Example
import com.canonical.Oxide 1.0
[...]
WebView {
id: webview
width: parent.width
height: parent.height
Component.onCompleted: {
url = "http://daker.me"
}
preferences.localStorageEnabled: true
preferences.loadsImagesAutomatically: false
preferences.passwordEchoEnabled: true
}
WebContext
Oxide also provides a WebContext
which allow to set other settings
- acceptLangs (QString)
- cachePath (QUrl)
- cookiePolicy (CookiePolicy)
- dataPath (QUrl)
- objectName (QString)
- popupBlockerEnabled (bool)
- product (QString)
- sessionCookieMode
- storageAccessPermissionDelegate
- userAgent (QString)
- userAgentOverrideDelegate
- userScripts
UserAgent
This example shows how you can use the WebContext
to override the default UserAgent
import com.canonical.Oxide 1.0
[...]
WebContext {
id: webcontext
userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3"
}
WebView {
id: webview
width: parent.width
height: parent.height
context: webcontext
Component.onCompleted: {
url = "http://www.whatsmyuseragent.com"
}
}
networkRequestDelegate
You can also override the http request headers by using the networkRequestDelegate
, in this example i am adding a Do Not Track (DNT) an HTTP header field on the fly.
import com.canonical.Oxide 1.0
[...]
WebContext {
id: webcontext
networkRequestDelegate: WebContextDelegateWorker {
source: Qt.resolvedUrl("dnt.js")
}
}
WebView {
id: webview
width: parent.width
height: parent.height
context: webcontext
Component.onCompleted: {
url = "http://www.browserleaks.com/donottrack"
}
}
/*
dnt.js
Made by Adnane Belmadiaf <daker AT ubuntu DOT com>
*/
exports.onBeforeSendHeaders = function(event) {
event.setHeader("DNT", 1);
};
UserScripts
Oxide supports Greasemonkey-style user scripts, here is an example to do some DOM manipulation.
import com.canonical.Oxide 1.0
[...]
WebContext {
id: webcontext
userScripts: [
UserScript {
context: "oxide://"
url: Qt.resolvedUrl("oxide_dom.js")
incognitoEnabled: true
matchAllFrames: true
}
]
}
WebView {
id: webview
width: parent.width
height: parent.height
context: webcontext
Component.onCompleted: {
url = "http://www.ubuntu.com/"
}
}
// ==UserScript==
// @name Dom Manipulation
// @namespace http://daker.me
// @description Oxide UserScript demo
// ==/UserScript==
function oxide_dom() {
var div = document.createElement('div');
div.innerHTML = '<h1>Content inserted using Oxide UserScript!</h1>';
div.style.color = 'red';
document.getElementById("nav-global").insertBefore(div);
}
window.addEventListener('load', oxide_dom, true);
Message API
Oxide does also provide a message API, in this example the script will send a message to Oxide and Oxide will reply back.
import com.canonical.Oxide 1.0
[...]
WebContext {
id: webcontext
networkRequestDelegate: WebContextDelegateWorker {
source: Qt.resolvedUrl("message-api.js")
onMessage: console.log("Message from Oxide : ", message.msg)
Component.onCompleted: {
sendMessage({ msg: 'ping' })
}
}
}
WebView {
id: webview
width: parent.width
height: parent.height
context: webcontext
Component.onCompleted: {
url = "http://www.ubuntu.com/"
}
}
/*
message-api.js
This script will send a message to Oxide on every request
*/
var response_msg = "";
oxide.onMessage = function(msg) {
if ("msg" in msg) {
if (msg["msg"] == 'ping') {
response_msg = "pong";
}
}
};
exports.onBeforeSendHeaders = function(event) {
oxide.sendMessage({msg: response_msg});
};