unity-chromium-extension-3.0.0+14.04.20140318/ 0000755 0000152 0177776 00000000000 12312132125 021104 5 ustar pbuser nogroup 0000000 0000000 unity-chromium-extension-3.0.0+14.04.20140318/ChangeLog 0000644 0000152 0177776 00000000000 12312131641 022646 0 ustar pbuser nogroup 0000000 0000000 unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/ 0000755 0000152 0177776 00000000000 12312132125 024741 5 ustar pbuser nogroup 0000000 0000000 unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/base-content-script.js 0000644 0000152 0177776 00000005614 12312131641 031173 0 ustar pbuser nogroup 0000000 0000000 /* Chromium Unity integration extension
*
* Copyright 2013 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3, as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranties of
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
**/
(function () {
var performContentScriptInitialization = function (loggerf) {
UnityContentScriptApi = {
getExtensionSettings: function (callback) {
chrome.runtime.sendMessage ({method: "get_extension_settings"}
, function (response) {
if (response && response.error) {
// TODO log
return;
}
callback (response);
});
},
};
//
// Initialize if needed
//
var initializeIntegrationScriptIfNeededForUrl = function (loggerf) {
var logger = loggerf || function (m) {};
// does the unity script injection + user script if necessary
logger ('Base content script, started on url: ' + document.URL);
var getUserScriptContent = function (url) {
var content = null;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
content = xhr.responseText;
}
};
// mmh blocking
xhr.open("GET", url, false);
try {
xhr.send();
} catch(e) {
logger ('Could not load user script content from: ' + url);
}
return content;
};
/**
* Injects a given javascript file in the current content script
*
* @param path path *in the current extension* of the required file
*/
var require = function (path) {
try {
eval.call (window, getUserScriptContent (chrome.runtime.getURL (path)));
}
catch (e) {
logger ('Failed to add required dependancy: ' + path + ', ' + e);
}
};
UnityContentScriptApi.getExtensionSettings (
function (settings) {
// Bail out if in incognito mode.
if (settings && settings.incognito) {
return;
}
require ("browser.js");
});
}; // initializeIntegrationScriptIfNeededForUrl
initializeIntegrationScriptIfNeededForUrl (loggerf);
}; // performContentScriptInitialization
// only do it for the top window, not the iframes
performContentScriptInitialization (
function (msg) {
if (top === self) {
console.log ("Content script: " + msg);
}
}
);
}
) ();
unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/background-page.js 0000644 0000152 0177776 00000042672 12312131641 030345 0 ustar pbuser nogroup 0000000 0000000 /* Chromium Unity integration extension
*
* Copyright 2012 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3, as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranties of
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
**/
var background_page = (function () {
// TODO extract based on logging settings
var log = {
info: function (msg) {
if (msg) {
console.log ('Info: ' + msg);
}
}
,
error: function (msg) {
if (msg) {
console.log ('Error: ' + msg);
}
}
};
// connection & init w/ plugin NPAPI layer
var plugin = document.getElementById ('unityChromiumExtensionId');
if ( ! plugin) {
log.error ("Unable to retrieve the Unity Chromium plugin");
return null;
}
var service = plugin.service_new ();
if (! service) {
log.error ("Unable to retrieve a connection to Unity Webapps service");
return null;
}
/////////////////////////////////////////////////////////
//
// Handle login & connection to online-accounts project's
// extension
//
////////////////////////////////////////////////////////
var loginListeners = [];
var onLoginListenerRequest = function (request, sender, sendResponse) {
if (request.action == "registerLoginListener") {
log.info ("Login listener request from " + sender.id);
loginListeners.push (sender.id);
}
};
chrome.runtime.onMessageExternal.addListener (onLoginListenerRequest);
var onLoginEvent = function (request, sender, sendResponse) {
if (request.action == "loginEvent") {
log.info ("Login on " + request.domain + ": " + request.login);
var len = loginListeners.length;
for (var i = 0; i < len; i++) {
var extensionId = loginListeners[i];
log.info("Notifying login listener: " + extensionId);
chrome.runtime.sendMessage (extensionId, {
type: "login",
login: request.login,
domain: request.domain
});
}
}
};
chrome.runtime.onMessage.addListener (onLoginEvent);
/////////////////////////////////////////////////////////
//
// Scafolding to keep track of data associated w/ infobar requests
// (Chromium's structure imposes some kind of state being maintained
// in order to communicate data)
//
////////////////////////////////////////////////////////
//
// list of callback that are to be called asynchronously
// per tab. Used in the user integration/installation resquests context.
//
// One thing to keep in mind is that one constraint, that bring some amount of
// 'soundness' is that there is a hard limit (provided by the browser) of one infobar per tab.
var user_infobar_request_callbacks = {};
var addInfobarRequestCallbackFor = function (infobarRequestId, callback, message, details) {
user_infobar_request_callbacks[infobarRequestId] = {callback: callback
, message: message
, details: details
};
};
var getDataIfAnyFor = function (infobarRequestId) {
if (user_infobar_request_callbacks[infobarRequestId] === undefined) {
return "";
}
return { message: user_infobar_request_callbacks[infobarRequestId].message,
details: user_infobar_request_callbacks[infobarRequestId].details };
};
var invokeAndRemoveCallbackIfAnyFor = function (infobarRequestId, arguments) {
if (user_infobar_request_callbacks[infobarRequestId] === undefined) {
return;
}
var callback = user_infobar_request_callbacks[infobarRequestId].callback;
user_infobar_request_callbacks[infobarRequestId] = undefined;
if (typeof(callback) === 'function') {
callback(arguments);
}
};
/////////////////////////////////////////////////////////
//
// Extract installed userscripts & webapps info
//
////////////////////////////////////////////////////////
var initializeIntegrationScriptRepositoryAccess = function (plugin) {
var repo = plugin.application_repository_new_default ();
plugin.application_repository_prepare (repo);
return repo;
};
var repo_ = initializeIntegrationScriptRepositoryAccess(plugin);
var repo_install_request_stamps = {};
/**
* Performs a match on the list of loaded integration scripts
* given a url.
*
*/
var matchesIntegrationScripts = function (plugin, url, repo, windowInfos, callback) {
function askForApplicationInstallation(plugin, appPackageName, appDomain, url, installationCallback) {
if (plugin.permissions_get_domain_dontask(appDomain)) {
log.info ("WebApp domain was found in the 'dont ask' list, won't install: " + appPackageName);
installationCallback ();
return;
}
if (repo_install_request_stamps[appPackageName] !== undefined) {
log.info ('WebApp not being considered for install (request is only issues once per session): ' + appPackageName);
installationCallback ();
return;
}
repo_install_request_stamps[appPackageName] = true;
function installApp() {
log.info ('Installing application: ' + appPackageName);
plugin.permissions_allow_domain(appDomain);
plugin.application_repository_install_application(repo, appPackageName, installationCallback, null);
}
function addToIgnoreList() {
plugin.permissions_dontask_domain(appDomain);
}
var isInstallationConfirmed = function (response) {
return response && response.integrate;
};
if (!plugin.permissions_get_domain_preauthorized(appDomain)) {
var appName = plugin.application_repository_get_resolved_application_name(repo, appPackageName);
addInfobarRequestCallbackFor (windowInfos.tabId,
function (result) {
log.info ('Asking for installation : ' + windowInfos.tabId);
if (result === undefined) {
installationCallback();
}
if (isInstallationConfirmed(result))
installApp();
else
addToIgnoreList();
},
chrome.i18n.getMessage("integration_copy", [appName, appDomain]),
null);
chrome.infobars.show ({tabId: windowInfos.tabId, path: "infobar.html"});
}
else {
plugin.permissions_allow_domain(appDomain);
installApp();
}
} // function askForApplicationInstallation
var APPLICATION_STATUS_AVAILABLE = 0;
var APPLICATION_STATUS_INSTALLED = 1;
var APPLICATION_STATUS_UNRESOLVED = 2;
var formatMatchedWebAppInfo = function (packageName, appName, appDomain, src) {
return {
packageName: packageName,
appName: appName,
appDomain: appDomain,
content: src,
requires: null,
includes: null
};
};
/**
* Gathers the lists of installed and (if any) available apps for a given list of app names
* (available for a given url).
*
* @returns object with "installed" and "available" list properties
*/
var gatherApplicationsStatuses = function (packageNames) {
var installed = [];
var available = [];
for (var i = 0; i < packageNames.length; ++i) {
var packageName = packageNames[i];
var status = plugin.application_repository_get_resolved_application_status (repo, packageName);
var appName = plugin.application_repository_get_resolved_application_name (repo, packageName);
var appDomain = plugin.application_repository_get_resolved_application_domain (repo, packageName);
log.info ('A WebApp application has been found: ' + appName + ', status: ' + status);
switch (status) {
case APPLICATION_STATUS_INSTALLED:
// we have found an installed application, use it directly
var src = plugin.application_repository_get_userscript_contents (repo, packageName);
installed.push (formatMatchedWebAppInfo(packageName, appName, appDomain, src));
break;
case APPLICATION_STATUS_AVAILABLE:
// we have found an application that can apply and be installed
available.push (formatMatchedWebAppInfo(packageName, appName, appDomain));
break;
}
}
return {
installed: installed,
available: available
};
};
var packageNames = JSON.parse(plugin.application_repository_resolve_url_as_json(repo_, url));
if (null != packageNames) {
var appStatuses = gatherApplicationsStatuses(packageNames);
if (appStatuses && appStatuses.installed && appStatuses.installed.length > 0) {
var app = appStatuses.installed[0];
if (repo_install_request_stamps[app.packageName] == undefined
&& ! plugin.permissions_get_domain_dontask(app.appDomain)
&& ! plugin.permissions_get_domain_allowed(app.appDomain)) {
// requesting for install
addInfobarRequestCallbackFor (windowInfos.tabId,
function (result) {
if (result && result.integrate) {
plugin.application_repository_add_desktop_to_launcher(app.appName, app.appDomain);
plugin.permissions_allow_domain(app.appDomain);
}
else {
plugin.permissions_dontask_domain(app.appDomain);
}
},
chrome.i18n.getMessage("integration_copy", [app.appName, app.appDomain]),
null);
chrome.infobars.show ({tabId: windowInfos.tabId, path: "infobar.html"});
}
return;
}
// we should have at most one script for a given app
if (appStatuses && appStatuses.available && appStatuses.available.length > 0) {
var app = appStatuses.available[0];
askForApplicationInstallation (plugin,
app.packageName,
app.appDomain,
url,
function (_repository, name, status, data) {
log.info ('Application installed: ' + name + ', (status ' + status + ')');
if (name !== undefined && status == APPLICATION_STATUS_INSTALLED) {
callback (true, app.packageName, app.appName, app.appDomain);
}
}
);
}
else
callback (false);
} // if (null != names) {
}; // var matchesIntegrationScripts = function (plugin, url, repo, windowInfos, callback) {
////////////////////////////////////////
//
// main request handler
//
///////////////////////////////////////
/**
* Handles & responds to content script requests.
*
*/
var init_requested_stamps = {};
var contentScriptsRequestHandler = function (request, sender, callback) {
var handlers = {
get_extension_settings: function (request, sender, callback) {
var settings = {
logging: false,
incognito: sender.tab.incognito
};
try {
if (window.localStorage) {
settings.logging = localStorage['logging'];
}
}
catch (e) {
log.error ("Error while trying to retrieve logging information: " + str(e));
}
callback (settings);
}
,
on_user_infobar_request_result: function (request, sender, callback) {
invokeAndRemoveCallbackIfAnyFor (request.tabId, request);
}
,
init_requested: function (request, sender, callback) {
var name = request.options.name;
var domain = request.options.domain;
var iconUrl = request.options.iconUrl + '';
var homepage = request.options.homepage || request.options.url;
if (! domain || ! name || typeof(domain) !== 'string' || typeof(name) !== 'string')
return;
var islocal = request.options.protocol && request.options.protocol === 'file:';
var host = request.options.hostname || request.options.host;
if ( ! islocal && (! host || typeof(host) !== 'string'))
return;
if (-1 === homepage.indexOf(domain) || -1 === host.indexOf(domain)) {
log.error('Invalid call to init(), homepage, domain and host are not consistent');
return;
}
log.info('init_requested() called for ' + name + ' domain: ' + domain);
if (plugin.permissions_get_domain_dontask(domain) || plugin.permissions_get_domain_allowed(domain)) {
log.info('Domain already listed in allow or dont ask lists');
return;
}
var stampname = name + domain;
if (init_requested_stamps[stampname] == undefined) {
addInfobarRequestCallbackFor (sender.tab.id,
function (result) {
if (result && result.integrate) {
plugin.application_repository_generate_desktop_for_url_launch(name, domain, homepage, iconUrl);
plugin.application_repository_add_desktop_to_launcher(name, domain);
plugin.permissions_allow_domain(domain);
}
else {
plugin.permissions_dontask_domain(domain);
}
},
chrome.i18n.getMessage("integration_copy", [name, domain]),
null);
init_requested_stamps[stampname] = true;
chrome.infobars.show ({tabId: sender.tab.id, path: "infobar.html"});
}
}
}; // handlers
// validate request
if ( ! request || ! request.method) {
callback ({error: "Invalid request structure"});
return true;
}
if ( ! sender) {
callback ({error: "Invalid sender"});
return true;
}
if ( typeof (request.method) != 'string' || request.method.length == 0) {
callback ({error: "Invalid request method"});
return true;
}
log.info ('Got request: ' + request.method);
var handler = handlers [request.method];
if (handler !== undefined && typeof(handler) == 'function') {
log.info ('Calling handler for: ' + request.method);
handler (request, sender, callback);
return true;
}
return false;
} // var contentScriptsRequestHandler =
// Main event handler and communication link
// w/ content scripts
chrome.runtime.onMessage.addListener (contentScriptsRequestHandler);
///////////////////////////////////////////////////////////////////////
//
// Window management related functions. In chromeless mode, we have specific
// rules for tab management to make webapps feel more "native" than plain
// web applications.
//
///////////////////////////////////////////////////////////////////////
var onTabChanged = function (tabId, windowId, url) {
var onInstalled = function (installed, packageName, appName, appDomain) { };
matchesIntegrationScripts (plugin,
url,
repo_,
{
windowId: windowId,
tabId: tabId
},
onInstalled
);
};
chrome.tabs.onCreated.addListener(
function(tab) {
if (tab && tab.url) {
onTabChanged(tab.id, tab.windowId, tab.url);
} // if (tab && tab.url) {
}
);
chrome.tabs.onUpdated.addListener (
function(tabId, changeInfo, tab) {
if (changeInfo && changeInfo.url) {
onTabChanged(tabId, tab.windowId, changeInfo.url);
}
}
);
return {
/*
* Returns a potential message associated with a tab id (infobar)
*/
getMessageForTabId: function (tabId) {
return getDataIfAnyFor (tabId).message;
}
};
}) ();
unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/infobar.html 0000644 0000152 0177776 00000000575 12312131641 027260 0 ustar pbuser nogroup 0000000 0000000
unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/unity-webapps.json.in 0000644 0000152 0177776 00000000104 12312131641 031045 0 ustar pbuser nogroup 0000000 0000000 {
"external_crx": "@EXTDIR@",
"external_version": "@VERSION@"
}
unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/manifest.json.in 0000644 0000152 0177776 00000002355 12312131641 030056 0 ustar pbuser nogroup 0000000 0000000 {
"name": "Unity WebApps Chromium extension",
"manifest_version": 2,
"minimum_chrome_version": "20.0",
"content_security_policy": "script-src 'self' chrome-extension://infobar.js 'unsafe-eval'; object-src 'self'",
"version": "@VERSION@",
"description": "Unity Webapps Chromium integration",
"web_accessible_resources": [
"browser.js",
"unity-api-page-proxy-builder-gen.js",
"unity-api-page-proxy.js",
"infobar.js",
"options.js"
],
"icons": {
"16": "skin/cof-16.png",
"48": "skin/cof-48.png"
},
"default_locale": "en",
"background": {
"page": "background-page.html"
},
"permissions": ["tabs", "http://*/*", "infobars"],
"options_page": "options.html",
"plugins": [
/** The "path" property specifies the path to your plugin, relative to the manifest file.
* The "public" property specifies whether your plugin can be accessed by regular web pages;
* the default is false, meaning only your extension can load the plugin.
*/
{ "path": "libunity_npapi_plugin.so", "public": false }
],
"content_scripts": [
{
"all_frames": true,
"matches": [ "" ],
"js": ["base-content-script.js"],
"run_at": "document_end"
}
]
}
unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/infobar.css 0000644 0000152 0177776 00000000532 12312131641 027075 0 ustar pbuser nogroup 0000000 0000000 body {
background: -webkit-linear-gradient(#E9E9E9, #DADADA);
font-family: Tahoma, Geneva, sans-serif;
font-size: 13px;
height: 36px; /* Infobars are limited to 36-72px */
margin: 0;
overflow: hidden;
padding-left: 6px;
padding-right: 6px;
padding-top: 5px;
}
img {
padding-right: 6px;
}
button {
padding-right: 10px;
}
unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/browser.js 0000644 0000152 0177776 00000012663 12312131641 026774 0 ustar pbuser nogroup 0000000 0000000 /**
* Handles all the related work to injecting the 'external' extension into the
* content script (well, more precisely the current environment), and the proxy
* responsbile for handling the API requests in a webapplication.
*
*/
(function (currentWindow) {
var aWindow = currentWindow;
var plugin = null;
var service = null;
var api = {
init: function (options) {
options.url = window.location.href;
options.hostname = window.location.hostname;
options.host = window.location.host;
options.protocol = window.location.protocol;
chrome.runtime.sendMessage (
{method: "init_requested", options: options}
, function (response) {});
}
};
/**
* Inserts a given script in the webpage.
* Needs chrome.extension functionality.
*
* @param path of file to be injected (part of the extension)
*/
var insertScriptIntoWebpage = function (path) {
var script = document.createElement ('script');
script.type = 'text/javascript';
script.src = chrome.runtime.getURL (path);
document.getElementsByTagName("head")[0].appendChild (script);
};
var injectApiProxy = function () {
// 1. inject a piece of javascript proxying all the requests
// to the unity webapps api
insertScriptIntoWebpage('unity-api-page-proxy-builder-gen.js');
insertScriptIntoWebpage('unity-api-page-proxy.js');
function makeWebpageCallback (id) {
// TODO/FIXME: add support for callback params (needed for DnD)
return function () {
var d = document.createElement ("textarea");
var e = document.createEvent ("Events");
d.style.cssText = "display:none;";
d.value = id;
d.addEventListener ("unity-webapps-chromium-api-com-link-callback-called-ack"
, function() { d.parentNode.removeChild (d); }
, true);
document.body.appendChild (d);
e.initEvent ("unity-webapps-chromium-api-com-link-callback-called", false, true);
d.dispatchEvent (e);
};
};
// TODO: should be shared / generated w/ web page code
var isIterableObject = function(obj) {
if (obj === undefined || obj === null) {
return false;
}
var t = typeof(obj);
var types = {'string': 0, 'function': 0, 'number': 0, 'undefined': 0, 'boolean': 0};
return types[t] === undefined;
};
/**
* Wraps callback ids in proper callback that dispatch to the
* webpage thru a proper event
*
*/
function wrapCallbackIds (obj) {
if ( ! isIterableObject(obj)) {
return obj;
}
if (obj
&& obj.hasOwnProperty('callbackid')
&& obj.callbackid != null) {
return makeWebpageCallback (obj.callbackid);
}
var ret = (obj instanceof Array) ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (isIterableObject (obj[key])) {
if (obj[key].callbackid != null) {
ret[key] = makeWebpageCallback (obj[key].callbackid);
}
else {
ret[key] = wrapCallbackIds (obj[key]);
}
}
else {
ret[key] = obj[key];
}
}
}
return ret;
};
// 2. open the communication mean between the two
// TODO has the implicit knowledge of who's behind ...
var dispatchActualFunctionCall = function (funcname, args) {
var funcnames = funcname.split('.');
var reducetarget = api;
// a bit hacky
try {
// Assumes that we are calling a 'callable' from a succession of objects
funcnames.reduce (
function (prev, cur) {
return typeof prev[cur] == "function" ? prev[cur].bind(prev) : prev[cur];
}, reducetarget).apply (null, args);
} catch (err) {
console.log ('Error while dispatching call to ' + funcnames.join('.') + ': ' + err);
}
};
document.addEventListener("unity-webapps-chromium-api-com-link"
, function(event) {
var from = event.target;
if (from) {
var type = from.getAttribute("data-eventType");
var args = JSON.parse(from.value);
args = args.map (function (arg) { return wrapCallbackIds (arg); });
// Actuall call, e.g. 'Notification.showNotification("a","b")
// being reduces to successive calls to associated objects:
// Notification, showNotification
//
// TODO add proper error handling
dispatchActualFunctionCall(type, args);
}
// send ack event to allow cleanup
var ret = document.createEvent('Events');
ret.initEvent('unity-webapps-chromium-api-com-link-ack', true, false);
from.dispatchEvent(ret);
}
, true);
};
// handle the proxy side of the api which is being injected on the
// webpage
injectApiProxy();
}
)(window);
unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/crxmake.sh 0000755 0000152 0177776 00000002411 12312131641 026732 0 ustar pbuser nogroup 0000000 0000000 #!/bin/bash -e
#
# Purpose: Pack a Chromium extension directory into crx format
if test $# -ne 2; then
echo "Usage: crxmake.sh "
exit 1
fi
dir=$1
key=$2
name=$(basename "$dir")
crx="$name.crx"
pub="$name.pub"
sig="$name.sig"
zip="$name.zip"
trap 'rm -f "$pub" "$sig" "$zip"' EXIT
# zip up the crx dir
cwd=$(pwd -P)
(cd "$dir" && zip -qr -9 -X "$cwd/$zip" .)
# signature
openssl sha1 -sha1 -binary -sign "$key" < "$zip" > "$sig"
# public key
openssl rsa -pubout -outform DER < "$key" > "$pub" 2>/dev/null
byte_swap () {
# Take "abcdefgh" and return it as "ghefcdab"
echo "${1:6:2}${1:4:2}${1:2:2}${1:0:2}"
}
crmagic_hex="4372 3234" # Cr24
version_hex="0200 0000" # 2
pub_len_hex=$(byte_swap $(printf '%08x\n' $(ls -l "$pub" | awk '{print $5}')))
sig_len_hex=$(byte_swap $(printf '%08x\n' $(ls -l "$sig" | awk '{print $5}')))
(
echo "$crmagic_hex $version_hex $pub_len_hex $sig_len_hex" | xxd -r -p
cat "$pub" "$sig" "$zip"
) > "$crx"
echo "Wrote $crx"
# Output files to package in subdir "res"
res="$cwd/res"
mkdir -p $res
echo "Result: $res"
cp -f $crx $res/
eid=`cat $key | openssl rsa -pubout -outform DER | openssl dgst -sha256 | awk '{print $2}' | cut -c 1-32 | tr '0-9a-f' 'a-p'`
echo "ID: $eid"
cp -f unity-webapps.json $res/$eid.json
unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/unity-api-page-proxy-builder-gen.js0000644 0000152 0177776 00000035700 12312131641 033511 0 ustar pbuser nogroup 0000000 0000000 var UnityWebappsApiPageProxyBuilder = function(backend) {
var dummy = true;
var unity = { context: dummy, contextReady: dummy };
var uwa = { ContextActionCallbackType: null };
var CallbackManager = {
makeCallback: function (dumd, func) {
return func;
}
};
function checkString(str, allowUndef) {
if (allowUndef && str == undefined) {
return;
}
if (!str || typeof(str) !== 'string') {
throw new TypeError("incorrect argument");
}
}
var findName = function (func, prefix, obj) {
if (!prefix) {
return findName(func, 'Unity.', api);
}
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
if (typeof(keys[i]) !== 'string') {
continue;
}
var descr = Object.getOwnPropertyDescriptor(obj, keys[i]);
if (descr.value === func) {
return prefix + keys[i];
}
if (descr.value instanceof Object) {
var res = findName(func, prefix + keys[i] + '.', obj[keys[i]]);
if (res)
return res;
}
if (obj.__lookupGetter__(keys[i]) === func) {
return prefix + keys[i];
}
if (obj.__lookupSetter__(keys[i]) === func) {
return prefix + keys[i];
}
}
return null;
};
var stringify = function (obj) {
if (obj === undefined)
return obj;
if (obj === null)
return obj;
if (typeof(obj) == 'string')
return obj;
if (typeof(obj) == 'number')
return obj;
if (typeof(obj) == 'function')
return String(obj);
var dump = {};
for (var i in obj) {
if (obj.hasOwnProperty(i))
dump[i] = stringify(obj[i]);
}
return dump;
};
var stringifyArgs = function (obj) {
var args = [];
for (var i = 0; i < obj.length; i++) {
args.push(stringify(obj[i]));
}
var res = JSON.stringify(args);
return res.substr(1, res.length - 2);
};
var createArgumentsSanitaizer = function (func, argsDesc, callback) {
return function () {
var realArgs = arguments;
var name = findName(arguments.callee);
var k = 0;
function argumentSanitaizer(desc, arg) {
if (!desc) {
throw new InternalError("argument description is null");
}
if (desc.dummy) {
k--;
return null;
}
if (desc.array) {
if (!(desc.array instanceof Object) || !(desc.array.element instanceof Object)) {
throw new InternalError("invalid argument description");
}
try {
for (var j = 0; j < arg.length; j++) {
argumentSanitaizer(desc.array.element, arg[j]);
}
} catch (x) {
throw new TypeError("incorrect argument");
}
return arg;
}
if (desc.obj) {
if (!(desc.obj instanceof Object)) {
throw new InternalError("invalid argument description");
}
var res = {}, i;
for (i in desc.obj) {
if (desc.obj.hasOwnProperty(i)) {
res[i] = argumentSanitaizer(desc.obj[i], arg[i]);
}
}
return res;
}
if (desc.str) {
if (desc.allowNull && !arg) {
return null;
}
checkString(arg, false);
return arg;
}
if (desc.number) {
if (typeof(arg) !== 'number' && typeof(arg) !== 'boolean')
throw new TypeError("incorrect argument");
return arg;
}
if (!desc.type) {
throw new InternalError("argument description miss required parameter");
}
if ((arg instanceof desc.type) || (desc.type === Function && ((typeof arg) === 'function'))
|| (arg === null && desc.allowNull)) {
if (desc.type === Function) {
if (!arg) {
return null;
}
var id;
if (desc.argAsCallbackId !== undefined) {
id = realArgs[desc.argAsCallbackId];
}
return CallbackManager.makeCallback(uwa.ContextActionCallbackType,
function (context, user_data) {
arg();
}, name, id);
}
return arg;
} else {
throw new TypeError("incorrect argument");
}
throw new InternalError("unreacheable");
}
var args = [unity.context], i;
for (i = 0; i < argsDesc.length; i++) {
if (k >= realArgs.length && k > 0 && !argsDesc[i].dummy) {
throw new Error("not enough arguments");
}
var value = argumentSanitaizer(argsDesc[i], realArgs[k]);
k++;
if (argsDesc[i].obj) {
args = args.concat(value);
} else {
args.push(value);
}
}
if (k < realArgs.length) {
throw new Error("too much arguments");
}
if (callback)
callback.apply(uwa, args);
if (func)
return Function.apply.apply(func, [uwa, args]);
return null;
};
};
var api = {
init: function(props) {
checkString(props.name, false);
checkString(props.iconUrl, true);
checkString(props.domain, true);
checkString(props.login, true);
checkString(props.mimeTypes, true);
checkString(props.homepage, true);
if (props.homepage && !/^(http|https|file):\/\//.test(props.homepage)) {
throw new TypeError("incorrect argument");
}
backend("init", [props]);
}
,
acceptData: createArgumentsSanitaizer(null,
[{ array: { element: { str: true } } }, { type: Function, js: true }],
function (context, mimeTypes, callback) {
backend('acceptData', [mimeTypes, callback]);
})
,
addAction: createArgumentsSanitaizer(null,
[{ str: true }, { type: Function, argAsCallbackId: 0 }],
function (context, name, callback) {
backend('addAction', [name, callback]);
})
,
clearAction: createArgumentsSanitaizer(null,
[{ str: true }]
, function (context, name) {
backend('clearAction', [name]);
})
,
clearActions: createArgumentsSanitaizer(null,
[],
function (context) {
backend('clearActions', []);
})
,
MediaPlayer: {
init: createArgumentsSanitaizer(null,
[{ str: true }],
function (context, name) {
backend('MediaPlayer.init', [name]);
})
,
onPlayPause: createArgumentsSanitaizer(null,
[{ type: Function, allowNull: true }, { dummy: true }],
function (context, callback) {
backend('MediaPlayer.onPlayPause', [callback]);
}
)
,
onPrevious: createArgumentsSanitaizer(null,
[{ type: Function, allowNull: true }, { dummy: true }],
function (context, callback) {
backend('MediaPlayer.onPrevious', [callback]);
})
,
onNext: createArgumentsSanitaizer(null,
[{ type: Function, allowNull: true }, { dummy: true }],
function (context, callback) {
backend('MediaPlayer.onNext', [callback]);
}
)
,
setTrack: createArgumentsSanitaizer(null,
[{ obj: { artist: { str: true, place: 0, allowNull: true },
album: { str: true, place: 1, allowNull: true },
title: { str: true, place: 2 },
artLocation: { str: true, place: 3, allowNull: true } } }],
function (context, trackinfos) {
backend('MediaPlayer.setTrack', [trackinfos]);
})
,
setCanGoNext: createArgumentsSanitaizer(null,
[{ number: true }],
function (context, v) {
backend('MediaPlayer.setCanGoNext', [v]);
}
)
,
setCanGoPrevious: createArgumentsSanitaizer(null,
[{ number: true }],
function (context, v) {
backend('MediaPlayer.setCanGoPrevious', [v]);
}
)
,
setCanPlay: createArgumentsSanitaizer(null,
[{ number: true }],
function (context, v) { backend('MediaPlayer.setCanPlay', [v]); }
)
,
setCanPause: createArgumentsSanitaizer(null,
[{ number: true }],
function (context, v) { backend('MediaPlayer.setCanPause', [v]); }
)
,
setPlaybackState: createArgumentsSanitaizer(null,
[{ number: true }],
function (context, v) { backend('MediaPlayer.setPlaybackState', [v]); }
)
,
getPlaybackState: createArgumentsSanitaizer(null
, [{ type: Function }]
, function (context, callback) {
backend('MediaPlayer.getPlaybackState', [callback]);
}
)
,
PlaybackState: {PLAYING: 0, PAUSED:1}
},
Notification: {
showNotification: createArgumentsSanitaizer(null,
[{ str: true }, { str: true }, { str: true, allowNull: true }],
function (context, title, name, dummy) {
backend('Notification.showNotification', [title, name, dummy]);
}
)
},
Launcher: {
setCount: createArgumentsSanitaizer(null,
[{ number: true }],
function (context, count) {
backend('Launcher.setCount', [count]);
}
)
,
clearCount: createArgumentsSanitaizer(null,
[],
function (context) {
backend('Launcher.clearCount', []);
}),
setProgress: createArgumentsSanitaizer(null,
[{ number: true }],
function (context, progress) {
backend('Launcher.setProgress', [progress]);
}
)
,
clearProgress: createArgumentsSanitaizer(null,
[],
function (context) {
backend('Launcher.clearProgress', []);
}
)
,
setUrgent: createArgumentsSanitaizer(null,
[],
function (context) {
backend('Launcher.setUrgent', []);
}
)
,
addAction: function(arg1, arg2) {
backend('Launcher.addAction', [arg1, arg2]);
}
,
removeAction: createArgumentsSanitaizer(null,
[{ str: true }],
function (context, name) {
backend('Launcher.removeAction', [name]);
}
)
,
removeActions: createArgumentsSanitaizer(null,
[],
function (context) {
backend('Launcher.removeActions', []);
}
)
},
MessagingIndicator: {
addAction: createArgumentsSanitaizer(null,
[{ str: true }, { type: Function, argAsCallbackId: 0 }, { dummy: true }],
function (context, name, callback, dummy) {
backend('MessagingIndicator.addAction', [name, callback, dummy]);
}
)
,
showIndicator: function(name, properties) {
backend('MessagingIndicator.showIndicator', [name, properties]);
}
,
clearIndicator: createArgumentsSanitaizer(null, [{ str: true }], function(context, name) { backend('MessagingIndicator.clearIndicator', [name]); }),
clearIndicators: createArgumentsSanitaizer(null, [], function (context) { backend('MessagingIndicator.clearIndicators', []); })
}
};
return api;
};
unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/options.html 0000644 0000152 0177776 00000001522 12312131641 027324 0 ustar pbuser nogroup 0000000 0000000
Unity Webapps Options
Unity Webapps Integration Extension
Enable extension logging:
unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/background-page.html 0000644 0000152 0177776 00000000430 12312131641 030657 0 ustar pbuser nogroup 0000000 0000000
Unity Webapps Extension Background Page
unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/options.js 0000644 0000152 0177776 00000001155 12312131641 026776 0 ustar pbuser nogroup 0000000 0000000 function save_options() {
var logging = document.getElementById("logging");
localStorage["logging"] = logging.checked;
}
function restore_options() {
if ( ! window.localStorage) {
alert ("Please enable local storage in order to access options");
document.getElementById('logging').disabled = true;
return;
}
var logging = localStorage["logging"];
var loggingElt = document.getElementById("logging");
if (loggingElt) {
loggingElt.checked = (logging == "true");
}
}
window.onload = function () {
restore_options();
document.getElementById('logging').onclick = save_options;
};
unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/Makefile.am 0000644 0000152 0177776 00000002102 12312131641 026772 0 ustar pbuser nogroup 0000000 0000000 CLEANFILES = res/*
EXTRA_DIST =
extensiondir = $(libdir)/libunity-chromium
extension_DATA=res/unity-webapps.crx
clean-extension-package:
rm -f $(CLEANFILES)
SCRIPT_FILES = \
$(shell ls *.css) \
$(shell ls *.html) \
$(shell ls *.js) \
$(shell ls skin/*) \
$(shell ls _locales/*/*)
res/unity-webapps.crx: $(SCRIPT_FILES) unity-webapps.json manifest.json
cp -f $(top_builddir)/npapi-plugin/src/.libs/libunity_npapi_plugin.so .
if [ ! -f ../unity-webapps.pem ]; \
then \
openssl genrsa 1024 > ../unity-webapps.pem; \
fi
$(srcdir)/crxmake.sh $(abs_builddir) ../unity-webapps.pem
mv res/chromium-extension.crx res/unity-webapps.crx
manifestdir = $(datadir)/chromium/extensions/
manifest_DATA = $(shell ls $(top_builddir)/chromium-extension/res/*.json)
%.json: %.json.in
sed -e "s|\@EXTDIR\@|$(extensiondir)/unity-webapps.crx|" $< | sed -e "s|\@VERSION\@|$(VERSION)|"> $@
CLEANFILES += \
unity-webapps.json \
manifest.json \
libunity_npapi_plugin.so \
chromium-extension.crx
EXTRA_DIST += \
unity-webapps.json.in \
manifest.json.in \
crxmake.sh \
$(SCRIPT_FILES)
unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/infobar.js 0000644 0000152 0177776 00000001663 12312131641 026727 0 ustar pbuser nogroup 0000000 0000000 var doIntegrate = function (integrate) {
chrome.tabs.getCurrent (function (tab) {
chrome.runtime.sendMessage ({tabId: tab.id, method: "on_user_infobar_request_result", integrate: integrate}
, function (response) {});
window.close();
});
};
window.onload = function () {
chrome.runtime.getBackgroundPage(function (bg) {
document.getElementById('notintegrate').onclick = function () { doIntegrate(false); };
document.getElementById('integrate').onclick = function () { doIntegrate(true); };
chrome.tabs.getCurrent (function (tab) {
if (!bg|| !bg.background_page) {
window.close();
return;
}
var msg = bg.background_page.getMessageForTabId(tab.id);
if (msg == null) {
window.close();
return;
}
document.getElementById ('content').style.display = "block";
document.getElementById ('message').innerHTML = msg || "";
});
});
};
unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/build.sh 0000755 0000152 0177776 00000001002 12312131641 026372 0 ustar pbuser nogroup 0000000 0000000 #!/bin/bash -e
CRX_FILENAME=`pwd`/../chromium-extension.crx
PEM_FILENAME=`pwd`/../chromium-extension.pem
if [ -e "$CRX_FILENAME" ]
then
rm -f "$CRX_FILENAME"
fi
#if [ -e "$PEM_FILENAME" ]
#then
# rm -f "$PEM_FILENAME"
#fi
if test -n "`which google-chrome`"; then
google-chrome --no-message-box --pack-extension=`pwd` --pack-extension-key=../chromium-extension.pem
else
chromium-browser --no-message-box --pack-extension=`pwd`
fi
# not necessary
# mv `pwd`/../unity-chromium-extension.crx .
unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/skin/ 0000755 0000152 0177776 00000000000 12312132125 025705 5 ustar pbuser nogroup 0000000 0000000 unity-chromium-extension-3.0.0+14.04.20140318/chromium-extension/skin/cof-48.png 0000644 0000152 0177776 00000005451 12312131641 027422 0 ustar pbuser nogroup 0000000 0000000 PNG
IHDR 0 0 W sRGB bKGD pHYs tIME
n tEXtComment Created with GIMPW
IDAThyp?ow%ٖزqrpSP(L
v @nsJi(w)W8`ZBIpt t`
HXrHeIHZ_Rb;3{iW *Uu/Vd$ HT]/A)PЖ-cdUBDfj #RUA U""_KkW 2:T\R*CUTQYZ
h ,YbYeVTPT%-6WZ+
c pwYU6Y@XUDe|'OTu jiZU^J2Fqb=UQ!~lh<a*"/rL7=Iu!-'n\B$PT2~$oZR_8}T]e_8*_8'w[BQqymsV` 6P;`G8=qb=h2= bUWZCmb,A5#Qj0-
?⟞oXU"LcJtՋ#;itw)#B>p&iK>8E0#>gySvƕL8MY3qz9+e WnZU w⛾?vWVEt:,?`qhј'