Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
124
gaia/tests/atoms/accessibility.js
Executable file
124
gaia/tests/atoms/accessibility.js
Executable file
|
|
@ -0,0 +1,124 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
'use strict';
|
||||
|
||||
/* globals Components, marionetteScriptFinished */
|
||||
/* exported Accessibility */
|
||||
|
||||
var Accessibility = {
|
||||
|
||||
_accRetrieval: Components.classes[
|
||||
'@mozilla.org/accessibleRetrieval;1'].getService(
|
||||
Components.interfaces.nsIAccessibleRetrieval),
|
||||
|
||||
_getAccessible:
|
||||
function Accessibility__getAccessible(element, callback, once) {
|
||||
let attempts = 500;
|
||||
let intervalId = setInterval(() => {
|
||||
let acc = this._accRetrieval.getAccessibleFor(element);
|
||||
if (acc || --attempts <= 0 || once) {
|
||||
clearInterval(intervalId);
|
||||
if (attempts <= 0) {
|
||||
let tagName = element ? element.tagName : undefined;
|
||||
let elemId = element ? element.id : undefined;
|
||||
console.log('accessibility.js: failed to get accessible for tag=\"' +
|
||||
tagName + '\" id=\"' + elemId + '\"');
|
||||
}
|
||||
try {
|
||||
callback(acc);
|
||||
} catch (e) {
|
||||
marionetteScriptFinished({ error: e.message });
|
||||
}
|
||||
}
|
||||
}, 10);
|
||||
},
|
||||
|
||||
_matchState: function Accessibility__matchState(acc, stateName) {
|
||||
let stateToMatch = Components.interfaces.nsIAccessibleStates[stateName];
|
||||
let state = {};
|
||||
let extState = {};
|
||||
acc.getState(state, extState);
|
||||
return !!(state.value & stateToMatch);
|
||||
},
|
||||
|
||||
click: function Accessibility_click(element) {
|
||||
this._getAccessible(element.wrappedJSObject, function(acc) {
|
||||
acc.doAction(0);
|
||||
marionetteScriptFinished();
|
||||
});
|
||||
},
|
||||
|
||||
wheel: function Accessibility_wheel(element, direction) {
|
||||
let horizontal = direction === 'left' || direction === 'right';
|
||||
let page = (direction === 'left' || direction === 'up') ? 1 : -1;
|
||||
let event = new window.wrappedJSObject.WheelEvent('wheel', {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
deltaX: horizontal ? page : 0,
|
||||
deltaY: horizontal ? 0 : page,
|
||||
deltaMode: window.wrappedJSObject.WheelEvent.DOM_DELTA_PAGE,
|
||||
});
|
||||
element.wrappedJSObject.dispatchEvent(event);
|
||||
},
|
||||
|
||||
isDisabled: function Accessibility_isDisabled(element) {
|
||||
this._getAccessible(element.wrappedJSObject, (acc) => {
|
||||
marionetteScriptFinished(
|
||||
{ result: this._matchState(acc, 'STATE_UNAVAILABLE') });
|
||||
});
|
||||
},
|
||||
|
||||
_isAriaHidden: function Accessibility__isAriaHidden(element) {
|
||||
do {
|
||||
if (JSON.parse(element.getAttribute('aria-hidden'))) {
|
||||
return true;
|
||||
}
|
||||
element = element.parentNode;
|
||||
} while (element && element.getAttribute);
|
||||
},
|
||||
|
||||
isHidden: function Accessibility_isHidden(element) {
|
||||
let elem = element.wrappedJSObject;
|
||||
if (this._isAriaHidden(elem)) {
|
||||
marionetteScriptFinished({ result: true });
|
||||
return;
|
||||
}
|
||||
|
||||
this._getAccessible(elem, (acc) => {
|
||||
if (!acc) {
|
||||
marionetteScriptFinished({ result: true });
|
||||
return;
|
||||
}
|
||||
marionetteScriptFinished(
|
||||
{ result: this._matchState(acc, 'STATE_INVISIBLE') });
|
||||
}, true);
|
||||
},
|
||||
|
||||
isVisible: function Accessibility_isVisible(element) {
|
||||
let elem = element.wrappedJSObject;
|
||||
if (this._isAriaHidden(elem)) {
|
||||
marionetteScriptFinished({ result: false });
|
||||
return;
|
||||
}
|
||||
|
||||
this._getAccessible(elem, (acc) => {
|
||||
marionetteScriptFinished(
|
||||
{ result: !this._matchState(acc, 'STATE_INVISIBLE') });
|
||||
});
|
||||
},
|
||||
|
||||
getName: function Accessibility_getName(element) {
|
||||
this._getAccessible(element.wrappedJSObject, (acc) => {
|
||||
marionetteScriptFinished({ result: acc.name });
|
||||
});
|
||||
},
|
||||
|
||||
getRole: function Accessibility_getRole(element) {
|
||||
this._getAccessible(element.wrappedJSObject, (acc) => {
|
||||
marionetteScriptFinished(
|
||||
{ result: this._accRetrieval.getStringRole(acc.role) });
|
||||
});
|
||||
},
|
||||
};
|
||||
441
gaia/tests/atoms/gaia_apps.js
Executable file
441
gaia/tests/atoms/gaia_apps.js
Executable file
|
|
@ -0,0 +1,441 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
'use strict';
|
||||
/* globals marionetteScriptFinished, waitFor */
|
||||
|
||||
var GaiaApps = {
|
||||
|
||||
normalizeName: function(name) {
|
||||
return name.replace(/[- ]+/g, '').toLowerCase();
|
||||
},
|
||||
|
||||
getInstalledApps: function() {
|
||||
let req = navigator.mozApps.mgmt.getAll();
|
||||
req.onsuccess = function() {
|
||||
marionetteScriptFinished(req.result);
|
||||
};
|
||||
},
|
||||
|
||||
getRunningApps: function(includeSystemApps) {
|
||||
let runningApps = GaiaApps.getApps(includeSystemApps);
|
||||
// Return a simplified version of the runningApps object which can be
|
||||
// JSON-serialized.
|
||||
let apps = {};
|
||||
for (let app in runningApps) {
|
||||
let anApp = {};
|
||||
for (let key in runningApps[app]) {
|
||||
if (['name', 'origin', 'manifest'].indexOf(key) > -1) {
|
||||
anApp[key] = runningApps[app][key];
|
||||
}
|
||||
}
|
||||
apps[runningApps[app].origin] = anApp;
|
||||
}
|
||||
return apps;
|
||||
},
|
||||
|
||||
getApps: function(includeSystemApps) {
|
||||
let service = window.wrappedJSObject.Service;
|
||||
let apps = includeSystemApps ?
|
||||
service.query('getApps') :
|
||||
service.query('snapshot');
|
||||
return apps;
|
||||
},
|
||||
|
||||
getRunningAppOrigin: function(name) {
|
||||
let apps = GaiaApps.getApps(true);
|
||||
|
||||
for (let id in apps) {
|
||||
if (apps[id].name == name) {
|
||||
return apps[id].origin;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
|
||||
getPermission: function(appName, permissionName) {
|
||||
GaiaApps.locateWithName(appName, function(app) {
|
||||
console.log('Getting permission \'' +
|
||||
permissionName +
|
||||
'\' for ' +
|
||||
appName);
|
||||
var mozPerms = navigator.mozPermissionSettings;
|
||||
var result = mozPerms.get(
|
||||
permissionName, app.manifestURL, app.origin, false
|
||||
);
|
||||
marionetteScriptFinished(result);
|
||||
});
|
||||
},
|
||||
|
||||
setPermission: function(appName, permissionName, value) {
|
||||
GaiaApps.locateWithName(appName, function(app) {
|
||||
console.log('Setting permission \'' + permissionName + '\' for ' +
|
||||
appName + 'to \'' + value + '\'');
|
||||
var mozPerms = navigator.mozPermissionSettings;
|
||||
mozPerms.set(
|
||||
permissionName, value, app.manifestURL, app.origin, false
|
||||
);
|
||||
marionetteScriptFinished();
|
||||
});
|
||||
},
|
||||
|
||||
setPermissionByUrl: function(manifestUrl, permissionName, value, entryPoint) {
|
||||
GaiaApps.locateWithManifestURL(manifestUrl, entryPoint, function(app) {
|
||||
console.log('Setting permission \'' + permissionName + '\' for ' +
|
||||
manifestUrl + 'to \'' + value + '\'');
|
||||
var mozPerms = navigator.mozPermissionSettings;
|
||||
mozPerms.set(
|
||||
permissionName, value, app.manifestURL, app.origin, false
|
||||
);
|
||||
marionetteScriptFinished();
|
||||
});
|
||||
},
|
||||
|
||||
sendLocateResponse:
|
||||
function(aCallback, app, appName, launchPath, entryPoint) {
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
if (callback === marionetteScriptFinished) {
|
||||
var result = false;
|
||||
if (typeof(app) === 'object') {
|
||||
result = {
|
||||
name: app.manifest.name,
|
||||
origin: app.origin,
|
||||
entryPoint: entryPoint || null,
|
||||
normalizedName: appName
|
||||
};
|
||||
}
|
||||
callback(result);
|
||||
} else {
|
||||
callback(app, appName, launchPath, entryPoint);
|
||||
}
|
||||
},
|
||||
|
||||
locateWithName: function(name, aCallback) {
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
let apps = window.wrappedJSObject.applications ||
|
||||
window.wrappedJSObject.Applications;
|
||||
let installedApps = apps.installedApps;
|
||||
let normalizedSearchName = GaiaApps.normalizeName(name);
|
||||
|
||||
for (let manifestURL in installedApps) {
|
||||
let app = installedApps[manifestURL];
|
||||
let entryPoints = app.manifest.entry_points;
|
||||
if (entryPoints) {
|
||||
for (let ep in entryPoints) {
|
||||
let currentEntryPoint = entryPoints[ep];
|
||||
let appName = currentEntryPoint.name;
|
||||
let launchPath = currentEntryPoint.launch_path;
|
||||
let locales = currentEntryPoint.locales;
|
||||
|
||||
if (normalizedSearchName === GaiaApps.normalizeName(appName)) {
|
||||
return GaiaApps.sendLocateResponse(callback,
|
||||
app,
|
||||
appName,
|
||||
launchPath,
|
||||
ep);
|
||||
} else if (locales) {
|
||||
for (let id in locales) {
|
||||
let localisedAppName = locales[id].name;
|
||||
if (localisedAppName && normalizedSearchName ===
|
||||
GaiaApps.normalizeName(localisedAppName)) {
|
||||
return GaiaApps.sendLocateResponse(callback,
|
||||
app,
|
||||
appName,
|
||||
launchPath,
|
||||
ep);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let appName = app.manifest.name;
|
||||
let launchPath = app.manifest.launch_path;
|
||||
let locales = app.manifest.locales;
|
||||
|
||||
if (normalizedSearchName === GaiaApps.normalizeName(appName)) {
|
||||
return GaiaApps.sendLocateResponse(callback,
|
||||
app,
|
||||
appName,
|
||||
launchPath);
|
||||
} else if (locales) {
|
||||
for (let id in locales) {
|
||||
let localisedAppName = locales[id].name;
|
||||
if (localisedAppName && normalizedSearchName ===
|
||||
GaiaApps.normalizeName(localisedAppName)) {
|
||||
return GaiaApps.sendLocateResponse(callback,
|
||||
app,
|
||||
appName,
|
||||
launchPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
callback(false);
|
||||
},
|
||||
|
||||
locateWithManifestURL: function(manifestURL, entryPoint, aCallback) {
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
var apps = window.wrappedJSObject.applications ||
|
||||
window.wrappedJSObject.Applications;
|
||||
var app = apps.getByManifestURL(manifestURL);
|
||||
var launchPath;
|
||||
|
||||
if (app != null) {
|
||||
GaiaApps._formatApp(app, manifestURL, entryPoint, callback, launchPath);
|
||||
} else {
|
||||
callback(false);
|
||||
}
|
||||
},
|
||||
_formatApp: function(app, manifestURL, entryPoint, callback, launchPath) {
|
||||
if (entryPoint) {
|
||||
if (app.manifest.entry_points[entryPoint]) {
|
||||
launchPath = app.manifest.entry_points[entryPoint].launch_path;
|
||||
} else {
|
||||
app = null;
|
||||
}
|
||||
} else {
|
||||
launchPath = app.manifest.launch_path;
|
||||
}
|
||||
GaiaApps.sendLocateResponse(callback, app,
|
||||
manifestURL, launchPath, entryPoint);
|
||||
},
|
||||
|
||||
// Returns the number of running apps.
|
||||
// if includeSystemApps is true then system always-running
|
||||
// apps (eg Homescreen) will be counted
|
||||
numRunningApps: function(includeSystemApps) {
|
||||
return Object.keys(GaiaApps.getApps(includeSystemApps)).length;
|
||||
},
|
||||
|
||||
isRunning: function(origin) {
|
||||
var apps = GaiaApps.getApps(true);
|
||||
for (var id in apps) {
|
||||
if (apps[id].origin === origin) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
// Kills the specified app.
|
||||
kill: function(aOrigin, aCallback) {
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
if (!GaiaApps.isRunning(aOrigin)) {
|
||||
callback(false);
|
||||
}
|
||||
else {
|
||||
window.addEventListener('appterminated', function gt_onAppTerminated() {
|
||||
window.removeEventListener('appterminated', gt_onAppTerminated);
|
||||
waitFor(
|
||||
function() {
|
||||
console.log('app with origin \'' + aOrigin + '\' has terminated');
|
||||
callback(true);
|
||||
},
|
||||
function() {
|
||||
return !GaiaApps.isRunning(aOrigin);
|
||||
}
|
||||
);
|
||||
});
|
||||
console.log('terminating app with origin \'' + aOrigin + '\'');
|
||||
window.wrappedJSObject.Service.request('AppWindowManager:kill', aOrigin);
|
||||
}
|
||||
},
|
||||
|
||||
// Kills all running apps that may be killed by the user, defined as
|
||||
// being accessible by the Cards View/Stack Manager
|
||||
killAll: function() {
|
||||
let originsToClose = [];
|
||||
let that = this;
|
||||
|
||||
let apps = GaiaApps.getApps();
|
||||
for (let id in apps) {
|
||||
let origin = apps[id].origin;
|
||||
originsToClose.push(origin);
|
||||
}
|
||||
|
||||
if (!originsToClose.length) {
|
||||
marionetteScriptFinished(true);
|
||||
return;
|
||||
}
|
||||
|
||||
originsToClose.slice(0).forEach(function(origin) {
|
||||
GaiaApps.kill(origin, function() {});
|
||||
});
|
||||
|
||||
// Even after the 'appterminated' event has been fired for an app,
|
||||
// it can still exist in the apps list, so wait until 1 or fewer
|
||||
// apps are running (since we don't close the homescreen app).
|
||||
waitFor(
|
||||
function() { marionetteScriptFinished(true); },
|
||||
function() { return that.numRunningApps() <= 1; }
|
||||
);
|
||||
},
|
||||
|
||||
launch: function(app, appName, launchPath, entryPoint) {
|
||||
if (app) {
|
||||
let manifestURL = app.manifestURL;
|
||||
let origin = app.origin;
|
||||
|
||||
let sendResponse = function() {
|
||||
let result = GaiaApps.getDisplayedApp();
|
||||
marionetteScriptFinished(result);
|
||||
};
|
||||
|
||||
let displayedApp = GaiaApps.getDisplayedApp();
|
||||
if ((displayedApp.manifestURL == manifestURL &&
|
||||
displayedApp.entryPoint == entryPoint) ||
|
||||
(!displayedApp.manifestURL && displayedApp.origin == origin)) {
|
||||
console.log(`app with origin: ${displayedApp.origin} and
|
||||
manifestURL: ${displayedApp.manifestURL} and
|
||||
entryPoint: ${displayedApp.entryPoint} is already running`);
|
||||
sendResponse();
|
||||
} else {
|
||||
window.addEventListener('windowopened', function appOpen() {
|
||||
window.removeEventListener('windowopened', appOpen);
|
||||
waitFor(
|
||||
function() {
|
||||
console.log(`app with origin: ${displayedApp.origin} and
|
||||
manifestURL: ${displayedApp.manifestURL} and
|
||||
entryPoint: ${displayedApp.entryPoint} has launched`);
|
||||
sendResponse();
|
||||
},
|
||||
function() {
|
||||
// wait for the displayed app to have expected manifestURL/origin
|
||||
let displayedApp = GaiaApps.getDisplayedApp();
|
||||
if (displayedApp.manifestURL) {
|
||||
return displayedApp.manifestURL == manifestURL &&
|
||||
displayedApp.entryPoint == entryPoint;
|
||||
} else {
|
||||
return displayedApp.origin == origin;
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
console.log('launching app with name \'' + appName + '\'');
|
||||
app.launch(entryPoint || null);
|
||||
}
|
||||
} else {
|
||||
marionetteScriptFinished(false);
|
||||
}
|
||||
},
|
||||
|
||||
// Launches app with the specified name (e.g., 'Calculator'); returns the
|
||||
// an object with the app frame if successful, false if the app can't be
|
||||
// found, or times out if the app frame can't be found after launching the
|
||||
// app.
|
||||
launchWithName: function(name) {
|
||||
GaiaApps.locateWithName(name, this.launch.bind(this));
|
||||
},
|
||||
|
||||
// Launches app with the specified manifestURL. returns the
|
||||
// an object with the app frame if successful, false if the app can't be
|
||||
// found, or times out if the app frame can't be found after launching the
|
||||
// app.
|
||||
//
|
||||
// This is prefered over launchWithName because localized builds have
|
||||
// different names
|
||||
launchWithManifestURL: function(manifestURL, entryPoint) {
|
||||
GaiaApps.locateWithManifestURL(manifestURL, entryPoint, this.launch);
|
||||
},
|
||||
|
||||
close: function(app, appName, entryPoint) {
|
||||
if (app) {
|
||||
let origin = GaiaApps.getRunningAppOrigin(appName);
|
||||
GaiaApps.kill(origin);
|
||||
} else {
|
||||
marionetteScriptFinished(false);
|
||||
}
|
||||
},
|
||||
|
||||
// Closes app with the specified name (e.g., 'Calculator'); returns nothing
|
||||
closeWithName: function(name) {
|
||||
GaiaApps.locateWithName(name, this.close);
|
||||
},
|
||||
|
||||
closeWithManifestURL: function(manifestURL, entryPoint) {
|
||||
GaiaApps.locateWithManifestURL(manifestURL, entryPoint, this.close);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the currently displayed app.
|
||||
* This is more like getDisplayedFrame really,
|
||||
* as we return what frame the user is interacting with
|
||||
*/
|
||||
getDisplayedApp: function() {
|
||||
let app = window.wrappedJSObject.Service.query('getTopMostWindow');
|
||||
if (!app || app.isLockscreen) {
|
||||
// fallback to app window.
|
||||
app = window.wrappedJSObject.Service
|
||||
.query('AppWindowManager.getActiveWindow').getTopMostWindow();
|
||||
}
|
||||
|
||||
let currentEntryPoint = null;
|
||||
// When browser is on a website, app.manifest is null
|
||||
if (app.manifest) {
|
||||
let entryPoints = app.manifest.entry_points;
|
||||
if (entryPoints) {
|
||||
for (let ep in entryPoints) {
|
||||
if (entryPoints[ep].launch_path == app.manifest.launch_path) {
|
||||
currentEntryPoint = ep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let result = {
|
||||
frame: (app.browser) ? app.browser.element : app.frame.firstChild,
|
||||
src: (app.browser) ? app.browser.element.src : app.iframe.src,
|
||||
name: app.name,
|
||||
origin: app.origin,
|
||||
manifestURL: app.manifestURL,
|
||||
entryPoint: currentEntryPoint
|
||||
};
|
||||
return result;
|
||||
},
|
||||
/**
|
||||
* Install the app with the specified ManifestURL
|
||||
*/
|
||||
install: function(manifestURL) {
|
||||
let req = navigator.mozApps.install(manifestURL);
|
||||
req.onsuccess = function() {
|
||||
marionetteScriptFinished(true);
|
||||
};
|
||||
req.onerror = function() {
|
||||
marionetteScriptFinished(req.error);
|
||||
};
|
||||
},
|
||||
|
||||
installPackage: function(manifestURL) {
|
||||
let req = navigator.mozApps.installPackage(manifestURL);
|
||||
req.onsuccess = function() {
|
||||
marionetteScriptFinished(true);
|
||||
};
|
||||
req.onerror = function() {
|
||||
marionetteScriptFinished(req.error);
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Uninstall the app with the specified ManifestURL
|
||||
*/
|
||||
uninstall: function(manifestURL) {
|
||||
GaiaApps.locateWithManifestURL(manifestURL, null, function uninstall(app) {
|
||||
if (typeof(app) !== 'object') {
|
||||
// App is already not there, so nothing to do here
|
||||
marionetteScriptFinished(true);
|
||||
return;
|
||||
}
|
||||
|
||||
let req = navigator.mozApps.mgmt.uninstall(app);
|
||||
req.onsuccess = function() {
|
||||
marionetteScriptFinished(true);
|
||||
};
|
||||
req.onerror = function() {
|
||||
marionetteScriptFinished(req.error);
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
621
gaia/tests/atoms/gaia_data_layer.js
Executable file
621
gaia/tests/atoms/gaia_data_layer.js
Executable file
|
|
@ -0,0 +1,621 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
'use strict';
|
||||
/* global marionetteScriptFinished, pair, mozContact, i */
|
||||
/* global waitFor, aContacts */
|
||||
/* exported pair, discovery, GaiaDataLayer */
|
||||
/* jshint -W083 */
|
||||
|
||||
var GaiaDataLayer = {
|
||||
|
||||
getBluetoothDefaultAdapter: function() {
|
||||
var bluetooth = window.navigator.mozBluetooth;
|
||||
if (bluetooth.defaultAdapter) {
|
||||
return bluetooth.defaultAdapter;
|
||||
} else {
|
||||
return bluetooth.getAdapters()[0];
|
||||
}
|
||||
},
|
||||
|
||||
setBluetooth: function(aState) {
|
||||
var adapter = this.getBluetoothDefaultAdapter();
|
||||
|
||||
if (adapter.state == aState) {
|
||||
console.log('bluetooth already ' + aState);
|
||||
marionetteScriptFinished(true);
|
||||
return;
|
||||
}
|
||||
|
||||
waitFor(
|
||||
function() {
|
||||
console.log('bluetooth ' + aState);
|
||||
marionetteScriptFinished(true);
|
||||
},
|
||||
function() {
|
||||
console.log('bluetooth enable status: ' + adapter.state);
|
||||
|
||||
// Wait for the adapter state to become 'disabled' or 'enabled'
|
||||
if (adapter.state === 'disabling' || adapter.state === 'enabling') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (adapter.state != aState) {
|
||||
console.log('trying to make bluetooth ' + aState);
|
||||
if (aState === 'enabled') {
|
||||
adapter.enable();
|
||||
} else {
|
||||
adapter.disable();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return adapter.state === aState;
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
disableBluetooth: function() {
|
||||
this.setBluetooth('disabled');
|
||||
},
|
||||
|
||||
enableBluetooth: function() {
|
||||
this.setBluetooth('enabled');
|
||||
},
|
||||
|
||||
insertContact: function(aContact) {
|
||||
// requires the 'contacts-create' permission
|
||||
if (aContact.photo) {
|
||||
var blob = GaiaDataLayer.base64ToBlob(aContact.photo, 'image/jpg');
|
||||
aContact.photo = [blob];
|
||||
}
|
||||
|
||||
var contact = new mozContact(aContact);
|
||||
var req = window.navigator.mozContacts.save(contact);
|
||||
req.onsuccess = function() {
|
||||
console.log('success saving contact');
|
||||
marionetteScriptFinished(true);
|
||||
};
|
||||
req.onerror = function() {
|
||||
console.error('error saving contact', req.error.name);
|
||||
marionetteScriptFinished(false);
|
||||
};
|
||||
},
|
||||
|
||||
insertSIMContact: function(aType, aContact) {
|
||||
|
||||
// Get 1st SIM
|
||||
var iccId = window.navigator.mozIccManager.iccIds[0];
|
||||
var icc = window.navigator.mozIccManager.getIccById(iccId);
|
||||
|
||||
var simContact = new window.mozContact(aContact);
|
||||
if ('id' in aContact) {
|
||||
simContact.id = aContact.id;
|
||||
}
|
||||
|
||||
var req = icc.updateContact(aType, simContact);
|
||||
req.onsuccess = function() {
|
||||
console.log('success saving contact to SIM');
|
||||
marionetteScriptFinished(req.result);
|
||||
};
|
||||
req.onerror = function() {
|
||||
console.error('error saving contact to SIM', req.error.name);
|
||||
marionetteScriptFinished(false);
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
deleteSIMContact: function(aType, aId) {
|
||||
|
||||
// Get 1st SIM
|
||||
var iccId = window.navigator.mozIccManager.iccIds[0];
|
||||
var icc = window.navigator.mozIccManager.getIccById(iccId);
|
||||
|
||||
var aContact = new mozContact();
|
||||
aContact.id = aId;
|
||||
|
||||
var req = icc.updateContact(aType, aContact);
|
||||
req.onsuccess = function() {
|
||||
console.log('success removing contact from SIM');
|
||||
marionetteScriptFinished(true);
|
||||
};
|
||||
req.onerror = function() {
|
||||
console.error('error removing contact from SIM', req.error.name);
|
||||
marionetteScriptFinished(false);
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
getAllContacts: function(aCallback) {
|
||||
// requires 'contacts-read' permission
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
var req = window.navigator.mozContacts.find({});
|
||||
req.onsuccess = function() {
|
||||
console.log('success finding contacts');
|
||||
callback(req.result);
|
||||
};
|
||||
req.onerror = function() {
|
||||
console.error('error finding contacts ' + req.error.name);
|
||||
callback([]);
|
||||
};
|
||||
},
|
||||
|
||||
getSIMContacts: function(aType, aCallback) {
|
||||
var type = aType || 'adn';
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
var icc = navigator.mozIccManager;
|
||||
|
||||
// See bug 932134
|
||||
// To keep all tests passed while introducing multi-sim APIs, in bug 928325
|
||||
// we do the following check. Remove it after the APIs land.
|
||||
if (icc && icc.iccIds && icc.iccIds[0]) {
|
||||
icc = icc.getIccById(icc.iccIds[0]);
|
||||
}
|
||||
var req = icc.readContacts(type);
|
||||
req.onsuccess = function() {
|
||||
console.log('success finding ' + type + ' contacts');
|
||||
callback(req.result);
|
||||
};
|
||||
req.onerror = function() {
|
||||
console.error('error finding ' + type + ' contacts ' + req.error.name);
|
||||
callback([]);
|
||||
};
|
||||
},
|
||||
|
||||
removeAllContacts: function() {
|
||||
var self = this;
|
||||
this.getAllContacts(function(aContacts) {
|
||||
if (aContacts.length > 0) {
|
||||
var contactsLength = aContacts.length;
|
||||
var done = 0;
|
||||
for (var i = 0; i < contactsLength; i++) {
|
||||
self.removeContact(aContacts[i], function() {
|
||||
if (++done === contactsLength) {
|
||||
marionetteScriptFinished(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log('no contacts to remove');
|
||||
marionetteScriptFinished(true);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
removeContact: function(aContact, aCallback) {
|
||||
// requires the 'contacts-write' persmission
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
console.log('removing contact with id \'' + aContact.id + '\'');
|
||||
var req = window.navigator.mozContacts.remove(aContact);
|
||||
req.onsuccess = function() {
|
||||
console.log('success removing contact with id \'' + aContact.id + '\'');
|
||||
callback(true);
|
||||
};
|
||||
req.onerror = function() {
|
||||
console.error('error removing contact with id \'' +
|
||||
aContacts[i].id + '\'');
|
||||
callback(false);
|
||||
};
|
||||
},
|
||||
|
||||
getSetting: function(aName, aCallback) {
|
||||
// requires the 'settings-read' and 'settings-api-read' permissions
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
var req = window.navigator.mozSettings.createLock().get(aName);
|
||||
req.onsuccess = function() {
|
||||
console.log('setting retrieved');
|
||||
let result = aName === '*' ? req.result : req.result[aName];
|
||||
callback(result);
|
||||
};
|
||||
req.onerror = function() {
|
||||
console.log('error getting setting ' + req.error.name);
|
||||
};
|
||||
},
|
||||
|
||||
setSetting: function(aName, aValue, aReturnOnSuccess) {
|
||||
// requires the 'settings-write' and 'settings-api-write' permissions
|
||||
var returnOnSuccess = aReturnOnSuccess || aReturnOnSuccess === undefined;
|
||||
var setting = {};
|
||||
setting[aName] = aValue;
|
||||
console.log('setting ' + aName + ' to ' + aValue);
|
||||
var lock = window.navigator.mozSettings.createLock();
|
||||
var req = lock.set(setting);
|
||||
lock.onsettingstransactionsuccess = function() {
|
||||
console.log('setting changed');
|
||||
if (returnOnSuccess) {
|
||||
marionetteScriptFinished(true);
|
||||
}
|
||||
};
|
||||
lock.onsettingstransactionfailure = function() {
|
||||
console.log('error changing setting ' + req.error.name);
|
||||
marionetteScriptFinished(false);
|
||||
};
|
||||
},
|
||||
|
||||
connectToWiFi: function(aNetwork, aCallback) {
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
var manager = window.navigator.mozWifiManager;
|
||||
|
||||
if (this.isWiFiConnected(aNetwork)) {
|
||||
console.log('already connected to network with ssid \'' +
|
||||
aNetwork.ssid + '\'');
|
||||
callback(true);
|
||||
}
|
||||
else {
|
||||
var req;
|
||||
if (window.MozWifiNetwork === undefined) {
|
||||
req = manager.associate(aNetwork);
|
||||
} else {
|
||||
req = manager.associate(new window.MozWifiNetwork(aNetwork));
|
||||
}
|
||||
|
||||
req.onsuccess = function() {
|
||||
console.log('waiting for connection status \'connected\'');
|
||||
waitFor(
|
||||
function() {
|
||||
console.log('success connecting to network with ssid \'' +
|
||||
aNetwork.ssid + '\'');
|
||||
callback(true);
|
||||
},
|
||||
function() {
|
||||
console.log('connection status: ' + manager.connection.status);
|
||||
return manager.connection.status === 'connected';
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
req.onerror = function() {
|
||||
console.log('error connecting to network ' + req.error.name);
|
||||
callback(false);
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
disableWiFi: function() {
|
||||
var manager = window.navigator.mozWifiManager;
|
||||
if (manager.enabled) {
|
||||
waitFor(
|
||||
function() { marionetteScriptFinished(true); },
|
||||
function() {
|
||||
console.log('wifi enabled status: ' + manager.enabled);
|
||||
return manager.enabled === false;
|
||||
});
|
||||
this.setSetting('wifi.enabled', false, false);
|
||||
}
|
||||
else {
|
||||
console.log('wifi already disabled');
|
||||
marionetteScriptFinished(true);
|
||||
}
|
||||
},
|
||||
|
||||
enableWiFi: function() {
|
||||
var manager = window.navigator.mozWifiManager;
|
||||
if (!manager.enabled) {
|
||||
waitFor(
|
||||
function() { marionetteScriptFinished(true); },
|
||||
function() {
|
||||
console.log('wifi enabled status: ' + manager.enabled);
|
||||
return manager.enabled === true;
|
||||
});
|
||||
this.setSetting('wifi.enabled', true, false);
|
||||
}
|
||||
else {
|
||||
console.log('wifi already enabled');
|
||||
marionetteScriptFinished(true);
|
||||
}
|
||||
},
|
||||
|
||||
forgetAllNetworks: function(aCallback) {
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
var self = this;
|
||||
this.getKnownNetworks(function(aNetworks) {
|
||||
if (aNetworks.length > 0) {
|
||||
var networksLength = aNetworks.length;
|
||||
var done = 0;
|
||||
for (var i = 0; i < networksLength; i++) {
|
||||
self.forgetWiFi(aNetworks[i], function() {
|
||||
if (++done === networksLength) {
|
||||
callback(true);
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log('no known networks to forget');
|
||||
callback(true);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getKnownNetworks: function(aCallback) {
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
var manager = window.navigator.mozWifiManager;
|
||||
var req = manager.getKnownNetworks();
|
||||
|
||||
req.onsuccess = function() {
|
||||
console.log('success getting known networks');
|
||||
callback(req.result);
|
||||
};
|
||||
|
||||
req.onerror = function() {
|
||||
console.log('error getting known networks ' + req.error.name);
|
||||
callback([]);
|
||||
};
|
||||
},
|
||||
|
||||
forgetWiFi: function(aNetwork, aCallback, aWaitForStatus) {
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
var waitForStatus = aWaitForStatus || 'disconnected';
|
||||
var manager = window.navigator.mozWifiManager;
|
||||
var req = manager.forget(aNetwork);
|
||||
|
||||
req.onsuccess = function() {
|
||||
console.log('success forgetting network with ssid \'' +
|
||||
aNetwork.ssid + '\'');
|
||||
if (waitForStatus !== false) {
|
||||
console.log('waiting for connection status \'' +
|
||||
waitForStatus + '\'');
|
||||
waitFor(
|
||||
function() { callback(true); },
|
||||
function() {
|
||||
console.log('connection status: ' + manager.connection.status);
|
||||
return manager.connection.status === waitForStatus;
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
callback(true);
|
||||
}
|
||||
};
|
||||
|
||||
req.onerror = function() {
|
||||
console.log('error forgetting network with ssid \'' +
|
||||
aNetwork.ssid + '\' ' + req.error.name);
|
||||
callback(false);
|
||||
};
|
||||
},
|
||||
|
||||
isWiFiConnected: function(aNetwork) {
|
||||
let manager = window.navigator.mozWifiManager;
|
||||
let connected = manager.connection.status === 'connected';
|
||||
if (connected && aNetwork) {
|
||||
return manager.connection.network.ssid === aNetwork.ssid;
|
||||
} else {
|
||||
return connected;
|
||||
}
|
||||
},
|
||||
|
||||
getMozTelephonyState: function() {
|
||||
return window.navigator.mozTelephony.active.state;
|
||||
},
|
||||
|
||||
connectToCellData: function() {
|
||||
var manager = window.navigator.mozMobileConnections &&
|
||||
window.navigator.mozMobileConnections[0];
|
||||
|
||||
if (!manager.data.connected) {
|
||||
waitFor(
|
||||
function() {
|
||||
console.log('cell data enabled');
|
||||
marionetteScriptFinished(true);
|
||||
},
|
||||
function() { return manager.data.connected; }
|
||||
);
|
||||
this.setSetting('ril.data.enabled', true, false);
|
||||
}
|
||||
else {
|
||||
console.log('cell data already connected');
|
||||
marionetteScriptFinished(true);
|
||||
}
|
||||
},
|
||||
|
||||
disableCellData: function() {
|
||||
var self = this;
|
||||
this.getSetting('ril.data.enabled', function(aCellDataEnabled) {
|
||||
var manager = window.navigator.mozMobileConnections &&
|
||||
window.navigator.mozMobileConnections[0];
|
||||
|
||||
if (aCellDataEnabled) {
|
||||
waitFor(
|
||||
function() {
|
||||
console.log('cell data disabled');
|
||||
marionetteScriptFinished(true);
|
||||
},
|
||||
function() { return !manager.data.connected; }
|
||||
);
|
||||
self.setSetting('ril.data.enabled', false, false);
|
||||
}
|
||||
else {
|
||||
console.log('cell data already disabled');
|
||||
marionetteScriptFinished(true);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getAllPictures: function() {
|
||||
this.getFiles('pictures');
|
||||
},
|
||||
|
||||
getAllVideos: function() {
|
||||
this.getFiles('videos');
|
||||
},
|
||||
|
||||
getAllMusic: function() {
|
||||
this.getFiles('music');
|
||||
},
|
||||
|
||||
getAllSDCardFiles: function() {
|
||||
this.getFiles('sdcard');
|
||||
},
|
||||
|
||||
getFiles: function(aType, aCallback) {
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
var files = [];
|
||||
console.log('getting ' + aType);
|
||||
var storage = navigator.getDeviceStorage(aType);
|
||||
var req = storage.enumerate();
|
||||
req.onsuccess = function() {
|
||||
var file = req.result;
|
||||
if (file) {
|
||||
if (aType === 'music' && file.name.slice(-4) === '.3gp') {
|
||||
// 3gp is both music and video; we skip the music definition
|
||||
req.continue();
|
||||
}
|
||||
else {
|
||||
// File.name returns a fully qualified path
|
||||
files.push({'name': file.name, 'size': file.size});
|
||||
req.continue();
|
||||
}
|
||||
}
|
||||
else {
|
||||
callback(files);
|
||||
}
|
||||
};
|
||||
req.onerror = function() {
|
||||
console.error('failed to enumerate ' + aType + ' ' + req.error.name);
|
||||
callback(false);
|
||||
};
|
||||
},
|
||||
|
||||
sendSMS: function(recipient, content, skipVerification, aCallback) {
|
||||
// requires the 'sms' permission and the 'dom.sms.enabled' pref
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
console.log('sending sms message to number: ' + recipient);
|
||||
|
||||
let messageManager = window.navigator.mozMobileMessage;
|
||||
let request = messageManager.send(recipient, content);
|
||||
if (skipVerification) {
|
||||
marionetteScriptFinished(true);
|
||||
return;
|
||||
}
|
||||
|
||||
request.onsuccess = function(event) {
|
||||
var sms = event.target.result;
|
||||
|
||||
waitFor(
|
||||
function() { callback(true); },
|
||||
function() {
|
||||
console.log('sms delivery state: ' + sms.delivery);
|
||||
return sms.delivery === 'sent';
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
request.onerror = function() {
|
||||
console.log('sms message not sent');
|
||||
callback(false);
|
||||
};
|
||||
},
|
||||
|
||||
getAllSms: function(aCallback) {
|
||||
// requires the 'sms' permission and the 'dom.sms.enabled' pref
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
console.log('searching for sms messages');
|
||||
|
||||
let sms = window.navigator.mozMobileMessage;
|
||||
|
||||
let msgList = [];
|
||||
let cursor = sms.getMessages(null, false);
|
||||
|
||||
cursor.onsuccess = function(event) {
|
||||
if(cursor.result) {
|
||||
// Add the sms to the list
|
||||
msgList.push(cursor.result);
|
||||
// Now get the next in the list
|
||||
cursor.continue();
|
||||
}else{
|
||||
// Send back the list
|
||||
callback(msgList);
|
||||
}
|
||||
};
|
||||
|
||||
cursor.onerror = function(event) {
|
||||
console.log('sms.getMessages error: ' + event.target.error.name);
|
||||
callback(false);
|
||||
};
|
||||
},
|
||||
|
||||
deleteAllSms: function(aCallback) {
|
||||
// requires the 'sms' permission and the 'dom.sms.enabled' pref
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
console.log('searching for sms messages');
|
||||
|
||||
let sms = window.navigator.mozMobileMessage;
|
||||
|
||||
let msgList = [];
|
||||
let cursor = sms.getMessages(null, false);
|
||||
|
||||
cursor.onsuccess = function(event) {
|
||||
// Check if message was found
|
||||
if (cursor.result) {
|
||||
msgList.push(cursor.result.id);
|
||||
// Now get next message in the list
|
||||
cursor.continue();
|
||||
} else {
|
||||
// No (more) messages found
|
||||
if (msgList.length) {
|
||||
console.log('found ' + msgList.length + ' sms messages to delete');
|
||||
deleteSmsMsgs(msgList);
|
||||
} else {
|
||||
console.log('zero sms messages found');
|
||||
callback(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
cursor.onerror = function(event) {
|
||||
console.log('sms.getMessages error: ' + event.target.error.name);
|
||||
callback(false);
|
||||
};
|
||||
|
||||
function deleteSmsMsgs(msgList) {
|
||||
let smsId = msgList.shift();
|
||||
console.log('deleting sms id: ' + smsId);
|
||||
let request = sms.delete(smsId);
|
||||
|
||||
request.onsuccess = function(event) {
|
||||
if (event.target.result) {
|
||||
// Message deleted, continue until none are left
|
||||
if (msgList.length) {
|
||||
deleteSmsMsgs(msgList);
|
||||
} else {
|
||||
// All messages deleted
|
||||
console.log('finished deleting all sms messages');
|
||||
callback(true);
|
||||
}
|
||||
} else {
|
||||
console.log('sms delete failed');
|
||||
callback(false);
|
||||
}
|
||||
};
|
||||
|
||||
request.onerror = function(event) {
|
||||
console.log('sms.delete request returned unexpected error: ' +
|
||||
event.target.error.name);
|
||||
callback(false);
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
deleteAllAlarms: function() {
|
||||
window.wrappedJSObject.AlarmManager.getAlarmList(function(aList) {
|
||||
aList.forEach(function(aAlarm) {
|
||||
console.log('Deleting alarm with id \'' + aAlarm.id + '\'');
|
||||
window.wrappedJSObject.AlarmManager.delete(aAlarm);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
base64ToBlob: function(base64, mimeType) {
|
||||
var binary = atob(base64);
|
||||
var len = binary.length;
|
||||
var buffer = new ArrayBuffer(len);
|
||||
var view = new Uint8Array(buffer);
|
||||
for (var i = 0; i < len; i++) {
|
||||
view[i] = binary.charCodeAt(i);
|
||||
}
|
||||
return new Blob([view], {type: mimeType});
|
||||
}
|
||||
};
|
||||
57
gaia/tests/atoms/gaia_lock_screen.js
Executable file
57
gaia/tests/atoms/gaia_lock_screen.js
Executable file
|
|
@ -0,0 +1,57 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
'use strict';
|
||||
/* globals waitFor, finish */
|
||||
/* exported GaiaLockScreen */
|
||||
|
||||
var GaiaLockScreen = {
|
||||
|
||||
unlock: function(forcibly) {
|
||||
let setlock = window.wrappedJSObject.SettingsListener.getSettingsLock();
|
||||
let service = window.wrappedJSObject.Service;
|
||||
let obj = {'screen.timeout': 0};
|
||||
setlock.set(obj);
|
||||
|
||||
waitFor(
|
||||
function() {
|
||||
service.request('unlock', { forcibly: forcibly });
|
||||
waitFor(
|
||||
function() {
|
||||
finish(service.locked);
|
||||
},
|
||||
function() {
|
||||
return !service.locked;
|
||||
}
|
||||
);
|
||||
},
|
||||
function() {
|
||||
return !!service;
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
lock: function(forcibly) {
|
||||
let service = window.wrappedJSObject.Service;
|
||||
let setlock = window.wrappedJSObject.SettingsListener.getSettingsLock();
|
||||
let obj = {'screen.timeout': 0};
|
||||
setlock.set(obj);
|
||||
waitFor(
|
||||
function() {
|
||||
service.request('lock', { forcibly: forcibly });
|
||||
waitFor(
|
||||
function() {
|
||||
finish(!service.locked);
|
||||
},
|
||||
function() {
|
||||
return service.locked;
|
||||
}
|
||||
);
|
||||
},
|
||||
function() {
|
||||
return !!service;
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
37
gaia/tests/atoms/reflow.js
Executable file
37
gaia/tests/atoms/reflow.js
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
'use strict';
|
||||
|
||||
(function(exports) {
|
||||
if ('MozReflowAtom' in exports) {
|
||||
return;
|
||||
}
|
||||
|
||||
exports.MozReflowAtom = {
|
||||
count: null,
|
||||
_trackingManifest: null,
|
||||
|
||||
init: function rw_init() {
|
||||
exports.addEventListener('developer-hud-update', this);
|
||||
},
|
||||
|
||||
handleEvent: function rw_handleEvent(evt) {
|
||||
var metric = evt.detail.metric.name || evt.detail.metric;
|
||||
if (metric !== 'reflows' ||
|
||||
evt.detail.manifest !== this._trackingManifest) {
|
||||
return;
|
||||
}
|
||||
this.count++;
|
||||
},
|
||||
|
||||
startTracking: function(manifestURL) {
|
||||
this._trackingManifest = manifestURL;
|
||||
this.count = 0;
|
||||
},
|
||||
|
||||
stopTracking: function() {
|
||||
this.count = 0;
|
||||
this._trackingManifest = null;
|
||||
},
|
||||
};
|
||||
|
||||
exports.MozReflowAtom.init();
|
||||
})(window);
|
||||
15
gaia/tests/atoms/remote_date.js
Executable file
15
gaia/tests/atoms/remote_date.js
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
return (function(ms) {
|
||||
|
||||
var date = new Date();
|
||||
|
||||
return {
|
||||
year: date.getFullYear(),
|
||||
month: date.getMonth(),
|
||||
date: date.getDate(),
|
||||
hours: date.getHours(),
|
||||
minutes: date.getMinutes(),
|
||||
seconds: date.getSeconds()
|
||||
};
|
||||
|
||||
}.apply(this, arguments));
|
||||
|
||||
20
gaia/tests/atoms/screenshot.js
Executable file
20
gaia/tests/atoms/screenshot.js
Executable file
|
|
@ -0,0 +1,20 @@
|
|||
return (function takeScreenshot() {
|
||||
var canvas = document.createElementNS('http://www.w3.org/1999/xhtml',
|
||||
'canvas');
|
||||
var width = window.innerWidth;
|
||||
var height = window.innerHeight;
|
||||
canvas.setAttribute('width', width);
|
||||
canvas.setAttribute('height', height);
|
||||
|
||||
var context = canvas.getContext('2d');
|
||||
var flags =
|
||||
context.DRAWWINDOW_DRAW_CARET |
|
||||
context.DRAWWINDOW_DRAW_VIEW |
|
||||
context.DRAWWINDOW_USE_WIDGET_LAYERS;
|
||||
|
||||
context.drawWindow(window, 0, 0, width, height,
|
||||
'rgb(255,255,255)', flags);
|
||||
|
||||
return context.canvas.toDataURL('image/png');
|
||||
|
||||
}.apply(this, arguments));
|
||||
Loading…
Reference in a new issue