Merge inbound to m-c. a=merge
|
@ -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 grid’s 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)
|
||||
|
|