зеркало из https://github.com/mozilla/pluotsorbet.git
756 строки
22 KiB
JavaScript
756 строки
22 KiB
JavaScript
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* Pre-load dependencies and then load the main page.
|
|
*/
|
|
(function() {
|
|
var loadingPromises = [];
|
|
if (config.midletClassName == "RunTests") {
|
|
loadingPromises.push(loadScript("tests/contacts.js"),
|
|
loadScript("tests/index.js"),
|
|
loadScript("tests/mozactivitymock.js"));
|
|
}
|
|
|
|
if (navigator.userAgent.indexOf('Chrome') > -1) {
|
|
loadingPromises.push(loadScript("polyfill/chrome_polyfills.js"));
|
|
}
|
|
|
|
Promise.all(loadingPromises).then(function() {
|
|
document.getElementById("mozbrowser").src = "main.html" + location.search;
|
|
});
|
|
})();
|
|
|
|
var childOrigin = document.location.origin;
|
|
document.getElementById("mozbrowser").addEventListener("mozbrowserlocationchange", function(event) {
|
|
childOrigin = new URL(event.detail).origin;
|
|
var parentOrigin = document.location.origin;
|
|
if (childOrigin !== parentOrigin) {
|
|
console.warn("on location change: child origin " + childOrigin + " !== parent origin " + parentOrigin);
|
|
}
|
|
});
|
|
|
|
var DumbPipe = {
|
|
// Functions that handle requests to open a pipe, indexed by type.
|
|
openers: {},
|
|
|
|
// Functions that receive messages from the other side for active pipes.
|
|
recipients: {},
|
|
|
|
// Every time we want to make the other side retrieve messages, the hash
|
|
// of the other side's web page has to change, so we increment it.
|
|
nextHashID: 0,
|
|
|
|
registerOpener: function(type, opener) {
|
|
this.openers[type] = opener;
|
|
},
|
|
|
|
handleEvent: function(event) {
|
|
var parentOrigin = document.location.origin;
|
|
if (childOrigin !== parentOrigin) {
|
|
console.error("on show modal prompt: child origin " + childOrigin + " !== parent origin " + parentOrigin);
|
|
return;
|
|
}
|
|
|
|
window.setZeroTimeout(this.handlePipeEvent.bind(this, event));
|
|
},
|
|
|
|
handlePipeEvent: function(event) {
|
|
if (event.detail.promptType == "custom-prompt") {
|
|
console.warn("unresponsive script warning; figure out how to handle");
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* We embed messages in the mozbrowsershowmodalprompt event's detail.message
|
|
* property. The value of that property is a JSON string representing
|
|
* the message envelope, whose inner "message" property contains the actual
|
|
* message.
|
|
*
|
|
* @property command {String} the command to invoke: open|message|get|close
|
|
* @property type {String} the type of pipe to open (when command == open)
|
|
* @property pipeID {Number} unique ID (when command == open|message|close)
|
|
* @property message {String} the JSON message to forward to this side
|
|
*/
|
|
var envelope = JSON.parse(event.detail.message);
|
|
|
|
switch (envelope.command) {
|
|
case "open":
|
|
//console.log("outer recv: " + JSON.stringify(envelope));
|
|
this.openPipe(envelope.pipeID, envelope.type, envelope.message);
|
|
break;
|
|
case "message":
|
|
//console.log("outer recv: " + JSON.stringify(envelope));
|
|
this.receiveMessage(envelope.pipeID, envelope.message);
|
|
break;
|
|
case "close":
|
|
//console.log("outer recv: " + JSON.stringify(envelope));
|
|
this.closePipe(envelope.pipeID);
|
|
break;
|
|
}
|
|
},
|
|
|
|
openPipe: function(pipeID, type, message) {
|
|
var opener = this.openers[type];
|
|
|
|
if (!opener) {
|
|
console.error("no opener for pipe type " + type);
|
|
return;
|
|
}
|
|
|
|
// Create a function that this side of the boundary can use to send
|
|
// a message to the other side.
|
|
var sender = this.sendMessage.bind(this, pipeID);
|
|
|
|
this.recipients[pipeID] = opener(message, sender);
|
|
},
|
|
|
|
sendMessage: function(pipeID, message) {
|
|
var envelope = { pipeID: pipeID, message: message };
|
|
//console.log("outer send: " + JSON.stringify(envelope));
|
|
|
|
try {
|
|
document.getElementById("mozbrowser").contentWindow.postMessage(envelope, "*");
|
|
} catch (e) {
|
|
console.log("Error " + e + " while sending message: " + JSON.stringify(envelope));
|
|
}
|
|
},
|
|
|
|
receiveMessage: function(pipeID, message, detail) {
|
|
window.setZeroTimeout(function() {
|
|
if (!this.recipients[pipeID]) {
|
|
console.warn("nonexistent pipe " + pipeID + " received message " + JSON.stringify(message));
|
|
return;
|
|
}
|
|
|
|
try {
|
|
this.recipients[pipeID](message);
|
|
} catch(ex) {
|
|
console.error(ex + "\n" + ex.stack);
|
|
}
|
|
}.bind(this));
|
|
},
|
|
|
|
closePipe: function(pipeID) {
|
|
delete this.recipients[pipeID];
|
|
}
|
|
};
|
|
|
|
document.getElementById("mozbrowser").addEventListener("mozbrowsershowmodalprompt",
|
|
DumbPipe.handleEvent.bind(DumbPipe),
|
|
true);
|
|
|
|
DumbPipe.registerOpener("alert", function(message, sender) {
|
|
alert(message);
|
|
});
|
|
|
|
DumbPipe.registerOpener("mobileInfo", function(message, sender) {
|
|
// Initialize the object with the URL params and fallback placeholders
|
|
// for testing/debugging on a desktop.
|
|
var mobileInfo = {
|
|
network: {
|
|
mcc: config.network_mcc || "310", // United States
|
|
mnc: config.network_mnc || "001",
|
|
},
|
|
icc: {
|
|
mcc: config.icc_mcc || "310", // United States
|
|
mnc: config.icc_mnc || "001",
|
|
msisdn: config.icc_msisdn || "10005551212",
|
|
},
|
|
};
|
|
|
|
var mobileConnections = window.navigator.mozMobileConnections;
|
|
if (!mobileConnections && window.navigator.mozMobileConnection) {
|
|
mobileConnections = [ window.navigator.mozMobileConnection ];
|
|
}
|
|
|
|
// If we have access to the Mobile Connection API, then we use it to get
|
|
// the actual values.
|
|
if (mobileConnections) {
|
|
// Then the only part of the Mobile Connection API that is accessible
|
|
// to privileged apps is lastKnownNetwork and lastKnownHomeNetwork, which
|
|
// is fortunately all we need. lastKnownNetwork is a string of format
|
|
// "<mcc>-<mnc>", while lastKnownHomeNetwork is "<mcc>-<mnc>[-<spn>]".
|
|
// Use only the info about the first SIM for the time being.
|
|
var lastKnownNetwork = mobileConnections[0].lastKnownNetwork.split("-");
|
|
mobileInfo.network.mcc = lastKnownNetwork[0];
|
|
mobileInfo.network.mnc = lastKnownNetwork[1];
|
|
|
|
var lastKnownHomeNetwork = mobileConnections[0].lastKnownHomeNetwork.split("-");
|
|
mobileInfo.icc.mcc = lastKnownHomeNetwork[0];
|
|
mobileInfo.icc.mnc = lastKnownHomeNetwork[1];
|
|
}
|
|
|
|
sender(mobileInfo);
|
|
});
|
|
|
|
DumbPipe.registerOpener("contacts", function(message, sender) {
|
|
var req = navigator.mozContacts.getAll();
|
|
|
|
req.onsuccess = function() {
|
|
var contact = req.result;
|
|
// Transform the mozContact into a normal object, otherwise
|
|
// the pipe won't be able to send it.
|
|
sender(contact ? JSON.parse(JSON.stringify(contact)) : null);
|
|
if (contact) {
|
|
req.continue();
|
|
}
|
|
}
|
|
|
|
req.onerror = function() {
|
|
console.error("Error while reading contacts");
|
|
}
|
|
});
|
|
|
|
DumbPipe.registerOpener("socket", function(message, sender) {
|
|
var socket;
|
|
try {
|
|
socket = navigator.mozTCPSocket.open(message.host, message.port, { binaryType: "arraybuffer" });
|
|
} catch(ex) {
|
|
sender({ type: "error", error: "error opening socket" });
|
|
return function() {};
|
|
}
|
|
|
|
socket.onopen = function() {
|
|
sender({ type: "open" });
|
|
}
|
|
|
|
socket.onerror = function(event) {
|
|
sender({ type: "error", error: event.data.name });
|
|
}
|
|
|
|
socket.ondata = function(event) {
|
|
sender({ type: "data", data: event.data });
|
|
}
|
|
|
|
socket.ondrain = function(event) {
|
|
sender({ type: "drain" });
|
|
}
|
|
|
|
socket.onclose = function(event) {
|
|
sender({ type: "close" });
|
|
}
|
|
|
|
var send = function(data) {
|
|
// Convert the data back to an Int8Array.
|
|
data = new Int8Array(data);
|
|
|
|
try {
|
|
var result = socket.send(data.buffer, 0, data.length);
|
|
sender({ type: "send", result: result });
|
|
} catch (ex) {
|
|
sender({ type: "send", error: ex.toString() });
|
|
}
|
|
};
|
|
|
|
return function(message) {
|
|
switch (message.type) {
|
|
case "send":
|
|
send(message.data);
|
|
break;
|
|
case "close":
|
|
socket.close();
|
|
break;
|
|
}
|
|
};
|
|
});
|
|
|
|
DumbPipe.registerOpener("audiorecorder", function(message, sender) {
|
|
var mediaRecorder = null;
|
|
var localAudioStream = null;
|
|
|
|
function startRecording(localStream) {
|
|
localAudioStream = localStream;
|
|
|
|
mediaRecorder = new MediaRecorder(localStream, {
|
|
mimeType: message.mimeType // 'audio/3gpp' // need to be certified app.
|
|
});
|
|
|
|
mediaRecorder.ondataavailable = function(e) {
|
|
if (e.data.size == 0) {
|
|
return;
|
|
}
|
|
|
|
var fileReader = new FileReader();
|
|
fileReader.onload = function() {
|
|
sender({ type: "data", data: fileReader.result });
|
|
};
|
|
fileReader.readAsArrayBuffer(e.data);
|
|
};
|
|
|
|
mediaRecorder.onstop = function(e) {
|
|
// Do nothing here, just relay the event.
|
|
//
|
|
// We can't close the pipe here, one reason is |onstop| is fired before |ondataavailable|,
|
|
// if close pipe here, there is no chance to deliever the recorded voice. Another reason is
|
|
// the recording might be stopped and started back and forth. So let's do the pipe
|
|
// closing on the other side instead, i.e. DirectRecord::nClose.
|
|
sender({ type: "stop" });
|
|
};
|
|
|
|
mediaRecorder.onerror = function(e) {
|
|
sender({ type: "error" });
|
|
};
|
|
|
|
mediaRecorder.onpause = function(e) {
|
|
sender({ type: "pause" });
|
|
};
|
|
|
|
mediaRecorder.onstart = function(e) {
|
|
sender({ type: "start" });
|
|
};
|
|
|
|
mediaRecorder.start();
|
|
}
|
|
|
|
return function(message) {
|
|
switch(message.type) {
|
|
case "start":
|
|
try {
|
|
if (!mediaRecorder) {
|
|
navigator.mozGetUserMedia({
|
|
audio: true
|
|
}, function(localStream) {
|
|
startRecording(localStream);
|
|
}, function(e) {
|
|
sender({ type: "error", error: e });
|
|
});
|
|
} else if (mediaRecorder.state == "paused") {
|
|
mediaRecorder.resume();
|
|
} else {
|
|
mediaRecorder.start();
|
|
}
|
|
} catch (e) {
|
|
sender({ type: "error", error: e });
|
|
}
|
|
break;
|
|
case "requestData":
|
|
try {
|
|
// An InvalidState error might be thrown.
|
|
mediaRecorder.requestData();
|
|
} catch (e) {
|
|
sender({ type: "error", error: e });
|
|
}
|
|
break;
|
|
case "pause":
|
|
try {
|
|
mediaRecorder.pause();
|
|
} catch (e) {
|
|
sender({ type: "error", error: e });
|
|
}
|
|
break;
|
|
case "stop":
|
|
try {
|
|
mediaRecorder.stop();
|
|
localAudioStream.stop();
|
|
mediaRecorder = null;
|
|
localAudioStream = null;
|
|
} catch (e) {
|
|
sender({ type: "error", error: e });
|
|
}
|
|
break;
|
|
}
|
|
};
|
|
});
|
|
|
|
|
|
DumbPipe.registerOpener("audioplayer", function(message, sender) {
|
|
var audio = new Audio();
|
|
|
|
function play() {
|
|
audio.play();
|
|
audio.onended = function() {
|
|
sender({ type: "end", duration: getDuration() });
|
|
};
|
|
}
|
|
|
|
function getDuration() {
|
|
return Math.round(audio.duration * 1000);
|
|
}
|
|
|
|
return function(message) {
|
|
var data;
|
|
switch(message.type) {
|
|
case "start":
|
|
if (!message.data) {
|
|
play();
|
|
return;
|
|
}
|
|
// Convert the data back to an Int8Array.
|
|
data = new Int8Array(message.data);
|
|
new Promise(function(resolve, reject) {
|
|
var blob = new Blob([ data ],
|
|
{ type: message.contentType });
|
|
audio.src = URL.createObjectURL(blob);
|
|
audio.onloadedmetadata = function() {
|
|
resolve();
|
|
play();
|
|
};
|
|
audio.onerror = reject;
|
|
}).done(function() {
|
|
URL.revokeObjectURL(audio.src);
|
|
});
|
|
break;
|
|
case "play":
|
|
play();
|
|
break;
|
|
case "pause":
|
|
audio.onended = null;
|
|
audio.pause();
|
|
break;
|
|
case "close":
|
|
audio.pause();
|
|
audio.src = "";
|
|
break;
|
|
case "getMediaTime":
|
|
sender({ type: "mediaTime", data: Math.round(audio.currentTime * 1000) });
|
|
break;
|
|
case "setMediaTime":
|
|
audio.currentTime = message.data / 1000;
|
|
break;
|
|
case "setVolume":
|
|
audio.volume = message.data / 100;
|
|
break;
|
|
case "setMute":
|
|
audio.muted = message.data;
|
|
case "getDuration":
|
|
sender({ type: "duration", data: getDuration() });
|
|
break;
|
|
}
|
|
};
|
|
});
|
|
|
|
DumbPipe.registerOpener("camera", function(message, sender) {
|
|
var mediaStream = null;
|
|
var url = null;
|
|
|
|
var video = document.createElement("video");
|
|
document.body.appendChild(video);
|
|
video.style.position = "absolute";
|
|
video.style.visibility = "hidden";
|
|
// Some MIDlets need user touch/click on the screen to complete the snapshot,
|
|
// to make sure the MIDlet itself instead of the video element can capture
|
|
// the mouse/touch events, we need to set `pointer-events` as `none`.
|
|
video.style.pointerEvents = "none";
|
|
|
|
video.addEventListener('canplay', function(ev) {
|
|
// We should use videoWidth and videoHeight, but they are unavailable (https://bugzilla.mozilla.org/show_bug.cgi?id=926753)
|
|
var getDimensions = setInterval(function() {
|
|
if (video.videoWidth > 0 && video.videoHeight > 0) {
|
|
clearInterval(getDimensions);
|
|
sender({ type: "gotstream", width: video.videoWidth, height: video.videoHeight });
|
|
}
|
|
}, 50);
|
|
}, false);
|
|
|
|
navigator.mozGetUserMedia({
|
|
video: true,
|
|
audio: false,
|
|
}, function(localMediaStream) {
|
|
mediaStream = localMediaStream;
|
|
url = URL.createObjectURL(localMediaStream);
|
|
|
|
video.onerror = video.onloadeddata = function() {
|
|
URL.revokeObjectURL(url);
|
|
};
|
|
|
|
video.src = url;
|
|
video.play();
|
|
}, function(err) {
|
|
console.log("Error: " + err);
|
|
sender({ type: "initerror", name: err.name, message: err.message });
|
|
});
|
|
|
|
return function(message) {
|
|
switch (message.type) {
|
|
case "setPosition":
|
|
video.style.left = message.x + "px";
|
|
video.style.top = message.y + "px";
|
|
video.style.width = message.w + "px";
|
|
video.style.height = message.h + "px";
|
|
break;
|
|
|
|
case "setVisible":
|
|
video.style.visibility = message.visible ? "visible" : "hidden";
|
|
break;
|
|
|
|
case "snapshot":
|
|
var canvas = document.createElement("canvas");
|
|
canvas.width = video.videoWidth;
|
|
canvas.height = video.videoHeight;
|
|
var ctx = canvas.getContext("2d");
|
|
ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
|
|
|
|
canvas.toBlob(function(blob) {
|
|
var fileReader = new FileReader();
|
|
|
|
fileReader.onload = function(data) {
|
|
sender({ type: "snapshot", data: fileReader.result });
|
|
}
|
|
|
|
fileReader.readAsArrayBuffer(blob);
|
|
}, message.imageType);
|
|
break;
|
|
|
|
case "close":
|
|
if (mediaStream) {
|
|
mediaStream.stop();
|
|
}
|
|
|
|
if (video.parentNode) {
|
|
document.body.removeChild(video);
|
|
}
|
|
|
|
break;
|
|
}
|
|
};
|
|
});
|
|
|
|
// #if JSR_179 == 1
|
|
var LocationProvider = {};
|
|
LocationProvider.AVAILABLE = 1;
|
|
LocationProvider.TEMPORARILY_UNAVAILABLE = 1;
|
|
LocationProvider.OUT_OF_SERVICE = 1;
|
|
LocationProvider.state = LocationProvider.OUT_OF_SERVICE;
|
|
LocationProvider.position = {
|
|
timestamp: 0,
|
|
latitude: 0,
|
|
longitude: 0,
|
|
altitude: NaN,
|
|
horizontalAccuracy: NaN,
|
|
verticalAccuracy: NaN,
|
|
speed: NaN,
|
|
heading: NaN
|
|
};
|
|
|
|
DumbPipe.registerOpener("locationprovider", function(message, sender) {
|
|
var id = -1;
|
|
var waitForData = false;
|
|
|
|
// Used to stop watching geolocation if it hasn't been accessed for a given
|
|
// time period.
|
|
var clearWatchInterval = -1;
|
|
var lastVisited = 0;
|
|
|
|
function watchPosition() {
|
|
lastVisited = Date.now();
|
|
if (id !== -1) {
|
|
return;
|
|
}
|
|
LocationProvider.state = LocationProvider.TEMPORARILY_UNAVAILABLE;
|
|
id = navigator.geolocation.watchPosition(function(pos) {
|
|
LocationProvider.state = LocationProvider.AVAILABLE;
|
|
LocationProvider.position.timestamp = pos.timestamp;
|
|
|
|
var c = pos.coords;
|
|
LocationProvider.position.latitude = c.latitude;
|
|
LocationProvider.position.longitude = c.longitude;
|
|
LocationProvider.position.altitude =
|
|
c.altitude !== null ? c.altitude : NaN;
|
|
LocationProvider.position.horizontalAccuracy =
|
|
c.accuracy !== null ? c.accuracy : NaN;
|
|
LocationProvider.position.verticalAccuracy =
|
|
c.altitudeAccuracy !== null ? c.altitudeAccuracy : NaN;
|
|
LocationProvider.position.speed = c.speed !== null ? c.speed : NaN;
|
|
LocationProvider.position.course = c.heading !== null ? c.heading : NaN;
|
|
sendData();
|
|
}, function(err) {
|
|
console.log("locationprovider error: " + err);
|
|
LocationProvider.state = LocationProvider.OUT_OF_SERVICE;
|
|
clearWatch();
|
|
sendData();
|
|
});
|
|
clearWatchInterval = setInterval(function() {
|
|
// Stop watching after being inactive for 30s to save power.
|
|
if (Date.now() - lastVisited > 30 * 1000) {
|
|
clearWatch();
|
|
}
|
|
}, 10000);
|
|
}
|
|
|
|
function clearWatch() {
|
|
if (id === -1) {
|
|
return;
|
|
}
|
|
clearInterval(clearWatchInterval);
|
|
clearWatchInterval = -1;
|
|
navigator.geolocation.clearWatch(id);
|
|
id = -1;
|
|
}
|
|
|
|
function sendData() {
|
|
if (!waitForData) {
|
|
return;
|
|
}
|
|
sender({
|
|
type: "data",
|
|
position: LocationProvider.position,
|
|
state: LocationProvider.state
|
|
});
|
|
waitForData = false;
|
|
}
|
|
|
|
watchPosition();
|
|
|
|
return function(message) {
|
|
switch (message.type) {
|
|
case "close":
|
|
clearWatch();
|
|
break;
|
|
|
|
case "requestData":
|
|
waitForData = true;
|
|
watchPosition();
|
|
break;
|
|
}
|
|
};
|
|
});
|
|
// #endif
|
|
|
|
var notification = null;
|
|
DumbPipe.registerOpener("notification", function(message, sender) {
|
|
if (notification) {
|
|
notification.close();
|
|
notification = null;
|
|
}
|
|
|
|
var img = new Image();
|
|
img.src = URL.createObjectURL(new Blob([ new Uint8Array(message.icon) ], { type : message.mime_type }));
|
|
img.onload = function() {
|
|
var width = Math.min(32, img.naturalWidth);
|
|
var height = Math.min(32, img.naturalHeight);
|
|
|
|
var canvas = document.createElement("canvas");
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
var ctx = canvas.getContext("2d");
|
|
ctx.drawImage(img, 0, 0, width, height);
|
|
|
|
URL.revokeObjectURL(img.src);
|
|
img.src = '';
|
|
|
|
message.options.icon = canvas.toDataURL();
|
|
|
|
function permissionGranted() {
|
|
notification = new Notification(message.title, message.options);
|
|
notification.onshow = function() {
|
|
sender({ type: "opened" });
|
|
};
|
|
notification.onclick = function() {
|
|
var request = navigator.mozApps.getSelf();
|
|
request.onsuccess = function() {
|
|
var app = request.result;
|
|
if (app) {
|
|
app.launch();
|
|
}
|
|
};
|
|
};
|
|
}
|
|
|
|
if (Notification.permission === "granted") {
|
|
permissionGranted();
|
|
} else if (Notification.permission !== 'denied') {
|
|
Notification.requestPermission(function(permission) {
|
|
if (permission === "granted") {
|
|
permissionGranted();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
img.onerror = function() {
|
|
URL.revokeObjectURL(img.src);
|
|
}
|
|
|
|
return function(message) {
|
|
switch(message.type) {
|
|
case "close":
|
|
if (notification) {
|
|
notification.close();
|
|
notification = null;
|
|
}
|
|
|
|
sender({ type: "close" });
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
|
|
DumbPipe.registerOpener("JARDownloader", function(url, sender) {
|
|
loadWithProgress(url, "text", function(jadData) {
|
|
try {
|
|
var manifest = {};
|
|
|
|
jadData
|
|
.replace(/\r\n|\r/g, "\n")
|
|
.replace(/\n /g, "")
|
|
.split("\n")
|
|
.forEach(function(entry) {
|
|
if (entry) {
|
|
var keyEnd = entry.indexOf(":");
|
|
var key = entry.substring(0, keyEnd);
|
|
var val = entry.substring(keyEnd + 1).trim();
|
|
manifest[key] = val;
|
|
}
|
|
});
|
|
|
|
var jarURL = manifest["MIDlet-Jar-URL"];
|
|
|
|
if (!jarURL.startsWith("http")) {
|
|
var jarName = jarURL.substring(jarURL.lastIndexOf("/") + 1);
|
|
jarURL = url.substring(0, url.lastIndexOf("/") + 1) + jarName;
|
|
}
|
|
|
|
loadWithProgress(jarURL, "arraybuffer", function(jarData) {
|
|
sender({ type: "done", data: { jadData: jadData, jarData: jarData } });
|
|
}, function() {
|
|
sender({ type: "fail" });
|
|
}, function(progress) {
|
|
sender({ type: "progress", progress: progress });
|
|
}, manifest["MIDlet-Jar-Size"] || 0);
|
|
} catch (e) {
|
|
sender({ type: "fail" });
|
|
}
|
|
}, function() {
|
|
sender({ type: "fail" });
|
|
});
|
|
});
|
|
|
|
DumbPipe.registerOpener("windowOpen", function(message, sender) {
|
|
window.open(message);
|
|
});
|
|
|
|
// #if BENCHMARK == "true"
|
|
DumbPipe.registerOpener("gcReload", function(message, sender) {
|
|
window.location.replace(window.location.href.replace("index.html", "gc.html"));
|
|
});
|
|
// #endif
|
|
|
|
DumbPipe.registerOpener("reload", function(message, sender) {
|
|
window.location.reload();
|
|
});
|
|
|
|
DumbPipe.registerOpener("exit", function(message, sender) {
|
|
window.close();
|
|
});
|
|
|
|
DumbPipe.registerOpener("backgroundCheck", function(message, sender) {
|
|
if (navigator.mozAlarms) {
|
|
navigator.mozAlarms.add(new Date(Date.now() + MIDlet.wakeUpAlarm), 'ignoreTimezone', {});
|
|
|
|
navigator.mozSetMessageHandler('alarm', function() {
|
|
navigator.mozAlarms.add(new Date(Date.now() + MIDlet.wakeUpAlarm), 'ignoreTimezone', {});
|
|
});
|
|
}
|
|
});
|
|
|
|
DumbPipe.registerOpener("mozActivity", function(message, sender) {
|
|
var activity = new MozActivity(message);
|
|
|
|
activity.onsuccess = sender.bind(null, { type: "onsuccess" });
|
|
|
|
activity.onerror = sender.bind(null, { type: "onerror" });
|
|
});
|