This commit is contained in:
Ryan VanderMeulen 2017-05-30 12:39:46 -04:00
Родитель 2af91f1c45 dd4d4daa0a
Коммит 9289913a09
51 изменённых файлов: 563 добавлений и 186 удалений

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

@ -36,7 +36,11 @@
this.invoke = function testTabRelations_invoke()
{
var docURIs = ["about:", "about:mozilla"];
tabBrowser().loadTabs(docURIs, false, true);
tabBrowser().loadTabs(docURIs, {
inBackground: false,
replace: true,
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
}
this.finalCheck = function testTabRelations_finalCheck(aEvent)

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

@ -35,7 +35,11 @@
this.invoke = function testTabHierarchy_invoke()
{
var docURIs = ["about:", "about:mozilla"];
tabBrowser().loadTabs(docURIs, false, true);
tabBrowser().loadTabs(docURIs, {
inBackground: false,
replace: true,
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
}
this.finalCheck = function testTabHierarchy_finalCheck(aEvent)

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

@ -659,6 +659,12 @@ pref("accessibility.loadedInLastSession", false);
pref("plugins.click_to_play", true);
pref("plugins.testmode", false);
// Should plugins that are hidden show the infobar UI?
pref("plugins.show_infobar", true);
// Should dismissing the hidden plugin infobar suppress it permanently?
pref("plugins.remember_infobar_dismissal", false);
pref("plugin.default.state", 1);
// Plugins bundled in XPIs are enabled by default.

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

@ -6,6 +6,9 @@
var gPluginHandler = {
PREF_SESSION_PERSIST_MINUTES: "plugin.sessionPermissionNow.intervalInMinutes",
PREF_PERSISTENT_DAYS: "plugin.persistentPermissionAlways.intervalInDays",
PREF_SHOW_INFOBAR: "plugins.show_infobar",
PREF_INFOBAR_DISMISSAL_PERMANENT: "plugins.remember_infobar_dismissal",
MESSAGES: [
"PluginContent:ShowClickToPlayNotification",
"PluginContent:RemoveNotification",
@ -345,6 +348,10 @@ var gPluginHandler = {
// 2b. Multiple types of plugins are hidden on the page, but none are
// vulnerable. Show the nonvulnerable multi-UI.
function showNotification() {
if (!Services.prefs.getBoolPref(gPluginHandler.PREF_SHOW_INFOBAR, true)) {
return;
}
let n = notificationBox.getNotificationWithValue("plugin-hidden");
if (n) {
// If something is already shown, just keep it
@ -414,9 +421,21 @@ var gPluginHandler = {
}
}
];
function notificationCallback(type) {
if (type == "dismissed") {
Services.telemetry.getHistogramById("PLUGINS_INFOBAR_DISMISSED").
add(true);
if (Services.prefs.getBoolPref(gPluginHandler.PREF_INFOBAR_DISMISSAL_PERMANENT, false)) {
Services.perms.addFromPrincipal(principal,
"plugin-hidden-notification",
Services.perms.DENY_ACTION);
}
}
}
n = notificationBox.
appendNotification(message, "plugin-hidden", null,
notificationBox.PRIORITY_INFO_HIGH, buttons);
notificationBox.PRIORITY_INFO_HIGH, buttons,
notificationCallback);
if (haveInsecure) {
n.classList.add("pluginVulnerable");
}

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

@ -1426,7 +1426,11 @@ var gBrowserInit = {
// This function throws for certain malformed URIs, so use exception handling
// so that we don't disrupt startup
try {
gBrowser.loadTabs(specs, false, true);
gBrowser.loadTabs(specs, {
inBackground: false,
replace: true,
// Bug 1365232, provide correct triggeringPrincipal
});
} catch (e) {}
} else if (uriToLoad instanceof XULElement) {
// swap the given tab with the default about:blank tab and then close
@ -2162,7 +2166,10 @@ function BrowserGoHome(aEvent) {
case "tab":
urls = homePage.split("|");
var loadInBackground = getBoolPref("browser.tabs.loadBookmarksInBackground", false);
gBrowser.loadTabs(urls, loadInBackground);
gBrowser.loadTabs(urls, {
inBackground: loadInBackground,
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
break;
case "window":
OpenBrowserWindow();
@ -2180,7 +2187,11 @@ function loadOneOrMoreURIs(aURIString) {
// This function throws for certain malformed URIs, so use exception handling
// so that we don't disrupt startup
try {
gBrowser.loadTabs(aURIString.split("|"), false, true);
gBrowser.loadTabs(aURIString.split("|"), {
inBackground: false,
replace: true,
// Bug 1365232, provide correct triggeringPrincipal
});
} catch (e) {
}
}
@ -5827,14 +5838,15 @@ function stripUnsafeProtocolOnPaste(pasteData) {
}
// handleDroppedLink has the following 2 overloads:
// handleDroppedLink(event, url, name)
// handleDroppedLink(event, links)
function handleDroppedLink(event, urlOrLinks, name) {
// handleDroppedLink(event, url, name, triggeringPrincipal)
// handleDroppedLink(event, links, triggeringPrincipal)
function handleDroppedLink(event, urlOrLinks, nameOrTriggeringPrincipal, triggeringPrincipal) {
let links;
if (Array.isArray(urlOrLinks)) {
links = urlOrLinks;
triggeringPrincipal = nameOrTriggeringPrincipal;
} else {
links = [{ url: urlOrLinks, name, type: "" }];
links = [{ url: urlOrLinks, nameOrTriggeringPrincipal, type: "" }];
}
let lastLocationChange = gBrowser.selectedBrowser.lastLocationChange;
@ -5865,6 +5877,7 @@ function handleDroppedLink(event, urlOrLinks, name) {
allowThirdPartyFixup: false,
postDatas,
userContextId,
triggeringPrincipal,
});
}
})();

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

@ -7016,6 +7016,13 @@
let replace = !!targetTab;
let newIndex = this._getDropIndex(event, true);
let urls = links.map(link => link.url);
// Bug 1367038: mozSourceNode is null if the drag event originated
// in an external application - needs better fallback!
let triggeringPrincipal = dt.mozSourceNode
? dt.mozSourceNode.nodePrincipal
: Services.scriptSecurityManager.getSystemPrincipal();
this.tabbrowser.loadTabs(urls, {
inBackground,
replace,
@ -7023,6 +7030,7 @@
targetTab,
newIndex,
userContextId,
triggeringPrincipal,
});
}

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

@ -13,4 +13,4 @@ MOCHITEST_MANIFESTS += [
]
with Files('**'):
BUG_COMPONENT = ('Firefox', 'OriginAttributes')
BUG_COMPONENT = ('Core', 'DOM: Security')

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

@ -953,7 +953,11 @@ this.PlacesUIUtils = {
// For consistency, we want all the bookmarks to open in new tabs, instead
// of having one of them replace the currently focused tab. Hence we call
// loadTabs with aReplace set to false.
browserWindow.gBrowser.loadTabs(urls, loadInBackground, false);
browserWindow.gBrowser.loadTabs(urls, {
inBackground: loadInBackground,
replace: false,
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
},
openLiveMarkNodesInTabs:

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

@ -15,6 +15,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "BrowserUITelemetry",
"resource:///modules/BrowserUITelemetry.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUIUtils",
"resource:///modules/PlacesUIUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
this.EXPORTED_SYMBOLS = [
"TabListComponent"
@ -127,7 +129,11 @@ TabListComponent.prototype = {
"chrome,dialog=no,all", urls.join("|"));
} else {
let loadInBackground = where == "tabshifted" ? true : false;
this._getChromeWindow(this._window).gBrowser.loadTabs(urls, loadInBackground, false);
this._getChromeWindow(this._window).gBrowser.loadTabs(urls, {
inBackground: loadInBackground,
replace: false,
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
}
BrowserUITelemetry.countSyncedTabEvent("openmultiple", "sidebar");
},

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

@ -4,6 +4,7 @@ let { SyncedTabs } = Cu.import("resource://services-sync/SyncedTabs.jsm", {});
let { TabListComponent } = Cu.import("resource:///modules/syncedtabs/TabListComponent.js", {});
let { SyncedTabsListStore } = Cu.import("resource:///modules/syncedtabs/SyncedTabsListStore.js", {});
let { View } = Cu.import("resource:///modules/syncedtabs/TabListView.js", {});
let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const ACTION_METHODS = [
"onSelectRow",
@ -139,9 +140,17 @@ add_task(function* testActions() {
let tabsToOpen = ["uri1", "uri2"];
component.onOpenTabs(tabsToOpen, "where");
Assert.ok(getChromeWindowMock.calledWith(windowMock));
Assert.ok(chromeWindowMock.gBrowser.loadTabs.calledWith(tabsToOpen, false, false));
Assert.ok(chromeWindowMock.gBrowser.loadTabs.calledWith(tabsToOpen, {
inBackground: false,
replace: false,
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
}));
component.onOpenTabs(tabsToOpen, "tabshifted");
Assert.ok(chromeWindowMock.gBrowser.loadTabs.calledWith(tabsToOpen, true, false));
Assert.ok(chromeWindowMock.gBrowser.loadTabs.calledWith(tabsToOpen, {
inBackground: true,
replace: false,
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
}));
sinon.spy(clipboardHelperMock, "copyString");
component.onCopyTabLocation("uri");

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

@ -92,7 +92,12 @@ this.Tabs = {
"about:home",
DEFAULT_FAVICON_TAB,
"about:newtab",
], true, true);
],
{
inBackground: true,
replace: true,
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
});
browserWindow.gBrowser.pinTab(browserWindow.gBrowser.tabs[1]);
browserWindow.gBrowser.pinTab(browserWindow.gBrowser.tabs[2]);
browserWindow.gBrowser.selectTabAtIndex(3);
@ -119,7 +124,12 @@ function fiveTabsHelper() {
DEFAULT_FAVICON_TAB,
"about:newtab",
CUST_TAB,
], true, true);
],
{
inBackground: true,
replace: true,
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
});
browserWindow.gBrowser.selectTabAtIndex(1);
}

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

@ -8,6 +8,7 @@ const { addons, createClass, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const Types = require("../types");
const { getStr } = require("../utils/l10n");
const COLUMNS = "cols";
const ROWS = "rows";
@ -15,6 +16,10 @@ const ROWS = "rows";
// The delay prior to executing the grid cell highlighting.
const GRID_HIGHLIGHTING_DEBOUNCE = 50;
// Minimum height/width a grid cell can be
const MIN_CELL_HEIGHT = 5;
const MIN_CELL_WIDTH = 5;
// Move SVG grid to the right 100 units, so that it is not flushed against the edge of
// layout border
const TRANSLATE_X = 0;
@ -40,8 +45,9 @@ module.exports = createClass({
getInitialState() {
return {
selectedGrid: null,
height: 0,
selectedGrid: null,
showOutline: true,
width: 0,
};
},
@ -56,7 +62,7 @@ module.exports = createClass({
? this.getTotalWidthAndHeight(selectedGrid)
: { width: 0, height: 0 };
this.setState({ height, width, selectedGrid });
this.setState({ height, width, selectedGrid, showOutline: true });
},
/**
@ -135,6 +141,7 @@ module.exports = createClass({
if (this.highlightTimeout) {
clearTimeout(this.highlightTimeout);
}
this.highlightTimeout = setTimeout(() => {
this.doHighlightCell(e);
this.highlightTimeout = null;
@ -164,6 +171,25 @@ module.exports = createClass({
}
},
/**
* Displays a message text "Cannot show outline for this grid".
*
*/
renderCannotShowOutlineText() {
return dom.div(
{
className: "grid-outline-text"
},
dom.span(
{
className: "grid-outline-text-icon",
title: getStr("layout.cannotShowGridOutline.title")
}
),
getStr("layout.cannotShowGridOutline")
);
},
/**
* Renders the grid outline for the given grid container object.
*
@ -192,6 +218,14 @@ module.exports = createClass({
for (let columnNumber = 1; columnNumber <= numberOfColumns; columnNumber++) {
width = GRID_CELL_SCALE_FACTOR * (cols.tracks[columnNumber - 1].breadth / 100);
// If a grid cell is less than the minimum pixels in width or height,
// do not render the outline at all.
if (width < MIN_CELL_WIDTH || height < MIN_CELL_HEIGHT) {
this.setState({ showOutline: false });
return [];
}
const gridAreaName = this.getGridAreaName(columnNumber, rowNumber, areas);
const gridCell = this.renderGridCell(id, gridFragmentIndex, x, y,
rowNumber, columnNumber, color, gridAreaName,
@ -420,13 +454,17 @@ module.exports = createClass({
lineNumber, type);
},
render() {
const { selectedGrid, height, width } = this.state;
renderOutline() {
const {
height,
selectedGrid,
showOutline,
width,
} = this.state;
return selectedGrid ?
return showOutline ?
dom.svg(
{
className: "grid-outline",
width: "100%",
height: this.getHeight(),
viewBox: `${TRANSLATE_X} ${TRANSLATE_Y} ${width} ${height}`,
@ -435,6 +473,20 @@ module.exports = createClass({
this.renderGridLines(selectedGrid)
)
:
this.renderCannotShowOutlineText();
},
render() {
const { selectedGrid } = this.state;
return selectedGrid ?
dom.div(
{
className: "grid-outline",
},
this.renderOutline()
)
:
null;
},

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

@ -216,6 +216,7 @@ devtools.jar:
skin/images/gcli_sec_good.svg (themes/images/gcli_sec_good.svg)
skin/images/gcli_sec_moderate.svg (themes/images/gcli_sec_moderate.svg)
skin/images/globe.svg (themes/images/globe.svg)
skin/images/sad-face.svg (themes/images/sad-face.svg)
skin/images/tool-options.svg (themes/images/tool-options.svg)
skin/images/tool-webconsole.svg (themes/images/tool-webconsole.svg)
skin/images/tool-canvas.svg (themes/images/tool-canvas.svg)

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

@ -7,6 +7,11 @@
# The Layout Inspector may need to be enabled in about:config by setting
# devtools.layoutview.enabled to true.
# LOCALIZATION NOTE (layout.cannotShowGridOutline, layout.cannotSHowGridOutline.title):
# In the case where the grid outline cannot be effectively displayed.
layout.cannotShowGridOutline=Cannot show outline for this grid
layout.cannotShowGridOutline.title=The selected grids outline cannot effectively fit inside the layout panel for it to be usable.
# LOCALIZATION NOTE (layout.displayNumbersOnLines): Label of the display numbers on lines
# setting option in the CSS Grid pane.
layout.displayNumbersOnLines=Display numbers on lines

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

@ -0,0 +1,9 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="#D92215">
<path d="M8 14.5c-3.6 0-6.5-2.9-6.5-6.5S4.4 1.5 8 1.5s6.5 2.9 6.5 6.5-2.9 6.5-6.5 6.5zm0-12C5 2.5 2.5 5 2.5 8S5 13.5 8 13.5 13.5 11 13.5 8 11 2.5 8 2.5z"/>
<circle cx="5" cy="6" r="1" transform="translate(1 1)"/>
<circle cx="9" cy="6" r="1" transform="translate(1 1)"/>
<path d="M5.5 11c-.1 0-.2 0-.3-.1-.2-.1-.3-.4-.1-.7C6 9 7 8.5 8.1 8.5c1.7.1 2.8 1.7 2.8 1.8.2.2.1.5-.1.7-.2.1-.6 0-.7-.2 0 0-.9-1.3-2-1.3-.7 0-1.4.4-2.1 1.3-.2.2-.4.2-.5.2z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 772 B

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

@ -58,15 +58,6 @@
margin: 5px;
}
/**
* Grid Outline
*/
.grid-outline {
margin-top: 10px;
overflow: visible;
}
/**
* Grid Content
*/
@ -75,7 +66,7 @@
display: flex;
flex-wrap: wrap;
flex: 1;
margin-top: 10px;
margin: 5px 0;
}
.grid-container:first-child {
@ -86,8 +77,12 @@
* Grid Outline
*/
#grid-outline {
margin: 5px auto;
.grid-outline {
margin: 5px 0;
}
.grid-outline svg {
overflow: visible;
}
.grid-outline-border {
@ -114,6 +109,20 @@
stroke-width: 10;
}
.grid-outline-text {
display: flex;
align-items: center;
justify-content: center;
color: var(--theme-graphs-full-red);
}
.grid-outline-text-icon {
background: url("chrome://devtools/skin/images/sad-face.svg");
margin-inline-end: 5px;
width: 16px;
height: 16px;
}
/**
* Container when no grids are present
*/

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

@ -994,7 +994,20 @@ nsDocShellTreeOwner::HandleEvent(nsIDOMEvent* aEvent)
if (webBrowserChrome) {
nsCOMPtr<nsITabChild> tabChild = do_QueryInterface(webBrowserChrome);
if (tabChild) {
nsresult rv = tabChild->RemoteDropLinks(linksCount, links);
nsCOMPtr<nsIDOMDataTransfer> domDataTransfer;
dragEvent->GetDataTransfer(getter_AddRefs(domDataTransfer));
NS_ENSURE_TRUE(domDataTransfer, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsIDOMNode> domSourceNode;
domDataTransfer->GetMozSourceNode(getter_AddRefs(domSourceNode));
nsCOMPtr<nsINode> sourceNode = do_QueryInterface(domSourceNode);
nsCOMPtr<nsIPrincipal> triggeringPrincipal;
if (sourceNode) {
triggeringPrincipal = sourceNode->NodePrincipal();
} else {
triggeringPrincipal = NullPrincipal::Create();
}
nsresult rv = tabChild->RemoteDropLinks(linksCount, links,
triggeringPrincipal);
for (uint32_t i = 0; i < linksCount; i++) {
NS_RELEASE(links[i]);
}

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

@ -4,6 +4,7 @@
#include "nsISupports.idl"
interface nsIFrameLoader;
interface nsIPrincipal;
[scriptable, uuid(14e5a0cb-e223-4202-95e8-fe53275193ea)]
interface nsIBrowser : nsISupports
@ -23,9 +24,12 @@ interface nsIBrowser : nsISupports
*
* @param linksCount length of links
* @param links a flat array of url, name, and type for each link
* @param triggeringPrincipal a principal that initiated loading
* of the dropped links
*/
void dropLinks(in unsigned long linksCount,
[array, size_is(linksCount)] in wstring links);
[array, size_is(linksCount)] in wstring links,
in nsIPrincipal aTriggeringPrincipal);
/**
* Flags for controlling the behavior of swapBrowsers

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

@ -8,6 +8,7 @@
interface nsIContentFrameMessageManager;
interface nsIWebBrowserChrome3;
interface nsIPrincipal;
native CommandsArray(nsTArray<nsCString>);
[ref] native CommandsArrayRef(nsTArray<nsCString>);
@ -31,7 +32,8 @@ interface nsITabChild : nsISupports
in int32_t shellItemWidth, in int32_t shellItemHeight);
[noscript] void remoteDropLinks(in unsigned long linksCount,
[array, size_is(linksCount)] in nsIDroppedLinkItem links);
[array, size_is(linksCount)] in nsIDroppedLinkItem links,
in nsIPrincipal triggeringPrincipal);
readonly attribute uint64_t tabId;

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

@ -21,6 +21,7 @@ include protocol PFileDescriptorSet;
include protocol PIPCBlobInputStream;
include protocol PPaymentRequest;
include PBackgroundSharedTypes;
include DOMTypes;
include IPCBlob;
include IPCStream;
@ -195,7 +196,7 @@ parent:
*
* aLinks A flat array of url, name, and type for each link
*/
async DropLinks(nsString[] aLinks);
async DropLinks(nsString[] aLinks, PrincipalInfo aTriggeringPrincipalInfo);
async Event(RemoteDOMEvent aEvent);

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

@ -748,7 +748,9 @@ TabChild::RemoteSizeShellTo(int32_t aWidth, int32_t aHeight,
}
NS_IMETHODIMP
TabChild::RemoteDropLinks(uint32_t aLinksCount, nsIDroppedLinkItem** aLinks)
TabChild::RemoteDropLinks(uint32_t aLinksCount,
nsIDroppedLinkItem** aLinks,
nsIPrincipal* aTriggeringPrincipal)
{
nsTArray<nsString> linksArray;
nsresult rv = NS_OK;
@ -773,7 +775,9 @@ TabChild::RemoteDropLinks(uint32_t aLinksCount, nsIDroppedLinkItem** aLinks)
linksArray.AppendElement(tmp);
}
bool sent = SendDropLinks(linksArray);
PrincipalInfo triggeringPrincipalInfo;
PrincipalToPrincipalInfo(aTriggeringPrincipal, &triggeringPrincipalInfo);
bool sent = SendDropLinks(linksArray, triggeringPrincipalInfo);
return sent ? NS_OK : NS_ERROR_FAILURE;
}

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

@ -526,7 +526,8 @@ TabParent::RecvSizeShellTo(const uint32_t& aFlags, const int32_t& aWidth, const
}
mozilla::ipc::IPCResult
TabParent::RecvDropLinks(nsTArray<nsString>&& aLinks)
TabParent::RecvDropLinks(nsTArray<nsString>&& aLinks,
const PrincipalInfo& aTriggeringPrincipalInfo)
{
nsCOMPtr<nsIBrowser> browser = do_QueryInterface(mFrameElement);
if (browser) {
@ -535,7 +536,12 @@ TabParent::RecvDropLinks(nsTArray<nsString>&& aLinks)
for (uint32_t i = 0; i < aLinks.Length(); i++) {
links[i] = aLinks[i].get();
}
browser->DropLinks(aLinks.Length(), links.get());
nsCOMPtr<nsIPrincipal> triggeringPrincipal =
PrincipalInfoToPrincipal(aTriggeringPrincipalInfo);
if (nsContentUtils::IsSystemPrincipal(triggeringPrincipal)) {
return IPC_FAIL(this, "Invalid triggeringPrincipal");
}
browser->DropLinks(aLinks.Length(), links.get(), triggeringPrincipal);
}
return IPC_OK();
}

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

@ -161,7 +161,8 @@ public:
const int32_t& aShellItemWidth,
const int32_t& aShellItemHeight) override;
virtual mozilla::ipc::IPCResult RecvDropLinks(nsTArray<nsString>&& aLinks) override;
virtual mozilla::ipc::IPCResult RecvDropLinks(nsTArray<nsString>&& aLinks,
const PrincipalInfo& aTriggeringPrincipalInfo) override;
virtual mozilla::ipc::IPCResult RecvEvent(const RemoteDOMEvent& aEvent) override;

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

@ -260,7 +260,7 @@ js::RegExpCreate(JSContext* cx, HandleValue patternValue, HandleValue flagsValue
MutableHandleValue rval)
{
/* Step 1. */
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx));
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, GenericObject));
if (!regexp)
return false;
@ -450,7 +450,7 @@ js::regexp_construct(JSContext* cx, unsigned argc, Value* vp)
if (!GetPrototypeFromCallableConstructor(cx, args, &proto))
return false;
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, proto));
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, GenericObject, proto));
if (!regexp)
return false;
@ -509,7 +509,7 @@ js::regexp_construct(JSContext* cx, unsigned argc, Value* vp)
if (!GetPrototypeFromCallableConstructor(cx, args, &proto))
return false;
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, proto));
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, GenericObject, proto));
if (!regexp)
return false;
@ -542,7 +542,7 @@ js::regexp_construct_raw_flags(JSContext* cx, unsigned argc, Value* vp)
int32_t flags = int32_t(args[1].toNumber());
// Step 7.
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx));
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, GenericObject));
if (!regexp)
return false;

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

