Merge m-c to autoland, a=merge

This commit is contained in:
Wes Kocher 2016-08-30 18:15:33 -07:00
Родитель 4a2a67b606 6536590412
Коммит 81db6ce036
160 изменённых файлов: 3837 добавлений и 846 удалений

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

@ -263,8 +263,7 @@ static const MarkupMapInfo sMarkupMapList[] = {
nsAccessibilityService *nsAccessibilityService::gAccessibilityService = nullptr;
ApplicationAccessible* nsAccessibilityService::gApplicationAccessible = nullptr;
xpcAccessibleApplication* nsAccessibilityService::gXPCApplicationAccessible = nullptr;
bool nsAccessibilityService::gIsShutdown = true;
bool nsAccessibilityService::gIsPlatformCaller = false;
uint32_t nsAccessibilityService::gConsumers = 0;
nsAccessibilityService::nsAccessibilityService() :
DocManager(), FocusManager(), mMarkupMaps(ArrayLength(sMarkupMapList))
@ -273,7 +272,7 @@ nsAccessibilityService::nsAccessibilityService() :
nsAccessibilityService::~nsAccessibilityService()
{
NS_ASSERTION(gIsShutdown, "Accessibility wasn't shutdown!");
NS_ASSERTION(IsShutdown(), "Accessibility wasn't shutdown!");
gAccessibilityService = nullptr;
}
@ -957,7 +956,7 @@ nsAccessibilityService::CreateAccessible(nsINode* aNode,
{
MOZ_ASSERT(aContext, "No context provided");
MOZ_ASSERT(aNode, "No node to create an accessible for");
MOZ_ASSERT(!gIsShutdown, "No creation after shutdown");
MOZ_ASSERT(gConsumers, "No creation after shutdown");
if (aIsSubtreeHidden)
*aIsSubtreeHidden = false;
@ -1284,8 +1283,6 @@ nsAccessibilityService::Init()
sPluginTimers = new nsTArray<nsCOMPtr<nsITimer> >;
#endif
gIsShutdown = false;
// Now its safe to start platform accessibility.
if (XRE_IsParentProcess())
PlatformInit();
@ -1303,9 +1300,9 @@ nsAccessibilityService::Shutdown()
// Don't null accessibility service static member at this point to be safe
// if someone will try to operate with it.
MOZ_ASSERT(!gIsShutdown, "Accessibility was shutdown already");
MOZ_ASSERT(gConsumers, "Accessibility was shutdown already");
gIsShutdown = true;
gConsumers = 0;
// Remove observers.
nsCOMPtr<nsIObserverService> observerService =
@ -1344,7 +1341,6 @@ nsAccessibilityService::Shutdown()
NS_RELEASE(gAccessibilityService);
gAccessibilityService = nullptr;
gIsPlatformCaller = false;
}
already_AddRefed<Accessible>
@ -1778,12 +1774,8 @@ nsAccessibilityService::CreateAccessibleForXULTree(nsIContent* aContent,
#endif
nsAccessibilityService*
GetOrCreateAccService(bool aIsPlatformCaller)
GetOrCreateAccService(uint32_t aNewConsumer)
{
if (aIsPlatformCaller) {
nsAccessibilityService::gIsPlatformCaller = aIsPlatformCaller;
}
if (!nsAccessibilityService::gAccessibilityService) {
RefPtr<nsAccessibilityService> service = new nsAccessibilityService();
if (!service->Init()) {
@ -1794,19 +1786,34 @@ GetOrCreateAccService(bool aIsPlatformCaller)
MOZ_ASSERT(nsAccessibilityService::gAccessibilityService,
"Accessible service is not initialized.");
nsAccessibilityService::gConsumers |= aNewConsumer;
return nsAccessibilityService::gAccessibilityService;
}
bool
CanShutdownAccService()
void
MaybeShutdownAccService(uint32_t aFormerConsumer)
{
nsAccessibilityService* accService = nsAccessibilityService::gAccessibilityService;
if (!accService) {
return false;
nsAccessibilityService* accService =
nsAccessibilityService::gAccessibilityService;
if (!accService || accService->IsShutdown()) {
return;
}
if (nsCoreUtils::AccEventObserversExist() ||
xpcAccessibilityService::IsInUse()) {
// Still used by XPCOM
nsAccessibilityService::gConsumers =
(nsAccessibilityService::gConsumers & ~aFormerConsumer) |
nsAccessibilityService::eXPCOM;
return;
}
if (nsAccessibilityService::gConsumers & ~aFormerConsumer) {
nsAccessibilityService::gConsumers &= ~aFormerConsumer;
} else {
accService->Shutdown(); // Will unset all nsAccessibilityService::gConsumers
}
return !xpcAccessibilityService::IsInUse() &&
!accService->IsPlatformCaller() && !accService->IsShutdown() &&
!nsCoreUtils::AccEventObserversExist();
}
////////////////////////////////////////////////////////////////////////////////

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

@ -195,12 +195,10 @@ public:
/**
* Return true if accessibility service has been shutdown.
*/
static bool IsShutdown() { return gIsShutdown; }
/**
* Return true if accessibility service has been initialized by platform.
*/
static bool IsPlatformCaller() { return gIsPlatformCaller; };
static bool IsShutdown()
{
return gConsumers == 0;
};
/**
* Creates an accessible for the given DOM node.
@ -226,6 +224,25 @@ public:
void MarkupAttributes(const nsIContent* aContent,
nsIPersistentProperties* aAttributes) const;
/**
* A list of possible accessibility service consumers. Accessibility service
* can only be shut down when there are no remaining consumers.
*
* eXPCOM - accessibility service is used by XPCOM.
*
* eMainProcess - accessibility service was started by main process in the
* content process.
*
* ePlatformAPI - accessibility service is used by the platform api in the
* main process.
*/
enum ServiceConsumer
{
eXPCOM = 1 << 0,
eMainProcess = 1 << 1,
ePlatformAPI = 1 << 2,
};
private:
// nsAccessibilityService creation is controlled by friend
// GetOrCreateAccService, keep constructors private.
@ -277,20 +294,15 @@ private:
static mozilla::a11y::xpcAccessibleApplication* gXPCApplicationAccessible;
/**
* Indicates whether accessibility service was shutdown.
* Contains a set of accessibility service consumers.
*/
static bool gIsShutdown;
/**
* Indicates whether accessibility service was initialized by platform.
*/
static bool gIsPlatformCaller;
static uint32_t gConsumers;
nsDataHashtable<nsPtrHashKey<const nsIAtom>, const mozilla::a11y::MarkupMapInfo*> mMarkupMaps;
friend nsAccessibilityService* GetAccService();
friend nsAccessibilityService* GetOrCreateAccService(bool);
friend bool CanShutdownAccService();
friend nsAccessibilityService* GetOrCreateAccService(uint32_t);
friend void MaybeShutdownAccService(uint32_t);
friend mozilla::a11y::FocusManager* mozilla::a11y::FocusMgr();
friend mozilla::a11y::SelectionManager* mozilla::a11y::SelectionMgr();
friend mozilla::a11y::ApplicationAccessible* mozilla::a11y::ApplicationAcc();
@ -310,12 +322,13 @@ GetAccService()
/**
* Return accessibility service instance; creating one if necessary.
*/
nsAccessibilityService* GetOrCreateAccService(bool aIsPlatformCaller = true);
nsAccessibilityService* GetOrCreateAccService(
uint32_t aNewConsumer = nsAccessibilityService::ePlatformAPI);
/**
* Return a flag indicating if accessibility service can be shutdown.
* Shutdown accessibility service if needed.
*/
bool CanShutdownAccService();
void MaybeShutdownAccService(uint32_t aFormerConsumer);
/**
* Return true if we're in a content process and not B2G.

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

@ -5,5 +5,13 @@ support-files =
shared-head.js
[browser_shutdown_multi_reference.js]
[browser_shutdown_parent_own_reference.js]
skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
[browser_shutdown_remote_no_reference.js]
skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
[browser_shutdown_remote_only.js]
skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
[browser_shutdown_remote_own_reference.js]
skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
[browser_shutdown_scope_lifecycle.js]
[browser_shutdown_start_restart.js]

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

@ -0,0 +1,72 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
add_task(function* () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
yield BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
<head>
<meta charset="utf-8"/>
<title>Accessibility Test</title>
</head>
<body></body>
</html>`
}, function*(browser) {
info('Creating a service in parent and waiting for service to be created ' +
'in content');
// Create a11y service in the main process. This will trigger creating of
// the a11y service in parent as well.
let parentA11yInit = initPromise();
let contentA11yInit = initPromise(browser);
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized in parent');
yield Promise.all([parentA11yInit, contentA11yInit]);
info('Adding additional reference to accessibility service in content ' +
'process');
// Add a new reference to the a11y service inside the content process.
loadFrameScripts(browser, `let accService = Components.classes[
'@mozilla.org/accessibilityService;1'].getService(
Components.interfaces.nsIAccessibilityService);`);
info('Trying to shut down a service in content and making sure it stays ' +
'alive as it was started by parent');
let contentCanShutdown = false;
// This promise will resolve only if contentCanShutdown flag is set to true.
// If 'a11y-init-or-shutdown' event with '0' flag (in content) comes before
// it can be shut down, the promise will reject.
let contentA11yShutdown = new Promise((resolve, reject) =>
shutdownPromise(browser).then(flag => contentCanShutdown ?
resolve() : reject('Accessible service was shut down incorrectly')));
// Remove a11y service reference in content and force garbage collection.
// This should not trigger shutdown since a11y was originally initialized by
// the main process.
loadFrameScripts(browser, `accService = null; Components.utils.forceGC();`);
// Have some breathing room between a11y service shutdowns.
yield new Promise(resolve => executeSoon(resolve));
info('Removing a service in parent');
// Now allow a11y service to shutdown in content.
contentCanShutdown = true;
// Remove the a11y service reference in the main process.
let parentA11yShutdown = shutdownPromise();
accService = null;
ok(!accService, 'Service is removed in parent');
// Force garbage collection that should trigger shutdown in both parent and
// content.
forceGC();
yield Promise.all([parentA11yShutdown, contentA11yShutdown]);
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
});
});

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

@ -0,0 +1,48 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
add_task(function* () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
yield BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
<head>
<meta charset="utf-8"/>
<title>Accessibility Test</title>
</head>
<body></body>
</html>`
}, function*(browser) {
info('Creating a service in parent and waiting for service to be created ' +
'in content');
// Create a11y service in the main process. This will trigger creating of
// the a11y service in parent as well.
let parentA11yInit = initPromise();
let contentA11yInit = initPromise(browser);
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized in parent');
yield Promise.all([parentA11yInit, contentA11yInit]);
info('Removing a service in parent and waiting for service to be shut ' +
'down in content');
// Remove a11y service reference in the main process.
let parentA11yShutdown = shutdownPromise();
let contentA11yShutdown = shutdownPromise(browser);
accService = null;
ok(!accService, 'Service is removed in parent');
// Force garbage collection that should trigger shutdown in both main and
// content process.
forceGC();
yield Promise.all([parentA11yShutdown, contentA11yShutdown]);
});
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
});

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

@ -0,0 +1,40 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
add_task(function* () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
yield BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
<head>
<meta charset="utf-8"/>
<title>Accessibility Test</title>
</head>
<body></body>
</html>`
}, function*(browser) {
info('Creating a service in content');
// Create a11y service in the content process.
let a11yInit = initPromise(browser);
loadFrameScripts(browser, `let accService = Components.classes[
'@mozilla.org/accessibilityService;1'].getService(
Components.interfaces.nsIAccessibilityService);`);
yield a11yInit;
info('Removing a service in content');
// Remove a11y service reference from the content process.
let a11yShutdown = shutdownPromise(browser);
// Force garbage collection that should trigger shutdown.
loadFrameScripts(browser, `accService = null; Components.utils.forceGC();`);
yield a11yShutdown;
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
});
});

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

@ -0,0 +1,75 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
add_task(function* () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
yield BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
<head>
<meta charset="utf-8"/>
<title>Accessibility Test</title>
</head>
<body></body>
</html>`
}, function*(browser) {
info('Creating a service in parent and waiting for service to be created ' +
'in content');
// Create a11y service in the main process. This will trigger creating of
// the a11y service in parent as well.
let parentA11yInit = initPromise();
let contentA11yInit = initPromise(browser);
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized in parent');
yield Promise.all([parentA11yInit, contentA11yInit]);
info('Adding additional reference to accessibility service in content ' +
'process');
// Add a new reference to the a11y service inside the content process.
loadFrameScripts(browser, `let accService = Components.classes[
'@mozilla.org/accessibilityService;1'].getService(
Components.interfaces.nsIAccessibilityService);`);
info('Shutting down a service in parent and making sure the one in ' +
'content stays alive');
let contentCanShutdown = false;
let parentA11yShutdown = shutdownPromise();
// This promise will resolve only if contentCanShutdown flag is set to true.
// If 'a11y-init-or-shutdown' event with '0' flag (in content) comes before
// it can be shut down, the promise will reject.
let contentA11yShutdown = new Promise((resolve, reject) =>
shutdownPromise(browser).then(flag => contentCanShutdown ?
resolve() : reject('Accessible service was shut down incorrectly')));
// Remove a11y service reference in the main process and force garbage
// collection. This should not trigger shutdown in content since a11y
// service is used by XPCOM.
accService = null;
ok(!accService, 'Service is removed in parent');
// Force garbage collection that should not trigger shutdown because there
// is a reference in a content process.
forceGC();
loadFrameScripts(browser, `Components.utils.forceGC();`);
yield parentA11yShutdown;
// Have some breathing room between a11y service shutdowns.
yield new Promise(resolve => executeSoon(resolve));
info('Removing a service in content');
// Now allow a11y service to shutdown in content.
contentCanShutdown = true;
// Remove last reference to a11y service in content and force garbage
// collection that should trigger shutdown.
loadFrameScripts(browser, `accService = null; Components.utils.forceGC();`);
yield contentA11yShutdown;
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
});
});

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

@ -4,7 +4,7 @@
'use strict';
add_task(function* testScopeLifecycle() {
add_task(function* () {
// Create a11y service inside of the function scope. Its reference should be
// released once the anonimous function is called.
let a11yInitThenShutdown = initPromise().then(shutdownPromise);

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

@ -4,7 +4,7 @@
'use strict';
add_task(function* testStartAndRestart() {
add_task(function* () {
info('Creating a service');
// Create a11y service.
let a11yInit = initPromise();

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

@ -23,10 +23,7 @@ xpcAccessibilityService *xpcAccessibilityService::gXPCAccessibilityService = nul
void
xpcAccessibilityService::ShutdownCallback(nsITimer* aTimer, void* aClosure)
{
if (CanShutdownAccService()) {
GetAccService()->Shutdown();
}
MaybeShutdownAccService(nsAccessibilityService::eXPCOM);
xpcAccessibilityService* xpcAccService =
reinterpret_cast<xpcAccessibilityService*>(aClosure);
@ -47,7 +44,7 @@ xpcAccessibilityService::AddRef(void)
NS_LOG_ADDREF(this, count, "xpcAccessibilityService", sizeof(*this));
if (mRefCnt > 1) {
GetOrCreateAccService(false);
GetOrCreateAccService(nsAccessibilityService::eXPCOM);
}
return count;
@ -238,7 +235,7 @@ NS_GetAccessibilityService(nsIAccessibilityService** aResult)
NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
*aResult = nullptr;
GetOrCreateAccService(false);
GetOrCreateAccService(nsAccessibilityService::eXPCOM);
xpcAccessibilityService* service = new xpcAccessibilityService();
NS_ENSURE_TRUE(service, NS_ERROR_OUT_OF_MEMORY);

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

@ -24,11 +24,23 @@ richlistitem[type="download"].download-state[state="1"]:not([exists]) .downloadS
#downloadsSummary:not([inprogress]) > vbox > #downloadsSummaryProgress,
#downloadsSummary:not([inprogress]) > vbox > #downloadsSummaryDetails,
#downloadsFooter[showingsummary] > #downloadsFooterButtons,
#downloadsFooter:not([showingsummary]) > #downloadsSummary {
#downloadsFooter:not([showingsummary]) #downloadsSummary {
display: none;
}
#downloadsFooter[showingdropdown] > stack > #downloadsSummary,
#downloadsFooter[showingsummary] > stack:hover > #downloadsSummary,
#downloadsFooter[showingsummary]:not([showingdropdown]) > stack:not(:hover) > #downloadsFooterButtons {
/* If we used "visibility: hidden;" then the mouseenter event of
#downloadsHistory wouldn't be triggered immediately, and the hover styling
of the button would not apply until the mouse is moved again.
"-moz-user-focus: ignore;" prevents the elements with "opacity: 0;" from
being focused with the keyboard. */
opacity: 0;
-moz-user-focus: ignore;
}
/*** Downloads View ***/
/**

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

@ -382,14 +382,15 @@ const DownloadsPanel = {
} else {
itemClearList.setAttribute("hidden", "true");
}
DownloadsViewController.updateCommands();
document.getElementById("downloadsFooterButtonsSplitter").classList
.add("downloadsDropmarkerSplitterExtend");
document.getElementById("downloadsFooter")
.setAttribute("showingdropdown", true);
},
onFooterPopupHidden(aEvent) {
document.getElementById("downloadsFooterButtonsSplitter").classList
.remove("downloadsDropmarkerSplitterExtend");
document.getElementById("downloadsFooter")
.removeAttribute("showingdropdown");
},
//////////////////////////////////////////////////////////////////////////////

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

@ -129,51 +129,53 @@
<spacer flex="1"/>
<vbox id="downloadsFooter"
class="downloadsPanelFooter">
<hbox id="downloadsSummary"
align="center"
orient="horizontal"
onkeydown="DownloadsSummary.onKeyDown(event);"
onclick="DownloadsSummary.onClick(event);">
<image class="downloadTypeIcon" />
<vbox pack="center"
class="downloadContainer"
style="width: &downloadDetails.width;">
<description id="downloadsSummaryDescription"
style="min-width: &downloadsSummary.minWidth2;"/>
<progressmeter id="downloadsSummaryProgress"
class="downloadProgress"
min="0"
max="100"
mode="normal" />
<description id="downloadsSummaryDetails"
crop="end"/>
</vbox>
</hbox>
<hbox id="downloadsFooterButtons">
<button id="downloadsHistory"
class="plain downloadsPanelFooterButton"
label="&downloadsHistory.label;"
accesskey="&downloadsHistory.accesskey;"
flex="1"
oncommand="DownloadsPanel.showDownloadsHistory();"/>
<toolbarseparator id="downloadsFooterButtonsSplitter"
class="downloadsDropmarkerSplitter"/>
<button id="downloadsFooterDropmarker"
class="plain downloadsPanelFooterButton downloadsDropmarker"
type="menu">
<menupopup id="downloadSubPanel"
onpopupshowing="DownloadsPanel.onFooterPopupShowing(event);"
onpopuphidden="DownloadsPanel.onFooterPopupHidden(event);"
position="after_end">
<menuitem id="downloadsDropdownItemClearList"
command="downloadsCmd_clearList"
label="&cmd.clearList2.label;"/>
<menuitem id="downloadsDropdownItemOpenDownloadsFolder"
oncommand="DownloadsPanel.openDownloadsFolder();"
label="&openDownloadsFolder.label;"/>
</menupopup>
</button>
</hbox>
<stack>
<hbox id="downloadsSummary"
align="center"
orient="horizontal"
onkeydown="DownloadsSummary.onKeyDown(event);"
onclick="DownloadsSummary.onClick(event);">
<image class="downloadTypeIcon" />
<vbox pack="center"
class="downloadContainer"
style="width: &downloadDetails.width;">
<description id="downloadsSummaryDescription"
style="min-width: &downloadsSummary.minWidth2;"/>
<progressmeter id="downloadsSummaryProgress"
class="downloadProgress"
min="0"
max="100"
mode="normal" />
<description id="downloadsSummaryDetails"
crop="end"/>
</vbox>
</hbox>
<hbox id="downloadsFooterButtons">
<button id="downloadsHistory"
class="plain downloadsPanelFooterButton"
label="&downloadsHistory.label;"
accesskey="&downloadsHistory.accesskey;"
flex="1"
oncommand="DownloadsPanel.showDownloadsHistory();"/>
<toolbarseparator id="downloadsFooterButtonsSplitter"
class="downloadsDropmarkerSplitter"/>
<button id="downloadsFooterDropmarker"
class="plain downloadsPanelFooterButton downloadsDropmarker"
type="menu">
<menupopup id="downloadSubPanel"
onpopupshowing="DownloadsPanel.onFooterPopupShowing(event);"
onpopuphidden="DownloadsPanel.onFooterPopupHidden(event);"
position="after_end">
<menuitem id="downloadsDropdownItemClearList"
command="downloadsCmd_clearList"
label="&cmd.clearList2.label;"/>
<menuitem id="downloadsDropdownItemOpenDownloadsFolder"
oncommand="DownloadsPanel.openDownloadsFolder();"
label="&openDownloadsFolder.label;"/>
</menupopup>
</button>
</hbox>
</stack>
</vbox>
</panelview>

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

@ -7,3 +7,4 @@ support-files =
[browser_dummy.js]
skip-if = true
[browser_localStorageIsolation.js]

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

@ -0,0 +1,24 @@
/**
* Bug 1264567 - A test case for localStorage isolation.
*/
const TEST_PAGE = "http://mochi.test:8888/browser/browser/components/" +
"originattributes/test/browser/file_firstPartyBasic.html";
// Use a random key so we don't access it in later tests.
const key = Math.random().toString();
// Define the testing function
function* doTest(aBrowser) {
return yield ContentTask.spawn(aBrowser, key, function (key) {
let value = content.localStorage.getItem(key);
if (value === null) {
// No value is found, so we create one.
value = Math.random().toString();
content.localStorage.setItem(key, value);
}
return value;
});
}
IsolationTestTools.runTests(TEST_PAGE, doTest);

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

@ -176,7 +176,7 @@ this.IsolationTestTools = {
add_task(function* addTaskForIsolationTests() {
let testSettings = [
{ mode: TEST_MODE_FIRSTPARTY,
skip: false,
skip: true,
prefs: [["privacy.firstparty.isolate", true]]
},
{ mode: TEST_MODE_NO_ISOLATION,

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

@ -3,6 +3,7 @@
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=0
ac_add_options --with-branding=browser/branding/unofficial
ac_add_options --enable-update-channel=default
# Need this to prevent name conflicts with the normal nightly build packages
export MOZ_PKG_SPECIAL=add-on-devel

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

@ -3,6 +3,7 @@
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=0
ac_add_options --with-branding=browser/branding/unofficial
ac_add_options --enable-update-channel=default
# Need this to prevent name conflicts with the normal nightly build packages
export MOZ_PKG_SPECIAL=add-on-devel

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

@ -3,6 +3,7 @@
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=0
ac_add_options --with-branding=browser/branding/unofficial
ac_add_options --enable-update-channel=default
# Need this to prevent name conflicts with the normal nightly build packages
export MOZ_PKG_SPECIAL=add-on-devel

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

@ -3,6 +3,7 @@
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=0
ac_add_options --with-branding=browser/branding/unofficial
ac_add_options --enable-update-channel=default
#Need this to prevent name conflicts with the normal nightly build packages
export MOZ_PKG_SPECIAL=add-on-devel

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

@ -94,7 +94,7 @@ toolbarseparator.downloadsDropmarkerSplitter {
}
#downloadsFooter:hover toolbarseparator.downloadsDropmarkerSplitter,
#downloadsFooter toolbarseparator.downloadsDropmarkerSplitterExtend {
#downloadsFooter[showingdropdown] toolbarseparator {
margin: 0;
}

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

@ -47,6 +47,7 @@ support-files =
[browser_toolbox_highlight.js]
[browser_toolbox_hosts.js]
[browser_toolbox_hosts_size.js]
[browser_toolbox_hosts_telemetry.js]
[browser_toolbox_keyboard_navigation.js]
skip-if = os == "mac" # Full keyboard navigation on OSX only works if Full Keyboard Access setting is set to All Control in System Keyboard Preferences
[browser_toolbox_minimize.js]

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

@ -0,0 +1,50 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const {Toolbox} = require("devtools/client/framework/toolbox");
const {SIDE, BOTTOM, WINDOW} = Toolbox.HostType;
const URL = "data:text/html;charset=utf8,browser_toolbox_hosts_telemetry.js";
function getHostHistogram() {
return Services.telemetry.getHistogramById("DEVTOOLS_TOOLBOX_HOST");
}
add_task(function* () {
// Reset it to make counting easier
getHostHistogram().clear();
info("Create a test tab and open the toolbox");
let tab = yield addTab(URL);
let target = TargetFactory.forTab(tab);
let toolbox = yield gDevTools.showToolbox(target, "webconsole");
yield changeToolboxHost(toolbox);
yield checkResults();
yield toolbox.destroy();
toolbox = target = null;
gBrowser.removeCurrentTab();
// Cleanup
getHostHistogram().clear();
});
function* changeToolboxHost(toolbox) {
info("Switch toolbox host");
yield toolbox.switchHost(SIDE);
yield toolbox.switchHost(WINDOW);
yield toolbox.switchHost(BOTTOM);
yield toolbox.switchHost(SIDE);
yield toolbox.switchHost(WINDOW);
yield toolbox.switchHost(BOTTOM);
}
function checkResults() {
let counts = getHostHistogram().snapshot().counts;
is(counts[0], 3, "Toolbox HostType bottom has 3 successful entries");
is(counts[1], 2, "Toolbox HostType side has 2 successful entries");
is(counts[2], 2, "Toolbox HostType window has 2 successful entries");
}

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

@ -504,3 +504,50 @@ var closeToolbox = Task.async(function* () {
let target = TargetFactory.forTab(gBrowser.selectedTab);
yield gDevTools.closeToolbox(target);
});
/**
* Load the Telemetry utils, then stub Telemetry.prototype.log and
* Telemetry.prototype.logKeyed in order to record everything that's logged in
* it.
* Store all recordings in Telemetry.telemetryInfo.
* @return {Telemetry}
*/
function loadTelemetryAndRecordLogs() {
info("Mock the Telemetry log function to record logged information");
let Telemetry = require("devtools/client/shared/telemetry");
Telemetry.prototype.telemetryInfo = {};
Telemetry.prototype._oldlog = Telemetry.prototype.log;
Telemetry.prototype.log = function (histogramId, value) {
if (!this.telemetryInfo) {
// Telemetry instance still in use after stopRecordingTelemetryLogs
return;
}
if (histogramId) {
if (!this.telemetryInfo[histogramId]) {
this.telemetryInfo[histogramId] = [];
}
this.telemetryInfo[histogramId].push(value);
}
};
Telemetry.prototype._oldlogKeyed = Telemetry.prototype.logKeyed;
Telemetry.prototype.logKeyed = function (histogramId, key, value) {
this.log(`${histogramId}|${key}`, value);
};
return Telemetry;
}
/**
* Stop recording the Telemetry logs and put back the utils as it was before.
* @param {Telemetry} Required Telemetry
* Telemetry object that needs to be stopped.
*/
function stopRecordingTelemetryLogs(Telemetry) {
info("Stopping Telemetry");
Telemetry.prototype.log = Telemetry.prototype._oldlog;
Telemetry.prototype.logKeyed = Telemetry.prototype._oldlogKeyed;
delete Telemetry.prototype._oldlog;
delete Telemetry.prototype._oldlogKeyed;
delete Telemetry.prototype.telemetryInfo;
}

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

@ -9,6 +9,7 @@ const SPLITCONSOLE_ENABLED_PREF = "devtools.toolbox.splitconsoleEnabled";
const SPLITCONSOLE_HEIGHT_PREF = "devtools.toolbox.splitconsoleHeight";
const OS_HISTOGRAM = "DEVTOOLS_OS_ENUMERATED_PER_USER";
const OS_IS_64_BITS = "DEVTOOLS_OS_IS_64_BITS_PER_USER";
const HOST_HISTOGRAM = "DEVTOOLS_TOOLBOX_HOST";
const SCREENSIZE_HISTOGRAM = "DEVTOOLS_SCREEN_RESOLUTION_ENUMERATED_PER_USER";
const HTML_NS = "http://www.w3.org/1999/xhtml";
const { SourceMapService } = require("./source-map-service");
@ -488,6 +489,17 @@ Toolbox.prototype = {
return this.browserRequire("devtools/client/shared/vendor/react-dom");
},
// Return HostType id for telemetry
_getTelemetryHostId: function () {
switch (this.hostType) {
case Toolbox.HostType.BOTTOM: return 0;
case Toolbox.HostType.SIDE: return 1;
case Toolbox.HostType.WINDOW: return 2;
case Toolbox.HostType.CUSTOM: return 3;
default: return 9;
}
},
_pingTelemetry: function () {
this._telemetry.toolOpened("toolbox");
@ -495,6 +507,7 @@ Toolbox.prototype = {
this._telemetry.logOncePerBrowserVersion(OS_IS_64_BITS,
Services.appinfo.is64Bit ? 1 : 0);
this._telemetry.logOncePerBrowserVersion(SCREENSIZE_HISTOGRAM, system.getScreenDimensions());
this._telemetry.log(HOST_HISTOGRAM, this._getTelemetryHostId());
},
/**
@ -1836,6 +1849,8 @@ Toolbox.prototype = {
this.focusTool(this.currentToolId, true);
this.emit("host-changed");
this._telemetry.log(HOST_HISTOGRAM, this._getTelemetryHostId());
});
},

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

@ -29,6 +29,7 @@
<script type="application/javascript;version=1.8"
src="chrome://devtools/content/shared/theme-switching.js"/>
<box flex="1" class="devtools-responsive-container theme-body">
<vbox flex="1" class="devtools-main-content">
<html:div id="inspector-toolbar"

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

@ -81,6 +81,8 @@ ToolSidebar.prototype = {
"devtools/client/shared/components/tabs/tabbar"));
let sidebar = Tabbar({
toolbox: this._toolPanel._toolbox,
showAllTabsMenu: true,
onSelect: this.handleSelectionChange.bind(this),
});

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

@ -30,7 +30,7 @@ define(function (require, exports, module) {
if (this.props.objectLink) {
return this.props.objectLink({
object: grip
}, grip.class);
}, grip.class + " ");
}
return "";
},

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

@ -36,7 +36,7 @@ define(function (require, exports, module) {
return span({className: "objectBox"},
this.props.objectLink({
object: grip
}, grip.class)
}, grip.class + " ")
);
}
return "";

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

@ -30,7 +30,7 @@ define(function (require, exports, module) {
if (this.props.objectLink) {
return this.props.objectLink({
object: grip
}, "function");
}, "function ");
}
return "";
},

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

@ -38,7 +38,7 @@ define(function (require, exports, module) {
if (this.props.mode != "tiny") {
return objectLink({
object: object
}, object.class);
}, object.class + " ");
}
return "";
},

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

@ -34,7 +34,7 @@ define(function (require, exports, module) {
if (this.props.objectLink) {
return this.props.objectLink({
object: object
}, object.class);
}, object.class + " ");
}
return object.class || "Object";
},

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

@ -31,7 +31,7 @@ define(function (require, exports, module) {
return span({className: "objectBox"},
this.props.objectLink({
object: grip
}, this.getType(grip))
}, this.getType(grip) + " ")
);
}
return "";

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

@ -31,7 +31,7 @@ define(function (require, exports, module) {
return span({className: "objectBox"},
this.props.objectLink({
object: grip
}, this.getType(grip))
}, this.getType(grip) + " ")
);
}
return "";

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

@ -30,7 +30,7 @@ define(function (require, exports, module) {
if (this.props.objectLink) {
return this.props.objectLink({
object: object
}, object.class);
}, object.class + " ");
}
return "Object";
},

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

@ -72,6 +72,7 @@ define(function (require, exports, module) {
propTypes: {
object: React.PropTypes.any,
defaultRep: React.PropTypes.object,
mode: React.PropTypes.string
},
render: function () {

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

@ -32,7 +32,7 @@ define(function (require, exports, module) {
return DOM.span({className: "objectBox"},
this.props.objectLink({
object: grip
}, title)
}, title + " ")
);
}
return title;

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

@ -31,7 +31,7 @@ define(function (require, exports, module) {
return DOM.span({className: "objectBox"},
this.props.objectLink({
object: grip
}, grip.class)
}, grip.class + " ")
);
}
return "";

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

@ -34,8 +34,11 @@
}
/* The tab takes entire horizontal space and individual tabs
should stretch accordingly. Use flexbox for the behavior. */
should stretch accordingly. Use flexbox for the behavior.
Use also `overflow: hidden` so, 'overflow' and 'underflow'
events are fired (it's utilized by the all-tabs-menu). */
.tabs .tabs-navigation .tabs-menu {
overflow: hidden;
display: flex;
}

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

@ -9,6 +9,9 @@
const { DOM, createClass, PropTypes, createFactory } = require("devtools/client/shared/vendor/react");
const Tabs = createFactory(require("devtools/client/shared/components/tabs/tabs").Tabs);
const Menu = require("devtools/client/framework/menu");
const MenuItem = require("devtools/client/framework/menu-item");
// Shortcuts
const { div } = DOM;
@ -20,6 +23,14 @@ let Tabbar = createClass({
propTypes: {
onSelect: PropTypes.func,
showAllTabsMenu: PropTypes.bool,
toolbox: PropTypes.object,
},
getDefaultProps: function () {
return {
showAllTabsMenu: false,
};
},
getInitialState: function () {
@ -125,6 +136,33 @@ let Tabbar = createClass({
}
},
onAllTabsMenuClick: function (event) {
let menu = new Menu();
let target = event.target;
// Generate list of menu items from the list of tabs.
this.state.tabs.forEach(tab => {
menu.append(new MenuItem({
label: tab.title,
type: "checkbox",
checked: this.getCurrentTabId() == tab.id,
click: () => this.select(tab.id),
}));
});
// Show a drop down menu with frames.
// XXX Missing menu API for specifying target (anchor)
// and relative position to it. See also:
// https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/Method/openPopup
// https://bugzilla.mozilla.org/show_bug.cgi?id=1274551
let rect = target.getBoundingClientRect();
let screenX = target.ownerDocument.defaultView.mozInnerScreenX;
let screenY = target.ownerDocument.defaultView.mozInnerScreenY;
menu.popup(rect.left + screenX, rect.bottom + screenY, this.props.toolbox);
return menu;
},
// Rendering
renderTab: function (tab) {
@ -148,6 +186,8 @@ let Tabbar = createClass({
return (
div({className: "devtools-sidebar-tabs"},
Tabs({
onAllTabsMenuClick: this.onAllTabsMenuClick,
showAllTabsMenu: this.props.showAllTabsMenu,
tabActive: this.state.activeTab,
onAfterChange: this.onTabChanged},
tabs

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

@ -39,6 +39,27 @@
height: 100%;
}
.tabs .all-tabs-menu {
position: absolute;
top: 0;
right: 0;
width: 15px;
height: 100%;
border-style: solid;
border-width: 0;
border-inline-start-width: 1px;
border-color: var(--theme-splitter-color);
background: url("chrome://devtools/skin/images/dropmarker.svg");
background-repeat: no-repeat;
background-position: center;
background-color: var(--theme-tab-toolbar-background);
}
.tabs .all-tabs-menu:-moz-locale-dir(rtl) {
right: unset;
left: 0;
}
/* Light Theme */
.theme-dark .tabs,
@ -48,6 +69,7 @@
.theme-dark .tabs .tabs-navigation,
.theme-light .tabs .tabs-navigation {
position: relative;
border-bottom: 1px solid var(--theme-splitter-color);
background: var(--theme-tab-toolbar-background);
}

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

@ -47,12 +47,15 @@ define(function (require, exports, module) {
children: React.PropTypes.oneOfType([
React.PropTypes.array,
React.PropTypes.element
]).isRequired
]).isRequired,
showAllTabsMenu: React.PropTypes.bool,
onAllTabsMenuClick: React.PropTypes.func,
},
getDefaultProps: function () {
return {
tabActive: 0
tabActive: 0,
showAllTabsMenu: false,
};
},
@ -69,6 +72,9 @@ define(function (require, exports, module) {
// E.g. in case of an iframe being used as a tab-content
// we want the iframe to stay in the DOM.
created: [],
// True if tabs can't fit into available horizontal space.
overflow: false,
};
},
@ -76,6 +82,15 @@ define(function (require, exports, module) {
let node = findDOMNode(this);
node.addEventListener("keydown", this.onKeyDown, false);
// Register overflow listeners to manage visibility
// of all-tabs-menu. This menu is displayed when there
// is not enough h-space to render all tabs.
// It allows the user to select a tab even if it's hidden.
if (this.props.showAllTabsMenu) {
node.addEventListener("overflow", this.onOverflow, false);
node.addEventListener("underflow", this.onUnderflow, false);
}
let index = this.state.tabActive;
if (this.props.onMount) {
this.props.onMount(index);
@ -83,7 +98,9 @@ define(function (require, exports, module) {
},
componentWillReceiveProps: function (newProps) {
if (newProps.tabActive) {
// Check type of 'tabActive' props to see if it's valid
// (it's 0-based index).
if (typeof newProps.tabActive == "number") {
let created = [...this.state.created];
created[newProps.tabActive] = true;
@ -97,10 +114,31 @@ define(function (require, exports, module) {
componentWillUnmount: function () {
let node = findDOMNode(this);
node.removeEventListener("keydown", this.onKeyDown, false);
if (this.props.showAllTabsMenu) {
node.removeEventListener("overflow", this.onOverflow, false);
node.removeEventListener("underflow", this.onUnderflow, false);
}
},
// DOM Events
onOverflow: function (event) {
if (event.target.classList.contains("tabs-menu")) {
this.setState({
overflow: true
});
}
},
onUnderflow: function (event) {
if (event.target.classList.contains("tabs-menu")) {
this.setState({
overflow: false
});
}
},
onKeyDown: function (event) {
// Bail out if the focus isn't on a tab.
if (!event.target.closest(".tabs-menu-item")) {
@ -129,6 +167,12 @@ define(function (require, exports, module) {
event.preventDefault();
},
onAllTabsMenuClick: function (event) {
if (this.props.onAllTabsMenuClick) {
this.props.onAllTabsMenuClick(event);
}
},
// API
setActive: function (index) {
@ -218,11 +262,21 @@ define(function (require, exports, module) {
);
});
// Display the menu only if there is not enough horizontal
// space for all tabs (and overflow happened).
let allTabsMenu = this.state.overflow ? (
DOM.div({
className: "all-tabs-menu",
onClick: this.props.onAllTabsMenuClick
})
) : null;
return (
DOM.nav({className: "tabs-navigation"},
DOM.ul({className: "tabs-menu", role: "tablist"},
tabs
)
),
allTabsMenu
)
);
},

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

@ -29,6 +29,7 @@ support-files =
[test_sidebar_toggle.html]
[test_stack-trace.html]
[test_tabs_accessibility.html]
[test_tabs_menu.html]
[test_tree_01.html]
[test_tree_02.html]
[test_tree_03.html]

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

@ -51,7 +51,7 @@ window.onload = Task.async(function* () {
is(renderedRep.type, GripArray.rep, `Rep correctly selects ${GripArray.rep.displayName}`);
// Test rendering
const defaultOutput = `Array[]`;
const defaultOutput = `Array []`;
const modeTests = [
{
@ -79,7 +79,7 @@ window.onload = Task.async(function* () {
// Test array: `[1, "foo", {}]`;
const testName = "testMaxProps";
const defaultOutput = `Array[ 1, "foo", Object ]`;
const defaultOutput = `Array [ 1, "foo", Object ]`;
const modeTests = [
{
@ -107,7 +107,7 @@ window.onload = Task.async(function* () {
// Test array = `["test string"…] //4 items`
const testName = "testMoreThanShortMaxProps";
const defaultOutput = `Array[ ${Array(maxLength.short).fill("\"test string\"").join(", ")}, 1 more… ]`;
const defaultOutput = `Array [ ${Array(maxLength.short).fill("\"test string\"").join(", ")}, 1 more… ]`;
const modeTests = [
{
@ -124,7 +124,7 @@ window.onload = Task.async(function* () {
},
{
mode: "long",
expectedOutput: `Array[ ${Array(maxLength.short + 1).fill("\"test string\"").join(", ")} ]`,
expectedOutput: `Array [ ${Array(maxLength.short + 1).fill("\"test string\"").join(", ")} ]`,
}
];
@ -135,8 +135,8 @@ window.onload = Task.async(function* () {
// Test array = `["test string"…] //301 items`
const testName = "testMoreThanLongMaxProps";
const defaultShortOutput = `Array[ ${Array(maxLength.short).fill("\"test string\"").join(", ")}, ${maxLength.long + 1 - maxLength.short} more… ]`;
const defaultLongOutput = `Array[ ${Array(maxLength.long).fill("\"test string\"").join(", ")}, 1 more… ]`;
const defaultShortOutput = `Array [ ${Array(maxLength.short).fill("\"test string\"").join(", ")}, ${maxLength.long + 1 - maxLength.short} more… ]`;
const defaultLongOutput = `Array [ ${Array(maxLength.long).fill("\"test string\"").join(", ")}, 1 more… ]`;
const modeTests = [
{
@ -164,7 +164,7 @@ window.onload = Task.async(function* () {
// Test array = `let a = []; a = [a]`
const testName = "testRecursiveArray";
const defaultOutput = `Array[ [1] ]`;
const defaultOutput = `Array [ [1] ]`;
const modeTests = [
{
@ -191,8 +191,8 @@ window.onload = Task.async(function* () {
function testPreviewLimit() {
const testName = "testPreviewLimit";
const shortOutput = `Array[ 0, 1, 2, 8 more… ]`;
const defaultOutput = `Array[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1 more… ]`;
const shortOutput = `Array [ 0, 1, 2, 8 more… ]`;
const defaultOutput = `Array [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1 more… ]`;
const modeTests = [
{
@ -219,7 +219,7 @@ window.onload = Task.async(function* () {
function testNamedNodeMap() {
const testName = "testNamedNodeMap";
const defaultOutput = `NamedNodeMap[ class="myclass", cellpadding="7", border="3" ]`;
const defaultOutput = `NamedNodeMap [ class="myclass", cellpadding="7", border="3" ]`;
const modeTests = [
{

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

@ -0,0 +1,78 @@
<!DOCTYPE HTML>
<html class="theme-light">
<!--
Test all-tabs menu.
-->
<head>
<meta charset="utf-8">
<title>Tabs component All-tabs menu test</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
<link rel="stylesheet" type="text/css" href="resource://devtools/client/themes/variables.css">
<link rel="stylesheet" type="text/css" href="resource://devtools/client/themes/common.css">
<link rel="stylesheet" type="text/css" href="resource://devtools/client/themes/light-theme.css">
<link rel="stylesheet" type="text/css" href="resource://devtools/client/shared/components/tabs/tabs.css">
<link rel="stylesheet" type="text/css" href="resource://devtools/client/shared/components/tabs/tabbar.css">
<link rel="stylesheet" type="text/css" href="resource://devtools/client/inspector/components/side-panel.css">
<link rel="stylesheet" type="text/css" href="resource://devtools/client/inspector/components/inspector-tab-panel.css">
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
window.onload = Task.async(function* () {
try {
const ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
const React = browserRequire("devtools/client/shared/vendor/react");
const Tabbar = React.createFactory(browserRequire("devtools/client/shared/components/tabs/tabbar"));
// Create container for the TabBar. Set smaller width
// to ensure that tabs won't fit and the all-tabs menu
// needs to appear.
const tabBarBox = document.createElement("div");
tabBarBox.style.width = "200px";
tabBarBox.style.height = "200px";
tabBarBox.style.border = "1px solid lightgray";
document.body.appendChild(tabBarBox);
// Render the tab-bar.
const tabbar = Tabbar({
showAllTabsMenu: true,
});
const tabbarReact = ReactDOM.render(tabbar, tabBarBox);
// Test panel.
let TabPanel = React.createFactory(React.createClass({
render: function () {
return React.DOM.div({}, "content");
}
}));
// Create a few panels.
yield addTabWithPanel(1);
yield addTabWithPanel(2);
yield addTabWithPanel(3);
yield addTabWithPanel(4);
yield addTabWithPanel(5);
// Make sure the all-tabs menu is there.
const allTabsMenu = tabBarBox.querySelector(".all-tabs-menu");
ok(allTabsMenu, "All-tabs menu must be rendered");
function addTabWithPanel(tabId) {
return setState(tabbarReact, Object.assign({}, tabbarReact.state, {
tabs: tabbarReact.state.tabs.concat({id: `${tabId}`,
title: `tab-${tabId}`, panel: TabPanel}),
}));
}
} catch(e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
SimpleTest.finish();
}
});
</script>
</pre>
</body>
</html>

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

@ -118,44 +118,6 @@ Task.async(function* (type = "bottom", src = "data:text/html;charset=utf-8,") {
return [host, iframe.contentWindow, iframe.contentDocument];
});
/**
* Load the Telemetry utils, then stub Telemetry.prototype.log in order to
* record everything that's logged in it.
* Store all recordings on Telemetry.telemetryInfo.
* @return {Telemetry}
*/
function loadTelemetryAndRecordLogs() {
info("Mock the Telemetry log function to record logged information");
let Telemetry = require("devtools/client/shared/telemetry");
Telemetry.prototype.telemetryInfo = {};
Telemetry.prototype._oldlog = Telemetry.prototype.log;
Telemetry.prototype.log = function (histogramId, value) {
if (!this.telemetryInfo) {
// Can be removed when Bug 992911 lands (see Bug 1011652 Comment 10)
return;
}
if (histogramId) {
if (!this.telemetryInfo[histogramId]) {
this.telemetryInfo[histogramId] = [];
}
this.telemetryInfo[histogramId].push(value);
}
};
return Telemetry;
}
/**
* Stop recording the Telemetry logs and put back the utils as it was before.
*/
function stopRecordingTelemetryLogs(Telemetry) {
Telemetry.prototype.log = Telemetry.prototype._oldlog;
delete Telemetry.prototype._oldlog;
delete Telemetry.prototype.telemetryInfo;
}
/**
* Check the correctness of the data recorded in Telemetry after
* loadTelemetryAndRecordLogs was called.

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

@ -688,7 +688,7 @@ CSSFilterEditorWidget.prototype = {
this.filtersList.querySelector(".filter:last-of-type input");
if (lastInput) {
lastInput.focus();
if (lastInput.type == "text") {
if (lastInput.type === "text") {
// move cursor to end of input
const end = lastInput.value.length;
lastInput.setSelectionRange(end, end);

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

@ -367,6 +367,7 @@ tags = trackingprotection
[browser_webconsole_output_dom_elements_02.js]
skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug timeout)
[browser_webconsole_output_dom_elements_03.js]
skip-if = e10s # Bug 1241019
[browser_webconsole_output_dom_elements_04.js]
skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug timeout)
[browser_webconsole_output_dom_elements_05.js]

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

@ -97,7 +97,7 @@ var inputTests = [
{
input: "window.typedarray1",
output: "Int32Array [ 1, 287, 8651, 40983, 8754 ]",
printOutput: "[object Int32Array]",
printOutput: "1,287,8651,40983,8754",
inspectable: true,
variablesViewLabel: "Int32Array[5]",
},

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

@ -802,7 +802,7 @@ function InvalidCommandError() {
* or "Float32Array".
*/
function getConstructorName(obj) {
return obj.toString().match(/\[object ([^\[\]]*)\]\]?$/)[1];
return Object.prototype.toString.call(obj).match(/\[object ([^\[\]]*)\]\]?$/)[1];
}
/**

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

@ -39,14 +39,14 @@ public:
// This will call SwapElements on aArguments with an empty array.
nsJSScriptTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow,
Function& aFunction,
FallibleTArray<JS::Heap<JS::Value> >& aArguments,
nsTArray<JS::Heap<JS::Value>>&& aArguments,
ErrorResult& aError);
nsJSScriptTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow,
const nsAString& aExpression, bool* aAllowEval,
ErrorResult& aError);
nsJSScriptTimeoutHandler(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
Function& aFunction,
FallibleTArray<JS::Heap<JS::Value> >& aArguments);
nsTArray<JS::Heap<JS::Value>>&& aArguments);
nsJSScriptTimeoutHandler(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
const nsAString& aExpression);
@ -74,7 +74,7 @@ private:
~nsJSScriptTimeoutHandler();
void Init(JSContext* aCx,
FallibleTArray<JS::Heap<JS::Value>>& aArguments);
nsTArray<JS::Heap<JS::Value>>&& aArguments);
void Init(JSContext* aCx);
// filename, line number and JS language version string of the
@ -82,7 +82,7 @@ private:
nsCString mFileName;
uint32_t mLineNo;
uint32_t mColumn;
nsTArray<JS::Heap<JS::Value> > mArgs;
nsTArray<JS::Heap<JS::Value>> mArgs;
// The expression to evaluate or function to call. If mFunction is non-null
// it should be used, else use mExpr.
@ -209,7 +209,7 @@ nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler()
nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
nsGlobalWindow *aWindow,
Function& aFunction,
FallibleTArray<JS::Heap<JS::Value>>& aArguments,
nsTArray<JS::Heap<JS::Value>>&& aArguments,
ErrorResult& aError)
: mLineNo(0)
, mColumn(0)
@ -222,7 +222,7 @@ nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
return;
}
Init(aCx, aArguments);
Init(aCx, Move(aArguments));
}
nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
@ -252,7 +252,7 @@ nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
WorkerPrivate* aWorkerPrivate,
Function& aFunction,
FallibleTArray<JS::Heap<JS::Value>>& aArguments)
nsTArray<JS::Heap<JS::Value>>&& aArguments)
: mLineNo(0)
, mColumn(0)
, mFunction(&aFunction)
@ -260,7 +260,7 @@ nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
Init(aCx, aArguments);
Init(aCx, Move(aArguments));
}
nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
@ -283,10 +283,10 @@ nsJSScriptTimeoutHandler::~nsJSScriptTimeoutHandler()
void
nsJSScriptTimeoutHandler::Init(JSContext* aCx,
FallibleTArray<JS::Heap<JS::Value>>& aArguments)
nsTArray<JS::Heap<JS::Value>>&& aArguments)
{
mozilla::HoldJSObjects(this);
mArgs.SwapElements(aArguments);
mArgs = Move(aArguments);
Init(aCx);
}
@ -321,14 +321,14 @@ NS_CreateJSTimeoutHandler(JSContext *aCx, nsGlobalWindow *aWindow,
const Sequence<JS::Value>& aArguments,
ErrorResult& aError)
{
FallibleTArray<JS::Heap<JS::Value> > args;
nsTArray<JS::Heap<JS::Value>> args;
if (!args.AppendElements(aArguments, fallible)) {
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
RefPtr<nsJSScriptTimeoutHandler> handler =
new nsJSScriptTimeoutHandler(aCx, aWindow, aFunction, args, aError);
new nsJSScriptTimeoutHandler(aCx, aWindow, aFunction, Move(args), aError);
return aError.Failed() ? nullptr : handler.forget();
}
@ -352,14 +352,14 @@ NS_CreateJSTimeoutHandler(JSContext *aCx, WorkerPrivate* aWorkerPrivate,
const Sequence<JS::Value>& aArguments,
ErrorResult& aError)
{
FallibleTArray<JS::Heap<JS::Value>> args;
nsTArray<JS::Heap<JS::Value>> args;
if (!args.AppendElements(aArguments, fallible)) {
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
RefPtr<nsJSScriptTimeoutHandler> handler =
new nsJSScriptTimeoutHandler(aCx, aWorkerPrivate, aFunction, args);
new nsJSScriptTimeoutHandler(aCx, aWorkerPrivate, aFunction, Move(args));
return handler.forget();
}

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

@ -243,7 +243,7 @@ nsLocation::GetURI(nsIURI** aURI, bool aGetInnermostURI)
}
nsresult
nsLocation::GetWritableURI(nsIURI** aURI)
nsLocation::GetWritableURI(nsIURI** aURI, const nsACString* aNewRef)
{
*aURI = nullptr;
@ -254,7 +254,11 @@ nsLocation::GetWritableURI(nsIURI** aURI)
return rv;
}
return uri->Clone(aURI);
if (!aNewRef) {
return uri->Clone(aURI);
}
return uri->CloneWithNewRef(*aNewRef, aURI);
}
nsresult
@ -349,18 +353,13 @@ nsLocation::GetHash(nsAString& aHash)
NS_IMETHODIMP
nsLocation::SetHash(const nsAString& aHash)
{
nsCOMPtr<nsIURI> uri;
nsresult rv = GetWritableURI(getter_AddRefs(uri));
if (NS_FAILED(rv) || !uri) {
return rv;
}
NS_ConvertUTF16toUTF8 hash(aHash);
if (hash.IsEmpty() || hash.First() != char16_t('#')) {
hash.Insert(char16_t('#'), 0);
}
rv = uri->SetRef(hash);
if (NS_WARN_IF(NS_FAILED(rv))) {
nsCOMPtr<nsIURI> uri;
nsresult rv = GetWritableURI(getter_AddRefs(uri), &hash);
if (NS_FAILED(rv) || !uri) {
return rv;
}

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

@ -175,7 +175,9 @@ protected:
// fetched from as the URI instead of the jar: uri itself. Pass in
// true for aGetInnermostURI when that's the case.
nsresult GetURI(nsIURI** aURL, bool aGetInnermostURI = false);
nsresult GetWritableURI(nsIURI** aURL);
nsresult GetWritableURI(nsIURI** aURL,
// If not null, give it the new ref
const nsACString* aNewRef = nullptr);
nsresult SetURI(nsIURI* aURL, bool aReplace = false);
nsresult SetHrefWithBase(const nsAString& aHref, nsIURI* aBase,
bool aReplace);

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

@ -5006,6 +5006,15 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
# create an empty array, which is all we need here.
default = CGGeneric("%s.RawSetAs%s();\n" %
(value, name))
elif defaultValue.type.isEnum():
name = getUnionMemberName(defaultValue.type)
# Make sure we actually construct the thing inside the nullable.
value = declLoc + (".SetValue()" if nullable else "")
default = CGGeneric(
"%s.RawSetAs%s() = %s::%s;\n" %
(value, name,
defaultValue.type.inner.identifier.name,
getEnumValueName(defaultValue.value)))
else:
default = CGGeneric(
handleDefaultStringValue(

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

@ -3309,6 +3309,11 @@ def matchIntegerValueToType(value):
return None
class NoCoercionFoundError(WebIDLError):
"""
A class we use to indicate generic coercion failures because none of the
types worked out in IDLValue.coerceToType.
"""
class IDLValue(IDLObject):
def __init__(self, location, type, value):
@ -3336,8 +3341,18 @@ class IDLValue(IDLObject):
# use the value's type when it is a default value of a
# union, and the union cares about the exact float type.
return IDLValue(self.location, subtype, coercedValue.value)
except:
pass
except Exception as e:
# Make sure to propagate out WebIDLErrors that are not the
# generic "hey, we could not coerce to this type at all"
# exception, because those are specific "coercion failed for
# reason X" exceptions. Note that we want to swallow
# non-WebIDLErrors here, because those can just happen if
# "type" is not something that can have a default value at
# all.
if (isinstance(e, WebIDLError) and
not isinstance(e, NoCoercionFoundError)):
raise e
# If the type allows null, rerun this matching on the inner type, except
# nullable enums. We handle those specially, because we want our
# default string values to stay strings even when assigned to a nullable
@ -3399,8 +3414,8 @@ class IDLValue(IDLObject):
return IDLValue(self.location, type, self.value)
raise WebIDLError("Cannot coerce type %s to type %s." %
(self.type, type), [location])
raise NoCoercionFoundError("Cannot coerce type %s to type %s." %
(self.type, type), [location])
def _getDependentObjects(self):
return set()

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

@ -673,7 +673,7 @@ public:
//void PassUnionWithInterfacesAndNullable(const TestInterfaceOrNullOrTestExternalInterface& arg);
void PassUnionWithArrayBuffer(const ArrayBufferOrLong&);
void PassUnionWithString(JSContext*, const StringOrObject&);
//void PassUnionWithEnum(JSContext*, const TestEnumOrObject&);
void PassUnionWithEnum(JSContext*, const SupportedTypeOrObject&);
//void PassUnionWithCallback(JSContext*, const TestCallbackOrLong&);
void PassUnionWithObject(JSContext*, const ObjectOrLong&);
@ -693,6 +693,9 @@ public:
void PassUnionWithDefaultValue14(const DoubleOrByteString& arg);
void PassUnionWithDefaultValue15(const DoubleOrByteString& arg);
void PassUnionWithDefaultValue16(const DoubleOrByteString& arg);
void PassUnionWithDefaultValue17(const DoubleOrSupportedType& arg);
void PassUnionWithDefaultValue18(const DoubleOrSupportedType& arg);
void PassUnionWithDefaultValue19(const DoubleOrSupportedType& arg);
void PassNullableUnionWithDefaultValue1(const Nullable<DoubleOrString>& arg);
void PassNullableUnionWithDefaultValue2(const Nullable<DoubleOrString>& arg);
@ -710,6 +713,10 @@ public:
void PassNullableUnionWithDefaultValue14(const Nullable<DoubleOrByteString>& arg);
void PassNullableUnionWithDefaultValue15(const Nullable<DoubleOrByteString>& arg);
void PassNullableUnionWithDefaultValue16(const Nullable<DoubleOrByteString>& arg);
void PassNullableUnionWithDefaultValue17(const Nullable<DoubleOrSupportedType>& arg);
void PassNullableUnionWithDefaultValue18(const Nullable<DoubleOrSupportedType>& arg);
void PassNullableUnionWithDefaultValue19(const Nullable<DoubleOrSupportedType>& arg);
void PassNullableUnionWithDefaultValue20(const Nullable<DoubleOrSupportedType>& arg);
void PassSequenceOfUnions(const Sequence<OwningCanvasPatternOrCanvasGradient>&);
void PassSequenceOfUnions2(JSContext*, const Sequence<OwningObjectOrLong>&);

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

@ -644,7 +644,12 @@ interface TestInterface {
//void passUnionWithSequence((sequence<object> or long) arg);
void passUnionWithArrayBuffer((ArrayBuffer or long) arg);
void passUnionWithString((DOMString or object) arg);
//void passUnionWithEnum((TestEnum or object) arg);
// Using an enum in a union. Note that we use some enum not declared in our
// binding file, because UnionTypes.h will need to include the binding header
// for this enum. Pick an enum from an interface that won't drag in too much
// stuff.
void passUnionWithEnum((SupportedType or object) arg);
// Trying to use a callback in a union won't include the test
// headers, unfortunately, so won't compile.
//void passUnionWithCallback((TestCallback or long) arg);
@ -667,6 +672,9 @@ interface TestInterface {
void passUnionWithDefaultValue14(optional (double or ByteString) arg = "");
void passUnionWithDefaultValue15(optional (double or ByteString) arg = 1);
void passUnionWithDefaultValue16(optional (double or ByteString) arg = 1.5);
void passUnionWithDefaultValue17(optional (double or SupportedType) arg = "text/html");
void passUnionWithDefaultValue18(optional (double or SupportedType) arg = 1);
void passUnionWithDefaultValue19(optional (double or SupportedType) arg = 1.5);
void passNullableUnionWithDefaultValue1(optional (double or DOMString)? arg = "");
void passNullableUnionWithDefaultValue2(optional (double or DOMString)? arg = 1);
@ -684,6 +692,10 @@ interface TestInterface {
void passNullableUnionWithDefaultValue14(optional (double or ByteString)? arg = 1);
void passNullableUnionWithDefaultValue15(optional (double or ByteString)? arg = 1.5);
void passNullableUnionWithDefaultValue16(optional (double or ByteString)? arg = null);
void passNullableUnionWithDefaultValue17(optional (double or SupportedType)? arg = "text/html");
void passNullableUnionWithDefaultValue18(optional (double or SupportedType)? arg = 1);
void passNullableUnionWithDefaultValue19(optional (double or SupportedType)? arg = 1.5);
void passNullableUnionWithDefaultValue20(optional (double or SupportedType)? arg = null);
void passSequenceOfUnions(sequence<(CanvasPattern or CanvasGradient)> arg);
void passSequenceOfUnions2(sequence<(object or long)> arg);

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

@ -479,7 +479,12 @@ interface TestExampleInterface {
//void passUnionWithSequence((sequence<object> or long) arg);
void passUnionWithArrayBuffer((ArrayBuffer or long) arg);
void passUnionWithString((DOMString or object) arg);
//void passUnionWithEnum((TestEnum or object) arg);
// Using an enum in a union. Note that we use some enum not declared in our
// binding file, because UnionTypes.h will need to include the binding header
// for this enum. Pick an enum from an interface that won't drag in too much
// stuff.
void passUnionWithEnum((SupportedType or object) arg);
// Trying to use a callback in a union won't include the test
// headers, unfortunately, so won't compile.
// void passUnionWithCallback((TestCallback or long) arg);
@ -502,6 +507,9 @@ interface TestExampleInterface {
void passUnionWithDefaultValue14(optional (double or ByteString) arg = "");
void passUnionWithDefaultValue15(optional (double or ByteString) arg = 1);
void passUnionWithDefaultValue16(optional (double or ByteString) arg = 1.5);
void passUnionWithDefaultValue17(optional (double or SupportedType) arg = "text/html");
void passUnionWithDefaultValue18(optional (double or SupportedType) arg = 1);
void passUnionWithDefaultValue19(optional (double or SupportedType) arg = 1.5);
void passNullableUnionWithDefaultValue1(optional (double or DOMString)? arg = "");
void passNullableUnionWithDefaultValue2(optional (double or DOMString)? arg = 1);
@ -519,6 +527,10 @@ interface TestExampleInterface {
void passNullableUnionWithDefaultValue14(optional (double or ByteString)? arg = 1);
void passNullableUnionWithDefaultValue15(optional (double or ByteString)? arg = 1.5);
void passNullableUnionWithDefaultValue16(optional (double or ByteString)? arg = null);
void passNullableUnionWithDefaultValue17(optional (double or SupportedType)? arg = "text/html");
void passNullableUnionWithDefaultValue18(optional (double or SupportedType)? arg = 1);
void passNullableUnionWithDefaultValue19(optional (double or SupportedType)? arg = 1.5);
void passNullableUnionWithDefaultValue20(optional (double or SupportedType)? arg = null);
void passSequenceOfUnions(sequence<(CanvasPattern or CanvasGradient)> arg);
void passSequenceOfUnions2(sequence<(object or long)> arg);

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

@ -491,7 +491,12 @@ interface TestJSImplInterface {
//void passUnionWithSequence((sequence<object> or long) arg);
void passUnionWithArrayBuffer((ArrayBuffer or long) arg);
void passUnionWithString((DOMString or object) arg);
//void passUnionWithEnum((MyTestEnum or object) arg);
// Using an enum in a union. Note that we use some enum not declared in our
// binding file, because UnionTypes.h will need to include the binding header
// for this enum. Pick an enum from an interface that won't drag in too much
// stuff.
void passUnionWithEnum((SupportedType or object) arg);
// Trying to use a callback in a union won't include the test
// headers, unfortunately, so won't compile.
// void passUnionWithCallback((MyTestCallback or long) arg);
@ -514,6 +519,9 @@ interface TestJSImplInterface {
void passUnionWithDefaultValue14(optional (double or ByteString) arg = "");
void passUnionWithDefaultValue15(optional (double or ByteString) arg = 1);
void passUnionWithDefaultValue16(optional (double or ByteString) arg = 1.5);
void passUnionWithDefaultValue17(optional (double or SupportedType) arg = "text/html");
void passUnionWithDefaultValue18(optional (double or SupportedType) arg = 1);
void passUnionWithDefaultValue19(optional (double or SupportedType) arg = 1.5);
void passNullableUnionWithDefaultValue1(optional (double or DOMString)? arg = "");
void passNullableUnionWithDefaultValue2(optional (double or DOMString)? arg = 1);
@ -531,6 +539,10 @@ interface TestJSImplInterface {
void passNullableUnionWithDefaultValue14(optional (double or ByteString)? arg = 1);
void passNullableUnionWithDefaultValue15(optional (double or ByteString)? arg = 1.5);
void passNullableUnionWithDefaultValue16(optional (double or ByteString)? arg = null);
void passNullableUnionWithDefaultValue17(optional (double or SupportedType)? arg = "text/html");
void passNullableUnionWithDefaultValue18(optional (double or SupportedType)? arg = 1);
void passNullableUnionWithDefaultValue19(optional (double or SupportedType)? arg = 1.5);
void passNullableUnionWithDefaultValue20(optional (double or SupportedType)? arg = null);
void passSequenceOfUnions(sequence<(CanvasPattern or CanvasGradient)> arg);
void passSequenceOfUnions2(sequence<(object or long)> arg);

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

@ -2477,7 +2477,18 @@ ContentChild::RecvActivateA11y()
#ifdef ACCESSIBILITY
// Start accessibility in content process if it's running in chrome
// process.
GetOrCreateAccService();
GetOrCreateAccService(nsAccessibilityService::eMainProcess);
#endif
return true;
}
bool
ContentChild::RecvShutdownA11y()
{
#ifdef ACCESSIBILITY
// Try to shutdown accessibility in content process if it's shutting down in
// chrome process.
MaybeShutdownAccService(nsAccessibilityService::eMainProcess);
#endif
return true;
}

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

@ -440,6 +440,7 @@ public:
virtual bool RecvFlushMemory(const nsString& reason) override;
virtual bool RecvActivateA11y() override;
virtual bool RecvShutdownA11y() override;
virtual bool RecvGarbageCollect() override;
virtual bool RecvCycleCollect() override;

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

@ -275,6 +275,10 @@ using namespace mozilla::system;
#include "nsThread.h"
#endif
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"
#endif
// For VP9Benchmark::sBenchmarkFpsPref
#include "Benchmark.h"
@ -2843,19 +2847,24 @@ ContentParent::Observe(nsISupports* aSubject,
}
#endif
#ifdef ACCESSIBILITY
// Make sure accessibility is running in content process when accessibility
// gets initiated in chrome process.
else if (aData && (*aData == '1') &&
!strcmp(aTopic, "a11y-init-or-shutdown")) {
else if (aData && !strcmp(aTopic, "a11y-init-or-shutdown")) {
if (*aData == '1') {
// Make sure accessibility is running in content process when
// accessibility gets initiated in chrome process.
#if !defined(XP_WIN)
Unused << SendActivateA11y();
#else
// On Windows we currently only enable a11y in the content process
// for testing purposes.
if (Preferences::GetBool(kForceEnableE10sPref, false)) {
Unused << SendActivateA11y();
}
#else
// On Windows we currently only enable a11y in the content process
// for testing purposes.
if (Preferences::GetBool(kForceEnableE10sPref, false)) {
Unused << SendActivateA11y();
}
#endif
} else {
// If possible, shut down accessibility in content process when
// accessibility gets shutdown in chrome process.
Unused << SendShutdownA11y();
}
}
#endif
else if (!strcmp(aTopic, "app-theme-changed")) {

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

@ -550,6 +550,11 @@ child:
*/
async ActivateA11y();
/**
* Shutdown accessibility engine in content process (if not in use).
*/
async ShutdownA11y();
async AppInfo(nsCString version, nsCString buildID, nsCString name, nsCString UAName,
nsCString ID, nsCString vendor);
async AppInit();

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

@ -347,6 +347,9 @@ function* test_basics() {
serverQueue = connectedResult.queue;
// -- Attempt to send non-string data.
// Restore the original behavior by replacing toString with
// Object.prototype.toString. (bug 1121938)
bigUint8Array.toString = Object.prototype.toString;
is(clientSocket.send(bigUint8Array), true,
'Client sending a large non-string should only send a small string.');
clientSocket.close();

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

@ -360,8 +360,12 @@ void nsPluginTag::InitMime(const char* const* aMimeTypes,
mSupportsAsyncInit = true;
break;
case nsPluginHost::eSpecialType_Flash:
mIsFlashPlugin = true;
mSupportsAsyncInit = true;
// VLC sometimes claims to implement the Flash MIME type, and we want
// to allow users to control that separately from Adobe Flash.
if (Name().EqualsLiteral("Shockwave Flash")) {
mIsFlashPlugin = true;
mSupportsAsyncInit = true;
}
break;
case nsPluginHost::eSpecialType_Silverlight:
case nsPluginHost::eSpecialType_Unity:

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

@ -10,7 +10,7 @@
"use strict";
SimpleTest.waitForExplicitFinish();
ok(SpecialPowers.setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED, "Flash Test Plug-in"), "Should find allowed test flash plugin");
ok(SpecialPowers.setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED, "Shockwave Flash"), "Should find allowed test flash plugin");
ok(SpecialPowers.setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED, "Silverlight Test Plug-in"), "Should find allowed test silverlight plugin");
ok(!SpecialPowers.setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED, "Third Test Plug-in"), "Should not find disallowed plugin");
@ -56,11 +56,11 @@
pluginElement = document.getElementById("disallowedPlugin");
is(typeof pluginElement.identifierToStringTest, "undefined", "Should NOT be able to call a function on a disallowed plugin");
ok(navigator.plugins["Flash Test Plug-in"], "Should have queried a plugin named 'Flash Test Plug-in'");
ok(navigator.plugins["Shockwave Flash"], "Should have queried a plugin named 'Shockwave Flash'");
ok(navigator.plugins["Silverlight Test Plug-in"], "Should have queried a plugin named 'Silverlight Test Plug-in'");
ok(!navigator.plugins["Third Test Plug-in"], "Should NOT have queried a disallowed plugin named 'Third Test Plug-in'");
ok(findPlugin("Flash Test Plug-in"), "Should have found a plugin named 'Flash Test Plug-in'");
ok(findPlugin("Shockwave Flash"), "Should have found a plugin named 'Shockwave Flash'");
ok(findPlugin("Silverlight Test Plug-in"), "Should have found a plugin named 'Silverlight Test Plug-in'");
ok(!findPlugin("Third Test Plug-in"), "Should NOT found a disallowed plugin named 'Third Test Plug-in'");

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

@ -19,7 +19,7 @@
<key>CFBundleVersion</key>
<string>1.0.0.0</string>
<key>WebPluginName</key>
<string>Flash Test Plug-in</string>
<string>Shockwave Flash</string>
<key>WebPluginDescription</key>
<string>Flash plug-in for testing purposes.</string>
<key>WebPluginMIMETypes</key>

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

@ -31,7 +31,7 @@ BEGIN
VALUE "InternalName", "npswftest"
VALUE "MIMEType", "application/x-shockwave-flash-test"
VALUE "OriginalFilename", "npswftest.dll"
VALUE "ProductName", "Flash Test Plug-in"
VALUE "ProductName", "Shockwave Flash"
VALUE "ProductVersion", "1.0"
END
END

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

@ -2,6 +2,6 @@
* 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/. */
const char *sPluginName = "Flash Test Plug-in";
const char *sPluginName = "Shockwave Flash";
const char *sPluginDescription = "Flash plug-in for testing purposes.";
const char *sMimeDescription = "application/x-shockwave-flash-test:swf:Flash test type";

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

@ -45,13 +45,19 @@ function resolvePromise() {
}
onmessage = function(event) {
// FIXME(catalinb): we cannot treat these events as extendable
// yet. Bug 1143717
event.source.postMessage({type: "message", state: state});
var lastState = state;
state = event.data;
if (event.data === "release") {
if (state === 'wait') {
event.waitUntil(new Promise(function(res, rej) {
if (resolvePromiseCallback) {
dump("ERROR: service worker was already waiting on a promise.\n");
}
resolvePromiseCallback = res;
}));
} else if (state === 'release') {
resolvePromise();
}
event.source.postMessage({type: "message", state: lastState});
}
onpush = function(event) {

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

@ -253,11 +253,17 @@
.then(cancelShutdownObserver)
// Test with push events and message events
.then(setShutdownObserver(true))
.then(createIframe)
// Make sure we are shutdown before entering our "no shutdown" sequence
// to avoid races.
.then(waitOnShutdownObserver)
.then(setShutdownObserver(false))
.then(checkStateAndUpdate(pushEvent, "from_scope", "wait"))
.then(checkStateAndUpdate(messageEventIframe, "wait", "update"))
.then(checkStateAndUpdate(messageEventIframe, "update", "update"))
.then(setShutdownObserver(true))
.then(checkStateAndUpdate(messageEventIframe, "wait", "release"))
.then(checkStateAndUpdate(messageEventIframe, "update", "release"))
.then(waitOnShutdownObserver)
.then(closeIframe)
}
@ -272,8 +278,12 @@
// Older versions used to terminate workers when the last controlled
// window was closed. This should no longer happen, though. Verify
// the new behavior.
setShutdownObserver(true)(ctx);
return createIframe(ctx)
.then(setShutdownObserver(true))
// Make sure we are shutdown before entering our "no shutdown" sequence
// to avoid races.
.then(waitOnShutdownObserver)
.then(setShutdownObserver(false))
.then(checkStateAndUpdate(fetchEvent, "from_scope", "wait"))
.then(closeIframe)
.then(setShutdownObserver(true))
@ -282,7 +292,11 @@
// Push workers were exempt from the old rule and should continue to
// survive past the closing of the last controlled window.
.then(setShutdownObserver(true))
.then(createIframe)
// Make sure we are shutdown before entering our "no shutdown" sequence
// to avoid races.
.then(waitOnShutdownObserver)
.then(setShutdownObserver(false))
.then(checkStateAndUpdate(pushEvent, "from_scope", "wait"))
.then(closeIframe)

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

@ -115,7 +115,7 @@ gfxContext::~gfxContext()
{
for (int i = mStateStack.Length() - 1; i >= 0; i--) {
for (unsigned int c = 0; c < mStateStack[i].pushedClips.Length(); c++) {
mDT->PopClip();
mStateStack[i].drawTarget->PopClip();
}
}
mDT->Flush();

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

@ -1319,7 +1319,7 @@ DecodeElemSection(Decoder& d, bool newFormat, Uint32Vector&& oldElems, ModuleGen
return true;
}
return mg.addElemSegment(ElemSegment(0, InitExpr(Val(uint32_t(0))), Move(oldElems)));
return mg.addElemSegment(InitExpr(Val(uint32_t(0))), Move(oldElems));
}
uint32_t sectionStart, sectionSize;
@ -1336,44 +1336,47 @@ DecodeElemSection(Decoder& d, bool newFormat, Uint32Vector&& oldElems, ModuleGen
return Fail(d, "too many elem segments");
for (uint32_t i = 0, prevEnd = 0; i < numSegments; i++) {
ElemSegment seg;
if (!d.readVarU32(&seg.tableIndex))
uint32_t tableIndex;
if (!d.readVarU32(&tableIndex))
return Fail(d, "expected table index");
if (seg.tableIndex >= mg.tables().length())
MOZ_ASSERT(mg.tables().length() <= 1);
if (tableIndex >= mg.tables().length())
return Fail(d, "table index out of range");
if (!DecodeInitializerExpression(d, mg.globals(), ValType::I32, &seg.offset))
InitExpr offset;
if (!DecodeInitializerExpression(d, mg.globals(), ValType::I32, &offset))
return false;
if (seg.offset.isVal() && seg.offset.val().i32() < prevEnd)
if (offset.isVal() && offset.val().i32() < prevEnd)
return Fail(d, "elem segments must be disjoint and ordered");
uint32_t numElems;
if (!d.readVarU32(&numElems))
return Fail(d, "expected segment size");
uint32_t tableLength = mg.tables()[seg.tableIndex].initial;
if (seg.offset.isVal()) {
uint32_t offset = seg.offset.val().i32();
if (offset > tableLength || tableLength - offset < numElems)
uint32_t tableLength = mg.tables()[tableIndex].initial;
if (offset.isVal()) {
uint32_t off = offset.val().i32();
if (off > tableLength || tableLength - off < numElems)
return Fail(d, "element segment does not fit");
}
if (!seg.elems.resize(numElems))
Uint32Vector elemFuncIndices;
if (!elemFuncIndices.resize(numElems))
return false;
for (uint32_t i = 0; i < numElems; i++) {
if (!d.readVarU32(&seg.elems[i]))
if (!d.readVarU32(&elemFuncIndices[i]))
return Fail(d, "failed to read element function index");
if (seg.elems[i] >= mg.numFuncSigs())
if (elemFuncIndices[i] >= mg.numFuncSigs())
return Fail(d, "table element out of range");
}
if (seg.offset.isVal())
prevEnd = seg.offset.val().i32() + seg.elems.length();
if (offset.isVal())
prevEnd = offset.val().i32() + elemFuncIndices.length();
if (!mg.addElemSegment(Move(seg)))
if (!mg.addElemSegment(offset, Move(elemFuncIndices)))
return false;
}

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

@ -901,18 +901,26 @@ ModuleGenerator::finishFuncDefs()
}
bool
ModuleGenerator::addElemSegment(ElemSegment&& seg)
ModuleGenerator::addElemSegment(InitExpr offset, Uint32Vector&& elemFuncIndices)
{
MOZ_ASSERT(!isAsmJS());
MOZ_ASSERT(finishedFuncDefs_);
MOZ_ASSERT(shared_->tables.length() == 1);
if (shared_->tables[0].external) {
for (uint32_t funcIndex : seg.elems) {
for (uint32_t funcIndex : elemFuncIndices) {
if (!exportedFuncs_.put(funcIndex))
return false;
}
}
return elemSegments_.append(Move(seg));
Uint32Vector codeRangeIndices;
if (!codeRangeIndices.resize(elemFuncIndices.length()))
return false;
for (size_t i = 0; i < elemFuncIndices.length(); i++)
codeRangeIndices[i] = funcIndexToCodeRange_[elemFuncIndices[i]];
return elemSegments_.emplaceBack(0, offset, Move(elemFuncIndices), Move(codeRangeIndices));
}
void
@ -945,11 +953,19 @@ bool
ModuleGenerator::initSigTableElems(uint32_t sigIndex, Uint32Vector&& elemFuncIndices)
{
MOZ_ASSERT(isAsmJS());
MOZ_ASSERT(finishedFuncDefs_);
uint32_t tableIndex = shared_->asmJSSigToTableIndex[sigIndex];
MOZ_ASSERT(shared_->tables[tableIndex].initial == elemFuncIndices.length());
return elemSegments_.emplaceBack(tableIndex, InitExpr(Val(uint32_t(0))), Move(elemFuncIndices));
Uint32Vector codeRangeIndices;
if (!codeRangeIndices.resize(elemFuncIndices.length()))
return false;
for (size_t i = 0; i < elemFuncIndices.length(); i++)
codeRangeIndices[i] = funcIndexToCodeRange_[elemFuncIndices[i]];
InitExpr offset(Val(uint32_t(0)));
return elemSegments_.emplaceBack(tableIndex, offset, Move(elemFuncIndices), Move(codeRangeIndices));
}
SharedModule
@ -1023,16 +1039,6 @@ ModuleGenerator::finish(const ShareableBytes& bytecode)
}
#endif
// Convert function indices to offsets into the code section.
// WebAssembly's tables are (currently) all untyped and point to the table
// entry. asm.js tables are all typed and thus point to the normal entry.
for (ElemSegment& seg : elemSegments_) {
for (uint32_t& elem : seg.elems) {
const CodeRange& cr = funcCodeRange(elem);
elem = isAsmJS() ? cr.funcNonProfilingEntry() : cr.funcTableEntry();
}
}
if (!finishLinkData(code))
return nullptr;

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

@ -184,7 +184,7 @@ class MOZ_STACK_CLASS ModuleGenerator
// Segments:
MOZ_MUST_USE bool addDataSegment(DataSegment s) { return dataSegments_.append(s); }
MOZ_MUST_USE bool addElemSegment(ElemSegment&& s);
MOZ_MUST_USE bool addElemSegment(InitExpr offset, Uint32Vector&& elemFuncIndices);
// Function names:
void setFuncNames(NameInBytecodeVector&& funcNames);

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

@ -269,7 +269,8 @@ ElemSegment::serializedSize() const
{
return sizeof(tableIndex) +
sizeof(offset) +
SerializedPodVectorSize(elems);
SerializedPodVectorSize(elemFuncIndices) +
SerializedPodVectorSize(elemCodeRangeIndices);
}
uint8_t*
@ -277,7 +278,8 @@ ElemSegment::serialize(uint8_t* cursor) const
{
cursor = WriteBytes(cursor, &tableIndex, sizeof(tableIndex));
cursor = WriteBytes(cursor, &offset, sizeof(offset));
cursor = SerializePodVector(cursor, elems);
cursor = SerializePodVector(cursor, elemFuncIndices);
cursor = SerializePodVector(cursor, elemCodeRangeIndices);
return cursor;
}
@ -286,14 +288,16 @@ ElemSegment::deserialize(const uint8_t* cursor)
{
(cursor = ReadBytes(cursor, &tableIndex, sizeof(tableIndex))) &&
(cursor = ReadBytes(cursor, &offset, sizeof(offset))) &&
(cursor = DeserializePodVector(cursor, &elems));
(cursor = DeserializePodVector(cursor, &elemFuncIndices)) &&
(cursor = DeserializePodVector(cursor, &elemCodeRangeIndices));
return cursor;
}
size_t
ElemSegment::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const
{
return elems.sizeOfExcludingThis(mallocSizeOf);
return elemFuncIndices.sizeOfExcludingThis(mallocSizeOf) +
elemCodeRangeIndices.sizeOfExcludingThis(mallocSizeOf);
}
size_t
@ -451,26 +455,26 @@ Module::initElems(JSContext* cx, HandleWasmInstanceObject instanceObj,
}
uint32_t tableLength = instance.metadata().tables[seg.tableIndex].initial;
if (offset > tableLength || tableLength - offset < seg.elems.length()) {
if (offset > tableLength || tableLength - offset < seg.elemCodeRangeIndices.length()) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_FAIL,
"element segment does not fit");
return false;
}
// If profiling is already enabled in the wasm::Compartment, the new
// instance must use the profiling entry for typed functions instead of
// the default nonProfilingEntry.
bool useProfilingEntry = instance.code().profilingEnabled() && table.isTypedFunction();
bool profilingEnabled = instance.code().profilingEnabled();
const CodeRangeVector& codeRanges = instance.code().metadata().codeRanges;
uint8_t* codeBase = instance.codeBase();
for (uint32_t i = 0; i < seg.elems.length(); i++) {
void* code = codeBase + seg.elems[i];
if (useProfilingEntry)
code = codeBase + instance.code().lookupRange(code)->funcProfilingEntry();
table.set(offset + i, code, instance);
for (uint32_t i = 0; i < seg.elemCodeRangeIndices.length(); i++) {
const CodeRange& cr = codeRanges[seg.elemCodeRangeIndices[i]];
uint32_t codeOffset = table.isTypedFunction()
? profilingEnabled
? cr.funcProfilingEntry()
: cr.funcNonProfilingEntry()
: cr.funcTableEntry();
table.set(offset + i, codeBase + codeOffset, instance);
}
prevEnd = offset + seg.elems.length();
prevEnd = offset + seg.elemFuncIndices.length();
}
return true;

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

@ -156,19 +156,28 @@ struct DataSegment
typedef Vector<DataSegment, 0, SystemAllocPolicy> DataSegmentVector;
// ElemSegment represents an element segment in the module where each element's
// function index has been translated to its offset in the code section.
// ElemSegment represents an element segment in the module where each element
// describes both its function index and its code range.
struct ElemSegment
{
MOZ_INIT_OUTSIDE_CTOR uint32_t tableIndex;
MOZ_INIT_OUTSIDE_CTOR InitExpr offset;
MOZ_INIT_OUTSIDE_CTOR Uint32Vector elems;
uint32_t tableIndex;
InitExpr offset;
Uint32Vector elemFuncIndices;
Uint32Vector elemCodeRangeIndices;
ElemSegment() = default;
ElemSegment(uint32_t tableIndex, InitExpr offset, Uint32Vector&& elems)
: tableIndex(tableIndex), offset(offset), elems(Move(elems))
{}
ElemSegment(uint32_t tableIndex,
InitExpr offset,
Uint32Vector&& elemFuncIndices,
Uint32Vector&& elemCodeRangeIndices)
: tableIndex(tableIndex),
offset(offset),
elemFuncIndices(Move(elemFuncIndices)),
elemCodeRangeIndices(Move(elemCodeRangeIndices))
{
MOZ_ASSERT(elemFuncIndices.length() == elemCodeRangeIndices.length());
}
WASM_DECLARE_SERIALIZABLE(ElemSegment)
};

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

@ -29,7 +29,7 @@ function IsDetachedBuffer(buffer) {
// optimization in place there to avoid incurring the cost here. An
// alternative is to give SharedArrayBuffer the same layout as ArrayBuffer.
if (IsSharedArrayBuffer(buffer))
return false;
return false;
var flags = UnsafeGetInt32FromReservedSlot(buffer, JS_ARRAYBUFFER_FLAGS_SLOT);
return (flags & JS_ARRAYBUFFER_DETACHED_FLAG) !== 0;
@ -171,11 +171,10 @@ function TypedArrayEvery(callbackfn, thisArg = undefined) {
// Steps 3-5.
var len;
if (isTypedArray) {
if (isTypedArray)
len = TypedArrayLength(O);
} else {
else
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
}
// Step 6.
if (arguments.length === 0)
@ -260,11 +259,10 @@ function TypedArrayFilter(callbackfn, thisArg = undefined) {
// Step 4.
var len;
if (isTypedArray) {
if (isTypedArray)
len = TypedArrayLength(O);
} else {
else
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
}
// Step 5.
if (arguments.length === 0)
@ -329,11 +327,10 @@ function TypedArrayFind(predicate, thisArg = undefined) {
// Steps 3-5.
var len;
if (isTypedArray) {
if (isTypedArray)
len = TypedArrayLength(O);
} else {
else
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
}
// Step 6.
if (arguments.length === 0)
@ -372,11 +369,10 @@ function TypedArrayFindIndex(predicate, thisArg = undefined) {
// Steps 3-5.
var len;
if (isTypedArray) {
if (isTypedArray)
len = TypedArrayLength(O);
} else {
else
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
}
// Step 6.
if (arguments.length === 0)
@ -413,11 +409,10 @@ function TypedArrayForEach(callbackfn, thisArg = undefined) {
// Step 3-4.
var len;
if (isTypedArray) {
if (isTypedArray)
len = TypedArrayLength(O);
} else {
else
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
}
// Step 5.
if (arguments.length === 0)
@ -518,7 +513,7 @@ function TypedArrayJoin(separator) {
var element0 = O[0];
// Steps 10-11.
// Omit the 'if' clause in step 10, since typed arrays can not have undefined or null elements.
// Omit the 'if' clause in step 10, since typed arrays can't have undefined or null elements.
var R = ToString(element0);
// Steps 12-13.
@ -530,7 +525,7 @@ function TypedArrayJoin(separator) {
var element = O[k];
// Steps 13.c-13.d.
// Omit the 'if' clause in step 13.c, since typed arrays can not have undefined or null elements.
// Omit the 'if' clause in step 13.c, since typed arrays can't have undefined or null elements.
var next = ToString(element);
// Step 13.e.
@ -607,11 +602,10 @@ function TypedArrayMap(callbackfn, thisArg = undefined) {
// Step 4.
var len;
if (isTypedArray) {
if (isTypedArray)
len = TypedArrayLength(O);
} else {
else
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
}
// Step 5.
if (arguments.length === 0)
@ -657,11 +651,10 @@ function TypedArrayReduce(callbackfn/*, initialValue*/) {
// Steps 3-5.
var len;
if (isTypedArray) {
if (isTypedArray)
len = TypedArrayLength(O);
} else {
else
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
}
// Step 6.
if (arguments.length === 0)
@ -704,11 +697,10 @@ function TypedArrayReduceRight(callbackfn/*, initialValue*/) {
// Steps 3-5.
var len;
if (isTypedArray) {
if (isTypedArray)
len = TypedArrayLength(O);
} else {
else
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
}
// Step 6.
if (arguments.length === 0)
@ -870,7 +862,7 @@ function SetFromTypedArray(target, typedArray, targetOffset, targetLength) {
}
// ES6 draft 20150304 %TypedArray%.prototype.set
function TypedArraySet(overloaded, offset) {
function TypedArraySet(overloaded, offset = 0) {
// Steps 2-5, either algorithm.
var target = this;
if (!IsObject(target) || !IsTypedArray(target)) {
@ -971,11 +963,10 @@ function TypedArraySome(callbackfn, thisArg = undefined) {
// Steps 3-5.
var len;
if (isTypedArray) {
if (isTypedArray)
len = TypedArrayLength(O);
} else {
else
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
}
// Step 6.
if (arguments.length === 0)
@ -1106,6 +1097,78 @@ function TypedArraySort(comparefn) {
return QuickSort(obj, len, comparefn);
}
// ES2017 draft rev f8a9be8ea4bd97237d176907a1e3080dce20c68f
// 22.2.3.28 %TypedArray%.prototype.toLocaleString ([ reserved1 [ , reserved2 ] ])
// ES2017 Intl draft rev 78bbe7d1095f5ff3760ac4017ed366026e4cb276
// 13.4.1 Array.prototype.toLocaleString ([ locales [ , options ]])
function TypedArrayToLocaleString(locales = undefined, options = undefined) {
// ValidateTypedArray, then step 1.
var array = this;
// This function is not generic.
// We want to make sure that we have an attached buffer, per spec prose.
var isTypedArray = IsTypedArrayEnsuringArrayBuffer(array);
// If we got here, `this` is either a typed array or a cross-compartment
// wrapper for one.
// Step 2.
var len;
if (isTypedArray)
len = TypedArrayLength(array);
else
len = callFunction(CallTypedArrayMethodIfWrapped, array, array, "TypedArrayLength");
// Step 4.
if (len === 0)
return "";
// Step 5.
var firstElement = array[0];
// Steps 6-7.
// Omit the 'if' clause in step 6, since typed arrays can't have undefined
// or null elements.
#if EXPOSE_INTL_API
var R = ToString(callContentFunction(firstElement.toLocaleString, firstElement, locales, options));
#else
var R = ToString(callContentFunction(firstElement.toLocaleString, firstElement));
#endif
// Step 3 (reordered).
// We don't (yet?) implement locale-dependent separators.
var separator = ",";
// Steps 8-9.
for (var k = 1; k < len; k++) {
// Step 9.a.
var S = R + separator;
// Step 9.b.
var nextElement = array[k];
// Step 9.c *should* be unreachable: typed array elements are numbers.
// But bug 1079853 means |nextElement| *could* be |undefined|, if the
// previous iteration's step 9.d or step 7 detached |array|'s buffer.
// Conveniently, if this happens, evaluating |nextElement.toLocaleString|
// throws the required TypeError, and the only observable difference is
// the error message. So despite bug 1079853, we can skip step 9.c.
// Step 9.d.
#if EXPOSE_INTL_API
R = ToString(callContentFunction(nextElement.toLocaleString, nextElement, locales, options));
#else
R = ToString(callContentFunction(nextElement.toLocaleString, nextElement));
#endif
// Step 9.e.
R = S + R;
}
// Step 10.
return R;
}
// ES6 draft 20150304 %TypedArray%.prototype.subarray
function TypedArraySubarray(begin, end) {
// Step 1.

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

@ -0,0 +1,7 @@
function f(x) {
return (x ** (1 / ~4294967297)) && x;
};
for (var i = 0; i < 2; ++i) {
assertEq(f(-Infinity), 0);
}

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

@ -1,3 +1,10 @@
// This test case was created before %TypedArrayPrototype%.toString was
// implemented. Now that we've got %TypedArrayPrototype%.toString the test will
// attempt to create a 300300001 character long string and either timeout or
// throw an oom error. Restore the original behavior by replacing toString with
// Object.prototype.toString.
Uint8ClampedArray.prototype.toString = Object.prototype.toString;
function A(a) { this.a = a; }
A.prototype.foo = function (x) {};
function B(b) { this.b = b; }

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

@ -0,0 +1,17 @@
// |jit-test| test-also-wasm-baseline
load(libdir + "wasm.js");
// Bug 1298808.
assertEq(wasmEvalText(`(module
(func
(result i32)
(i32.wrap/i64
(i64.mul
;; Conditions: rhs == lhs, rhs is not a constant.
(i64.add (i64.const 1) (i64.const 10))
(i64.add (i64.const 1) (i64.const 10))
)
)
)
(export "" 0)
)`)(), 121);

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

@ -211,22 +211,23 @@ LIRGeneratorARM::lowerForALUInt64(LInstructionHelper<INT64_PIECES, 2 * INT64_PIE
void
LIRGeneratorARM::lowerForMulInt64(LMulI64* ins, MMul* mir, MDefinition* lhs, MDefinition* rhs)
{
bool constantNeedTemp = true;
bool needsTemp = true;
if (rhs->isConstant()) {
int64_t constant = rhs->toConstant()->toInt64();
int32_t shift = mozilla::FloorLog2(constant);
// See special cases in CodeGeneratorARM::visitMulI64
if (constant >= -1 && constant <= 2)
constantNeedTemp = false;
needsTemp = false;
if (int64_t(1) << shift == constant)
constantNeedTemp = false;
needsTemp = false;
}
ins->setInt64Operand(0, useInt64RegisterAtStart(lhs));
ins->setInt64Operand(INT64_PIECES,
lhs != rhs ? useInt64OrConstant(rhs) : useInt64OrConstantAtStart(rhs));
if (constantNeedTemp)
ins->setInt64Operand(INT64_PIECES, useInt64OrConstant(rhs));
if (needsTemp)
ins->setTemp(0, temp());
defineInt64ReuseInput(ins, mir, 0);
}

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

@ -878,8 +878,8 @@ CodeGeneratorX86Shared::visitPowHalfD(LPowHalfD* ins)
masm.branchDouble(cond, input, scratch, &sqrt);
// Math.pow(-Infinity, 0.5) == Infinity.
masm.zeroDouble(input);
masm.subDouble(scratch, input);
masm.zeroDouble(output);
masm.subDouble(scratch, output);
masm.jump(&done);
masm.bind(&sqrt);
@ -888,11 +888,12 @@ CodeGeneratorX86Shared::visitPowHalfD(LPowHalfD* ins)
if (!ins->mir()->operandIsNeverNegativeZero()) {
// Math.pow(-0, 0.5) == 0 == Math.pow(0, 0.5). Adding 0 converts any -0 to 0.
masm.zeroDouble(scratch);
masm.addDouble(scratch, input);
masm.addDouble(input, scratch);
masm.vsqrtsd(scratch, output, output);
} else {
masm.vsqrtsd(input, output, output);
}
masm.vsqrtsd(input, output, output);
masm.bind(&done);
}

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

@ -217,23 +217,24 @@ LIRGeneratorX86::lowerForALUInt64(LInstructionHelper<INT64_PIECES, 2 * INT64_PIE
void
LIRGeneratorX86::lowerForMulInt64(LMulI64* ins, MMul* mir, MDefinition* lhs, MDefinition* rhs)
{
bool constantNeedTemp = true;
bool needsTemp = true;
if (rhs->isConstant()) {
int64_t constant = rhs->toConstant()->toInt64();
int32_t shift = mozilla::FloorLog2(constant);
// See special cases in CodeGeneratorX86Shared::visitMulI64
// See special cases in CodeGeneratorX86Shared::visitMulI64.
if (constant >= -1 && constant <= 2)
constantNeedTemp = false;
needsTemp = false;
if (int64_t(1) << shift == constant)
constantNeedTemp = false;
needsTemp = false;
}
// MulI64 on x86 needs output to be in edx, eax;
ins->setInt64Operand(0, useInt64Fixed(lhs, Register64(edx, eax), /*useAtStart = */ true));
ins->setInt64Operand(INT64_PIECES,
lhs != rhs ? useInt64OrConstant(rhs) : useInt64OrConstantAtStart(rhs));
if (constantNeedTemp)
ins->setInt64Operand(INT64_PIECES, useInt64OrConstant(rhs));
if (needsTemp)
ins->setTemp(0, temp());
defineInt64Fixed(ins, mir, LInt64Allocation(LAllocation(AnyRegister(edx)),
LAllocation(AnyRegister(eax))));
}

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

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

@ -0,0 +1,103 @@
if (typeof Intl === "object") {
const constructors = [
Int8Array,
Uint8Array,
Uint8ClampedArray,
Int16Array,
Uint16Array,
Int32Array,
Uint32Array,
Float32Array,
Float64Array,
];
const localeSep = [,,].toLocaleString();
const originalNumberToLocaleString = Number.prototype.toLocaleString;
// Missing arguments are passed as |undefined|.
for (let constructor of constructors) {
Number.prototype.toLocaleString = function() {
assertEq(arguments.length, 2);
assertEq(arguments[0], undefined);
assertEq(arguments[1], undefined);
return "pass";
};
// Single element case.
assertEq(new constructor(1).toLocaleString(), "pass");
// More than one element.
assertEq(new constructor(2).toLocaleString(), "pass" + localeSep + "pass");
}
Number.prototype.toLocaleString = originalNumberToLocaleString;
// Missing options is passed as |undefined|.
for (let constructor of constructors) {
Number.prototype.toLocaleString = function() {
assertEq(arguments.length, 2);
assertEq(arguments[0], locales);
assertEq(arguments[1], undefined);
return "pass";
};
let locales = {};
// Single element case.
assertEq(new constructor(1).toLocaleString(locales), "pass");
// More than one element.
assertEq(new constructor(2).toLocaleString(locales), "pass" + localeSep + "pass");
}
Number.prototype.toLocaleString = originalNumberToLocaleString;
// Ensure "locales" and "options" arguments are passed to the array elements.
for (let constructor of constructors) {
Number.prototype.toLocaleString = function() {
assertEq(arguments.length, 2);
assertEq(arguments[0], locales);
assertEq(arguments[1], options);
return "pass";
};
let locales = {};
let options = {};
// Single element case.
assertEq(new constructor(1).toLocaleString(locales, options), "pass");
// More than one element.
assertEq(new constructor(2).toLocaleString(locales, options), "pass" + localeSep + "pass");
}
Number.prototype.toLocaleString = originalNumberToLocaleString;
assertEq(new Float32Array([NaN]).toLocaleString("ar"), "ليس رقم");
assertEq(new Float64Array([NaN]).toLocaleString(["zh-hant", "ar"]), "非數值");
assertEq(new Float32Array([Infinity]).toLocaleString(["dz"]), "གྲངས་མེད");
assertEq(new Float64Array([-Infinity]).toLocaleString(["fr", "en"]), "-∞");
const sampleValues = [-0, +0, -1, +1, -2, +2, -0.5, +0.5];
const sampleLocales = [
void 0,
"en",
"th-th-u-nu-thai",
["tlh", "de"],
];
const sampleOptions = [
void 0,
{},
{style: "percent"},
{style: "currency", currency: "USD", minimumIntegerDigits: 4},
];
for (let locale of sampleLocales) {
for (let options of sampleOptions) {
let nf = new Intl.NumberFormat(locale, options);
for (let constructor of constructors) {
let typedArray = new constructor(sampleValues);
let expected = [].map.call(typedArray, nf.format).join(localeSep);
assertEq(typedArray.toLocaleString(locale, options), expected);
}
}
}
}
if (typeof reportCompare === "function")
reportCompare(true, true);

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

@ -0,0 +1,33 @@
const TypedArrayPrototype = Object.getPrototypeOf(Int8Array.prototype);
const constructors = [
Int8Array,
Uint8Array,
Uint8ClampedArray,
Int16Array,
Uint16Array,
Int32Array,
Uint32Array,
Float32Array,
Float64Array
];
// %TypedArrayPrototype% has an own "set" function property.
assertEq(TypedArrayPrototype.hasOwnProperty("set"), true);
assertEq(typeof TypedArrayPrototype.set, "function");
// The concrete TypedArray prototypes do not have an own "set" property.
assertEq(constructors.every(c => !c.hasOwnProperty("set")), true);
assertDeepEq(Object.getOwnPropertyDescriptor(TypedArrayPrototype, "set"), {
value: TypedArrayPrototype.set,
writable: true,
enumerable: false,
configurable: true,
});
assertEq(TypedArrayPrototype.set.name, "set");
assertEq(TypedArrayPrototype.set.length, 1);
if (typeof reportCompare === "function")
reportCompare(true, true);

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

@ -0,0 +1,50 @@
if (typeof detachArrayBuffer === "function") {
const constructors = [
Int8Array,
Uint8Array,
Uint8ClampedArray,
Int16Array,
Uint16Array,
Int32Array,
Uint32Array,
Float32Array,
Float64Array,
];
const originalNumberToLocaleString = Number.prototype.toLocaleString;
// Throws if array buffer is detached.
for (let constructor of constructors) {
let typedArray = new constructor(42);
detachArrayBuffer(typedArray.buffer);
assertThrowsInstanceOf(() => typedArray.toLocaleString(), TypeError);
}
// Throws a TypeError if detached in Number.prototype.toLocaleString.
for (let constructor of constructors) {
Number.prototype.toLocaleString = function() {
"use strict";
if (!detached) {
detachArrayBuffer(typedArray.buffer);
detached = true;
}
return this;
};
// No error for single element arrays.
let detached = false;
let typedArray = new constructor(1);
assertEq(typedArray.toLocaleString(), "0");
assertEq(detached, true);
// TypeError if more than one element is present.
detached = false;
typedArray = new constructor(2);
assertThrowsInstanceOf(() => typedArray.toLocaleString(), TypeError);
assertEq(detached, true);
}
Number.prototype.toLocaleString = originalNumberToLocaleString;
}
if (typeof reportCompare === "function")
reportCompare(true, true);

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

@ -0,0 +1,52 @@
if (typeof Intl !== "object") {
const constructors = [
Int8Array,
Uint8Array,
Uint8ClampedArray,
Int16Array,
Uint16Array,
Int32Array,
Uint32Array,
Float32Array,
Float64Array,
];
const localeSep = [,,].toLocaleString();
const originalNumberToLocaleString = Number.prototype.toLocaleString;
// Ensure no arguments are passed to the array elements.
for (let constructor of constructors) {
Number.prototype.toLocaleString = function() {
assertEq(arguments.length, 0);
return "pass";
};
// Single element case.
assertEq(new constructor(1).toLocaleString(), "pass");
// More than one element.
assertEq(new constructor(2).toLocaleString(), "pass" + localeSep + "pass");
}
Number.prototype.toLocaleString = originalNumberToLocaleString;
// Ensure no arguments are passed to the array elements even if supplied.
for (let constructor of constructors) {
Number.prototype.toLocaleString = function() {
assertEq(arguments.length, 0);
return "pass";
};
let locales = {};
let options = {};
// Single element case.
assertEq(new constructor(1).toLocaleString(locales, options), "pass");
// More than one element.
assertEq(new constructor(2).toLocaleString(locales, options), "pass" + localeSep + "pass");
}
Number.prototype.toLocaleString = originalNumberToLocaleString;
}
if (typeof reportCompare === "function")
reportCompare(true, true);

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

@ -0,0 +1,92 @@
const TypedArrayPrototype = Object.getPrototypeOf(Int8Array.prototype);
const constructors = [
Int8Array,
Uint8Array,
Uint8ClampedArray,
Int16Array,
Uint16Array,
Int32Array,
Uint32Array,
Float32Array,
Float64Array,
];
// %TypedArrayPrototype% has an own "toLocaleString" function property.
assertEq(TypedArrayPrototype.hasOwnProperty("toLocaleString"), true);
assertEq(typeof TypedArrayPrototype.toLocaleString, "function");
// The initial value of %TypedArrayPrototype%.toLocaleString is not Array.prototype.toLocaleString.
assertEq(TypedArrayPrototype.toLocaleString === Array.prototype.toLocaleString, false);
// The concrete TypedArray prototypes do not have an own "toLocaleString" property.
assertEq(constructors.every(c => !c.hasOwnProperty("toLocaleString")), true);
assertDeepEq(Object.getOwnPropertyDescriptor(TypedArrayPrototype, "toLocaleString"), {
value: TypedArrayPrototype.toLocaleString,
writable: true,
enumerable: false,
configurable: true,
});
assertEq(TypedArrayPrototype.toLocaleString.name, "toLocaleString");
assertEq(TypedArrayPrototype.toLocaleString.length, 0);
// It's not a generic method.
assertThrowsInstanceOf(() => TypedArrayPrototype.toLocaleString.call(), TypeError);
for (let invalid of [void 0, null, {}, [], function(){}, true, 0, "", Symbol()]) {
assertThrowsInstanceOf(() => TypedArrayPrototype.toLocaleString.call(invalid), TypeError);
}
const localeOne = 1..toLocaleString(),
localeTwo = 2..toLocaleString(),
localeSep = [,,].toLocaleString();
for (let constructor of constructors) {
assertEq(new constructor([]).toLocaleString(), "");
assertEq(new constructor([1]).toLocaleString(), localeOne);
assertEq(new constructor([1, 2]).toLocaleString(), localeOne + localeSep + localeTwo);
}
const originalNumberToLocaleString = Number.prototype.toLocaleString;
// Calls Number.prototype.toLocaleString on each element.
for (let constructor of constructors) {
Number.prototype.toLocaleString = function() {
"use strict";
// Ensure this-value is not boxed.
assertEq(typeof this, "number");
// Test ToString is applied.
return {
valueOf: () => {
throw new Error("valueOf called");
},
toString: () => {
return this + 10;
}
};
};
let typedArray = new constructor([1, 2]);
assertEq(typedArray.toLocaleString(), "11" + localeSep + "12");
}
Number.prototype.toLocaleString = originalNumberToLocaleString;
// Calls Number.prototype.toLocaleString from the current Realm.
const otherGlobal = newGlobal();
for (let constructor of constructors) {
Number.prototype.toLocaleString = function() {
"use strict";
called = true;
return this;
};
let typedArray = new otherGlobal[constructor.name]([1]);
let called = false;
assertEq(TypedArrayPrototype.toLocaleString.call(typedArray), "1");
assertEq(called, true);
}
Number.prototype.toLocaleString = originalNumberToLocaleString;
if (typeof reportCompare === "function")
reportCompare(true, true);

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

@ -0,0 +1,48 @@
const TypedArrayPrototype = Object.getPrototypeOf(Int8Array.prototype);
const constructors = [
Int8Array,
Uint8Array,
Uint8ClampedArray,
Int16Array,
Uint16Array,
Int32Array,
Uint32Array,
Float32Array,
Float64Array,
];
// %TypedArrayPrototype% has an own "toString" property.
assertEq(TypedArrayPrototype.hasOwnProperty("toString"), true);
// The initial value of %TypedArrayPrototype%.toString is Array.prototype.toString.
assertEq(TypedArrayPrototype.toString, Array.prototype.toString);
// The concrete TypedArray prototypes do not have an own "toString" property.
assertEq(constructors.every(c => !c.hasOwnProperty("toString")), true);
assertDeepEq(Object.getOwnPropertyDescriptor(TypedArrayPrototype, "toString"), {
value: TypedArrayPrototype.toString,
writable: true,
enumerable: false,
configurable: true,
});
for (let constructor of constructors) {
assertEq(new constructor([]).toString(), "");
assertEq(new constructor([1]).toString(), "1");
assertEq(new constructor([1, 2]).toString(), "1,2");
}
assertEq(new Int8Array([-1, 2, -3, 4, NaN]).toString(), "-1,2,-3,4,0");
assertEq(new Uint8Array([255, 2, 3, 4, NaN]).toString(), "255,2,3,4,0");
assertEq(new Uint8ClampedArray([255, 256, 2, 3, 4, NaN]).toString(), "255,255,2,3,4,0");
assertEq(new Int16Array([-1, 2, -3, 4, NaN]).toString(), "-1,2,-3,4,0");
assertEq(new Uint16Array([-1, 2, 3, 4, NaN]).toString(), "65535,2,3,4,0");
assertEq(new Int32Array([-1, 2, -3, 4, NaN]).toString(), "-1,2,-3,4,0");
assertEq(new Uint32Array([-1, 2, 3, 4, NaN]).toString(), "4294967295,2,3,4,0");
assertEq(new Float32Array([-0, 0, 0.5, -0.5, NaN, Infinity, -Infinity]).toString(), "0,0,0.5,-0.5,NaN,Infinity,-Infinity");
assertEq(new Float64Array([-0, 0, 0.5, -0.5, NaN, Infinity, -Infinity]).toString(), "0,0,0.5,-0.5,NaN,Infinity,-Infinity");
if (typeof reportCompare === "function")
reportCompare(true, true);

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

@ -0,0 +1,17 @@
// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
/*
* Any copyright is dedicated to the Public Domain.
* https://creativecommons.org/publicdomain/zero/1.0/
*/
var { testLoad } = Helpers;
testLoad('Int16x8', new Int16Array(SIZE_16_ARRAY));
if (typeof SharedArrayBuffer != "undefined") {
testLoad('Int16x8', new Int16Array(new SharedArrayBuffer(SIZE_8_ARRAY)));
}
if (typeof reportCompare === "function")
reportCompare(true, true);

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

@ -7,14 +7,10 @@
var { testLoad } = Helpers;
testLoad('Int8x16', new Int8Array(SIZE_8_ARRAY));
testLoad('Int16x8', new Int16Array(SIZE_16_ARRAY));
testLoad('Int32x4', new Int32Array(SIZE_32_ARRAY));
if (typeof SharedArrayBuffer != "undefined") {
testLoad('Int8x16', new Int8Array(new SharedArrayBuffer(SIZE_8_ARRAY)));
testLoad('Int16x8', new Int16Array(new SharedArrayBuffer(SIZE_8_ARRAY)));
testLoad('Int32x4', new Int32Array(new SharedArrayBuffer(SIZE_8_ARRAY)));
testLoad('Int32x4', new Int32Array(new SharedArrayBuffer(SIZE_8_ARRAY)));
}
if (typeof reportCompare === "function")

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

@ -0,0 +1,17 @@
// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
/*
* Any copyright is dedicated to the Public Domain.
* https://creativecommons.org/publicdomain/zero/1.0/
*/
var { testLoad } = Helpers;
testLoad('Int8x16', new Int8Array(SIZE_8_ARRAY));
if (typeof SharedArrayBuffer != "undefined") {
testLoad('Int8x16', new Int8Array(new SharedArrayBuffer(SIZE_8_ARRAY)));
}
if (typeof reportCompare === "function")
reportCompare(true, true);

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

@ -1356,7 +1356,7 @@ TypedArrayObject::protoFunctions[] = {
#if 0 /* disabled until perf-testing is completed */
JS_SELF_HOSTED_FN("set", "TypedArraySet", 2, 0),
#else
JS_FN("set", TypedArrayObject::set, 2, 0),
JS_FN("set", TypedArrayObject::set, 1, 0),
#endif
JS_SELF_HOSTED_FN("copyWithin", "TypedArrayCopyWithin", 3, 0),
JS_SELF_HOSTED_FN("every", "TypedArrayEvery", 2, 0),
@ -1380,6 +1380,8 @@ TypedArrayObject::protoFunctions[] = {
JS_SELF_HOSTED_FN("values", "TypedArrayValues", 0, 0),
JS_SELF_HOSTED_SYM_FN(iterator, "TypedArrayValues", 0, 0),
JS_SELF_HOSTED_FN("includes", "TypedArrayIncludes", 2, 0),
JS_SELF_HOSTED_FN("toString", "ArrayToString", 0, 0),
JS_SELF_HOSTED_FN("toLocaleString", "TypedArrayToLocaleString", 2, 0),
JS_FS_END
};

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

@ -4,5 +4,5 @@ function run_test() {
var xhr = Cu.evalInSandbox('new XMLHttpRequest()', sb);
do_check_eq(xhr.toString(), '[object XMLHttpRequest]');
do_check_eq((new sb.Object()).toString(), '[object Object]');
do_check_eq((new sb.Uint16Array()).toString(), '[object Uint16Array]');
do_check_eq(sb.Object.prototype.toString.call(new sb.Uint16Array()), '[object Uint16Array]');
}

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

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bug 1288255 - Wrong line breaking due to cached hyphen width</title>
<style>
@font-face {
font-family: LongHyphenTest;
src: url(LongHyphenTest.woff2);
}
#test {
font: 16px/2 LongHyphenTest;
width: 14em;
border: 1px solid blue;
}
</style>
</head>
<body>
<p>Test passes if there are two lines each has three rectangles:</p>
<div id="test">
XXX XXX XXX<br>XXX XXX XXX
</div>
</body>
</html>

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

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en" class="reftest-wait">
<head>
<meta charset="UTF-8">
<title>Bug 1288255 - Wrong line breaking due to cached hyphen width</title>
<style id="font" media="not all">
@font-face {
font-family: LongHyphenTest;
src: url(LongHyphenTest.woff2);
}
</style>
<style>
#test {
font: 16px/2 LongHyphenTest;
width: 14em;
border: 1px solid blue;
}
</style>
</head>
<body onload="load_font()">
<p>Test passes if there are two lines each has three rectangles:</p>
<div id="test">
<span>XXX XXX</span> XXX X&shy;XX XXX XXX
</div>
<script>
function load_font() {
document.getElementById("font").media = "";
document.fonts.load("16px LongHyphenTest").then(() => {
document.documentElement.className = "";
});
}
</script>
</body>
</html>

Двоичные данные
layout/reftests/bugs/LongHyphenTest.woff2 Normal file

Двоичный файл не отображается.

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

@ -1962,6 +1962,7 @@ random-if(!winWidget) == 1273154-2.html 1273154-2-ref.html # depends on Windows
!= 1276161-1b.html 1276161-1-notref.html
!= 1276161-1a.html 1276161-1b.html
== 1275411-1.html 1275411-1-ref.html
== 1288255.html 1288255-ref.html
fuzzy(8,1900) == 1291528.html 1291528-ref.html
# Buttons in 2 pages have different position and the rendering result can be
# different, but they should use the same button style and the background color

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше