mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to inbound.
This commit is contained in:
commit
81208466f0
@ -1065,13 +1065,13 @@ let RemoteDebugger = {
|
||||
if ("nsIProfiler" in Ci) {
|
||||
DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/profiler.js");
|
||||
}
|
||||
DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/styleeditor.js");
|
||||
DebuggerServer.registerModule("devtools/server/actors/inspector")
|
||||
DebuggerServer.registerModule("devtools/server/actors/styleeditor");
|
||||
DebuggerServer.enableWebappsContentActor = true;
|
||||
}
|
||||
DebuggerServer.addActors('chrome://browser/content/dbg-browser-actors.js');
|
||||
DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/webapps.js");
|
||||
DebuggerServer.registerModule("devtools/server/actors/device");
|
||||
DebuggerServer.registerModule("devtools/server/actors/inspector")
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
DebuggerServer.onConnectionChange = function(what) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"revision": "79e25f81e1e868ea9903eca5dd7452f2c778c7ce",
|
||||
"revision": "9919e96678a4fc08ffe6ca9068bfc245394fa5e3",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ MOZ_APP_UA_NAME=Firefox
|
||||
|
||||
MOZ_UA_OS_AGNOSTIC=1
|
||||
|
||||
MOZ_B2G_VERSION=1.3.0.0-prerelease
|
||||
MOZ_B2G_VERSION=1.4.0.0-prerelease
|
||||
MOZ_B2G_OS_NAME=Boot2Gecko
|
||||
|
||||
MOZ_BRANDING_DIRECTORY=b2g/branding/unofficial
|
||||
|
@ -95,7 +95,6 @@ let UI = {
|
||||
let newSelection = document.querySelector("." + panel + "-" + type);
|
||||
if (oldSelection) oldSelection.removeAttribute("selected");
|
||||
if (newSelection) {
|
||||
newSelection.scrollIntoView(false);
|
||||
newSelection.setAttribute("selected", "true");
|
||||
if (newSelection.classList.contains("toolbox")) {
|
||||
isToolboxTab = true;
|
||||
|
@ -26,6 +26,10 @@ h1 {
|
||||
border-bottom: 1px solid rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
form {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin: 10px;
|
||||
@ -39,7 +43,7 @@ label > span {
|
||||
}
|
||||
|
||||
#submit {
|
||||
margin-left: 160px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
input:invalid {
|
||||
|
@ -12,7 +12,7 @@
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<head>
|
||||
<title>&title;</title>
|
||||
<link rel="stylesheet" href="chrome://browser/skin/devtools/common.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="chrome://browser/skin/devtools/dark-theme.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="chrome://browser/content/devtools/connect.css" type="text/css"/>
|
||||
<script type="application/javascript;version=1.8" src="connect.js"></script>
|
||||
</head>
|
||||
|
@ -11,6 +11,11 @@
|
||||
color: #8fa1b2;
|
||||
}
|
||||
|
||||
::-moz-selection {
|
||||
background-color: #1d4f73;
|
||||
color: #f5f7fa;
|
||||
}
|
||||
|
||||
.theme-twisty {
|
||||
cursor: pointer;
|
||||
width: 14px;
|
||||
|
@ -11,6 +11,11 @@
|
||||
color: black;
|
||||
}
|
||||
|
||||
::-moz-selection {
|
||||
background-color: #4c9ed9;
|
||||
color: #f5f7fa;
|
||||
}
|
||||
|
||||
.theme-twisty {
|
||||
cursor: pointer;
|
||||
width: 14px;
|
||||
|
@ -132,50 +132,38 @@
|
||||
.devtools-searchinput {
|
||||
-moz-appearance: none;
|
||||
margin: 0 3px;
|
||||
min-height: 22px;
|
||||
border: 1px solid hsla(210,8%,5%,.6);
|
||||
border: 1px solid rgb(88, 94, 101);
|
||||
%ifdef XP_MACOSX
|
||||
border-radius: 20px;
|
||||
%else
|
||||
border-radius: 2px;
|
||||
%endif
|
||||
background-color: transparent;
|
||||
background-image: linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
|
||||
padding: 3px;
|
||||
box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
|
||||
0 0 0 1px hsla(210,16%,76%,.1) inset,
|
||||
0 1px 0 hsla(210,16%,76%,.15);
|
||||
color: inherit;
|
||||
background-color: rgba(24, 29, 32, 1);
|
||||
padding: 4px 6px;
|
||||
color: rgba(184, 200, 217, 1);
|
||||
}
|
||||
|
||||
.devtools-searchinput {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
-moz-padding-start: 18px;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
-moz-padding-start: 22px;
|
||||
-moz-padding-end: 12px;
|
||||
background-image: url(magnifying-glass.png), linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
|
||||
background-position: 4px center, top left, top left;
|
||||
background-image: url(magnifying-glass.png);
|
||||
background-position: 8px center;
|
||||
background-repeat: no-repeat;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.devtools-searchinput:-moz-locale-dir(rtl) {
|
||||
background-position: calc(100% - 4px) center, top left, top left;
|
||||
background-position: calc(100% - 8px) center;
|
||||
}
|
||||
|
||||
.devtools-searchinput > .textbox-input-box > .textbox-search-icons {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.devtools-searchinput > .textbox-input-box > .textbox-input::-moz-placeholder {
|
||||
color: hsl(208,10%,66%);
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
.devtools-no-search-result {
|
||||
box-shadow: inset 0 0 0 1px hsla(0,68%,6%,.35);
|
||||
border-color: hsl(10,70%,40%) hsl(10,75%,37%) hsl(10,80%,35%) !important;
|
||||
background-image: url(magnifying-glass.png), linear-gradient(hsla(1,16%,76%,.45), hsla(1,16%,76%,.75));
|
||||
border-color: #eb5368 !important;
|
||||
}
|
||||
|
||||
/* Close button */
|
||||
@ -549,21 +537,24 @@
|
||||
#toolbox-tabs .devtools-tab[selected=true] {
|
||||
color: #f5f7fa;
|
||||
background-color: #1a4666;
|
||||
border-width: 0;
|
||||
box-shadow: 0 2px 0 #d7f1ff inset,
|
||||
0 8px 3px -5px #2b82bf inset,
|
||||
0 -2px 0 rgba(0,0,0,.2) inset;
|
||||
}
|
||||
|
||||
.devtools-tab[selected=true]:not(:first-child) {
|
||||
.devtools-tab[selected=true]:not(:first-child),
|
||||
.devtools-tab.highlighted:not(:first-child) {
|
||||
border-width: 0;
|
||||
-moz-padding-start: 1px;
|
||||
}
|
||||
|
||||
.devtools-tab[selected=true]:last-child {
|
||||
.devtools-tab[selected=true]:last-child,
|
||||
.devtools-tab.highlighted:last-child {
|
||||
-moz-padding-end: 1px;
|
||||
}
|
||||
|
||||
.devtools-tab[selected=true] + .devtools-tab {
|
||||
.devtools-tab[selected=true] + .devtools-tab,
|
||||
.devtools-tab.highlighted + .devtools-tab {
|
||||
-moz-border-start-width: 0;
|
||||
-moz-padding-start: 1px;
|
||||
}
|
||||
|
@ -1082,7 +1082,7 @@ nsXBLBinding::DoInitJSClass(JSContext *cx, JS::Handle<JSObject*> global,
|
||||
bool
|
||||
nsXBLBinding::AllowScripts()
|
||||
{
|
||||
return mPrototypeBinding->GetAllowScripts();
|
||||
return mBoundElement && mPrototypeBinding->GetAllowScripts();
|
||||
}
|
||||
|
||||
nsXBLBinding*
|
||||
|
@ -1808,6 +1808,12 @@ Navigator::HasFMRadioSupport(JSContext* /* unused */, JSObject* aGlobal)
|
||||
bool
|
||||
Navigator::HasNfcSupport(JSContext* /* unused */, JSObject* aGlobal)
|
||||
{
|
||||
// Do not support NFC if NFC content helper does not exist.
|
||||
nsCOMPtr<nsISupports> contentHelper = do_GetService("@mozilla.org/nfc/content-helper;1");
|
||||
if (!contentHelper) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
|
||||
return win && (CheckPermission(win, "nfc-read") ||
|
||||
CheckPermission(win, "nfc-write"));
|
||||
|
@ -484,10 +484,6 @@ TabParent::UpdateDimensions(const nsRect& rect, const nsIntSize& size)
|
||||
mOrientation = orientation;
|
||||
|
||||
unused << SendUpdateDimensions(mRect, mDimensions, mOrientation);
|
||||
if (RenderFrameParent* rfp = GetRenderFrame()) {
|
||||
rfp->NotifyDimensionsChanged(ScreenIntSize::FromUnknownSize(
|
||||
gfx::IntSize(mDimensions.width, mDimensions.height)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1687,12 +1683,6 @@ TabParent::RecvPRenderFrameConstructor(PRenderFrameParent* actor,
|
||||
TextureFactoryIdentifier* factoryIdentifier,
|
||||
uint64_t* layersId)
|
||||
{
|
||||
RenderFrameParent* rfp = GetRenderFrame();
|
||||
if (mDimensions != nsIntSize() && rfp) {
|
||||
rfp->NotifyDimensionsChanged(ScreenIntSize::FromUnknownSize(
|
||||
gfx::IntSize(mDimensions.width, mDimensions.height)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ dictionary MmsDeliveryInfo
|
||||
// |delivery| = "received" or not yet read).
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(4ca3a456-0e25-4331-974a-a8f11a5efb4b)]
|
||||
[scriptable, builtinclass, uuid(f41d7400-0026-11e3-829d-eb7459c03810)]
|
||||
interface nsIDOMMozMmsMessage : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -61,6 +61,10 @@ interface nsIDOMMozMmsMessage : nsISupports
|
||||
|
||||
readonly attribute DOMTimeStamp timestamp;
|
||||
|
||||
readonly attribute DOMTimeStamp sentTimestamp;
|
||||
// 0 if not available (e.g., |delivery| =
|
||||
// "sending").
|
||||
|
||||
readonly attribute boolean read;
|
||||
readonly attribute DOMString subject;
|
||||
readonly attribute DOMString smil;
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "domstubs.idl"
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, builtinclass, uuid(c591dcf8-5322-11e3-899e-9baad640ca82)]
|
||||
[scriptable, builtinclass, uuid(fc8153d2-0026-11e3-bf31-8b0c1d5e7638)]
|
||||
interface nsIDOMMozSmsMessage : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -52,6 +52,10 @@ interface nsIDOMMozSmsMessage : nsISupports
|
||||
|
||||
readonly attribute DOMTimeStamp timestamp;
|
||||
|
||||
readonly attribute DOMTimeStamp sentTimestamp;
|
||||
// 0 if not available (e.g., |delivery| =
|
||||
// "sending").
|
||||
|
||||
readonly attribute DOMTimeStamp deliveryTimestamp;
|
||||
// 0 if not available (e.g., |delivery| =
|
||||
// "received" or not yet delivered).
|
||||
|
@ -14,7 +14,7 @@ interface nsIDOMMozSmsSegmentInfo;
|
||||
#define MOBILE_MESSAGE_SERVICE_CONTRACTID "@mozilla.org/mobilemessage/mobilemessageservice;1"
|
||||
%}
|
||||
|
||||
[scriptable, builtinclass, uuid(7255f557-0dd1-42f9-82fa-031cebb76bb5)]
|
||||
[scriptable, builtinclass, uuid(67d038b2-0039-11e3-9fd3-83de190730f7)]
|
||||
interface nsIMobileMessageService : nsISupports
|
||||
{
|
||||
[implicit_jscontext]
|
||||
@ -28,6 +28,7 @@ interface nsIMobileMessageService : nsISupports
|
||||
in DOMString body,
|
||||
in DOMString messageClass,
|
||||
in jsval timestamp,
|
||||
in jsval sentTimestamp,
|
||||
in jsval deliveryTimestamp,
|
||||
in bool read);
|
||||
|
||||
@ -40,6 +41,7 @@ interface nsIMobileMessageService : nsISupports
|
||||
in DOMString sender,
|
||||
in jsval receivers,
|
||||
in jsval timestamp,
|
||||
in jsval sentTimestamp,
|
||||
in boolean read,
|
||||
in DOMString subject,
|
||||
in DOMString smil,
|
||||
|
@ -43,6 +43,7 @@ MmsMessage::MmsMessage(int32_t aId,
|
||||
const nsAString& aSender,
|
||||
const nsTArray<nsString>& aReceivers,
|
||||
uint64_t aTimestamp,
|
||||
uint64_t aSentTimestamp,
|
||||
bool aRead,
|
||||
const nsAString& aSubject,
|
||||
const nsAString& aSmil,
|
||||
@ -57,6 +58,7 @@ MmsMessage::MmsMessage(int32_t aId,
|
||||
mSender(aSender),
|
||||
mReceivers(aReceivers),
|
||||
mTimestamp(aTimestamp),
|
||||
mSentTimestamp(aSentTimestamp),
|
||||
mRead(aRead),
|
||||
mSubject(aSubject),
|
||||
mSmil(aSmil),
|
||||
@ -74,6 +76,7 @@ MmsMessage::MmsMessage(const mobilemessage::MmsMessageData& aData)
|
||||
, mSender(aData.sender())
|
||||
, mReceivers(aData.receivers())
|
||||
, mTimestamp(aData.timestamp())
|
||||
, mSentTimestamp(aData.sentTimestamp())
|
||||
, mRead(aData.read())
|
||||
, mSubject(aData.subject())
|
||||
, mSmil(aData.smil())
|
||||
@ -173,6 +176,7 @@ MmsMessage::Create(int32_t aId,
|
||||
const nsAString& aSender,
|
||||
const JS::Value& aReceivers,
|
||||
const JS::Value& aTimestamp,
|
||||
const JS::Value& aSentTimestamp,
|
||||
bool aRead,
|
||||
const nsAString& aSubject,
|
||||
const nsAString& aSmil,
|
||||
@ -256,6 +260,11 @@ MmsMessage::Create(int32_t aId,
|
||||
nsresult rv = convertTimeToInt(aCx, aTimestamp, timestamp);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set |sentTimestamp|.
|
||||
uint64_t sentTimestamp;
|
||||
rv = convertTimeToInt(aCx, aSentTimestamp, sentTimestamp);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set |attachments|.
|
||||
if (!aAttachments.isObject()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
@ -294,6 +303,7 @@ MmsMessage::Create(int32_t aId,
|
||||
aSender,
|
||||
receivers,
|
||||
timestamp,
|
||||
sentTimestamp,
|
||||
aRead,
|
||||
aSubject,
|
||||
aSmil,
|
||||
@ -317,6 +327,7 @@ MmsMessage::GetData(ContentParent* aParent,
|
||||
aData.sender().Assign(mSender);
|
||||
aData.receivers() = mReceivers;
|
||||
aData.timestamp() = mTimestamp;
|
||||
aData.sentTimestamp() = mSentTimestamp;
|
||||
aData.read() = mRead;
|
||||
aData.subject() = mSubject;
|
||||
aData.smil() = mSmil;
|
||||
@ -570,6 +581,13 @@ MmsMessage::GetTimestamp(DOMTimeStamp* aTimestamp)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MmsMessage::GetSentTimestamp(DOMTimeStamp* aSentTimestamp)
|
||||
{
|
||||
*aSentTimestamp = mSentTimestamp;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MmsMessage::GetRead(bool* aRead)
|
||||
{
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
const nsAString& aSender,
|
||||
const nsTArray<nsString>& aReceivers,
|
||||
uint64_t aTimestamp,
|
||||
uint64_t aSentTimestamp,
|
||||
bool aRead,
|
||||
const nsAString& aSubject,
|
||||
const nsAString& aSmil,
|
||||
@ -52,6 +53,7 @@ public:
|
||||
const nsAString& aSender,
|
||||
const JS::Value& aReceivers,
|
||||
const JS::Value& aTimestamp,
|
||||
const JS::Value& aSentTimestamp,
|
||||
bool aRead,
|
||||
const nsAString& aSubject,
|
||||
const nsAString& aSmil,
|
||||
@ -74,6 +76,7 @@ private:
|
||||
nsString mSender;
|
||||
nsTArray<nsString> mReceivers;
|
||||
uint64_t mTimestamp;
|
||||
uint64_t mSentTimestamp;
|
||||
bool mRead;
|
||||
nsString mSubject;
|
||||
nsString mSmil;
|
||||
|
@ -39,6 +39,7 @@ MobileMessageService::CreateSmsMessage(int32_t aId,
|
||||
const nsAString& aBody,
|
||||
const nsAString& aMessageClass,
|
||||
const JS::Value& aTimestamp,
|
||||
const JS::Value& aSentTimestamp,
|
||||
const JS::Value& aDeliveryTimestamp,
|
||||
const bool aRead,
|
||||
JSContext* aCx,
|
||||
@ -54,6 +55,7 @@ MobileMessageService::CreateSmsMessage(int32_t aId,
|
||||
aBody,
|
||||
aMessageClass,
|
||||
aTimestamp,
|
||||
aSentTimestamp,
|
||||
aDeliveryTimestamp,
|
||||
aRead,
|
||||
aCx,
|
||||
@ -69,6 +71,7 @@ MobileMessageService::CreateMmsMessage(int32_t aId,
|
||||
const nsAString& aSender,
|
||||
const JS::Value& aReceivers,
|
||||
const JS::Value& aTimestamp,
|
||||
const JS::Value& aSentTimestamp,
|
||||
bool aRead,
|
||||
const nsAString& aSubject,
|
||||
const nsAString& aSmil,
|
||||
@ -86,6 +89,7 @@ MobileMessageService::CreateMmsMessage(int32_t aId,
|
||||
aSender,
|
||||
aReceivers,
|
||||
aTimestamp,
|
||||
aSentTimestamp,
|
||||
aRead,
|
||||
aSubject,
|
||||
aSmil,
|
||||
|
@ -36,10 +36,11 @@ SmsMessage::SmsMessage(int32_t aId,
|
||||
const nsString& aBody,
|
||||
MessageClass aMessageClass,
|
||||
uint64_t aTimestamp,
|
||||
uint64_t aSentTimestamp,
|
||||
uint64_t aDeliveryTimestamp,
|
||||
bool aRead)
|
||||
: mData(aId, aThreadId, aIccId, aDelivery, aDeliveryStatus,
|
||||
aSender, aReceiver, aBody, aMessageClass, aTimestamp,
|
||||
aSender, aReceiver, aBody, aMessageClass, aTimestamp, aSentTimestamp,
|
||||
aDeliveryTimestamp, aRead)
|
||||
{
|
||||
}
|
||||
@ -60,6 +61,7 @@ SmsMessage::Create(int32_t aId,
|
||||
const nsAString& aBody,
|
||||
const nsAString& aMessageClass,
|
||||
const JS::Value& aTimestamp,
|
||||
const JS::Value& aSentTimestamp,
|
||||
const JS::Value& aDeliveryTimestamp,
|
||||
const bool aRead,
|
||||
JSContext* aCx,
|
||||
@ -120,6 +122,10 @@ SmsMessage::Create(int32_t aId,
|
||||
nsresult rv = convertTimeToInt(aCx, aTimestamp, data.timestamp());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set |sentTimestamp|.
|
||||
rv = convertTimeToInt(aCx, aSentTimestamp, data.sentTimestamp());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set |deliveryTimestamp|.
|
||||
rv = convertTimeToInt(aCx, aDeliveryTimestamp, data.deliveryTimestamp());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -260,9 +266,16 @@ SmsMessage::GetMessageClass(nsAString& aMessageClass)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SmsMessage::GetTimestamp(DOMTimeStamp* aDate)
|
||||
SmsMessage::GetTimestamp(DOMTimeStamp* aTimestamp)
|
||||
{
|
||||
*aDate = mData.timestamp();
|
||||
*aTimestamp = mData.timestamp();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SmsMessage::GetSentTimestamp(DOMTimeStamp* aSentTimestamp)
|
||||
{
|
||||
*aSentTimestamp = mData.sentTimestamp();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
const nsString& aBody,
|
||||
mobilemessage::MessageClass aMessageClass,
|
||||
uint64_t aTimestamp,
|
||||
uint64_t aSentTimestamp,
|
||||
uint64_t aDeliveryTimestamp,
|
||||
bool aRead);
|
||||
SmsMessage(const mobilemessage::SmsMessageData& aData);
|
||||
@ -45,6 +46,7 @@ public:
|
||||
const nsAString& aBody,
|
||||
const nsAString& aMessageClass,
|
||||
const JS::Value& aTimestamp,
|
||||
const JS::Value& aSentTimestamp,
|
||||
const JS::Value& aDeliveryTimestamp,
|
||||
const bool aRead,
|
||||
JSContext* aCx,
|
||||
|
@ -1504,7 +1504,10 @@ MmsService.prototype = {
|
||||
mergeRetrievalConfirmation: function mergeRetrievalConfirmation(mmsConnection,
|
||||
intermediate,
|
||||
savable) {
|
||||
// Prepare timestamp/sentTimestamp.
|
||||
savable.timestamp = Date.now();
|
||||
savable.sentTimestamp = intermediate.headers["date"].getTime();
|
||||
|
||||
savable.receivers = [];
|
||||
// We don't have Bcc in recevied MMS message.
|
||||
for each (let type in ["cc", "to"]) {
|
||||
@ -1572,19 +1575,20 @@ MmsService.prototype = {
|
||||
// because the system message mechamism will rewrap the object
|
||||
// based on the content window, which needs to know the properties.
|
||||
gSystemMessenger.broadcastMessage(aName, {
|
||||
type: aDomMessage.type,
|
||||
id: aDomMessage.id,
|
||||
threadId: aDomMessage.threadId,
|
||||
delivery: aDomMessage.delivery,
|
||||
deliveryInfo: aDomMessage.deliveryInfo,
|
||||
sender: aDomMessage.sender,
|
||||
receivers: aDomMessage.receivers,
|
||||
timestamp: aDomMessage.timestamp,
|
||||
read: aDomMessage.read,
|
||||
subject: aDomMessage.subject,
|
||||
smil: aDomMessage.smil,
|
||||
attachments: aDomMessage.attachments,
|
||||
expiryDate: aDomMessage.expiryDate
|
||||
type: aDomMessage.type,
|
||||
id: aDomMessage.id,
|
||||
threadId: aDomMessage.threadId,
|
||||
delivery: aDomMessage.delivery,
|
||||
deliveryInfo: aDomMessage.deliveryInfo,
|
||||
sender: aDomMessage.sender,
|
||||
receivers: aDomMessage.receivers,
|
||||
timestamp: aDomMessage.timestamp,
|
||||
sentTimestamp: aDomMessage.sentTimestamp,
|
||||
read: aDomMessage.read,
|
||||
subject: aDomMessage.subject,
|
||||
smil: aDomMessage.smil,
|
||||
attachments: aDomMessage.attachments,
|
||||
expiryDate: aDomMessage.expiryDate
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -23,7 +23,7 @@ const DEBUG = false;
|
||||
const DISABLE_MMS_GROUPING_FOR_RECEIVING = true;
|
||||
|
||||
|
||||
const DB_VERSION = 20;
|
||||
const DB_VERSION = 21;
|
||||
const MESSAGE_STORE_NAME = "sms";
|
||||
const THREAD_STORE_NAME = "thread";
|
||||
const PARTICIPANT_STORE_NAME = "participant";
|
||||
@ -218,6 +218,10 @@ MobileMessageDB.prototype = {
|
||||
self.upgradeSchema19(event.target.transaction, next);
|
||||
break;
|
||||
case 20:
|
||||
if (DEBUG) debug("Upgrade to version 21. Add sentTimestamp.");
|
||||
self.upgradeSchema20(event.target.transaction, next);
|
||||
break;
|
||||
case 21:
|
||||
// This will need to be moved for each new version
|
||||
if (DEBUG) debug("Upgrade finished.");
|
||||
break;
|
||||
@ -1265,6 +1269,32 @@ MobileMessageDB.prototype = {
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Add sentTimestamp.
|
||||
*/
|
||||
upgradeSchema20: function upgradeSchema20(transaction, next) {
|
||||
let messageStore = transaction.objectStore(MESSAGE_STORE_NAME);
|
||||
messageStore.openCursor().onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (!cursor) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
let messageRecord = cursor.value;
|
||||
messageRecord.sentTimestamp = 0;
|
||||
|
||||
// We can still have changes to assign |sentTimestamp| for the existing
|
||||
// MMS message records.
|
||||
if (messageRecord.type == "mms" && messageRecord.headers["date"]) {
|
||||
messageRecord.sentTimestamp = messageRecord.headers["date"].getTime();
|
||||
}
|
||||
|
||||
cursor.update(messageRecord);
|
||||
cursor.continue();
|
||||
};
|
||||
},
|
||||
|
||||
matchParsedPhoneNumbers: function matchParsedPhoneNumbers(addr1, parsedAddr1,
|
||||
addr2, parsedAddr2) {
|
||||
if ((parsedAddr1.internationalNumber &&
|
||||
@ -1328,6 +1358,7 @@ MobileMessageDB.prototype = {
|
||||
aMessageRecord.body,
|
||||
aMessageRecord.messageClass,
|
||||
aMessageRecord.timestamp,
|
||||
aMessageRecord.sentTimestamp,
|
||||
aMessageRecord.deliveryTimestamp,
|
||||
aMessageRecord.read);
|
||||
} else if (aMessageRecord.type == "mms") {
|
||||
@ -1383,6 +1414,7 @@ MobileMessageDB.prototype = {
|
||||
aMessageRecord.sender,
|
||||
aMessageRecord.receivers,
|
||||
aMessageRecord.timestamp,
|
||||
aMessageRecord.sentTimestamp,
|
||||
aMessageRecord.read,
|
||||
subject,
|
||||
smil,
|
||||
@ -1884,6 +1916,13 @@ MobileMessageDB.prototype = {
|
||||
messageRecord.delivery = delivery;
|
||||
messageRecord.deliveryIndex = [delivery, messageRecord.timestamp];
|
||||
isRecordUpdated = true;
|
||||
|
||||
// When updating an message's delivey state to 'sent', we also update
|
||||
// its |sentTimestamp| by the current device timestamp to represent
|
||||
// when the message is successfully sent.
|
||||
if (delivery == DELIVERY_SENT) {
|
||||
messageRecord.sentTimestamp = Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to update |deliveryStatus| and |deliveryTimestamp| of:
|
||||
@ -2080,6 +2119,11 @@ MobileMessageDB.prototype = {
|
||||
aMessage.readIndex = [FILTER_READ_UNREAD, timestamp];
|
||||
aMessage.read = FILTER_READ_UNREAD;
|
||||
|
||||
// If |sentTimestamp| is not specified, use 0 as default.
|
||||
if (aMessage.sentTimestamp == undefined) {
|
||||
aMessage.sentTimestamp = 0;
|
||||
}
|
||||
|
||||
if (aMessage.type == "mms") {
|
||||
aMessage.transactionIdIndex = aMessage.headers["x-mms-transaction-id"];
|
||||
aMessage.isReadReportSent = false;
|
||||
@ -2171,6 +2215,9 @@ MobileMessageDB.prototype = {
|
||||
aMessage.messageClass = MESSAGE_CLASS_NORMAL;
|
||||
aMessage.read = FILTER_READ_READ;
|
||||
|
||||
// |sentTimestamp| is not available when the message is still sedning.
|
||||
aMessage.sentTimestamp = 0;
|
||||
|
||||
let addresses;
|
||||
if (aMessage.type == "sms") {
|
||||
addresses = [aMessage.receiver];
|
||||
|
@ -36,6 +36,7 @@ struct SmsMessageData
|
||||
nsString body;
|
||||
MessageClass messageClass;
|
||||
uint64_t timestamp; // ms since epoch.
|
||||
uint64_t sentTimestamp; // ms since epoch.
|
||||
uint64_t deliveryTimestamp; // ms since epoch.
|
||||
bool read;
|
||||
};
|
||||
@ -65,12 +66,13 @@ struct MmsMessageData
|
||||
MmsDeliveryInfoData[] deliveryInfo;
|
||||
nsString sender;
|
||||
nsString[] receivers;
|
||||
uint64_t timestamp;
|
||||
uint64_t timestamp; // ms since epoch.
|
||||
uint64_t sentTimestamp; // ms since epoch.
|
||||
bool read;
|
||||
nsString subject;
|
||||
nsString smil;
|
||||
MmsAttachmentData[] attachments;
|
||||
uint64_t expiryDate;
|
||||
uint64_t expiryDate; // ms since epoch.
|
||||
bool readReportRequested;
|
||||
};
|
||||
|
||||
|
@ -20,7 +20,9 @@ let outSmsId = 0;
|
||||
let inThreadId = 0;
|
||||
let outThreadId = 0;
|
||||
let inSmsTimeStamp;
|
||||
let inSmsSentTimeStamp;
|
||||
let outSmsTimeStamp;
|
||||
let outSmsSentTimeStamp;
|
||||
|
||||
function verifyInitialState() {
|
||||
log("Verifying initial state.");
|
||||
@ -49,6 +51,7 @@ function simulateIncomingSms() {
|
||||
is(incomingSms.sender, REMOTE, "sender");
|
||||
is(incomingSms.messageClass, "normal", "messageClass");
|
||||
inSmsTimeStamp = incomingSms.timestamp;
|
||||
inSmsSentTimeStamp = incomingSms.sentTimestamp;
|
||||
sendSms();
|
||||
};
|
||||
// Simulate incoming sms sent from remoteNumber to our emulator
|
||||
@ -77,6 +80,7 @@ function sendSms() {
|
||||
is(sentSms.sender, EMULATOR, "sender");
|
||||
is(sentSms.messageClass, "normal", "messageClass");
|
||||
outSmsTimeStamp = sentSms.timestamp;
|
||||
outSmsSentTimeStamp = sentSms.sentTimestamp;
|
||||
is(sentSms.deliveryTimestamp, 0, "deliveryTimestamp is 0");
|
||||
|
||||
if (gotSmsOnsent && gotReqOnsuccess) { getReceivedSms(); }
|
||||
@ -127,6 +131,7 @@ function getReceivedSms() {
|
||||
is(foundSms.sender, REMOTE, "sender");
|
||||
is(foundSms.messageClass, "normal", "messageClass");
|
||||
is(foundSms.timestamp, inSmsTimeStamp, "timestamp matches");
|
||||
is(foundSms.sentTimestamp, inSmsSentTimeStamp, "sentTimestamp matches");
|
||||
getSentSms();
|
||||
};
|
||||
|
||||
@ -160,6 +165,7 @@ function getSentSms() {
|
||||
is(foundSms.sender, EMULATOR, "sender");
|
||||
is(foundSms.messageClass, "normal", "messageClass");
|
||||
is(foundSms.timestamp, outSmsTimeStamp, "timestamp matches");
|
||||
is(foundSms.sentTimestamp, outSmsSentTimeStamp, "sentTimestamp matches");
|
||||
deleteMsgs();
|
||||
};
|
||||
|
||||
|
@ -202,6 +202,7 @@ function verifyFoundMsgs(foundSmsList, reverse) {
|
||||
|
||||
isIn(foundSmsList[x].sender, [smsList[x].sender, "+15552229797"], "sender");
|
||||
is(foundSmsList[x].timestamp, smsList[x].timestamp, "timestamp");
|
||||
is(foundSmsList[x].sentTimestamp, smsList[x].sentTimestamp, "sentTimestamp");
|
||||
}
|
||||
|
||||
log("Content in all of the returned SMS messages is correct.");
|
||||
|
@ -13,6 +13,8 @@ const PDU_TIMESTAMP = "00101000000000"; // 2000/01/01
|
||||
const PDU_UDL = "01";
|
||||
const PDU_UD = "41";
|
||||
|
||||
const SENT_TIMESTAMP = Date.UTC(2000, 0, 1); // Must be equal to PDU_TIMESTAMP.
|
||||
|
||||
SpecialPowers.addPermission("sms", true, document);
|
||||
|
||||
let manager = window.navigator.mozMobileMessage;
|
||||
@ -70,6 +72,8 @@ function test_message_class_0() {
|
||||
"Message's timestamp should be greater then the timetamp of sending");
|
||||
ok(event.message.timestamp <= Date.now(),
|
||||
"Message's timestamp should be lesser than the timestamp of now");
|
||||
is(event.message.sentTimestamp, SENT_TIMESTAMP,
|
||||
"Message's sentTimestamp should be equal to SENT_TIMESTAMP");
|
||||
|
||||
// Make sure the message is not stored.
|
||||
let cursor = manager.getMessages(null, false);
|
||||
@ -118,6 +122,8 @@ function doTestMessageClassGeneric(allDCSs, messageClass, next) {
|
||||
"Message's timestamp should be greater then the timetamp of sending");
|
||||
ok(event.message.timestamp <= Date.now(),
|
||||
"Message's timestamp should be lesser than the timestamp of now");
|
||||
is(event.message.sentTimestamp, SENT_TIMESTAMP,
|
||||
"Message's sentTimestamp should be equal to SENT_TIMESTAMP");
|
||||
|
||||
++dcsIndex;
|
||||
if (dcsIndex >= allDCSs.length) {
|
||||
@ -173,6 +179,8 @@ function test_message_class_2() {
|
||||
"Message's timestamp should be greater then the timetamp of sending");
|
||||
ok(event.message.timestamp <= Date.now(),
|
||||
"Message's timestamp should be lesser than the timestamp of now");
|
||||
is(event.message.sentTimestamp, SENT_TIMESTAMP,
|
||||
"Message's sentTimestamp should be equal to SENT_TIMESTAMP");
|
||||
|
||||
next();
|
||||
return;
|
||||
|
@ -43,11 +43,17 @@ function checkMessage(message, delivery, body) {
|
||||
ok(message.receiver, "message.receiver");
|
||||
is(message.body, body, "message.body");
|
||||
is(message.messageClass, "normal", "message.messageClass");
|
||||
is(message.read, true, "message.read");
|
||||
|
||||
// TODO: bug 788928 - add test cases for deliverysuccess event.
|
||||
is(message.deliveryTimestamp, 0, "deliveryTimestamp is 0");
|
||||
|
||||
is(message.read, true, "message.read");
|
||||
// Test message.sentTimestamp.
|
||||
if (message.delivery == "sending") {
|
||||
ok(message.sentTimestamp == 0, "message.sentTimestamp should be 0");
|
||||
} else if (message.delivery == "sent") {
|
||||
ok(message.sentTimestamp != 0, "message.sentTimestamp shouldn't be 0");
|
||||
}
|
||||
}
|
||||
|
||||
function doSendMessageAndCheckSuccess(receivers, body, callback) {
|
||||
@ -90,8 +96,7 @@ function doSendMessageAndCheckSuccess(receivers, body, callback) {
|
||||
is(message.id, saved.id, "message.id");
|
||||
is(message.receiver, saved.receiver, "message.receiver");
|
||||
is(message.body, saved.body, "message.body");
|
||||
is(message.timestamp, saved.timestamp,
|
||||
"the messages got from onsent event and request result must be the same");
|
||||
is(message.timestamp, saved.timestamp, "message.timestamp");
|
||||
|
||||
opt[mark] = true;
|
||||
|
||||
|
@ -33,7 +33,7 @@ function run_test() {
|
||||
*/
|
||||
add_test(function test_interface() {
|
||||
let sms = newMessage(null, null, ICC_ID, "sent", "success", null, null, null,
|
||||
"normal", new Date(), 0, true);
|
||||
"normal", new Date(), new Date(), new Date(), true);
|
||||
do_check_true(sms instanceof Ci.nsIDOMMozSmsMessage);
|
||||
do_check_eq(sms.id, 0);
|
||||
do_check_eq(sms.threadId, 0);
|
||||
@ -44,7 +44,6 @@ add_test(function test_interface() {
|
||||
do_check_eq(sms.sender, null);
|
||||
do_check_eq(sms.body, null);
|
||||
do_check_eq(sms.messageClass, "normal");
|
||||
do_check_eq(sms.deliveryTimestamp, 0);
|
||||
do_check_true(sms.read);
|
||||
run_next_test();
|
||||
});
|
||||
@ -54,7 +53,7 @@ add_test(function test_interface() {
|
||||
*/
|
||||
add_test(function test_icc_id_not_available() {
|
||||
let sms = newMessage(null, null, null, "sent", "success", null, null, null,
|
||||
"normal", new Date(), 0, true);
|
||||
"normal", new Date(), new Date(), new Date(), true);
|
||||
do_check_true(sms instanceof Ci.nsIDOMMozSmsMessage);
|
||||
do_check_eq(sms.id, 0);
|
||||
do_check_eq(sms.threadId, 0);
|
||||
@ -65,7 +64,6 @@ add_test(function test_icc_id_not_available() {
|
||||
do_check_eq(sms.sender, null);
|
||||
do_check_eq(sms.body, null);
|
||||
do_check_eq(sms.messageClass, "normal");
|
||||
do_check_eq(sms.deliveryTimestamp, 0);
|
||||
do_check_true(sms.read);
|
||||
run_next_test();
|
||||
});
|
||||
@ -74,8 +72,8 @@ add_test(function test_icc_id_not_available() {
|
||||
* Verify that attributes are read-only.
|
||||
*/
|
||||
add_test(function test_readonly_attributes() {
|
||||
let sms = newMessage(null, null, ICC_ID, "received", "success", null, null, null,
|
||||
"normal", new Date(), 0, true);
|
||||
let sms = newMessage(null, null, ICC_ID, "sent", "success", null, null, null,
|
||||
"normal", new Date(), new Date(), new Date(), true);
|
||||
|
||||
sms.id = 1;
|
||||
do_check_eq(sms.id, 0);
|
||||
@ -86,8 +84,8 @@ add_test(function test_readonly_attributes() {
|
||||
sms.iccId = "987654321";
|
||||
do_check_eq(sms.iccId, ICC_ID);
|
||||
|
||||
sms.delivery = "sent";
|
||||
do_check_eq(sms.delivery, "received");
|
||||
sms.delivery = "received";
|
||||
do_check_eq(sms.delivery, "sent");
|
||||
|
||||
sms.deliveryStatus = "pending";
|
||||
do_check_eq(sms.deliveryStatus, "success");
|
||||
@ -108,6 +106,10 @@ add_test(function test_readonly_attributes() {
|
||||
sms.timestamp = Date.now();
|
||||
do_check_eq(sms.timestamp, oldTimestamp);
|
||||
|
||||
let oldSentTimestamp = sms.sentTimestamp;
|
||||
sms.sentTimestamp = Date.now();
|
||||
do_check_eq(sms.sentTimestamp, oldSentTimestamp);
|
||||
|
||||
let oldDeliveryTimestamp = sms.deliveryTimestamp;
|
||||
sms.deliveryTimestamp = Date.now();
|
||||
do_check_eq(sms.deliveryTimestamp, oldDeliveryTimestamp);
|
||||
@ -124,7 +126,7 @@ add_test(function test_readonly_attributes() {
|
||||
add_test(function test_timestamp_number() {
|
||||
let ts = Date.now();
|
||||
let sms = newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", ts, 0, true);
|
||||
"the body", "normal", ts, ts, ts, true);
|
||||
do_check_eq(sms.id, 42);
|
||||
do_check_eq(sms.threadId, 1);
|
||||
do_check_eq(sms.iccId, ICC_ID);
|
||||
@ -135,7 +137,8 @@ add_test(function test_timestamp_number() {
|
||||
do_check_eq(sms.body, "the body");
|
||||
do_check_eq(sms.messageClass, "normal");
|
||||
do_check_eq(sms.timestamp, ts);
|
||||
do_check_eq(sms.deliveryTimestamp, 0);
|
||||
do_check_eq(sms.sentTimestamp, ts);
|
||||
do_check_eq(sms.deliveryTimestamp, ts);
|
||||
do_check_true(sms.read);
|
||||
run_next_test();
|
||||
});
|
||||
@ -146,7 +149,7 @@ add_test(function test_timestamp_number() {
|
||||
add_test(function test_timestamp_date() {
|
||||
let date = new Date();
|
||||
let sms = newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", date, 0, true);
|
||||
"the body", "normal", date, date, date, true);
|
||||
do_check_eq(sms.id, 42);
|
||||
do_check_eq(sms.threadId, 1);
|
||||
do_check_eq(sms.iccId, ICC_ID);
|
||||
@ -157,7 +160,8 @@ add_test(function test_timestamp_date() {
|
||||
do_check_eq(sms.body, "the body");
|
||||
do_check_eq(sms.messageClass, "normal");
|
||||
do_check_eq(sms.timestamp, date.getTime());
|
||||
do_check_eq(sms.deliveryTimestamp, 0);
|
||||
do_check_eq(sms.sentTimestamp, date.getTime());
|
||||
do_check_eq(sms.deliveryTimestamp, date.getTime());
|
||||
do_check_true(sms.read);
|
||||
run_next_test();
|
||||
});
|
||||
@ -169,13 +173,19 @@ add_test(function test_invalid_timestamp_float() {
|
||||
// Test timestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", 3.1415, 0, true);
|
||||
"the body", "normal", 3.1415, new Date(), new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test sentTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", new Date(), 3.1415, new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test deliveryTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", 0, 3.1415, true);
|
||||
"the body", "normal", new Date(), new Date(), 3.1415, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
run_next_test();
|
||||
@ -188,13 +198,19 @@ add_test(function test_invalid_timestamp_null() {
|
||||
// Test timestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", null, 0, true);
|
||||
"the body", "normal", null, new Date(), new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test sentTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", new Date(), null, new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test deliveryTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", 0, null, true);
|
||||
"the body", "normal", new Date(), new Date(), null, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
run_next_test();
|
||||
@ -207,13 +223,19 @@ add_test(function test_invalid_timestamp_undefined() {
|
||||
// Test timestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", undefined, 0, true);
|
||||
"the body", "normal", undefined, new Date(), new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test sentTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", new Date(), undefined, new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test deliveryTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", 0, undefined, true);
|
||||
"the body", "normal", new Date(), new Date(), undefined, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
run_next_test();
|
||||
@ -226,13 +248,19 @@ add_test(function test_invalid_timestamp_object() {
|
||||
// Test timestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", {}, 0, true);
|
||||
"the body", "normal", {}, new Date(), new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test sentTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", new Date(), {}, new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test deliveryTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", 0, {}, true);
|
||||
"the body", "normal", new Date(), new Date(), {}, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
run_next_test();
|
||||
@ -244,7 +272,7 @@ add_test(function test_invalid_timestamp_object() {
|
||||
add_test(function test_invalid_delivery_string() {
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "this is invalid", "pending", "the sender",
|
||||
"the receiver", "the body", "normal", new Date(), 0, true);
|
||||
"the receiver", "the body", "normal", new Date(), 0, 0, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
run_next_test();
|
||||
});
|
||||
@ -255,7 +283,7 @@ add_test(function test_invalid_delivery_string() {
|
||||
add_test(function test_invalid_delivery_string() {
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, 1, "pending", "the sender", "the receiver", "the body",
|
||||
"normal", new Date(), 0, true);
|
||||
"normal", new Date(), 0, 0, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
run_next_test();
|
||||
});
|
||||
@ -266,7 +294,7 @@ add_test(function test_invalid_delivery_string() {
|
||||
add_test(function test_invalid_delivery_status_string() {
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "this is invalid", "the sender", "the receiver",
|
||||
"the body", "normal", new Date(), 0, true);
|
||||
"the body", "normal", new Date(), new Date(), 0, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
run_next_test();
|
||||
});
|
||||
@ -277,7 +305,7 @@ add_test(function test_invalid_delivery_status_string() {
|
||||
add_test(function test_invalid_delivery_status_string() {
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", 1, "the sender", "the receiver", "the body",
|
||||
"normal", new Date(), 0, true);
|
||||
"normal", new Date(), new Date(), 0, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
run_next_test();
|
||||
});
|
||||
@ -288,7 +316,7 @@ add_test(function test_invalid_delivery_status_string() {
|
||||
add_test(function test_invalid_message_class_string() {
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "this is invalid", new Date(), 0, true);
|
||||
"the body", "this is invalid", new Date(), new Date(), new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
run_next_test();
|
||||
});
|
||||
@ -299,7 +327,7 @@ add_test(function test_invalid_message_class_string() {
|
||||
add_test(function test_invalid_message_class_string() {
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", 1, new Date(), 0, true);
|
||||
"the body", 1, new Date(), new Date(), new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -2010,6 +2010,7 @@ RadioInterface.prototype = {
|
||||
body: aDomMessage.body,
|
||||
messageClass: aDomMessage.messageClass,
|
||||
timestamp: aDomMessage.timestamp,
|
||||
sentTimestamp: aDomMessage.sentTimestamp,
|
||||
deliveryTimestamp: aDomMessage.deliveryTimestamp,
|
||||
read: aDomMessage.read
|
||||
});
|
||||
@ -2099,6 +2100,7 @@ RadioInterface.prototype = {
|
||||
message.body,
|
||||
message.messageClass,
|
||||
message.timestamp,
|
||||
message.sentTimestamp,
|
||||
0,
|
||||
message.read);
|
||||
|
||||
@ -2168,6 +2170,7 @@ RadioInterface.prototype = {
|
||||
message.body,
|
||||
message.messageClass,
|
||||
message.timestamp,
|
||||
message.sentTimestamp,
|
||||
0,
|
||||
message.read);
|
||||
|
||||
@ -3354,6 +3357,7 @@ RadioInterface.prototype = {
|
||||
sms.body,
|
||||
sms.messageClass,
|
||||
sms.timestamp,
|
||||
Date.now(),
|
||||
0,
|
||||
sms.read));
|
||||
// We don't wait for SMS-DELIVER-REPORT for silent one.
|
||||
@ -3394,8 +3398,8 @@ RadioInterface.prototype = {
|
||||
};
|
||||
|
||||
if (silent) {
|
||||
let deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_PENDING;
|
||||
let delivery = DOM_MOBILE_MESSAGE_DELIVERY_SENDING;
|
||||
let deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_PENDING;
|
||||
let domMessage =
|
||||
gMobileMessageService.createSmsMessage(-1, // id
|
||||
0, // threadId
|
||||
@ -3408,6 +3412,7 @@ RadioInterface.prototype = {
|
||||
"normal", // message class
|
||||
sendingMessage.timestamp,
|
||||
0,
|
||||
0,
|
||||
false);
|
||||
notifyResult(Cr.NS_OK, domMessage);
|
||||
return;
|
||||
|
@ -7470,7 +7470,7 @@ let GsmPDUHelper = {
|
||||
// - TP-Data-Coding-Scheme -
|
||||
this.readDataCodingScheme(msg);
|
||||
// - TP-Service-Center-Time-Stamp -
|
||||
msg.timestamp = this.readTimestamp();
|
||||
msg.sentTimestamp = this.readTimestamp();
|
||||
// - TP-User-Data-Length -
|
||||
let userDataLength = this.readHexOctet();
|
||||
|
||||
|
@ -553,20 +553,6 @@ APZCTreeManager::ReceiveInputEvent(WidgetInputEvent& aEvent,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
APZCTreeManager::UpdateRootCompositionBounds(const uint64_t& aLayersId,
|
||||
const ScreenIntRect& aCompositionBounds)
|
||||
{
|
||||
// There can be multiple root APZCs for a given layers id (e.g. tabs in
|
||||
// a single-process setup) and in such a case we probably want to notify
|
||||
// all of them.
|
||||
nsTArray< nsRefPtr<AsyncPanZoomController> > rootApzcs;
|
||||
GetRootAPZCsFor(aLayersId, &rootApzcs);
|
||||
for (size_t i = 0; i < rootApzcs.Length(); i++) {
|
||||
rootApzcs[i]->UpdateCompositionBounds(aCompositionBounds);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
APZCTreeManager::ZoomToRect(const ScrollableLayerGuid& aGuid,
|
||||
const CSSRect& aRect)
|
||||
@ -774,17 +760,6 @@ APZCTreeManager::BuildOverscrollHandoffChain(const nsRefPtr<AsyncPanZoomControll
|
||||
CompareByScrollPriority());
|
||||
}
|
||||
|
||||
void
|
||||
APZCTreeManager::GetRootAPZCsFor(const uint64_t& aLayersId,
|
||||
nsTArray< nsRefPtr<AsyncPanZoomController> >* aOutRootApzcs)
|
||||
{
|
||||
MonitorAutoLock lock(mTreeLock);
|
||||
// The root may have siblings, check those too
|
||||
for (AsyncPanZoomController* apzc = mRootApzc; apzc; apzc = apzc->GetPrevSibling()) {
|
||||
FindRootAPZCs(apzc, aLayersId, aOutRootApzcs);
|
||||
}
|
||||
}
|
||||
|
||||
AsyncPanZoomController*
|
||||
APZCTreeManager::FindTargetAPZC(AsyncPanZoomController* aApzc, const ScrollableLayerGuid& aGuid)
|
||||
{
|
||||
@ -861,25 +836,6 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& a
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
APZCTreeManager::FindRootAPZCs(AsyncPanZoomController* aApzc,
|
||||
const uint64_t& aLayersId,
|
||||
nsTArray< nsRefPtr<AsyncPanZoomController> >* aOutRootApzcs)
|
||||
{
|
||||
mTreeLock.AssertCurrentThreadOwns();
|
||||
|
||||
if (aApzc->IsRootForLayersId(aLayersId)) {
|
||||
aOutRootApzcs->AppendElement(aApzc);
|
||||
// If this APZC is a root for this layers id then we know nothing else
|
||||
// in the subtree rooted here will match so we can early-exit
|
||||
return;
|
||||
}
|
||||
|
||||
for (AsyncPanZoomController* child = aApzc->GetLastChild(); child; child = child->GetPrevSibling()) {
|
||||
FindRootAPZCs(child, aLayersId, aOutRootApzcs);
|
||||
}
|
||||
}
|
||||
|
||||
/* This function sets the aTransformToApzcOut and aTransformToGeckoOut out-parameters
|
||||
to some useful transformations that input events may need applied. This is best
|
||||
illustrated with an example. Consider a chain of layers, L, M, N, O, P, Q, R. Layer L
|
||||
|
@ -134,17 +134,6 @@ public:
|
||||
void TransformCoordinateToGecko(const ScreenIntPoint& aPoint,
|
||||
LayoutDeviceIntPoint* aOutTransformedPoint);
|
||||
|
||||
/**
|
||||
* Updates the composition bounds on the root APZC for the given layers id.
|
||||
* See FrameMetrics::mCompositionBounds for the definition of what the
|
||||
* composition bounds are. This function is only meant for updating the
|
||||
* composition bounds on the root APZC because that is the one that is
|
||||
* zoomable, and the zoom may need to be adjusted immediately upon a change
|
||||
* in the composition bounds.
|
||||
*/
|
||||
void UpdateRootCompositionBounds(const uint64_t& aLayersId,
|
||||
const ScreenIntRect& aCompositionBounds);
|
||||
|
||||
/**
|
||||
* Kicks an animation to zoom to a rect. This may be either a zoom out or zoom
|
||||
* in. The actual animation is done on the compositor thread after being set
|
||||
@ -263,17 +252,12 @@ public:
|
||||
*/
|
||||
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScrollableLayerGuid& aGuid);
|
||||
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScreenPoint& aPoint);
|
||||
void GetRootAPZCsFor(const uint64_t& aLayersId,
|
||||
nsTArray< nsRefPtr<AsyncPanZoomController> >* aOutRootApzcs);
|
||||
void GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix& aTransformToApzcOut,
|
||||
gfx3DMatrix& aTransformToGeckoOut);
|
||||
private:
|
||||
/* Helpers */
|
||||
AsyncPanZoomController* FindTargetAPZC(AsyncPanZoomController* aApzc, const ScrollableLayerGuid& aGuid);
|
||||
AsyncPanZoomController* GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& aHitTestPoint);
|
||||
void FindRootAPZCs(AsyncPanZoomController* aApzc,
|
||||
const uint64_t& aLayersId,
|
||||
nsTArray< nsRefPtr<AsyncPanZoomController> >* aOutRootApzcs);
|
||||
already_AddRefed<AsyncPanZoomController> CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2);
|
||||
already_AddRefed<AsyncPanZoomController> RootAPZCForLayersId(AsyncPanZoomController* aApzc);
|
||||
already_AddRefed<AsyncPanZoomController> GetTouchInputBlockAPZC(const WidgetTouchEvent& aEvent, ScreenPoint aPoint);
|
||||
|
@ -1483,28 +1483,6 @@ const FrameMetrics& AsyncPanZoomController::GetFrameMetrics() {
|
||||
return mFrameMetrics;
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::UpdateCompositionBounds(const ScreenIntRect& aCompositionBounds) {
|
||||
ReentrantMonitorAutoEnter lock(mMonitor);
|
||||
|
||||
ScreenIntRect oldCompositionBounds = mFrameMetrics.mCompositionBounds;
|
||||
mFrameMetrics.mCompositionBounds = aCompositionBounds;
|
||||
|
||||
// If the window had 0 dimensions before, or does now, we don't want to
|
||||
// repaint or update the zoom since we'll run into rendering issues and/or
|
||||
// divide-by-zero. This manifests itself as the screen flashing. If the page
|
||||
// has gone out of view, the buffer will be cleared elsewhere anyways.
|
||||
if (aCompositionBounds.width && aCompositionBounds.height &&
|
||||
oldCompositionBounds.width && oldCompositionBounds.height) {
|
||||
float adjustmentFactor = float(aCompositionBounds.width) / float(oldCompositionBounds.width);
|
||||
mFrameMetrics.mZoom.scale =
|
||||
clamped(mFrameMetrics.mZoom.scale * adjustmentFactor,
|
||||
mMinZoom.scale, mMaxZoom.scale);
|
||||
|
||||
// Repaint on a rotation so that our new resolution gets properly updated.
|
||||
RequestContentRepaint();
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
|
||||
SetState(ANIMATING_ZOOM);
|
||||
|
||||
|
@ -104,15 +104,6 @@ public:
|
||||
*/
|
||||
nsEventStatus ReceiveInputEvent(const InputData& aEvent);
|
||||
|
||||
/**
|
||||
* Updates the composition bounds, i.e. the dimensions of the final size of
|
||||
* the frame this is tied to during composition onto, in device pixels. In
|
||||
* general, this will just be:
|
||||
* { x = 0, y = 0, width = surface.width, height = surface.height }, however
|
||||
* there is no hard requirement for this.
|
||||
*/
|
||||
void UpdateCompositionBounds(const ScreenIntRect& aCompositionBounds);
|
||||
|
||||
/**
|
||||
* Kicks an animation to zoom to a rect. This may be either a zoom out or zoom
|
||||
* in. The actual animation is done on the compositor thread after being set
|
||||
|
@ -231,9 +231,11 @@ CompileCompartment::hasObjectMetadataCallback()
|
||||
return compartment()->hasObjectMetadataCallback();
|
||||
}
|
||||
|
||||
#ifdef JS_WORKER_THREADS
|
||||
AutoLockForCompilation::AutoLockForCompilation(CompileCompartment *compartment
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(compartment->compartment()->runtimeFromAnyThread());
|
||||
}
|
||||
#endif
|
||||
|
@ -863,11 +863,19 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||
}
|
||||
|
||||
void addCompilationThread() {
|
||||
#ifdef JS_WORKER_THREADS
|
||||
numCompilationThreads++;
|
||||
#else
|
||||
MOZ_ASSUME_UNREACHABLE("No threads");
|
||||
#endif
|
||||
}
|
||||
void removeCompilationThread() {
|
||||
#ifdef JS_WORKER_THREADS
|
||||
JS_ASSERT(numCompilationThreads);
|
||||
numCompilationThreads--;
|
||||
#else
|
||||
MOZ_ASSUME_UNREACHABLE("No threads");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool compilationThreadsPresent() const {
|
||||
|
@ -910,15 +910,6 @@ RenderFrameParent::NotifyInputEvent(const WidgetInputEvent& aEvent,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RenderFrameParent::NotifyDimensionsChanged(ScreenIntSize size)
|
||||
{
|
||||
if (GetApzcTreeManager()) {
|
||||
GetApzcTreeManager()->UpdateRootCompositionBounds(
|
||||
mLayersId, ScreenIntRect(ScreenIntPoint(), size));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RenderFrameParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
|
@ -110,8 +110,6 @@ public:
|
||||
ScrollableLayerGuid* aOutTargetGuid,
|
||||
WidgetInputEvent* aOutEvent);
|
||||
|
||||
void NotifyDimensionsChanged(ScreenIntSize size);
|
||||
|
||||
void ZoomToRect(uint32_t aPresShellId, ViewID aViewId, const CSSRect& aRect);
|
||||
|
||||
void ContentReceivedTouch(const ScrollableLayerGuid& aGuid,
|
||||
|
@ -119,9 +119,12 @@ class ActionModeCompatView extends LinearLayout implements GeckoMenu.ActionItemB
|
||||
maxWidth = mActionButtonBar.getMeasuredWidth();
|
||||
}
|
||||
|
||||
// Since we don't know how many items will be added, we always reserve space for the overflow menu
|
||||
mMenuButton.measure(SPEC, SPEC);
|
||||
maxWidth -= mMenuButton.getMeasuredWidth();
|
||||
// If the menu button is already visible, no need to account for it
|
||||
if (mMenuButton.getVisibility() == View.GONE) {
|
||||
// Since we don't know how many items will be added, we always reserve space for the overflow menu
|
||||
mMenuButton.measure(SPEC, SPEC);
|
||||
maxWidth -= mMenuButton.getMeasuredWidth();
|
||||
}
|
||||
|
||||
if (mActionButtonsWidth <= 0) {
|
||||
mActionButtonsWidth = 0;
|
||||
@ -142,12 +145,14 @@ class ActionModeCompatView extends LinearLayout implements GeckoMenu.ActionItemB
|
||||
mActionButtonBar.addView(actionItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* GeckoMenu.ActionItemBarPresenter */
|
||||
@Override
|
||||
public void removeActionItem(View actionItem) {
|
||||
actionItem.measure(SPEC, SPEC);
|
||||
mActionButtonsWidth -= actionItem.getMeasuredWidth();
|
||||
mActionButtonBar.removeView(actionItem);
|
||||
}
|
||||
|
@ -171,11 +171,12 @@ public class GeckoMenu extends ListView
|
||||
}
|
||||
});
|
||||
|
||||
mActionItems.put(menuItem, actionView);
|
||||
mActionItemBarPresenter.addActionItem(actionView);
|
||||
mItems.add(menuItem);
|
||||
|
||||
return true;
|
||||
if (mActionItemBarPresenter.addActionItem(actionView)) {
|
||||
mActionItems.put(menuItem, actionView);
|
||||
mItems.add(menuItem);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -10,18 +10,6 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Prompt.jsm");
|
||||
|
||||
// Whitelist of methods we remote - to check against malicious data.
|
||||
// For example, it would be dangerous to allow content to show auth prompts.
|
||||
const REMOTABLE_METHODS = {
|
||||
alert: { outParams: [] },
|
||||
alertCheck: { outParams: [4] },
|
||||
confirm: { outParams: [] },
|
||||
prompt: { outParams: [3, 5] },
|
||||
confirmEx: { outParams: [8] },
|
||||
confirmCheck: { outParams: [4] },
|
||||
select: { outParams: [5] }
|
||||
};
|
||||
|
||||
var gPromptService = null;
|
||||
|
||||
function PromptService() {
|
||||
@ -134,18 +122,21 @@ InternalPrompt.prototype = {
|
||||
PromptUtils.getLocaleString("Cancel")
|
||||
]
|
||||
});
|
||||
return p;
|
||||
},
|
||||
|
||||
addCheckbox: function addCheckbox(aPrompt, aCheckMsg, aCheckState) {
|
||||
// Don't bother to check for aCheckSate. For nsIPomptService interfaces, aCheckState is an
|
||||
// out param and is required to be defined. If we've gotten here without it, something
|
||||
// has probably gone wrong and we should fail
|
||||
if (aCheckMsg) {
|
||||
p.addCheckbox({
|
||||
aPrompt.addCheckbox({
|
||||
label: PromptUtils.cleanUpLabel(aCheckMsg),
|
||||
checked: aCheckState.value
|
||||
});
|
||||
}
|
||||
|
||||
return p;
|
||||
return aPrompt;
|
||||
},
|
||||
|
||||
/* Shows a native prompt, and then spins the event loop for this thread while we wait
|
||||
@ -223,7 +214,8 @@ InternalPrompt.prototype = {
|
||||
},
|
||||
|
||||
alertCheck: function alertCheck(aTitle, aText, aCheckMsg, aCheckState) {
|
||||
let p = this._getPrompt(aTitle, aText, [ PromptUtils.getLocaleString("OK") ], aCheckMsg, aCheckState);
|
||||
let p = this._getPrompt(aTitle, aText, [ PromptUtils.getLocaleString("OK") ]);
|
||||
this.addCheckbox(p, aCheckMsg, aCheckState);
|
||||
let data = this.showPrompt(p);
|
||||
if (aCheckState && data.button > -1)
|
||||
aCheckState.value = data.checkbox0 == "true";
|
||||
@ -237,7 +229,8 @@ InternalPrompt.prototype = {
|
||||
},
|
||||
|
||||
confirmCheck: function confirmCheck(aTitle, aText, aCheckMsg, aCheckState) {
|
||||
let p = this._getPrompt(aTitle, aText, null, aCheckMsg, aCheckState);
|
||||
let p = this._getPrompt(aTitle, aText, null);
|
||||
this.addCheckbox(p, aCheckMsg, aCheckState);
|
||||
let data = this.showPrompt(p);
|
||||
let ok = data.button == 0;
|
||||
if (aCheckState && data.button > -1)
|
||||
@ -284,7 +277,8 @@ InternalPrompt.prototype = {
|
||||
aButtonFlags >>= 8;
|
||||
}
|
||||
|
||||
let p = this._getPrompt(aTitle, aText, buttons, aCheckMsg, aCheckState);
|
||||
let p = this._getPrompt(aTitle, aText, buttons);
|
||||
this.addCheckbox(p, aCheckMsg, aCheckState);
|
||||
let data = this.showPrompt(p);
|
||||
if (aCheckState && data.button > -1)
|
||||
aCheckState.value = data.checkbox0 == "true";
|
||||
@ -298,6 +292,7 @@ InternalPrompt.prototype = {
|
||||
value: aValue.value,
|
||||
autofocus: true
|
||||
});
|
||||
this.addCheckbox(p, aCheckMsg, aCheckState);
|
||||
let data = this.showPrompt(p);
|
||||
|
||||
let ok = data.button == 0;
|
||||
@ -310,12 +305,13 @@ InternalPrompt.prototype = {
|
||||
|
||||
nsIPrompt_promptPassword: function nsIPrompt_promptPassword(
|
||||
aTitle, aText, aPassword, aCheckMsg, aCheckState) {
|
||||
let p = this._getPrompt(aTitle, aText, null, aCheckMsg, aCheckState);
|
||||
let p = this._getPrompt(aTitle, aText, null);
|
||||
p.addPassword({
|
||||
value: aPassword.value || "",
|
||||
autofocus: true,
|
||||
hint: PromptUtils.getLocaleString("password", "passwdmgr")
|
||||
});
|
||||
this.addCheckbox(p, aCheckMsg, aCheckState);
|
||||
let data = this.showPrompt(p);
|
||||
|
||||
let ok = data.button == 0;
|
||||
@ -328,7 +324,7 @@ InternalPrompt.prototype = {
|
||||
|
||||
nsIPrompt_promptUsernameAndPassword: function nsIPrompt_promptUsernameAndPassword(
|
||||
aTitle, aText, aUsername, aPassword, aCheckMsg, aCheckState) {
|
||||
let p = this._getPrompt(aTitle, aText, null, aCheckMsg, aCheckState);
|
||||
let p = this._getPrompt(aTitle, aText, null);
|
||||
p.addTextbox({
|
||||
value: aUsername.value,
|
||||
autofocus: true,
|
||||
@ -337,6 +333,7 @@ InternalPrompt.prototype = {
|
||||
value: aPassword.value,
|
||||
hint: PromptUtils.getLocaleString("password", "passwdmgr")
|
||||
});
|
||||
this.addCheckbox(p, aCheckMsg, aCheckState);
|
||||
let data = this.showPrompt(p);
|
||||
|
||||
let ok = data.button == 0;
|
||||
@ -350,7 +347,7 @@ InternalPrompt.prototype = {
|
||||
},
|
||||
|
||||
select: function select(aTitle, aText, aCount, aSelectList, aOutSelection) {
|
||||
let p = this._getPrompt(aTitle, aText, [ PromptUtils.getLocaleString("OK") ], "", { value: false });
|
||||
let p = this._getPrompt(aTitle, aText, [ PromptUtils.getLocaleString("OK") ]);
|
||||
p.addMenulist({ values: aSelectList });
|
||||
let data = this.showPrompt(p);
|
||||
|
||||
|
@ -356,10 +356,6 @@ body {
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.button:active {
|
||||
background-color: #ff9500;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
|
@ -272,8 +272,8 @@ nsHttpConnection::EnsureNPNComplete()
|
||||
if (NS_FAILED(rv))
|
||||
goto npnComplete;
|
||||
|
||||
LOG(("nsHttpConnection::EnsureNPNComplete %p negotiated to '%s'\n",
|
||||
this, negotiatedNPN.get()));
|
||||
LOG(("nsHttpConnection::EnsureNPNComplete %p [%s] negotiated to '%s'\n",
|
||||
this, mConnInfo->Host(), negotiatedNPN.get()));
|
||||
|
||||
uint8_t spdyVersion;
|
||||
rv = gHttpHandler->SpdyInfo()->GetNPNVersionIndex(negotiatedNPN,
|
||||
|
@ -129,6 +129,151 @@ nsHttpResponseHead::Parse(char *block)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpResponseHead::AssignDefaultStatusText()
|
||||
{
|
||||
LOG(("response status line needs default reason phrase\n"));
|
||||
|
||||
// if a http response doesn't contain a reason phrase, put one in based
|
||||
// on the status code. The reason phrase is totally meaningless so its
|
||||
// ok to have a default catch all here - but this makes debuggers and addons
|
||||
// a little saner to use if we don't map things to "404 OK" or other nonsense.
|
||||
// In particular, HTTP/2 does not use reason phrases at all so they need to
|
||||
// always be injected.
|
||||
|
||||
switch (mStatus) {
|
||||
// start with the most common
|
||||
case 200:
|
||||
mStatusText.AssignLiteral("OK");
|
||||
break;
|
||||
case 404:
|
||||
mStatusText.AssignLiteral("Not Found");
|
||||
break;
|
||||
case 301:
|
||||
mStatusText.AssignLiteral("Moved Permanently");
|
||||
break;
|
||||
case 304:
|
||||
mStatusText.AssignLiteral("Not Modified");
|
||||
break;
|
||||
case 307:
|
||||
mStatusText.AssignLiteral("Temporary Redirect");
|
||||
break;
|
||||
case 500:
|
||||
mStatusText.AssignLiteral("Internal Server Error");
|
||||
break;
|
||||
|
||||
// also well known
|
||||
case 100:
|
||||
mStatusText.AssignLiteral("Continue");
|
||||
break;
|
||||
case 101:
|
||||
mStatusText.AssignLiteral("Switching Protocols");
|
||||
break;
|
||||
case 201:
|
||||
mStatusText.AssignLiteral("Created");
|
||||
break;
|
||||
case 202:
|
||||
mStatusText.AssignLiteral("Accepted");
|
||||
break;
|
||||
case 203:
|
||||
mStatusText.AssignLiteral("Non Authoritative");
|
||||
break;
|
||||
case 204:
|
||||
mStatusText.AssignLiteral("No Content");
|
||||
break;
|
||||
case 205:
|
||||
mStatusText.AssignLiteral("Reset Content");
|
||||
break;
|
||||
case 206:
|
||||
mStatusText.AssignLiteral("Partial Content");
|
||||
break;
|
||||
case 300:
|
||||
mStatusText.AssignLiteral("Multiple Choices");
|
||||
break;
|
||||
case 302:
|
||||
mStatusText.AssignLiteral("Found");
|
||||
break;
|
||||
case 303:
|
||||
mStatusText.AssignLiteral("See Other");
|
||||
break;
|
||||
case 305:
|
||||
mStatusText.AssignLiteral("Use Proxy");
|
||||
break;
|
||||
case 308:
|
||||
mStatusText.AssignLiteral("Permanent Redirect");
|
||||
break;
|
||||
case 400:
|
||||
mStatusText.AssignLiteral("Bad Request");
|
||||
break;
|
||||
case 401:
|
||||
mStatusText.AssignLiteral("Unauthorized");
|
||||
break;
|
||||
case 402:
|
||||
mStatusText.AssignLiteral("Payment Required");
|
||||
break;
|
||||
case 403:
|
||||
mStatusText.AssignLiteral("Forbidden");
|
||||
break;
|
||||
case 405:
|
||||
mStatusText.AssignLiteral("Method Not Allowed");
|
||||
break;
|
||||
case 406:
|
||||
mStatusText.AssignLiteral("Not Acceptable");
|
||||
break;
|
||||
case 407:
|
||||
mStatusText.AssignLiteral("Proxy Authentication Required");
|
||||
break;
|
||||
case 408:
|
||||
mStatusText.AssignLiteral("Request Timeout");
|
||||
break;
|
||||
case 409:
|
||||
mStatusText.AssignLiteral("Conflict");
|
||||
break;
|
||||
case 410:
|
||||
mStatusText.AssignLiteral("Gone");
|
||||
break;
|
||||
case 411:
|
||||
mStatusText.AssignLiteral("Length Required");
|
||||
break;
|
||||
case 412:
|
||||
mStatusText.AssignLiteral("Precondition Failed");
|
||||
break;
|
||||
case 413:
|
||||
mStatusText.AssignLiteral("Request Entity Too Large");
|
||||
break;
|
||||
case 414:
|
||||
mStatusText.AssignLiteral("Request URI Too Long");
|
||||
break;
|
||||
case 415:
|
||||
mStatusText.AssignLiteral("Unsupported Media Type");
|
||||
break;
|
||||
case 416:
|
||||
mStatusText.AssignLiteral("Requested Range Not Satisfiable");
|
||||
break;
|
||||
case 417:
|
||||
mStatusText.AssignLiteral("Expectation Failed");
|
||||
break;
|
||||
case 501:
|
||||
mStatusText.AssignLiteral("Not Implemented");
|
||||
break;
|
||||
case 502:
|
||||
mStatusText.AssignLiteral("Bad Gateway");
|
||||
break;
|
||||
case 503:
|
||||
mStatusText.AssignLiteral("Service Unavailable");
|
||||
break;
|
||||
case 504:
|
||||
mStatusText.AssignLiteral("Gateway Timeout");
|
||||
break;
|
||||
case 505:
|
||||
mStatusText.AssignLiteral("HTTP Version Unsupported");
|
||||
break;
|
||||
default:
|
||||
mStatusText.AssignLiteral("No Reason Phrase");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpResponseHead::ParseStatusLine(const char *line)
|
||||
{
|
||||
@ -141,7 +286,7 @@ nsHttpResponseHead::ParseStatusLine(const char *line)
|
||||
|
||||
if ((mVersion == NS_HTTP_VERSION_0_9) || !(line = PL_strchr(line, ' '))) {
|
||||
mStatus = 200;
|
||||
mStatusText.AssignLiteral("OK");
|
||||
AssignDefaultStatusText();
|
||||
}
|
||||
else {
|
||||
// Status-Code
|
||||
@ -153,8 +298,7 @@ nsHttpResponseHead::ParseStatusLine(const char *line)
|
||||
|
||||
// Reason-Phrase is whatever is remaining of the line
|
||||
if (!(line = PL_strchr(line, ' '))) {
|
||||
LOG(("mal-formed response status line; assuming statusText = 'OK'\n"));
|
||||
mStatusText.AssignLiteral("OK");
|
||||
AssignDefaultStatusText();
|
||||
}
|
||||
else
|
||||
mStatusText = nsDependentCString(++line);
|
||||
|
@ -112,6 +112,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void AssignDefaultStatusText();
|
||||
void ParseVersion(const char *);
|
||||
void ParseCacheControl(const char *);
|
||||
void ParsePragma(const char *);
|
||||
|
@ -9,3 +9,4 @@ from marionette_test import MarionetteTestCase, MarionetteJSTestCase, CommonTest
|
||||
from emulator import Emulator
|
||||
from errors import *
|
||||
from runner import *
|
||||
from wait import Wait
|
||||
|
211
testing/marionette/client/marionette/tests/unit/test_wait.py
Normal file
211
testing/marionette/client/marionette/tests/unit/test_wait.py
Normal file
@ -0,0 +1,211 @@
|
||||
# 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/.
|
||||
|
||||
import unittest
|
||||
import time
|
||||
import sys
|
||||
|
||||
import errors
|
||||
import wait
|
||||
|
||||
from marionette_test import MarionetteTestCase
|
||||
from wait import Wait
|
||||
|
||||
class TickingClock(object):
|
||||
def __init__(self, incr=1):
|
||||
self.ticks = 0
|
||||
self.increment = incr
|
||||
|
||||
def sleep(self, dur):
|
||||
self.ticks += self.increment
|
||||
|
||||
@property
|
||||
def now(self):
|
||||
return self.ticks
|
||||
|
||||
class MockMarionette(object):
|
||||
def __init__(self):
|
||||
self.waited = 0
|
||||
|
||||
def exception(self, e=None, wait=1):
|
||||
self.wait()
|
||||
if self.waited == wait:
|
||||
if e is None:
|
||||
e = Exception
|
||||
raise e
|
||||
|
||||
def true(self, wait=1):
|
||||
self.wait()
|
||||
if self.waited == wait:
|
||||
return True
|
||||
return None
|
||||
|
||||
def false(self, wait=1):
|
||||
self.wait()
|
||||
return False
|
||||
|
||||
def none(self, wait=1):
|
||||
self.wait()
|
||||
return None
|
||||
|
||||
def value(self, value, wait=1):
|
||||
self.wait()
|
||||
if self.waited == wait:
|
||||
return value
|
||||
return None
|
||||
|
||||
def wait(self):
|
||||
self.waited += 1
|
||||
|
||||
def at_third_attempt(clock, end):
|
||||
return clock.now == 2
|
||||
|
||||
class SystemClockTest(MarionetteTestCase):
|
||||
def setUp(self):
|
||||
super(SystemClockTest, self).setUp()
|
||||
self.clock = wait.SystemClock()
|
||||
|
||||
def test_construction_initializes_time(self):
|
||||
self.assertEqual(self.clock._time, time)
|
||||
|
||||
def test_sleep(self):
|
||||
start = time.time()
|
||||
self.clock.sleep(0.1)
|
||||
end = time.time() - start
|
||||
|
||||
self.assertGreaterEqual(end, 0.1)
|
||||
|
||||
def test_time_now(self):
|
||||
self.assertIsNotNone(self.clock.now)
|
||||
|
||||
class FormalWaitTest(MarionetteTestCase):
|
||||
def test_construction_with_custom_timeout(self):
|
||||
w = Wait(None, timeout=42)
|
||||
self.assertEqual(w.timeout, 42)
|
||||
|
||||
def test_construction_with_custom_interval(self):
|
||||
w = Wait(None, interval=42)
|
||||
self.assertEqual(w.interval, 42)
|
||||
|
||||
def test_construction_with_custom_clock(self):
|
||||
c = TickingClock(1)
|
||||
w = Wait(None, clock=c)
|
||||
self.assertEqual(w.clock, c)
|
||||
|
||||
def test_construction_with_custom_exception(self):
|
||||
w = Wait(None, ignored_exceptions=Exception)
|
||||
self.assertIn(Exception, w.exceptions)
|
||||
self.assertEqual(len(w.exceptions), 1)
|
||||
|
||||
def test_construction_with_custom_exception_list(self):
|
||||
exc = [Exception, ValueError]
|
||||
w = Wait(None, ignored_exceptions=exc)
|
||||
for e in exc:
|
||||
self.assertIn(e, w.exceptions)
|
||||
self.assertEqual(len(w.exceptions), len(exc))
|
||||
|
||||
def test_construction_with_custom_exception_tuple(self):
|
||||
exc = (Exception, ValueError)
|
||||
w = Wait(None, ignored_exceptions=exc)
|
||||
for e in exc:
|
||||
self.assertIn(e, w.exceptions)
|
||||
self.assertEqual(len(w.exceptions), len(exc))
|
||||
|
||||
def test_duplicate_exceptions(self):
|
||||
w = Wait(None, ignored_exceptions=[Exception, Exception])
|
||||
self.assertIn(Exception, w.exceptions)
|
||||
self.assertEqual(len(w.exceptions), 1)
|
||||
|
||||
def test_default_timeout(self):
|
||||
self.assertEqual(wait.DEFAULT_TIMEOUT, 5)
|
||||
|
||||
def test_default_interval(self):
|
||||
self.assertEqual(wait.DEFAULT_INTERVAL, 0.1)
|
||||
|
||||
def test_end_property(self):
|
||||
w = Wait(None)
|
||||
self.assertIsNotNone(w.end)
|
||||
|
||||
def test_marionette_property(self):
|
||||
marionette = "cheddar"
|
||||
w = Wait(marionette)
|
||||
self.assertEqual(w.marionette, marionette)
|
||||
|
||||
def test_clock_property(self):
|
||||
w = Wait(None)
|
||||
self.assertIsInstance(w.clock, wait.SystemClock)
|
||||
|
||||
class PredicatesTest(MarionetteTestCase):
|
||||
def test_until(self):
|
||||
c = wait.SystemClock()
|
||||
self.assertFalse(wait.until_pred(c, sys.maxint))
|
||||
self.assertTrue(wait.until_pred(c, 0))
|
||||
|
||||
class WaitUntilTest(MarionetteTestCase):
|
||||
def setUp(self):
|
||||
super(WaitUntilTest, self).setUp()
|
||||
|
||||
self.m = MockMarionette()
|
||||
self.clock = TickingClock()
|
||||
self.w = Wait(self.m, timeout=10, interval=1, clock=self.clock)
|
||||
|
||||
def test_true(self):
|
||||
r = self.w.until(lambda x: x.true())
|
||||
self.assertTrue(r)
|
||||
self.assertEqual(self.clock.ticks, 0)
|
||||
|
||||
def test_true_within_timeout(self):
|
||||
r = self.w.until(lambda x: x.true(wait=5))
|
||||
self.assertTrue(r)
|
||||
self.assertEqual(self.clock.ticks, 4)
|
||||
|
||||
def test_timeout(self):
|
||||
with self.assertRaises(errors.TimeoutException):
|
||||
r = self.w.until(lambda x: x.true(wait=15))
|
||||
self.assertEqual(self.clock.ticks, 10)
|
||||
|
||||
def test_exception_raises_immediately(self):
|
||||
with self.assertRaises(Exception):
|
||||
self.w.until(lambda x: x.exception())
|
||||
self.assertEqual(self.clock.ticks, 0)
|
||||
|
||||
def test_custom_ignored_exception(self):
|
||||
self.w.exceptions = self.w.exceptions + (Exception,)
|
||||
with self.assertRaises(Exception):
|
||||
self.w.until(lambda x: x.exception(e=Exception))
|
||||
|
||||
def test_ignored_exception_after_timeout_is_not_raised(self):
|
||||
with self.assertRaises(errors.TimeoutException):
|
||||
r = self.w.until(lambda x: x.exception(wait=15))
|
||||
self.assertEqual(self.clock.ticks, 10)
|
||||
|
||||
def test_keyboard_interrupt(self):
|
||||
with self.assertRaises(KeyboardInterrupt):
|
||||
self.w.until(lambda x: x.exception(e=KeyboardInterrupt))
|
||||
|
||||
def test_system_exit(self):
|
||||
with self.assertRaises(SystemExit):
|
||||
self.w.until(lambda x: x.exception(SystemExit))
|
||||
|
||||
def test_true_condition_returns_immediately(self):
|
||||
r = self.w.until(lambda x: x.true())
|
||||
self.assertIsInstance(r, bool)
|
||||
self.assertTrue(r)
|
||||
self.assertEqual(self.clock.ticks, 0)
|
||||
|
||||
def test_value(self):
|
||||
r = self.w.until(lambda x: "foo")
|
||||
self.assertEqual(r, "foo")
|
||||
self.assertEqual(self.clock.ticks, 0)
|
||||
|
||||
def test_custom_predicate(self):
|
||||
r = self.w.until(lambda x: x.true(wait=2), is_true=at_third_attempt)
|
||||
self.assertTrue(r)
|
||||
self.assertEqual(self.clock.ticks, 1)
|
||||
|
||||
def test_custom_predicate_times_out(self):
|
||||
with self.assertRaises(errors.TimeoutException):
|
||||
self.w.until(lambda x: x.true(wait=4), is_true=at_third_attempt)
|
||||
|
||||
self.assertEqual(self.clock.ticks, 2)
|
@ -91,8 +91,9 @@ b2g = false
|
||||
b2g = false
|
||||
[test_window_type.py]
|
||||
b2g = false
|
||||
|
||||
[test_implicit_waits.py]
|
||||
[test_wait.py]
|
||||
qemu = false
|
||||
[test_date_time_value.py]
|
||||
[test_getactiveframe_oop.py]
|
||||
[test_submit.py]
|
||||
|
147
testing/marionette/client/marionette/wait.py
Normal file
147
testing/marionette/client/marionette/wait.py
Normal file
@ -0,0 +1,147 @@
|
||||
# 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/.
|
||||
|
||||
import collections
|
||||
import errors
|
||||
import time
|
||||
|
||||
DEFAULT_TIMEOUT = 5
|
||||
DEFAULT_INTERVAL = 0.1
|
||||
|
||||
class Wait(object):
|
||||
"""An explicit conditional utility class for waiting until a condition
|
||||
evaluates to true or not null.
|
||||
|
||||
This will repeatedly evaluate a condition in anticipation for a
|
||||
truthy return value, or its timeout to expire, or its waiting
|
||||
predicate to become true.
|
||||
|
||||
A Wait instance defines the maximum amount of time to wait for a
|
||||
condition, as well as the frequency with which to check the
|
||||
condition. Furthermore, the user may configure the wait to ignore
|
||||
specific types of exceptions whilst waiting, such as
|
||||
errors.NoSuchElementException when searching for an element on the
|
||||
page.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, marionette, timeout=DEFAULT_TIMEOUT,
|
||||
interval=DEFAULT_INTERVAL, ignored_exceptions=None,
|
||||
clock=None):
|
||||
"""Configure the Wait instance to have a custom timeout, interval, and
|
||||
list of ignored exceptions. Optionally a different time
|
||||
implementation than the one provided by the standard library
|
||||
(time) can also be provided.
|
||||
|
||||
Sample usage:
|
||||
|
||||
# Wait 30 seconds for window to open, checking for its presence once
|
||||
# every 5 seconds.
|
||||
wait = Wait(marionette, timeout=30, interval=5,
|
||||
ignored_exceptions=errors.NoSuchWindowException)
|
||||
window = wait.until(lambda marionette: marionette.switch_to_window(42))
|
||||
|
||||
:param marionette: The input value to be provided to
|
||||
conditions, usually a Marionette instance.
|
||||
|
||||
:param timeout: How long to wait for the evaluated condition
|
||||
to become true. The default time is wait.DEFAULT_TIMEOUT.
|
||||
|
||||
:param interval: How often the condition should be evaluated.
|
||||
In reality the interval may be greater as the cost of
|
||||
evaluating the condition function is not factored in. The
|
||||
default polling interval is wait.DEFAULT_INTERVAL.
|
||||
|
||||
:param ignored_exceptions: Ignore specific types of exceptions
|
||||
whilst waiting for the condition. Any exceptions not
|
||||
whitelisted will be allowed to propagate, terminating the
|
||||
wait.
|
||||
|
||||
:param clock: Allows overriding the use of the runtime's
|
||||
default time library. See wait.SystemClock for
|
||||
implementation details.
|
||||
|
||||
"""
|
||||
|
||||
self.marionette = marionette
|
||||
self.timeout = timeout
|
||||
self.clock = clock or SystemClock()
|
||||
self.end = self.clock.now + self.timeout
|
||||
self.interval = interval
|
||||
|
||||
exceptions = []
|
||||
if ignored_exceptions is not None:
|
||||
if isinstance(ignored_exceptions, collections.Iterable):
|
||||
exceptions.extend(iter(ignored_exceptions))
|
||||
else:
|
||||
exceptions.append(ignored_exceptions)
|
||||
self.exceptions = tuple(set(exceptions))
|
||||
|
||||
|
||||
def until(self, condition, is_true=None):
|
||||
"""Repeatedly runs condition until its return value evaluates to true,
|
||||
or its timeout expires or the predicate evaluates to true.
|
||||
|
||||
This will poll at the given interval until the given timeout
|
||||
is reached, or the predicate or conditions returns true. A
|
||||
condition that returns null or does not evaluate to true will
|
||||
fully elapse its timeout before raising an
|
||||
errors.TimeoutException.
|
||||
|
||||
If an exception is raised in the condition function and it's
|
||||
not ignored, this function will raise immediately. If the
|
||||
exception is ignored, it will continue polling for the
|
||||
condition until it returns successfully or a TimeoutException
|
||||
is raised.
|
||||
|
||||
:param condition: A callable function whose return value will
|
||||
be returned by this function if it evaluates to true.
|
||||
|
||||
:param is_true: A predicate that will terminate and return
|
||||
when it evaluates to False. It should be a function that
|
||||
will be passed clock and an end time. The default
|
||||
predicate will terminate a wait when the clock elapses the
|
||||
timeout.
|
||||
|
||||
"""
|
||||
|
||||
rv = None
|
||||
last_exc = None
|
||||
until = is_true or until_pred
|
||||
|
||||
while not until(self.clock, self.end):
|
||||
try:
|
||||
rv = condition(self.marionette)
|
||||
except (KeyboardInterrupt, SystemExit) as e:
|
||||
raise e
|
||||
except self.exceptions as e:
|
||||
last_exc = e
|
||||
|
||||
if isinstance(rv, bool) and not rv:
|
||||
self.clock.sleep(self.interval)
|
||||
continue
|
||||
|
||||
if rv is not None:
|
||||
return rv
|
||||
|
||||
self.clock.sleep(self.interval)
|
||||
|
||||
if last_exc is not None:
|
||||
raise last_exc
|
||||
|
||||
raise errors.TimeoutException
|
||||
|
||||
def until_pred(clock, end):
|
||||
return clock.now >= end
|
||||
|
||||
class SystemClock(object):
|
||||
def __init__(self):
|
||||
self._time = time
|
||||
|
||||
def sleep(self, duration):
|
||||
self._time.sleep(duration)
|
||||
|
||||
@property
|
||||
def now(self):
|
||||
return self._time.time()
|
Loading…
Reference in New Issue
Block a user