@ -9398,7 +9398,8 @@ Parser<ParseHandler, CharT>::newRegExp()
RegExpFlag flags = tokenStream.currentToken().regExpFlags();
Rooted<RegExpObject*> reobj(context);
reobj = RegExpObject::create(context, chars, length, flags, nullptr, &tokenStream, alloc);
reobj = RegExpObject::create(context, chars, length, flags, nullptr, &tokenStream, alloc,
TenuredObject);
if (!reobj)
return null();

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

@ -11979,6 +11979,8 @@ IonBuilder::jsop_delelem()
AbortReasonOr<Ok>
IonBuilder::jsop_regexp(RegExpObject* reobj)
{
MOZ_ASSERT(!IsInsideNursery(reobj));
MRegExp* regexp = MRegExp::New(alloc(), constraints(), reobj);
current->add(regexp);
current->push(regexp);

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

@ -6115,7 +6115,8 @@ JS_NewRegExpObject(JSContext* cx, const char* bytes, size_t length, unsigned fla
return nullptr;
RegExpObject* reobj = RegExpObject::create(cx, chars, length, RegExpFlag(flags),
nullptr, nullptr, cx->tempLifoAlloc());
nullptr, nullptr, cx->tempLifoAlloc(),
GenericObject);
return reobj;
}
@ -6125,7 +6126,8 @@ JS_NewUCRegExpObject(JSContext* cx, const char16_t* chars, size_t length, unsign
AssertHeapIsIdle();
CHECK_REQUEST(cx);
return RegExpObject::create(cx, chars, length, RegExpFlag(flags),
nullptr, nullptr, cx->tempLifoAlloc());
nullptr, nullptr, cx->tempLifoAlloc(),
GenericObject);
}
JS_PUBLIC_API(bool)

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

