Merge latest green inbound changeset and mozilla-central

This commit is contained in:
Ed Morley 2013-05-24 15:49:15 +01:00
Родитель ca85028dd7 2404a06181
Коммит 702a315b61
34 изменённых файлов: 981 добавлений и 381 удалений

Просмотреть файл

@ -17,7 +17,7 @@
#
# Modifying this file will now automatically clobber the buildbot machines \o/
#
Bug 868047 - Adding a field to FrameMetrics affects ContainerLayer class size
Bug 874640 touched webidl, so Windows needs to clobber + Bug 854517: Integrate valgrind into B2G builds
Alternative to clobber is to run ./config.status from the objdir and to
touch the CLOBBER file in the objdir.

Просмотреть файл

@ -61,6 +61,7 @@ xul|scrollbarbutton[sbattr="scrollbar-bottom-top"] {
}
xul|thumb {
-moz-appearance: none !important;
background-color: rgba(0, 0, 0, 0.4) !important;
-moz-border-top-colors: none !important;
-moz-border-bottom-colors: none !important;
@ -75,30 +76,30 @@ xul|thumb {
-moz-binding: url("chrome://global/content/bindings/videocontrols.xml#touchControls");
}
select:not([size]):not([multiple]) > xul|scrollbar,
select[size="1"] > xul|scrollbar,
select:not([size]):not([multiple]) xul|scrollbarbutton,
select[size="1"] xul|scrollbarbutton {
html select:not([size]):not([multiple]) > xul|scrollbar,
html select[size="1"] > xul|scrollbar,
html select:not([size]):not([multiple]) xul|scrollbarbutton,
html select[size="1"] xul|scrollbarbutton {
display: block;
margin-left: 0;
min-width: 16px;
}
/* Override inverse OS themes */
select,
textarea,
button,
xul|button,
* > input:not([type="image"]) {
html select,
html textarea,
html button,
html xul|button,
html * > input:not([type="image"]) {
-moz-appearance: none !important; /* See bug 598421 for fixing the platform */
border-radius: 3px;
}
select[size],
select[multiple],
select[size][multiple],
textarea,
* > input:not([type="image"]) {
html select[size],
html select[multiple],
html select[size][multiple],
html textarea,
html * > input:not([type="image"]) {
border-style: solid;
border-color: #7d7d7d;
color: #414141;
@ -106,70 +107,70 @@ textarea,
}
/* Selects are handled by the form helper, see bug 685197 */
select option, select optgroup {
html select option, html select optgroup {
pointer-events: none;
}
select:not([size]):not([multiple]),
select[size="0"],
select[size="1"],
* > input[type="button"],
* > input[type="submit"],
* > input[type="reset"],
button {
html select:not([size]):not([multiple]),
html select[size="0"],
html select[size="1"],
html * > input[type="button"],
html * > input[type="submit"],
html * > input[type="reset"],
html button {
border-style: solid;
border-color: #7d7d7d;
color: #414141;
background: white linear-gradient(rgba(255,255,255,0.2) 0, rgba(215,215,215,0.5) 18px, rgba(115,115,115,0.5) 100%);
}
input[type="checkbox"] {
html input[type="checkbox"] {
background: white linear-gradient(rgba(115,115,115,0.5) 0, rgba(215,215,215,0.5) 2px, rgba(255,255,255,0.2) 6px);
}
input[type="radio"] {
html input[type="radio"] {
background: radial-gradient(at 6px 6px, rgba(255,255,255,0.2) 3px, rgba(195,195,195,0.5) 5px, rgba(115,115,115,0.5) 100%);
}
select {
html select {
border-width: 1px;
padding: 1px;
}
select:not([size]):not([multiple]),
select[size="0"],
select[size="1"] {
html select:not([size]):not([multiple]),
html select[size="0"],
html select[size="1"] {
padding: 0 1px 0 1px;
}
* > input:not([type="image"]) {
html * > input:not([type="image"]) {
border-width: 1px;
padding: 1px;
}
textarea {
html textarea {
resize: none;
border-width: 1px;
padding: 2px 1px 2px 1px;
}
input[type="button"],
input[type="submit"],
input[type="reset"],
button {
html input[type="button"],
html input[type="submit"],
html input[type="reset"],
html button {
border-width: 1px;
padding: 0 7px 0 7px;
}
input[type="radio"],
input[type="checkbox"] {
html input[type="radio"],
html input[type="checkbox"] {
max-width: 14px;
max-height: 14px;
border: 1px solid #a7a7a7 !important;
padding: 2px 1px 2px 1px;
}
select > button {
html select > button {
border-width: 0px !important;
margin: 0px !important;
padding: 0px !important;
@ -187,54 +188,54 @@ select > button {
font-size: inherit;
}
select[size]:focus,
select[multiple]:focus,
select[size][multiple]:focus,
textarea:focus,
input[type="file"]:focus > input[type="text"],
* > input:not([type="image"]):focus {
html select[size]:focus,
html select[multiple]:focus,
html select[size][multiple]:focus,
html textarea:focus,
html input[type="file"]:focus > input[type="text"],
html * > input:not([type="image"]):focus {
outline: 0px !important;
border-style: solid;
border-color: rgb(94,128,153);
background: white linear-gradient(rgba(27,113,177,0.5) 0, rgba(198,225,246,0.2) 3px, rgba(255,255,255,0.2) 16px);
}
select:not([size]):not([multiple]):focus,
select[size="0"]:focus,
select[size="1"]:focus,
input[type="button"]:focus,
input[type="submit"]:focus,
input[type="reset"]:focus,
button:focus {
html select:not([size]):not([multiple]):focus,
html select[size="0"]:focus,
html select[size="1"]:focus,
html input[type="button"]:focus,
html input[type="submit"]:focus,
html input[type="reset"]:focus,
html button:focus {
outline: 0px !important;
border-style: solid;
border-color: rgb(94,128,153);
background: white linear-gradient(rgba(255,255,255,0.2) 0, rgba(198,225,256,0.2) 18px, rgba(27,113,177,0.5) 100%);
}
input[type="checkbox"]:focus,
input[type="radio"]:focus {
html input[type="checkbox"]:focus,
html input[type="radio"]:focus {
border-color: #99c6e0 !important;
}
input[type="checkbox"]:focus {
html input[type="checkbox"]:focus {
background: white linear-gradient(rgba(27,113,177,0.5) 0, rgba(198,225,246,0.2) 2px, rgba(255,255,255,0.2) 6px);
}
input[type="radio"]:focus {
html input[type="radio"]:focus {
background: radial-gradient(at 6px 6px, rgba(255,255,255,0.2) 3px, rgba(198,225,246,0.2) 5px, rgba(27,113,177,0.5) 100%);
}
/* we need to be specific for selects because the above rules are specific too */
textarea[disabled],
select[size][disabled],
select[multiple][disabled],
select[size][multiple][disabled],
select:not([size]):not([multiple])[disabled],
select[size="0"][disabled],
select[size="1"][disabled],
button[disabled],
* > input:not([type="image"])[disabled] {
html textarea[disabled],
html select[size][disabled],
html select[multiple][disabled],
html select[size][multiple][disabled],
html select:not([size]):not([multiple])[disabled],
html select[size="0"][disabled],
html select[size="1"][disabled],
html button[disabled],
html * > input:not([type="image"])[disabled] {
color: rgba(0,0,0,0.3);
border-color: rgba(125,125,125,0.4);
border-style: solid;
@ -242,44 +243,44 @@ button[disabled],
background: transparent linear-gradient(rgba(185,185,185,0.4) 0, rgba(235,235,235,0.4) 3px, rgba(255,255,255,0.4) 100%);
}
select:not([size]):not([multiple])[disabled],
select[size="0"][disabled],
select[size="1"][disabled] {
html select:not([size]):not([multiple])[disabled],
html select[size="0"][disabled],
html select[size="1"][disabled] {
background: transparent linear-gradient(rgba(255,255,255,0.4) 0, rgba(235,235,235,0.4) 3px, rgba(185,185,185,0.4) 100%);
}
input[type="button"][disabled],
input[type="submit"][disabled],
input[type="reset"][disabled],
button[disabled="true"] {
html input[type="button"][disabled],
html input[type="submit"][disabled],
html input[type="reset"][disabled],
html button[disabled="true"] {
padding: 0 7px 0 7px;
background: transparent linear-gradient(rgba(255,255,255,0.4) 0, rgba(235,235,235,0.4) 3px, rgba(185,185,185,0.4) 100%);
}
input[type="radio"][disabled],
input[type="radio"][disabled]:active,
input[type="radio"][disabled]:hover,
input[type="radio"][disabled]:hover:active,
input[type="checkbox"][disabled],
input[type="checkbox"][disabled]:active,
input[type="checkbox"][disabled]:hover,
input[type="checkbox"][disabled]:hover:active {
html input[type="radio"][disabled],
html input[type="radio"][disabled]:active,
html input[type="radio"][disabled]:hover,
html input[type="radio"][disabled]:hover:active,
html input[type="checkbox"][disabled],
html input[type="checkbox"][disabled]:active,
html input[type="checkbox"][disabled]:hover,
html input[type="checkbox"][disabled]:hover:active {
border:1px solid rgba(125,125,125,0.4) !important;
}
select[disabled] > button {
html select[disabled] > button {
opacity: 0.6;
padding: 1px 7px 1px 7px;
}
*:-moz-any-link:active,
*[role=button]:active,
button:active,
input:active,
option:active,
select:active,
label:active,
textarea:active {
html *:-moz-any-link:active,
html *[role=button]:active,
html button:active,
html input:active,
html option:active,
html select:active,
html label:active,
html textarea:active {
background-color: rgba(141, 184, 216, 0.5);
}

Просмотреть файл

@ -431,8 +431,8 @@ var shell = {
},
lastHardwareButtonEventType: null, // property for the hack above
needBufferSysMsgs: true,
bufferedSysMsgs: [],
needBufferOpenAppReq: true,
bufferedOpenAppReqs: [],
timer: null,
visibleNormalAudioActive: false,
@ -548,7 +548,7 @@ var shell = {
ObjectWrapper.wrap(details, getContentWindow()));
},
sendSystemMessage: function shell_sendSystemMessage(msg) {
openAppForSystemMessage: function shell_openAppForSystemMessage(msg) {
let origin = Services.io.newURI(msg.manifest, null, null).prePath;
this.sendChromeEvent({
type: 'open-app',
@ -623,16 +623,16 @@ nsBrowserAccess.prototype = {
}
};
// Listen for system messages and relay them to Gaia.
Services.obs.addObserver(function onSystemMessage(subject, topic, data) {
// Listen for the request of opening app and relay them to Gaia.
Services.obs.addObserver(function onSystemMessageOpenApp(subject, topic, data) {
let msg = JSON.parse(data);
// Buffer non-activity messages until content starts to load for 10 seconds.
// We'll revisit this later if new kind of messages don't need to be cached.
if (shell.needBufferSysMsgs && msg.type !== 'activity') {
shell.bufferedSysMsgs.push(msg);
// Buffer non-activity request until content starts to load for 10 seconds.
// We'll revisit this later if new kind of requests don't need to be cached.
if (shell.needBufferOpenAppReq && msg.type !== 'activity') {
shell.bufferedOpenAppReqs.push(msg);
return;
}
shell.sendSystemMessage(msg);
shell.openAppForSystemMessage(msg);
}, 'system-messages-open-app', false);
Services.obs.addObserver(function(aSubject, aTopic, aData) {
@ -662,14 +662,17 @@ var CustomEventManager = {
content.addEventListener("mozContentEvent", this, false, true);
// After content starts to load for 10 seconds, send and
// clean up the buffered system messages if there is any.
// clean up the buffered open-app requests if there is any.
//
// TODO: Bug 793420 - Remove the waiting timer for the 'open-app'
// mozChromeEvents requested by System Message
shell.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
shell.timer.initWithCallback(function timerCallback() {
shell.bufferedSysMsgs.forEach(function sendSysMsg(msg) {
shell.sendSystemMessage(msg);
shell.bufferedOpenAppReqs.forEach(function bufferOpenAppReq(msg) {
shell.openAppForSystemMessage(msg);
});
shell.bufferedSysMsgs.length = 0;
shell.needBufferSysMsgs = false;
shell.bufferedOpenAppReqs.length = 0;
shell.needBufferOpenAppReq = false;
shell.timer = null;
}, 10000, Ci.nsITimer.TYPE_ONE_SHOT);
}).bind(this), false);

Просмотреть файл

@ -4,13 +4,8 @@
"use strict"
let DEBUG = 0;
let debug;
if (DEBUG) {
debug = function (s) { dump("-*- ContentPermissionPrompt: " + s + "\n"); };
}
else {
debug = function (s) {};
function debug(str) {
//dump("-*- ContentPermissionPrompt: " + s + "\n");
}
const Ci = Components.interfaces;
@ -18,7 +13,7 @@ const Cr = Components.results;
const Cu = Components.utils;
const Cc = Components.classes;
const PROMPT_FOR_UNKNOWN = ['geolocation', 'desktop-notification'];
const PROMPT_FOR_UNKNOWN = ["geolocation", "desktop-notification"];
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
@ -116,8 +111,8 @@ ContentPermissionPrompt.prototype = {
return true;
},
_id: 0,
prompt: function(request) {
if (secMan.isSystemPrincipal(request.principal)) {
request.allow();
return true;
@ -130,58 +125,104 @@ ContentPermissionPrompt.prototype = {
if (this.handleExistingPermission(request))
return;
// If the request was initiated from a hidden iframe
// we don't forward it to content and cancel it right away
let frame = request.element;
let requestId = this._id++;
if (!frame) {
this.delegatePrompt(request);
this.delegatePrompt(request, requestId);
return;
}
frame = frame.wrappedJSObject;
var cancelRequest = function() {
frame.removeEventListener("mozbrowservisibilitychange", onVisibilityChange);
request.cancel();
}
var self = this;
frame.wrappedJSObject.getVisible().onsuccess = function gv_success(evt) {
var onVisibilityChange = function(evt) {
if (evt.detail.visible === true)
return;
self.cancelPrompt(request, requestId);
cancelRequest();
}
// If the request was initiated from a hidden iframe
// we don't forward it to content and cancel it right away
let domRequest = frame.getVisible();
domRequest.onsuccess = function gv_success(evt) {
if (!evt.target.result) {
request.cancel();
cancelRequest();
return;
}
self.delegatePrompt(request);
// Monitor the frame visibility and cancel the request if the frame goes
// away but the request is still here.
frame.addEventListener("mozbrowservisibilitychange", onVisibilityChange);
self.delegatePrompt(request, requestId, function onCallback() {
frame.removeEventListener("mozbrowservisibilitychange", onVisibilityChange);
});
};
// Something went wrong. Let's cancel the request just in case.
domRequest.onerror = function gv_error() {
cancelRequest();
}
},
_id: 0,
delegatePrompt: function(request) {
cancelPrompt: function(request, requestId) {
this.sendToBrowserWindow("cancel-permission-prompt", request, requestId);
},
delegatePrompt: function(request, requestId, callback) {
let access = (request.access && request.access !== "unused") ? request.type + "-" + request.access :
request.type;
let principal = request.principal;
this._permission = access;
this._uri = principal.URI.spec;
this._origin = principal.origin;
this.sendToBrowserWindow("permission-prompt", request, requestId, function(type, remember) {
if (type == "permission-allow") {
rememberPermission(request.type, principal, !remember);
callback();
request.allow();
return;
}
if (remember) {
Services.perms.addFromPrincipal(principal, access,
Ci.nsIPermissionManager.DENY_ACTION);
} else {
Services.perms.addFromPrincipal(principal, access,
Ci.nsIPermissionManager.DENY_ACTION,
Ci.nsIPermissionManager.EXPIRE_SESSION, 0);
}
callback();
request.cancel();
});
},
sendToBrowserWindow: function(type, request, requestId, callback) {
let browser = Services.wm.getMostRecentWindow("navigator:browser");
let content = browser.getContentWindow();
if (!content)
return;
let access = (request.access && request.access !== "unused") ? request.type + "-" + request.access :
request.type;
if (callback) {
content.addEventListener("mozContentEvent", function contentEvent(evt) {
let detail = evt.detail;
if (detail.id != requestId)
return;
evt.target.removeEventListener(evt.type, contentEvent);
let requestId = this._id++;
content.addEventListener("mozContentEvent", function contentEvent(evt) {
if (evt.detail.id != requestId)
return;
evt.target.removeEventListener(evt.type, contentEvent);
if (evt.detail.type == "permission-allow") {
rememberPermission(request.type, request.principal, !evt.detail.remember);
request.allow();
return;
}
if (evt.detail.remember) {
Services.perms.addFromPrincipal(request.principal, access,
Ci.nsIPermissionManager.DENY_ACTION);
} else {
Services.perms.addFromPrincipal(request.principal, access,
Ci.nsIPermissionManager.DENY_ACTION,
Ci.nsIPermissionManager.EXPIRE_SESSION, 0);
}
request.cancel();
});
callback(detail.type, detail.remember);
})
}
let principal = request.principal;
let isApp = principal.appStatus != Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED;
@ -191,7 +232,7 @@ ContentPermissionPrompt.prototype = {
: request.remember;
let details = {
type: "permission-prompt",
type: type,
permission: request.type,
id: requestId,
origin: principal.origin,
@ -199,10 +240,6 @@ ContentPermissionPrompt.prototype = {
remember: remember
};
this._permission = access;
this._uri = request.principal.URI.spec;
this._origin = request.principal.origin;
if (!isApp) {
browser.shell.sendChromeEvent(details);
return;

Просмотреть файл

@ -38,6 +38,7 @@ let Keyboard = {
init: function keyboardInit() {
Services.obs.addObserver(this, 'in-process-browser-or-app-frame-shown', false);
Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
Services.obs.addObserver(this, 'oop-frameloader-crashed', false);
for (let name of this._messageNames)
ppmm.addMessageListener('Keyboard:' + name, this);
@ -46,18 +47,26 @@ let Keyboard = {
observe: function keyboardObserve(subject, topic, data) {
let frameLoader = subject.QueryInterface(Ci.nsIFrameLoader);
let mm = frameLoader.messageManager;
mm.addMessageListener('Forms:Input', this);
mm.addMessageListener('Forms:SelectionChange', this);
// When not running apps OOP, we need to load forms.js here since this
// won't happen from dom/ipc/preload.js
try {
if (Services.prefs.getBoolPref("dom.ipc.tabs.disabled") === true) {
mm.loadFrameScript(kFormsFrameScript, true);
}
} catch (e) {
dump('Error loading ' + kFormsFrameScript + ' as frame script: ' + e + '\n');
}
if (topic == 'oop-frameloader-crashed') {
if (this.messageManager == mm) {
// The application has been closed unexpectingly. Let's tell the
// keyboard app that the focus has been lost.
ppmm.broadcastAsyncMessage('Keyboard:FocusChange', { 'type': 'blur' });
}
} else {
mm.addMessageListener('Forms:Input', this);
// When not running apps OOP, we need to load forms.js here since this
// won't happen from dom/ipc/preload.js
try {
if (Services.prefs.getBoolPref("dom.ipc.tabs.disabled") === true) {
mm.loadFrameScript(kFormsFrameScript, true);
}
} catch (e) {
dump('Error loading ' + kFormsFrameScript + ' as frame script: ' + e + '\n');
}
}
},
receiveMessage: function keyboardReceiveMessage(msg) {

Просмотреть файл

@ -203,7 +203,7 @@ if test -n "$gonkdir" ; then
case "$ANDROID_VERSION" in
15)
GONK_INCLUDES="-I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/frameworks/base/include -I$gonkdir/frameworks/base/services/camera -I$gonkdir/frameworks/base/include/media/stagefright -I$gonkdir/frameworks/base/include/media/stagefright/openmax -I$gonkdir/frameworks/base/media/libstagefright/rtsp -I$gonkdir/frameworks/base/media/libstagefright/include -I$gonkdir/external/dbus -I$gonkdir/external/bluetooth/bluez/lib -I$gonkdir/dalvik/libnativehelper/include/nativehelper"
GONK_INCLUDES="-I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/frameworks/base/include -I$gonkdir/frameworks/base/services/camera -I$gonkdir/frameworks/base/include/media/stagefright -I$gonkdir/frameworks/base/include/media/stagefright/openmax -I$gonkdir/frameworks/base/media/libstagefright/rtsp -I$gonkdir/frameworks/base/media/libstagefright/include -I$gonkdir/external/dbus -I$gonkdir/external/bluetooth/bluez/lib -I$gonkdir/dalvik/libnativehelper/include/nativehelper -I$gonkdir/external/valgrind"
MOZ_B2G_BT=1
MOZ_B2G_CAMERA=1
MOZ_OMX_DECODER=1

Просмотреть файл

@ -1700,6 +1700,10 @@ void HTMLMediaElement::SetMutedInternal(uint32_t aMuted)
NS_IMETHODIMP HTMLMediaElement::SetMuted(bool aMuted)
{
if (aMuted == Muted()) {
return NS_OK;
}
if (aMuted) {
SetMutedInternal(mMuted | MUTED_BY_CONTENT);
} else {

Просмотреть файл

@ -710,19 +710,22 @@ BluetoothOppManager::ServerDataHandler(UnixSocketRawData* aMessage)
ReplyToConnect();
AfterOppConnected();
mIsServer = true;
} else if (opCode == ObexRequestCode::Disconnect ||
opCode == ObexRequestCode::Abort) {
// Section 3.3.2 "Disconnect", IrOBEX 1.2
} else if (opCode == ObexRequestCode::Abort) {
// Section 3.3.5 "Abort", IrOBEX 1.2
// [opcode:1][length:2][Headers:var]
ParseHeaders(&aMessage->mData[3],
receivedLength - 3,
&pktHeaders);
ReplyToDisconnect();
ReplyToDisconnectOrAbort();
DeleteReceivedFile();
} else if (opCode == ObexRequestCode::Disconnect) {
// Section 3.3.2 "Disconnect", IrOBEX 1.2
// [opcode:1][length:2][Headers:var]
ParseHeaders(&aMessage->mData[3],
receivedLength - 3,
&pktHeaders);
ReplyToDisconnectOrAbort();
AfterOppDisconnected();
if (opCode == ObexRequestCode::Abort) {
DeleteReceivedFile();
}
FileTransferComplete();
} else if (opCode == ObexRequestCode::Put ||
opCode == ObexRequestCode::PutFinal) {
@ -1143,11 +1146,12 @@ BluetoothOppManager::ReplyToConnect()
}
void
BluetoothOppManager::ReplyToDisconnect()
BluetoothOppManager::ReplyToDisconnectOrAbort()
{
if (!mConnected) return;
// Section 3.3.2 "Disconnect", IrOBEX 1.2
// Section 3.3.2 "Disconnect" and Section 3.3.5 "Abort", IrOBEX 1.2
// The format of response packet of "Disconnect" and "Abort" are the same
// [opcode:1][length:2][Headers:var]
uint8_t req[255];
int index = 3;

Просмотреть файл

@ -101,7 +101,7 @@ private:
bool WriteToFile(const uint8_t* aData, int aDataLength);
void DeleteReceivedFile();
void ReplyToConnect();
void ReplyToDisconnect();
void ReplyToDisconnectOrAbort();
void ReplyToPut(bool aFinal, bool aContinue);
void AfterOppConnected();
void AfterFirstPut();

Просмотреть файл

@ -220,7 +220,7 @@ BluetoothServiceChildProcess::UpdateSdpRecords(const nsAString& aDeviceAddress,
BluetoothProfileManagerBase* aManager)
{
MOZ_NOT_REACHED("This should never be called!");
return NS_ERROR_FAILURE;
return false;
}
bool

Просмотреть файл

@ -41,6 +41,66 @@ function sendAsyncMsg(msg, data) {
sendAsyncMessage('browser-element-api:call', data);
}
function sendSyncMsg(msg, data) {
// Ensure that we don't send any messages before BrowserElementChild.js
// finishes loading.
if (!BrowserElementIsReady)
return;
if (!data) {
data = { };
}
data.msg_name = msg;
return sendSyncMessage('browser-element-api:call', data);
}
let CERTIFICATE_ERROR_PAGE_PREF = 'security.alternate_certificate_error_page';
let NS_ERROR_MODULE_BASE_OFFSET = 0x45;
let NS_ERROR_MODULE_SECURITY= 21;
function NS_ERROR_GET_MODULE(err) {
return ((((err) >> 16) - NS_ERROR_MODULE_BASE_OFFSET) & 0x1fff)
}
function NS_ERROR_GET_CODE(err) {
return ((err) & 0xffff);
}
let SEC_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SEC_ERROR_BASE;
let SEC_ERROR_UNKNOWN_ISSUER = (SEC_ERROR_BASE + 13);
let SEC_ERROR_CA_CERT_INVALID = (SEC_ERROR_BASE + 36);
let SEC_ERROR_UNTRUSTED_ISSUER = (SEC_ERROR_BASE + 20);
let SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE = (SEC_ERROR_BASE + 30);
let SEC_ERROR_UNTRUSTED_CERT = (SEC_ERROR_BASE + 21);
let SEC_ERROR_INADEQUATE_KEY_USAGE = (SEC_ERROR_BASE + 90);
let SEC_ERROR_EXPIRED_CERTIFICATE = (SEC_ERROR_BASE + 11);
let SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED = (SEC_ERROR_BASE + 176);
let SSL_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SSL_ERROR_BASE;
let SSL_ERROR_BAD_CERT_DOMAIN = (SSL_ERROR_BASE + 12);
function getErrorClass(errorCode) {
let NSPRCode = -1 * NS_ERROR_GET_CODE(errorCode);
switch (NSPRCode) {
case SEC_ERROR_UNKNOWN_ISSUER:
case SEC_ERROR_CA_CERT_INVALID:
case SEC_ERROR_UNTRUSTED_ISSUER:
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
case SEC_ERROR_UNTRUSTED_CERT:
case SEC_ERROR_INADEQUATE_KEY_USAGE:
case SSL_ERROR_BAD_CERT_DOMAIN:
case SEC_ERROR_EXPIRED_CERTIFICATE:
case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED:
return Ci.nsINSSErrorsService.ERROR_CLASS_BAD_CERT;
default:
return Ci.nsINSSErrorsService.ERROR_CLASS_SSL_PROTOCOL;
}
return null;
}
/**
* The BrowserElementChild implements one half of <iframe mozbrowser>.
* (The other half is, unsurprisingly, BrowserElementParent.)
@ -478,8 +538,6 @@ BrowserElementChild.prototype = {
return;
}
e.preventDefault();
this._ctxCounter++;
this._ctxHandlers = {};
@ -508,7 +566,18 @@ BrowserElementChild.prototype = {
menuData.contextmenu = this._buildMenuObj(menu, '');
}
}
sendAsyncMsg('contextmenu', menuData);
// The value returned by the contextmenu sync call is true iff the embedder
// called preventDefault() on its contextmenu event.
//
// We call preventDefault() on our contextmenu event iff the embedder called
// preventDefault() on /its/ contextmenu event. This way, if the embedder
// ignored the contextmenu event, TabChild will fire a click.
if (sendSyncMsg('contextmenu', menuData)[0]) {
e.preventDefault();
} else {
this._ctxHandlers = {};
}
},
_getSystemCtxMenuData: function(elem) {
@ -700,7 +769,7 @@ BrowserElementChild.prototype = {
var visible = this._forcedVisible && this._ownerVisible;
if (docShell.isActive !== visible) {
docShell.isActive = visible;
sendAsyncMsg('visibility-change', {visible: visible});
sendAsyncMsg('visibilitychange', {visible: visible});
}
},
@ -827,6 +896,24 @@ BrowserElementChild.prototype = {
return;
}
if (NS_ERROR_GET_MODULE(status) == NS_ERROR_MODULE_SECURITY &&
getErrorClass(status) == Ci.nsINSSErrorsService.ERROR_CLASS_BAD_CERT) {
// XXX Is there a point firing the event if the error page is not
// certerror? If yes, maybe we should add a property to the
// event to to indicate whether there is a custom page. That would
// let the embedder have more control over the desired behavior.
var errorPage = null;
try {
errorPage = Services.prefs.getCharPref(CERTIFICATE_ERROR_PAGE_PREF);
} catch(e) {}
if (errorPage == 'certerror') {
sendAsyncMsg('error', { type: 'certerror' });
return;
}
}
// TODO See nsDocShell::DisplayLoadError for a list of all the error
// codes (the status param) we should eventually handle here.
sendAsyncMsg('error', { type: 'other' });

Просмотреть файл

@ -694,10 +694,22 @@ const KineticPanning = {
momentums: [],
record: function kp_record(delta, timestamp) {
this.momentums.push({ 'time': timestamp, 'dx' : delta.x, 'dy' : delta.y });
this.momentums.push({ 'time': this._getTime(timestamp),
'dx' : delta.x, 'dy' : delta.y });
this.distance.add(delta.x, delta.y);
},
_getTime: function kp_getTime(time) {
// Touch events generated by the platform or hand-made are defined in
// microseconds instead of milliseconds. Bug 77992 will fix this at the
// platform level.
if (time > Date.now()) {
return Math.floor(time / 1000);
} else {
return time;
}
},
get threshold() {
let dpi = content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)

Просмотреть файл

@ -119,7 +119,7 @@ function BrowserElementParent(frameLoader, hasRemoteFrame) {
"rollback-fullscreen": this._remoteFrameFullscreenReverted,
"exit-fullscreen": this._exitFullscreen,
"got-visible": this._gotDOMRequestResult,
"visibility-change": this._childVisibilityChange,
"visibilitychange": this._childVisibilityChange,
}
this._mm.addMessageListener('browser-element-api:call', function(aMsg) {
@ -294,7 +294,7 @@ BrowserElementParent.prototype = {
let evtName = detail.msg_name;
debug('fireCtxMenuEventFromMsg: ' + evtName + ' ' + detail);
let evt = this._createEvent(evtName, detail);
let evt = this._createEvent(evtName, detail, /* cancellable */ true);
if (detail.contextmenu) {
var self = this;
@ -302,10 +302,11 @@ BrowserElementParent.prototype = {
self._sendAsyncMsg('fire-ctx-callback', {menuitem: id});
});
}
// The embedder may have default actions on context menu events, so
// we fire a context menu event even if the child didn't define a
// custom context menu
this._frameElement.dispatchEvent(evt);
return !this._frameElement.dispatchEvent(evt);
},
/**
@ -575,6 +576,8 @@ BrowserElementParent.prototype = {
_childVisibilityChange: function(data) {
debug("_childVisibilityChange(" + data.json.visible + ")");
this._frameLoader.visible = data.json.visible;
this._fireEventFromMsg(data);
},
_exitFullscreen: function() {

Просмотреть файл

@ -28,7 +28,6 @@ MOCHITEST_FILES = \
browserElement_DataURI.js \
test_browserElement_inproc_DataURI.html \
browserElement_ErrorSecurity.js \
test_browserElement_inproc_ErrorSecurity.html \
browserElement_Titlechange.js \
test_browserElement_inproc_Titlechange.html \
browserElement_TopBarrier.js \
@ -161,6 +160,8 @@ MOCHITEST_FILES = \
test_browserElement_inproc_PurgeHistory.html \
browserElement_DocumentFirstPaint.js \
test_browserElement_inproc_DocumentFirstPaint.html \
browserElement_VisibilityChange.js \
test_browserElement_inproc_VisibilityChange.html \
$(NULL)
# Disabled due to https://bugzilla.mozilla.org/show_bug.cgi?id=774100
@ -169,6 +170,9 @@ MOCHITEST_FILES = \
# Disabled due to focus issues (no bug that I'm aware of)
# test_browserElement_oop_KeyEvents.html \
# Disable due to certificate issue (no bug that I'm aware of)
# test_browserElement_inproc_ErrorSecurity.html \
# OOP tests don't work on native-fennec (bug 774939).
#
# Both the "inproc" and "oop" versions of OpenMixedProcess open remote frames,
@ -179,6 +183,7 @@ MOCHITEST_FILES += \
browserElement_OpenMixedProcess.js \
file_browserElement_OpenMixedProcess.html \
test_browserElement_inproc_OpenMixedProcess.html \
test_browserElement_inproc_ErrorSecurity.html \
test_browserElement_oop_OpenMixedProcess.html \
test_browserElement_oop_LoadEvents.html \
test_browserElement_oop_DataURI.html \
@ -230,6 +235,7 @@ MOCHITEST_FILES += \
test_browserElement_oop_ReloadPostRequest.html \
test_browserElement_oop_PurgeHistory.html \
test_browserElement_oop_DocumentFirstPaint.html \
test_browserElement_oop_VisibilityChange.html \
$(NULL)
endif #}

Просмотреть файл

@ -1,142 +1,222 @@
"use strict";
'use strict';
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var iframeScript = function() {
content.fireContextMenu = function(element) {
var ev = content.document.createEvent('HTMLEvents');
ev.initEvent('contextmenu', true, false);
element.dispatchEvent(ev);
};
XPCNativeWrapper.unwrap(content).ctxCallbackFired = function(data) {
sendAsyncMessage('test:callbackfired', {data: data});
};
XPCNativeWrapper.unwrap(content).onerror = function(e) {
sendAsyncMessage('test:errorTriggered', {data: e});
};
content.fireContextMenu(content.document.body);
content.fireContextMenu(content.document.getElementById('menu1-trigger'));
content.fireContextMenu(content.document.getElementById('inner-link').childNodes[0]);
content.fireContextMenu(content.document.getElementById('menu2-trigger'));
function runTests() {
createIframe(function onIframeLoaded() {
checkEmptyContextMenu();
});
}
var trigger1 = function() {
content.fireContextMenu(content.document.getElementById('menu1-trigger'));
function checkEmptyContextMenu() {
sendContextMenuTo('body', function onContextMenu(detail) {
is(detail.contextmenu, null, 'Body context clicks have no context menu');
checkInnerContextMenu();
});
}
function checkInnerContextMenu() {
sendContextMenuTo('#inner-link', function onContextMenu(detail) {
is(detail.systemTargets.length, 1, 'Includes anchor data');
is(detail.contextmenu.items.length, 2, 'Inner clicks trigger correct menu');
checkCustomContextMenu();
});
}
function checkCustomContextMenu() {
sendContextMenuTo('#menu1-trigger', function onContextMenu(detail) {
is(detail.contextmenu.items.length, 2, 'trigger custom contextmenu');
checkNestedContextMenu();
});
}
function checkNestedContextMenu() {
sendContextMenuTo('#menu2-trigger', function onContextMenu(detail) {
var innerMenu = detail.contextmenu.items.filter(function(x) {
return x.type === 'menu';
});
is(detail.systemTargets.length, 2, 'Includes anchor and img data');
ok(innerMenu.length > 0, 'Menu contains a nested menu');
checkPreviousContextMenuHandler();
});
}
// Finished testing the data passed to the contextmenu handler,
// now we start selecting contextmenu items
function checkPreviousContextMenuHandler() {
// This is previously triggered contextmenu data, since we have
// fired subsequent contextmenus this should not be mistaken
// for a current menuitem
var detail = previousContextMenuDetail;
var previousId = detail.contextmenu.items[0].id;
checkContextMenuCallbackForId(detail, previousId, function onCallbackFired(label) {
is(label, null, 'Callback label should be empty since this handler is old');
checkCurrentContextMenuHandler();
});
}
function checkCurrentContextMenuHandler() {
// This triggers a current menuitem
var detail = currentContextMenuDetail;
var innerMenu = detail.contextmenu.items.filter(function(x) {
return x.type === 'menu';
});
var currentId = innerMenu[0].items[1].id;
checkContextMenuCallbackForId(detail, currentId, function onCallbackFired(label) {
is(label, 'inner 2', 'Callback label should be set correctly');
checkAgainCurrentContextMenuHandler();
});
}
function checkAgainCurrentContextMenuHandler() {
// Once an item it selected, subsequent selections are ignored
var detail = currentContextMenuDetail;
var innerMenu = detail.contextmenu.items.filter(function(x) {
return x.type === 'menu';
});
var currentId = innerMenu[0].items[1].id;
checkContextMenuCallbackForId(detail, currentId, function onCallbackFired(label) {
is(label, null, 'Callback label should be empty since this handler has already been used');
checkCallbackWithPreventDefault();
});
};
function runTest() {
var iframe1 = document.createElement('iframe');
SpecialPowers.wrap(iframe1).mozbrowser = true;
document.body.appendChild(iframe1);
iframe1.src = 'data:text/html,<html>' +
// Finished testing callbacks if the embedder calls preventDefault() on the
// mozbrowsercontextmenu event, now we start checking for some cases where the embedder
// does not want to call preventDefault() for some reasons.
function checkCallbackWithPreventDefault() {
sendContextMenuTo('#menu1-trigger', function onContextMenu(detail) {
var id = detail.contextmenu.items[0].id;
checkContextMenuCallbackForId(detail, id, function onCallbackFired(label) {
is(label, 'foo', 'Callback label should be set correctly');
checkCallbackWithoutPreventDefault();
});
});
}
function checkCallbackWithoutPreventDefault() {
sendContextMenuTo('#menu1-trigger', function onContextMenu(detail) {
var id = detail.contextmenu.items[0].id;
checkContextMenuCallbackForId(detail, id, function onCallbackFired(label) {
is(label, null, 'Callback label should be null');
SimpleTest.finish();
});
}, /* ignorePreventDefault */ true);
}
/* Helpers */
var mm = null;
var previousContextMenuDetail = null;
var currentContextMenuDetail = null;
function sendContextMenuTo(selector, callback, ignorePreventDefault) {
iframe.addEventListener('mozbrowsercontextmenu', function oncontextmenu(e) {
iframe.removeEventListener(e.type, oncontextmenu);
// The embedder should call preventDefault() on the event if it will handle
// it. Not calling preventDefault() means it won't handle the event and
// should not be able to deal with context menu callbacks.
if (ignorePreventDefault !== true) {
e.preventDefault();
}
// Keep a reference to previous/current contextmenu event details.
previousContextMenuDetail = currentContextMenuDetail;
currentContextMenuDetail = e.detail;
setTimeout(function() { callback(e.detail); });
});
mm.sendAsyncMessage('contextmenu', { 'selector': selector });
}
function checkContextMenuCallbackForId(detail, id, callback) {
mm.addMessageListener('test:callbackfired', function onCallbackFired(msg) {
mm.removeMessageListener('test:callbackfired', onCallbackFired);
msg = SpecialPowers.wrap(msg);
setTimeout(function() { callback(msg.data.label); });
});
detail.contextMenuItemSelected(id);
}
var iframe = null;
function createIframe(callback) {
iframe = document.createElement('iframe');
SpecialPowers.wrap(iframe).mozbrowser = true;
iframe.src = 'data:text/html,<html>' +
'<body>' +
'<menu type="context" id="menu1" label="firstmenu">' +
'<menuitem label="foo" onclick="window.ctxCallbackFired(\'foo\')"></menuitem>' +
'<menuitem label="bar" onclick="throw(\'anerror\')"></menuitem>' +
'<menuitem label="foo" onclick="window.onContextMenuCallbackFired(event)"></menuitem>' +
'<menuitem label="bar" onclick="window.onContextMenuCallbackFired(event)"></menuitem>' +
'</menu>' +
'<menu type="context" id="menu2" label="secondmenu">' +
'<menuitem label="outer" onclick="window.ctxCallbackFired(\'err\')"></menuitem>' +
'<menuitem label="outer" onclick="window.onContextMenuCallbackFired(event)"></menuitem>' +
'<menu>' +
'<menuitem label="inner 1"></menuitem>' +
'<menuitem label="inner 2" onclick="window.ctxCallbackFired(\'inner2\')"></menuitem>' +
'<menuitem label="inner 2" onclick="window.onContextMenuCallbackFired(event)"></menuitem>' +
'</menu>' +
'</menu>' +
'<div id="menu1-trigger" contextmenu="menu1"><a id="inner-link" href="foo.html">Menu 1</a></div>' +
'<a href="bar.html" contextmenu="menu2"><img id="menu2-trigger" src="example.png" /></a>' +
'</body></html>';
document.body.appendChild(iframe);
var mm;
var numIframeLoaded = 0;
var ctxMenuEvents = 0;
var ctxCallbackEvents = 0;
// The following code will be included in the child
// =========================================================================
function iframeScript() {
addMessageListener('contextmenu', function onContextMenu(msg) {
var document = content.document;
var evt = document.createEvent('HTMLEvents');
evt.initEvent('contextmenu', true, true);
document.querySelector(msg.data.selector).dispatchEvent(evt);
});
var cachedCtxDetail = null;
addMessageListener('browser-element-api:call', function onCallback(msg) {
if (msg.data.msg_name != 'fire-ctx-callback')
return;
// We fire off various contextmenu events to check the data that gets
// passed to the handler
function iframeContextmenuHandler(e) {
var detail = e.detail;
ctxMenuEvents++;
if (ctxMenuEvents === 1) {
ok(detail.contextmenu === null, 'body context clicks have no context menu');
} else if (ctxMenuEvents === 2) {
cachedCtxDetail = detail;
ok(detail.contextmenu.items.length === 2, 'trigger custom contextmenu');
} else if (ctxMenuEvents === 3) {
ok(detail.systemTargets.length === 1, 'Includes anchor data');
ok(detail.contextmenu.items.length === 2, 'Inner clicks trigger correct menu');
} else if (ctxMenuEvents === 4) {
var innerMenu = detail.contextmenu.items.filter(function(x) {
return x.type === 'menu';
/* Use setTimeout in order to react *after* the platform */
content.setTimeout(function() {
sendAsyncMessage('test:callbackfired', { label: label });
label = null;
});
ok(detail.systemTargets.length === 2, 'Includes anchor and img data');
ok(innerMenu.length > 0, 'Menu contains a nested menu');
ok(true, 'Got correct number of contextmenu events');
// Finished testing the data passed to the contextmenu handler,
// now we start selecting contextmenu items
});
// This is previously triggered contextmenu data, since we have
// fired subsequent contextmenus this should not be mistaken
// for a current menuitem
var prevId = cachedCtxDetail.contextmenu.items[0].id;
cachedCtxDetail.contextMenuItemSelected(prevId);
// This triggers a current menuitem
detail.contextMenuItemSelected(innerMenu[0].items[1].id);
// Once an item it selected, subsequent selections are ignored
detail.contextMenuItemSelected(innerMenu[0].items[0].id);
} else if (ctxMenuEvents === 5) {
ok(detail.contextmenu.label === 'firstmenu', 'Correct menu enabled');
detail.contextMenuItemSelected(detail.contextmenu.items[0].id);
} else if (ctxMenuEvents === 6) {
detail.contextMenuItemSelected(detail.contextmenu.items[1].id);
} else if (ctxMenuEvents > 6) {
ok(false, 'Too many events');
}
var label = null;
XPCNativeWrapper.unwrap(content).onContextMenuCallbackFired = function(e) {
label = e.target.getAttribute('label');
};
}
// =========================================================================
function ctxCallbackRecieved(msg) {
msg = SpecialPowers.wrap(msg);
ctxCallbackEvents++;
if (ctxCallbackEvents === 1) {
ok(msg.json.data === 'inner2', 'Callback function got fired correctly');
mm.loadFrameScript('data:,(' + trigger1.toString() + ')();', false);
} else if (ctxCallbackEvents === 2) {
ok(msg.json.data === 'foo', 'Callback function got fired correctly');
mm.loadFrameScript('data:,(' + trigger1.toString() + ')();', false);
} else if (ctxCallbackEvents > 2) {
ok(false, 'Too many callback events');
}
}
iframe.addEventListener('mozbrowserloadend', function onload(e) {
iframe.removeEventListener(e.type, onload);
mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
mm.loadFrameScript('data:,(' + iframeScript.toString() + ')();', false);
var gotError = false;
function errorTriggered(msg) {
if (gotError) {
return;
}
gotError = true;
ok(true, 'An error in the callback triggers window.onerror');
SimpleTest.finish();
}
function iframeLoadedHandler() {
numIframeLoaded++;
if (numIframeLoaded === 2) {
mm = SpecialPowers.getBrowserFrameMessageManager(iframe1);
mm.addMessageListener('test:callbackfired', ctxCallbackRecieved);
mm.addMessageListener('test:errorTriggered', errorTriggered);
mm.loadFrameScript('data:,(' + iframeScript.toString() + ')();', false);
}
}
iframe1.addEventListener('mozbrowsercontextmenu', iframeContextmenuHandler);
iframe1.addEventListener('mozbrowserloadend', iframeLoadedHandler);
// Now we're ready, let's start testing.
callback();
});
}
addEventListener('testready', runTest);
addEventListener('testready', runTests);

Просмотреть файл

@ -9,18 +9,50 @@ SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var iframe = null;
function runTest() {
var iframe = document.createElement('iframe');
iframe = document.createElement('iframe');
SpecialPowers.wrap(iframe).mozbrowser = true;
document.body.appendChild(iframe);
iframe.addEventListener("mozbrowsererror", function(e) {
checkForGenericError();
}
function checkForGenericError() {
iframe.addEventListener("mozbrowsererror", function onGenericError(e) {
iframe.removeEventListener(e.type, onGenericError);
ok(true, "Got mozbrowsererror event.");
ok(e.detail.type, "Event's detail has a |type| param.");
SimpleTest.finish();
ok(e.detail.type == "other", "Event's detail has a |type| param with the value '" + e.detail.type + "'.");
checkForExpiredCertificateError();
});
iframe.src = "http://this_is_not_a_domain.example.com";
}
function checkForExpiredCertificateError() {
iframe.addEventListener("mozbrowsererror", function onCertError(e) {
iframe.removeEventListener(e.type, onCertError);
ok(true, "Got mozbrowsererror event.");
ok(e.detail.type == "certerror", "Event's detail has a |type| param with the value '" + e.detail.type + "'.");
checkForNoCertificateError();
});
iframe.src = "https://expired.example.com";
document.body.appendChild(iframe);
}
function checkForNoCertificateError() {
iframe.addEventListener("mozbrowsererror", function onCertError(e) {
iframe.removeEventListener(e.type, onCertError);
ok(true, "Got mozbrowsererror event.");
ok(e.detail.type == "certerror", "Event's detail has a |type| param with the value '" + e.detail.type + "'.");
SimpleTest.finish();
});
iframe.src = "https://nocert.example.com";
}
addEventListener('testready', runTest);

Просмотреть файл

@ -0,0 +1,43 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that the onmozbrowservisibilitychange event works.
'use strict';
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var iframe1 = null;
function runTest() {
iframe1 = document.createElement('iframe');
SpecialPowers.wrap(iframe1).mozbrowser = true;
document.body.appendChild(iframe1);
iframe1.src = 'data:text/html,<html><head><title>Title</title></head><body></body></html>';
checkVisibilityFalse();
}
function checkVisibilityFalse() {
iframe1.addEventListener('mozbrowservisibilitychange', function onvisibilitychange(e) {
iframe1.removeEventListener(e.type, onvisibilitychange);
is(e.detail.visible, false, 'Visibility should be false');
checkVisibilityTrue();
});
iframe1.setVisible(false);
}
function checkVisibilityTrue() {
iframe1.addEventListener('mozbrowservisibilitychange', function onvisibilitychange(e) {
iframe1.removeEventListener(e.type, onvisibilitychange);
is(e.detail.visible, true, 'Visibility should be true');
SimpleTest.finish();
});
iframe1.setVisible(true);
}
addEventListener('testready', runTest);

Просмотреть файл

@ -0,0 +1,19 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=868816
-->
<head>
<title>Test for Bug 868816</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=868816">Mozilla Bug 868816</a>
<script type="application/javascript;version=1.7" src='browserElement_VisibilityChange.js'>
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,19 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=868816
-->
<head>
<title>Test for Bug 868816</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=868816">Mozilla Bug 868816</a>
<script type="application/javascript;version=1.7" src='browserElement_VisibilityChange.js'>
</script>
</body>
</html>

Просмотреть файл

@ -2031,7 +2031,6 @@ public:
r = new PostResultEvent(mRequest, totalUsage);
}
NS_DispatchToMainThread(r);
return NS_OK;
}
@ -2778,6 +2777,7 @@ nsDOMDeviceStorage::AddNamed(nsIDOMBlob *aBlob,
NS_ADDREF(*_retval = request);
r = new PostErrorEvent(request, POST_ERROR_EVENT_UNKNOWN);
NS_DispatchToMainThread(r);
return NS_OK;
}
return ds->AddNamed(aBlob, storagePath, _retval);
}

Просмотреть файл

@ -251,7 +251,7 @@ void SystemMessageHandledObserver::Init()
mozilla::services::GetObserverService();
if (os) {
os->AddObserver(this, "SystemMessageManager:HandleMessageDone",
os->AddObserver(this, "handle-system-messages-done",
/* ownsWeak */ false);
}
}

Просмотреть файл

@ -1608,11 +1608,8 @@ TabChild::RecvMouseEvent(const nsString& aType,
const int32_t& aModifiers,
const bool& aIgnoreRootScrollFrame)
{
nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils());
NS_ENSURE_TRUE(utils, true);
bool ignored = false;
utils->SendMouseEvent(aType, aX, aY, aButton, aClickCount, aModifiers,
aIgnoreRootScrollFrame, 0, 0, &ignored);
DispatchMouseEvent(aType, aX, aY, aButton, aClickCount, aModifiers,
aIgnoreRootScrollFrame);
return true;
}
@ -1749,8 +1746,21 @@ void
TabChild::FireContextMenuEvent()
{
MOZ_ASSERT(mTapHoldTimer && mActivePointerId >= 0);
RecvHandleLongTap(mGestureDownPoint);
CancelTapTracking();
bool defaultPrevented = DispatchMouseEvent(NS_LITERAL_STRING("contextmenu"),
mGestureDownPoint.x, mGestureDownPoint.y,
2 /* Right button */,
1 /* Click count */,
0 /* Modifiers */,
false /* Ignore root scroll frame */);
// Fire a click event if someone didn't call preventDefault() on the context
// menu event.
if (defaultPrevented) {
CancelTapTracking();
} else if (mTapHoldTimer) {
mTapHoldTimer->Cancel();
mTapHoldTimer = nullptr;
}
}
void
@ -2222,6 +2232,24 @@ TabChild::IsAsyncPanZoomEnabled()
return mScrolling == ASYNC_PAN_ZOOM;
}
bool
TabChild::DispatchMouseEvent(const nsString& aType,
const float& aX,
const float& aY,
const int32_t& aButton,
const int32_t& aClickCount,
const int32_t& aModifiers,
const bool& aIgnoreRootScrollFrame)
{
nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils());
NS_ENSURE_TRUE(utils, true);
bool defaultPrevented = false;
utils->SendMouseEvent(aType, aX, aY, aButton, aClickCount, aModifiers,
aIgnoreRootScrollFrame, 0, 0, &defaultPrevented);
return defaultPrevented;
}
void
TabChild::MakeVisible()
{

Просмотреть файл

@ -306,6 +306,17 @@ public:
bool IsAsyncPanZoomEnabled();
/** Return a boolean indicating if the page has called preventDefault on
* the event.
*/
bool DispatchMouseEvent(const nsString& aType,
const float& aX,
const float& aY,
const int32_t& aButton,
const int32_t& aClickCount,
const int32_t& aModifiers,
const bool& aIgnoreRootScrollFrame);
/**
* Signal to this TabChild that it should be made visible:
* activated widget, retained layer tree, etc. (Respectively,

Просмотреть файл

@ -21,6 +21,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator",
"@mozilla.org/uuid-generator;1",
"nsIUUIDGenerator");
XPCOMUtils.defineLazyServiceGetter(this, "powerManagerService",
"@mozilla.org/power/powermanagerservice;1",
"nsIPowerManagerService");
// Limit the number of pending messages for a given page.
let kMaxPendingMessages;
try {
@ -36,6 +40,7 @@ const kMessages =["SystemMessageManager:GetPendingMessages",
"SystemMessageManager:Unregister",
"SystemMessageManager:Message:Return:OK",
"SystemMessageManager:AskReadyToRegister",
"SystemMessageManager:HandleMessagesDone",
"child-process-shutdown"]
function debug(aMsg) {
@ -59,6 +64,8 @@ function SystemMessageInternal() {
this._webappsRegistryReady = false;
this._bufferedSysMsgs = [];
this._cpuWakeLocks = {};
Services.obs.addObserver(this, "xpcom-shutdown", false);
Services.obs.addObserver(this, "webapps-registry-start", false);
Services.obs.addObserver(this, "webapps-registry-ready", false);
@ -70,6 +77,57 @@ function SystemMessageInternal() {
}
SystemMessageInternal.prototype = {
_cancelCpuWakeLock: function _cancelCpuWakeLock(aPageKey) {
let cpuWakeLock = this._cpuWakeLocks[aPageKey];
if (cpuWakeLock) {
debug("Releasing the CPU wake lock for page key = " + aPageKey);
cpuWakeLock.wakeLock.unlock();
cpuWakeLock.timer.cancel();
delete this._cpuWakeLocks[aPageKey];
}
},
_acquireCpuWakeLock: function _acquireCpuWakeLock(aPageKey) {
let cpuWakeLock = this._cpuWakeLocks[aPageKey];
if (!cpuWakeLock) {
// We have to ensure the CPU doesn't sleep during the process of the page
// handling the system messages, so that they can be handled on time.
debug("Acquiring a CPU wake lock for page key = " + aPageKey);
cpuWakeLock = this._cpuWakeLocks[aPageKey] = {
wakeLock: powerManagerService.newWakeLock("cpu"),
timer: Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer),
lockCount: 1
};
} else {
// We've already acquired the CPU wake lock for this page,
// so just add to the lock count and extend the timeout.
cpuWakeLock.lockCount++;
}
// Set a watchdog to avoid locking the CPU wake lock too long,
// because it'd exhaust the battery quickly which is very bad.
// This could probably happen if the app failed to launch or
// handle the system messages due to any unexpected reasons.
cpuWakeLock.timer.initWithCallback(function timerCb() {
debug("Releasing the CPU wake lock because the system messages " +
"were not handled by its registered page before time out.");
this._cancelCpuWakeLock(aPageKey);
}.bind(this), 30000, Ci.nsITimer.TYPE_ONE_SHOT);
},
_releaseCpuWakeLock: function _releaseCpuWakeLock(aPageKey, aHandledCount) {
let cpuWakeLock = this._cpuWakeLocks[aPageKey];
if (cpuWakeLock) {
cpuWakeLock.lockCount -= aHandledCount;
if (cpuWakeLock.lockCount <= 0) {
debug("Unlocking the CPU wake lock now that the system messages " +
"have been successfully handled by its registered page.");
this._cancelCpuWakeLock(aPageKey);
}
}
},
sendMessage: function sendMessage(aType, aMessage, aPageURI, aManifestURI) {
// Buffer system messages until the webapps' registration is ready,
// so that we can know the correct pages registered to be sent.
@ -224,7 +282,8 @@ SystemMessageInternal.prototype = {
"SystemMessageManager:Unregister",
"SystemMessageManager:GetPendingMessages",
"SystemMessageManager:HasPendingMessages",
"SystemMessageManager:Message:Return:OK"].indexOf(aMessage.name) != -1) {
"SystemMessageManager:Message:Return:OK",
"SystemMessageManager:HandleMessagesDone"].indexOf(aMessage.name) != -1) {
if (!aMessage.target.assertContainApp(msg.manifest)) {
debug("Got message from a child process containing illegal manifest URL.");
return null;
@ -237,13 +296,15 @@ SystemMessageInternal.prototype = {
break;
case "SystemMessageManager:Register":
{
debug("Got Register from " + msg.manifest);
debug("Got Register from " + msg.uri + " @ " + msg.manifest);
let targets, index;
if (!(targets = this._listeners[msg.manifest])) {
this._listeners[msg.manifest] = [{ target: aMessage.target,
uri: msg.uri,
winCount: 1 }];
} else if ((index = this._findTargetIndex(targets, aMessage.target)) === -1) {
targets.push({ target: aMessage.target,
uri: msg.uri,
winCount: 1 });
} else {
targets[index].winCount++;
@ -301,7 +362,6 @@ SystemMessageInternal.prototype = {
aMessage.target.sendAsyncMessage("SystemMessageManager:GetPendingMessages:Return",
{ type: msg.type,
manifest: msg.manifest,
uri: msg.uri,
msgQueue: pendingMessages });
break;
}
@ -348,6 +408,16 @@ SystemMessageInternal.prototype = {
}, this);
break;
}
case "SystemMessageManager:HandleMessagesDone":
{
debug("received SystemMessageManager:HandleMessagesDone " + msg.type +
" with " + msg.handledCount + " for " + msg.uri + " @ " + msg.manifest);
// A page has finished handling some of its system messages, so we try
// to release the CPU wake lock we acquired on behalf of that page.
this._releaseCpuWakeLock(this._createKeyForPage(msg), msg.handledCount);
break;
}
}
},
@ -440,19 +510,45 @@ SystemMessageInternal.prototype = {
return false;
}
let appPageIsRunning = false;
let pageKey = this._createKeyForPage({ type: aType,
manifest: aManifestURI,
uri: aPageURI })
let targets = this._listeners[aManifestURI];
if (targets) {
for (let index = 0; index < targets.length; ++index) {
let manager = targets[index].target;
manager.sendAsyncMessage("SystemMessageManager:Message",
{ type: aType,
msg: aMessage,
manifest: aManifestURI,
uri: aPageURI,
msgID: aMessageID });
let target = targets[index];
// We only need to send the system message to the targets which match
// the manifest URL and page URL of the destination of system message.
if (target.uri != aPageURI) {
continue;
}
appPageIsRunning = true;
// We need to acquire a CPU wake lock for that page and expect that
// we'll receive a "SystemMessageManager:HandleMessagesDone" message
// when the page finishes handling the system message. At that point,
// we'll release the lock we acquired.
this._acquireCpuWakeLock(pageKey);
let manager = target.target;
manager.sendAsyncMessage("SystemMessageManager:Message",
{ type: aType,
msg: aMessage,
msgID: aMessageID });
}
}
if (!appPageIsRunning) {
// The app page isn't running and relies on the 'open-app' chrome event to
// wake it up. We still need to acquire a CPU wake lock for that page and
// expect that we will receive a "SystemMessageManager:HandleMessagesDone"
// message when the page finishes handling the system message with other
// pending messages. At that point, we'll release the lock we acquired.
this._acquireCpuWakeLock(pageKey);
}
return true;
},

Просмотреть файл

@ -74,10 +74,6 @@ SystemMessageManager.prototype = {
aHandler.handleMessage(wrapped ? aMessage
: ObjectWrapper.wrap(aMessage, this._window));
Services.obs.notifyObservers(/* aSubject */ null,
"SystemMessageManager:HandleMessageDone",
/* aData */ null);
},
mozSetMessageHandler: function sysMessMgr_setMessageHandler(aType, aHandler) {
@ -148,44 +144,59 @@ SystemMessageManager.prototype = {
cpmm.sendAsyncMessage("SystemMessageManager:Unregister",
{ manifest: this._manifest,
innerWindowID: this.innerWindowID
});
innerWindowID: this.innerWindowID });
},
// Possible messages:
//
// - SystemMessageManager:Message
// This one will only be received when the child process is alive when
// the message is initially sent.
//
// - SystemMessageManager:GetPendingMessages:Return
// This one will be received when the starting child process wants to
// retrieve the pending system messages from the parent (i.e. after
// sending SystemMessageManager:GetPendingMessages).
receiveMessage: function sysMessMgr_receiveMessage(aMessage) {
debug("receiveMessage " + aMessage.name + " for [" + aMessage.data.type + "] " +
"with manifest = " + aMessage.data.manifest + " (" + this._manifest + ") " +
"and uri = " + aMessage.data.uri + " (" + this._uri + ")");
"with manifest = " + this._manifest + " and uri = " + this._uri);
let msg = aMessage.data;
if (msg.manifest != this._manifest || msg.uri != this._uri) {
return;
}
if (aMessage.name == "SystemMessageManager:Message") {
// Send an acknowledgement to parent to clean up the pending message,
// so a re-launched app won't handle it again, which is redundant.
cpmm.sendAsyncMessage(
"SystemMessageManager:Message:Return:OK",
{ type: msg.type,
manifest: msg.manifest,
uri: msg.uri,
msgID: msg.msgID });
}
// Bail out if we have no handlers registered for this type.
if (!(msg.type in this._handlers)) {
debug("No handler for this type");
return;
cpmm.sendAsyncMessage("SystemMessageManager:Message:Return:OK",
{ type: msg.type,
manifest: this._manifest,
uri: this._uri,
msgID: msg.msgID });
}
let messages = (aMessage.name == "SystemMessageManager:Message")
? [msg.msg]
: msg.msgQueue;
messages.forEach(function(aMsg) {
this._dispatchMessage(msg.type, this._handlers[msg.type], aMsg);
}, this);
// We only dispatch messages when a handler is registered.
let handler = this._handlers[msg.type];
if (handler) {
messages.forEach(function(aMsg) {
this._dispatchMessage(msg.type, handler, aMsg);
}, this);
}
// We need to notify the parent the system messages have been handled,
// even if there are no handlers registered for them, so the parent can
// release the CPU wake lock it took on our behalf.
cpmm.sendAsyncMessage("SystemMessageManager:HandleMessagesDone",
{ type: msg.type,
manifest: this._manifest,
uri: this._uri,
handledCount: messages.length });
Services.obs.notifyObservers(/* aSubject */ null,
"handle-system-messages-done",
/* aData */ null);
},
// nsIDOMGlobalPropertyInitializer implementation.
@ -239,8 +250,9 @@ SystemMessageManager.prototype = {
if (!this._registerManifestReady) {
cpmm.sendAsyncMessage("SystemMessageManager:Register",
{ manifest: this._manifest,
innerWindowID: this.innerWindowID
});
uri: this._uri,
innerWindowID: this.innerWindowID });
this._registerManifestReady = true;
}
},

Просмотреть файл

@ -718,19 +718,8 @@ function SendTransaction(msg) {
if (DEBUG) debug("Check max values parameters fail.");
throw new Error("Check max values parameters fail.");
}
let messageSize = 0;
if (msg.content) {
messageSize = msg.content.length;
} else if (msg.parts) {
for (let i = 0; i < msg.parts.length; i++) {
if (msg.parts[i].content.size) {
messageSize += msg.parts[i].content.size;
} else {
messageSize += msg.parts[i].content.length;
}
}
if (msg.parts) {
let contentType = {
params: {
// `The type parameter must be specified and its value is the MIME
@ -757,10 +746,6 @@ function SendTransaction(msg) {
msg.headers["content-type"] = contentType;
}
// Assign to X-Mms-Message-Size
msg.headers["x-mms-message-size"] = messageSize;
// TODO: bug 809832 - support customizable max incoming/outgoing message size
if (DEBUG) debug("msg: " + JSON.stringify(msg));
this.msg = msg;

Просмотреть файл

@ -32,3 +32,4 @@ qemu = true
[test_outgoing_max_segments.js]
[test_update_thread_record_in_delete.js]
[test_massive_incoming_delete.js]
[test_getsegmentinfofortext.js]

Просмотреть файл

@ -0,0 +1,106 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
// Copied from dom/system/gonk/ril_consts.js.
const PDU_MAX_USER_DATA_7BIT = 160;
SpecialPowers.setBoolPref("dom.sms.enabled", true);
SpecialPowers.addPermission("sms", true, document);
let sms = window.navigator.mozSms;
ok(sms instanceof MozSmsManager, "mozSmsManager");
let tasks = {
// List of test fuctions. Each of them should call |tasks.next()| when
// completed or |tasks.finish()| to jump to the last one.
_tasks: [],
_nextTaskIndex: 0,
push: function push(func) {
this._tasks.push(func);
},
next: function next() {
let index = this._nextTaskIndex++;
let task = this._tasks[index];
try {
task();
} catch (ex) {
ok(false, "test task[" + index + "] throws: " + ex);
// Run last task as clean up if possible.
if (index != this._tasks.length - 1) {
this.finish();
}
}
},
finish: function finish() {
this._tasks[this._tasks.length - 1]();
},
run: function run() {
this.next();
}
};
function addTest(text, segments, charsPerSegment, charsAvailableInLastSegment) {
tasks.push(function () {
log("Testing '" + text + "' ...");
let info = sms.getSegmentInfoForText(text);
is(info.segments, segments, "info.segments");
is(info.charsPerSegment, charsPerSegment, "info.charsPerSegment");
is(info.charsAvailableInLastSegment, charsAvailableInLastSegment,
"info.charsAvailableInLastSegment");
tasks.next();
});
}
function addTestThrows(text) {
tasks.push(function () {
log("Testing '" + text + "' ...");
try {
let info = sms.getSegmentInfoForText(text);
ok(false, "Not thrown");
tasks.finish();
} catch (e) {
tasks.next();
}
});
}
addTestThrows(null);
// Testing "undefined".
addTest(undefined, 1, PDU_MAX_USER_DATA_7BIT,
PDU_MAX_USER_DATA_7BIT - "undefined".length);
// Testing numeric values.
addTest(0, 1, PDU_MAX_USER_DATA_7BIT, PDU_MAX_USER_DATA_7BIT - "0".length);
addTest(1.0, 1, PDU_MAX_USER_DATA_7BIT, PDU_MAX_USER_DATA_7BIT - "1".length);
// Testing empty object. The empty object extends to "[object Object]" and both
// '[' and ']' are in default single shift table, so each of them takes two
// septets.
addTest({}, 1, PDU_MAX_USER_DATA_7BIT,
PDU_MAX_USER_DATA_7BIT - (("" + {}).length + 2));
// Testing Date object.
let date = new Date();
addTest(date, 1, PDU_MAX_USER_DATA_7BIT,
PDU_MAX_USER_DATA_7BIT - ("" + date).length);
addTest("", 0, PDU_MAX_USER_DATA_7BIT,
PDU_MAX_USER_DATA_7BIT - "".length);
// WARNING: All tasks should be pushed before this!!!
tasks.push(function cleanUp() {
SpecialPowers.removePermission("sms", document);
SpecialPowers.clearUserPref("dom.sms.enabled");
finish();
});
tasks.run();

Просмотреть файл

@ -269,8 +269,8 @@ NetworkStatsDB.prototype = {
this.fillResultSamples(start, end, data);
txn.result.connectionType = aOptions.connectionType;
txn.result.start = new Date(aOptions.start);
txn.result.end = new Date(aOptions.end);
txn.result.start = aOptions.start;
txn.result.end = aOptions.end;
txn.result.data = data;
}.bind(this);
}.bind(this), aResultCb);
@ -315,8 +315,8 @@ NetworkStatsDB.prototype = {
this.fillResultSamples(start, end, data);
txn.result.connectionType = aOptions.connectionType;
txn.result.start = new Date(aOptions.start);
txn.result.end = new Date(aOptions.end);
txn.result.start = aOptions.start;
txn.result.end = aOptions.end;
txn.result.data = data;
}.bind(this);
}.bind(this), aResultCb);

Просмотреть файл

@ -51,9 +51,8 @@ function test() {
}
function checkDataDates(data, start, end, sampleRate){
var offset = new Date().getTimezoneOffset() * 60 * 1000;
start = Math.floor((start.getTime() - offset) / sampleRate) * sampleRate + offset;
end = Math.floor((end.getTime() - offset) / sampleRate) * sampleRate + offset;
start = Math.floor(start.getTime() / sampleRate) * sampleRate;
end = Math.floor(end.getTime() / sampleRate) * sampleRate;
var counter = 0;
var date = start;
@ -150,8 +149,7 @@ var steps = [
// Get samplerate in millis
var sampleRate = netStats.sampleRate * 1000;
// Get date with samplerate's precision
var offset = new Date().getTimezoneOffset() * 60 * 1000;
var endDate = new Date(Math.floor((new Date().getTime() - offset) / sampleRate) * sampleRate + offset);
var endDate = new Date(Math.floor(new Date().getTime() / sampleRate) * sampleRate);
var startDate = new Date(endDate.getTime() - (sampleRate * diff));
// Calculate the number of samples that should be returned based on the
// the samplerate and including final and initial samples.
@ -181,8 +179,7 @@ var steps = [
// Get samplerate in millis
var sampleRate = netStats.sampleRate * 1000;
// Get date with samplerate's precision
var offset = new Date().getTimezoneOffset() * 60 * 1000;
var endDate = new Date(Math.floor((new Date().getTime() - offset) / sampleRate) * sampleRate + offset);
var endDate = new Date(Math.floor(new Date().getTime() / sampleRate) * sampleRate);
var startDate = new Date(endDate.getTime() - (sampleRate * diff));
// Calculate the number of samples that should be returned based on the
// the samplerate and including final and initial samples.

Просмотреть файл

@ -52,7 +52,7 @@ static int sMaxStreamVolumeTbl[AUDIO_STREAM_CNT] = {
15, // FM
};
// A bitwise variable for recording what kind of headset is attached.
static int sHeadsetState = SWITCH_STATE_OFF;
static int sHeadsetState;
static int kBtSampleRate = 8000;
class RecoverTask : public nsRunnable

Просмотреть файл

@ -2726,11 +2726,16 @@ RadioInterfaceLayer.prototype = {
}
let options = this._fragmentText(text, null, strict7BitEncoding);
let lastSegment = options.segments[options.segmentMaxSeq - 1];
let charsInLastSegment = lastSegment.encodedBodyLength;
if (options.dcs == RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET) {
// In UCS2 encoding, encodedBodyLength is in octets.
charsInLastSegment /= 2;
let charsInLastSegment;
if (options.segmentMaxSeq) {
let lastSegment = options.segments[options.segmentMaxSeq - 1];
charsInLastSegment = lastSegment.encodedBodyLength;
if (options.dcs == RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET) {
// In UCS2 encoding, encodedBodyLength is in octets.
charsInLastSegment /= 2;
}
} else {
charsInLastSegment = 0;
}
let result = gMobileMessageService.createSmsSegmentInfo(options.segmentMaxSeq,

Просмотреть файл

@ -188,7 +188,7 @@ if test -n "$gonkdir" ; then
;;
esac
CPPFLAGS="-DANDROID -isystem $gonkdir/bionic/libc/$ARCH_DIR/include -isystem $gonkdir/bionic/libc/include/ -isystem $gonkdir/bionic/libc/kernel/common -isystem $gonkdir/bionic/libc/kernel/$ARCH_DIR -isystem $gonkdir/bionic/libm/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/system/core/include -isystem $gonkdir/bionic $CPPFLAGS"
CPPFLAGS="-DANDROID -isystem $gonkdir/bionic/libc/$ARCH_DIR/include -isystem $gonkdir/bionic/libc/include/ -isystem $gonkdir/bionic/libc/kernel/common -isystem $gonkdir/bionic/libc/kernel/$ARCH_DIR -isystem $gonkdir/bionic/libm/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/system/core/include -isystem $gonkdir/bionic $CPPFLAGS -I$gonkdir/external/valgrind"
CFLAGS="-mandroid -fno-short-enums -fno-exceptions $CFLAGS"
CXXFLAGS="-mandroid -fno-short-enums -fno-exceptions -Wno-psabi $CXXFLAGS $STLPORT_CPPFLAGS"
LIBS="$LIBS $STLPORT_LIBS"

Просмотреть файл

@ -158,7 +158,7 @@ skip-if(B2G) == filter-scaled-02.html filter-scaled-02-ref.html
skip-if(B2G) == foreignObject-ancestor-style-change-01.svg foreignObject-ancestor-style-change-01-ref.svg
skip-if(B2G) == foreignObject-change-transform-01.svg pass.svg
== foreignObject-display-01.svg pass.svg
== foreignObject-form-theme.svg foreignObject-form-theme-ref.html
fails-if(B2G) == foreignObject-form-theme.svg foreignObject-form-theme-ref.html
== foreignObject-img-form-theme.html foreignObject-img-form-theme-ref.html
skip-if(B2G) == foreignObject-move-repaint-01.svg pass.svg
== foreignObject-overflow-01.svg pass.svg