Merge m-c to inbound.

This commit is contained in:
Ryan VanderMeulen 2014-01-03 14:12:28 -05:00
commit 0667febab1
31 changed files with 1452 additions and 280 deletions

View File

@ -1,4 +1,4 @@
{
"revision": "2977ae6150d723b2763e9e76da00aa1fb3c31678",
"revision": "23fea49fdb66496bd9b1a3e8cbe5b9dfaf9b88c1",
"repo_path": "/integration/gaia-central"
}

View File

@ -245,7 +245,7 @@
<menupopup id="toolbar-context-menu"
onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('viewToolbarsMenuSeparator'));">
<menuitem oncommand="gCustomizeMode.addToPanel(document.popupNode)"
accesskey="&customizeMenu.addToPanel.accesskey;"
accesskey="&customizeMenu.moveToPanel.accesskey;"
label="&customizeMenu.moveToPanel.label;"
class="customize-context-moveToPanel"/>
<menuitem oncommand="gCustomizeMode.removeFromArea(document.popupNode)"

View File

@ -37,6 +37,10 @@ let UI = {
},
onUnload: function() {
for (let [target, toolbox] of this._handledTargets) {
toolbox.destroy();
}
window.removeEventListener("unload", this.onUnload);
window.removeEventListener("message", this.onMessage);
if (this.connection) {
@ -62,6 +66,7 @@ let UI = {
this.selectTab("projects");
break;
case "toolbox-raise":
window.top.focus();
this.selectTab(json.uid);
break;
case "toolbox-close":
@ -158,7 +163,8 @@ let UI = {
openAndShowToolboxForTarget: function(target, name, icon) {
let host = devtools.Toolbox.HostType.CUSTOM;
if (!this._handledTargets.has(target)) {
let toolbox = gDevTools.getToolbox(target);
if (!toolbox) {
let uid = "uid" + this._toolboxTabCursor++;
let iframe = this.createToolboxTab(name, icon, uid);
let options = { customIframe: iframe , uid: uid };
@ -170,12 +176,6 @@ let UI = {
});
});
} else {
let toolbox = this._handledTargets.get(target);
if (!toolbox) {
// Target is handled, but toolbox is still being
// created.
return promise.resolve(null);
}
return gDevTools.showToolbox(target, null, host);
}
}

View File

@ -238,7 +238,7 @@ StyleEditorUI.prototype = {
{
let onFileSelected = function(file) {
if (!file) {
this.emit("error", LOAD_ERROR);
// nothing selected
return;
}
NetUtil.asyncFetch(file, (stream, status) => {

View File

@ -413,6 +413,37 @@ nsFrameLoader::ReallyStartLoading()
return rv;
}
class DelayedStartLoadingRunnable : public nsRunnable
{
public:
DelayedStartLoadingRunnable(nsFrameLoader* aFrameLoader)
: mFrameLoader(aFrameLoader)
{
}
NS_IMETHOD Run()
{
// Retry the request.
mFrameLoader->ReallyStartLoading();
// We delayed nsFrameLoader::ReallyStartLoading() after the child process is
// ready and might not be able to notify the remote browser in
// UpdatePositionAndSize() when reflow finished. Retrigger reflow.
nsIFrame* frame = mFrameLoader->GetPrimaryFrameOfOwningContent();
if (!frame) {
return NS_OK;
}
frame->InvalidateFrame();
frame->PresContext()->PresShell()->
FrameNeedsReflow(frame, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
return NS_OK;
}
private:
nsRefPtr<nsFrameLoader> mFrameLoader;
};
nsresult
nsFrameLoader::ReallyStartLoadingInternal()
{
@ -427,6 +458,13 @@ nsFrameLoader::ReallyStartLoadingInternal()
if (mRemoteFrame) {
if (!mRemoteBrowser) {
if (Preferences::GetBool("dom.ipc.processPrelaunch.enabled", false) &&
!ContentParent::PreallocatedProcessReady()) {
ContentParent::RunAfterPreallocatedProcessReady(
new DelayedStartLoadingRunnable(this));
return NS_ERROR_FAILURE;
}
TryRemoteBrowser();
if (!mRemoteBrowser) {

View File

@ -97,7 +97,7 @@ class MediaRecorder::Session: public nsIObserver
nsRefPtr<Session> mSession;
};
// Record thread task.
// Record thread task and it run in Media Encoder thread.
// Fetch encoded Audio/Video data from MediaEncoder.
class ExtractRunnable : public nsRunnable
{
@ -114,7 +114,7 @@ class MediaRecorder::Session: public nsIObserver
}
private:
nsRefPtr<Session> mSession;
Session* mSession;
};
// For Ensure recorder has tracks to record.

View File

@ -919,8 +919,8 @@ BrowserElementChild.prototype = {
this._pendingSetInputMethodActive.push(data);
return;
}
sendAsyncMsg('got-set-input-method-active', msgData);
msgData.successRv = null;
sendAsyncMsg('got-set-input-method-active', msgData);
return;
}
// Unwrap to access webpage content.

View File

@ -378,10 +378,6 @@ MozInputMethod.prototype = {
},
get mgmt() {
if (!WindowMap.isActive(this._window)) {
return null;
}
return this._mgmt;
},
@ -695,8 +691,8 @@ MozInputContext.prototype = {
contextId: self._contextId,
requestId: resolverId,
text: text,
beforeLength: offset || 0,
afterLength: length || 0
offset: offset || 0,
length: length || 0
});
});
},

View File

@ -585,13 +585,13 @@ let FormAssistant = {
case "Forms:ReplaceSurroundingText": {
CompositionManager.endComposition('');
let text = json.text;
let beforeLength = json.beforeLength;
let afterLength = json.afterLength;
let selectionRange = getSelectionRange(target);
replaceSurroundingText(target, text, selectionRange[0], beforeLength,
afterLength);
replaceSurroundingText(target,
json.text,
selectionRange[0],
selectionRange[1],
json.offset,
json.length);
if (json.requestId) {
sendAsyncMessage("Forms:ReplaceSurroundingText:Result:OK", {
@ -1064,25 +1064,24 @@ function getPlaintextEditor(element) {
return editor;
}
function replaceSurroundingText(element, text, selectionStart, beforeLength,
afterLength) {
function replaceSurroundingText(element, text, selectionStart, selectionEnd,
offset, length) {
let editor = FormAssistant.editor;
if (!editor) {
return;
}
// Check the parameters.
if (beforeLength < 0) {
beforeLength = 0;
let start = selectionStart + offset;
if (start < 0) {
start = 0;
}
if (afterLength < 0) {
afterLength = 0;
if (length < 0) {
length = 0;
}
let end = start + length;
let start = selectionStart - beforeLength;
let end = selectionStart + afterLength;
if (beforeLength != 0 || afterLength != 0) {
if (selectionStart != start || selectionEnd != end) {
// Change selection range before replacing.
setSelectionRange(element, start, end);
}

View File

@ -7,4 +7,5 @@ support-files =
[test_basic.html]
[test_bug944397.html]
[test_bug949059.html]
[test_sendkey_cancel.html]

View File

@ -82,7 +82,7 @@ function test_sendKey() {
function test_deleteSurroundingText() {
// Remove one character before current cursor position and move the cursor
// position back to 2.
gContext.deleteSurroundingText(1, 0).then(function() {
gContext.deleteSurroundingText(-1, 1).then(function() {
ok(true, 'deleteSurroundingText finished');
is(gContext.textBeforeCursor + gContext.textAfterCursor, 'Yuan',
'deleteSurroundingText should changed the input field correctly.');
@ -95,7 +95,7 @@ function test_deleteSurroundingText() {
function test_replaceSurroundingText() {
// Replace 'Yuan' with 'Xulei'.
gContext.replaceSurroundingText('Xulei', 2, 2).then(function() {
gContext.replaceSurroundingText('Xulei', -2, 4).then(function() {
ok(true, 'replaceSurroundingText finished');
is(gContext.textBeforeCursor + gContext.textAfterCursor, 'Xulei',
'replaceSurroundingText changed the input field correctly.');

View File

@ -51,6 +51,19 @@ function runTest() {
keyboard.setAttribute('mozbrowser', true);
document.body.appendChild(keyboard);
// Bug 953044 setInputMethodActive(false) before input method app loads should
// always succeed.
let req = keyboard.setInputMethodActive(false);
req.onsuccess = function() {
ok(true, 'setInputMethodActive before loading succeeded.');
};
req.onerror = function() {
ok(false, 'setInputMethodActive before loading failed: ' + this.error.name);
clearTimeout(timeoutId);
inputmethod_cleanup();
};
let path = location.pathname;
let imeUrl = location.protocol + '//' + location.host +
path.substring(0, path.lastIndexOf('/')) +

View File

@ -0,0 +1,40 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=949059
-->
<head>
<title>Test "mgmt" property of MozInputMethod.</title>
<script type="application/javascript;version=1.7" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript;version=1.7" src="inputmethod_common.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=949059">Mozilla Bug 949059</a>
<p id="display"></p>
<pre id="test">
<script class="testbody" type="application/javascript;version=1.7">
inputmethod_setup(function() {
runTest();
});
function runTest() {
let im = navigator.mozInputMethod;
// Treat current page as an input method and activate it.
SpecialPowers.wrap(im).setActive(true);
ok(im.mgmt, 'The mgmt property should not be null.');
// Deactivate current page.
SpecialPowers.wrap(im).setActive(false);
ok(im.mgmt, 'The mgmt property should not be null.');
inputmethod_cleanup();
}
</script>
</pre>
</body>
</html>

View File

@ -488,6 +488,24 @@ ContentParent::GetInitialProcessPriority(Element* aFrameElement)
PROCESS_PRIORITY_FOREGROUND;
}
bool
ContentParent::PreallocatedProcessReady()
{
#ifdef MOZ_NUWA_PROCESS
return PreallocatedProcessManager::PreallocatedProcessReady();
#else
return true;
#endif
}
void
ContentParent::RunAfterPreallocatedProcessReady(nsIRunnable* aRequest)
{
#ifdef MOZ_NUWA_PROCESS
PreallocatedProcessManager::RunAfterPreallocatedProcessReady(aRequest);
#endif
}
/*static*/ TabParent*
ContentParent::CreateBrowserOrApp(const TabContext& aContext,
Element* aFrameElement)
@ -562,6 +580,14 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
p = MaybeTakePreallocatedAppProcess(manifestURL, privs,
initialPriority);
if (!p) {
#ifdef MOZ_NUWA_PROCESS
if (Preferences::GetBool("dom.ipc.processPrelaunch.enabled",
false)) {
// Returning nullptr from here so the frame loader will retry
// later when we have a spare process.
return nullptr;
}
#endif
NS_WARNING("Unable to use pre-allocated app process");
p = new ContentParent(ownApp,
/* isForBrowserElement = */ false,

View File

@ -86,6 +86,9 @@ public:
*/
static void JoinAllSubprocesses();
static bool PreallocatedProcessReady();
static void RunAfterPreallocatedProcessReady(nsIRunnable* aRequest);
static already_AddRefed<ContentParent>
GetNewOrUsed(bool aForBrowserElement = false);

View File

@ -55,7 +55,9 @@ public:
void PublishSpareProcess(ContentParent* aContent);
void MaybeForgetSpare(ContentParent* aContent);
void OnNuwaReady();
bool PreallocatedProcessReady();
already_AddRefed<ContentParent> GetSpareProcess();
void RunAfterPreallocatedProcessReady(nsIRunnable* aRunnable);
private:
void OnNuwaForkTimeout();
@ -69,6 +71,8 @@ private:
nsAutoTArray<nsRefPtr<ContentParent>, 4> mSpareProcesses;
nsTArray<CancelableTask*> mNuwaForkWaitTasks;
nsTArray<nsCOMPtr<nsIRunnable> > mDelayedContentParentRequests;
// Nuwa process is ready for creating new process.
bool mIsNuwaReady;
#endif
@ -220,6 +224,18 @@ PreallocatedProcessManagerImpl::AllocateNow()
#ifdef MOZ_NUWA_PROCESS
void
PreallocatedProcessManagerImpl::RunAfterPreallocatedProcessReady(nsIRunnable* aRequest)
{
MOZ_ASSERT(NS_IsMainThread());
mDelayedContentParentRequests.AppendElement(aRequest);
if (!mPreallocateAppProcessTask) {
// This is an urgent NuwaFork() request.
DelayedNuwaFork();
}
}
void
PreallocatedProcessManagerImpl::ScheduleDelayedNuwaFork()
{
@ -302,6 +318,12 @@ PreallocatedProcessManagerImpl::PublishSpareProcess(ContentParent* aContent)
}
mSpareProcesses.AppendElement(aContent);
if (!mDelayedContentParentRequests.IsEmpty()) {
nsCOMPtr<nsIRunnable> runnable = mDelayedContentParentRequests[0];
mDelayedContentParentRequests.RemoveElementAt(0);
NS_DispatchToMainThread(runnable);
}
}
void
@ -309,6 +331,13 @@ PreallocatedProcessManagerImpl::MaybeForgetSpare(ContentParent* aContent)
{
MOZ_ASSERT(NS_IsMainThread());
if (!mDelayedContentParentRequests.IsEmpty()) {
if (!mPreallocateAppProcessTask) {
// This NuwaFork request is urgent. Don't delay it.
DelayedNuwaFork();
}
}
if (mSpareProcesses.RemoveElement(aContent)) {
return;
}
@ -338,6 +367,13 @@ PreallocatedProcessManagerImpl::OnNuwaReady()
NuwaFork();
}
bool
PreallocatedProcessManagerImpl::PreallocatedProcessReady()
{
return !mSpareProcesses.IsEmpty();
}
void
PreallocatedProcessManagerImpl::OnNuwaForkTimeout()
{
@ -473,6 +509,19 @@ PreallocatedProcessManager::OnNuwaReady()
{
GetPPMImpl()->OnNuwaReady();
}
/*static */ bool
PreallocatedProcessManager::PreallocatedProcessReady()
{
return GetPPMImpl()->PreallocatedProcessReady();
}
/* static */ void
PreallocatedProcessManager::RunAfterPreallocatedProcessReady(nsIRunnable* aRequest)
{
GetPPMImpl()->RunAfterPreallocatedProcessReady(aRequest);
}
#endif
} // namespace mozilla

View File

@ -11,6 +11,8 @@
#include "nsCOMPtr.h"
#include "nsIObserver.h"
class nsIRunnable;
namespace mozilla {
namespace dom {
class ContentParent;
@ -82,6 +84,8 @@ public:
static void PublishSpareProcess(ContentParent* aContent);
static void MaybeForgetSpare(ContentParent* aContent);
static void OnNuwaReady();
static bool PreallocatedProcessReady();
static void RunAfterPreallocatedProcessReady(nsIRunnable* aRunnable);
#endif
private:

View File

@ -11061,6 +11061,15 @@ let BerTlvHelper = {
retrieveFileIdentifier: function retrieveFileIdentifier(length) {
return {fileId : (GsmPDUHelper.readHexOctet() << 8) +
GsmPDUHelper.readHexOctet()};
},
searchForNextTag: function searchForNextTag(tag, iter) {
for (let [index, tlv] in iter) {
if (tlv.tag === tag) {
return tlv;
}
}
return null;
}
};
BerTlvHelper[BER_FCP_TEMPLATE_TAG] = function BER_FCP_TEMPLATE_TAG(length) {
@ -11342,9 +11351,60 @@ let ICCIOHelper = {
processICCIOGetResponse: function processICCIOGetResponse(options) {
let strLen = Buf.readInt32();
let peek = GsmPDUHelper.readHexOctet();
Buf.seekIncoming(-1 * Buf.PDU_HEX_OCTET_SIZE);
if (peek === BER_FCP_TEMPLATE_TAG) {
this.processUSimGetResponse(options, strLen / 2);
} else {
this.processSimGetResponse(options);
}
Buf.readStringDelimiter(strLen);
if (options.callback) {
options.callback(options);
}
},
/**
* Helper function for processing USIM get response.
*/
processUSimGetResponse: function processUSimGetResponse(options, octetLen) {
let berTlv = BerTlvHelper.decode(octetLen);
// See TS 102 221 Table 11.4 for the content order of getResponse.
let iter = Iterator(berTlv.value);
let tlv = BerTlvHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG,
iter);
if (!tlv || (tlv.value.fileStructure !== UICC_EF_STRUCTURE[options.type])) {
throw new Error("Expected EF type " + UICC_EF_STRUCTURE[options.type] +
" but read " + tlv.value.fileStructure);
}
if (tlv.value.fileStructure === UICC_EF_STRUCTURE[EF_TYPE_LINEAR_FIXED] ||
tlv.value.fileStructure === UICC_EF_STRUCTURE[EF_TYPE_CYCLIC]) {
options.recordSize = tlv.value.recordLength;
options.totalRecords = tlv.value.numOfRecords;
}
tlv = BerTlvHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter);
if (!tlv || (tlv.value.fileId !== options.fileId)) {
throw new Error("Expected file ID " + options.fileId.toString(16) +
" but read " + fileId.toString(16));
}
tlv = BerTlvHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter);
if (!tlv) {
throw new Error("Unexpected file size data");
}
options.fileSize = tlv.value.fileSizeData;
},
/**
* Helper function for processing SIM get response.
*/
processSimGetResponse: function processSimGetResponse(options) {
// The format is from TS 51.011, clause 9.2.1
// Skip RFU, data[0] data[1]
// Skip RFU, data[0] data[1].
Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
// File size, data[2], data[3]
@ -11378,6 +11438,7 @@ let ICCIOHelper = {
throw new Error("Expected EF type " + options.type + " but read " + efType);
}
// TODO: Bug 952025.
// Length of a record, data[14].
// Only available for LINEAR_FIXED and CYCLIC.
if (efType == EF_TYPE_LINEAR_FIXED || efType == EF_TYPE_CYCLIC) {
@ -11386,12 +11447,6 @@ let ICCIOHelper = {
} else {
Buf.seekIncoming(1 * Buf.PDU_HEX_OCTET_SIZE);
}
Buf.readStringDelimiter(strLen);
if (options.callback) {
options.callback(options);
}
},
/**

View File

@ -2733,15 +2733,6 @@ add_test(function test_fcp_template_for_transparent_structure() {
let pduHelper = worker.GsmPDUHelper;
let berHelper = worker.BerTlvHelper;
berHelper.searchForNextTag = function searchForNextTag(tag, iter) {
for (let [index, tlv] in iter) {
if (tlv.tag === tag) {
return tlv;
}
}
return null;
};
let tag_test = [
0x62,
0x22,
@ -2779,15 +2770,6 @@ add_test(function test_fcp_template_for_linear_fixed_structure() {
let pduHelper = worker.GsmPDUHelper;
let berHelper = worker.BerTlvHelper;
berHelper.searchForNextTag = function searchForNextTag(tag, iter) {
for (let [index, tlv] in iter) {
if (tlv.tag === tag) {
return tlv;
}
}
return null;
};
let tag_test = [
0x62,
0x1E,
@ -2818,3 +2800,73 @@ add_test(function test_fcp_template_for_linear_fixed_structure() {
run_next_test();
});
add_test(function test_icc_io_get_response_for_transparent_structure() {
let worker = newUint8Worker();
let buf = worker.Buf;
let iccioHelper = worker.ICCIOHelper;
let pduHelper = worker.GsmPDUHelper;
let responseArray = [
// SIM response.
[0x00, 0x00, 0x00, 0x0A, 0x2F, 0xE2, 0x04, 0x00, 0x0A, 0xA0, 0xAA, 0x00,
0x02, 0x00, 0x00],
// USIM response.
[0x62, 0x22, 0x82, 0x02, 0x41, 0x21, 0x83, 0x02, 0x2F, 0xE2, 0xA5, 0x09,
0xC1, 0x04, 0x40, 0x0F, 0xF5, 0x55, 0x92, 0x01, 0x00, 0x8A, 0x01, 0x05,
0x8B, 0x03, 0x2F, 0x06, 0x0B, 0x80, 0x02, 0x00, 0x0A, 0x88, 0x01, 0x10]
];
for (let i = 0; i < responseArray.length; i++) {
let strLen = responseArray[i].length * 2;
buf.writeInt32(strLen);
for (let j = 0; j < responseArray[i].length; j++) {
pduHelper.writeHexOctet(responseArray[i][j]);
}
buf.writeStringDelimiter(strLen);
let options = {fileId: ICC_EF_ICCID,
type: EF_TYPE_TRANSPARENT};
iccioHelper.processICCIOGetResponse(options);
do_check_eq(options.fileSize, 0x0A);
}
run_next_test();
});
add_test(function test_icc_io_get_response_for_linear_fixed_structure() {
let worker = newUint8Worker();
let buf = worker.Buf;
let iccioHelper = worker.ICCIOHelper;
let pduHelper = worker.GsmPDUHelper;
let responseArray = [
// SIM response.
[0x00, 0x00, 0x00, 0x1A, 0x6F, 0x40, 0x04, 0x00, 0x11, 0xA0, 0xAA, 0x00,
0x02, 0x01, 0x1A],
// USIM response.
[0x62, 0x1E, 0x82, 0x05, 0x42, 0x21, 0x00, 0x1A, 0x01, 0x83, 0x02, 0x6F,
0x40, 0xA5, 0x03, 0x92, 0x01, 0x00, 0x8A, 0x01, 0x07, 0x8B, 0x03, 0x6F,
0x06, 0x02, 0x80, 0x02, 0x00, 0x1A, 0x88, 0x00]
];
for (let i = 0; i < responseArray.length; i++) {
let strLen = responseArray[i].length * 2;
buf.writeInt32(strLen);
for (let j = 0; j < responseArray[i].length; j++) {
pduHelper.writeHexOctet(responseArray[i][j]);
}
buf.writeStringDelimiter(strLen);
let options = {fileId: ICC_EF_MSISDN,
type: EF_TYPE_LINEAR_FIXED};
iccioHelper.processICCIOGetResponse(options);
do_check_eq(options.fileSize, 0x1A);
do_check_eq(options.recordSize, 0x1A);
do_check_eq(options.totalRecords, 0x01);
}
run_next_test();
});

View File

@ -89,7 +89,7 @@ interface MozInputContext: EventTarget {
readonly attribute long selectionStart;
readonly attribute long selectionEnd;
// The start and stop position of the selection.
// The text before and after the begining of the selected text.
readonly attribute DOMString? textBeforeCursor;
readonly attribute DOMString? textAfterCursor;

View File

@ -3812,6 +3812,15 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
static=1))
clonemanagees.addstmt(otherstmt)
# Keep track of types created with an INOUT ctor. We need to call
# Register() or RegisterID() for them depending on the side the managee
# is created.
inoutCtorTypes = []
for msg in p.messageDecls:
msgtype = msg.decl.type
if msgtype.isCtor() and msgtype.isInout():
inoutCtorTypes.append(msgtype.constructedType())
actorvar = ExprVar('actor')
for managee in p.managesStmts:
block = StmtBlock()
@ -3827,6 +3836,19 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
init=Param(Type.UINT32, ivar.name, ExprLiteral.ZERO),
cond=ExprBinary(ivar, '<', _callCxxArrayLength(kidsvar)),
update=ExprPrefixUnop(ivar, '++'))
registerstmt = StmtExpr(ExprCall(p.registerIDMethod(),
args=[actorvar, _actorId(actorvar)]))
# Implement if (actor id > 0) then Register() else RegisterID()
if manageeipdltype in inoutCtorTypes:
registerif = StmtIf(ExprBinary(_actorId(actorvar),
'>',
ExprLiteral.ZERO))
registerif.addifstmt(StmtExpr(ExprCall(p.registerMethod(),
args=[actorvar])))
registerif.addelsestmt(registerstmt)
registerstmt = registerif
forstmt.addstmts([
StmtExpr(ExprAssn(
actorvar,
@ -3847,8 +3869,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
p.channelForSubactor())),
StmtExpr(ExprAssn(_actorState(actorvar), _actorState(ithkid))),
StmtExpr(_callCxxArrayInsertSorted(manageearray, actorvar)),
StmtExpr(ExprCall(p.registerIDMethod(),
args=[actorvar, _actorId(actorvar)])),
registerstmt,
StmtExpr(ExprCall(
ExprSelect(actorvar,
'->',

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,8 @@ include $(topsrcdir)/config/makefiles/rcs.mk
LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/threads
DEFINES += -DMOZ_APP_VERSION='"$(MOZ_APP_VERSION)"'
MOZ_HISTOGRAMS_VERSION ?= $(call getSourceRepo)/rev/$(firstword $(shell hg -R $(topsrcdir) parent --template='{node|short}\n' 2>/dev/null))
ifdef MOZ_HISTOGRAMS_VERSION
DEFINES += -DHISTOGRAMS_FILE_VERSION='$(MOZ_HISTOGRAMS_VERSION)'

View File

@ -23,6 +23,8 @@
#include "nsCOMArray.h"
#include "nsCOMPtr.h"
#include "nsXPCOMPrivate.h"
#include "nsIXULAppInfo.h"
#include "nsVersionComparator.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/ModuleUtils.h"
#include "nsIXPConnect.h"
@ -57,6 +59,8 @@
#include "shared-libraries.h"
#endif
#define EXPIRED_ID "__expired__"
namespace {
using namespace base;
@ -388,9 +392,11 @@ struct TelemetryHistogram {
uint32_t bucketCount;
uint32_t histogramType;
uint32_t id_offset;
uint32_t expiration_offset;
bool extendedStatisticsOK;
const char *id() const;
const char *expiration() const;
};
#include "TelemetryHistogramData.inc"
@ -402,31 +408,27 @@ TelemetryHistogram::id() const
return &gHistogramStringTable[this->id_offset];
}
bool
TelemetryHistogramType(Histogram *h, uint32_t *result)
const char *
TelemetryHistogram::expiration() const
{
switch (h->histogram_type()) {
case Histogram::HISTOGRAM:
*result = nsITelemetry::HISTOGRAM_EXPONENTIAL;
break;
case Histogram::LINEAR_HISTOGRAM:
*result = nsITelemetry::HISTOGRAM_LINEAR;
break;
case Histogram::BOOLEAN_HISTOGRAM:
*result = nsITelemetry::HISTOGRAM_BOOLEAN;
break;
case Histogram::FLAG_HISTOGRAM:
*result = nsITelemetry::HISTOGRAM_FLAG;
break;
default:
return false;
}
return true;
return &gHistogramStringTable[this->expiration_offset];
}
bool
IsExpired(const char *expiration){
static Version current_version = Version(MOZ_APP_VERSION);
MOZ_ASSERT(expiration);
return strcmp(expiration, "never") && (mozilla::Version(expiration) <= current_version);
}
bool
IsExpired(const Histogram *histogram){
return histogram->histogram_name() == EXPIRED_ID;
}
nsresult
HistogramGet(const char *name, uint32_t min, uint32_t max, uint32_t bucketCount,
uint32_t histogramType, Histogram **result)
HistogramGet(const char *name, const char *expiration, uint32_t min, uint32_t max,
uint32_t bucketCount, uint32_t histogramType, Histogram **result)
{
if (histogramType != nsITelemetry::HISTOGRAM_BOOLEAN
&& histogramType != nsITelemetry::HISTOGRAM_FLAG) {
@ -441,6 +443,14 @@ HistogramGet(const char *name, uint32_t min, uint32_t max, uint32_t bucketCount,
return NS_ERROR_ILLEGAL_VALUE;
}
if (IsExpired(expiration)) {
name = EXPIRED_ID;
min = 1;
max = 2;
bucketCount = 3;
histogramType = nsITelemetry::HISTOGRAM_LINEAR;
}
switch (histogramType) {
case nsITelemetry::HISTOGRAM_EXPONENTIAL:
*result = Histogram::FactoryGet(name, min, max, bucketCount, Histogram::kUmaTargetedHistogramFlag);
@ -472,20 +482,22 @@ GetHistogramByEnumId(Telemetry::ID id, Histogram **ret)
}
const TelemetryHistogram &p = gHistograms[id];
nsresult rv = HistogramGet(p.id(), p.min, p.max, p.bucketCount, p.histogramType, &h);
nsresult rv = HistogramGet(p.id(), p.expiration(), p.min, p.max, p.bucketCount, p.histogramType, &h);
if (NS_FAILED(rv))
return rv;
#ifdef DEBUG
// Check that the C++ Histogram code computes the same ranges as the
// Python histogram code.
const struct bounds &b = gBucketLowerBoundIndex[id];
if (b.length != 0) {
MOZ_ASSERT(size_t(b.length) == h->bucket_count(),
"C++/Python bucket # mismatch");
for (int i = 0; i < b.length; ++i) {
MOZ_ASSERT(gBucketLowerBounds[b.offset + i] == h->ranges(i),
"C++/Python bucket mismatch");
if (!IsExpired(p.expiration())) {
const struct bounds &b = gBucketLowerBoundIndex[id];
if (b.length != 0) {
MOZ_ASSERT(size_t(b.length) == h->bucket_count(),
"C++/Python bucket # mismatch");
for (int i = 0; i < b.length; ++i) {
MOZ_ASSERT(gBucketLowerBounds[b.offset + i] == h->ranges(i),
"C++/Python bucket mismatch");
}
}
}
#endif
@ -966,12 +978,13 @@ TelemetryImpl::InitMemoryReporter() {
}
NS_IMETHODIMP
TelemetryImpl::NewHistogram(const nsACString &name, uint32_t min, uint32_t max,
uint32_t bucketCount, uint32_t histogramType,
TelemetryImpl::NewHistogram(const nsACString &name, const nsACString &expiration, uint32_t min,
uint32_t max, uint32_t bucketCount, uint32_t histogramType,
JSContext *cx, JS::Value *ret)
{
Histogram *h;
nsresult rv = HistogramGet(PromiseFlatCString(name).get(), min, max, bucketCount, histogramType, &h);
nsresult rv = HistogramGet(PromiseFlatCString(name).get(), PromiseFlatCString(expiration).get(),
min, max, bucketCount, histogramType, &h);
if (NS_FAILED(rv))
return rv;
h->ClearFlags(Histogram::kUmaTargetedHistogramFlag);
@ -1089,20 +1102,23 @@ NS_IMETHODIMP
TelemetryImpl::HistogramFrom(const nsACString &name, const nsACString &existing_name,
JSContext *cx, JS::Value *ret)
{
Histogram *existing;
nsresult rv = GetHistogramByName(existing_name, &existing);
if (NS_FAILED(rv))
Telemetry::ID id;
nsresult rv = GetHistogramEnumId(PromiseFlatCString(existing_name).get(), &id);
if (NS_FAILED(rv)) {
return rv;
}
const TelemetryHistogram &p = gHistograms[id];
uint32_t histogramType;
bool success = TelemetryHistogramType(existing, &histogramType);
if (!success)
return NS_ERROR_INVALID_ARG;
Histogram *existing;
rv = GetHistogramByEnumId(id, &existing);
if (NS_FAILED(rv)) {
return rv;
}
Histogram *clone;
rv = HistogramGet(PromiseFlatCString(name).get(), existing->declared_min(),
existing->declared_max(), existing->bucket_count(),
histogramType, &clone);
rv = HistogramGet(PromiseFlatCString(name).get(), p.expiration(),
existing->declared_min(), existing->declared_max(),
existing->bucket_count(), p.histogramType, &clone);
if (NS_FAILED(rv))
return rv;
@ -1302,7 +1318,7 @@ TelemetryImpl::GetHistogramSnapshots(JSContext *cx, JS::Value *ret)
JS::Rooted<JSObject*> hobj(cx);
for (HistogramIterator it = hs.begin(); it != hs.end(); ++it) {
Histogram *h = *it;
if (!ShouldReflectHistogram(h) || IsEmpty(h)) {
if (!ShouldReflectHistogram(h) || IsEmpty(h) || IsExpired(h)) {
continue;
}
@ -1333,7 +1349,7 @@ TelemetryImpl::CreateHistogramForAddon(const nsACString &name,
AddonHistogramInfo &info)
{
Histogram *h;
nsresult rv = HistogramGet(PromiseFlatCString(name).get(),
nsresult rv = HistogramGet(PromiseFlatCString(name).get(), "never",
info.min, info.max, info.bucketCount,
info.histogramType, &h);
if (NS_FAILED(rv)) {
@ -1950,15 +1966,21 @@ NS_IMETHODIMP
TelemetryImpl::RegisteredHistograms(uint32_t *aCount, char*** aHistograms)
{
size_t count = ArrayLength(gHistograms);
size_t offset = 0;
char** histograms = static_cast<char**>(nsMemory::Alloc(count * sizeof(char*)));
for (size_t i = 0; i < count; ++i) {
if (IsExpired(gHistograms[i].expiration())) {
offset++;
continue;
}
const char* h = gHistograms[i].id();
size_t len = strlen(h);
histograms[i] = static_cast<char*>(nsMemory::Clone(h, len+1));
histograms[i - offset] = static_cast<char*>(nsMemory::Clone(h, len+1));
}
*aCount = count;
*aCount = count - offset;
*aHistograms = histograms;
return NS_OK;
}

View File

@ -47,19 +47,23 @@ class StringTable:
return ", ".join(map(toCChar, string))
f.write("const char %s[] = {\n" % name)
for (string, offset) in entries[:-1]:
f.write(" /* %5d */ %s, '\\0',\n"
% (offset, explodeToCharArray(string)))
e = explodeToCharArray(string)
if e:
f.write(" /* %5d */ %s, '\\0',\n"
% (offset, explodeToCharArray(string)))
else:
f.write(" /* %5d */ '\\0',\n" % offset)
f.write(" /* %5d */ %s, '\\0' };\n\n"
% (entries[-1][1], explodeToCharArray(entries[-1][0])))
def print_array_entry(histogram, name_index):
def print_array_entry(histogram, name_index, exp_index):
cpp_guard = histogram.cpp_guard()
if cpp_guard:
print "#if defined(%s)" % cpp_guard
print " { %s, %s, %s, %s, %d, %s }," \
print " { %s, %s, %s, %s, %d, %d, %s }," \
% (histogram.low(), histogram.high(),
histogram.n_buckets(), histogram.nsITelemetry_kind(),
name_index,
name_index, exp_index,
"true" if histogram.extended_statistics_ok() else "false")
if cpp_guard:
print "#endif"
@ -70,7 +74,8 @@ def write_histogram_table(histograms):
print "const TelemetryHistogram gHistograms[] = {"
for histogram in histograms:
name_index = table.stringIndex(histogram.name())
print_array_entry(histogram, name_index)
exp_index = table.stringIndex(histogram.expiration())
print_array_entry(histogram, name_index, exp_index)
print "};"
strtab_name = "gHistogramStringTable"

View File

@ -4,6 +4,7 @@
import json
import math
import re
from collections import OrderedDict
@ -54,7 +55,7 @@ def exponential_buckets(dmin, dmax, n_buckets):
ret_array[bucket_index] = current
return ret_array
always_allowed_keys = ['kind', 'description', 'cpp_guard']
always_allowed_keys = ['kind', 'description', 'cpp_guard', 'expires_in_version']
class Histogram:
"""A class for representing a histogram definition."""
@ -75,6 +76,7 @@ symbol that should guard C/C++ definitions associated with the histogram."""
self._kind = definition['kind']
self._cpp_guard = definition.get('cpp_guard')
self._extended_statistics_ok = definition.get('extended_statistics_ok', False)
self._expiration = definition.get('expires_in_version')
self.compute_bucket_parameters(definition)
table = { 'boolean': 'BOOLEAN',
'flag': 'FLAG',
@ -97,6 +99,10 @@ symbol that should guard C/C++ definitions associated with the histogram."""
Will be one of 'boolean', 'flag', 'enumerated', 'linear', or 'exponential'."""
return self._kind
def expiration(self):
"""Return the expiration version of the histogram."""
return self._expiration
def nsITelemetry_kind(self):
"""Return the nsITelemetry constant corresponding to the kind of
the histogram."""
@ -162,6 +168,19 @@ is enabled."""
table_dispatch(definition['kind'], table,
lambda allowed_keys: Histogram.check_keys(name, definition, allowed_keys))
Histogram.check_expiration(name, definition)
@staticmethod
def check_expiration(name, definition):
expiration = definition['expires_in_version']
if not expiration:
return
if not re.match(r'[1-9][0-9]*\..*|never', expiration):
raise BaseException, '%s not permitted as an expiration version for %s; the complete version name is required ' \
'(see https://developer.mozilla.org/en-US/docs/Performance/Adding_a_new_Telemetry_probe)' % (expiration, name)
@staticmethod
def check_keys(name, definition, allowed_keys):
for key in definition.iterkeys():

View File

@ -12,7 +12,7 @@ interface nsIFetchTelemetryDataCallback : nsISupports
void complete();
};
[scriptable, uuid(cb97b7b4-dce6-45fa-be6a-47e436a9aef9)]
[scriptable, uuid(3bdb3c83-1ac0-482a-9c3d-b15141174af4)]
interface nsITelemetry : nsISupports
{
/**
@ -139,6 +139,7 @@ interface nsITelemetry : nsISupports
* Create and return a histogram. Parameters:
*
* @param name Unique histogram name
* @param expiration Expiration version
* @param min - Minimal bucket size
* @param max - Maximum bucket size
* @param bucket_count - number of buckets in the histogram.
@ -149,7 +150,7 @@ interface nsITelemetry : nsISupports
* clear() - Zeros out the histogram's buckets and sum
*/
[implicit_jscontext]
jsval newHistogram(in ACString name, in uint32_t min, in uint32_t max, in uint32_t bucket_count, in unsigned long histogram_type);
jsval newHistogram(in ACString name, in ACString expiration, in uint32_t min, in uint32_t max, in uint32_t bucket_count, in unsigned long histogram_type);
/**
* Create a histogram using the current state of an existing histogram. The

View File

@ -44,6 +44,16 @@ var httpserver = new HttpServer();
var serverStarted = false;
var gFinished = false;
function test_expired_histogram() {
var histogram_id = "FOOBAR";
var dummy = Telemetry.newHistogram(histogram_id, "30", 1, 2, 3, Telemetry.HISTOGRAM_EXPONENTIAL);
dummy.add(1);
do_check_eq(TelemetryPing.getPayload()["histograms"][histogram_id], undefined);
do_check_eq(TelemetryPing.getPayload()["histograms"]["TELEMETRY_TEST_EXPIRED"], undefined);
}
function telemetry_ping () {
TelemetryPing.gatherStartup();
TelemetryPing.enableLoadSaveNotifications();
@ -98,7 +108,7 @@ function nonexistentServerObserver(aSubject, aTopic, aData) {
}
function setupTestData() {
Telemetry.newHistogram(IGNORE_HISTOGRAM, 1, 2, 3, Telemetry.HISTOGRAM_BOOLEAN);
Telemetry.newHistogram(IGNORE_HISTOGRAM, "never", 1, 2, 3, Telemetry.HISTOGRAM_BOOLEAN);
Telemetry.histogramFrom(IGNORE_CLONED_HISTOGRAM, IGNORE_HISTOGRAM_TO_CLONE);
Services.startup.interrupted = true;
Telemetry.registerAddonHistogram(ADDON_NAME, ADDON_HISTOGRAM, 1, 5, 6,
@ -499,6 +509,7 @@ function actualTest() {
registerFakePluginHost();
runInvalidJSONTest();
test_expired_histogram();
addWrappedObserver(nonexistentServerObserver, "telemetry-test-xhr-complete");
telemetry_ping();

View File

@ -9,9 +9,26 @@ const INT_MAX = 0x7FFFFFFF;
const Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
Cu.import("resource://gre/modules/Services.jsm");
function test_expired_histogram() {
var histogram_id = "FOOBAR";
var test_expired_id = "TELEMETRY_TEST_EXPIRED";
var clone_id = "ExpiredClone";
var dummy = Telemetry.newHistogram(histogram_id, "28.0a1", 1, 2, 3, Telemetry.HISTOGRAM_EXPONENTIAL);
var dummy_clone = Telemetry.histogramFrom(clone_id, test_expired_id);
var rh = Telemetry.registeredHistograms([]);
dummy.add(1);
dummy_clone.add(1);
do_check_eq(Telemetry.histogramSnapshots["__expired__"], undefined);
do_check_eq(Telemetry.histogramSnapshots[histogram_id], undefined);
do_check_eq(Telemetry.histogramSnapshots[test_expired_id], undefined);
do_check_eq(Telemetry.histogramSnapshots[clone_id], undefined);
do_check_eq(rh[test_expired_id], undefined);
}
function test_histogram(histogram_type, name, min, max, bucket_count) {
var h = Telemetry.newHistogram(name, min, max, bucket_count, histogram_type);
var h = Telemetry.newHistogram(name, "never", min, max, bucket_count, histogram_type);
var r = h.snapshot().ranges;
var sum = 0;
var log_sum = 0;
@ -109,7 +126,7 @@ function expect_success(f) {
function test_boolean_histogram()
{
var h = Telemetry.newHistogram("test::boolean histogram", 99,1,4, Telemetry.HISTOGRAM_BOOLEAN);
var h = Telemetry.newHistogram("test::boolean histogram", "never", 99,1,4, Telemetry.HISTOGRAM_BOOLEAN);
var r = h.snapshot().ranges;
// boolean histograms ignore numeric parameters
do_check_eq(uneval(r), uneval([0, 1, 2]))
@ -131,7 +148,7 @@ function test_boolean_histogram()
function test_flag_histogram()
{
var h = Telemetry.newHistogram("test::flag histogram", 130, 4, 5, Telemetry.HISTOGRAM_FLAG);
var h = Telemetry.newHistogram("test::flag histogram", "never", 130, 4, 5, Telemetry.HISTOGRAM_FLAG);
var r = h.snapshot().ranges;
// Flag histograms ignore numeric parameters.
do_check_eq(uneval(r), uneval([0, 1, 2]))
@ -312,7 +329,7 @@ function test_addons() {
// Check that telemetry doesn't record in private mode
function test_privateMode() {
var h = Telemetry.newHistogram("test::private_mode_boolean", 1,2,3, Telemetry.HISTOGRAM_BOOLEAN);
var h = Telemetry.newHistogram("test::private_mode_boolean", "never", 1,2,3, Telemetry.HISTOGRAM_BOOLEAN);
var orig = h.snapshot();
Telemetry.canRecord = false;
h.add(1);
@ -349,10 +366,10 @@ function run_test()
for each (let histogram_type in kinds) {
let [min, max, bucket_count] = [1, INT_MAX - 1, 10]
test_histogram(histogram_type, "test::"+histogram_type, min, max, bucket_count);
const nh = Telemetry.newHistogram;
expect_fail(function () nh("test::min", 0, max, bucket_count, histogram_type));
expect_fail(function () nh("test::bucket_count", min, max, 1, histogram_type));
expect_fail(function () nh("test::min", "never", 0, max, bucket_count, histogram_type));
expect_fail(function () nh("test::bucket_count", "never", min, max, 1, histogram_type));
}
// Instantiate the storage for this histogram and make sure it doesn't
@ -367,4 +384,5 @@ function run_test()
test_privateMode();
test_addons();
test_extended_stats();
test_expired_histogram();
}

View File

@ -11,7 +11,7 @@ netOffline=The application is currently in offline mode and can't access the net
deniedPortAccess=The application tried to access a network port that it should not have access to. The application has canceled the request for your protection.
proxyResolveFailure=The application is configured to use a proxy server that can't be found.
proxyConnectFailure=The application is configured to use a proxy server that is refusing connections.
contentEncodingError=The application recieved a response from a server which used an invalid or unsupported form of compression.
contentEncodingError=The application received a response from a server which used an invalid or unsupported form of compression.
unsafeContentType=The application cannot continue because it accessed a file type that may not be safe to open. Please contact the application authors to inform them of this problem.
cspFrameAncestorBlocked=This application tried to access a resource that has a content security policy that prevents it from being embedded in this way.
corruptedContentError=The application cannot continue loading because an error in the data transmission was detected.

View File

@ -52,13 +52,13 @@ SpecifiedWarning=Use of attributes' specified attribute is deprecated. It always
OwnerElementWarning=Use of attributes' ownerElement attribute is deprecated.
NodeValueWarning=Use of attributes' nodeValue attribute is deprecated. Use value instead.
TextContentWarning=Use of attributes' textContent attribute is deprecated. Use value instead.
EnablePrivilegeWarning=Use of enablePrivilege is deprecated. Please use code that runs with the system principal (e.g. an extension) instead.
nsIJSONDecodeDeprecatedWarning=nsIJSON.decode is deprecated. Please use JSON.parse instead.
nsIJSONEncodeDeprecatedWarning=nsIJSON.encode is deprecated. Please use JSON.stringify instead.
EnablePrivilegeWarning=Use of enablePrivilege is deprecated. Please use code that runs with the system principal (e.g. an extension) instead.
nsIJSONDecodeDeprecatedWarning=nsIJSON.decode is deprecated. Please use JSON.parse instead.
nsIJSONEncodeDeprecatedWarning=nsIJSON.encode is deprecated. Please use JSON.stringify instead.
nsIDOMWindowInternalWarning=Use of nsIDOMWindowInternal is deprecated. Use nsIDOMWindow instead.
InputEncodingWarning=Use of inputEncoding is deprecated.
# LOCALIZATION NOTE: Do not translate "MozBeforePaint" and "mozRequestAnimationFrame"
MozBeforePaintWarning=MozBeforePaint events are no longer supported. mozRequestAnimationFrame must be passed a non-null callback argument.
MozBeforePaintWarning=MozBeforePaint events are no longer supported. mozRequestAnimationFrame must be passed a non-null callback argument.
FullScreenDeniedBlocked=Request for full-screen was denied because this domain has been blocked from full-screen by user.
FullScreenDeniedDisabled=Request for full-screen was denied because full-screen API is disabled by user preference.
FullScreenDeniedFocusedPlugin=Request for full-screen was denied because a windowed plugin is focused.
@ -111,7 +111,7 @@ NoExposedPropsWarning=Exposing chrome JS objects to content without __exposedPro
# LOCALIZATION NOTE: Do not translate "Mutation Event" and "MutationObserver"
MutationEventWarning=Use of Mutation Events is deprecated. Use MutationObserver instead.
# LOCALIZATION NOTE: Do not translate "Blob", "mozSlice", or "slice"
MozSliceWarning=Use of mozSlice on the Blob object is deprecated. Use slice instead.
MozSliceWarning=Use of mozSlice on the Blob object is deprecated. Use slice instead.
# LOCALIZATION NOTE: Do not translate "Components"
ComponentsWarning=The Components object is deprecated. It will soon be removed.
PluginHangUITitle=Warning: Unresponsive plugin
@ -119,21 +119,21 @@ PluginHangUIMessage=%S may be busy, or it may have stopped responding. You can s
PluginHangUIWaitButton=Continue
PluginHangUIStopButton=Stop plugin
# LOCALIZATION NOTE: Do not translate "mozHidden", "mozVisibilityState", "hidden", or "visibilityState"
PrefixedVisibilityApiWarning='mozHidden' and 'mozVisibilityState' are deprecated. Please use the unprefixed 'hidden' and 'visibilityState' instead.
PrefixedVisibilityApiWarning='mozHidden' and 'mozVisibilityState' are deprecated. Please use the unprefixed 'hidden' and 'visibilityState' instead.
# LOCALIZATION NOTE: Do not translate "NodeIterator" or "detach()".
NodeIteratorDetachWarning=Calling detach() on a NodeIterator no longer has an effect.
# LOCALIZATION NOTE: Do not translate "Mozilla Audio Data API" and "Web Audio API".
MozAudioDataWarning=The Mozilla Audio Data API is deprecated. Please use the Web Audio API instead.
MozAudioDataWarning=The Mozilla Audio Data API is deprecated. Please use the Web Audio API instead.
# LOCALIZATION NOTE: Do not translate "LenientThis" and "this"
LenientThisWarning=Ignoring get or set of property that has [LenientThis] because the "this" object is incorrect.
# LOCALIZATION NOTE: Do not translate "nsIDOMWindowUtils", "getWindowWithOuterId", or "nsIWindowMediator"
GetWindowWithOuterIdWarning=Use of nsIDOMWindowUtils.getOuterWindowWithId() is deprecated. Instead, use the nsIWindowMediator method of the same name.
GetWindowWithOuterIdWarning=Use of nsIDOMWindowUtils.getOuterWindowWithId() is deprecated. Instead, use the nsIWindowMediator method of the same name.
# LOCALIZATION NOTE: Do not translate "getPreventDefault" or "defaultPrevented".
GetPreventDefaultWarning=Use of getPreventDefault() is deprecated. Use defaultPrevented instead.
GetPreventDefaultWarning=Use of getPreventDefault() is deprecated. Use defaultPrevented instead.
# LOCALIZATION NOTE: Do not translate "getUserData", "setUserData", "WeakMap", or "element.dataset".
GetSetUserDataWarning=Use of getUserData() or setUserData() is deprecated. Use WeakMap or element.dataset instead.
GetSetUserDataWarning=Use of getUserData() or setUserData() is deprecated. Use WeakMap or element.dataset instead.
# LOCALIZATION NOTE: Do not translate "mozGetAsFile" or "toBlob"
MozGetAsFileWarning=The non-standard mozGetAsFile method is deprecated and will soon be removed. Use the standard toBlob method instead.
MozGetAsFileWarning=The non-standard mozGetAsFile method is deprecated and will soon be removed. Use the standard toBlob method instead.
# LOCALIZATION NOTE: Do not translate "captureEvents()" or "addEventListener()"
UseOfCaptureEventsWarning=Use of captureEvents() is deprecated. To upgrade your code, use the DOM 2 addEventListener() method. For more help http://developer.mozilla.org/en/docs/DOM:element.addEventListener
# LOCALIZATION NOTE: Do not translate "releaseEvents()" or "removeEventListener()"
@ -143,4 +143,4 @@ UseOfDOM3LoadMethodWarning=Use of document.load() is deprecated. To upgrade your
# LOCALIZATION NOTE: Do not translate "window.showModalDialog()" or "window.open()"
ShowModalDialogWarning=Use of window.showModalDialog() is deprecated. Use window.open() instead. For more help https://developer.mozilla.org/en-US/docs/Web/API/Window.open
# LOCALIZATION NOTE: Do not translate "window._content" or "window.content"
Window_ContentWarning=window._content is deprecated. Please use window.content instead.
Window_ContentWarning=window._content is deprecated. Please use window.content instead.