@ -52,13 +52,9 @@ JS_STATIC_ASSERT(StickyFlag == JSREG_STICKY);
JS_STATIC_ASSERT(UnicodeFlag == JSREG_UNICODE);
RegExpObject*
js::RegExpAlloc(JSContext* cx, HandleObject proto /* = nullptr */)
js::RegExpAlloc(JSContext* cx, NewObjectKind newKind, HandleObject proto /* = nullptr */)
{
// Note: RegExp objects are always allocated in the tenured heap. This is
// not strictly required, but simplifies embedding them in jitcode.
Rooted<RegExpObject*> regexp(cx);
regexp = NewObjectWithClassProto<RegExpObject>(cx, proto, TenuredObject);
Rooted<RegExpObject*> regexp(cx, NewObjectWithClassProto<RegExpObject>(cx, proto, newKind));
if (!regexp)
return nullptr;
@ -239,19 +235,19 @@ const Class RegExpObject::protoClass_ = {
RegExpObject*
RegExpObject::create(JSContext* cx, const char16_t* chars, size_t length, RegExpFlag flags,
const ReadOnlyCompileOptions* options, TokenStream* tokenStream,
LifoAlloc& alloc)
LifoAlloc& alloc, NewObjectKind newKind)
{
RootedAtom source(cx, AtomizeChars(cx, chars, length));
if (!source)
return nullptr;
return create(cx, source, flags, options, tokenStream, alloc);
return create(cx, source, flags, options, tokenStream, alloc, newKind);
}
RegExpObject*
RegExpObject::create(JSContext* cx, HandleAtom source, RegExpFlag flags,
const ReadOnlyCompileOptions* options, TokenStream* tokenStream,
LifoAlloc& alloc)
LifoAlloc& alloc, NewObjectKind newKind)
{
Maybe<CompileOptions> dummyOptions;
if (!tokenStream && !options) {
@ -269,7 +265,7 @@ RegExpObject::create(JSContext* cx, HandleAtom source, RegExpFlag flags,
if (!irregexp::ParsePatternSyntax(*tokenStream, alloc, source, flags & UnicodeFlag))
return nullptr;
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx));
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, newKind));
if (!regexp)
return nullptr;
@ -1342,10 +1338,9 @@ js::CloneRegExpObject(JSContext* cx, JSObject* obj_)
{
Rooted<RegExpObject*> regex(cx, &obj_->as<RegExpObject>());
// Unlike RegExpAlloc, all clones must use |regex|'s group. Allocate
// in the tenured heap to simplify embedding them in JIT code.
// Unlike RegExpAlloc, all clones must use |regex|'s group.
RootedObjectGroup group(cx, regex->group());
Rooted<RegExpObject*> clone(cx, NewObjectWithGroup<RegExpObject>(cx, group, TenuredObject));
Rooted<RegExpObject*> clone(cx, NewObjectWithGroup<RegExpObject>(cx, group, GenericObject));
if (!clone)
return nullptr;
clone->initPrivate(nullptr);
@ -1466,7 +1461,8 @@ js::XDRScriptRegExpObject(XDRState<mode>* xdr, MutableHandle<RegExpObject*> objp
if (xdr->hasOptions())
options = &xdr->options();
RegExpObject* reobj = RegExpObject::create(xdr->cx(), source, flags,
options, nullptr, xdr->lifoAlloc());
options, nullptr, xdr->lifoAlloc(),
TenuredObject);
if (!reobj)
return false;
@ -1490,7 +1486,8 @@ js::CloneScriptRegExpObject(JSContext* cx, RegExpObject& reobj)
cx->markAtom(source);
return RegExpObject::create(cx, source, reobj.getFlags(),
nullptr, nullptr, cx->tempLifoAlloc());
nullptr, nullptr, cx->tempLifoAlloc(),
TenuredObject);
}
JS_FRIEND_API(bool)

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

