mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-18 15:55:36 +00:00
Merge mozilla-central to inbound a=merge on a CLOSED TREE
This commit is contained in:
commit
e6104a10ba
@ -1092,8 +1092,12 @@
|
||||
// overflowed.
|
||||
this.arrowScrollbox._updateScrollButtonsDisabledState();
|
||||
|
||||
// Preload the next about:newtab if there isn't one already.
|
||||
gBrowser._createPreloadBrowser();
|
||||
// If this browser isn't lazy (indicating it's probably created by
|
||||
// session restore), preload the next about:newtab if we don't
|
||||
// already have a preloaded browser.
|
||||
if (tab.linkedPanel) {
|
||||
gBrowser._createPreloadBrowser();
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -97,3 +97,4 @@ skip-if = !healthreport || !telemetry || (os == 'linux' && debug) || (os == 'and
|
||||
run-if = nightly_build # Containers is enabled only on Nightly
|
||||
[browser_fluent.js]
|
||||
[browser_hometab_restore_defaults.js]
|
||||
skip-if = debug #Bug 1517966
|
||||
|
@ -260,7 +260,8 @@ class UrlbarView {
|
||||
this.panel.setAttribute("width", width);
|
||||
|
||||
// Subtract two pixels for left and right borders on the panel.
|
||||
this._mainContainer.style.maxWidth = (width - 2) + "px";
|
||||
let contentWidth = width - 2;
|
||||
this._mainContainer.style.maxWidth = contentWidth + "px";
|
||||
|
||||
// Keep the popup items' site icons aligned with the input's identity
|
||||
// icon if it's not too far from the edge of the window. We define
|
||||
@ -289,10 +290,12 @@ class UrlbarView {
|
||||
|
||||
this.panel.style.setProperty("--item-padding-start", Math.round(start) + "px");
|
||||
this.panel.style.setProperty("--item-padding-end", Math.round(endOffset) + "px");
|
||||
contentWidth -= start + endOffset;
|
||||
} else {
|
||||
this.panel.style.removeProperty("--item-padding-start");
|
||||
this.panel.style.removeProperty("--item-padding-end");
|
||||
}
|
||||
this.panel.style.setProperty("--item-content-width", Math.round(contentWidth) + "px");
|
||||
}
|
||||
|
||||
_createRow(resultIndex) {
|
||||
|
@ -107,6 +107,15 @@
|
||||
background-image: url(chrome://browser/skin/tab.svg);
|
||||
}
|
||||
|
||||
.urlbarView-title {
|
||||
display: inline-block;
|
||||
vertical-align: text-bottom;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
max-width: calc(var(--item-content-width) * .7 - 2 * (16px + @urlbarViewIconMarginEnd@));
|
||||
}
|
||||
|
||||
.urlbarView-secondary::before {
|
||||
content: "\2014";
|
||||
color: var(--panel-disabled-color);
|
||||
|
@ -12,6 +12,7 @@
|
||||
* Components
|
||||
*/
|
||||
@import "resource://devtools/client/aboutdebugging-new/src/components/App.css";
|
||||
@import "resource://devtools/client/aboutdebugging-new/src/components/ProfilerDialog.css";
|
||||
@import "resource://devtools/client/aboutdebugging-new/src/components/RuntimePage.css";
|
||||
@import "resource://devtools/client/aboutdebugging-new/src/components/connect/ConnectPage.css";
|
||||
@import "resource://devtools/client/aboutdebugging-new/src/components/connect/ConnectSteps.css";
|
||||
|
@ -13,12 +13,14 @@ const {
|
||||
ADB_ADDON_UNINSTALL_FAILURE,
|
||||
ADB_ADDON_STATUS_UPDATED,
|
||||
DEBUG_TARGET_COLLAPSIBILITY_UPDATED,
|
||||
HIDE_PROFILER_DIALOG,
|
||||
NETWORK_LOCATIONS_UPDATED,
|
||||
PAGE_TYPES,
|
||||
SELECT_PAGE_FAILURE,
|
||||
SELECT_PAGE_START,
|
||||
SELECT_PAGE_SUCCESS,
|
||||
SELECTED_RUNTIME_ID_UPDATED,
|
||||
SHOW_PROFILER_DIALOG,
|
||||
USB_RUNTIMES_SCAN_START,
|
||||
USB_RUNTIMES_SCAN_SUCCESS,
|
||||
} = require("../constants");
|
||||
@ -51,6 +53,11 @@ function selectPage(page, runtimeId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop showing the profiler dialog if we are navigating to another page.
|
||||
if (getState().ui.showProfilerDialog) {
|
||||
await dispatch({ type: HIDE_PROFILER_DIALOG });
|
||||
}
|
||||
|
||||
// Stop watching current runtime, if currently on a RUNTIME page.
|
||||
if (currentPage === PAGE_TYPES.RUNTIME) {
|
||||
const currentRuntimeId = getState().runtimes.selectedRuntimeId;
|
||||
@ -93,6 +100,14 @@ function removeNetworkLocation(location) {
|
||||
};
|
||||
}
|
||||
|
||||
function showProfilerDialog() {
|
||||
return { type: SHOW_PROFILER_DIALOG };
|
||||
}
|
||||
|
||||
function hideProfilerDialog() {
|
||||
return { type: HIDE_PROFILER_DIALOG };
|
||||
}
|
||||
|
||||
function updateAdbAddonStatus(adbAddonStatus) {
|
||||
return { type: ADB_ADDON_STATUS_UPDATED, adbAddonStatus };
|
||||
}
|
||||
@ -147,10 +162,12 @@ function scanUSBRuntimes() {
|
||||
|
||||
module.exports = {
|
||||
addNetworkLocation,
|
||||
hideProfilerDialog,
|
||||
installAdbAddon,
|
||||
removeNetworkLocation,
|
||||
scanUSBRuntimes,
|
||||
selectPage,
|
||||
showProfilerDialog,
|
||||
uninstallAdbAddon,
|
||||
updateAdbAddonStatus,
|
||||
updateDebugTargetCollapsibility,
|
||||
|
@ -34,7 +34,10 @@
|
||||
--error-50: #ff0039;
|
||||
--error-60: #d70022;
|
||||
--highlight-50: #0a84ff;
|
||||
--grey-20: #ededf0;
|
||||
--grey-30: #d7d7db; /* for ui, no special semantic */
|
||||
--grey-90-a60: rgba(12, 12, 13, 0.6);
|
||||
--grey-90-a80: rgba(12, 12, 13, 0.8);
|
||||
--white-100: #fff; /* for ui, no special semantic */
|
||||
|
||||
/* Global layout vars */
|
||||
@ -264,6 +267,26 @@ Form controls
|
||||
height: calc(var(--base-unit) * 6);
|
||||
}
|
||||
|
||||
/* ghost button. icon button with no background from Photon guidelines */
|
||||
.ghost-button {
|
||||
border: none;
|
||||
border-radius: calc(var(--base-unit) / 2);
|
||||
fill: var(--grey-90-a80);
|
||||
height: calc(var(--base-unit) * 8);
|
||||
padding: calc(var(--base-unit) * 2);
|
||||
width: calc(var(--base-unit) * 8);
|
||||
|
||||
-moz-context-properties: fill;
|
||||
}
|
||||
|
||||
.ghost-button:hover {
|
||||
background-color: var(--grey-30);
|
||||
}
|
||||
|
||||
.ghost-button:active {
|
||||
background-color: var(--grey-40);
|
||||
}
|
||||
|
||||
/* standard inputs */
|
||||
.default-input {
|
||||
line-height: unset;
|
||||
|
@ -0,0 +1,55 @@
|
||||
/* 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/. */
|
||||
|
||||
.profiler-dialog__frame {
|
||||
border: none;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/*
|
||||
* The current layout of the dialog header is
|
||||
*
|
||||
* +-----------------------------+---+
|
||||
* | dialog title (auto) | X |
|
||||
* +-----------------------------+---+
|
||||
*/
|
||||
.profiler-dialog__header {
|
||||
align-items: center;
|
||||
background-color: var(--grey-20);
|
||||
display: grid;
|
||||
grid-template-columns: 1fr max-content;
|
||||
padding: var(--base-unit);
|
||||
}
|
||||
|
||||
.profiler-dialog__header__title {
|
||||
margin: 0;
|
||||
margin-inline-start: calc(var(--base-unit) * 2);
|
||||
|
||||
/* Reset <h1> styles */
|
||||
font-size: 15px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.profiler-dialog__inner {
|
||||
background-color: var(--white-100);
|
||||
display: grid;
|
||||
height: calc(var(--base-unit) * 150); /* 600px */
|
||||
grid-template-rows: max-content auto;
|
||||
max-height: calc(100% - calc(var(--base-unit) * 25)); /* 100% - 100px */
|
||||
position: fixed;
|
||||
width: calc(var(--base-unit) * 150); /* 600px */
|
||||
}
|
||||
|
||||
.profiler-dialog__mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: var(--grey-90-a60);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
|
||||
const FluentReact = require("devtools/client/shared/vendor/fluent-react");
|
||||
const Localized = createFactory(FluentReact.Localized);
|
||||
|
||||
const Actions = require("../actions/index");
|
||||
const Types = require("../types/index");
|
||||
|
||||
/**
|
||||
* This component a modal dialog containing the performance profiler UI.
|
||||
*/
|
||||
class ProfilerDialog extends PureComponent {
|
||||
static get propTypes() {
|
||||
return {
|
||||
runtimeDetails: Types.runtimeDetails.isRequired,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.props.dispatch(Actions.hideProfilerDialog());
|
||||
}
|
||||
|
||||
render() {
|
||||
const { clientWrapper } = this.props.runtimeDetails;
|
||||
|
||||
return dom.div(
|
||||
{
|
||||
className: "profiler-dialog__mask js-profiler-dialog-mask",
|
||||
onClick: () => this.hide(),
|
||||
},
|
||||
dom.article(
|
||||
{
|
||||
className: "profiler-dialog__inner js-profiler-dialog",
|
||||
onClick: e => e.stopPropagation(),
|
||||
},
|
||||
dom.header(
|
||||
{
|
||||
className: "profiler-dialog__header",
|
||||
},
|
||||
Localized(
|
||||
{
|
||||
id: "about-debugging-profiler-dialog-title",
|
||||
},
|
||||
dom.h1(
|
||||
{
|
||||
className: "profiler-dialog__header__title",
|
||||
},
|
||||
"Performance Profiler",
|
||||
)
|
||||
),
|
||||
dom.button(
|
||||
{
|
||||
className: "ghost-button js-profiler-dialog-close",
|
||||
onClick: () => this.hide(),
|
||||
},
|
||||
dom.img(
|
||||
{
|
||||
src: "chrome://devtools/skin/images/close.svg",
|
||||
}
|
||||
)
|
||||
)
|
||||
),
|
||||
dom.iframe({
|
||||
className: "profiler-dialog__frame",
|
||||
src: clientWrapper.getPerformancePanelUrl(),
|
||||
onLoad: (e) => {
|
||||
clientWrapper.loadPerformanceProfiler(e.target.contentWindow);
|
||||
},
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ProfilerDialog;
|
@ -16,6 +16,7 @@ const ConnectionPromptSetting = createFactory(require("./ConnectionPromptSetting
|
||||
const DebugTargetPane = createFactory(require("./debugtarget/DebugTargetPane"));
|
||||
const ExtensionDetail = createFactory(require("./debugtarget/ExtensionDetail"));
|
||||
const InspectAction = createFactory(require("./debugtarget/InspectAction"));
|
||||
const ProfilerDialog = createFactory(require("./ProfilerDialog"));
|
||||
const RuntimeInfo = createFactory(require("./RuntimeInfo"));
|
||||
const ServiceWorkerAction = createFactory(require("./debugtarget/ServiceWorkerAction"));
|
||||
const ServiceWorkersWarning = createFactory(require("./ServiceWorkersWarning"));
|
||||
@ -44,6 +45,7 @@ class RuntimePage extends PureComponent {
|
||||
runtimeId: PropTypes.string.isRequired,
|
||||
serviceWorkers: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
sharedWorkers: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
showProfilerDialog: PropTypes.bool.isRequired,
|
||||
tabs: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
temporaryExtensions: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
temporaryInstallError: PropTypes.string,
|
||||
@ -57,16 +59,44 @@ class RuntimePage extends PureComponent {
|
||||
dispatch(Actions.selectPage(PAGE_TYPES.RUNTIME, runtimeId));
|
||||
}
|
||||
|
||||
renderConnectionPromptSetting() {
|
||||
const { runtimeDetails, dispatch } = this.props;
|
||||
onProfilerButtonClick() {
|
||||
this.props.dispatch(Actions.showProfilerDialog());
|
||||
}
|
||||
|
||||
renderRemoteRuntimeActions() {
|
||||
const { runtimeDetails, runtimeId, dispatch } = this.props;
|
||||
const { connectionPromptEnabled } = runtimeDetails;
|
||||
|
||||
return dom.div(
|
||||
{
|
||||
className: "connection-prompt-setting",
|
||||
},
|
||||
ConnectionPromptSetting({ connectionPromptEnabled, dispatch }),
|
||||
);
|
||||
if (runtimeId === RUNTIMES.THIS_FIREFOX) {
|
||||
// Connection prompt and Profiling are only available on remote runtimes.
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
dom.div(
|
||||
{
|
||||
className: "connection-prompt-setting",
|
||||
key: "connection-prompt-setting",
|
||||
},
|
||||
ConnectionPromptSetting({ connectionPromptEnabled, dispatch }),
|
||||
),
|
||||
dom.p(
|
||||
{},
|
||||
Localized(
|
||||
{
|
||||
id: "about-debugging-runtime-profile-button",
|
||||
key: "profile-runtime-button",
|
||||
},
|
||||
dom.button(
|
||||
{
|
||||
className: "default-button js-profile-runtime-button",
|
||||
onClick: () => this.onProfilerButtonClick(),
|
||||
},
|
||||
"Profile Runtime"
|
||||
),
|
||||
),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
renderDebugTargetPane(name, targets, actionComponent,
|
||||
@ -100,9 +130,9 @@ class RuntimePage extends PureComponent {
|
||||
installedExtensions,
|
||||
otherWorkers,
|
||||
runtimeDetails,
|
||||
runtimeId,
|
||||
serviceWorkers,
|
||||
sharedWorkers,
|
||||
showProfilerDialog,
|
||||
tabs,
|
||||
temporaryExtensions,
|
||||
temporaryInstallError,
|
||||
@ -114,19 +144,13 @@ class RuntimePage extends PureComponent {
|
||||
return null;
|
||||
}
|
||||
|
||||
// do not show the connection prompt setting in 'This Firefox'
|
||||
const shallShowPromptSetting = runtimeId !== RUNTIMES.THIS_FIREFOX;
|
||||
|
||||
const { type } = runtimeDetails.info;
|
||||
return dom.article(
|
||||
{
|
||||
className: "page js-runtime-page",
|
||||
},
|
||||
RuntimeInfo(runtimeDetails.info),
|
||||
shallShowPromptSetting
|
||||
? this.renderConnectionPromptSetting()
|
||||
: null,
|
||||
|
||||
this.renderRemoteRuntimeActions(),
|
||||
runtimeDetails.serviceWorkersAvailable ? null : ServiceWorkersWarning(),
|
||||
isSupportedDebugTargetPane(type, DEBUG_TARGET_PANE.TEMPORARY_EXTENSION)
|
||||
? TemporaryExtensionInstaller({
|
||||
@ -169,6 +193,8 @@ class RuntimePage extends PureComponent {
|
||||
WorkerDetail,
|
||||
DEBUG_TARGET_PANE.OTHER_WORKER,
|
||||
"about-debugging-runtime-other-workers"),
|
||||
|
||||
showProfilerDialog ? ProfilerDialog({ dispatch, runtimeDetails }) : null,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -181,6 +207,7 @@ const mapStateToProps = state => {
|
||||
runtimeDetails: getCurrentRuntimeDetails(state.runtimes),
|
||||
serviceWorkers: state.debugTargets.serviceWorkers,
|
||||
sharedWorkers: state.debugTargets.sharedWorkers,
|
||||
showProfilerDialog: state.ui.showProfilerDialog,
|
||||
tabs: state.debugTargets.tabs,
|
||||
temporaryExtensions: state.debugTargets.temporaryExtensions,
|
||||
temporaryInstallError: state.ui.temporaryInstallError,
|
||||
|
@ -13,6 +13,8 @@ DevToolsModules(
|
||||
'App.css',
|
||||
'App.js',
|
||||
'ConnectionPromptSetting.js',
|
||||
'ProfilerDialog.css',
|
||||
'ProfilerDialog.js',
|
||||
'RuntimeInfo.js',
|
||||
'RuntimePage.css',
|
||||
'RuntimePage.js',
|
||||
|
@ -22,6 +22,7 @@ const actionTypes = {
|
||||
DISCONNECT_RUNTIME_FAILURE: "DISCONNECT_RUNTIME_FAILURE",
|
||||
DISCONNECT_RUNTIME_START: "DISCONNECT_RUNTIME_START",
|
||||
DISCONNECT_RUNTIME_SUCCESS: "DISCONNECT_RUNTIME_SUCCESS",
|
||||
HIDE_PROFILER_DIALOG: "HIDE_PROFILER_DIALOG",
|
||||
NETWORK_LOCATIONS_UPDATED: "NETWORK_LOCATIONS_UPDATED",
|
||||
REMOTE_RUNTIMES_UPDATED: "REMOTE_RUNTIMES_UPDATED",
|
||||
REQUEST_EXTENSIONS_FAILURE: "REQUEST_EXTENSIONS_FAILURE",
|
||||
@ -37,6 +38,7 @@ const actionTypes = {
|
||||
SELECT_PAGE_START: "SELECT_PAGE_START",
|
||||
SELECT_PAGE_SUCCESS: "SELECT_PAGE_SUCCESS",
|
||||
SELECTED_RUNTIME_ID_UPDATED: "SELECTED_RUNTIME_ID_UPDATED",
|
||||
SHOW_PROFILER_DIALOG: "SHOW_PROFILER_DIALOG",
|
||||
TELEMETRY_RECORD: "TELEMETRY_RECORD",
|
||||
TEMPORARY_EXTENSION_INSTALL_FAILURE: "TEMPORARY_EXTENSION_INSTALL_FAILURE",
|
||||
TEMPORARY_EXTENSION_INSTALL_START: "TEMPORARY_EXTENSION_INSTALL_START",
|
||||
|
@ -154,6 +154,18 @@ class ClientWrapper {
|
||||
isClosed() {
|
||||
return this.client._closed;
|
||||
}
|
||||
|
||||
// This method will be mocked to return a dummy URL during mochitests
|
||||
getPerformancePanelUrl() {
|
||||
return "chrome://devtools/content/performance-new/index.xhtml";
|
||||
}
|
||||
|
||||
async loadPerformanceProfiler(win) {
|
||||
const preferenceFront = await this.getFront("preference");
|
||||
const perfFront = await this.getFront("perf");
|
||||
const perfActorVersion = this.client.mainRoot.traits.perfActorVersion;
|
||||
win.gInit(perfFront, preferenceFront, perfActorVersion);
|
||||
}
|
||||
}
|
||||
|
||||
exports.ClientWrapper = ClientWrapper;
|
||||
|
@ -7,8 +7,10 @@
|
||||
const {
|
||||
ADB_ADDON_STATUS_UPDATED,
|
||||
DEBUG_TARGET_COLLAPSIBILITY_UPDATED,
|
||||
HIDE_PROFILER_DIALOG,
|
||||
NETWORK_LOCATIONS_UPDATED,
|
||||
SELECT_PAGE_SUCCESS,
|
||||
SHOW_PROFILER_DIALOG,
|
||||
TEMPORARY_EXTENSION_INSTALL_FAILURE,
|
||||
TEMPORARY_EXTENSION_INSTALL_SUCCESS,
|
||||
USB_RUNTIMES_SCAN_START,
|
||||
@ -25,6 +27,7 @@ function UiState(locations = [], debugTargetCollapsibilities = {},
|
||||
networkEnabled,
|
||||
networkLocations: locations,
|
||||
selectedPage: null,
|
||||
showProfilerDialog: false,
|
||||
showSystemAddons,
|
||||
temporaryInstallError: null,
|
||||
wifiEnabled,
|
||||
@ -55,6 +58,14 @@ function uiReducer(state = UiState(), action) {
|
||||
return Object.assign({}, state, { selectedPage: page });
|
||||
}
|
||||
|
||||
case SHOW_PROFILER_DIALOG: {
|
||||
return Object.assign({}, state, { showProfilerDialog: true });
|
||||
}
|
||||
|
||||
case HIDE_PROFILER_DIALOG: {
|
||||
return Object.assign({}, state, { showProfilerDialog: false });
|
||||
}
|
||||
|
||||
case USB_RUNTIMES_SCAN_START: {
|
||||
return Object.assign({}, state, { isScanningUsb: true });
|
||||
}
|
||||
|
@ -59,8 +59,9 @@ skip-if = (os == "win" && ccov) # Bug 1521349
|
||||
[browser_aboutdebugging_devtoolstoolbox_tooltip_markupview.js]
|
||||
[browser_aboutdebugging_navigate.js]
|
||||
[browser_aboutdebugging_persist_connection.js]
|
||||
[browser_aboutdebugging_profiler_dialog.js]
|
||||
[browser_aboutdebugging_routes.js]
|
||||
[browser_aboutdebugging_runtime_connection-prompt.js]
|
||||
[browser_aboutdebugging_runtime_remote_runtime_buttons.js]
|
||||
[browser_aboutdebugging_runtime_usbclient_closed.js]
|
||||
[browser_aboutdebugging_select_network_runtime.js]
|
||||
[browser_aboutdebugging_select_page_with_serviceworker.js]
|
||||
|
@ -0,0 +1,83 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/* import-globals-from helper-mocks.js */
|
||||
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-mocks.js", this);
|
||||
|
||||
/**
|
||||
* Test opening and closing the profiler dialog.
|
||||
*/
|
||||
add_task(async function() {
|
||||
// enable USB devices mocks
|
||||
const mocks = new Mocks();
|
||||
const usbClient = mocks.createUSBRuntime("1337id", {
|
||||
deviceName: "Fancy Phone",
|
||||
name: "Lorem ipsum",
|
||||
});
|
||||
|
||||
const { document, tab, window } = await openAboutDebugging();
|
||||
|
||||
mocks.emitUSBUpdate();
|
||||
await connectToRuntime("Fancy Phone", document);
|
||||
await selectRuntime("Fancy Phone", "Lorem ipsum", document);
|
||||
|
||||
info("Open the profiler dialog");
|
||||
await openProfilerDialog(usbClient, document);
|
||||
assertDialogVisible(document);
|
||||
|
||||
info("Click on the close button and wait until the dialog disappears");
|
||||
const closeDialogButton = document.querySelector(".js-profiler-dialog-close");
|
||||
closeDialogButton.click();
|
||||
await waitUntil(() => !document.querySelector(".js-profiler-dialog"));
|
||||
assertDialogHidden(document);
|
||||
|
||||
info("Open the profiler dialog again");
|
||||
await openProfilerDialog(usbClient, document);
|
||||
assertDialogVisible(document);
|
||||
|
||||
info("Click on the mask element and wait until the dialog disappears");
|
||||
const mask = document.querySelector(".js-profiler-dialog-mask");
|
||||
EventUtils.synthesizeMouse(mask, 5, 5, {}, window);
|
||||
await waitUntil(() => !document.querySelector(".js-profiler-dialog"));
|
||||
assertDialogHidden(document);
|
||||
|
||||
info("Open the profiler dialog again");
|
||||
await openProfilerDialog(usbClient, document);
|
||||
assertDialogVisible(document);
|
||||
|
||||
info("Navigate to this-firefox and wait until the dialog disappears");
|
||||
document.location.hash = "#/runtime/this-firefox";
|
||||
await waitUntil(() => !document.querySelector(".js-profiler-dialog"));
|
||||
assertDialogHidden(document);
|
||||
|
||||
info("Select the remote runtime again, check the dialog is still hidden");
|
||||
await selectRuntime("Fancy Phone", "Lorem ipsum", document);
|
||||
assertDialogHidden(document);
|
||||
|
||||
await removeTab(tab);
|
||||
});
|
||||
|
||||
function assertDialogVisible(doc) {
|
||||
ok(doc.querySelector(".js-profiler-dialog"), "Dialog is displayed");
|
||||
ok(doc.querySelector(".js-profiler-dialog-mask"), "Dialog mask is displayed");
|
||||
}
|
||||
|
||||
function assertDialogHidden(doc) {
|
||||
ok(!document.querySelector(".js-profiler-dialog"), "Dialog is removed");
|
||||
ok(!document.querySelector(".js-profiler-dialog-mask"), "Dialog mask is removed");
|
||||
}
|
||||
|
||||
function openProfilerDialog(client, doc) {
|
||||
const onProfilerLoaded = new Promise(r => {
|
||||
client.loadPerformanceProfiler = r;
|
||||
});
|
||||
|
||||
info("Click on the Profile Runtime button");
|
||||
const profileButton = doc.querySelector(".js-profile-runtime-button");
|
||||
profileButton.click();
|
||||
|
||||
info("Wait for the loadPerformanceProfiler callback to be executed on client-wrapper");
|
||||
return onProfilerLoaded;
|
||||
}
|
@ -8,8 +8,7 @@ Services.scriptloader.loadSubScript(
|
||||
CHROME_URL_ROOT + "helper-mocks.js", this);
|
||||
|
||||
/**
|
||||
* Test that remote runtimes show the connection prompt,
|
||||
* but it's hidden in 'This Firefox'
|
||||
* Test that remote runtimes show action buttons that are hidden for 'This Firefox'.
|
||||
*/
|
||||
add_task(async function() {
|
||||
// enable USB devices mocks
|
||||
@ -24,6 +23,8 @@ add_task(async function() {
|
||||
info("Checking This Firefox");
|
||||
ok(!document.querySelector(".js-connection-prompt-toggle-button"),
|
||||
"This Firefox does not contain the connection prompt button");
|
||||
ok(!document.querySelector(".js-profile-runtime-button"),
|
||||
"This Firefox does not contain the profile runtime button");
|
||||
|
||||
info("Checking a USB runtime");
|
||||
mocks.emitUSBUpdate();
|
||||
@ -31,6 +32,8 @@ add_task(async function() {
|
||||
await selectRuntime("Fancy Phone", "Lorem ipsum", document);
|
||||
ok(!!document.querySelector(".js-connection-prompt-toggle-button"),
|
||||
"Runtime contains the connection prompt button");
|
||||
ok(!!document.querySelector(".js-profile-runtime-button"),
|
||||
"Remote runtime contains the profile runtime button");
|
||||
|
||||
await removeTab(tab);
|
||||
});
|
@ -87,6 +87,8 @@ function createClientMock() {
|
||||
setPreference: function(prefName, value) {
|
||||
this._preferences[prefName] = value;
|
||||
},
|
||||
getPerformancePanelUrl: () => "data:text/html;charset=UTF-8,fake_profiler_page",
|
||||
loadPerformanceProfiler: () => {},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -126,6 +126,10 @@ about-debugging-runtime-shared-workers = Shared Workers
|
||||
# Title of the other workers category.
|
||||
about-debugging-runtime-other-workers = Other Workers
|
||||
|
||||
# Label of the button opening the performance profiler panel in runtime pages for remote
|
||||
# runtimes.
|
||||
about-debugging-runtime-profile-button = Profile Runtime
|
||||
|
||||
# This string is displayed in about:debugging#workers if the current configuration of the
|
||||
# browser is incompatible with service workers. Learn more points to MDN.
|
||||
# https://developer.mozilla.org/en-US/docs/Tools/about%3Adebugging#Service_workers_not_compatible
|
||||
@ -279,3 +283,6 @@ about-debugging-page-title-with-runtime = { -application-title } - { about-debug
|
||||
|
||||
# Page title without the runtime displayed in the tab
|
||||
about-debugging-page-title = { -application-title } - { about-debugging-page-title-selected-page }
|
||||
|
||||
# Title of a modal dialog displayed on remote runtime pages after clicking on the Profile Runtime button.
|
||||
about-debugging-profiler-dialog-title = Performance Profiler
|
||||
|
@ -2,5 +2,11 @@
|
||||
|
||||
module.exports = {
|
||||
// Extend from the shared list of defined globals for mochitests.
|
||||
"extends": "../../../../.eslintrc.mochitests.js"
|
||||
"extends": "../../../../.eslintrc.mochitests.js",
|
||||
"overrides": [{
|
||||
"files": ["test-dynamic-import.js"],
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
},
|
||||
}]
|
||||
};
|
||||
|
@ -72,6 +72,8 @@ support-files =
|
||||
test-data.json
|
||||
test-data.json^headers^
|
||||
test-duplicate-error.html
|
||||
test-dynamic-import.html
|
||||
test-dynamic-import.js
|
||||
test-encoding-ISO-8859-1.html
|
||||
test-error.html
|
||||
test-eval-in-stackframe.html
|
||||
@ -217,6 +219,7 @@ skip-if = verify
|
||||
[browser_jsterm_autocomplete-properties-with-non-alphanumeric-names.js]
|
||||
[browser_jsterm_await_assignments.js]
|
||||
[browser_jsterm_await_concurrent.js]
|
||||
[browser_jsterm_await_dynamic_import.js]
|
||||
[browser_jsterm_await_error.js]
|
||||
[browser_jsterm_await_helper_dollar_underscore.js]
|
||||
[browser_jsterm_await_paused.js]
|
||||
|
@ -0,0 +1,46 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that top-level await with dynamic import works as expected.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/test/mochitest/test-dynamic-import.html";
|
||||
|
||||
add_task(async function() {
|
||||
// Enable dynamic import
|
||||
await pushPref("javascript.options.dynamicImport", true);
|
||||
// Enable await mapping.
|
||||
await pushPref("devtools.debugger.features.map-await-expression", true);
|
||||
|
||||
// Run test with legacy JsTerm
|
||||
await pushPref("devtools.webconsole.jsterm.codeMirror", false);
|
||||
await performTests();
|
||||
// And then run it with the CodeMirror-powered one.
|
||||
await pushPref("devtools.webconsole.jsterm.codeMirror", true);
|
||||
await performTests();
|
||||
});
|
||||
|
||||
async function performTests() {
|
||||
const hud = await openNewTabAndConsole(TEST_URI);
|
||||
|
||||
const executeAndWaitForResultMessage = (input, expectedOutput) =>
|
||||
executeAndWaitForMessage(hud, input, expectedOutput, ".result");
|
||||
|
||||
info("Evaluate an expression with a dynamic import");
|
||||
let importAwaitExpression = `
|
||||
var {sum} = await import("./test-dynamic-import.js");
|
||||
sum(1, 2, 3);
|
||||
`;
|
||||
await executeAndWaitForResultMessage(importAwaitExpression, `1 + 2 + 3 = 6`);
|
||||
ok(true, "The `sum` module was imported and used successfully");
|
||||
|
||||
info("Import the same module a second time");
|
||||
// This used to make the content page crash (See Bug 1523897).
|
||||
importAwaitExpression = `
|
||||
var {sum} = await import("./test-dynamic-import.js");
|
||||
sum(2, 3, 4);
|
||||
`;
|
||||
await executeAndWaitForResultMessage(importAwaitExpression, `2 + 3 + 4 = 9`);
|
||||
ok(true, "The `sum` module was imported and used successfully a second time");
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test dynamic import usage in console</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Test dynamic import usage in console</h1>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,12 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* @param {Number} numbers that will be summed.
|
||||
* @returns {String} A string of the following form: `${arg1} + ${arg2} ${argn} = ${sum}`
|
||||
*/
|
||||
function sum(...args) {
|
||||
return `${args.join(" + ")} = ${args.reduce((acc, i) => acc + i)}`;
|
||||
}
|
||||
|
||||
export {sum};
|
@ -63,6 +63,8 @@ Then run this:
|
||||
./mach build
|
||||
```
|
||||
|
||||
Please note, if this fails it might be possible you need to run the `bootstrap.py` script first. Download the [bootstrap.py script](https://hg.mozilla.org/mozilla-central/raw-file/default/python/mozboot/bin/bootstrap.py) and save it in your project directory. Then run `python bootstrap.py` and follow the prompted steps.
|
||||
|
||||
**Note:** if using Windows, you might need to type the commands without the `./`:
|
||||
|
||||
```bash
|
||||
|
@ -14,9 +14,12 @@
|
||||
#include "BufferStream.h"
|
||||
#include "H264.h"
|
||||
#include "Index.h"
|
||||
#include "MP4Decoder.h"
|
||||
#include "MP4Metadata.h"
|
||||
#include "MoofParser.h"
|
||||
#include "ResourceStream.h"
|
||||
#include "VPXDecoder.h"
|
||||
#include "mozilla/Span.h"
|
||||
#include "mozilla/StaticPrefs.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsAutoPtr.h"
|
||||
@ -71,7 +74,11 @@ class MP4TrackDemuxer : public MediaTrackDemuxer,
|
||||
RefPtr<MediaRawData> mQueuedSample;
|
||||
bool mNeedReIndex;
|
||||
bool mNeedSPSForTelemetry;
|
||||
bool mIsH264 = false;
|
||||
enum CodecType {
|
||||
kH264,
|
||||
kVP9,
|
||||
kOther
|
||||
} mType = kOther;
|
||||
};
|
||||
|
||||
// Returns true if no SPS was found and search for it should continue.
|
||||
@ -350,9 +357,8 @@ MP4TrackDemuxer::MP4TrackDemuxer(MediaResource* aResource,
|
||||
|
||||
VideoInfo* videoInfo = mInfo->GetAsVideoInfo();
|
||||
// Collect telemetry from h264 AVCC SPS.
|
||||
if (videoInfo && (mInfo->mMimeType.EqualsLiteral("video/mp4") ||
|
||||
mInfo->mMimeType.EqualsLiteral("video/avc"))) {
|
||||
mIsH264 = true;
|
||||
if (videoInfo && MP4Decoder::IsH264(mInfo->mMimeType)) {
|
||||
mType = kH264;
|
||||
RefPtr<MediaByteBuffer> extraData = videoInfo->mExtraData;
|
||||
mNeedSPSForTelemetry = AccumulateSPSTelemetry(extraData);
|
||||
SPSData spsdata;
|
||||
@ -365,6 +371,9 @@ MP4TrackDemuxer::MP4TrackDemuxer(MediaResource* aResource,
|
||||
videoInfo->mDisplay.height = spsdata.display_height;
|
||||
}
|
||||
} else {
|
||||
if (videoInfo && VPXDecoder::IsVP9(mInfo->mMimeType)) {
|
||||
mType = kVP9;
|
||||
}
|
||||
// No SPS to be found.
|
||||
mNeedSPSForTelemetry = false;
|
||||
}
|
||||
@ -422,7 +431,7 @@ already_AddRefed<MediaRawData> MP4TrackDemuxer::GetNextSample() {
|
||||
}
|
||||
if (mInfo->GetAsVideoInfo()) {
|
||||
sample->mExtraData = mInfo->GetAsVideoInfo()->mExtraData;
|
||||
if (mIsH264 && !sample->mCrypto.IsEncrypted()) {
|
||||
if (mType == kH264 && !sample->mCrypto.IsEncrypted()) {
|
||||
H264::FrameType type = H264::GetFrameType(sample);
|
||||
switch (type) {
|
||||
case H264::FrameType::I_FRAME:
|
||||
@ -455,6 +464,20 @@ already_AddRefed<MediaRawData> MP4TrackDemuxer::GetNextSample() {
|
||||
// TODO: make demuxer errors non-fatal.
|
||||
break;
|
||||
}
|
||||
} else if (mType == kVP9 && !sample->mCrypto.IsEncrypted()) {
|
||||
bool keyframe = VPXDecoder::IsKeyframe(
|
||||
MakeSpan<const uint8_t>(sample->Data(), sample->Size()),
|
||||
VPXDecoder::Codec::VP9);
|
||||
if (sample->mKeyframe != keyframe) {
|
||||
NS_WARNING(nsPrintfCString(
|
||||
"Frame incorrectly marked as %skeyframe "
|
||||
"@ pts:%" PRId64 " dur:%" PRId64 " dts:%" PRId64,
|
||||
keyframe ? "" : "non-", sample->mTime.ToMicroseconds(),
|
||||
sample->mDuration.ToMicroseconds(),
|
||||
sample->mTimecode.ToMicroseconds())
|
||||
.get());
|
||||
sample->mKeyframe = keyframe;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -491,7 +514,7 @@ RefPtr<MP4TrackDemuxer::SamplesPromise> MP4TrackDemuxer::GetSamples(
|
||||
}
|
||||
for (const auto& sample : samples->mSamples) {
|
||||
// Collect telemetry from h264 Annex B SPS.
|
||||
if (mNeedSPSForTelemetry && mIsH264 && AnnexB::IsAVCC(sample)) {
|
||||
if (mNeedSPSForTelemetry && mType == kH264 && AnnexB::IsAVCC(sample)) {
|
||||
RefPtr<MediaByteBuffer> extradata = H264::ExtractExtraData(sample);
|
||||
if (H264::HasSPS(extradata)) {
|
||||
RefPtr<MediaByteBuffer> extradata = H264::ExtractExtraData(sample);
|
||||
|
@ -174,7 +174,6 @@ impl<'a> FrameBuildingState<'a> {
|
||||
#[derive(Debug)]
|
||||
pub struct PictureContext {
|
||||
pub pic_index: PictureIndex,
|
||||
pub pipeline_id: PipelineId,
|
||||
pub apply_local_clip_rect: bool,
|
||||
pub allow_subpixel_aa: bool,
|
||||
pub is_passthrough: bool,
|
||||
@ -189,7 +188,6 @@ pub struct PictureContext {
|
||||
/// Mutable state of a picture that gets modified when
|
||||
/// the children are processed.
|
||||
pub struct PictureState {
|
||||
pub is_cacheable: bool,
|
||||
pub map_local_to_pic: SpaceMapper<LayoutPixel, PicturePixel>,
|
||||
pub map_pic_to_world: SpaceMapper<PicturePixel, WorldPixel>,
|
||||
pub map_pic_to_raster: SpaceMapper<PicturePixel, RasterPixel>,
|
||||
|
@ -2385,7 +2385,6 @@ impl PicturePrimitive {
|
||||
|
||||
let state = PictureState {
|
||||
//TODO: check for MAX_CACHE_SIZE here?
|
||||
is_cacheable: true,
|
||||
map_local_to_pic,
|
||||
map_pic_to_world,
|
||||
map_pic_to_raster,
|
||||
@ -2432,7 +2431,6 @@ impl PicturePrimitive {
|
||||
|
||||
let context = PictureContext {
|
||||
pic_index,
|
||||
pipeline_id: self.pipeline_id,
|
||||
apply_local_clip_rect: self.apply_local_clip_rect,
|
||||
allow_subpixel_aa,
|
||||
is_passthrough: self.raster_config.is_none(),
|
||||
|
@ -2270,10 +2270,6 @@ impl PrimitiveStore {
|
||||
frame_state.clip_chain_stack.pop_surface();
|
||||
}
|
||||
|
||||
if !pic_state_for_children.is_cacheable {
|
||||
pic_state.is_cacheable = false;
|
||||
}
|
||||
|
||||
// Restore the dependencies (borrow check dance)
|
||||
self.pictures[pic_context_for_children.pic_index.0]
|
||||
.restore_context(
|
||||
@ -2319,11 +2315,6 @@ impl PrimitiveStore {
|
||||
prim_instance.prepared_frame_id = frame_state.render_tasks.frame_id();
|
||||
}
|
||||
|
||||
pic_state.is_cacheable &= prim_instance.is_cacheable(
|
||||
&data_stores,
|
||||
frame_state.resource_cache,
|
||||
);
|
||||
|
||||
match prim_instance.kind {
|
||||
PrimitiveInstanceKind::Picture { pic_index, .. } => {
|
||||
let pic = &mut self.pictures[pic_index.0];
|
||||
|
@ -70,7 +70,7 @@ class NoTypePolicy {
|
||||
class BoxInputsPolicy final : public TypePolicy {
|
||||
public:
|
||||
constexpr BoxInputsPolicy() {}
|
||||
SPECIALIZATION_DATA_;
|
||||
EMPTY_DATA_;
|
||||
static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc,
|
||||
MInstruction* def);
|
||||
MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc,
|
||||
|
@ -6617,51 +6617,13 @@ nsresult PresShell::EventHandler::HandleEvent(nsIFrame* aFrame,
|
||||
}
|
||||
}
|
||||
|
||||
// Suppress mouse event if it's being targeted at an element inside
|
||||
// a document which needs events suppressed
|
||||
if (aGUIEvent->mClass == eMouseEventClass &&
|
||||
frameToHandleEvent->PresContext()
|
||||
->Document()
|
||||
->EventHandlingSuppressed()) {
|
||||
if (aGUIEvent->mMessage == eMouseDown) {
|
||||
mPresShell->mNoDelayedMouseEvents = true;
|
||||
} else if (!mPresShell->mNoDelayedMouseEvents &&
|
||||
(aGUIEvent->mMessage == eMouseUp ||
|
||||
// contextmenu is triggered after right mouseup on Windows and
|
||||
// right mousedown on other platforms.
|
||||
aGUIEvent->mMessage == eContextMenu)) {
|
||||
auto event = MakeUnique<DelayedMouseEvent>(aGUIEvent->AsMouseEvent());
|
||||
PushDelayedEventIntoQueue(std::move(event));
|
||||
}
|
||||
|
||||
// If there is a suppressed event listener associated with the document,
|
||||
// notify it about the suppressed mouse event. This allows devtools
|
||||
// features to continue receiving mouse events even when the devtools
|
||||
// debugger has paused execution in a page.
|
||||
RefPtr<EventListener> suppressedListener =
|
||||
frameToHandleEvent->PresContext()
|
||||
->Document()
|
||||
->GetSuppressedEventListener();
|
||||
if (suppressedListener && aGUIEvent->AsMouseEvent()->mReason !=
|
||||
WidgetMouseEvent::eSynthesized) {
|
||||
nsCOMPtr<nsIContent> targetContent;
|
||||
frameToHandleEvent->GetContentForEvent(aGUIEvent,
|
||||
getter_AddRefs(targetContent));
|
||||
if (targetContent) {
|
||||
aGUIEvent->mTarget = targetContent;
|
||||
}
|
||||
|
||||
nsCOMPtr<EventTarget> et = aGUIEvent->mTarget;
|
||||
RefPtr<Event> event = EventDispatcher::CreateEvent(
|
||||
et, frameToHandleEvent->PresContext(), aGUIEvent, EmptyString());
|
||||
|
||||
suppressedListener->HandleEvent(*event);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!frameToHandleEvent)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!frameToHandleEvent)) {
|
||||
// Suppress mouse event if it's being targeted at an element inside
|
||||
// a document which needs events suppressed
|
||||
if (MaybeDiscardOrDelayMouseEvent(frameToHandleEvent, aGUIEvent)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -7260,6 +7222,61 @@ bool PresShell::EventHandler::MaybeDiscardOrDelayKeyboardEvent(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PresShell::EventHandler::MaybeDiscardOrDelayMouseEvent(
|
||||
nsIFrame* aFrameToHandleEvent, WidgetGUIEvent* aGUIEvent) {
|
||||
MOZ_ASSERT(aFrameToHandleEvent);
|
||||
MOZ_ASSERT(aGUIEvent);
|
||||
|
||||
if (aGUIEvent->mClass != eMouseEventClass) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aFrameToHandleEvent->PresContext()
|
||||
->Document()
|
||||
->EventHandlingSuppressed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aGUIEvent->mMessage == eMouseDown) {
|
||||
mPresShell->mNoDelayedMouseEvents = true;
|
||||
} else if (!mPresShell->mNoDelayedMouseEvents &&
|
||||
(aGUIEvent->mMessage == eMouseUp ||
|
||||
// contextmenu is triggered after right mouseup on Windows and
|
||||
// right mousedown on other platforms.
|
||||
aGUIEvent->mMessage == eContextMenu)) {
|
||||
UniquePtr<DelayedMouseEvent> delayedMouseEvent =
|
||||
MakeUnique<DelayedMouseEvent>(aGUIEvent->AsMouseEvent());
|
||||
PushDelayedEventIntoQueue(std::move(delayedMouseEvent));
|
||||
}
|
||||
|
||||
// If there is a suppressed event listener associated with the document,
|
||||
// notify it about the suppressed mouse event. This allows devtools
|
||||
// features to continue receiving mouse events even when the devtools
|
||||
// debugger has paused execution in a page.
|
||||
RefPtr<EventListener> suppressedListener = aFrameToHandleEvent->PresContext()
|
||||
->Document()
|
||||
->GetSuppressedEventListener();
|
||||
if (!suppressedListener ||
|
||||
aGUIEvent->AsMouseEvent()->mReason == WidgetMouseEvent::eSynthesized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> targetContent;
|
||||
aFrameToHandleEvent->GetContentForEvent(aGUIEvent,
|
||||
getter_AddRefs(targetContent));
|
||||
if (targetContent) {
|
||||
aGUIEvent->mTarget = targetContent;
|
||||
}
|
||||
|
||||
nsCOMPtr<EventTarget> eventTarget = aGUIEvent->mTarget;
|
||||
RefPtr<Event> event = EventDispatcher::CreateEvent(
|
||||
eventTarget, aFrameToHandleEvent->PresContext(), aGUIEvent,
|
||||
EmptyString());
|
||||
|
||||
suppressedListener->HandleEvent(*event);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsIFrame* PresShell::EventHandler::MaybeFlushThrottledStyles(
|
||||
nsIFrame* aFrameForPresShell) {
|
||||
|
||||
|
@ -711,6 +711,22 @@ class PresShell final : public nsIPresShell,
|
||||
*/
|
||||
bool MaybeDiscardOrDelayKeyboardEvent(WidgetGUIEvent* aGUIEvent);
|
||||
|
||||
/**
|
||||
* MaybeDiscardOrDelayMouseEvent() may discard or put aGUIEvent into the
|
||||
* delayed event queue if it's a mouse event and if we should do so.
|
||||
* If aGUIEvent is not a mouse event, this does nothing.
|
||||
* If there is suppressed event listener like debugger of devtools, this
|
||||
* notifies it of the event after discard or put it into the delayed
|
||||
* event queue.
|
||||
*
|
||||
* @param aFrameToHandleEvent The frame to handle aGUIEvent.
|
||||
* @param aGUIEvent The handling event.
|
||||
* @return true if this method discard the event
|
||||
* or put it into the delayed event queue.
|
||||
*/
|
||||
bool MaybeDiscardOrDelayMouseEvent(nsIFrame* aFrameToHandleEvent,
|
||||
WidgetGUIEvent* aGUIEvent);
|
||||
|
||||
/**
|
||||
* MaybeFlushThrottledStyles() tries to flush pending animation. If it's
|
||||
* flushed and then aFrameForPresShell is destroyed, returns new frame
|
||||
|
@ -253,7 +253,7 @@ class BaseBootstrapper(object):
|
||||
'%s does not yet implement suggest_mobile_android_artifact_mode_mozconfig()'
|
||||
% __name__)
|
||||
|
||||
def ensure_clang_static_analysis_package(self, checkout_root):
|
||||
def ensure_clang_static_analysis_package(self, state_dir, checkout_root):
|
||||
'''
|
||||
Install the clang static analysis package
|
||||
'''
|
||||
@ -276,23 +276,15 @@ class BaseBootstrapper(object):
|
||||
'%s does not yet implement ensure_node_packages()'
|
||||
% __name__)
|
||||
|
||||
def install_toolchain_static_analysis(self, checkout_root):
|
||||
mach_binary = os.path.join(checkout_root, 'mach')
|
||||
mach_binary = os.path.abspath(mach_binary)
|
||||
if not os.path.exists(mach_binary):
|
||||
raise ValueError("mach not found at %s" % mach_binary)
|
||||
def install_toolchain_static_analysis(self, state_dir, checkout_root, toolchain_job):
|
||||
clang_tools_path = os.path.join(state_dir, 'clang-tools')
|
||||
import shutil
|
||||
if os.path.exists(clang_tools_path):
|
||||
shutil.rmtree(clang_tools_path)
|
||||
|
||||
if not sys.executable:
|
||||
raise ValueError("cannot determine path to Python executable")
|
||||
|
||||
cmd = [sys.executable, mach_binary, 'static-analysis', 'install',
|
||||
'--force', '--minimal-install']
|
||||
|
||||
from subprocess import CalledProcessError
|
||||
try:
|
||||
subprocess.check_call(cmd)
|
||||
except CalledProcessError as e:
|
||||
print(e.output)
|
||||
# Re-create the directory for clang_tools
|
||||
os.mkdir(clang_tools_path)
|
||||
self.install_toolchain_artifact(clang_tools_path, checkout_root, toolchain_job)
|
||||
|
||||
def install_toolchain_artifact(self, state_dir, checkout_root, toolchain_job):
|
||||
mach_binary = os.path.join(checkout_root, 'mach')
|
||||
|
@ -382,7 +382,7 @@ class Bootstrapper(object):
|
||||
self.instance.ensure_node_packages(state_dir, checkout_root)
|
||||
if not self.instance.artifact_mode:
|
||||
self.instance.ensure_stylo_packages(state_dir, checkout_root)
|
||||
self.instance.ensure_clang_static_analysis_package(checkout_root)
|
||||
self.instance.ensure_clang_static_analysis_package(state_dir, checkout_root)
|
||||
|
||||
def check_telemetry_opt_in(self, state_dir):
|
||||
# We can't prompt the user.
|
||||
|
@ -66,7 +66,7 @@ class FreeBSDBootstrapper(BaseBootstrapper):
|
||||
# TODO: Figure out what not to install for artifact mode
|
||||
self.pkg_install(*self.browser_packages)
|
||||
|
||||
def ensure_clang_static_analysis_package(self, checkout_root):
|
||||
def ensure_clang_static_analysis_package(self, state_dir, checkout_root):
|
||||
# TODO: we don't ship clang base static analysis for this platform
|
||||
pass
|
||||
|
||||
|
@ -49,10 +49,12 @@ class ClangStaticAnalysisInstall(object):
|
||||
def __init__(self, **kwargs):
|
||||
pass
|
||||
|
||||
def ensure_clang_static_analysis_package(self, checkout_root):
|
||||
def ensure_clang_static_analysis_package(self, state_dir, checkout_root):
|
||||
if is_non_x86_64():
|
||||
print('Cannot install static analysis tools from taskcluster.\n'
|
||||
'Please install these tools manually.')
|
||||
return
|
||||
|
||||
self.install_toolchain_static_analysis(checkout_root)
|
||||
from mozboot import static_analysis
|
||||
self.install_toolchain_static_analysis(
|
||||
state_dir, checkout_root, static_analysis.LINUX_CLANG_TIDY)
|
||||
|
@ -72,8 +72,10 @@ class MozillaBuildBootstrapper(BaseBootstrapper):
|
||||
def install_mobile_android_artifact_mode_packages(self):
|
||||
pass
|
||||
|
||||
def ensure_clang_static_analysis_package(self, checkout_root):
|
||||
self.install_toolchain_static_analysis(checkout_root)
|
||||
def ensure_clang_static_analysis_package(self, state_dir, checkout_root):
|
||||
from mozboot import static_analysis
|
||||
self.install_toolchain_static_analysis(
|
||||
state_dir, checkout_root, static_analysis.WINDOWS_CLANG_TIDY)
|
||||
|
||||
def ensure_stylo_packages(self, state_dir, checkout_root):
|
||||
# On-device artifact builds are supported; on-device desktop builds are not.
|
||||
|
@ -47,7 +47,7 @@ class OpenBSDBootstrapper(BaseBootstrapper):
|
||||
# we use -z because there's no other way to say "any autoconf-2.13"
|
||||
self.run_as_root(['pkg_add', '-z'] + self.browser_packages)
|
||||
|
||||
def ensure_clang_static_analysis_package(self, checkout_root):
|
||||
def ensure_clang_static_analysis_package(self, state_dir, checkout_root):
|
||||
# TODO: we don't ship clang base static analysis for this platform
|
||||
pass
|
||||
|
||||
|
@ -516,8 +516,10 @@ class OSXBootstrapper(BaseBootstrapper):
|
||||
|
||||
return active_name.lower()
|
||||
|
||||
def ensure_clang_static_analysis_package(self, checkout_root):
|
||||
self.install_toolchain_static_analysis(checkout_root)
|
||||
def ensure_clang_static_analysis_package(self, state_dir, checkout_root):
|
||||
from mozboot import static_analysis
|
||||
self.install_toolchain_static_analysis(
|
||||
state_dir, checkout_root, static_analysis.MACOS_CLANG_TIDY)
|
||||
|
||||
def ensure_stylo_packages(self, state_dir, checkout_root):
|
||||
from mozboot import stylo
|
||||
|
9
python/mozboot/mozboot/static_analysis.py
Normal file
9
python/mozboot/mozboot/static_analysis.py
Normal file
@ -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/.
|
||||
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
WINDOWS_CLANG_TIDY = 'win64-clang-tidy'
|
||||
LINUX_CLANG_TIDY = 'linux64-clang-tidy'
|
||||
MACOS_CLANG_TIDY = 'macosx64-clang-tidy'
|
@ -99,8 +99,10 @@ class WindowsBootstrapper(BaseBootstrapper):
|
||||
def install_mobile_android_artifact_mode_packages(self):
|
||||
raise NotImplementedError('We do not support building Android on Windows. Sorry!')
|
||||
|
||||
def ensure_clang_static_analysis_package(self, checkout_root):
|
||||
self.install_toolchain_static_analysis(checkout_root)
|
||||
def ensure_clang_static_analysis_package(self, state_dir, checkout_root):
|
||||
from mozboot import static_analysis
|
||||
self.install_toolchain_static_analysis(
|
||||
state_dir, checkout_root, static_analysis.WINDOWS_CLANG_TIDY)
|
||||
|
||||
def ensure_stylo_packages(self, state_dir, checkout_root):
|
||||
# On-device artifact builds are supported; on-device desktop builds are not.
|
||||
|
@ -2817,7 +2817,8 @@ class StaticAnalysis(MachCommandBase):
|
||||
# Supported extension and accepted path
|
||||
path_list.append(f_in_dir)
|
||||
else:
|
||||
if f.endswith(extensions):
|
||||
# Make sure that the file exists and it has a supported extension
|
||||
if os.path.isfile(f) and f.endswith(extensions):
|
||||
path_list.append(f)
|
||||
|
||||
return path_list
|
||||
|
@ -53,7 +53,7 @@ linux64-rust-nightly:
|
||||
symbol: TL(rust-nightly)
|
||||
run:
|
||||
arguments: [
|
||||
'--channel', 'nightly-2018-10-05',
|
||||
'--channel', 'nightly-2018-12-14',
|
||||
'--host', 'x86_64-unknown-linux-gnu',
|
||||
'--target', 'x86_64-unknown-linux-gnu',
|
||||
'--target', 'i686-unknown-linux-gnu',
|
||||
@ -90,7 +90,7 @@ linux64-rust-nightly-macos:
|
||||
symbol: TL(rust-nightly-macos)
|
||||
run:
|
||||
arguments: [
|
||||
'--channel', 'nightly-2018-10-05',
|
||||
'--channel', 'nightly-2018-12-14',
|
||||
'--host', 'x86_64-unknown-linux-gnu',
|
||||
'--target', 'x86_64-unknown-linux-gnu',
|
||||
'--target', 'x86_64-apple-darwin',
|
||||
@ -143,7 +143,7 @@ win64-rust-nightly:
|
||||
symbol: TW64(rust-nightly)
|
||||
run:
|
||||
arguments: [
|
||||
'--channel', 'nightly-2018-10-05',
|
||||
'--channel', 'nightly-2018-12-14',
|
||||
'--host', 'x86_64-pc-windows-msvc',
|
||||
'--target', 'x86_64-pc-windows-msvc',
|
||||
'--target', 'i686-pc-windows-msvc',
|
||||
|
@ -7,7 +7,7 @@ from __future__ import absolute_import
|
||||
from setuptools import setup
|
||||
|
||||
PACKAGE_NAME = 'mozprofile'
|
||||
PACKAGE_VERSION = '2.1.0'
|
||||
PACKAGE_VERSION = '2.2.0'
|
||||
|
||||
deps = [
|
||||
'mozfile>=1.2',
|
||||
|
Loading…
Reference in New Issue
Block a user