@ -46,7 +46,7 @@ class RegExpStatics;
namespace frontend { class TokenStream; }
extern RegExpObject*
RegExpAlloc(JSContext* cx, HandleObject proto = nullptr);
RegExpAlloc(JSContext* cx, NewObjectKind newKind, HandleObject proto = nullptr);
// |regexp| is under-typed because this function's used in the JIT.
extern JSObject*
@ -74,11 +74,13 @@ class RegExpObject : public NativeObject
static RegExpObject*
create(JSContext* cx, const char16_t* chars, size_t length, RegExpFlag flags,
const ReadOnlyCompileOptions* options, frontend::TokenStream* ts, LifoAlloc& alloc);
const ReadOnlyCompileOptions* options, frontend::TokenStream* ts, LifoAlloc& alloc,
NewObjectKind newKind);
static RegExpObject*
create(JSContext* cx, HandleAtom atom, RegExpFlag flags,
const ReadOnlyCompileOptions* options, frontend::TokenStream* ts, LifoAlloc& alloc);
const ReadOnlyCompileOptions* options, frontend::TokenStream* ts, LifoAlloc& alloc,
NewObjectKind newKind);
/*
* Compute the initial shape to associate with fresh RegExp objects,

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

@ -3047,7 +3047,8 @@ CloneObject(JSContext* cx, HandleNativeObject selfHostedObject)
RootedAtom source(cx, reobj.getSource());
MOZ_ASSERT(source->isPermanentAtom());
clone = RegExpObject::create(cx, source, reobj.getFlags(),
nullptr, nullptr, cx->tempLifoAlloc());
nullptr, nullptr, cx->tempLifoAlloc(),
TenuredObject);
} else if (selfHostedObject->is<DateObject>()) {
clone = JS::NewDateObject(cx, selfHostedObject->as<DateObject>().clippedTime());
} else if (selfHostedObject->is<BooleanObject>()) {

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

@ -2127,7 +2127,7 @@ JSStructuredCloneReader::startRead(MutableHandleValue vp)
return false;
RegExpObject* reobj = RegExpObject::create(context(), atom, flags, nullptr, nullptr,
context()->tempLifoAlloc());
context()->tempLifoAlloc(), GenericObject);
if (!reobj)
return false;
vp.setObject(*reobj);

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

@ -4728,7 +4728,7 @@ pref("layers.tiles.adjust", true);
// 0 -> full-tilt mode: Recomposite even if not transaction occured.
pref("layers.offmainthreadcomposition.frame-rate", -1);
#ifdef XP_MACOSX
#if defined(XP_MACOSX) || defined (OS_OPENBSD)
pref("layers.enable-tiles", true);
pref("layers.tile-width", 512);
pref("layers.tile-height", 512);

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

@ -1066,7 +1066,7 @@ public:
InterceptFailedOnStop(nsIStreamListener *arg, HttpBaseChannel *chan)
: mNext(arg)
, mChannel(chan) {}
NS_DECL_ISUPPORTS
NS_DECL_THREADSAFE_ISUPPORTS
NS_IMETHOD OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) override
{

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

@ -34,7 +34,8 @@ NS_IMPL_ISUPPORTS(nsHTTPCompressConv,
nsIStreamConverter,
nsIStreamListener,
nsIRequestObserver,
nsICompressConvStats)
nsICompressConvStats,
nsIThreadRetargetableStreamListener)
// nsFTPDirListingConv methods
nsHTTPCompressConv::nsHTTPCompressConv()
@ -51,6 +52,7 @@ nsHTTPCompressConv::nsHTTPCompressConv()
, mSkipCount(0)
, mFlags(0)
, mDecodedDataLength(0)
, mMutex("nsHTTPCompressConv")
{
LOG(("nsHttpCompresssConv %p ctor\n", this));
if (NS_IsMainThread()) {
@ -104,12 +106,12 @@ nsHTTPCompressConv::AsyncConvertData(const char *aFromType,
mMode = HTTP_COMPRESS_BROTLI;
}
LOG(("nsHttpCompresssConv %p AsyncConvertData %s %s mode %d\n",
this, aFromType, aToType, mMode));
this, aFromType, aToType, (CompressMode)mMode));
MutexAutoLock lock(mMutex);
// hook ourself up with the receiving listener.
mListener = aListener;
mAsyncConvContext = aCtxt;
return NS_OK;
}
@ -117,7 +119,12 @@ NS_IMETHODIMP
nsHTTPCompressConv::OnStartRequest(nsIRequest* request, nsISupports *aContext)
{
LOG(("nsHttpCompresssConv %p onstart\n", this));
return mListener->OnStartRequest(request, aContext);
nsCOMPtr<nsIStreamListener> listener;
{
MutexAutoLock lock(mMutex);
listener = mListener;
}
return listener->OnStartRequest(request, aContext);
}
NS_IMETHODIMP
@ -145,7 +152,7 @@ nsHTTPCompressConv::OnStopRequest(nsIRequest* request, nsISupports *aContext,
if (fpChannel && !isPending) {
fpChannel->ForcePending(true);
}
if (mBrotli && (mBrotli->mTotalOut == 0) && !BrotliStateIsStreamEnd(&mBrotli->mState)) {
if (mBrotli && (mBrotli->mTotalOut == 0) && !mBrotli->mBrotliStateIsStreamEnd) {
status = NS_ERROR_INVALID_CONTENT_ENCODING;
}
LOG(("nsHttpCompresssConv %p onstop brotlihandler rv %" PRIx32 "\n",
@ -154,7 +161,13 @@ nsHTTPCompressConv::OnStopRequest(nsIRequest* request, nsISupports *aContext,
fpChannel->ForcePending(false);
}
}
return mListener->OnStopRequest(request, aContext, status);
nsCOMPtr<nsIStreamListener> listener;
{
MutexAutoLock lock(mMutex);
listener = mListener;
}
return listener->OnStopRequest(request, aContext, status);
}
@ -189,10 +202,13 @@ nsHTTPCompressConv::BrotliHandler(nsIInputStream *stream, void *closure, const c
// brotli api is documented in brotli/dec/decode.h and brotli/dec/decode.c
LOG(("nsHttpCompresssConv %p brotlihandler decompress %" PRIuSIZE "\n", self, avail));
size_t totalOut = self->mBrotli->mTotalOut;
res = ::BrotliDecompressStream(
&avail, reinterpret_cast<const unsigned char **>(&dataIn),
&outSize, &outPtr, &self->mBrotli->mTotalOut, &self->mBrotli->mState);
&outSize, &outPtr, &totalOut, &self->mBrotli->mState);
outSize = kOutSize - outSize;
self->mBrotli->mTotalOut = totalOut;
self->mBrotli->mBrotliStateIsStreamEnd = BrotliStateIsStreamEnd(&self->mBrotli->mState);
LOG(("nsHttpCompresssConv %p brotlihandler decompress rv=%" PRIx32 " out=%" PRIuSIZE "\n",
self, static_cast<uint32_t>(res), outSize));
@ -458,7 +474,12 @@ nsHTTPCompressConv::OnDataAvailable(nsIRequest* request,
break;
default:
rv = mListener->OnDataAvailable(request, aContext, iStr, aSourceOffset, aCount);
nsCOMPtr<nsIStreamListener> listener;
{
MutexAutoLock lock(mMutex);
listener = mListener;
}
rv = listener->OnDataAvailable(request, aContext, iStr, aSourceOffset, aCount);
if (NS_FAILED (rv)) {
return rv;
}
@ -491,8 +512,13 @@ nsHTTPCompressConv::do_OnDataAvailable(nsIRequest* request,
mStream->ShareData(buffer, count);
nsresult rv = mListener->OnDataAvailable(request, context, mStream,
offset, count);
nsCOMPtr<nsIStreamListener> listener;
{
MutexAutoLock lock(mMutex);
listener = mListener;
}
nsresult rv = listener->OnDataAvailable(request, context, mStream,
offset, count);
// Make sure the stream no longer references |buffer| in case our listener
// is crazy enough to try to read from |mStream| after ODA.
@ -640,6 +666,22 @@ nsHTTPCompressConv::check_header(nsIInputStream *iStr, uint32_t streamLen, nsres
return streamLen;
}
NS_IMETHODIMP
nsHTTPCompressConv::CheckListenerChain()
{
nsCOMPtr<nsIThreadRetargetableStreamListener> listener;
{
MutexAutoLock lock(mMutex);
listener = do_QueryInterface(mListener);
}
if (!listener) {
return NS_ERROR_NO_INTERFACE;
}
return listener->CheckListenerChain();
}
} // namespace net
} // namespace mozilla

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

@ -9,8 +9,11 @@
#include "nsIStreamConverter.h"
#include "nsICompressConvStats.h"
#include "nsIThreadRetargetableStreamListener.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "mozilla/Atomics.h"
#include "mozilla/Mutex.h"
#include "zlib.h"
@ -57,6 +60,7 @@ public:
BrotliWrapper()
: mTotalOut(0)
, mStatus(NS_OK)
, mBrotliStateIsStreamEnd(false)
{
BrotliStateInit(&mState);
}
@ -65,9 +69,10 @@ public:
BrotliStateCleanup(&mState);
}
BrotliState mState;
size_t mTotalOut;
nsresult mStatus;
BrotliState mState;
Atomic<size_t, Relaxed> mTotalOut;
nsresult mStatus;
Atomic<bool, Relaxed> mBrotliStateIsStreamEnd;
nsIRequest *mRequest;
nsISupports *mContext;
@ -77,6 +82,7 @@ public:
class nsHTTPCompressConv
: public nsIStreamConverter
, public nsICompressConvStats
, public nsIThreadRetargetableStreamListener
{
public:
// nsISupports methods
@ -84,6 +90,7 @@ class nsHTTPCompressConv
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSICOMPRESSCONVSTATS
NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
// nsIStreamConverter methods
NS_DECL_NSISTREAMCONVERTER
@ -94,7 +101,7 @@ private:
virtual ~nsHTTPCompressConv ();
nsCOMPtr<nsIStreamListener> mListener; // this guy gets the converted data via his OnDataAvailable ()
CompressMode mMode;
Atomic<CompressMode, Relaxed> mMode;
unsigned char *mOutBuffer;
unsigned char *mInpBuffer;
@ -104,7 +111,6 @@ private:
nsAutoPtr<BrotliWrapper> mBrotli;
nsCOMPtr<nsISupports> mAsyncConvContext;
nsCOMPtr<nsIStringInputStream> mStream;
static nsresult
@ -115,18 +121,20 @@ private:
uint64_t aSourceOffset, const char *buffer,
uint32_t aCount);
bool mCheckHeaderDone;
bool mStreamEnded;
bool mStreamInitialized;
bool mDummyStreamInitialised;
bool mFailUncleanStops;
bool mCheckHeaderDone;
Atomic<bool> mStreamEnded;
bool mStreamInitialized;
bool mDummyStreamInitialised;
bool mFailUncleanStops;
z_stream d_stream;
unsigned mLen, hMode, mSkipCount, mFlags;
uint32_t check_header (nsIInputStream *iStr, uint32_t streamLen, nsresult *rv);
uint32_t mDecodedDataLength;
Atomic<uint32_t, Relaxed> mDecodedDataLength;
mutable mozilla::Mutex mMutex;
};
} // namespace net

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

@ -7145,6 +7145,26 @@
"n_buckets": 20,
"description": "Time (ms) it takes for checking if the pending pings are over-quota"
},
"TELEMETRY_PENDING_LOAD_MS": {
"record_in_processes": ["main"],
"alert_emails": ["telemetry-client-dev@mozilla.com", "chutten@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"high": 2000,
"n_buckets": 20,
"bug_numbers": [1033860],
"description": "Time (ms) it takes for loading pending pings from disk"
},
"TELEMETRY_ARCHIVE_LOAD_MS": {
"record_in_processes": ["main"],
"alert_emails": ["telemetry-client-dev@mozilla.com", "chutten@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"high": 2000,
"n_buckets": 20,
"bug_numbers": [1033860],
"description": "Time (ms) it takes for loading archived pings from disk"
},
"TELEMETRY_PING_SIZE_EXCEEDED_SEND": {
"record_in_processes": ["main", "content"],
"alert_emails": ["telemetry-client-dev@mozilla.com"],
@ -8107,7 +8127,7 @@
"alert_emails": ["bsmedberg@mozilla.com"]
},
"PLUGINS_INFOBAR_SHOWN": {
"record_in_processes": ["main", "content"],
"record_in_processes": ["main"],
"releaseChannelCollection": "opt-out",
"expires_in_version": "60",
"kind": "boolean",
@ -8116,7 +8136,7 @@
"alert_emails": ["bsmedberg@mozilla.com"]
},
"PLUGINS_INFOBAR_BLOCK": {
"record_in_processes": ["main", "content"],
"record_in_processes": ["main"],
"releaseChannelCollection": "opt-out",
"expires_in_version": "60",
"kind": "boolean",
@ -8125,7 +8145,7 @@
"alert_emails": ["bsmedberg@mozilla.com"]
},
"PLUGINS_INFOBAR_ALLOW": {
"record_in_processes": ["main", "content"],
"record_in_processes": ["main"],
"releaseChannelCollection": "opt-out",
"expires_in_version": "60",
"kind": "boolean",
@ -8133,6 +8153,15 @@
"bug_numbers": [902075, 1345894],
"alert_emails": ["bsmedberg@mozilla.com"]
},
"PLUGINS_INFOBAR_DISMISSED": {
"record_in_processes": ["main"],
"releaseChannelCollection": "opt-out",
"expires_in_version": "60",
"kind": "boolean",
"description": "Count the number of times the user explicitly dismisses the hidden-plugin infobar without choosing allow or continue-blocking.",
"bug_numbers": [1368060],
"alert_emails": ["bsmedberg@mozilla.com"]
},
"POPUP_NOTIFICATION_STATS": {
"record_in_processes": ["main", "content"],
"releaseChannelCollection": "opt-out",

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

@ -137,6 +137,13 @@ this.TelemetryController = Object.freeze({
PREF_SERVER,
}),
/**
* Used only for testing purposes.
*/
testAssemblePing(aType, aPayload, aOptions) {
return Impl.assemblePing(aType, aPayload, aOptions);
},
/**
* Used only for testing purposes.
*/

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

@ -221,6 +221,8 @@ const DEFAULT_ENVIRONMENT_PREFS = new Map([
["network.proxy.ssl", {what: RECORD_PREF_STATE}],
["pdfjs.disabled", {what: RECORD_PREF_VALUE}],
["places.history.enabled", {what: RECORD_PREF_VALUE}],
["plugins.remember_infobar_dismissal", {what: RECORD_PREF_VALUE}],
["plugins.show_infobar", {what: RECORD_PREF_VALUE}],
["privacy.trackingprotection.enabled", {what: RECORD_PREF_VALUE}],
["privacy.donottrackheader.enabled", {what: RECORD_PREF_VALUE}],
["security.mixed_content.block_active_content", {what: RECORD_PREF_VALUE}],

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

@ -674,9 +674,6 @@ var Impl = {
_logger: null,
_prevValues: {},
_slowSQLStartup: {},
_hasWindowRestoredObserver: false,
_hasXulWindowVisibleObserver: false,
_hasActiveTicksObservers: false,
// The activity state for the user. If false, don't count the next
// active tick. Otherwise, increment the active ticks as usual.
_isUserActive: true,
@ -739,6 +736,18 @@ var Impl = {
// We save whether the "new-profile" ping was sent yet, to
// survive profile refresh and migrations.
_newProfilePingSent: false,
// Keep track of the active observers
_observedTopics: new Set(),
addObserver(aTopic) {
Services.obs.addObserver(this, aTopic)
this._observedTopics.add(aTopic)
},
removeObserver(aTopic) {
Services.obs.removeObserver(this, aTopic)
this._observedTopics.delete(aTopic)
},
get _log() {
if (!this._logger) {
@ -1448,41 +1457,26 @@ var Impl = {
* chrome process.
*/
attachEarlyObservers() {
Services.obs.addObserver(this, "sessionstore-windows-restored");
this.addObserver("sessionstore-windows-restored");
if (AppConstants.platform === "android") {
Services.obs.addObserver(this, "application-background");
this.addObserver("application-background");
}
Services.obs.addObserver(this, "xul-window-visible");
this._hasWindowRestoredObserver = true;
this._hasXulWindowVisibleObserver = true;
this.addObserver("xul-window-visible");
// Attach the active-ticks related observers.
Services.obs.addObserver(this, "user-interaction-active");
Services.obs.addObserver(this, "user-interaction-inactive");
this._hasActiveTicksObservers = true;
this.addObserver("user-interaction-active");
this.addObserver("user-interaction-inactive");
},
attachObservers: function attachObservers() {
if (!this._initialized)
return;
Services.obs.addObserver(this, "idle-daily");
this.addObserver("idle-daily");
if (Telemetry.canRecordExtended) {
Services.obs.addObserver(this, TOPIC_CYCLE_COLLECTOR_BEGIN);
this.addObserver(TOPIC_CYCLE_COLLECTOR_BEGIN);
}
},
detachObservers: function detachObservers() {
if (!this._initialized)
return;
Services.obs.removeObserver(this, "idle-daily");
try {
// Tests may flip Telemetry.canRecordExtended on and off. Just try to remove this
// observer and catch if it fails because the observer was not added.
Services.obs.removeObserver(this, TOPIC_CYCLE_COLLECTOR_BEGIN);
} catch (e) {
this._log.warn("detachObservers - Failed to remove " + TOPIC_CYCLE_COLLECTOR_BEGIN, e);
}
},
/**
* Lightweight init function, called as soon as Firefox starts.
@ -1616,7 +1610,7 @@ var Impl = {
return;
}
Services.obs.addObserver(this, "content-child-shutdown");
this.addObserver("content-child-shutdown");
cpml.addMessageListener(MESSAGE_TELEMETRY_GET_CHILD_THREAD_HANGS, this);
cpml.addMessageListener(MESSAGE_TELEMETRY_GET_CHILD_USS, this);
@ -1856,24 +1850,17 @@ var Impl = {
/**
* Do some shutdown work that is common to all process types.
*/
uninstall: function uninstall() {
this.detachObservers();
if (this._hasWindowRestoredObserver) {
Services.obs.removeObserver(this, "sessionstore-windows-restored");
this._hasWindowRestoredObserver = false;
}
if (this._hasXulWindowVisibleObserver) {
Services.obs.removeObserver(this, "xul-window-visible");
this._hasXulWindowVisibleObserver = false;
}
if (AppConstants.platform === "android") {
Services.obs.removeObserver(this, "application-background");
}
if (this._hasActiveTicksObservers) {
Services.obs.removeObserver(this, "user-interaction-active");
Services.obs.removeObserver(this, "user-interaction-inactive");
this._hasActiveTicksObservers = false;
uninstall() {
for (let topic of this._observedTopics) {
try {
// Tests may flip Telemetry.canRecordExtended on and off. It can be the case
// that the observer TOPIC_CYCLE_COLLECTOR_BEGIN was not added.
this.removeObserver(topic);
} catch (e) {
this._log.warn("uninstall - Failed to remove " + topic, e);
}
}
GCTelemetry.shutdown();
},
@ -1977,7 +1964,6 @@ var Impl = {
switch (aTopic) {
case "content-child-shutdown":
// content-child-shutdown is only registered for content processes.
Services.obs.removeObserver(this, "content-child-shutdown");
this.uninstall();
Telemetry.flushBatchedChildTelemetry();
this.sendContentProcessPing(REASON_SAVED_SESSION);
@ -1991,8 +1977,7 @@ var Impl = {
}
break;
case "xul-window-visible":
Services.obs.removeObserver(this, "xul-window-visible");
this._hasXulWindowVisibleObserver = false;
this.removeObserver("xul-window-visible");
var counters = processInfo.getCounters();
if (counters) {
[this._startupIO.startupWindowVisibleReadBytes,
@ -2000,8 +1985,7 @@ var Impl = {
}
break;
case "sessionstore-windows-restored":
Services.obs.removeObserver(this, "sessionstore-windows-restored");
this._hasWindowRestoredObserver = false;
this.removeObserver("sessionstore-windows-restored");
// Check whether debugger was attached during startup
let debugService = Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2);
gWasDebuggerAttached = debugService.isDebuggerAttached;

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

@ -17,6 +17,7 @@ Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://gre/modules/Services.jsm", this);
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
Cu.import("resource://gre/modules/osfile.jsm", this);
Cu.import("resource://gre/modules/TelemetryStopwatch.jsm", this);
Cu.import("resource://gre/modules/TelemetryUtils.jsm", this);
Cu.import("resource://gre/modules/Promise.jsm", this);
Cu.import("resource://gre/modules/Preferences.jsm", this);
@ -169,6 +170,18 @@ this.TelemetryStorage = {
return TelemetryStorageImpl.loadArchivedPing(id);
},
/**
* Remove an archived ping from disk.
*
* @param {string} id The ping's id.
* @param {number} timestampCreated The ping's creation timestamp.
* @param {string} type The ping's type.
* @return {promise<object>} Promise that is resolved when the ping is removed.
*/
removeArchivedPing(id, timestampCreated, type) {
return TelemetryStorageImpl._removeArchivedPing(id, timestampCreated, type);
},
/**
* Get a list of info on the archived pings.
* This will scan the archive directory and grab basic data about the existing
@ -689,8 +702,10 @@ var TelemetryStorageImpl = {
* @return {promise<object>} Promise that is resolved with the ping data.
*/
async loadArchivedPing(id) {
TelemetryStopwatch.start("TELEMETRY_ARCHIVE_LOAD_MS");
const data = this._archivedPings.get(id);
if (!data) {
TelemetryStopwatch.cancel("TELEMETRY_ARCHIVE_LOAD_MS");
this._log.trace("loadArchivedPing - no ping with id: " + id);
return Promise.reject(new Error("TelemetryStorage.loadArchivedPing - no ping with id " + id));
}
@ -705,25 +720,31 @@ var TelemetryStorageImpl = {
Telemetry.getHistogramById("TELEMETRY_DISCARDED_ARCHIVED_PINGS_SIZE_MB")
.add(Math.floor(fileSize / 1024 / 1024));
Telemetry.getHistogramById("TELEMETRY_PING_SIZE_EXCEEDED_ARCHIVED").add();
TelemetryStopwatch.cancel("TELEMETRY_ARCHIVE_LOAD_MS");
await OS.File.remove(path, {ignoreAbsent: true});
throw new Error("loadArchivedPing - exceeded the maximum ping size: " + fileSize);
}
};
let ping;
try {
// Try to load a compressed version of the archived ping first.
this._log.trace("loadArchivedPing - loading ping from: " + pathCompressed);
await checkSize(pathCompressed);
return await this.loadPingFile(pathCompressed, /* compressed*/ true);
ping = await this.loadPingFile(pathCompressed, /* compressed*/ true);
} catch (ex) {
if (!ex.becauseNoSuchFile) {
TelemetryStopwatch.cancel("TELEMETRY_ARCHIVE_LOAD_MS");
throw ex;
}
// If that fails, look for the uncompressed version.
this._log.trace("loadArchivedPing - compressed ping not found, loading: " + path);
await checkSize(path);
return await this.loadPingFile(path, /* compressed*/ false);
ping = await this.loadPingFile(path, /* compressed*/ false);
}
TelemetryStopwatch.finish("TELEMETRY_ARCHIVE_LOAD_MS");
return ping;
},
/**
@ -1318,8 +1339,10 @@ var TelemetryStorageImpl = {
async loadPendingPing(id) {
this._log.trace("loadPendingPing - id: " + id);
TelemetryStopwatch.start("TELEMETRY_PENDING_LOAD_MS");
let info = this._pendingPings.get(id);
if (!info) {
TelemetryStopwatch.cancel("TELEMETRY_PENDING_LOAD_MS");
this._log.trace("loadPendingPing - unknown id " + id);
throw new Error("TelemetryStorage.loadPendingPing - no ping with id " + id);
}
@ -1330,6 +1353,7 @@ var TelemetryStorageImpl = {
fileSize = (await OS.File.stat(info.path)).size;
} catch (e) {
if (!(e instanceof OS.File.Error) || !e.becauseNoSuchFile) {
TelemetryStopwatch.cancel("TELEMETRY_PENDING_LOAD_MS");
throw e;
}
// Fall through and let |loadPingFile| report the error.
@ -1341,6 +1365,7 @@ var TelemetryStorageImpl = {
Telemetry.getHistogramById("TELEMETRY_DISCARDED_PENDING_PINGS_SIZE_MB")
.add(Math.floor(fileSize / 1024 / 1024));
Telemetry.getHistogramById("TELEMETRY_PING_SIZE_EXCEEDED_PENDING").add();
TelemetryStopwatch.cancel("TELEMETRY_PENDING_LOAD_MS");
throw new Error("loadPendingPing - exceeded the maximum ping size: " + fileSize);
}
@ -1355,12 +1380,15 @@ var TelemetryStorageImpl = {
} else if (e instanceof PingParseError) {
Telemetry.getHistogramById("TELEMETRY_PENDING_LOAD_FAILURE_PARSE").add();
}
TelemetryStopwatch.cancel("TELEMETRY_PENDING_LOAD_MS");
// Remove the ping from the cache, so we don't try to load it again.
this._pendingPings.delete(id);
// Then propagate the rejection.
throw e;
}
TelemetryStopwatch.finish("TELEMETRY_PENDING_LOAD_MS");
return ping;
},

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

@ -0,0 +1,65 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://gre/modules/TelemetryController.jsm", this);
Cu.import("resource://gre/modules/TelemetrySession.jsm", this);
Cu.import("resource://gre/modules/TelemetryStorage.jsm", this);
Cu.import("resource://gre/modules/Services.jsm", this);
Cu.import("resource://gre/modules/TelemetryUtils.jsm", this);
const PING_TYPE_MAIN = "main";
const REASON_GATHER_PAYLOAD = "gather-payload";
function getPing() {
TelemetrySession.earlyInit(true);
const payload = TelemetrySession.getPayload(REASON_GATHER_PAYLOAD);
const options = {addClientId: true, addEnvironment: true};
return TelemetryController.testAssemblePing(PING_TYPE_MAIN, payload, options);
}
// Setting up test environment.
add_task(function* test_setup() {
do_get_profile();
});
// Testing whether correct values are being recorded in
// "TELEMETRY_PENDING_LOAD_MS" histogram.
add_task(function* test_pendingLoadTime() {
TelemetryStorage.reset();
var ping = getPing();
var h = Telemetry.getHistogramById("TELEMETRY_PENDING_LOAD_MS");
var initialSum = h.snapshot().sum;
TelemetryStorage.addPendingPing(ping).then(() => {
TelemetryStorage.loadPendingPing(ping.id).then(() => {
TelemetryStorage.removePendingPing(ping.id);
Assert.ok(h.snapshot().sum - initialSum > 0,
"Value must be inserted into the histogram.");
});
});
});
// Testing whether correct values are being recorded in
// "TELEMETRY_ARCHIVE_LOAD_MS" histogram.
add_task(function* test_archiveLoadTime() {
TelemetryStorage.reset();
var ping = getPing();
var creationDate = new Date(ping.creationDate);
var h = Telemetry.getHistogramById("TELEMETRY_ARCHIVE_LOAD_MS");
var initialSum = h.snapshot().sum;
TelemetryStorage.saveArchivedPing(ping).then(() => {
TelemetryStorage.loadArchivedPing(ping.id).then(() => {
TelemetryStorage.removeArchivedPing(ping.id, creationDate, ping.type);
Assert.ok(h.snapshot().sum - initialSum > 0,
"Value must be inserted into the histogram.");
});
});
});

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

@ -30,6 +30,7 @@ generated-files =
[test_MigratePendingPings.js]
[test_TelemetryHistograms.js]
[test_TelemetryStorage.js]
[test_SubsessionChaining.js]
tags = addons
[test_TelemetryEnvironment.js]

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

@ -1478,6 +1478,7 @@
<method name="dropLinks">
<parameter name="aLinksCount"/>
<parameter name="aLinks"/>
<parameter name="aTriggeringPrincipal"/>
<body><![CDATA[
if (!this.droppedLinkHandler) {
return false;
@ -1490,7 +1491,7 @@
type: aLinks[i + 2],
});
}
this.droppedLinkHandler(null, links);
this.droppedLinkHandler(null, links, aTriggeringPrincipal);
return true;
]]></body>
</method>
@ -1592,7 +1593,18 @@
}
if (links.length) {
this.droppedLinkHandler(event, links);
// Bug 1368481: mozSourceNode is null if the drag event originated
// in an external application - needs better fallback!
let triggeringPrincipal;
let sourceNode = event.dataTransfer.mozSourceNode;
if (sourceNode) {
triggeringPrincipal = sourceNode.nodePrincipal;
} else {
var secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"].
getService(Components.interfaces.nsIScriptSecurityManager);
triggeringPrincipal = secMan.getSystemPrincipal();
}
this.droppedLinkHandler(event, links, triggeringPrincipal);
}
]]>
</handler>

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

@ -74,7 +74,7 @@ button {
.nav > button {
width: 3rem;
height: var(--date-picker-item-height);
filter: url("chrome://global/skin/filters.svg#fill");
-moz-context-properties: fill;
fill: var(--button-font-color);
}
@ -88,12 +88,12 @@ button {
.nav > button.prev,
.nav > button.next:dir(rtl) {
background: url("chrome://global/skin/icons/calendar-arrows.svg#left") no-repeat 50% 50%;
background: url("chrome://global/skin/icons/calendar-arrow-left.svg") no-repeat 50% 50%;
}
.nav > button.next,
.nav > button.prev:dir(rtl) {
background: url("chrome://global/skin/icons/calendar-arrows.svg#right") no-repeat 50% 50%;
background: url("chrome://global/skin/icons/calendar-arrow-right.svg") no-repeat 50% 50%;
}
.month-year-container {
@ -133,13 +133,13 @@ button.month-year::after {
content: "";
width: 2.6rem;
height: 1.6rem;
background: url("chrome://global/skin/icons/spinner-arrows.svg#down") no-repeat 50% 50%;
filter: url("chrome://global/skin/filters.svg#fill");
background: url("chrome://global/skin/icons/spinner-arrow-down.svg") no-repeat 50% 50%;
-moz-context-properties: fill;
fill: var(--button-font-color);
}
button.month-year.active::after {
background: url("chrome://global/skin/icons/spinner-arrows.svg#up") no-repeat 50% 50%;
background: url("chrome://global/skin/icons/spinner-arrow-up.svg") no-repeat 50% 50%;
}
.month-year-view {
@ -287,7 +287,7 @@ button.month-year.active::after {
.spinner-container > button {
height: var(--spinner-button-height);
filter: url("chrome://global/skin/filters.svg#fill");
-moz-context-properties: fill;
fill: var(--button-font-color);
}
@ -300,11 +300,11 @@ button.month-year.active::after {
}
.spinner-container > button.up {
background: url("chrome://global/skin/icons/spinner-arrows.svg#up") no-repeat 50% 50%;
background: url("chrome://global/skin/icons/spinner-arrow-up.svg") no-repeat 50% 50%;
}
.spinner-container > button.down {
background: url("chrome://global/skin/icons/spinner-arrows.svg#down") no-repeat 50% 50%;
background: url("chrome://global/skin/icons/spinner-arrow-down.svg") no-repeat 50% 50%;
}
.spinner-container.hide-buttons > button {

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

@ -0,0 +1,7 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="14" height="14" viewBox="0 0 14 14">
<path fill="context-fill" d="M9.2 0L11 1.7 5.5 7 11 12.3 9.2 14 2 7"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 381 B

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

@ -0,0 +1,7 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="14" height="14" viewBox="0 0 14 14">
<path fill="context-fill" d="M4.8 14L3 12.3 8.5 7 3 1.7 4.8 0 12 7"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 380 B

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

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
<style>
path:not(:target) {
display: none;
}
</style>
<path id="right" d="M4.8 14L3 12.3 8.5 7 3 1.7 4.8 0 12 7"/>
<path id="left" d="M9.2 0L11 1.7 5.5 7 11 12.3 9.2 14 2 7"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 540 B

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

@ -0,0 +1,7 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="10" height="6" viewBox="0 0 10 6">
<path fill="context-fill" d="M0 1l1-1 4 4 4-4 1 1-5 5"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 365 B

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

@ -0,0 +1,7 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="10" height="6" viewBox="0 0 10 6">
<path fill="context-fill" d="M0 5l1 1 4-4 4 4 1-1-5-5"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 365 B

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

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="6" viewBox="0 0 10 6">
<style>
path:not(:target) {
display: none;
}
</style>
<path id="down" d="M0 1l1-1 4 4 4-4 1 1-5 5"/>
<path id="up" d="M0 5l1 1 4-4 4 4 1-1-5-5"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 508 B

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

@ -26,14 +26,16 @@ toolkit.jar:
skin/classic/global/filters.svg (../../shared/filters.svg)
skin/classic/global/passwordmgr.css (../../shared/passwordmgr.css)
skin/classic/global/scale.css (../../shared/scale.css)
skin/classic/global/icons/calendar-arrows.svg (../../shared/icons/calendar-arrows.svg)
skin/classic/global/icons/calendar-arrow-left.svg (../../shared/icons/calendar-arrow-left.svg)
skin/classic/global/icons/calendar-arrow-right.svg (../../shared/icons/calendar-arrow-right.svg)
skin/classic/global/icons/find-arrows.svg (../../shared/icons/find-arrows.svg)
skin/classic/global/icons/info.svg (../../shared/incontent-icons/info.svg)
skin/classic/global/icons/input-clear.svg (../../shared/icons/input-clear.svg)
skin/classic/global/icons/loading.png (../../shared/icons/loading.png)
skin/classic/global/icons/loading@2x.png (../../shared/icons/loading@2x.png)
skin/classic/global/icons/search-textbox.svg (../../shared/icons/search-textbox.svg)
skin/classic/global/icons/spinner-arrows.svg (../../shared/icons/spinner-arrows.svg)
skin/classic/global/icons/spinner-arrow-down.svg (../../shared/icons/spinner-arrow-down.svg)
skin/classic/global/icons/spinner-arrow-up.svg (../../shared/icons/spinner-arrow-up.svg)
skin/classic/global/icons/menubutton-dropmarker.svg (../../shared/icons/menubutton-dropmarker.svg)
skin/classic/global/icons/warning.svg (../../shared/incontent-icons/warning.svg)
skin/classic/global/icons/blocked.svg (../../shared/incontent-icons/blocked.svg)