Update On Tue Dec 3 19:21:39 CET 2024
This commit is contained in:
parent
3ebe7961ce
commit
9410b96786
487 changed files with 26230 additions and 19985 deletions
|
@ -463,7 +463,7 @@ const CacheDomain = {
|
|||
};
|
||||
|
||||
function accessibleTask(doc, task, options = {}) {
|
||||
return async function () {
|
||||
const wrapped = async function () {
|
||||
let cacheDomains;
|
||||
if (!("cacheDomains" in options)) {
|
||||
cacheDomains = CacheDomain.All;
|
||||
|
@ -615,6 +615,16 @@ function accessibleTask(doc, task, options = {}) {
|
|||
await runPython(`__reset__`);
|
||||
}
|
||||
};
|
||||
// Propagate the name of the task function to our wrapper function so it shows
|
||||
// up in test run output. For example:
|
||||
// 0:39.16 INFO Entering test bound testProtected
|
||||
// Even if the name is empty, we still propagate it here to override the
|
||||
// implicit "wrapped" name derived from the assignment at the top of this
|
||||
// function.
|
||||
// The "name" property of functions is not writable, but we can override that
|
||||
// using Object.defineProperty.
|
||||
Object.defineProperty(wrapped, "name", { value: task.name });
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2021,6 +2021,12 @@ pref("pdfjs.handleOctetStream", true);
|
|||
// Is the sidebar positioned ahead of the content browser
|
||||
pref("sidebar.position_start", true);
|
||||
pref("sidebar.revamp", false);
|
||||
// This is nightly only for now, as we need to address bug 1933527 and bug 1934039.
|
||||
#ifdef NIGHTLY_BUILD
|
||||
pref("sidebar.revamp.round-content-area", true);
|
||||
#else
|
||||
pref("sidebar.revamp.round-content-area", false);
|
||||
#endif
|
||||
pref("sidebar.animation.enabled", true);
|
||||
pref("sidebar.animation.duration-ms", 200);
|
||||
pref("sidebar.main.tools", "aichat,syncedtabs,history");
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"use strict";
|
||||
|
||||
/* import-globals-from aboutDialog-appUpdater.js */
|
||||
/* import-globals-from utilityOverlay.js */
|
||||
|
||||
// Services = object with smart getters for common XPCOM services
|
||||
var { AppConstants } = ChromeUtils.importESModule(
|
||||
|
@ -117,6 +118,38 @@ function init() {
|
|||
if (AppConstants.IS_ESR) {
|
||||
document.getElementById("release").hidden = false;
|
||||
}
|
||||
|
||||
document
|
||||
.getElementById("aboutDialogEscapeKey")
|
||||
.addEventListener("command", () => {
|
||||
window.close();
|
||||
});
|
||||
if (AppConstants.MOZ_UPDATER) {
|
||||
document
|
||||
.getElementById("aboutDialogHelpLink")
|
||||
.addEventListener("click", () => {
|
||||
openHelpLink("firefox-help");
|
||||
});
|
||||
document
|
||||
.getElementById("submit-feedback")
|
||||
.addEventListener("click", openFeedbackPage);
|
||||
document
|
||||
.getElementById("checkForUpdatesButton")
|
||||
.addEventListener("command", () => {
|
||||
gAppUpdater.checkForUpdates();
|
||||
});
|
||||
document
|
||||
.getElementById("downloadAndInstallButton")
|
||||
.addEventListener("command", () => {
|
||||
gAppUpdater.startDownload();
|
||||
});
|
||||
document.getElementById("updateButton").addEventListener("command", () => {
|
||||
gAppUpdater.buttonRestartAfterDownload();
|
||||
});
|
||||
window.addEventListener("unload", e => {
|
||||
onUnload(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
|
|
|
@ -8,9 +8,6 @@
|
|||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
id="aboutDialog"
|
||||
windowtype="Browser:About"
|
||||
#ifdef MOZ_UPDATER
|
||||
onunload="onUnload(event);"
|
||||
#endif
|
||||
#ifndef XP_MACOSX
|
||||
data-l10n-id="aboutDialog-title"
|
||||
#endif
|
||||
|
@ -65,18 +62,14 @@
|
|||
<deck id="updateDeck" orient="vertical">
|
||||
<description id="checkForUpdates">
|
||||
<button id="checkForUpdatesButton"
|
||||
data-l10n-id="update-checkForUpdatesButton"
|
||||
oncommand="gAppUpdater.checkForUpdates();"/>
|
||||
data-l10n-id="update-checkForUpdatesButton"/>
|
||||
</description>
|
||||
<description id="downloadAndInstall">
|
||||
<button id="downloadAndInstallButton"
|
||||
oncommand="gAppUpdater.startDownload();"/>
|
||||
<!-- label and accesskey will be filled by JS -->
|
||||
<button id="downloadAndInstallButton"/>
|
||||
</description>
|
||||
<description id="apply">
|
||||
<button id="updateButton"
|
||||
data-l10n-id="update-updateButton"
|
||||
oncommand="gAppUpdater.buttonRestartAfterDownload();"/>
|
||||
data-l10n-id="update-updateButton"/>
|
||||
</description>
|
||||
<description id="checkingForUpdates" data-l10n-id="update-checkingForUpdates"/>
|
||||
<description id="downloading" data-l10n-id="aboutdialog-update-downloading" data-l10n-args='{"transfer":""}'>
|
||||
|
@ -108,8 +101,8 @@
|
|||
<label id="releasenotes" is="text-link" hidden="true" data-l10n-id="releaseNotes-link"/>
|
||||
</hbox>
|
||||
<description class="text-blurb">
|
||||
<label is="text-link" onclick="openHelpLink('firefox-help')" data-l10n-id="aboutdialog-help-user"/>
|
||||
<label id="submit-feedback" is="text-link" onclick="openFeedbackPage()" data-l10n-id="aboutdialog-submit-feedback"/>
|
||||
<label id="aboutDialogHelpLink" is="text-link" data-l10n-id="aboutdialog-help-user"/>
|
||||
<label id="submit-feedback" is="text-link" data-l10n-id="aboutdialog-submit-feedback"/>
|
||||
</description>
|
||||
</vbox>
|
||||
#endif
|
||||
|
@ -151,7 +144,7 @@
|
|||
</html:div>
|
||||
|
||||
<keyset>
|
||||
<key keycode="VK_ESCAPE" oncommand="window.close();"/>
|
||||
<key id="aboutDialogEscapeKey" keycode="VK_ESCAPE"/>
|
||||
</keyset>
|
||||
|
||||
<script src="chrome://browser/content/aboutDialog.js"/>
|
||||
|
|
|
@ -134,16 +134,17 @@ document.addEventListener(
|
|||
BookmarksEventHandler.onMouseUp(event);
|
||||
});
|
||||
|
||||
mainMenuBar.addEventListener("dragover", event =>
|
||||
const bookmarksMenu = document.getElementById("bookmarksMenu");
|
||||
bookmarksMenu.addEventListener("dragover", event =>
|
||||
PlacesMenuDNDHandler.onDragOver(event)
|
||||
);
|
||||
mainMenuBar.addEventListener("dragenter", event =>
|
||||
bookmarksMenu.addEventListener("dragenter", event =>
|
||||
PlacesMenuDNDHandler.onDragEnter(event)
|
||||
);
|
||||
mainMenuBar.addEventListener("dragleave", event =>
|
||||
bookmarksMenu.addEventListener("dragleave", event =>
|
||||
PlacesMenuDNDHandler.onDragLeave(event)
|
||||
);
|
||||
mainMenuBar.addEventListener("drop", event =>
|
||||
bookmarksMenu.addEventListener("drop", event =>
|
||||
PlacesMenuDNDHandler.onDrop(event)
|
||||
);
|
||||
|
||||
|
|
|
@ -5787,6 +5787,13 @@ export var DefaultBrowserCheck = {
|
|||
win.MozXULElement.insertFTLIfNeeded(
|
||||
"browser/defaultBrowserNotification.ftl"
|
||||
);
|
||||
// Record default prompt impression
|
||||
let now = Math.floor(Date.now() / 1000).toString();
|
||||
Services.prefs.setCharPref(
|
||||
"browser.shell.mostRecentDefaultPromptSeen",
|
||||
now
|
||||
);
|
||||
|
||||
// Resolve the translations for the prompt elements and return only the
|
||||
// string values
|
||||
|
||||
|
@ -5867,6 +5874,7 @@ export var DefaultBrowserCheck = {
|
|||
}
|
||||
if (checkboxState) {
|
||||
shellService.shouldCheckDefaultBrowser = false;
|
||||
Services.prefs.setCharPref("browser.shell.userDisabledDefaultCheck", now);
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
@ -1,16 +1,85 @@
|
|||
# Remote CFR Messages
|
||||
Starting in Firefox 68, CFR messages will be defined using [Remote Settings](https://remote-settings.readthedocs.io/en/latest/index.html). In this document, we'll cover how to set up a dev environment.
|
||||
Starting in Firefox 68, CFR messages will be defined using [Remote Settings](https://remote-settings.readthedocs.io/en/latest/index.html).
|
||||
|
||||
## Using a dev server for Remote CFR
|
||||
|
||||
> Note: Since Novembre 2021, Remote Settings has a proper DEV instance, which is
|
||||
> reachable without VPN, but has the same config (openid, multi-signoff, ...)
|
||||
> and collections as STAGE/PROD.
|
||||
## Environments
|
||||
There are three environments available for Remote Settings:
|
||||
* DEV - `https://remote-settings-dev.allizom.org/v1/`
|
||||
* STAGING - `https://remote-settings.allizom.org/v1/`
|
||||
* PROD - `https://remote-settings.mozilla.org/v1/`
|
||||
|
||||
DEV is primarily used for testing the Remote Settings API and exploring new use cases. Messaging validation and QA are conducted in the STAGING environment, while finalized and validated messages are delivered in the PROD environment. Both STAGING and PROD follow the [Multi Signoff Workflow](https://remote-settings.readthedocs.io/en/latest/tutorial-multi-signoff.html). During the review process, messages are served in the `main-preview` bucket. Once reviewed, they are moved to the `main` bucket.
|
||||
|
||||
Access to STAGING and PROD environments requires VPN (using "Viscosity VPN," which can be requested via the Jira Service Desk). However, the DEV environment is accessible without VPN.
|
||||
|
||||
To switch between environments more easily, you can use the [remote-settings-devtools](https://github.com/mozilla-extensions/remote-settings-devtools) extension. After installation, click on the extension in your browser to open its UI. The devtools provide a dropdown menu to switch between environments (`prod`, `prod-preview`, `staging`, `staging-preview`, `dev`, and `dev-preview`) and automatically update the necessary preferences for each environment.
|
||||
|
||||
To easily change between these environments, the [remote-settings-devtools](https://github.com/mozilla-extensions/remote-settings-devtools) extension is available. Once installed, you can click on the extensions list in the browser, select `remote-settings-devtools` to interact with the devtools UI. The devtools allows you to switch between environments on your profile through the drop-down menu and will take care of correctly flipping all the required prefs. Specifically, it will allow you to point to `prod`, `prod-preview`, `staging`, `staging-preview`, `dev` and `dev-preview`.
|
||||
|
||||
Alternatively, it is possible to switch between environments by updating the following prefs in `about:config`:
|
||||
* `services.settings.default_bucket`: `main` or `main-preview`
|
||||
* `services.settings.server`: the applicable environment URL
|
||||
|
||||
For release and ESR, for security reasons, you will also need to run the application through the command line with `MOZ_REMOTE_SETTINGS_DEVTOOLS=1` environment variable for the preferences to be taken into account. Note that toggling the preference won’t have any effect until restart.
|
||||
|
||||
## Add Message using Remote Settings Admin UI
|
||||
|
||||
1. **Log in to the Remote Settings Admin UI**
|
||||
- Use your LDAP identity to log in and start testing in [STAGING](https://remote-settings.allizom.org/v1/admin/#/).
|
||||
|
||||
2. **Add Messaging System JSON**
|
||||
- On the left-hand side, under the **Workspace** bucket, click on the `cfr` collection.
|
||||
- Select `Create record` to open a text field.
|
||||
- Paste valid [Messaging System JSON](https://firefox-source-docs.mozilla.org/toolkit/components/messaging-system/docs/index.html) into the text field.
|
||||
- Ensure the following fields are accurate:
|
||||
- `id`: Unique identifier for the message.
|
||||
- `last_modified`: Current date and time in milliseconds.
|
||||
- These fields will be visible in the **Records** column.
|
||||
|
||||
3. **Preview testing**
|
||||
- Follow the [Multi Signoff Workflow](https://remote-settings.readthedocs.io/en/latest/tutorial-multi-signoff.html), add the message into preview by putting into review, it will be served in the `main-preview` bucket.
|
||||
- Install the [Remote Settings DevTools](https://github.com/mozilla-extensions/remote-settings-devtools).
|
||||
- Use the dev tools to point to `staging-preview`.
|
||||
- In `about:config`, enable the following preference:
|
||||
```
|
||||
browser.newtabpage.activity-stream.asrouter.devtoolsEnabled
|
||||
```
|
||||
- Go to `about:asrouter`.
|
||||
- Under the **Message** tab:
|
||||
- Filter the **Providers** for `cfr` to view the message in ASRouter.
|
||||
|
||||
4. **Main testing**
|
||||
- If the message looks good, switch to the **Review** tab in Remote Settings.
|
||||
- Have a peer review the changes.
|
||||
- Once the review has been approved, we can test the message again, pointing to `staging` instead of `staging-preview`.
|
||||
|
||||
5. **Deploy to PROD**
|
||||
- Follow the same steps for the [PROD Environment](https://remote-settings.mozilla.org/v1/admin/#/).
|
||||
- Use the `prod-preview` and `prod` buckets for final testing and deployment.
|
||||
|
||||
## Remote l10n
|
||||
By default, all CFR messages are localized with the remote Fluent files hosted in `ms-language-packs` collection on Remote Settings using the [ms-language-packs script](https://github.com/mozilla-services/ms-language-packs?tab=readme-ov-file#messaging-system-language-packs-for-remote-settings).
|
||||
|
||||
We can check which components of the messages are hooked up to RemoteL10n with the following [Searchfox regex query](https://searchfox.org/mozilla-central/search?q=lazy%5C.RemoteL10n%5C.%28formatLocalizableText%7CcreateElement%29&path=&case=false®exp=true). For example Infobar buttons are currently not Remotel10n configurable, see [Bug 1933819](https://bugzilla.mozilla.org/show_bug.cgi?id=1933819).
|
||||
|
||||
For local testing and development, we can force ASRouter to use the local Fluent files by flipping the pref `browser.newtabpage.activity-stream.asrouter.useRemoteL10n` in `about:config`. A note that [RemoteL10n uses the `main` bucket](https://searchfox.org/mozilla-central/source/browser/components/asrouter/modules/ASRouter.sys.mjs#297) so we cannot test using `main-preview`.
|
||||
|
||||
## The following are steps on how to authenticate and add messages manually
|
||||
|
||||
**1. Obtain your Bearer Token**
|
||||
This can be done through browser-based authentication or through the Admin portal.
|
||||
|
||||
Until [Bug 1630651](https://bugzilla.mozilla.org/show_bug.cgi?id=1630651) happens, the easiest way to obtain your OpenID credentials is to use the admin interface.
|
||||
### Browser-based authentication
|
||||
1. Ensure you have [kinto-http](https://pypi.org/project/kinto-http/) python library installed
|
||||
2. In your terminal, run `python` with the following:
|
||||
```python
|
||||
>>> import kinto_http
|
||||
>>> c = kinto_http.Client(server_url='https://remote-settings-dev.allizom.org/v1', auth=kinto_http.BrowserOAuth())
|
||||
>>> c.server_info()["user"]
|
||||
```
|
||||
3. This will open the browser with a login successful page with your credentials in the terminal
|
||||
|
||||
### Admin portal
|
||||
1. [Login on the Admin UI](https://remote-settings-dev.allizom.org/v1/admin/) using your LDAP identity
|
||||
2. Copy the authentication header (📋 icon in the top bar)
|
||||
3. Test your credentials with ``curl``. When reaching out the server root URL with this bearer token you should see a ``user`` entry whose ``id`` field is ``ldap:<you>@mozilla.com``.
|
||||
|
@ -24,8 +93,6 @@ curl -s ${SERVER}/ -H "Authorization:${BEARER_TOKEN}" | jq .user
|
|||
|
||||
**2. Create/Update/Delete CFR entries**
|
||||
|
||||
> The messages can also be created manually using the [admin interface](https://settings.dev.mozaws.net/v1/admin/).
|
||||
|
||||
In following example, we will create a new entry using the REST API (reusing `SERVER` and `BEARER_TOKEN` from previous step).
|
||||
|
||||
```bash
|
||||
|
@ -72,11 +139,3 @@ Services.prefs.setBoolPref("browser.newtabpage.activity-stream.asrouter.devtools
|
|||
|
||||
**4. Go to `about:asrouter`**
|
||||
There should be a "cfr-remote" provider listed.
|
||||
|
||||
## Using the staging server for Remote CFR
|
||||
|
||||
If your message is published in the staging environment the easiest way to test is using the [Remote Settings Devtools](https://github.com/mozilla/remote-settings-devtools/releases) addon. You can install this by going to `about:debugging` and using the `Load Temporary Addon` feature.
|
||||
The devtools allow you to switch your profile between production and staging and takes care of correctly flipping all the required preferences.
|
||||
|
||||
## Remote l10n
|
||||
By default, all CFR messages are localized with the remote Fluent files hosted in `ms-language-packs` on Remote Settings. For local test and development, you can force ASRouter to use the local Fluent files by flipping the pref `browser.newtabpage.activity-stream.asrouter.useRemoteL10n`.
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -40,7 +40,7 @@ export class _CustomizeMenu extends React.PureComponent {
|
|||
className="icon icon-settings personalize-button"
|
||||
onClick={() => this.props.onOpen()}
|
||||
onKeyDown={e => {
|
||||
if (e.key === 13) {
|
||||
if (e.key === "Enter") {
|
||||
this.props.onOpen();
|
||||
}
|
||||
}}
|
||||
|
|
|
@ -10772,7 +10772,7 @@ class _CustomizeMenu extends (external_React_default()).PureComponent {
|
|||
className: "icon icon-settings personalize-button",
|
||||
onClick: () => this.props.onOpen(),
|
||||
onKeyDown: e => {
|
||||
if (e.key === 13) {
|
||||
if (e.key === "Enter") {
|
||||
this.props.onOpen();
|
||||
}
|
||||
},
|
||||
|
|
|
@ -422,6 +422,20 @@ export const PREFS_CONFIG = new Map([
|
|||
value: false,
|
||||
},
|
||||
],
|
||||
[
|
||||
"newtabAdSize.leaderboard",
|
||||
{
|
||||
title: "Boolean flag to turn the leaderboard ad size on and off",
|
||||
value: false,
|
||||
},
|
||||
],
|
||||
[
|
||||
"newtabAdSize.billboard",
|
||||
{
|
||||
title: "Boolean flag to turn the billboard ad size on and off",
|
||||
value: false,
|
||||
},
|
||||
],
|
||||
[
|
||||
"newtabLayouts.variant-a",
|
||||
{
|
||||
|
|
|
@ -31,6 +31,8 @@ https_first_disabled = true
|
|||
|
||||
["browser_customize_menu_render.js"]
|
||||
|
||||
["browser_customize_menu_key_open.js"]
|
||||
|
||||
["browser_discovery_card.js"]
|
||||
|
||||
["browser_discovery_render.js"]
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
"use strict";
|
||||
|
||||
// Test that the customization menu is rendered.
|
||||
test_newtab({
|
||||
async before() {
|
||||
gBrowser.selectedBrowser.focus();
|
||||
},
|
||||
test: async function test_open_customizeMenu() {
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() => content.document.querySelector(".personalize-button"),
|
||||
"Wait for personalize button to load on the newtab page"
|
||||
);
|
||||
|
||||
let defaultPos = "matrix(1, 0, 0, 1, 0, 0)";
|
||||
Assert.notStrictEqual(
|
||||
content.getComputedStyle(
|
||||
content.document.querySelector(".customize-menu")
|
||||
).transform,
|
||||
defaultPos,
|
||||
"Customize Menu should be rendered, but not visible"
|
||||
);
|
||||
|
||||
let customizeButton = content.document.querySelector(".personalize-button");
|
||||
customizeButton.focus();
|
||||
await EventUtils.synthesizeKey("KEY_Enter", {}, content.window);
|
||||
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() => content.document.querySelector(".customize-animate-enter-done"),
|
||||
"Customize Menu should be rendered now"
|
||||
);
|
||||
},
|
||||
});
|
|
@ -21,7 +21,7 @@ test_newtab({
|
|||
customizeButton.click();
|
||||
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() => content.document.querySelector(".customize-menu"),
|
||||
() => content.document.querySelector(".customize-animate-enter-done"),
|
||||
"Customize Menu should be rendered now"
|
||||
);
|
||||
},
|
||||
|
|
|
@ -209,14 +209,14 @@ class SessionStoreTestCase(WindowManagerMixin, MarionetteTestCase):
|
|||
|
||||
return opened_windows
|
||||
|
||||
def _close_tab_shortcut(self):
|
||||
self.marionette.actions.sequence("key", "keyboard_id").key_down(
|
||||
self.accelKey
|
||||
).key_down("w").key_up("w").key_up(self.accelKey).perform()
|
||||
def _close_last_tab(self):
|
||||
# "self.marionette.close" cannot be used because it doesn't
|
||||
# allow closing the very last tab.
|
||||
self.marionette.execute_script("window.close()")
|
||||
|
||||
def close_all_tabs_and_restart(self):
|
||||
self.close_all_tabs()
|
||||
self.marionette.quit(callback=self._close_tab_shortcut)
|
||||
self.marionette.quit(callback=self._close_last_tab)
|
||||
self.marionette.start_session()
|
||||
|
||||
def simulate_os_shutdown(self):
|
||||
|
|
|
@ -207,6 +207,35 @@ add_task(async function showDefaultPrompt() {
|
|||
await BrowserTestUtils.closeWindow(win2);
|
||||
});
|
||||
|
||||
add_task(async function promptStoresImpressionAndDisableTimestamps() {
|
||||
await showAndWaitForModal(win => {
|
||||
const dialog = win.document.querySelector("dialog");
|
||||
dialog.querySelector("checkbox").click();
|
||||
dialog.getButton("cancel").click();
|
||||
});
|
||||
|
||||
const impressionTimestamp = Services.prefs.getCharPref(
|
||||
"browser.shell.mostRecentDefaultPromptSeen"
|
||||
);
|
||||
const disabledTimestamp = Services.prefs.getCharPref(
|
||||
"browser.shell.userDisabledDefaultCheck"
|
||||
);
|
||||
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
const oneHourInMs = 60 * 60 * 1000;
|
||||
|
||||
Assert.ok(
|
||||
impressionTimestamp &&
|
||||
now - parseInt(impressionTimestamp, 10) <= oneHourInMs,
|
||||
"Prompt impression timestamp is stored"
|
||||
);
|
||||
|
||||
Assert.ok(
|
||||
disabledTimestamp && now - parseInt(disabledTimestamp, 10) <= oneHourInMs,
|
||||
"Selecting checkbox stores timestamp of when user disabled the prompt"
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function showPromptStyleSpotlight() {
|
||||
let sandbox = sinon.createSandbox();
|
||||
|
||||
|
|
|
@ -1120,7 +1120,7 @@ suggest_relevance:
|
|||
notification_emails:
|
||||
- disco-team@mozilla.com
|
||||
- najiang@mozilla.com
|
||||
expires: 136
|
||||
expires: 139
|
||||
data_sensitivity:
|
||||
- technical
|
||||
outcome:
|
||||
|
@ -1140,7 +1140,7 @@ suggest_relevance:
|
|||
notification_emails:
|
||||
- disco-team@mozilla.com
|
||||
- najiang@mozilla.com
|
||||
expires: 136
|
||||
expires: 139
|
||||
data_sensitivity:
|
||||
- technical
|
||||
|
||||
|
|
|
@ -2,4 +2,4 @@ ${DEB_PKG_NAME} (${DEB_PKG_VERSION}) UNRELEASED; urgency=medium
|
|||
|
||||
* N/A
|
||||
|
||||
-- Mozilla Releng <release@mozilla.com> ${DEB_CHANGELOG_DATE}
|
||||
-- Mozilla <release@mozilla.com> ${DEB_CHANGELOG_DATE}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Source: ${DEB_PKG_NAME}
|
||||
Maintainer: Mozilla Releng <release@mozilla.com>
|
||||
Maintainer: Mozilla <release@mozilla.com>
|
||||
Priority: optional
|
||||
Section: web
|
||||
Build-Depends: debhelper (>= 9)
|
||||
|
|
|
@ -2,4 +2,4 @@ ${DEB_PKG_NAME} (${DEB_PKG_VERSION}) UNRELEASED; urgency=medium
|
|||
|
||||
* N/A
|
||||
|
||||
-- Mozilla Releng <release@mozilla.com> ${DEB_CHANGELOG_DATE}
|
||||
-- Mozilla <release@mozilla.com> ${DEB_CHANGELOG_DATE}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Source: ${DEB_PKG_NAME}
|
||||
Maintainer: Mozilla Releng <release@mozilla.com>
|
||||
Maintainer: Mozilla <release@mozilla.com>
|
||||
Priority: optional
|
||||
Section: web
|
||||
Build-Depends: debhelper (>= 9)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"af": {
|
||||
"pin": false,
|
||||
|
@ -35,7 +35,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"an": {
|
||||
"pin": false,
|
||||
|
@ -54,7 +54,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ar": {
|
||||
"pin": false,
|
||||
|
@ -73,7 +73,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ast": {
|
||||
"pin": false,
|
||||
|
@ -92,7 +92,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"az": {
|
||||
"pin": false,
|
||||
|
@ -111,7 +111,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"be": {
|
||||
"pin": false,
|
||||
|
@ -130,7 +130,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"bg": {
|
||||
"pin": false,
|
||||
|
@ -149,7 +149,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"bn": {
|
||||
"pin": false,
|
||||
|
@ -168,7 +168,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"bo": {
|
||||
"pin": false,
|
||||
|
@ -187,7 +187,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"br": {
|
||||
"pin": false,
|
||||
|
@ -206,7 +206,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"brx": {
|
||||
"pin": false,
|
||||
|
@ -225,7 +225,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"bs": {
|
||||
"pin": false,
|
||||
|
@ -244,7 +244,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ca": {
|
||||
"pin": false,
|
||||
|
@ -263,7 +263,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ca-valencia": {
|
||||
"pin": false,
|
||||
|
@ -282,7 +282,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"cak": {
|
||||
"pin": false,
|
||||
|
@ -301,7 +301,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ckb": {
|
||||
"pin": false,
|
||||
|
@ -320,7 +320,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"cs": {
|
||||
"pin": false,
|
||||
|
@ -339,7 +339,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"cy": {
|
||||
"pin": false,
|
||||
|
@ -358,7 +358,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"da": {
|
||||
"pin": false,
|
||||
|
@ -377,7 +377,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"de": {
|
||||
"pin": false,
|
||||
|
@ -396,7 +396,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"dsb": {
|
||||
"pin": false,
|
||||
|
@ -415,7 +415,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"el": {
|
||||
"pin": false,
|
||||
|
@ -434,7 +434,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"en-CA": {
|
||||
"pin": false,
|
||||
|
@ -453,7 +453,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"en-GB": {
|
||||
"pin": false,
|
||||
|
@ -472,7 +472,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"eo": {
|
||||
"pin": false,
|
||||
|
@ -491,7 +491,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"es-AR": {
|
||||
"pin": false,
|
||||
|
@ -510,7 +510,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"es-CL": {
|
||||
"pin": false,
|
||||
|
@ -529,7 +529,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"es-ES": {
|
||||
"pin": false,
|
||||
|
@ -548,7 +548,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"es-MX": {
|
||||
"pin": false,
|
||||
|
@ -567,7 +567,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"et": {
|
||||
"pin": false,
|
||||
|
@ -586,7 +586,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"eu": {
|
||||
"pin": false,
|
||||
|
@ -605,7 +605,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"fa": {
|
||||
"pin": false,
|
||||
|
@ -624,7 +624,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ff": {
|
||||
"pin": false,
|
||||
|
@ -643,7 +643,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"fi": {
|
||||
"pin": false,
|
||||
|
@ -662,7 +662,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"fr": {
|
||||
"pin": false,
|
||||
|
@ -681,7 +681,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"fur": {
|
||||
"pin": false,
|
||||
|
@ -700,7 +700,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"fy-NL": {
|
||||
"pin": false,
|
||||
|
@ -719,7 +719,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ga-IE": {
|
||||
"pin": false,
|
||||
|
@ -738,7 +738,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"gd": {
|
||||
"pin": false,
|
||||
|
@ -757,7 +757,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"gl": {
|
||||
"pin": false,
|
||||
|
@ -776,7 +776,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"gn": {
|
||||
"pin": false,
|
||||
|
@ -795,7 +795,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"gu-IN": {
|
||||
"pin": false,
|
||||
|
@ -814,7 +814,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"he": {
|
||||
"pin": false,
|
||||
|
@ -833,7 +833,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"hi-IN": {
|
||||
"pin": false,
|
||||
|
@ -852,7 +852,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"hr": {
|
||||
"pin": false,
|
||||
|
@ -871,7 +871,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"hsb": {
|
||||
"pin": false,
|
||||
|
@ -890,7 +890,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"hu": {
|
||||
"pin": false,
|
||||
|
@ -909,7 +909,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"hy-AM": {
|
||||
"pin": false,
|
||||
|
@ -928,7 +928,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"hye": {
|
||||
"pin": false,
|
||||
|
@ -947,7 +947,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ia": {
|
||||
"pin": false,
|
||||
|
@ -966,7 +966,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"id": {
|
||||
"pin": false,
|
||||
|
@ -985,7 +985,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"is": {
|
||||
"pin": false,
|
||||
|
@ -1004,7 +1004,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"it": {
|
||||
"pin": false,
|
||||
|
@ -1023,7 +1023,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ja": {
|
||||
"pin": false,
|
||||
|
@ -1040,7 +1040,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ja-JP-mac": {
|
||||
"pin": false,
|
||||
|
@ -1048,7 +1048,7 @@
|
|||
"macosx64",
|
||||
"macosx64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ka": {
|
||||
"pin": false,
|
||||
|
@ -1067,7 +1067,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"kab": {
|
||||
"pin": false,
|
||||
|
@ -1086,7 +1086,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"kk": {
|
||||
"pin": false,
|
||||
|
@ -1105,7 +1105,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"km": {
|
||||
"pin": false,
|
||||
|
@ -1124,7 +1124,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"kn": {
|
||||
"pin": false,
|
||||
|
@ -1143,7 +1143,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ko": {
|
||||
"pin": false,
|
||||
|
@ -1162,7 +1162,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"lij": {
|
||||
"pin": false,
|
||||
|
@ -1181,7 +1181,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"lo": {
|
||||
"pin": false,
|
||||
|
@ -1200,7 +1200,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"lt": {
|
||||
"pin": false,
|
||||
|
@ -1219,7 +1219,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ltg": {
|
||||
"pin": false,
|
||||
|
@ -1238,7 +1238,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"lv": {
|
||||
"pin": false,
|
||||
|
@ -1257,7 +1257,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"meh": {
|
||||
"pin": false,
|
||||
|
@ -1276,7 +1276,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"mk": {
|
||||
"pin": false,
|
||||
|
@ -1295,7 +1295,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"mr": {
|
||||
"pin": false,
|
||||
|
@ -1314,7 +1314,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ms": {
|
||||
"pin": false,
|
||||
|
@ -1333,7 +1333,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"my": {
|
||||
"pin": false,
|
||||
|
@ -1352,7 +1352,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"nb-NO": {
|
||||
"pin": false,
|
||||
|
@ -1371,7 +1371,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ne-NP": {
|
||||
"pin": false,
|
||||
|
@ -1390,7 +1390,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"nl": {
|
||||
"pin": false,
|
||||
|
@ -1409,7 +1409,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"nn-NO": {
|
||||
"pin": false,
|
||||
|
@ -1428,7 +1428,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"oc": {
|
||||
"pin": false,
|
||||
|
@ -1447,7 +1447,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"pa-IN": {
|
||||
"pin": false,
|
||||
|
@ -1466,7 +1466,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"pl": {
|
||||
"pin": false,
|
||||
|
@ -1485,7 +1485,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"pt-BR": {
|
||||
"pin": false,
|
||||
|
@ -1504,7 +1504,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"pt-PT": {
|
||||
"pin": false,
|
||||
|
@ -1523,7 +1523,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"rm": {
|
||||
"pin": false,
|
||||
|
@ -1542,7 +1542,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ro": {
|
||||
"pin": false,
|
||||
|
@ -1561,7 +1561,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ru": {
|
||||
"pin": false,
|
||||
|
@ -1580,7 +1580,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"sat": {
|
||||
"pin": false,
|
||||
|
@ -1599,7 +1599,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"sc": {
|
||||
"pin": false,
|
||||
|
@ -1618,7 +1618,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"scn": {
|
||||
"pin": false,
|
||||
|
@ -1637,7 +1637,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"sco": {
|
||||
"pin": false,
|
||||
|
@ -1656,7 +1656,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"si": {
|
||||
"pin": false,
|
||||
|
@ -1675,7 +1675,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"sk": {
|
||||
"pin": false,
|
||||
|
@ -1694,7 +1694,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"skr": {
|
||||
"pin": false,
|
||||
|
@ -1713,7 +1713,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"sl": {
|
||||
"pin": false,
|
||||
|
@ -1732,7 +1732,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"son": {
|
||||
"pin": false,
|
||||
|
@ -1751,7 +1751,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"sq": {
|
||||
"pin": false,
|
||||
|
@ -1770,7 +1770,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"sr": {
|
||||
"pin": false,
|
||||
|
@ -1789,7 +1789,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"sv-SE": {
|
||||
"pin": false,
|
||||
|
@ -1808,7 +1808,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"szl": {
|
||||
"pin": false,
|
||||
|
@ -1827,7 +1827,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ta": {
|
||||
"pin": false,
|
||||
|
@ -1846,7 +1846,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"te": {
|
||||
"pin": false,
|
||||
|
@ -1865,7 +1865,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"tg": {
|
||||
"pin": false,
|
||||
|
@ -1884,7 +1884,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"th": {
|
||||
"pin": false,
|
||||
|
@ -1903,7 +1903,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"tl": {
|
||||
"pin": false,
|
||||
|
@ -1922,7 +1922,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"tr": {
|
||||
"pin": false,
|
||||
|
@ -1941,7 +1941,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"trs": {
|
||||
"pin": false,
|
||||
|
@ -1960,7 +1960,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"uk": {
|
||||
"pin": false,
|
||||
|
@ -1979,7 +1979,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"ur": {
|
||||
"pin": false,
|
||||
|
@ -1998,7 +1998,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"uz": {
|
||||
"pin": false,
|
||||
|
@ -2017,7 +2017,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"vi": {
|
||||
"pin": false,
|
||||
|
@ -2036,7 +2036,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"wo": {
|
||||
"pin": false,
|
||||
|
@ -2055,7 +2055,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"xh": {
|
||||
"pin": false,
|
||||
|
@ -2074,7 +2074,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"zh-CN": {
|
||||
"pin": false,
|
||||
|
@ -2093,7 +2093,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
},
|
||||
"zh-TW": {
|
||||
"pin": false,
|
||||
|
@ -2112,6 +2112,6 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "075b103699fb2a73e322f2e3698297b14624b3ed"
|
||||
"revision": "c78c0710ab06c5911899748bf91d019673912d10"
|
||||
}
|
||||
}
|
|
@ -71,14 +71,17 @@
|
|||
outline: 0.01px solid var(--chrome-content-separator-color);
|
||||
box-shadow: var(--content-area-shadow);
|
||||
|
||||
:root:not([inDOMFullscreen]) &[sidebar-shown] {
|
||||
overflow: clip;
|
||||
border-start-end-radius: var(--border-radius-medium);
|
||||
/* stylelint-disable-next-line media-query-no-invalid */
|
||||
@media (-moz-bool-pref: "sidebar.revamp.round-content-area") {
|
||||
:root:not([inDOMFullscreen]) &[sidebar-shown] {
|
||||
overflow: clip;
|
||||
border-start-end-radius: var(--border-radius-medium);
|
||||
|
||||
/* stylelint-disable-next-line media-query-no-invalid */
|
||||
@media (-moz-bool-pref: "sidebar.position_start") {
|
||||
border-start-start-radius: var(--border-radius-medium);
|
||||
border-start-end-radius: 0;
|
||||
/* stylelint-disable-next-line media-query-no-invalid */
|
||||
@media (-moz-bool-pref: "sidebar.position_start") {
|
||||
border-start-start-radius: var(--border-radius-medium);
|
||||
border-start-end-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
- 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">
|
||||
<rect width="16" height="16" rx="4" stroke="context-stroke" stroke-width="1" fill="context-fill"/>
|
||||
<rect width="15" height="15" x="0.5" y="0.5" rx="4" stroke="context-stroke" stroke-width="1" fill="context-fill"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 409 B After Width: | Height: | Size: 425 B |
|
@ -1550,7 +1550,7 @@ toolbar:not(#TabsToolbar) #firefox-view-button {
|
|||
list-style-image: url("chrome://browser/skin/tabbrowser/tab-group-chicklet.svg");
|
||||
-moz-context-properties: fill, stroke;
|
||||
fill: light-dark(var(--tab-group-color), var(--tab-group-color-invert));
|
||||
stroke: transparent;
|
||||
stroke: light-dark(var(--tab-group-color), var(--tab-group-color-invert));
|
||||
}
|
||||
|
||||
.menu-iconic.tab-group-icon-collapsed,
|
||||
|
|
|
@ -162,6 +162,13 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
|
|||
clickOnAddonWidget(ADDON_ID);
|
||||
await onPopupMessage;
|
||||
|
||||
info("Assert the context of the evaluation context selector");
|
||||
const contextLabels = getContextLabels(toolbox);
|
||||
is(contextLabels.length, 3);
|
||||
is(contextLabels[0], "Web Extension Fallback Document");
|
||||
is(contextLabels[1], "/_generated_background_page.html");
|
||||
is(contextLabels[2], "/popup.html");
|
||||
|
||||
info("Wait a bit to catch unexpected duplicates or mixed up messages");
|
||||
await wait(1000);
|
||||
|
||||
|
@ -463,3 +470,12 @@ add_task(async function testWebExtensionTwoReloads() {
|
|||
await removeTemporaryExtension(BACKGROUND_ADDON_NAME, document);
|
||||
await removeTab(tab);
|
||||
});
|
||||
|
||||
function getContextLabels(toolbox) {
|
||||
// Note that the context menu is in the top level chrome document (toolbox.xhtml)
|
||||
// instead of webconsole.xhtml.
|
||||
const labels = toolbox.doc.querySelectorAll(
|
||||
"#webconsole-console-evaluation-context-selector-menu-list li .label"
|
||||
);
|
||||
return Array.from(labels).map(item => item.textContent);
|
||||
}
|
||||
|
|
|
@ -61,6 +61,15 @@ add_task(async function testOpenDebuggerReload() {
|
|||
"isWebExtension flag in sourcesTree is true"
|
||||
);
|
||||
|
||||
const descriptorTitle = devtoolsWindow.document.querySelector(
|
||||
".qa-descriptor-title"
|
||||
);
|
||||
is(
|
||||
descriptorTitle.textContent,
|
||||
EXTENSION_NAME,
|
||||
"The add-on name is displayed in the toolbox header"
|
||||
);
|
||||
|
||||
info("Check whether the element displays correctly");
|
||||
let sourceList = panelWin.document.querySelector(".sources-list");
|
||||
ok(sourceList, "Source list element displays correctly");
|
||||
|
@ -132,6 +141,24 @@ add_task(async function testAddAndRemoveBreakpoint() {
|
|||
const toolbox = getToolbox(devtoolsWindow);
|
||||
const dbg = createDebuggerContext(toolbox);
|
||||
|
||||
info("Assert the threads displayed in Source Tree as well as Threads pane");
|
||||
const sourceTreeThreads = findAllElements(dbg, "sourceTreeThreads");
|
||||
is(
|
||||
sourceTreeThreads.length,
|
||||
1,
|
||||
"There is only one thread with source in the Source Tree"
|
||||
);
|
||||
is(
|
||||
sourceTreeThreads[0].textContent,
|
||||
"/_generated_background_page.html",
|
||||
"That thread is the background page"
|
||||
);
|
||||
|
||||
const threadLabels = findAllElements(dbg, "threadsPaneItems");
|
||||
is(threadLabels.length, 2, "But there are two threads in the thread panel");
|
||||
is(threadLabels[0].textContent, "Web Extension Fallback Document");
|
||||
is(threadLabels[1].textContent, "/_generated_background_page.html");
|
||||
|
||||
info("Select the source and add a breakpoint");
|
||||
// Note: the background script filename is dynamically generated id, so we
|
||||
// simply get the first source from the list.
|
||||
|
|
|
@ -50,7 +50,11 @@ add_task(async function testWebExtensionsToolboxNoBackgroundPage() {
|
|||
"Toolbox is debugging an addon"
|
||||
);
|
||||
const targetName = toolbox.target.name;
|
||||
is(targetName, ADDON_NOBG_NAME, "Toolbox has the expected target");
|
||||
is(
|
||||
targetName,
|
||||
"Web Extension Fallback Document",
|
||||
"Toolbox has the expected target"
|
||||
);
|
||||
|
||||
const inspector = await toolbox.selectTool("inspector");
|
||||
|
||||
|
|
65
devtools/client/debugger/dist/parser-worker.js
vendored
65
devtools/client/debugger/dist/parser-worker.js
vendored
|
@ -39088,14 +39088,6 @@ Please specify the "importAttributesKeyword" generator option, whose value can b
|
|||
extractFunctionSymbol(path, state, symbols);
|
||||
}
|
||||
|
||||
if (libExports$2.isJSXElement(path)) {
|
||||
symbols.hasJsx = true;
|
||||
}
|
||||
|
||||
if (libExports$2.isGenericTypeAnnotation(path)) {
|
||||
symbols.hasTypes = true;
|
||||
}
|
||||
|
||||
if (libExports$2.isClassDeclaration(path)) {
|
||||
symbols.classes.push(getClassDeclarationSymbol(path.node));
|
||||
}
|
||||
|
@ -39132,6 +39124,27 @@ Please specify the "importAttributesKeyword" generator option, whose value can b
|
|||
}
|
||||
|
||||
function extractSymbols(sourceId) {
|
||||
// This is used in the main thread by:
|
||||
// * The `getFunctionSymbols` function which is used by the Outline, QuickOpen panels.
|
||||
// * The `getClosestFunctionName` function used in the mapping of frame function names.
|
||||
// * The `findOutOfScopeLocations` function use to determine in scope lines.
|
||||
// functions: symbols.functions,
|
||||
// The three following attributes are only used by `findBestMatchExpression` within the worker thread
|
||||
// `memberExpressions`, `literals`, `identifiers`
|
||||
//
|
||||
// These three memberExpressions, literals and identifiers attributes are arrays containing objects whose attributes are:
|
||||
// * name: string
|
||||
// * location: object {start: number, end: number}
|
||||
// * expression: string
|
||||
// * computed: boolean (only for memberExpressions)
|
||||
//
|
||||
// `findBestMatchExpression` uses `location`, `computed` and `expression` (not name).
|
||||
// `expression` isn't used from the worker thread implementation of `findBestMatchExpression`.
|
||||
// The main thread only uses `expression` and `location`.
|
||||
// This is used by the `getClassSymbols` function in the Outline panel
|
||||
// `classes`
|
||||
// This is only used by `findOutOfScopeLocations`:
|
||||
// `comments`
|
||||
const symbols = {
|
||||
functions: [],
|
||||
memberExpressions: [],
|
||||
|
@ -39142,8 +39155,6 @@ Please specify the "importAttributesKeyword" generator option, whose value can b
|
|||
identifiersKeys: new Set(),
|
||||
classes: [],
|
||||
literals: [],
|
||||
hasJsx: false,
|
||||
hasTypes: false,
|
||||
importsReact: false,
|
||||
};
|
||||
|
||||
|
@ -39431,38 +39442,10 @@ Please specify the "importAttributesKeyword" generator option, whose value can b
|
|||
}
|
||||
|
||||
// This is only called from the main thread and we return a subset of attributes
|
||||
// Note: This is now used just to trigger the parser
|
||||
function getSymbols(sourceId) {
|
||||
const symbols = getInternalSymbols(sourceId);
|
||||
return {
|
||||
// This is used in the main thread by:
|
||||
// * The `getFunctionSymbols` function which is used by the Outline, QuickOpen panels.
|
||||
// * The `getClosestFunctionName` function used in the mapping of frame function names.
|
||||
// * The `findOutOfScopeLocations` function use to determine in scope lines.
|
||||
// functions: symbols.functions,
|
||||
|
||||
// The three following attributes are only used by `findBestMatchExpression` within the worker thread
|
||||
// `memberExpressions`, `literals`, `identifiers`
|
||||
//
|
||||
// These three memberExpressions, literals and identifiers attributes are arrays containing objects whose attributes are:
|
||||
// * name: string
|
||||
// * location: object {start: number, end: number}
|
||||
// * expression: string
|
||||
// * computed: boolean (only for memberExpressions)
|
||||
//
|
||||
// `findBestMatchExpression` uses `location`, `computed` and `expression` (not name).
|
||||
// `expression` isn't used from the worker thread implementation of `findBestMatchExpression`.
|
||||
// The main thread only uses `expression` and `location`.
|
||||
|
||||
// This is used by the `getClassSymbols` function in the Outline panel
|
||||
// `classes`
|
||||
|
||||
// The two following are only used by the main thread for computing CodeMirror "mode"
|
||||
hasJsx: symbols.hasJsx,
|
||||
hasTypes: symbols.hasTypes,
|
||||
|
||||
// This is only used by `findOutOfScopeLocations`:
|
||||
// `comments`
|
||||
};
|
||||
getInternalSymbols(sourceId);
|
||||
return {};
|
||||
}
|
||||
|
||||
function getMemberExpressionSymbol(path) {
|
||||
|
|
|
@ -390,9 +390,14 @@ export async function createPause(threadActorID, pausedThreadState) {
|
|||
}
|
||||
|
||||
export function createThread(targetFront) {
|
||||
const name = targetFront.isTopLevel
|
||||
? L10N.getStr("mainThread")
|
||||
: targetFront.name;
|
||||
// When debugging a Web Extension, the top level target is always the fallback document.
|
||||
// It isn't really a top level document as it won't be the parent of any other.
|
||||
// So only print its name.
|
||||
const name =
|
||||
targetFront.isTopLevel &&
|
||||
!targetFront.commands.descriptorFront.isWebExtension
|
||||
? L10N.getStr("mainThread")
|
||||
: targetFront.name;
|
||||
|
||||
return {
|
||||
actor: targetFront.targetForm.threadActor,
|
||||
|
|
|
@ -24,7 +24,6 @@ import {
|
|||
getSelectedSourceTextContent,
|
||||
getSelectedBreakableLines,
|
||||
getConditionalPanelLocation,
|
||||
getSymbols,
|
||||
getIsCurrentThreadPaused,
|
||||
getSkipPausing,
|
||||
getInlinePreview,
|
||||
|
@ -113,7 +112,6 @@ class Editor extends PureComponent {
|
|||
updateCursorPosition: PropTypes.func.isRequired,
|
||||
jumpToMappedLocation: PropTypes.func.isRequired,
|
||||
selectedLocation: PropTypes.object,
|
||||
symbols: PropTypes.object,
|
||||
startPanelSize: PropTypes.number.isRequired,
|
||||
endPanelSize: PropTypes.number.isRequired,
|
||||
searchInFileEnabled: PropTypes.bool.isRequired,
|
||||
|
@ -140,6 +138,7 @@ class Editor extends PureComponent {
|
|||
// FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=1774507
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
let { editor } = this.state;
|
||||
const prevEditor = editor;
|
||||
|
||||
if (!editor) {
|
||||
// See Bug 1913061
|
||||
|
@ -158,7 +157,7 @@ class Editor extends PureComponent {
|
|||
if (shouldUpdateSize) {
|
||||
editor.codeMirror.setSize();
|
||||
}
|
||||
this.setTextContent(nextProps, editor);
|
||||
this.setTextContent(nextProps, editor, prevEditor);
|
||||
endOperation();
|
||||
|
||||
if (this.props.selectedSource != nextProps.selectedSource) {
|
||||
|
@ -168,16 +167,17 @@ class Editor extends PureComponent {
|
|||
}
|
||||
} else {
|
||||
// For codemirror 6
|
||||
this.setTextContent(nextProps, editor);
|
||||
this.setTextContent(nextProps, editor, prevEditor);
|
||||
}
|
||||
}
|
||||
|
||||
async setTextContent(nextProps, editor) {
|
||||
async setTextContent(nextProps, editor, prevEditor) {
|
||||
const shouldUpdateText =
|
||||
nextProps.selectedSource !== this.props.selectedSource ||
|
||||
nextProps.selectedSourceTextContent?.value !==
|
||||
this.props.selectedSourceTextContent?.value ||
|
||||
nextProps.symbols !== this.props.symbols;
|
||||
// If the selectedSource gets set before the editor get selected, make sure we update the text
|
||||
prevEditor !== editor;
|
||||
|
||||
const shouldScroll =
|
||||
nextProps.selectedLocation &&
|
||||
|
@ -727,9 +727,8 @@ class Editor extends PureComponent {
|
|||
!selectedSourceTextContent?.value &&
|
||||
nextProps.selectedSourceTextContent?.value;
|
||||
const locationChanged = selectedLocation !== nextProps.selectedLocation;
|
||||
const symbolsChanged = nextProps.symbols != this.props.symbols;
|
||||
|
||||
return contentChanged || locationChanged || symbolsChanged;
|
||||
return contentChanged || locationChanged;
|
||||
}
|
||||
|
||||
scrollToLocation(nextProps, editor) {
|
||||
|
@ -746,7 +745,7 @@ class Editor extends PureComponent {
|
|||
}
|
||||
|
||||
async setText(props, editor) {
|
||||
const { selectedSource, selectedSourceTextContent, symbols } = props;
|
||||
const { selectedSource, selectedSourceTextContent } = props;
|
||||
|
||||
if (!editor) {
|
||||
return;
|
||||
|
@ -776,12 +775,7 @@ class Editor extends PureComponent {
|
|||
}
|
||||
|
||||
if (!features.codemirrorNext) {
|
||||
showSourceText(
|
||||
editor,
|
||||
selectedSource,
|
||||
selectedSourceTextContent,
|
||||
symbols
|
||||
);
|
||||
showSourceText(editor, selectedSource, selectedSourceTextContent);
|
||||
} else {
|
||||
await editor.setText(
|
||||
selectedSourceTextContent.value.value,
|
||||
|
@ -1038,7 +1032,6 @@ const mapStateToProps = state => {
|
|||
isSourceOnSourceMapIgnoreList(state, selectedSource),
|
||||
searchInFileEnabled: getActiveSearch(state) === "file",
|
||||
conditionalPanelLocation: getConditionalPanelLocation(state),
|
||||
symbols: getSymbols(state, selectedLocation),
|
||||
isPaused: getIsCurrentThreadPaused(state),
|
||||
isTraceSelected: getSelectedTraceIndex(state) != null,
|
||||
skipPausing: getSkipPausing(state),
|
||||
|
|
|
@ -1,70 +1,5 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`visible column breakpoints doesnt show breakpoints to the right in CM5 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"breakpoint": Object {
|
||||
"disabled": false,
|
||||
"generatedLocation": Object {
|
||||
"column": 1,
|
||||
"line": 1,
|
||||
"source": Object {
|
||||
"displayURL": Object {
|
||||
"fileExtension": "",
|
||||
"filename": "url",
|
||||
"group": "",
|
||||
"path": "url",
|
||||
"search": "",
|
||||
},
|
||||
"extensionName": null,
|
||||
"id": "foo",
|
||||
"isExtension": false,
|
||||
"isOriginal": false,
|
||||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"longName": "url",
|
||||
"shortName": "url",
|
||||
"thread": "FakeThread",
|
||||
"url": "url",
|
||||
},
|
||||
},
|
||||
"id": "breakpoint",
|
||||
"location": Object {
|
||||
"column": 1,
|
||||
"line": 1,
|
||||
"source": Object {
|
||||
"displayURL": Object {
|
||||
"fileExtension": "",
|
||||
"filename": "url",
|
||||
"group": "",
|
||||
"path": "url",
|
||||
"search": "",
|
||||
},
|
||||
"extensionName": null,
|
||||
"id": "foo",
|
||||
"isExtension": false,
|
||||
"isOriginal": false,
|
||||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"longName": "url",
|
||||
"shortName": "url",
|
||||
"thread": "FakeThread",
|
||||
"url": "url",
|
||||
},
|
||||
},
|
||||
"options": Object {},
|
||||
"originalText": "text",
|
||||
"text": "text",
|
||||
},
|
||||
"location": Object {
|
||||
"column": 1,
|
||||
"line": 1,
|
||||
"sourceId": "foo",
|
||||
},
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`visible column breakpoints ignores single breakpoints 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
|
@ -211,6 +146,131 @@ Array [
|
|||
]
|
||||
`;
|
||||
|
||||
exports[`visible column breakpoints show all breakpoints including those to the right in CM6 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"breakpoint": Object {
|
||||
"disabled": false,
|
||||
"generatedLocation": Object {
|
||||
"column": 1,
|
||||
"line": 1,
|
||||
"source": Object {
|
||||
"displayURL": Object {
|
||||
"fileExtension": "",
|
||||
"filename": "url",
|
||||
"group": "",
|
||||
"path": "url",
|
||||
"search": "",
|
||||
},
|
||||
"extensionName": null,
|
||||
"id": "foo",
|
||||
"isExtension": false,
|
||||
"isOriginal": false,
|
||||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"longName": "url",
|
||||
"shortName": "url",
|
||||
"thread": "FakeThread",
|
||||
"url": "url",
|
||||
},
|
||||
},
|
||||
"id": "breakpoint",
|
||||
"location": Object {
|
||||
"column": 1,
|
||||
"line": 1,
|
||||
"source": Object {
|
||||
"displayURL": Object {
|
||||
"fileExtension": "",
|
||||
"filename": "url",
|
||||
"group": "",
|
||||
"path": "url",
|
||||
"search": "",
|
||||
},
|
||||
"extensionName": null,
|
||||
"id": "foo",
|
||||
"isExtension": false,
|
||||
"isOriginal": false,
|
||||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"longName": "url",
|
||||
"shortName": "url",
|
||||
"thread": "FakeThread",
|
||||
"url": "url",
|
||||
},
|
||||
},
|
||||
"options": Object {},
|
||||
"originalText": "text",
|
||||
"text": "text",
|
||||
},
|
||||
"location": Object {
|
||||
"column": 1,
|
||||
"line": 1,
|
||||
"sourceId": "foo",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"breakpoint": Object {
|
||||
"disabled": false,
|
||||
"generatedLocation": Object {
|
||||
"column": 15,
|
||||
"line": 1,
|
||||
"source": Object {
|
||||
"displayURL": Object {
|
||||
"fileExtension": "",
|
||||
"filename": "url",
|
||||
"group": "",
|
||||
"path": "url",
|
||||
"search": "",
|
||||
},
|
||||
"extensionName": null,
|
||||
"id": "foo",
|
||||
"isExtension": false,
|
||||
"isOriginal": false,
|
||||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"longName": "url",
|
||||
"shortName": "url",
|
||||
"thread": "FakeThread",
|
||||
"url": "url",
|
||||
},
|
||||
},
|
||||
"id": "breakpoint",
|
||||
"location": Object {
|
||||
"column": 15,
|
||||
"line": 1,
|
||||
"source": Object {
|
||||
"displayURL": Object {
|
||||
"fileExtension": "",
|
||||
"filename": "url",
|
||||
"group": "",
|
||||
"path": "url",
|
||||
"search": "",
|
||||
},
|
||||
"extensionName": null,
|
||||
"id": "foo",
|
||||
"isExtension": false,
|
||||
"isOriginal": false,
|
||||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"longName": "url",
|
||||
"shortName": "url",
|
||||
"thread": "FakeThread",
|
||||
"url": "url",
|
||||
},
|
||||
},
|
||||
"options": Object {},
|
||||
"originalText": "text",
|
||||
"text": "text",
|
||||
},
|
||||
"location": Object {
|
||||
"column": 15,
|
||||
"line": 1,
|
||||
"sourceId": "foo",
|
||||
},
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`visible column breakpoints simple 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
|
|
|
@ -91,7 +91,7 @@ const nonJSLanguageExtensionMap = new Map([
|
|||
* Returns Code Mirror mode for source content type
|
||||
*/
|
||||
// eslint-disable-next-line complexity
|
||||
export function getMode(source, sourceTextContent, symbols) {
|
||||
export function getMode(source, sourceTextContent) {
|
||||
const content = sourceTextContent.value;
|
||||
// Disable modes for minified files with 1+ million characters (See Bug 1569829).
|
||||
if (
|
||||
|
@ -107,18 +107,15 @@ export function getMode(source, sourceTextContent, symbols) {
|
|||
}
|
||||
|
||||
const extension = source.displayURL.fileExtension;
|
||||
if (extension === "jsx" || (symbols && symbols.hasJsx)) {
|
||||
if (symbols && symbols.hasTypes) {
|
||||
return contentTypeModeMap.get("text/typescript-jsx");
|
||||
}
|
||||
if (extension === "jsx") {
|
||||
return contentTypeModeMap.get("text/jsx");
|
||||
}
|
||||
|
||||
if (symbols && symbols.hasTypes) {
|
||||
if (symbols.hasJsx) {
|
||||
return contentTypeModeMap.get("text/typescript-jsx");
|
||||
}
|
||||
if (extension === "tsx") {
|
||||
return contentTypeModeMap.get("text/typescript-jsx");
|
||||
}
|
||||
|
||||
if (extension === "ts") {
|
||||
return contentTypeModeMap.get("text/typescript");
|
||||
}
|
||||
|
||||
|
@ -159,8 +156,8 @@ export function getMode(source, sourceTextContent, symbols) {
|
|||
return contentTypeModeMap.get("text/plain");
|
||||
}
|
||||
|
||||
function setMode(editor, source, sourceTextContent, symbols) {
|
||||
const mode = getMode(source, sourceTextContent, symbols);
|
||||
function setMode(editor, source, sourceTextContent) {
|
||||
const mode = getMode(source, sourceTextContent);
|
||||
const currentMode = editor.codeMirror.getOption("mode");
|
||||
if (!currentMode || currentMode.name != mode.name) {
|
||||
editor.setMode(mode);
|
||||
|
@ -171,17 +168,17 @@ function setMode(editor, source, sourceTextContent, symbols) {
|
|||
* Handle getting the source document or creating a new
|
||||
* document with the correct mode and text.
|
||||
*/
|
||||
export function showSourceText(editor, source, sourceTextContent, symbols) {
|
||||
export function showSourceText(editor, source, sourceTextContent) {
|
||||
if (hasDocument(source.id)) {
|
||||
const doc = getDocument(source.id);
|
||||
if (editor.codeMirror.doc === doc) {
|
||||
setMode(editor, source, sourceTextContent, symbols);
|
||||
setMode(editor, source, sourceTextContent);
|
||||
return;
|
||||
}
|
||||
|
||||
editor.replaceDocument(doc);
|
||||
updateLineNumberFormat(editor, source.id);
|
||||
setMode(editor, source, sourceTextContent, symbols);
|
||||
setMode(editor, source, sourceTextContent);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -191,7 +188,7 @@ export function showSourceText(editor, source, sourceTextContent, symbols) {
|
|||
// We can set wasm text content directly from the constructor, so we pass an empty string
|
||||
// here, and set the text after replacing the document.
|
||||
content.type !== "wasm" ? content.value : "",
|
||||
getMode(source, sourceTextContent, symbols)
|
||||
getMode(source, sourceTextContent)
|
||||
);
|
||||
|
||||
setDocument(source.id, doc);
|
||||
|
|
|
@ -9,18 +9,6 @@ import {
|
|||
makeMockWasmSourceWithContent,
|
||||
} from "../../test-mockup";
|
||||
|
||||
const defaultSymbolDeclarations = {
|
||||
classes: [],
|
||||
functions: [],
|
||||
memberExpressions: [],
|
||||
objectProperties: [],
|
||||
identifiers: [],
|
||||
comments: [],
|
||||
literals: [],
|
||||
hasJsx: false,
|
||||
hasTypes: false,
|
||||
};
|
||||
|
||||
describe("source-documents", () => {
|
||||
describe("getMode", () => {
|
||||
it("//", () => {
|
||||
|
@ -79,21 +67,6 @@ describe("source-documents", () => {
|
|||
expect(getMode(source, source.content)).toEqual({ name: "jsx" });
|
||||
});
|
||||
|
||||
it("returns jsx if sourceMetaData says it's a react component", () => {
|
||||
const source = makeMockSourceWithContent(
|
||||
undefined,
|
||||
undefined,
|
||||
"",
|
||||
"<h1></h1>"
|
||||
);
|
||||
expect(
|
||||
getMode(source, source.content, {
|
||||
...defaultSymbolDeclarations,
|
||||
hasJsx: true,
|
||||
})
|
||||
).toEqual({ name: "jsx" });
|
||||
});
|
||||
|
||||
it("returns jsx if the fileExtension is .jsx", () => {
|
||||
const source = makeMockSourceWithContent(
|
||||
"myComponent.jsx",
|
||||
|
|
|
@ -48,14 +48,6 @@ function extractSymbol(path, symbols, state) {
|
|||
extractFunctionSymbol(path, state, symbols);
|
||||
}
|
||||
|
||||
if (t.isJSXElement(path)) {
|
||||
symbols.hasJsx = true;
|
||||
}
|
||||
|
||||
if (t.isGenericTypeAnnotation(path)) {
|
||||
symbols.hasTypes = true;
|
||||
}
|
||||
|
||||
if (t.isClassDeclaration(path)) {
|
||||
symbols.classes.push(getClassDeclarationSymbol(path.node));
|
||||
}
|
||||
|
@ -92,6 +84,27 @@ function extractSymbol(path, symbols, state) {
|
|||
}
|
||||
|
||||
function extractSymbols(sourceId) {
|
||||
// This is used in the main thread by:
|
||||
// * The `getFunctionSymbols` function which is used by the Outline, QuickOpen panels.
|
||||
// * The `getClosestFunctionName` function used in the mapping of frame function names.
|
||||
// * The `findOutOfScopeLocations` function use to determine in scope lines.
|
||||
// functions: symbols.functions,
|
||||
// The three following attributes are only used by `findBestMatchExpression` within the worker thread
|
||||
// `memberExpressions`, `literals`, `identifiers`
|
||||
//
|
||||
// These three memberExpressions, literals and identifiers attributes are arrays containing objects whose attributes are:
|
||||
// * name: string
|
||||
// * location: object {start: number, end: number}
|
||||
// * expression: string
|
||||
// * computed: boolean (only for memberExpressions)
|
||||
//
|
||||
// `findBestMatchExpression` uses `location`, `computed` and `expression` (not name).
|
||||
// `expression` isn't used from the worker thread implementation of `findBestMatchExpression`.
|
||||
// The main thread only uses `expression` and `location`.
|
||||
// This is used by the `getClassSymbols` function in the Outline panel
|
||||
// `classes`
|
||||
// This is only used by `findOutOfScopeLocations`:
|
||||
// `comments`
|
||||
const symbols = {
|
||||
functions: [],
|
||||
memberExpressions: [],
|
||||
|
@ -102,8 +115,6 @@ function extractSymbols(sourceId) {
|
|||
identifiersKeys: new Set(),
|
||||
classes: [],
|
||||
literals: [],
|
||||
hasJsx: false,
|
||||
hasTypes: false,
|
||||
importsReact: false,
|
||||
};
|
||||
|
||||
|
@ -391,38 +402,10 @@ export function getClosestFunctionName(location) {
|
|||
}
|
||||
|
||||
// This is only called from the main thread and we return a subset of attributes
|
||||
// Note: This is now used just to trigger the parser
|
||||
export function getSymbols(sourceId) {
|
||||
const symbols = getInternalSymbols(sourceId);
|
||||
return {
|
||||
// This is used in the main thread by:
|
||||
// * The `getFunctionSymbols` function which is used by the Outline, QuickOpen panels.
|
||||
// * The `getClosestFunctionName` function used in the mapping of frame function names.
|
||||
// * The `findOutOfScopeLocations` function use to determine in scope lines.
|
||||
// functions: symbols.functions,
|
||||
|
||||
// The three following attributes are only used by `findBestMatchExpression` within the worker thread
|
||||
// `memberExpressions`, `literals`, `identifiers`
|
||||
//
|
||||
// These three memberExpressions, literals and identifiers attributes are arrays containing objects whose attributes are:
|
||||
// * name: string
|
||||
// * location: object {start: number, end: number}
|
||||
// * expression: string
|
||||
// * computed: boolean (only for memberExpressions)
|
||||
//
|
||||
// `findBestMatchExpression` uses `location`, `computed` and `expression` (not name).
|
||||
// `expression` isn't used from the worker thread implementation of `findBestMatchExpression`.
|
||||
// The main thread only uses `expression` and `location`.
|
||||
|
||||
// This is used by the `getClassSymbols` function in the Outline panel
|
||||
// `classes`
|
||||
|
||||
// The two following are only used by the main thread for computing CodeMirror "mode"
|
||||
hasJsx: symbols.hasJsx,
|
||||
hasTypes: symbols.hasTypes,
|
||||
|
||||
// This is only used by `findOutOfScopeLocations`:
|
||||
// `comments`
|
||||
};
|
||||
getInternalSymbols(sourceId);
|
||||
return {};
|
||||
}
|
||||
|
||||
function getMemberExpressionSymbol(path) {
|
||||
|
|
|
@ -1,127 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Parser.getSymbols allSymbols 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols call expression 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols call sites 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols class 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols component 1`] = `
|
||||
"hasJsx: true
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols destruct 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols es6 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols expression 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols finds symbols in an html file 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols flow 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: true"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols func 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols function names 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols jsx 1`] = `
|
||||
"hasJsx: true
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols math 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols object expressions 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols optional chaining 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols private fields 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols proto 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols react component 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols regexp 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols var 1`] = `
|
||||
"hasJsx: false
|
||||
|
||||
hasTypes: false"
|
||||
`;
|
|
@ -1,51 +0,0 @@
|
|||
/* eslint max-nested-callbacks: ["error", 4]*/
|
||||
/* 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/>. */
|
||||
|
||||
import { formatSymbols } from "../utils/formatSymbols";
|
||||
import { populateSource, populateOriginalSource } from "./helpers";
|
||||
import cases from "jest-in-case";
|
||||
|
||||
cases(
|
||||
"Parser.getSymbols",
|
||||
({ file, original, type }) => {
|
||||
const source = original
|
||||
? populateOriginalSource(file, type)
|
||||
: populateSource(file, type);
|
||||
|
||||
expect(formatSymbols(source.id)).toMatchSnapshot();
|
||||
},
|
||||
[
|
||||
{ name: "es6", file: "es6", original: true },
|
||||
{ name: "func", file: "func", original: true },
|
||||
{ name: "function names", file: "functionNames", original: true },
|
||||
{ name: "math", file: "math" },
|
||||
{ name: "proto", file: "proto" },
|
||||
{ name: "class", file: "class", original: true },
|
||||
{ name: "var", file: "var" },
|
||||
{ name: "expression", file: "expression" },
|
||||
{ name: "allSymbols", file: "allSymbols" },
|
||||
{ name: "call sites", file: "call-sites" },
|
||||
{ name: "call expression", file: "callExpressions" },
|
||||
{ name: "object expressions", file: "object-expressions" },
|
||||
{ name: "optional chaining", file: "optional-chaining" },
|
||||
{ name: "private fields", file: "private-fields" },
|
||||
{
|
||||
name: "finds symbols in an html file",
|
||||
file: "parseScriptTags",
|
||||
type: "html",
|
||||
},
|
||||
{ name: "component", file: "component", original: true },
|
||||
{
|
||||
name: "react component",
|
||||
file: "frameworks/reactComponent",
|
||||
original: true,
|
||||
},
|
||||
{ name: "flow", file: "flow", original: true },
|
||||
{ name: "jsx", file: "jsx", original: true },
|
||||
{ name: "destruct", file: "destructuring" },
|
||||
|
||||
{ name: "regexp", file: "regexp" },
|
||||
]
|
||||
);
|
|
@ -1,56 +0,0 @@
|
|||
/* 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/>. */
|
||||
|
||||
import { getSymbols } from "../getSymbols";
|
||||
|
||||
function formatLocation(loc) {
|
||||
if (!loc) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const { start, end } = loc;
|
||||
const startLoc = `(${start.line}, ${start.column})`;
|
||||
const endLoc = `(${end.line}, ${end.column})`;
|
||||
|
||||
return `[${startLoc}, ${endLoc}]`;
|
||||
}
|
||||
|
||||
function summarize(symbol) {
|
||||
if (typeof symbol == "boolean") {
|
||||
return symbol ? "true" : "false";
|
||||
}
|
||||
|
||||
const loc = formatLocation(symbol.location);
|
||||
const params = symbol.parameterNames
|
||||
? `(${symbol.parameterNames.join(", ")})`
|
||||
: "";
|
||||
const expression = symbol.expression || "";
|
||||
const klass = symbol.klass || "";
|
||||
const name = symbol.name == undefined ? "" : symbol.name;
|
||||
const names = symbol.specifiers ? symbol.specifiers.join(", ") : "";
|
||||
const values = symbol.values ? symbol.values.join(", ") : "";
|
||||
const index = symbol.index ? symbol.index : "";
|
||||
|
||||
return `${loc} ${expression} ${name}${params} ${klass} ${names} ${values} ${index}`.trim(); // eslint-disable-line max-len
|
||||
}
|
||||
const bools = ["hasJsx", "hasTypes"];
|
||||
function formatBool(name, symbols) {
|
||||
return `${name}: ${symbols[name] ? "true" : "false"}`;
|
||||
}
|
||||
|
||||
function formatKey(name, symbols) {
|
||||
if (bools.includes(name)) {
|
||||
return formatBool(name, symbols);
|
||||
}
|
||||
|
||||
return `${name}:\n${symbols[name].map(summarize).join("\n")}`;
|
||||
}
|
||||
|
||||
export function formatSymbols(sourceId) {
|
||||
const symbols = getSymbols(sourceId);
|
||||
|
||||
return Object.keys(symbols)
|
||||
.map(name => formatKey(name, symbols))
|
||||
.join("\n\n");
|
||||
}
|
|
@ -193,11 +193,17 @@ add_task(async function () {
|
|||
});
|
||||
is(keyTrace.textContent, "DOM | global.keypress");
|
||||
|
||||
is(
|
||||
tracerTree.querySelectorAll(".trace-line").length,
|
||||
8,
|
||||
"The key event adds two elements in the tree. The DOM Event and its top frame"
|
||||
);
|
||||
info("Wait for the key listener function to be displayed");
|
||||
await waitFor(() => {
|
||||
// Scroll to bottom to ensure rendering the last elements (otherwise they are not because of VirtualizedTree)
|
||||
tracerTree.scrollTop = tracerTree.scrollHeight;
|
||||
const elements = tracerTree.querySelectorAll(".trace-line");
|
||||
// Wait for the expected element to be rendered
|
||||
if (elements[elements.length - 1].textContent.includes("keyListener")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
info("Trigger a DOM Mutation");
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () {
|
||||
|
|
|
@ -19,7 +19,7 @@ requestLongerTimeout(4);
|
|||
*/
|
||||
add_task(async function () {
|
||||
const ToolboxTask = await initBrowserToolboxTask();
|
||||
await ToolboxTask.importFunctions({ clickMeatballItem });
|
||||
await ToolboxTask.importFunctions({ waitUntil, clickMeatballItem });
|
||||
|
||||
is(getPseudoLocale(), "", "Starts out as empty");
|
||||
|
||||
|
@ -61,28 +61,25 @@ function getPseudoLocale() {
|
|||
*
|
||||
* @param {"accented" | "bidi"} type
|
||||
*/
|
||||
function clickMeatballItem(type) {
|
||||
return new Promise(resolve => {
|
||||
/* global gToolbox */
|
||||
async function clickMeatballItem(type) {
|
||||
/* global gToolbox */
|
||||
|
||||
dump(`Opening the meatball menu in the browser toolbox.\n`);
|
||||
gToolbox.doc.getElementById("toolbox-meatball-menu-button").click();
|
||||
|
||||
gToolbox.doc.addEventListener(
|
||||
"popupshown",
|
||||
async () => {
|
||||
const menuItem = gToolbox.doc.getElementById(
|
||||
"toolbox-meatball-menu-pseudo-locale-" + type
|
||||
);
|
||||
dump(`Clicking the meatball menu item: "${type}".\n`);
|
||||
menuItem.click();
|
||||
|
||||
// Request the pseudo-locale so that we know the preference actor is fully
|
||||
// done setting the debuggee browser.
|
||||
await gToolbox.getPseudoLocale();
|
||||
resolve();
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
const onPopupShown = new Promise(resolve => {
|
||||
gToolbox.doc.addEventListener("popupshown", resolve, { once: true });
|
||||
});
|
||||
dump(`Opening the meatball menu in the browser toolbox.\n`);
|
||||
gToolbox.doc.getElementById("toolbox-meatball-menu-button").click();
|
||||
await onPopupShown;
|
||||
|
||||
const menuItem = gToolbox.doc.getElementById(
|
||||
"toolbox-meatball-menu-pseudo-locale-" + type
|
||||
);
|
||||
dump(`Clicking the meatball menu item: "${type}".\n`);
|
||||
const checked = menuItem.getAttribute("aria-checked");
|
||||
menuItem.click();
|
||||
|
||||
dump(
|
||||
"Wait for the new setting to be applied by waiting for the UI to be updated after the action is done\n"
|
||||
);
|
||||
await waitUntil(() => menuItem.getAttribute("aria-checked") != checked);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ class DebugTargetInfo extends PureComponent {
|
|||
}).isRequired,
|
||||
descriptorType: PropTypes.oneOf(Object.values(DESCRIPTOR_TYPES))
|
||||
.isRequired,
|
||||
descriptorName: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
L10N: PropTypes.object.isRequired,
|
||||
toolbox: PropTypes.object.isRequired,
|
||||
|
@ -234,18 +235,21 @@ class DebugTargetInfo extends PureComponent {
|
|||
);
|
||||
}
|
||||
|
||||
renderTargetTitle() {
|
||||
const title = this.props.toolbox.target.name;
|
||||
renderDescriptorName() {
|
||||
const name = this.props.debugTargetData.descriptorName;
|
||||
|
||||
const { image, l10nId } = this.getAssetsForDebugDescriptorType();
|
||||
|
||||
return dom.span(
|
||||
{
|
||||
className: "iconized-label debug-target-title",
|
||||
className: "iconized-label debug-descriptor-title",
|
||||
},
|
||||
dom.img({ src: image, alt: this.props.L10N.getStr(l10nId) }),
|
||||
title
|
||||
? dom.b({ className: "devtools-ellipsis-text qa-target-title" }, title)
|
||||
name
|
||||
? dom.b(
|
||||
{ className: "devtools-ellipsis-text qa-descriptor-title" },
|
||||
name
|
||||
)
|
||||
: null
|
||||
);
|
||||
}
|
||||
|
@ -401,7 +405,7 @@ class DebugTargetInfo extends PureComponent {
|
|||
},
|
||||
this.shallRenderConnection() ? this.renderConnection() : null,
|
||||
this.renderRuntime(),
|
||||
this.renderTargetTitle(),
|
||||
this.renderDescriptorName(),
|
||||
this.renderNavigation(),
|
||||
this.renderTargetURI(),
|
||||
...this.renderAlwaysOnTopButton()
|
||||
|
|
|
@ -32,16 +32,16 @@ exports[`DebugTargetInfo component Connection info renders the expected snapshot
|
|||
</span>
|
||||
</span>
|
||||
<span
|
||||
className="iconized-label debug-target-title"
|
||||
className="iconized-label debug-descriptor-title"
|
||||
>
|
||||
<img
|
||||
alt="toolbox.debugTargetInfo.targetType.tab"
|
||||
src="chrome://devtools/skin/images/globe.svg"
|
||||
/>
|
||||
<b
|
||||
className="devtools-ellipsis-text qa-target-title"
|
||||
className="devtools-ellipsis-text qa-descriptor-title"
|
||||
>
|
||||
Test Tab Name
|
||||
Usb debugging context
|
||||
</b>
|
||||
</span>
|
||||
<div
|
||||
|
@ -128,16 +128,16 @@ exports[`DebugTargetInfo component Target icon renders the expected snapshot for
|
|||
</span>
|
||||
</span>
|
||||
<span
|
||||
className="iconized-label debug-target-title"
|
||||
className="iconized-label debug-descriptor-title"
|
||||
>
|
||||
<img
|
||||
alt="toolbox.debugTargetInfo.targetType.process"
|
||||
src="chrome://devtools/skin/images/settings.svg"
|
||||
/>
|
||||
<b
|
||||
className="devtools-ellipsis-text qa-target-title"
|
||||
className="devtools-ellipsis-text qa-descriptor-title"
|
||||
>
|
||||
Test Tab Name
|
||||
Usb debugging context
|
||||
</b>
|
||||
</span>
|
||||
<span
|
||||
|
@ -184,16 +184,16 @@ exports[`DebugTargetInfo component Target icon renders the expected snapshot for
|
|||
</span>
|
||||
</span>
|
||||
<span
|
||||
className="iconized-label debug-target-title"
|
||||
className="iconized-label debug-descriptor-title"
|
||||
>
|
||||
<img
|
||||
alt="toolbox.debugTargetInfo.targetType.tab"
|
||||
src="chrome://devtools/skin/images/globe.svg"
|
||||
/>
|
||||
<b
|
||||
className="devtools-ellipsis-text qa-target-title"
|
||||
className="devtools-ellipsis-text qa-descriptor-title"
|
||||
>
|
||||
Test Tab Name
|
||||
Usb debugging context
|
||||
</b>
|
||||
</span>
|
||||
<div
|
||||
|
@ -280,16 +280,16 @@ exports[`DebugTargetInfo component Target icon renders the expected snapshot for
|
|||
</span>
|
||||
</span>
|
||||
<span
|
||||
className="iconized-label debug-target-title"
|
||||
className="iconized-label debug-descriptor-title"
|
||||
>
|
||||
<img
|
||||
alt="toolbox.debugTargetInfo.targetType.worker"
|
||||
src="chrome://devtools/skin/images/debugging-workers.svg"
|
||||
/>
|
||||
<b
|
||||
className="devtools-ellipsis-text qa-target-title"
|
||||
className="devtools-ellipsis-text qa-descriptor-title"
|
||||
>
|
||||
Test Tab Name
|
||||
Usb debugging context
|
||||
</b>
|
||||
</span>
|
||||
<span
|
||||
|
@ -336,16 +336,16 @@ exports[`DebugTargetInfo component Target icon renders the expected snapshot for
|
|||
</span>
|
||||
</span>
|
||||
<span
|
||||
className="iconized-label debug-target-title"
|
||||
className="iconized-label debug-descriptor-title"
|
||||
>
|
||||
<img
|
||||
alt="toolbox.debugTargetInfo.targetType.extension"
|
||||
src="chrome://devtools/skin/images/debugging-addons.svg"
|
||||
/>
|
||||
<b
|
||||
className="devtools-ellipsis-text qa-target-title"
|
||||
className="devtools-ellipsis-text qa-descriptor-title"
|
||||
>
|
||||
Test Tab Name
|
||||
Usb debugging context
|
||||
</b>
|
||||
</span>
|
||||
<div
|
||||
|
@ -373,16 +373,16 @@ exports[`DebugTargetInfo component Target icon renders the expected snapshot for
|
|||
className="debug-target-info qa-debug-target-info"
|
||||
>
|
||||
<span
|
||||
className="iconized-label debug-target-title"
|
||||
className="iconized-label debug-descriptor-title"
|
||||
>
|
||||
<img
|
||||
alt="toolbox.debugTargetInfo.targetType.extension"
|
||||
src="chrome://devtools/skin/images/debugging-addons.svg"
|
||||
/>
|
||||
<b
|
||||
className="devtools-ellipsis-text qa-target-title"
|
||||
className="devtools-ellipsis-text qa-descriptor-title"
|
||||
>
|
||||
Test Tab Name
|
||||
This firefox first tab
|
||||
</b>
|
||||
</span>
|
||||
<div
|
||||
|
@ -429,16 +429,16 @@ exports[`DebugTargetInfo component Target title renders the expected snapshot fo
|
|||
/>
|
||||
</span>
|
||||
<span
|
||||
className="iconized-label debug-target-title"
|
||||
className="iconized-label debug-descriptor-title"
|
||||
>
|
||||
<img
|
||||
alt="toolbox.debugTargetInfo.targetType.tab"
|
||||
src="chrome://devtools/skin/images/globe.svg"
|
||||
/>
|
||||
<b
|
||||
className="devtools-ellipsis-text qa-target-title"
|
||||
className="devtools-ellipsis-text qa-descriptor-title"
|
||||
>
|
||||
Test Tab Name
|
||||
This firefox first tab
|
||||
</b>
|
||||
</span>
|
||||
<div
|
||||
|
@ -514,7 +514,7 @@ exports[`DebugTargetInfo component Target title renders the expected snapshot fo
|
|||
/>
|
||||
</span>
|
||||
<span
|
||||
className="iconized-label debug-target-title"
|
||||
className="iconized-label debug-descriptor-title"
|
||||
>
|
||||
<img
|
||||
alt="toolbox.debugTargetInfo.targetType.tab"
|
||||
|
|
|
@ -86,6 +86,7 @@ const USB_TARGET_INFO = {
|
|||
connectionType: CONNECTION_TYPES.USB,
|
||||
runtimeInfo: USB_DEVICE_DESCRIPTION,
|
||||
descriptorType: DESCRIPTOR_TYPES.TAB,
|
||||
descriptorName: "Usb debugging context",
|
||||
},
|
||||
toolbox: TEST_TOOLBOX,
|
||||
L10N: stubL10N,
|
||||
|
@ -96,6 +97,7 @@ const THIS_FIREFOX_TARGET_INFO = {
|
|||
connectionType: CONNECTION_TYPES.THIS_FIREFOX,
|
||||
runtimeInfo: THIS_FIREFOX_DEVICE_DESCRIPTION,
|
||||
descriptorType: DESCRIPTOR_TYPES.TAB,
|
||||
descriptorName: "This firefox first tab",
|
||||
},
|
||||
toolbox: TEST_TOOLBOX,
|
||||
L10N: stubL10N,
|
||||
|
@ -106,6 +108,7 @@ const THIS_FIREFOX_NO_NAME_TARGET_INFO = {
|
|||
connectionType: CONNECTION_TYPES.THIS_FIREFOX,
|
||||
runtimeInfo: THIS_FIREFOX_DEVICE_DESCRIPTION,
|
||||
descriptorType: DESCRIPTOR_TYPES.TAB,
|
||||
/* Avoid passing a name via 'descriptorName' attribute */
|
||||
},
|
||||
toolbox: TEST_TOOLBOX_NO_NAME,
|
||||
L10N: stubL10N,
|
||||
|
@ -140,9 +143,9 @@ describe("DebugTargetInfo component", () => {
|
|||
const component = renderer.create(
|
||||
DebugTargetInfo(THIS_FIREFOX_TARGET_INFO)
|
||||
);
|
||||
expect(findByClassName(component.root, "qa-target-title").length).toEqual(
|
||||
1
|
||||
);
|
||||
expect(
|
||||
findByClassName(component.root, "qa-descriptor-title").length
|
||||
).toEqual(1);
|
||||
});
|
||||
|
||||
it("renders the expected snapshot for This Firefox target", () => {
|
||||
|
@ -156,9 +159,9 @@ describe("DebugTargetInfo component", () => {
|
|||
const component = renderer.create(
|
||||
DebugTargetInfo(THIS_FIREFOX_NO_NAME_TARGET_INFO)
|
||||
);
|
||||
expect(findByClassName(component.root, "qa-target-title").length).toEqual(
|
||||
0
|
||||
);
|
||||
expect(
|
||||
findByClassName(component.root, "qa-descriptor-title").length
|
||||
).toEqual(0);
|
||||
});
|
||||
|
||||
it("renders the expected snapshot for a Toolbox with an unnamed target", () => {
|
||||
|
|
|
@ -1416,6 +1416,7 @@ Toolbox.prototype = {
|
|||
connectionType,
|
||||
runtimeInfo,
|
||||
descriptorType: this._descriptorFront.descriptorType,
|
||||
descriptorName: this._descriptorFront.name,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -3338,16 +3339,23 @@ Toolbox.prototype = {
|
|||
selectedTargetFront.name &&
|
||||
selectedTargetFront.name != selectedTargetFront.url
|
||||
) {
|
||||
// Only display the target `URL` when it isn't already the target `name`
|
||||
// For Web Extension, we remove the `moz-extension://${addon-uid}` from the URL
|
||||
const url = this._descriptorFront.isWebExtensionDescriptor
|
||||
? this.getExtensionPathName(selectedTargetFront.url)
|
||||
: getUnicodeUrl(selectedTargetFront.url);
|
||||
title = L10N.getFormatStr(
|
||||
"toolbox.titleTemplate2",
|
||||
selectedTargetFront.name,
|
||||
url
|
||||
);
|
||||
// For Web Extensions, the target name may only be the pathname of the target URL.
|
||||
// In such case, only print the absolute target url.
|
||||
if (
|
||||
this._descriptorFront.isWebExtensionDescriptor &&
|
||||
selectedTargetFront.url.includes(selectedTargetFront.name)
|
||||
) {
|
||||
title = L10N.getFormatStr(
|
||||
"toolbox.titleTemplate1",
|
||||
getUnicodeUrl(selectedTargetFront.url)
|
||||
);
|
||||
} else {
|
||||
title = L10N.getFormatStr(
|
||||
"toolbox.titleTemplate2",
|
||||
selectedTargetFront.name,
|
||||
getUnicodeUrl(selectedTargetFront.url)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
title = L10N.getFormatStr(
|
||||
"toolbox.titleTemplate1",
|
||||
|
|
|
@ -277,7 +277,23 @@ function TargetMixin(parentClass) {
|
|||
return this.typeName === "windowGlobalTarget";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name to be displayed in the debugger and console context selector.
|
||||
*/
|
||||
get name() {
|
||||
// When debugging Web Extensions, all documents have moz-extension://${uuid}/... URL
|
||||
// When the developer don't set a custom title, fallback on displaying the pathname
|
||||
// to avoid displaying long URL prefix with the addon internal UUID.
|
||||
if (this.commands.descriptorFront.isWebExtensionDescriptor) {
|
||||
if (this._title) {
|
||||
return this._title;
|
||||
}
|
||||
return URL.canParse(this._url)
|
||||
? new URL(this._url).pathname
|
||||
: // If document URL can't be parsed, fallback to the raw URL.
|
||||
this._url;
|
||||
}
|
||||
|
||||
if (this.isWebExtension || this.isContentProcess) {
|
||||
return this.targetForm.name;
|
||||
}
|
||||
|
|
|
@ -33,15 +33,6 @@ class PauseResumeButton extends PureComponent {
|
|||
|
||||
this.onKeyDown = this.onKeyDown.bind(this);
|
||||
this.pauseResumeButtonRef = createRef();
|
||||
|
||||
this.state = {
|
||||
isRunning: false,
|
||||
};
|
||||
}
|
||||
|
||||
// FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=1774507
|
||||
UNSAFE_componentWillMount() {
|
||||
this.updateState(this.props);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -49,10 +40,6 @@ class PauseResumeButton extends PureComponent {
|
|||
targetEl.addEventListener("keydown", this.onKeyDown);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
componentWillUnount() {
|
||||
const targetEl = this.getKeyEventTarget();
|
||||
targetEl.removeEventListener("keydown", this.onKeyDown);
|
||||
|
@ -64,8 +51,8 @@ class PauseResumeButton extends PureComponent {
|
|||
|
||||
onToggleAnimationsPlayState(event) {
|
||||
event.stopPropagation();
|
||||
const { setAnimationsPlayState } = this.props;
|
||||
const { isRunning } = this.state;
|
||||
const { setAnimationsPlayState, animations } = this.props;
|
||||
const isRunning = hasRunningAnimation(animations);
|
||||
|
||||
setAnimationsPlayState(!isRunning);
|
||||
}
|
||||
|
@ -80,14 +67,8 @@ class PauseResumeButton extends PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
updateState() {
|
||||
const { animations } = this.props;
|
||||
const isRunning = hasRunningAnimation(animations);
|
||||
this.setState({ isRunning });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isRunning } = this.state;
|
||||
const isRunning = hasRunningAnimation(this.props.animations);
|
||||
|
||||
return dom.button({
|
||||
className:
|
||||
|
|
|
@ -18,7 +18,6 @@ support-files = [
|
|||
["browser_fontinspector.js"]
|
||||
|
||||
["browser_fontinspector_all-fonts.js"]
|
||||
fail-if = ["a11y_checks"] # Bug 1849028 clicked element may not be focusable and/or labeled
|
||||
|
||||
["browser_fontinspector_copy-URL.js"]
|
||||
fail-if = ["a11y_checks"] # Bug 1849028 clicked element may not be focusable and/or labeled
|
||||
|
|
|
@ -125,7 +125,7 @@
|
|||
/*
|
||||
* XXX: This was added to match the padding 8px used by the reload button.
|
||||
* This padding makes the debug target component taller and also creates
|
||||
* spacing with the debug-target-title separator.
|
||||
* spacing with the debug-descriptor-title separator.
|
||||
* See Bug 1641920 for improving the CSS of the DebugTargetInfo component.
|
||||
*/
|
||||
.debug-target-info .debug-target-url-readonly {
|
||||
|
|
|
@ -110,9 +110,13 @@ class EvaluationContextSelector extends Component {
|
|||
renderMenuItem(target) {
|
||||
const { selectTarget, selectedTarget } = this.props;
|
||||
|
||||
const label = target.isTopLevel
|
||||
? l10n.getStr("webconsole.input.selector.top")
|
||||
: target.name;
|
||||
// When debugging a Web Extension, the top level target is always the fallback document.
|
||||
// It isn't really a top level document as it won't be the parent of any other.
|
||||
// So only print its name.
|
||||
const label =
|
||||
target.isTopLevel && !target.commands.descriptorFront.isWebExtension
|
||||
? l10n.getStr("webconsole.input.selector.top")
|
||||
: target.name;
|
||||
|
||||
return MenuItem({
|
||||
key: `webconsole-evaluation-selector-item-${target.actorID}`,
|
||||
|
@ -227,7 +231,14 @@ class EvaluationContextSelector extends Component {
|
|||
getLabel() {
|
||||
const { selectedTarget } = this.props;
|
||||
|
||||
if (!selectedTarget || selectedTarget.isTopLevel) {
|
||||
// When debugging a Web Extension, the top level target is always the fallback document.
|
||||
// It isn't really a top level document as it won't be the parent of any other.
|
||||
// So only print its name.
|
||||
if (
|
||||
!selectedTarget ||
|
||||
(selectedTarget.isTopLevel &&
|
||||
!selectedTarget.commands.descriptorFront.isWebExtension)
|
||||
) {
|
||||
return l10n.getStr("webconsole.input.selector.top");
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ For quick reference, here are some of the main code style rules:
|
|||
* getters / setters require { },
|
||||
* only import specific, explicitly-declared symbols into your namespace:
|
||||
* `const { foo, bar } = require("foo/bar");`,
|
||||
* `const { foo, bar } = ChromeUtils.import("...");`,
|
||||
* `const { foo, bar } = ChromeUtils.importESModule("...");`,
|
||||
* use Maps, Sets, WeakMaps when possible,
|
||||
* use [template strings](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) whenever possible to avoid concatenation, allow multi-line strings, and interpolation.
|
||||
|
||||
|
|
|
@ -36,11 +36,12 @@ Example:
|
|||
* `loader.lazyRequireGetter(this, "layout", "devtools/server/actors/layout")`
|
||||
* `require("devtools/server/actors/layout")`
|
||||
|
||||
### `ChromeUtils.import()`
|
||||
### `ChromeUtils.importESModule()`
|
||||
|
||||
Some older DevTools JS modules use the Gecko JavaScript code module format with the file extension `.jsm`. We are trying to move away from this format, so it's unlikely you would add a new one, but you might need to import an existing one in your code.
|
||||
Some DevTools modules use a variant of the standard ECMAScript module, with
|
||||
the file extension `.sys.mjs`.
|
||||
|
||||
These modules are loaded using `ChromeUtils.import()`. To `import()` a file, you provide a `resource://` URL, which is exactly the source tree path.
|
||||
These modules are loaded using `ChromeUtils.importESModule()`. To `importESModule()` a file, you provide a `resource://` URL, which is exactly the source tree path.
|
||||
|
||||
In more detail:
|
||||
|
||||
|
@ -56,10 +57,10 @@ Example:
|
|||
|
||||
Example:
|
||||
|
||||
* File: `/toolkit/mozapps/extensions/AddonManager.jsm`
|
||||
* File: `/toolkit/mozapps/extensions/AddonManager.sys.mjs`
|
||||
* Usage (prefer lazy in most cases):
|
||||
* `const lazy = {}; ChromeUtils.defineModuleGetter(lazy, "AddonManager", "resource://gre/modules/AddonManager.jsm")`
|
||||
* `const { AddonManager } = ChromeUtils.import("resource://gre/modules/AddonManager.jsm")`
|
||||
* `const lazy = {}; ChromeUtils.defineESModuleGetter(lazy, "AddonManager", "resource://gre/modules/AddonManager.sys.mjs")`
|
||||
* `const { AddonManager } = ChromeUtils.importESModule("resource://gre/modules/AddonManager.sys.mjs")`
|
||||
|
||||
## Chrome Content
|
||||
|
||||
|
|
|
@ -610,14 +610,8 @@ class WindowGlobalTargetActor extends BaseTargetActor {
|
|||
|
||||
/**
|
||||
* Getter for the window global's title.
|
||||
* For Web Extension it will ignore the document title and refer to the addon one.
|
||||
*/
|
||||
get title() {
|
||||
if (this.sessionContext.type == "webextension") {
|
||||
const policy = WebExtensionPolicy.getByID(this.sessionContext.addonId);
|
||||
// Note that the policy may be null if we query the title while the add-on is reloading
|
||||
return policy?.name;
|
||||
}
|
||||
return this.contentDocument.title;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
export const Census = {};
|
||||
function dumpn(msg) {
|
||||
dump("DBG-TEST: Census.jsm: " + msg + "\n");
|
||||
dump("DBG-TEST: Census.sys.mjs: " + msg + "\n");
|
||||
}
|
||||
|
||||
// Census.walkCensus(subject, name, walker)
|
||||
|
|
|
@ -32,7 +32,7 @@ var gNextLoaderID = 0;
|
|||
* If true, the modules will be forced to be loaded in a distinct
|
||||
* compartment. It is typically used to load the modules in a distinct
|
||||
* system compartment, different from the main one, which is shared by
|
||||
* all JSMs, XPCOMs and modules loaded with this flag set to true.
|
||||
* all ESMs, XPCOMs and modules loaded with this flag set to true.
|
||||
* We use this in order to debug modules loaded in this shared system
|
||||
* compartment. The debugger actor has to be running in a distinct
|
||||
* compartment than the context it is debugging.
|
||||
|
@ -166,7 +166,7 @@ export function DevToolsLoader({
|
|||
);
|
||||
|
||||
// Define the loader id for these two usecases:
|
||||
// * access via the JSM (this.id)
|
||||
// * access via the ESM (this.id)
|
||||
// let { loader } = ChromeUtils.importESModule("resource://devtools/shared/loader/Loader.sys.mjs");
|
||||
// loader.id
|
||||
this.id = gNextLoaderID++;
|
||||
|
@ -176,7 +176,7 @@ export function DevToolsLoader({
|
|||
globals.loader.invisibleToDebugger = invisibleToDebugger;
|
||||
|
||||
// Expose lazy helpers on `loader`
|
||||
// ie. when you use it like that from a JSM:
|
||||
// ie. when you use it like that from a ESM:
|
||||
// let { loader } = ChromeUtils.importESModule("resource://devtools/shared/loader/Loader.sys.mjs");
|
||||
// loader.lazyGetter(...);
|
||||
this.lazyGetter = globals.loader.lazyGetter;
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// This module does import many attributes from the global object
|
||||
/* eslint-disable mozilla/reject-global-this */
|
||||
|
||||
// A CommonJS module loader that is designed to run inside a worker debugger.
|
||||
// We can't simply use the SDK module loader, because it relies heavily on
|
||||
// Components, which isn't available in workers.
|
||||
|
@ -368,7 +365,7 @@ var {
|
|||
loadSubScript,
|
||||
setImmediate,
|
||||
xpcInspector,
|
||||
} = function () {
|
||||
} = (function () {
|
||||
// Main thread
|
||||
if (typeof Components === "object") {
|
||||
const principal = Components.Constructor(
|
||||
|
@ -477,7 +474,7 @@ addDebuggerToGlobal(globalThis);
|
|||
setImmediate: globalThis.setImmediate,
|
||||
xpcInspector,
|
||||
};
|
||||
}.call(this);
|
||||
})();
|
||||
/* eslint-enable no-shadow */
|
||||
|
||||
// Create the default instance of the worker loader, using the APIs we defined
|
||||
|
|
|
@ -3,4 +3,5 @@
|
|||
- file, You can obtain one at https://mozilla.org/MPL/2.0/. -->
|
||||
<!doctype html>
|
||||
<meta charset="utf-8" />
|
||||
<title>Web Extension Fallback Document</title>
|
||||
<h1>Your addon does not have any document opened yet.</h1>
|
||||
|
|
|
@ -1041,9 +1041,12 @@ DevToolsStartup.prototype = {
|
|||
if (pauseOnStartup) {
|
||||
// Spin the event loop until the debugger connects.
|
||||
const tm = Cc["@mozilla.org/thread-manager;1"].getService();
|
||||
tm.spinEventLoopUntil("DevToolsStartup.jsm:handleDebuggerFlag", () => {
|
||||
return devtoolsThreadResumed;
|
||||
});
|
||||
tm.spinEventLoopUntil(
|
||||
"DevToolsStartup.sys.mjs:handleDebuggerFlag",
|
||||
() => {
|
||||
return devtoolsThreadResumed;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (cmdLine.state == Ci.nsICommandLine.STATE_REMOTE_AUTO) {
|
||||
|
|
|
@ -1131,7 +1131,8 @@ nsresult ChromeTooltipListener::MouseMove(Event* aMouseEvent) {
|
|||
// within the timer callback. On win32, we'll get a MouseMove event even when
|
||||
// a popup goes away -- even when the mouse doesn't change position! To get
|
||||
// around this, we make sure the mouse has really moved before proceeding.
|
||||
CSSIntPoint newMouseClientPoint = mouseEvent->ClientPoint();
|
||||
const CSSIntPoint newMouseClientPoint =
|
||||
RoundedToInt(mouseEvent->ClientPoint());
|
||||
if (mMouseClientPoint == newMouseClientPoint) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/TrustedTypeUtils.h"
|
||||
#include "mozilla/dom/TrustedTypesConstants.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -53,9 +55,8 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMParser, mOwner)
|
|||
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMParser)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMParser)
|
||||
|
||||
already_AddRefed<Document> DOMParser::ParseFromString(const nsAString& aStr,
|
||||
SupportedType aType,
|
||||
ErrorResult& aRv) {
|
||||
already_AddRefed<Document> DOMParser::ParseFromStringInternal(
|
||||
const nsAString& aStr, SupportedType aType, ErrorResult& aRv) {
|
||||
if (aType == SupportedType::Text_html) {
|
||||
nsCOMPtr<Document> document = SetUpDocument(DocumentFlavorHTML, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
|
@ -99,6 +100,24 @@ already_AddRefed<Document> DOMParser::ParseFromString(const nsAString& aStr,
|
|||
return ParseFromStream(stream, u"UTF-8"_ns, utf8str.Length(), aType, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<Document> DOMParser::ParseFromString(
|
||||
const TrustedHTMLOrString& aStr, SupportedType aType, ErrorResult& aRv) {
|
||||
constexpr nsLiteralString sink = u"DOMParser parseFromString"_ns;
|
||||
|
||||
MOZ_ASSERT(mOwner);
|
||||
nsCOMPtr<nsIGlobalObject> pinnedOwner = mOwner;
|
||||
Maybe<nsAutoString> compliantStringHolder;
|
||||
const nsAString* compliantString =
|
||||
TrustedTypeUtils::GetTrustedTypesCompliantString(
|
||||
aStr, sink, kTrustedTypesOnlySinkGroup, *pinnedOwner,
|
||||
compliantStringHolder, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ParseFromStringInternal(*compliantString, aType, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<Document> DOMParser::ParseFromSafeString(const nsAString& aStr,
|
||||
SupportedType aType,
|
||||
ErrorResult& aRv) {
|
||||
|
@ -111,7 +130,7 @@ already_AddRefed<Document> DOMParser::ParseFromSafeString(const nsAString& aStr,
|
|||
mPrincipal = mOwner->PrincipalOrNull();
|
||||
}
|
||||
|
||||
RefPtr<Document> ret = ParseFromString(aStr, aType, aRv);
|
||||
RefPtr<Document> ret = ParseFromStringInternal(aStr, aType, aRv);
|
||||
mPrincipal = docPrincipal;
|
||||
return ret.forget();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ class ErrorResult;
|
|||
|
||||
namespace dom {
|
||||
|
||||
class TrustedHTMLOrString;
|
||||
|
||||
class DOMParser final : public nsISupports, public nsWrapperCache {
|
||||
typedef mozilla::dom::GlobalObject GlobalObject;
|
||||
|
||||
|
@ -34,9 +36,12 @@ class DOMParser final : public nsISupports, public nsWrapperCache {
|
|||
static already_AddRefed<DOMParser> Constructor(const GlobalObject& aOwner,
|
||||
mozilla::ErrorResult& rv);
|
||||
|
||||
already_AddRefed<Document> ParseFromString(const nsAString& aStr,
|
||||
SupportedType aType,
|
||||
ErrorResult& aRv);
|
||||
already_AddRefed<Document> ParseFromStringInternal(const nsAString& aStr,
|
||||
SupportedType aType,
|
||||
ErrorResult& aRv);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT already_AddRefed<Document> ParseFromString(
|
||||
const TrustedHTMLOrString& aStr, SupportedType aType, ErrorResult& aRv);
|
||||
|
||||
// ChromeOnly API
|
||||
already_AddRefed<Document> ParseFromSafeString(const nsAString& aStr,
|
||||
|
|
|
@ -28,7 +28,7 @@ nsTArray<RefPtr<nsRange>> TextDirectiveFinder::FindTextDirectivesInDocument() {
|
|||
: nsCString();
|
||||
TEXT_FRAGMENT_LOG("Trying to find text directives in document '%s'.",
|
||||
uri.Data());
|
||||
mDocument.FlushPendingNotifications(FlushType::Frames);
|
||||
mDocument.FlushPendingNotifications(FlushType::Layout);
|
||||
// https://wicg.github.io/scroll-to-text-fragment/#invoke-text-directives
|
||||
// To invoke text directives, given as input a list of text directives text
|
||||
// directives and a Document document, run these steps:
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "nsComputedDOMStyle.h"
|
||||
#include "nsDOMAttributeMap.h"
|
||||
#include "nsFind.h"
|
||||
#include "nsFrameSelection.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsINode.h"
|
||||
|
@ -18,6 +19,7 @@
|
|||
#include "fragmentdirectives_ffi_generated.h"
|
||||
#include "Text.h"
|
||||
#include "mozilla/intl/WordBreaker.h"
|
||||
#include "mozilla/SelectionMovementUtils.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
LazyLogModule sFragmentDirectiveLog("FragmentDirective");
|
||||
|
@ -67,73 +69,19 @@ LazyLogModule sFragmentDirectiveLog("FragmentDirective");
|
|||
/* static */ RangeBoundary TextDirectiveUtil::MoveRangeBoundaryOneWord(
|
||||
const RangeBoundary& aRangeBoundary, TextScanDirection aDirection) {
|
||||
MOZ_ASSERT(aRangeBoundary.IsSetAndValid());
|
||||
RefPtr<nsINode> curNode = aRangeBoundary.Container();
|
||||
uint32_t offset = *aRangeBoundary.Offset(
|
||||
RangeBoundary::OffsetFilter::kValidOrInvalidOffsets);
|
||||
|
||||
const int offsetIncrement = int(aDirection);
|
||||
// Get the text node of the start of the range and the offset.
|
||||
// This is the current position of the start of the range.
|
||||
nsAutoString textContent;
|
||||
if (NodeIsVisibleTextNode(*curNode)) {
|
||||
const Text* textNode = Text::FromNode(curNode);
|
||||
|
||||
// Assuming that the current position might not be at a word boundary,
|
||||
// advance to the word boundary at word begin/end.
|
||||
if (!IsWhitespaceAtPosition(textNode, offset)) {
|
||||
textNode->GetData(textContent);
|
||||
const intl::WordRange wordRange =
|
||||
intl::WordBreaker::FindWord(textContent, offset);
|
||||
if (aDirection == TextScanDirection::Right &&
|
||||
offset != wordRange.mBegin) {
|
||||
offset = wordRange.mEnd;
|
||||
} else if (aDirection == TextScanDirection::Left &&
|
||||
offset != wordRange.mEnd) {
|
||||
// The additional -1 is necessary to move to offset to *before* the
|
||||
// start of the word.
|
||||
offset = wordRange.mBegin - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Now, skip any whitespace, so that `offset` points to the word boundary of
|
||||
// the next word (which is the one this algorithm actually aims to move over).
|
||||
while (curNode) {
|
||||
if (!NodeIsVisibleTextNode(*curNode) || NodeIsSearchInvisible(*curNode) ||
|
||||
offset >= curNode->Length()) {
|
||||
curNode = aDirection == TextScanDirection::Left ? curNode->GetPrevNode()
|
||||
: curNode->GetNextNode();
|
||||
if (!curNode) {
|
||||
break;
|
||||
}
|
||||
offset =
|
||||
aDirection == TextScanDirection::Left ? curNode->Length() - 1 : 0;
|
||||
continue;
|
||||
}
|
||||
const Text* textNode = Text::FromNode(curNode);
|
||||
if (IsWhitespaceAtPosition(textNode, offset)) {
|
||||
offset += offsetIncrement;
|
||||
continue;
|
||||
}
|
||||
|
||||
// At this point, the caret has been moved to the next non-whitespace
|
||||
// position.
|
||||
// find word boundaries at the current position
|
||||
textNode->GetData(textContent);
|
||||
const intl::WordRange wordRange =
|
||||
intl::WordBreaker::FindWord(textContent, offset);
|
||||
offset = aDirection == TextScanDirection::Left ? wordRange.mBegin
|
||||
: wordRange.mEnd;
|
||||
bool allPunctuation = true;
|
||||
for (uint32_t ch = wordRange.mBegin; ch != wordRange.mEnd && allPunctuation;
|
||||
++ch) {
|
||||
allPunctuation = mozilla::IsPunctuationForWordSelect(textContent[ch]);
|
||||
}
|
||||
if (!allPunctuation) {
|
||||
return {curNode, offset};
|
||||
}
|
||||
offset += int(aDirection);
|
||||
}
|
||||
return {};
|
||||
PeekOffsetOptions options = {PeekOffsetOption::JumpLines,
|
||||
PeekOffsetOption::StopAtScroller,
|
||||
PeekOffsetOption::IsKeyboardSelect};
|
||||
Result<RangeBoundary, nsresult> newBoundary =
|
||||
SelectionMovementUtils::MoveRangeBoundaryToSomewhere(
|
||||
aRangeBoundary,
|
||||
aDirection == TextScanDirection::Left ? nsDirection::eDirPrevious
|
||||
: nsDirection::eDirNext,
|
||||
aDirection == TextScanDirection::Left ? CaretAssociationHint::Before
|
||||
: CaretAssociationHint::After,
|
||||
intl::BidiEmbeddingLevel::DefaultLTR(),
|
||||
nsSelectionAmount::eSelectWord, options);
|
||||
return newBoundary.unwrapOr({});
|
||||
}
|
||||
|
||||
/* static */ bool TextDirectiveUtil::IsWhitespaceAtPosition(const Text* aText,
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "mozilla/intl/LineBreaker.h" // for LineBreaker::ComputeBreakPositions
|
||||
#include "mozilla/intl/Locale.h"
|
||||
#include "mozilla/intl/UnicodeProperties.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/StaticPrefs_intl.h"
|
||||
|
||||
using mozilla::AutoRestore;
|
||||
|
@ -150,6 +151,15 @@ static void SetupCapitalization(const char16_t* aWord, uint32_t aLength,
|
|||
}
|
||||
|
||||
nsresult nsLineBreaker::FlushCurrentWord() {
|
||||
auto cleanup = mozilla::MakeScopeExit([&] {
|
||||
mCurrentWord.Clear();
|
||||
mTextItems.Clear();
|
||||
mCurrentWordMightBeBreakable = false;
|
||||
mCurrentWordContainsMixedLang = false;
|
||||
mCurrentWordLanguage = nullptr;
|
||||
mWordContinuation = false;
|
||||
});
|
||||
|
||||
uint32_t length = mCurrentWord.Length();
|
||||
AutoTArray<uint8_t, 4000> breakState;
|
||||
if (!breakState.AppendElements(length, mozilla::fallible)) {
|
||||
|
@ -232,12 +242,6 @@ nsresult nsLineBreaker::FlushCurrentWord() {
|
|||
offset += ti->mLength;
|
||||
}
|
||||
|
||||
mCurrentWord.Clear();
|
||||
mTextItems.Clear();
|
||||
mCurrentWordMightBeBreakable = false;
|
||||
mCurrentWordContainsMixedLang = false;
|
||||
mCurrentWordLanguage = nullptr;
|
||||
mWordContinuation = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ TEST(TestParser, TestParserMain)
|
|||
RefPtr<mozilla::dom::DOMParser> parser =
|
||||
mozilla::dom::DOMParser::CreateWithoutGlobal(rv2);
|
||||
if (rv2.Failed()) break;
|
||||
nsCOMPtr<mozilla::dom::Document> document = parser->ParseFromString(
|
||||
nsCOMPtr<mozilla::dom::Document> document = parser->ParseFromStringInternal(
|
||||
htmlInput, mozilla::dom::SupportedType::Text_html, rv2);
|
||||
if (rv2.Failed()) break;
|
||||
|
||||
|
|
|
@ -37,7 +37,8 @@ TEST(TestXMLSerializerNoBreakLink, TestXMLSerializerNoBreakLinkMain)
|
|||
IgnoredErrorResult rv;
|
||||
RefPtr<DOMParser> parser = DOMParser::CreateWithoutGlobal(rv);
|
||||
ASSERT_FALSE(rv.Failed());
|
||||
document = parser->ParseFromString(htmlInput, SupportedType::Text_html, rv);
|
||||
document = parser->ParseFromStringInternal(htmlInput,
|
||||
SupportedType::Text_html, rv);
|
||||
ASSERT_FALSE(rv.Failed());
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ support-files = ["file_self_close.html"]
|
|||
["test_popup_blocker_link_target_blank.html"]
|
||||
support-files = ["file_self_close.html"]
|
||||
|
||||
["test_popup_blocker_microtask.html"]
|
||||
|
||||
["test_popup_blocker_mouse_event.html"]
|
||||
|
||||
["test_popup_blocker_pointer_event.html"]
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for triggering popup in microtask</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="target" style="width: 50px; height: 50px; background: green"></div>
|
||||
<script>
|
||||
|
||||
add_setup(async function() {
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
// Enable popup blocker
|
||||
["dom.disable_open_during_load", true],
|
||||
]});
|
||||
});
|
||||
|
||||
// Test for bug 1863217
|
||||
add_task(async function window_open_in_microtask() {
|
||||
let target = document.getElementById("target");
|
||||
let testPromise = new Promise(resolve => {
|
||||
target.addEventListener("click", () => {
|
||||
queueMicrotask(() => {
|
||||
let w = window.open("about:blank");
|
||||
ok(!!w, "Should allow popup");
|
||||
if (w) {
|
||||
w.close();
|
||||
}
|
||||
w = window.open("about:blank");
|
||||
ok(!w, "Should block popup");
|
||||
if (w) {
|
||||
w.close();
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
}, { once: true });
|
||||
});
|
||||
|
||||
SpecialPowers.wrap(document).notifyUserGestureActivation();
|
||||
// Dispatch an untrusted click event.
|
||||
SimpleTest.executeSoon(() => {
|
||||
target.dispatchEvent(new MouseEvent("click", {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
view: window,
|
||||
}));
|
||||
});
|
||||
await testPromise;
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -65,7 +65,7 @@ A review of the pre-Fission Message Manager mechanism
|
|||
.. note::
|
||||
There are actually several types of Message Managers: Frame Message Managers, Window Message Managers, Group Message Managers and Process Message Managers. For the purposes of this documentation, it's simplest to refer to all of these mechanisms altogether as the "Message Manager mechanism". Most of the examples in this document will be operating on the assumption that the Message Manager is a Frame Message Manager, which is the most commonly used one.
|
||||
|
||||
Currently, in the post `Electrolysis Project`_ Firefox codebase, we have code living in the parent process (UI) that is in plain JS (.js files) or in JS modules (.jsm files). In the child process (hosting the content), we use framescripts (.js) and also JS modules. The framescripts are instantiated once per top-level frame (or, in simpler terms, once per tab). This code has access to all of the DOM from the web content, including all iframes within it.
|
||||
Currently, in the post `Electrolysis Project`_ Firefox codebase, we have code living in the parent process (UI) that is in plain JS (.js files) or in ES modules (.sys.mjs files). In the child process (hosting the content), we use framescripts (.js) and also ES modules. The framescripts are instantiated once per top-level frame (or, in simpler terms, once per tab). This code has access to all of the DOM from the web content, including all iframes within it.
|
||||
|
||||
The two processes communicate via the Frame Message Manager (mm) using the ``sendAsyncMessage`` / ``receiveMessage`` API, and any code in the parent can communicate with any code in the child (and vice versa), by just listening to the messages of interest.
|
||||
|
||||
|
@ -373,7 +373,7 @@ Your best bet for storing state is in the parent process.
|
|||
.. hint::
|
||||
If each individual frame needs state, consider using a ``WeakMap`` in the parent process, mapping ``CanonicalBrowsingContext``'s with that state. That way, if the associates frames ever go away, you don't have to do any cleaning up yourself.
|
||||
|
||||
If you have state that you want multiple ``JSWindowActorParent``'s to have access to, consider having a "manager" of those ``JSWindowActorParent``'s inside of the same .jsm file to hold that state.
|
||||
If you have state that you want multiple ``JSWindowActorParent``'s to have access to, consider having a "manager" of those ``JSWindowActorParent``'s inside of the same .sys.mjs file to hold that state.
|
||||
|
||||
Registering a new actor
|
||||
-----------------------
|
||||
|
@ -422,7 +422,7 @@ Let's examine parent registration:
|
|||
Here, we're declaring that class ``PluginParent`` (here, a subclass of ``JSWindowActorParent``) is defined and exported from module ``PluginParent.sys.mjs``. That's all we have to say for the parent (main process) side of things.
|
||||
|
||||
.. note::
|
||||
It's not sufficient to just add a new .jsm file to the actors subdirectories. You also need to update the ``moz.build`` files in the same directory to get the ``resource://`` linkages set up correctly.
|
||||
It's not sufficient to just add a new .sys.mjs file to the actors subdirectories. You also need to update the ``moz.build`` files in the same directory to get the ``resource://`` linkages set up correctly.
|
||||
|
||||
Let's look at the second chunk:
|
||||
|
||||
|
@ -459,7 +459,7 @@ Design considerations when adding a new actor
|
|||
|
||||
A few things worth bearing in mind when adding your own actor registration:
|
||||
|
||||
- Any ``child`` or ``parent`` side you register **must** have a ``moduleURI`` property.
|
||||
- Any ``child`` or ``parent`` side you register **must** have a ``esModuleURI`` property.
|
||||
- You do not need to have both ``child`` and ``parent`` modules, and should avoid having actor sides that do nothing but send messages. The process without a defined module will still get an actor, and you can send messages from that side, but cannot receive them via ``receiveMessage``. Note that you **can** also use ``sendQuery`` from this side, enabling you to handle a response from the other process despite not having a ``receiveMessage`` method.
|
||||
- If you are writing a JSWindowActor, consider whether you really need ``allFrames`` - it'll save memory and CPU time if we don't need to instantiate the actor for subframes.
|
||||
- When copying/moving "Legacy" :ref:`fission.message-manager-actors`, remove their ``messages`` properties. They are no longer necessary.
|
||||
|
@ -475,17 +475,15 @@ Get a JSWindowActor
|
|||
|
||||
.. code-block:: javascript
|
||||
|
||||
// resource://testing-common/TestWindowParent.jsm
|
||||
var EXPORTED_SYMBOLS = ["TestWindowParent"];
|
||||
class TestParent extends JSWindowActorParent {
|
||||
// resource://testing-common/TestWindowParent.sys.mjs
|
||||
export class TestParent extends JSWindowActorParent {
|
||||
...
|
||||
}
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
// resource://testing-common/TestWindowChild.jsm
|
||||
var EXPORTED_SYMBOLS = ["TestWindowChild"];
|
||||
class TestChild extends JSWindowActorChild {
|
||||
// resource://testing-common/TestWindowChild.sys.mjs
|
||||
export class TestChild extends JSWindowActorChild {
|
||||
...
|
||||
}
|
||||
|
||||
|
@ -507,17 +505,15 @@ Get a JSProcessActor
|
|||
|
||||
.. code-block:: javascript
|
||||
|
||||
// resource://testing-common/TestProcessParent.jsm
|
||||
var EXPORTED_SYMBOLS = ["TestProcessParent"];
|
||||
class TestParent extends JSProcessActorParent {
|
||||
// resource://testing-common/TestProcessParent.sys.mjs
|
||||
export class TestParent extends JSProcessActorParent {
|
||||
...
|
||||
}
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
// resource://testing-common/TestProcessChild.jsm
|
||||
var EXPORTED_SYMBOLS = ["TestProcessChild"];
|
||||
class TestChild extends JSProcessActorChild {
|
||||
// resource://testing-common/TestProcessChild.sys.mjs
|
||||
export class TestChild extends JSProcessActorChild {
|
||||
...
|
||||
}
|
||||
|
||||
|
@ -546,5 +542,5 @@ And more
|
|||
.. _Context Menu Fission Port: https://hg.mozilla.org/mozilla-central/rev/adc60720b7b8
|
||||
.. _JSProcessActor.webidl: https://searchfox.org/mozilla-central/source/dom/chrome-webidl/JSProcessActor.webidl
|
||||
.. _JSWindowActor.webidl: https://searchfox.org/mozilla-central/source/dom/chrome-webidl/JSWindowActor.webidl
|
||||
.. _BrowserElementParent.jsm: https://searchfox.org/mozilla-central/rev/ec806131cb7bcd1c26c254d25cd5ab8a61b2aeb6/toolkit/actors/BrowserElementParent.jsm
|
||||
.. _BrowserElementParent.sys.mjs: https://searchfox.org/mozilla-central/source/toolkit/actors/BrowserElementParent.sys.mjs
|
||||
.. _Transferable: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
* 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/. */
|
||||
|
||||
#include "mozilla/dom/DragEvent.h"
|
||||
#include "DragEvent.h"
|
||||
|
||||
#include "mozilla/dom/MouseEventBinding.h"
|
||||
#include "mozilla/ImageInputTelemetry.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "prtime.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
|
@ -28,20 +28,18 @@ DragEvent::DragEvent(EventTarget* aOwner, nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
void DragEvent::InitDragEvent(const nsAString& aType, bool aCanBubble,
|
||||
bool aCancelable, nsGlobalWindowInner* aView,
|
||||
int32_t aDetail, int32_t aScreenX,
|
||||
int32_t aScreenY, int32_t aClientX,
|
||||
int32_t aClientY, bool aCtrlKey, bool aAltKey,
|
||||
bool aShiftKey, bool aMetaKey, uint16_t aButton,
|
||||
EventTarget* aRelatedTarget,
|
||||
DataTransfer* aDataTransfer) {
|
||||
void DragEvent::InitDragEventInternal(
|
||||
const nsAString& aType, bool aCanBubble, bool aCancelable,
|
||||
nsGlobalWindowInner* aView, int32_t aDetail, double aScreenX,
|
||||
double aScreenY, double aClientX, double aClientY, bool aCtrlKey,
|
||||
bool aAltKey, bool aShiftKey, bool aMetaKey, uint16_t aButton,
|
||||
EventTarget* aRelatedTarget, DataTransfer* aDataTransfer) {
|
||||
NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
|
||||
|
||||
MouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable, aView, aDetail,
|
||||
aScreenX, aScreenY, aClientX, aClientY, aCtrlKey,
|
||||
aAltKey, aShiftKey, aMetaKey, aButton,
|
||||
aRelatedTarget);
|
||||
MouseEvent::InitMouseEventInternal(aType, aCanBubble, aCancelable, aView,
|
||||
aDetail, aScreenX, aScreenY, aClientX,
|
||||
aClientY, aCtrlKey, aAltKey, aShiftKey,
|
||||
aMetaKey, aButton, aRelatedTarget);
|
||||
if (mEventIsInternal) {
|
||||
mEvent->AsDragEvent()->mDataTransfer = aDataTransfer;
|
||||
}
|
||||
|
@ -86,11 +84,11 @@ already_AddRefed<DragEvent> DragEvent::Constructor(
|
|||
nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
RefPtr<DragEvent> e = new DragEvent(t, nullptr, nullptr);
|
||||
bool trusted = e->Init(t);
|
||||
e->InitDragEvent(aType, aParam.mBubbles, aParam.mCancelable, aParam.mView,
|
||||
aParam.mDetail, aParam.mScreenX, aParam.mScreenY,
|
||||
aParam.mClientX, aParam.mClientY, aParam.mCtrlKey,
|
||||
aParam.mAltKey, aParam.mShiftKey, aParam.mMetaKey,
|
||||
aParam.mButton, aParam.mRelatedTarget, aParam.mDataTransfer);
|
||||
e->InitDragEventInternal(
|
||||
aType, aParam.mBubbles, aParam.mCancelable, aParam.mView, aParam.mDetail,
|
||||
aParam.mScreenX, aParam.mScreenY, aParam.mClientX, aParam.mClientY,
|
||||
aParam.mCtrlKey, aParam.mAltKey, aParam.mShiftKey, aParam.mMetaKey,
|
||||
aParam.mButton, aParam.mRelatedTarget, aParam.mDataTransfer);
|
||||
e->InitializeExtraMouseEventDictionaryMembers(aParam);
|
||||
e->SetTrusted(trusted);
|
||||
e->SetComposed(aParam.mComposed);
|
||||
|
|
|
@ -36,7 +36,12 @@ class DragEvent : public MouseEvent {
|
|||
int32_t aScreenX, int32_t aScreenY, int32_t aClientX,
|
||||
int32_t aClientY, bool aCtrlKey, bool aAltKey,
|
||||
bool aShiftKey, bool aMetaKey, uint16_t aButton,
|
||||
EventTarget* aRelatedTarget, DataTransfer* aDataTransfer);
|
||||
EventTarget* aRelatedTarget, DataTransfer* aDataTransfer) {
|
||||
InitDragEventInternal(aType, aCanBubble, aCancelable, aView, aDetail,
|
||||
aScreenX, aScreenY, aClientX, aClientY, aCtrlKey,
|
||||
aAltKey, aShiftKey, aMetaKey, aButton, aRelatedTarget,
|
||||
aDataTransfer);
|
||||
}
|
||||
|
||||
static already_AddRefed<DragEvent> Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aType,
|
||||
|
@ -47,6 +52,14 @@ class DragEvent : public MouseEvent {
|
|||
|
||||
protected:
|
||||
~DragEvent() = default;
|
||||
|
||||
void InitDragEventInternal(const nsAString& aType, bool aCanBubble,
|
||||
bool aCancelable, nsGlobalWindowInner* aView,
|
||||
int32_t aDetail, double aScreenX, double aScreenY,
|
||||
double aClientX, double aClientY, bool aCtrlKey,
|
||||
bool aAltKey, bool aShiftKey, bool aMetaKey,
|
||||
uint16_t aButton, EventTarget* aRelatedTarget,
|
||||
DataTransfer* aDataTransfer);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* 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/. */
|
||||
|
||||
#include "Event.h"
|
||||
|
||||
#include "AccessCheck.h"
|
||||
#include "base/basictypes.h"
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
|
@ -27,7 +29,6 @@
|
|||
#include "mozilla/ViewportUtils.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/DocumentInlines.h"
|
||||
#include "mozilla/dom/Event.h"
|
||||
#include "mozilla/dom/ShadowRoot.h"
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
#include "mozilla/ScrollContainerFrame.h"
|
||||
|
@ -582,28 +583,22 @@ bool Event::IsDispatchStopped() { return mEvent->PropagationStopped(); }
|
|||
WidgetEvent* Event::WidgetEventPtr() { return mEvent; }
|
||||
|
||||
// static
|
||||
Maybe<CSSIntPoint> Event::GetScreenCoords(nsPresContext* aPresContext,
|
||||
WidgetEvent* aEvent,
|
||||
LayoutDeviceIntPoint aPoint) {
|
||||
Maybe<CSSDoublePoint> Event::GetScreenCoords(
|
||||
nsPresContext* aPresContext, WidgetEvent* aEvent,
|
||||
const LayoutDeviceDoublePoint& aWidgetRelativePoint) {
|
||||
if (PointerLockManager::IsLocked()) {
|
||||
return Some(EventStateManager::sLastScreenPoint);
|
||||
}
|
||||
|
||||
if (!aEvent || (aEvent->mClass != eMouseEventClass &&
|
||||
aEvent->mClass != eMouseScrollEventClass &&
|
||||
aEvent->mClass != eWheelEventClass &&
|
||||
aEvent->mClass != ePointerEventClass &&
|
||||
aEvent->mClass != eTouchEventClass &&
|
||||
aEvent->mClass != eDragEventClass &&
|
||||
aEvent->mClass != eSimpleGestureEventClass)) {
|
||||
if (!aEvent || !aEvent->DOMEventSupportsCoords()) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
// Doing a straight conversion from LayoutDeviceIntPoint to CSSIntPoint
|
||||
// Doing a straight conversion from LayoutDeviceDoublePoint to CSSDoublePoint
|
||||
// seem incorrect, but it is needed to maintain legacy functionality.
|
||||
WidgetGUIEvent* guiEvent = aEvent->AsGUIEvent();
|
||||
if (!aPresContext || !(guiEvent && guiEvent->mWidget)) {
|
||||
return Some(CSSIntPoint(aPoint.x, aPoint.y));
|
||||
const WidgetGUIEvent* guiEvent = aEvent->AsGUIEvent();
|
||||
if (MOZ_UNLIKELY(!aPresContext) || !(guiEvent && guiEvent->mWidget)) {
|
||||
return Some(CSSDoublePoint(aWidgetRelativePoint.x, aWidgetRelativePoint.y));
|
||||
}
|
||||
|
||||
// (Potentially) transform the point from the coordinate space of an
|
||||
|
@ -611,120 +606,126 @@ Maybe<CSSIntPoint> Event::GetScreenCoords(nsPresContext* aPresContext,
|
|||
// window. The transform can only be applied to a point whose components
|
||||
// are floating-point values, so convert the integer point first, then
|
||||
// transform, and then round the result back to an integer point.
|
||||
LayoutDevicePoint floatPoint(aPoint);
|
||||
LayoutDevicePoint topLevelPoint =
|
||||
const LayoutDeviceIntPoint topLevelPoint = LayoutDeviceIntPoint::Round(
|
||||
guiEvent->mWidget->WidgetToTopLevelWidgetTransform().TransformPoint(
|
||||
floatPoint);
|
||||
LayoutDeviceIntPoint rounded = RoundedToInt(topLevelPoint);
|
||||
|
||||
nsPoint pt = LayoutDevicePixel::ToAppUnits(
|
||||
rounded, aPresContext->DeviceContext()->AppUnitsPerDevPixel());
|
||||
|
||||
pt += LayoutDevicePixel::ToAppUnits(
|
||||
guiEvent->mWidget->TopLevelWidgetToScreenOffset(),
|
||||
aPresContext->DeviceContext()->AppUnitsPerDevPixel());
|
||||
|
||||
return Some(CSSPixel::FromAppUnitsRounded(pt));
|
||||
aWidgetRelativePoint));
|
||||
const CSSPoint pt = CSSPixel::FromAppUnits(
|
||||
LayoutDevicePixel::ToAppUnits(
|
||||
topLevelPoint, aPresContext->DeviceContext()->AppUnitsPerDevPixel()) +
|
||||
LayoutDevicePixel::ToAppUnits(
|
||||
guiEvent->mWidget->TopLevelWidgetToScreenOffset(),
|
||||
aPresContext->DeviceContext()->AppUnitsPerDevPixel()));
|
||||
return Some(CSSDoublePoint(pt.x, pt.y));
|
||||
}
|
||||
|
||||
// static
|
||||
CSSIntPoint Event::GetPageCoords(nsPresContext* aPresContext,
|
||||
WidgetEvent* aEvent,
|
||||
LayoutDeviceIntPoint aPoint,
|
||||
CSSIntPoint aDefaultPoint) {
|
||||
CSSIntPoint pagePoint =
|
||||
Event::GetClientCoords(aPresContext, aEvent, aPoint, aDefaultPoint);
|
||||
CSSDoublePoint Event::GetPageCoords(
|
||||
nsPresContext* aPresContext, WidgetEvent* aEvent,
|
||||
const LayoutDeviceDoublePoint& aWidgetRelativePoint,
|
||||
const CSSDoublePoint& aDefaultClientPoint) {
|
||||
const CSSDoublePoint clientCoords = Event::GetClientCoords(
|
||||
aPresContext, aEvent, aWidgetRelativePoint, aDefaultClientPoint);
|
||||
|
||||
// If there is some scrolling, add scroll info to client point.
|
||||
if (aPresContext && aPresContext->GetPresShell()) {
|
||||
PresShell* presShell = aPresContext->PresShell();
|
||||
if (ScrollContainerFrame* sf = presShell->GetRootScrollContainerFrame()) {
|
||||
pagePoint += CSSIntPoint::FromAppUnitsRounded(sf->GetScrollPosition());
|
||||
const CSSPoint scrollPoint = CSSPixel::FromAppUnits([&]() {
|
||||
if (aPresContext && aPresContext->GetPresShell()) {
|
||||
if (const ScrollContainerFrame* const sf =
|
||||
aPresContext->PresShell()->GetRootScrollContainerFrame()) {
|
||||
return sf->GetScrollPosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pagePoint;
|
||||
return nsPoint{};
|
||||
}());
|
||||
return clientCoords + CSSDoublePoint(scrollPoint.x, scrollPoint.y);
|
||||
}
|
||||
|
||||
// static
|
||||
CSSIntPoint Event::GetClientCoords(nsPresContext* aPresContext,
|
||||
WidgetEvent* aEvent,
|
||||
LayoutDeviceIntPoint aPoint,
|
||||
CSSIntPoint aDefaultPoint) {
|
||||
CSSDoublePoint Event::GetClientCoords(
|
||||
nsPresContext* aPresContext, WidgetEvent* aEvent,
|
||||
const LayoutDeviceDoublePoint& aWidgetRelativePoint,
|
||||
const CSSDoublePoint& aDefaultClientPoint) {
|
||||
if (PointerLockManager::IsLocked()) {
|
||||
return EventStateManager::sLastClientPoint;
|
||||
}
|
||||
|
||||
if (!aEvent ||
|
||||
(aEvent->mClass != eMouseEventClass &&
|
||||
aEvent->mClass != eMouseScrollEventClass &&
|
||||
aEvent->mClass != eWheelEventClass &&
|
||||
aEvent->mClass != eTouchEventClass &&
|
||||
aEvent->mClass != eDragEventClass &&
|
||||
aEvent->mClass != ePointerEventClass &&
|
||||
aEvent->mClass != eSimpleGestureEventClass) ||
|
||||
!aPresContext || !aEvent->AsGUIEvent()->mWidget) {
|
||||
return aDefaultPoint;
|
||||
if (MOZ_UNLIKELY(!aPresContext) || MOZ_UNLIKELY(!aEvent) ||
|
||||
!aEvent->DOMEventSupportsCoords() ||
|
||||
MOZ_UNLIKELY(!aEvent->AsGUIEvent()->mWidget)) {
|
||||
return aDefaultClientPoint;
|
||||
}
|
||||
|
||||
PresShell* presShell = aPresContext->GetPresShell();
|
||||
if (!presShell) {
|
||||
return CSSIntPoint(0, 0);
|
||||
const PresShell* const presShell = aPresContext->GetPresShell();
|
||||
if (MOZ_UNLIKELY(!presShell)) {
|
||||
return CSSDoublePoint(0, 0);
|
||||
}
|
||||
nsIFrame* rootFrame = presShell->GetRootFrame();
|
||||
if (!rootFrame) {
|
||||
return CSSIntPoint(0, 0);
|
||||
// XXX Why don't we flush pending notifications before computing the offset
|
||||
// from the root frame?
|
||||
const nsIFrame* const rootFrame = presShell->GetRootFrame();
|
||||
if (MOZ_UNLIKELY(!rootFrame)) {
|
||||
return CSSDoublePoint(0, 0);
|
||||
}
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(
|
||||
aEvent, aPoint, RelativeTo{rootFrame});
|
||||
|
||||
return CSSIntPoint::FromAppUnitsRounded(pt);
|
||||
const CSSPoint pt =
|
||||
CSSPixel::FromAppUnits(nsLayoutUtils::GetEventCoordinatesRelativeTo(
|
||||
aEvent, LayoutDeviceIntPoint::Round(aWidgetRelativePoint),
|
||||
RelativeTo{rootFrame}));
|
||||
return CSSDoublePoint(pt.x, pt.y);
|
||||
}
|
||||
|
||||
// static
|
||||
CSSIntPoint Event::GetOffsetCoords(nsPresContext* aPresContext,
|
||||
WidgetEvent* aEvent,
|
||||
LayoutDeviceIntPoint aPoint,
|
||||
CSSIntPoint aDefaultPoint) {
|
||||
if (!aEvent->mTarget) {
|
||||
return GetPageCoords(aPresContext, aEvent, aPoint, aDefaultPoint);
|
||||
nsIFrame* Event::GetPrimaryFrameOfEventTarget(const nsPresContext& aPresContext,
|
||||
const WidgetEvent& aEvent) {
|
||||
const nsCOMPtr<nsIContent> content =
|
||||
nsIContent::FromEventTargetOrNull(aEvent.mTarget);
|
||||
if (!content) {
|
||||
return nullptr;
|
||||
}
|
||||
nsCOMPtr<nsIContent> content = nsIContent::FromEventTarget(aEvent->mTarget);
|
||||
if (!content || !aPresContext) {
|
||||
return CSSIntPoint();
|
||||
// XXX Even after the event target content is moved to different document, we
|
||||
// may get its primary frame. In this case, should we return nullptr here?
|
||||
nsIFrame* const frame = content->GetPrimaryFrame(FlushType::Layout);
|
||||
if (MOZ_UNLIKELY(!frame)) {
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<PresShell> presShell = aPresContext->GetPresShell();
|
||||
if (!presShell) {
|
||||
return CSSIntPoint();
|
||||
}
|
||||
presShell->FlushPendingNotifications(FlushType::Layout);
|
||||
nsIFrame* frame = content->GetPrimaryFrame();
|
||||
if (!frame) {
|
||||
return CSSIntPoint();
|
||||
}
|
||||
// For compat, see https://github.com/w3c/csswg-drafts/issues/1508. In SVG we
|
||||
// just return the coordinates of the outer SVG box. This is all kinda
|
||||
// For compat, see https://github.com/w3c/csswg-drafts/issues/1508. In SVG
|
||||
// we just return the coordinates of the outer SVG box. This is all kinda
|
||||
// unfortunate.
|
||||
if (frame->HasAnyStateBits(NS_FRAME_SVG_LAYOUT) &&
|
||||
StaticPrefs::dom_events_offset_in_svg_relative_to_svg_root()) {
|
||||
frame = SVGUtils::GetOuterSVGFrame(frame);
|
||||
if (!frame) {
|
||||
return CSSIntPoint();
|
||||
}
|
||||
return SVGUtils::GetOuterSVGFrame(frame);
|
||||
}
|
||||
nsIFrame* rootFrame = presShell->GetRootFrame();
|
||||
if (!rootFrame) {
|
||||
return CSSIntPoint();
|
||||
return frame;
|
||||
}
|
||||
|
||||
// static
|
||||
CSSDoublePoint Event::GetOffsetCoords(
|
||||
nsPresContext* aPresContext, WidgetEvent* aEvent,
|
||||
const LayoutDeviceDoublePoint& aWidgetRelativePoint,
|
||||
const CSSDoublePoint& aDefaultClientPoint) {
|
||||
if (!aEvent->mTarget) {
|
||||
return GetPageCoords(aPresContext, aEvent, aWidgetRelativePoint,
|
||||
aDefaultClientPoint);
|
||||
}
|
||||
CSSIntPoint clientCoords =
|
||||
GetClientCoords(aPresContext, aEvent, aPoint, aDefaultPoint);
|
||||
nsPoint pt = CSSPixel::ToAppUnits(clientCoords);
|
||||
if (nsLayoutUtils::TransformPoint(RelativeTo{rootFrame}, RelativeTo{frame},
|
||||
pt) == nsLayoutUtils::TRANSFORM_SUCCEEDED) {
|
||||
pt -= frame->GetPaddingRectRelativeToSelf().TopLeft();
|
||||
return CSSPixel::FromAppUnitsRounded(pt);
|
||||
if (!nsIContent::FromEventTarget(aEvent->mTarget) || !aPresContext) {
|
||||
return CSSDoublePoint();
|
||||
}
|
||||
return CSSIntPoint();
|
||||
const nsIFrame* const frame =
|
||||
GetPrimaryFrameOfEventTarget(*aPresContext, *aEvent);
|
||||
if (MOZ_UNLIKELY(!frame)) {
|
||||
return CSSDoublePoint();
|
||||
}
|
||||
MOZ_ASSERT(aPresContext->PresShell()->GetRootFrame());
|
||||
const CSSDoublePoint clientCoords = GetClientCoords(
|
||||
aPresContext, aEvent, aWidgetRelativePoint, aDefaultClientPoint);
|
||||
nsPoint ptInAppUnits = CSSPixel::ToAppUnits(CSSPoint(
|
||||
static_cast<float>(clientCoords.x), static_cast<float>(clientCoords.y)));
|
||||
if (nsLayoutUtils::TransformPoint(
|
||||
RelativeTo{aPresContext->PresShell()->GetRootFrame()},
|
||||
RelativeTo{frame},
|
||||
ptInAppUnits) != nsLayoutUtils::TRANSFORM_SUCCEEDED) {
|
||||
return CSSDoublePoint();
|
||||
}
|
||||
ptInAppUnits -= frame->GetPaddingRectRelativeToSelf().TopLeft();
|
||||
const CSSPoint pt = CSSPixel::FromAppUnits(ptInAppUnits);
|
||||
return CSSDoublePoint(pt.x, pt.y);
|
||||
}
|
||||
|
||||
// To be called ONLY by Event::GetType (which has the additional
|
||||
|
|
|
@ -174,22 +174,82 @@ class Event : public nsISupports, public nsWrapperCache {
|
|||
bool Init(EventTarget* aGlobal);
|
||||
|
||||
static const char16_t* GetEventName(EventMessage aEventType);
|
||||
static CSSIntPoint GetClientCoords(nsPresContext* aPresContext,
|
||||
WidgetEvent* aEvent,
|
||||
LayoutDeviceIntPoint aPoint,
|
||||
CSSIntPoint aDefaultPoint);
|
||||
static CSSIntPoint GetPageCoords(nsPresContext* aPresContext,
|
||||
WidgetEvent* aEvent,
|
||||
LayoutDeviceIntPoint aPoint,
|
||||
CSSIntPoint aDefaultPoint);
|
||||
static Maybe<CSSIntPoint> GetScreenCoords(nsPresContext* aPresContext,
|
||||
WidgetEvent* aEvent,
|
||||
LayoutDeviceIntPoint aPoint);
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
static CSSIntPoint GetOffsetCoords(nsPresContext* aPresContext,
|
||||
WidgetEvent* aEvent,
|
||||
LayoutDeviceIntPoint aPoint,
|
||||
CSSIntPoint aDefaultPoint);
|
||||
|
||||
/**
|
||||
* Return clientX and clientY values for aEvent fired at aWidgetRelativePoint.
|
||||
* If you do not want fractional values as the result, you should floor
|
||||
* aWidgetRelativePoint and aDefaultClientPoint before calling this method
|
||||
* like defined by the Pointer Events spec.
|
||||
* https://w3c.github.io/pointerevents/#event-coordinates
|
||||
* And finally round the result to the integer.
|
||||
* Note that if you want fractional values and the source of
|
||||
* aWidgetRelativePoint and aDefaultClientPoint is an untrusted event, the
|
||||
* result may not be representable with floats, i.e., CSSPoint. However, if
|
||||
* it's trusted point, the result is representable with floats because we use
|
||||
* CSSPoint to convert to/from app units.
|
||||
*/
|
||||
static CSSDoublePoint GetClientCoords(
|
||||
nsPresContext* aPresContext, WidgetEvent* aEvent,
|
||||
const LayoutDeviceDoublePoint& aWidgetRelativePoint,
|
||||
const CSSDoublePoint& aDefaultClientPoint);
|
||||
|
||||
/**
|
||||
* Return pageX and pageY values for aEvent fired at aWidgetRelativePoint,
|
||||
* which are client point + scroll position of the root scrollable frame. If
|
||||
* you do not want fractional values as the result, you should floor
|
||||
* aWidgetRelativePoint and aDefaultClientPoint before calling this method
|
||||
* like defined by the Pointer Events spec.
|
||||
* https://w3c.github.io/pointerevents/#event-coordinates
|
||||
* And finally round the result to the integer.
|
||||
* Note that if you want fractional values and the source of
|
||||
* aWidgetRelativePoint and aDefaultClientPoint is an untrusted event, the
|
||||
* result may not be representable with floats, i.e., CSSPoint. However, if
|
||||
* it's trusted point, the result is representable with floats because we use
|
||||
* CSSPoint to convert to/from app units.
|
||||
*/
|
||||
static CSSDoublePoint GetPageCoords(
|
||||
nsPresContext* aPresContext, WidgetEvent* aEvent,
|
||||
const LayoutDeviceDoublePoint& aWidgetRelativePoint,
|
||||
const CSSDoublePoint& aDefaultClientPoint);
|
||||
|
||||
/**
|
||||
* Return screenX and screenY values for aEvent fired at aWidgetRelativePoint.
|
||||
* If aEvent does not support exposing the ref point, this returns Nothing. If
|
||||
* you do not want fractional values as the result, you should floor
|
||||
* aWidgetRelativePoint and aDefaultClientPoint before calling this method
|
||||
* like defined by the Pointer Events spec.
|
||||
* https://w3c.github.io/pointerevents/#event-coordinates
|
||||
* And finally round the result to the integer.
|
||||
* Note that if you want fractional values and the source of
|
||||
* aWidgetRelativePoint and aDefaultClientPoint is an untrusted event, the
|
||||
* result may not be representable with floats, i.e., CSSPoint. However, if
|
||||
* it's trusted point, the result is representable with floats because we use
|
||||
* CSSPoint to convert to/from app units.
|
||||
*/
|
||||
static Maybe<CSSDoublePoint> GetScreenCoords(
|
||||
nsPresContext* aPresContext, WidgetEvent* aEvent,
|
||||
const LayoutDeviceDoublePoint& aWidgetRelativePoint);
|
||||
|
||||
/**
|
||||
* Return offsetX and offsetY values for aEvent fired at aWidgetRelativePoint,
|
||||
* which are offset in the target element. If you do not want fractional
|
||||
* values as the result, you should floor aWidgetRelativePoint and
|
||||
* aDefaultClientPoint before calling this method like defined by the Pointer
|
||||
* Events spec. https://w3c.github.io/pointerevents/#event-coordinates
|
||||
* And finally round the result to the integer. Note that if you want
|
||||
* fractional values and the source of aWidgetRelativePoint and
|
||||
* aDefaultClientPoint is an untrusted event, the result may not be
|
||||
* representable with floats, i.e., CSSPoint. However, if it's trusted point,
|
||||
* the result is representable with floats because we use CSSPoint to convert
|
||||
* to/from app units.
|
||||
*
|
||||
* Be aware, this may flush the layout.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static CSSDoublePoint GetOffsetCoords(
|
||||
nsPresContext* aPresContext, WidgetEvent* aEvent,
|
||||
const LayoutDeviceDoublePoint& aWidgetRelativePoint,
|
||||
const CSSDoublePoint& aDefaultClientPoint);
|
||||
|
||||
static already_AddRefed<Event> Constructor(EventTarget* aEventTarget,
|
||||
const nsAString& aType,
|
||||
|
@ -341,6 +401,10 @@ class Event : public nsISupports, public nsWrapperCache {
|
|||
already_AddRefed<EventTarget> EnsureWebAccessibleRelatedTarget(
|
||||
EventTarget* aRelatedTarget);
|
||||
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT static nsIFrame*
|
||||
GetPrimaryFrameOfEventTarget(const nsPresContext& aPresContext,
|
||||
const WidgetEvent& aEvent);
|
||||
|
||||
mozilla::WidgetEvent* mEvent;
|
||||
RefPtr<nsPresContext> mPresContext;
|
||||
nsCOMPtr<EventTarget> mExplicitOriginalTarget;
|
||||
|
|
|
@ -942,11 +942,11 @@ nsresult EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||
// XXX Probably doesn't matter much, but storing these in CSS pixels instead
|
||||
// of device pixels means behavior can be a bit odd if you zoom while
|
||||
// pointer-locked.
|
||||
sLastScreenPoint =
|
||||
sLastScreenPoint = RoundedToInt(
|
||||
Event::GetScreenCoords(aPresContext, aEvent, aEvent->mRefPoint)
|
||||
.extract();
|
||||
sLastClientPoint = Event::GetClientCoords(
|
||||
aPresContext, aEvent, aEvent->mRefPoint, CSSIntPoint(0, 0));
|
||||
.extract());
|
||||
sLastClientPoint = RoundedToInt(Event::GetClientCoords(
|
||||
aPresContext, aEvent, aEvent->mRefPoint, CSSDoublePoint{0, 0}));
|
||||
}
|
||||
|
||||
*aStatus = nsEventStatus_eIgnore;
|
||||
|
@ -4420,9 +4420,9 @@ nsresult EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
// to set drag end point in such case (you hit assersion if you do
|
||||
// it).
|
||||
if (sourceWC) {
|
||||
CSSIntPoint dropPointInScreen =
|
||||
const CSSIntPoint dropPointInScreen = RoundedToInt(
|
||||
Event::GetScreenCoords(aPresContext, aEvent, aEvent->mRefPoint)
|
||||
.extract();
|
||||
.extract());
|
||||
dragSession->SetDragEndPointForTests(dropPointInScreen.x,
|
||||
dropPointInScreen.y);
|
||||
}
|
||||
|
|
|
@ -4,16 +4,27 @@
|
|||
* 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/. */
|
||||
|
||||
#include "mozilla/dom/MouseEvent.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "MouseEvent.h"
|
||||
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/PresShell.h"
|
||||
#include "mozilla/StaticPrefs_dom.h"
|
||||
#include "mozilla/ViewportUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIScreenManager.h"
|
||||
#include "prtime.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
static nsIntPoint DevPixelsToCSSPixels(const LayoutDeviceIntPoint& aPoint,
|
||||
nsPresContext* aContext) {
|
||||
return nsIntPoint(aContext->DevPixelsToIntCSSPixels(aPoint.x),
|
||||
aContext->DevPixelsToIntCSSPixels(aPoint.y));
|
||||
}
|
||||
|
||||
MouseEvent::MouseEvent(EventTarget* aOwner, nsPresContext* aPresContext,
|
||||
WidgetMouseEventBase* aEvent)
|
||||
: UIEvent(aOwner, aPresContext,
|
||||
|
@ -24,29 +35,32 @@ MouseEvent::MouseEvent(EventTarget* aOwner, nsPresContext* aPresContext,
|
|||
// It's not that important, though, since a scroll event is not a real
|
||||
// DOM event.
|
||||
|
||||
WidgetMouseEvent* mouseEvent = mEvent->AsMouseEvent();
|
||||
WidgetMouseEventBase* const mouseEventBase = mEvent->AsMouseEventBase();
|
||||
MOZ_ASSERT(mouseEventBase);
|
||||
if (aEvent) {
|
||||
mEventIsInternal = false;
|
||||
} else {
|
||||
mEventIsInternal = true;
|
||||
mEvent->mRefPoint = LayoutDeviceIntPoint(0, 0);
|
||||
mouseEvent->mInputSource = MouseEvent_Binding::MOZ_SOURCE_UNKNOWN;
|
||||
mouseEventBase->mInputSource = MouseEvent_Binding::MOZ_SOURCE_UNKNOWN;
|
||||
}
|
||||
|
||||
if (mouseEvent) {
|
||||
mUseFractionalCoords = mouseEventBase->DOMEventShouldUseFractionalCoords();
|
||||
mWidgetRelativePoint = mEvent->mRefPoint;
|
||||
|
||||
if (const WidgetMouseEvent* mouseEvent = mouseEventBase->AsMouseEvent()) {
|
||||
MOZ_ASSERT(mouseEvent->mReason != WidgetMouseEvent::eSynthesized,
|
||||
"Don't dispatch DOM events from synthesized mouse events");
|
||||
mDetail = mouseEvent->mClickCount;
|
||||
mDetail = static_cast<int32_t>(mouseEvent->mClickCount);
|
||||
}
|
||||
}
|
||||
|
||||
void MouseEvent::InitMouseEvent(const nsAString& aType, bool aCanBubble,
|
||||
bool aCancelable, nsGlobalWindowInner* aView,
|
||||
int32_t aDetail, int32_t aScreenX,
|
||||
int32_t aScreenY, int32_t aClientX,
|
||||
int32_t aClientY, bool aCtrlKey, bool aAltKey,
|
||||
bool aShiftKey, bool aMetaKey, uint16_t aButton,
|
||||
EventTarget* aRelatedTarget) {
|
||||
void MouseEvent::InitMouseEventInternal(
|
||||
const nsAString& aType, bool aCanBubble, bool aCancelable,
|
||||
nsGlobalWindowInner* aView, int32_t aDetail, double aScreenX,
|
||||
double aScreenY, double aClientX, double aClientY, bool aCtrlKey,
|
||||
bool aAltKey, bool aShiftKey, bool aMetaKey, uint16_t aButton,
|
||||
EventTarget* aRelatedTarget) {
|
||||
NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
|
||||
|
||||
UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, aDetail);
|
||||
|
@ -63,15 +77,29 @@ void MouseEvent::InitMouseEvent(const nsAString& aType, bool aCanBubble,
|
|||
mouseEventBase->mButton = aButton;
|
||||
mouseEventBase->InitBasicModifiers(aCtrlKey, aAltKey, aShiftKey,
|
||||
aMetaKey);
|
||||
mDefaultClientPoint.x = aClientX;
|
||||
mDefaultClientPoint.y = aClientY;
|
||||
mouseEventBase->mRefPoint.x = aScreenX;
|
||||
mouseEventBase->mRefPoint.y = aScreenY;
|
||||
mDefaultClientPoint = CSSDoublePoint(aClientX, aClientY);
|
||||
mWidgetRelativePoint = LayoutDeviceDoublePoint(aScreenX, aScreenY);
|
||||
mouseEventBase->mRefPoint =
|
||||
LayoutDeviceIntPoint::Floor(mWidgetRelativePoint);
|
||||
|
||||
WidgetMouseEvent* mouseEvent = mEvent->AsMouseEvent();
|
||||
if (mouseEvent) {
|
||||
mouseEvent->mClickCount = aDetail;
|
||||
}
|
||||
|
||||
mUseFractionalCoords =
|
||||
mouseEventBase->DOMEventShouldUseFractionalCoords();
|
||||
if (!mUseFractionalCoords) {
|
||||
// If we should not use fractional coordinates for this event, we need
|
||||
// to drop the fractional part as defined for the backward compatibility
|
||||
// when we treated the input values are integer coordinates. These
|
||||
// values will be exposed as screenX, screenY, clientX and clientY as-is
|
||||
// too. That matches with the Pointer Events spec definitions too.
|
||||
// https://w3c.github.io/pointerevents/#event-coordinates
|
||||
mDefaultClientPoint = CSSIntPoint::Floor(mDefaultClientPoint);
|
||||
mWidgetRelativePoint =
|
||||
LayoutDeviceIntPoint::Floor(mWidgetRelativePoint);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -79,18 +107,16 @@ void MouseEvent::InitMouseEvent(const nsAString& aType, bool aCanBubble,
|
|||
}
|
||||
}
|
||||
|
||||
void MouseEvent::InitMouseEvent(const nsAString& aType, bool aCanBubble,
|
||||
bool aCancelable, nsGlobalWindowInner* aView,
|
||||
int32_t aDetail, int32_t aScreenX,
|
||||
int32_t aScreenY, int32_t aClientX,
|
||||
int32_t aClientY, int16_t aButton,
|
||||
EventTarget* aRelatedTarget,
|
||||
const nsAString& aModifiersList) {
|
||||
void MouseEvent::InitMouseEventInternal(
|
||||
const nsAString& aType, bool aCanBubble, bool aCancelable,
|
||||
nsGlobalWindowInner* aView, int32_t aDetail, double aScreenX,
|
||||
double aScreenY, double aClientX, double aClientY, int16_t aButton,
|
||||
EventTarget* aRelatedTarget, const nsAString& aModifiersList) {
|
||||
NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
|
||||
|
||||
Modifiers modifiers = ComputeModifierState(aModifiersList);
|
||||
|
||||
InitMouseEvent(
|
||||
InitMouseEventInternal(
|
||||
aType, aCanBubble, aCancelable, aView, aDetail, aScreenX, aScreenY,
|
||||
aClientX, aClientY, (modifiers & MODIFIER_CONTROL) != 0,
|
||||
(modifiers & MODIFIER_ALT) != 0, (modifiers & MODIFIER_SHIFT) != 0,
|
||||
|
@ -124,11 +150,11 @@ already_AddRefed<MouseEvent> MouseEvent::Constructor(
|
|||
nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
RefPtr<MouseEvent> e = new MouseEvent(t, nullptr, nullptr);
|
||||
bool trusted = e->Init(t);
|
||||
e->InitMouseEvent(aType, aParam.mBubbles, aParam.mCancelable, aParam.mView,
|
||||
aParam.mDetail, aParam.mScreenX, aParam.mScreenY,
|
||||
aParam.mClientX, aParam.mClientY, aParam.mCtrlKey,
|
||||
aParam.mAltKey, aParam.mShiftKey, aParam.mMetaKey,
|
||||
aParam.mButton, aParam.mRelatedTarget);
|
||||
e->InitMouseEventInternal(
|
||||
aType, aParam.mBubbles, aParam.mCancelable, aParam.mView, aParam.mDetail,
|
||||
aParam.mScreenX, aParam.mScreenY, aParam.mClientX, aParam.mClientY,
|
||||
aParam.mCtrlKey, aParam.mAltKey, aParam.mShiftKey, aParam.mMetaKey,
|
||||
aParam.mButton, aParam.mRelatedTarget);
|
||||
e->InitializeExtraMouseEventDictionaryMembers(aParam);
|
||||
e->SetTrusted(trusted);
|
||||
e->SetComposed(aParam.mComposed);
|
||||
|
@ -147,16 +173,47 @@ void MouseEvent::InitNSMouseEvent(const nsAString& aType, bool aCanBubble,
|
|||
float aPressure, uint16_t aInputSource) {
|
||||
NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
|
||||
|
||||
MouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable, aView, aDetail,
|
||||
aScreenX, aScreenY, aClientX, aClientY, aCtrlKey,
|
||||
aAltKey, aShiftKey, aMetaKey, aButton,
|
||||
aRelatedTarget);
|
||||
InitMouseEventInternal(aType, aCanBubble, aCancelable, aView, aDetail,
|
||||
aScreenX, aScreenY, aClientX, aClientY, aCtrlKey,
|
||||
aAltKey, aShiftKey, aMetaKey, aButton, aRelatedTarget);
|
||||
|
||||
WidgetMouseEventBase* mouseEventBase = mEvent->AsMouseEventBase();
|
||||
mouseEventBase->mPressure = aPressure;
|
||||
mouseEventBase->mInputSource = aInputSource;
|
||||
}
|
||||
|
||||
void MouseEvent::DuplicatePrivateData() {
|
||||
// If this is a event not created from WidgetMouseEventBase or its subclasses
|
||||
// (i.e., created by JS), mDefaultClientPoint and mMovementPoint are
|
||||
// initialized as expected values. Therefore, we don't need to recompute it.
|
||||
if (!mEventIsInternal) {
|
||||
mDefaultClientPoint = ClientPoint();
|
||||
mMovementPoint = GetMovementPoint();
|
||||
}
|
||||
// However, mPagePoint needs to include the scroll position. Therefore, we
|
||||
// need to compute here.
|
||||
mPagePoint = PagePoint();
|
||||
|
||||
// mEvent->mRefPoint is computed by UIEvent::DuplicatePrivateData() with
|
||||
// the device pixel scale, but if we need to store fractional values to
|
||||
// mWidgetRelativePoint, we need to do same thing by ourselves.
|
||||
Maybe<const CSSDoublePoint> maybeScreenPoint;
|
||||
if (mUseFractionalCoords) {
|
||||
maybeScreenPoint.emplace(ScreenPoint(CallerType::System));
|
||||
}
|
||||
UIEvent::DuplicatePrivateData();
|
||||
if (maybeScreenPoint.isSome()) {
|
||||
CSSToLayoutDeviceScale scale = mPresContext
|
||||
? mPresContext->CSSToDevPixelScale()
|
||||
: CSSToLayoutDeviceScale(1);
|
||||
mWidgetRelativePoint = maybeScreenPoint.ref() * scale;
|
||||
} else {
|
||||
// As mentioned above, mEvent->mRefPoint is already computed by UIEvent, so,
|
||||
// do not need to compute the scale.
|
||||
mWidgetRelativePoint = mEvent->mRefPoint;
|
||||
}
|
||||
}
|
||||
|
||||
void MouseEvent::PreventClickEvent() {
|
||||
if (WidgetMouseEvent* mouseEvent = mEvent->AsMouseEvent()) {
|
||||
mouseEvent->mClickEventPrevented = true;
|
||||
|
@ -217,32 +274,42 @@ already_AddRefed<EventTarget> MouseEvent::GetRelatedTarget() {
|
|||
return EnsureWebAccessibleRelatedTarget(relatedTarget);
|
||||
}
|
||||
|
||||
CSSIntPoint MouseEvent::ScreenPoint(CallerType aCallerType) const {
|
||||
CSSDoublePoint MouseEvent::ScreenPoint(CallerType aCallerType) const {
|
||||
if (mEvent->mFlags.mIsPositionless) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// If this is a trusted event, mWidgetRelativeOffset is a copy of
|
||||
// mEvent->mRefPoint, so, the values are integer.
|
||||
// If this is an untrusted event, mWidgetRelativeOffset should be floored when
|
||||
// it's initialized.
|
||||
MOZ_ASSERT_IF(!mUseFractionalCoords,
|
||||
mWidgetRelativePoint ==
|
||||
LayoutDeviceIntPoint::Floor(mWidgetRelativePoint));
|
||||
if (nsContentUtils::ShouldResistFingerprinting(
|
||||
aCallerType, GetParentObject(), RFPTarget::MouseEventScreenPoint)) {
|
||||
// Sanitize to something sort of like client cooords, but not quite
|
||||
// Sanitize to something sort of like client coords, but not quite
|
||||
// (defaulting to (0,0) instead of our pre-specified client coords).
|
||||
return Event::GetClientCoords(mPresContext, mEvent, mEvent->mRefPoint,
|
||||
CSSIntPoint(0, 0));
|
||||
const CSSDoublePoint clientPoint = Event::GetClientCoords(
|
||||
mPresContext, mEvent, mWidgetRelativePoint, CSSDoublePoint{0, 0});
|
||||
return mUseFractionalCoords ? clientPoint : RoundedToInt(clientPoint);
|
||||
}
|
||||
|
||||
return Event::GetScreenCoords(mPresContext, mEvent, mEvent->mRefPoint)
|
||||
.extract();
|
||||
const CSSDoublePoint screenPoint =
|
||||
Event::GetScreenCoords(mPresContext, mEvent, mWidgetRelativePoint)
|
||||
.extract();
|
||||
return mUseFractionalCoords ? screenPoint : RoundedToInt(screenPoint);
|
||||
}
|
||||
|
||||
LayoutDeviceIntPoint MouseEvent::ScreenPointLayoutDevicePix() const {
|
||||
const CSSIntPoint point = ScreenPoint(CallerType::System);
|
||||
const CSSDoublePoint point = ScreenPoint(CallerType::System);
|
||||
auto scale = mPresContext ? mPresContext->CSSToDevPixelScale()
|
||||
: CSSToLayoutDeviceScale();
|
||||
return LayoutDeviceIntPoint::Round(point * scale);
|
||||
}
|
||||
|
||||
DesktopIntPoint MouseEvent::ScreenPointDesktopPix() const {
|
||||
const CSSIntPoint point = ScreenPoint(CallerType::System);
|
||||
const CSSDoublePoint point = ScreenPoint(CallerType::System);
|
||||
auto scale =
|
||||
mPresContext
|
||||
? mPresContext->CSSToDevPixelScale() /
|
||||
|
@ -261,35 +328,104 @@ already_AddRefed<nsIScreen> MouseEvent::GetScreen() {
|
|||
DesktopIntRect(ScreenPointDesktopPix(), DesktopIntSize(1, 1)));
|
||||
}
|
||||
|
||||
CSSIntPoint MouseEvent::PagePoint() const {
|
||||
CSSDoublePoint MouseEvent::PagePoint() const {
|
||||
if (mEvent->mFlags.mIsPositionless) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (mPrivateDataDuplicated) {
|
||||
// mPagePoint should be floored when it started to cache the values after
|
||||
// the propagation.
|
||||
MOZ_ASSERT_IF(!mUseFractionalCoords,
|
||||
mPagePoint == CSSIntPoint::Floor(mPagePoint));
|
||||
return mPagePoint;
|
||||
}
|
||||
|
||||
return Event::GetPageCoords(mPresContext, mEvent, mEvent->mRefPoint,
|
||||
mDefaultClientPoint);
|
||||
// If this is a trusted event, mWidgetRelativeOffset is a copy of
|
||||
// mEvent->mRefPoint, so, the values are integer.
|
||||
// If this is an untrusted event, mWidgetRelativeOffset should be floored when
|
||||
// it's initialized.
|
||||
MOZ_ASSERT_IF(!mUseFractionalCoords,
|
||||
mWidgetRelativePoint ==
|
||||
LayoutDeviceIntPoint::Floor(mWidgetRelativePoint));
|
||||
// If this is a trusted event, mDefaultClientPoint should be floored when
|
||||
// it started to cache the values after the propagation.
|
||||
// If this is an untrusted event, mDefaultClientPoint should be floored when
|
||||
// it's initialized.
|
||||
MOZ_ASSERT_IF(!mUseFractionalCoords,
|
||||
mDefaultClientPoint == CSSIntPoint::Floor(mDefaultClientPoint));
|
||||
const CSSDoublePoint pagePoint = Event::GetPageCoords(
|
||||
mPresContext, mEvent, mWidgetRelativePoint, mDefaultClientPoint);
|
||||
return mUseFractionalCoords ? pagePoint : RoundedToInt(pagePoint);
|
||||
}
|
||||
|
||||
CSSIntPoint MouseEvent::ClientPoint() const {
|
||||
CSSDoublePoint MouseEvent::ClientPoint() const {
|
||||
if (mEvent->mFlags.mIsPositionless) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return Event::GetClientCoords(mPresContext, mEvent, mEvent->mRefPoint,
|
||||
mDefaultClientPoint);
|
||||
// If this is a trusted event, mWidgetRelativeOffset is a copy of
|
||||
// mEvent->mRefPoint, so, the values are integer.
|
||||
// If this is an untrusted event, mWidgetRelativeOffset should be floored when
|
||||
// it's initialized.
|
||||
MOZ_ASSERT_IF(!mUseFractionalCoords,
|
||||
mWidgetRelativePoint ==
|
||||
LayoutDeviceIntPoint::Floor(mWidgetRelativePoint));
|
||||
// If this is a trusted event, mDefaultClientPoint should be floored when
|
||||
// it started to cache the values after the propagation.
|
||||
// If this is an untrusted event, mDefaultClientPoint should be floored when
|
||||
// it's initialized.
|
||||
MOZ_ASSERT_IF(!mUseFractionalCoords,
|
||||
mDefaultClientPoint == CSSIntPoint::Floor(mDefaultClientPoint));
|
||||
const CSSDoublePoint clientPoint = Event::GetClientCoords(
|
||||
mPresContext, mEvent, mWidgetRelativePoint, mDefaultClientPoint);
|
||||
return mUseFractionalCoords ? clientPoint : RoundedToInt(clientPoint);
|
||||
}
|
||||
|
||||
CSSIntPoint MouseEvent::OffsetPoint() const {
|
||||
CSSDoublePoint MouseEvent::OffsetPoint() const {
|
||||
if (mEvent->mFlags.mIsPositionless) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return Event::GetOffsetCoords(mPresContext, mEvent, mEvent->mRefPoint,
|
||||
mDefaultClientPoint);
|
||||
// If this is a trusted event, mWidgetRelativeOffset is a copy of
|
||||
// mEvent->mRefPoint, so, the values are integer.
|
||||
// If this is an untrusted event, mWidgetRelativeOffset should be floored when
|
||||
// it's initialized.
|
||||
MOZ_ASSERT_IF(!mUseFractionalCoords,
|
||||
mWidgetRelativePoint ==
|
||||
LayoutDeviceIntPoint::Floor(mWidgetRelativePoint));
|
||||
// If this is a trusted event, mDefaultClientPoint should be floored when
|
||||
// it started to cache the values after the propagation.
|
||||
// If this is an untrusted event, mDefaultClientPoint should be floored when
|
||||
// it's initialized.
|
||||
MOZ_ASSERT_IF(!mUseFractionalCoords,
|
||||
mDefaultClientPoint == CSSIntPoint::Floor(mDefaultClientPoint));
|
||||
RefPtr<nsPresContext> presContext(mPresContext);
|
||||
const CSSDoublePoint offsetPoint = Event::GetOffsetCoords(
|
||||
presContext, mEvent, mWidgetRelativePoint, mDefaultClientPoint);
|
||||
return mUseFractionalCoords ? offsetPoint : RoundedToInt(offsetPoint);
|
||||
}
|
||||
|
||||
nsIntPoint MouseEvent::GetMovementPoint() const {
|
||||
if (mEvent->mFlags.mIsPositionless) {
|
||||
return nsIntPoint(0, 0);
|
||||
}
|
||||
|
||||
if (mPrivateDataDuplicated || mEventIsInternal) {
|
||||
return mMovementPoint;
|
||||
}
|
||||
|
||||
if (!mEvent || !mEvent->AsGUIEvent()->mWidget ||
|
||||
(mEvent->mMessage != eMouseMove && mEvent->mMessage != ePointerMove)) {
|
||||
// Pointer Lock spec defines that movementX/Y must be zero for all mouse
|
||||
// events except mousemove.
|
||||
return nsIntPoint(0, 0);
|
||||
}
|
||||
|
||||
// Calculate the delta between the last screen point and the current one.
|
||||
nsIntPoint current = DevPixelsToCSSPixels(mEvent->mRefPoint, mPresContext);
|
||||
nsIntPoint last = DevPixelsToCSSPixels(mEvent->mLastRefPoint, mPresContext);
|
||||
return current - last;
|
||||
}
|
||||
|
||||
bool MouseEvent::AltKey() { return mEvent->AsInputEvent()->IsAlt(); }
|
||||
|
|
|
@ -28,6 +28,8 @@ class MouseEvent : public UIEvent {
|
|||
|
||||
virtual MouseEvent* AsMouseEvent() override { return this; }
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY void DuplicatePrivateData() override;
|
||||
|
||||
// Web IDL binding methods
|
||||
virtual uint32_t Which(CallerType aCallerType) override {
|
||||
return Button() + 1;
|
||||
|
@ -35,28 +37,67 @@ class MouseEvent : public UIEvent {
|
|||
|
||||
already_AddRefed<nsIScreen> GetScreen();
|
||||
|
||||
// In CSS coords.
|
||||
CSSIntPoint ScreenPoint(CallerType) const;
|
||||
int32_t ScreenX(CallerType aCallerType) const {
|
||||
/**
|
||||
* Return screenX and screenY values for this event in CSS pixels.
|
||||
* If current setting allows to expose fractional coordinates for the event,
|
||||
* this returns the fractional values as-is. Otherwise, this returns
|
||||
* integer values with rounding the computed values. Note that if this
|
||||
* event is untrusted one and should not expose fractional values, the
|
||||
* initialized values are floored before computing the values as defined by
|
||||
* Pointer Events spec.
|
||||
*/
|
||||
CSSDoublePoint ScreenPoint(CallerType) const;
|
||||
double ScreenX(CallerType aCallerType) const {
|
||||
return ScreenPoint(aCallerType).x;
|
||||
}
|
||||
int32_t ScreenY(CallerType aCallerType) const {
|
||||
double ScreenY(CallerType aCallerType) const {
|
||||
return ScreenPoint(aCallerType).y;
|
||||
}
|
||||
LayoutDeviceIntPoint ScreenPointLayoutDevicePix() const;
|
||||
DesktopIntPoint ScreenPointDesktopPix() const;
|
||||
|
||||
CSSIntPoint PagePoint() const;
|
||||
int32_t PageX() const { return PagePoint().x; }
|
||||
int32_t PageY() const { return PagePoint().y; }
|
||||
/**
|
||||
* Return pageX and pageY values for this event in CSS pixels which are
|
||||
* client point + scroll position of the root scrollable frame.
|
||||
* If current setting allows to expose fractional coordinates for the event,
|
||||
* this returns the fractional values as-is. Otherwise, this returns
|
||||
* integer values with rounding the computed values. Note that if this
|
||||
* event is untrusted one and should not expose fractional values, the
|
||||
* initialized values are floored before computing the values as defined by
|
||||
* Pointer Events spec.
|
||||
*/
|
||||
CSSDoublePoint PagePoint() const;
|
||||
double PageX() const { return PagePoint().x; }
|
||||
double PageY() const { return PagePoint().y; }
|
||||
|
||||
CSSIntPoint ClientPoint() const;
|
||||
int32_t ClientX() const { return ClientPoint().x; }
|
||||
int32_t ClientY() const { return ClientPoint().y; }
|
||||
/**
|
||||
* Return clientX and clientY values for this event in CSS pixels.
|
||||
* If current setting allows to expose fractional coordinates for the event,
|
||||
* this returns the fractional values as-is. Otherwise, this returns
|
||||
* integer values with rounding the computed values. Note that if this
|
||||
* event is untrusted one and should not expose fractional values, the
|
||||
* initialized values are floored before computing the values as defined by
|
||||
* Pointer Events spec.
|
||||
*/
|
||||
CSSDoublePoint ClientPoint() const;
|
||||
double ClientX() const { return ClientPoint().x; }
|
||||
double ClientY() const { return ClientPoint().y; }
|
||||
|
||||
CSSIntPoint OffsetPoint() const;
|
||||
int32_t OffsetX() const { return OffsetPoint().x; }
|
||||
int32_t OffsetY() const { return OffsetPoint().y; }
|
||||
/**
|
||||
* Return offsetX and offsetY values for this event in CSS pixels which are
|
||||
* offset in the target element.
|
||||
* If current setting allows to expose fractional coordinates for the event,
|
||||
* this returns the fractional values as-is. Otherwise, this returns
|
||||
* integer values with rounding the computed values. Note that if this
|
||||
* event is untrusted one and should not expose fractional values, the
|
||||
* initialized values are floored before computing the values as defined by
|
||||
* Pointer Events spec.
|
||||
*
|
||||
* Note that this may flush the pending layout.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY CSSDoublePoint OffsetPoint() const;
|
||||
double OffsetX() const { return OffsetPoint().x; }
|
||||
double OffsetY() const { return OffsetPoint().y; }
|
||||
|
||||
bool CtrlKey();
|
||||
bool ShiftKey();
|
||||
|
@ -70,7 +111,12 @@ class MouseEvent : public UIEvent {
|
|||
int32_t aScreenX, int32_t aScreenY, int32_t aClientX,
|
||||
int32_t aClientY, bool aCtrlKey, bool aAltKey,
|
||||
bool aShiftKey, bool aMetaKey, uint16_t aButton,
|
||||
EventTarget* aRelatedTarget);
|
||||
EventTarget* aRelatedTarget) {
|
||||
InitMouseEventInternal(aType, aCanBubble, aCancelable, aView, aDetail,
|
||||
aScreenX, aScreenY, aClientX, aClientY, aCtrlKey,
|
||||
aAltKey, aShiftKey, aMetaKey, aButton,
|
||||
aRelatedTarget);
|
||||
}
|
||||
|
||||
void InitializeExtraMouseEventDictionaryMembers(const MouseEventInit& aParam);
|
||||
|
||||
|
@ -97,12 +143,49 @@ class MouseEvent : public UIEvent {
|
|||
protected:
|
||||
~MouseEvent() = default;
|
||||
|
||||
void InitMouseEvent(const nsAString& aType, bool aCanBubble, bool aCancelable,
|
||||
nsGlobalWindowInner* aView, int32_t aDetail,
|
||||
int32_t aScreenX, int32_t aScreenY, int32_t aClientX,
|
||||
int32_t aClientY, int16_t aButton,
|
||||
EventTarget* aRelatedTarget,
|
||||
const nsAString& aModifiersList);
|
||||
nsIntPoint GetMovementPoint() const;
|
||||
|
||||
void InitMouseEventInternal(const nsAString& aType, bool aCanBubble,
|
||||
bool aCancelable, nsGlobalWindowInner* aView,
|
||||
int32_t aDetail, double aScreenX, double aScreenY,
|
||||
double aClientX, double aClientY, bool aCtrlKey,
|
||||
bool aAltKey, bool aShiftKey, bool aMetaKey,
|
||||
uint16_t aButton, EventTarget* aRelatedTarget);
|
||||
|
||||
void InitMouseEventInternal(const nsAString& aType, bool aCanBubble,
|
||||
bool aCancelable, nsGlobalWindowInner* aView,
|
||||
int32_t aDetail, double aScreenX, double aScreenY,
|
||||
double aClientX, double aClientY, int16_t aButton,
|
||||
EventTarget* aRelatedTarget,
|
||||
const nsAString& aModifiersList);
|
||||
|
||||
// mWidgetRelativePoint stores the reference point of the event within the
|
||||
// double coordinates. If this is a trusted event, the values are copied from
|
||||
// mEvent->mRefPoint whose type is LayoutDeviceIntPoint. Therefore, the
|
||||
// values are always integer. On the other hand, if this is an untrusted
|
||||
// event, this may store fractional values if and only if the event should
|
||||
// expose fractional coordinates. Otherwise, this is floored values for the
|
||||
// backward compatibility.
|
||||
LayoutDeviceDoublePoint mWidgetRelativePoint;
|
||||
|
||||
// If this is a trusted event and after dispatching this, mDefaultClientPoint
|
||||
// stores the clientX and clientY values at duplicating the data.
|
||||
// If this is an untrusted event, mDefaultClientPoint stores the clientX and
|
||||
// clientY inputs. If this event should expose fractional coordinates, the
|
||||
// values are set as-is. Otherwise, this stores floored input values for
|
||||
// the backward compatibility.
|
||||
CSSDoublePoint mDefaultClientPoint;
|
||||
|
||||
// If this is a trusted event and after dispatching this, mPagePoint stores
|
||||
// the pageX and pageY values at duplicating the data.
|
||||
// If this is an untrusted event, mPagePoint stores the pageX and pageY
|
||||
// inputs. If this event should expose fractional coordinates, the values are
|
||||
// set as-is. Otherwise, this stores floored input values for the backward
|
||||
// compatibility.
|
||||
CSSDoublePoint mPagePoint;
|
||||
|
||||
nsIntPoint mMovementPoint;
|
||||
bool mUseFractionalCoords = false;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
* 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/. */
|
||||
|
||||
#include "mozilla/dom/MouseScrollEvent.h"
|
||||
#include "MouseScrollEvent.h"
|
||||
|
||||
#include "mozilla/dom/MouseEventBinding.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "prtime.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
|
@ -30,18 +30,18 @@ MouseScrollEvent::MouseScrollEvent(EventTarget* aOwner,
|
|||
mDetail = mEvent->AsMouseScrollEvent()->mDelta;
|
||||
}
|
||||
|
||||
void MouseScrollEvent::InitMouseScrollEvent(
|
||||
void MouseScrollEvent::InitMouseScrollEventInternal(
|
||||
const nsAString& aType, bool aCanBubble, bool aCancelable,
|
||||
nsGlobalWindowInner* aView, int32_t aDetail, int32_t aScreenX,
|
||||
int32_t aScreenY, int32_t aClientX, int32_t aClientY, bool aCtrlKey,
|
||||
nsGlobalWindowInner* aView, int32_t aDetail, double aScreenX,
|
||||
double aScreenY, double aClientX, double aClientY, bool aCtrlKey,
|
||||
bool aAltKey, bool aShiftKey, bool aMetaKey, uint16_t aButton,
|
||||
EventTarget* aRelatedTarget, int32_t aAxis) {
|
||||
NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
|
||||
|
||||
MouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable, aView, aDetail,
|
||||
aScreenX, aScreenY, aClientX, aClientY, aCtrlKey,
|
||||
aAltKey, aShiftKey, aMetaKey, aButton,
|
||||
aRelatedTarget);
|
||||
MouseEvent::InitMouseEventInternal(aType, aCanBubble, aCancelable, aView,
|
||||
aDetail, aScreenX, aScreenY, aClientX,
|
||||
aClientY, aCtrlKey, aAltKey, aShiftKey,
|
||||
aMetaKey, aButton, aRelatedTarget);
|
||||
mEvent->AsMouseScrollEvent()->mIsHorizontal =
|
||||
(aAxis == MouseScrollEvent_Binding::HORIZONTAL_AXIS);
|
||||
}
|
||||
|
|
|
@ -32,10 +32,24 @@ class MouseScrollEvent : public MouseEvent {
|
|||
int32_t aClientX, int32_t aClientY, bool aCtrlKey,
|
||||
bool aAltKey, bool aShiftKey, bool aMetaKey,
|
||||
uint16_t aButton, EventTarget* aRelatedTarget,
|
||||
int32_t aAxis);
|
||||
int32_t aAxis) {
|
||||
InitMouseScrollEventInternal(aType, aCanBubble, aCancelable, aView, aDetail,
|
||||
aScreenX, aScreenY, aClientX, aClientY,
|
||||
aCtrlKey, aAltKey, aShiftKey, aMetaKey,
|
||||
aButton, aRelatedTarget, aAxis);
|
||||
}
|
||||
|
||||
protected:
|
||||
~MouseScrollEvent() = default;
|
||||
|
||||
void InitMouseScrollEventInternal(const nsAString& aType, bool aCanBubble,
|
||||
bool aCancelable,
|
||||
nsGlobalWindowInner* aView, int32_t aDetail,
|
||||
double aScreenX, double aScreenY,
|
||||
double aClientX, double aClientY,
|
||||
bool aCtrlKey, bool aAltKey, bool aShiftKey,
|
||||
bool aMetaKey, uint16_t aButton,
|
||||
EventTarget* aRelatedTarget, int32_t aAxis);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -117,10 +117,10 @@ already_AddRefed<PointerEvent> PointerEvent::Constructor(
|
|||
RefPtr<PointerEvent> e = new PointerEvent(aOwner, nullptr, nullptr);
|
||||
bool trusted = e->Init(aOwner);
|
||||
|
||||
e->InitMouseEvent(aType, aParam.mBubbles, aParam.mCancelable, aParam.mView,
|
||||
aParam.mDetail, aParam.mScreenX, aParam.mScreenY,
|
||||
aParam.mClientX, aParam.mClientY, false, false, false,
|
||||
false, aParam.mButton, aParam.mRelatedTarget);
|
||||
e->InitMouseEventInternal(
|
||||
aType, aParam.mBubbles, aParam.mCancelable, aParam.mView, aParam.mDetail,
|
||||
aParam.mScreenX, aParam.mScreenY, aParam.mClientX, aParam.mClientY, false,
|
||||
false, false, false, aParam.mButton, aParam.mRelatedTarget);
|
||||
e->InitializeExtraMouseEventDictionaryMembers(aParam);
|
||||
e->mPointerType = Some(aParam.mPointerType);
|
||||
|
||||
|
@ -246,12 +246,12 @@ int32_t PointerEvent::PointerId() {
|
|||
: mEvent->AsPointerEvent()->pointerId;
|
||||
}
|
||||
|
||||
int32_t PointerEvent::Width() {
|
||||
return ShouldResistFingerprinting() ? 1 : mEvent->AsPointerEvent()->mWidth;
|
||||
double PointerEvent::Width() const {
|
||||
return ShouldResistFingerprinting() ? 1.0 : mEvent->AsPointerEvent()->mWidth;
|
||||
}
|
||||
|
||||
int32_t PointerEvent::Height() {
|
||||
return ShouldResistFingerprinting() ? 1 : mEvent->AsPointerEvent()->mHeight;
|
||||
double PointerEvent::Height() const {
|
||||
return ShouldResistFingerprinting() ? 1.0 : mEvent->AsPointerEvent()->mHeight;
|
||||
}
|
||||
|
||||
float PointerEvent::Pressure() {
|
||||
|
|
|
@ -41,8 +41,8 @@ class PointerEvent : public MouseEvent {
|
|||
PointerEvent* AsPointerEvent() final { return this; }
|
||||
|
||||
int32_t PointerId();
|
||||
int32_t Width();
|
||||
int32_t Height();
|
||||
double Width() const;
|
||||
double Height() const;
|
||||
float Pressure();
|
||||
float TangentialPressure();
|
||||
int32_t TiltX();
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
* 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/. */
|
||||
|
||||
#include "SimpleGestureEvent.h"
|
||||
|
||||
#include "mozilla/dom/MouseEventBinding.h"
|
||||
#include "mozilla/dom/SimpleGestureEvent.h"
|
||||
#include "mozilla/TouchEvents.h"
|
||||
#include "prtime.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
|
@ -51,19 +51,19 @@ uint32_t SimpleGestureEvent::ClickCount() const {
|
|||
return mEvent->AsSimpleGestureEvent()->mClickCount;
|
||||
}
|
||||
|
||||
void SimpleGestureEvent::InitSimpleGestureEvent(
|
||||
void SimpleGestureEvent::InitSimpleGestureEventInternal(
|
||||
const nsAString& aTypeArg, bool aCanBubbleArg, bool aCancelableArg,
|
||||
nsGlobalWindowInner* aViewArg, int32_t aDetailArg, int32_t aScreenX,
|
||||
int32_t aScreenY, int32_t aClientX, int32_t aClientY, bool aCtrlKeyArg,
|
||||
nsGlobalWindowInner* aViewArg, int32_t aDetailArg, double aScreenX,
|
||||
double aScreenY, double aClientX, double aClientY, bool aCtrlKeyArg,
|
||||
bool aAltKeyArg, bool aShiftKeyArg, bool aMetaKeyArg, uint16_t aButton,
|
||||
EventTarget* aRelatedTarget, uint32_t aAllowedDirectionsArg,
|
||||
uint32_t aDirectionArg, double aDeltaArg, uint32_t aClickCountArg) {
|
||||
NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
|
||||
|
||||
MouseEvent::InitMouseEvent(aTypeArg, aCanBubbleArg, aCancelableArg, aViewArg,
|
||||
aDetailArg, aScreenX, aScreenY, aClientX, aClientY,
|
||||
aCtrlKeyArg, aAltKeyArg, aShiftKeyArg, aMetaKeyArg,
|
||||
aButton, aRelatedTarget);
|
||||
MouseEvent::InitMouseEventInternal(
|
||||
aTypeArg, aCanBubbleArg, aCancelableArg, aViewArg, aDetailArg, aScreenX,
|
||||
aScreenY, aClientX, aClientY, aCtrlKeyArg, aAltKeyArg, aShiftKeyArg,
|
||||
aMetaKeyArg, aButton, aRelatedTarget);
|
||||
|
||||
WidgetSimpleGestureEvent* simpleGestureEvent = mEvent->AsSimpleGestureEvent();
|
||||
simpleGestureEvent->mAllowedDirections = aAllowedDirectionsArg;
|
||||
|
|
|
@ -41,10 +41,23 @@ class SimpleGestureEvent : public MouseEvent {
|
|||
bool aShiftKey, bool aMetaKey, uint16_t aButton,
|
||||
EventTarget* aRelatedTarget,
|
||||
uint32_t aAllowedDirections, uint32_t aDirection,
|
||||
double aDelta, uint32_t aClickCount);
|
||||
double aDelta, uint32_t aClickCount) {
|
||||
InitSimpleGestureEventInternal(
|
||||
aType, aCanBubble, aCancelable, aView, aDetail, aScreenX, aScreenY,
|
||||
aClientX, aClientY, aCtrlKey, aAltKey, aShiftKey, aMetaKey, aButton,
|
||||
aRelatedTarget, aAllowedDirections, aDirection, aDelta, aClickCount);
|
||||
}
|
||||
|
||||
protected:
|
||||
~SimpleGestureEvent() = default;
|
||||
|
||||
void InitSimpleGestureEventInternal(
|
||||
const nsAString& aType, bool aCanBubble, bool aCancelable,
|
||||
nsGlobalWindowInner* aView, int32_t aDetail, double aScreenX,
|
||||
double aScreenY, double aClientX, double aClientY, bool aCtrlKey,
|
||||
bool aAltKey, bool aShiftKey, bool aMetaKey, uint16_t aButton,
|
||||
EventTarget* aRelatedTarget, uint32_t aAllowedDirections,
|
||||
uint32_t aDirection, double aDelta, uint32_t aClickCount);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -187,12 +187,12 @@ void Touch::InitializePoints(nsPresContext* aPresContext, WidgetEvent* aEvent) {
|
|||
if (mPointsInitialized) {
|
||||
return;
|
||||
}
|
||||
mClientPoint =
|
||||
Event::GetClientCoords(aPresContext, aEvent, mRefPoint, mClientPoint);
|
||||
mPagePoint =
|
||||
Event::GetPageCoords(aPresContext, aEvent, mRefPoint, mClientPoint);
|
||||
mScreenPoint =
|
||||
Event::GetScreenCoords(aPresContext, aEvent, mRefPoint).extract();
|
||||
mClientPoint = RoundedToInt(
|
||||
Event::GetClientCoords(aPresContext, aEvent, mRefPoint, mClientPoint));
|
||||
mPagePoint = RoundedToInt(
|
||||
Event::GetPageCoords(aPresContext, aEvent, mRefPoint, mClientPoint));
|
||||
mScreenPoint = RoundedToInt(
|
||||
Event::GetScreenCoords(aPresContext, aEvent, mRefPoint).extract());
|
||||
mPointsInitialized = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,10 +30,7 @@ UIEvent::UIEvent(EventTarget* aOwner, nsPresContext* aPresContext,
|
|||
WidgetGUIEvent* aEvent)
|
||||
: Event(aOwner, aPresContext,
|
||||
aEvent ? aEvent : new InternalUIEvent(false, eVoidEvent, nullptr)),
|
||||
mDefaultClientPoint(0, 0),
|
||||
mLayerPoint(0, 0),
|
||||
mPagePoint(0, 0),
|
||||
mMovementPoint(0, 0) {
|
||||
mLayerPoint(0, 0) {
|
||||
if (aEvent) {
|
||||
mEventIsInternal = false;
|
||||
} else {
|
||||
|
@ -90,34 +87,6 @@ NS_IMPL_RELEASE_INHERITED(UIEvent, Event)
|
|||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(UIEvent)
|
||||
NS_INTERFACE_MAP_END_INHERITING(Event)
|
||||
|
||||
static nsIntPoint DevPixelsToCSSPixels(const LayoutDeviceIntPoint& aPoint,
|
||||
nsPresContext* aContext) {
|
||||
return nsIntPoint(aContext->DevPixelsToIntCSSPixels(aPoint.x),
|
||||
aContext->DevPixelsToIntCSSPixels(aPoint.y));
|
||||
}
|
||||
|
||||
nsIntPoint UIEvent::GetMovementPoint() {
|
||||
if (mEvent->mFlags.mIsPositionless) {
|
||||
return nsIntPoint(0, 0);
|
||||
}
|
||||
|
||||
if (mPrivateDataDuplicated || mEventIsInternal) {
|
||||
return mMovementPoint;
|
||||
}
|
||||
|
||||
if (!mEvent || !mEvent->AsGUIEvent()->mWidget ||
|
||||
(mEvent->mMessage != eMouseMove && mEvent->mMessage != ePointerMove)) {
|
||||
// Pointer Lock spec defines that movementX/Y must be zero for all mouse
|
||||
// events except mousemove.
|
||||
return nsIntPoint(0, 0);
|
||||
}
|
||||
|
||||
// Calculate the delta between the last screen point and the current one.
|
||||
nsIntPoint current = DevPixelsToCSSPixels(mEvent->mRefPoint, mPresContext);
|
||||
nsIntPoint last = DevPixelsToCSSPixels(mEvent->mLastRefPoint, mPresContext);
|
||||
return current - last;
|
||||
}
|
||||
|
||||
void UIEvent::InitUIEvent(const nsAString& typeArg, bool canBubbleArg,
|
||||
bool cancelableArg, nsGlobalWindowInner* viewArg,
|
||||
int32_t detailArg) {
|
||||
|
@ -187,16 +156,12 @@ nsIntPoint UIEvent::GetLayerPoint() const {
|
|||
}
|
||||
|
||||
void UIEvent::DuplicatePrivateData() {
|
||||
mDefaultClientPoint = Event::GetClientCoords(
|
||||
mPresContext, mEvent, mEvent->mRefPoint, mDefaultClientPoint);
|
||||
mMovementPoint = GetMovementPoint();
|
||||
mLayerPoint = GetLayerPoint();
|
||||
mPagePoint = Event::GetPageCoords(mPresContext, mEvent, mEvent->mRefPoint,
|
||||
mDefaultClientPoint);
|
||||
|
||||
// GetScreenPoint converts mEvent->mRefPoint to right coordinates.
|
||||
CSSIntPoint screenPoint =
|
||||
const CSSIntPoint screenPoint = RoundedToInt(
|
||||
Event::GetScreenCoords(mPresContext, mEvent, mEvent->mRefPoint)
|
||||
.valueOr(CSSIntPoint{0, 0});
|
||||
.valueOr(CSSIntPoint{0, 0}));
|
||||
|
||||
Event::DuplicatePrivateData();
|
||||
|
||||
|
|
|
@ -97,16 +97,11 @@ class UIEvent : public Event {
|
|||
~UIEvent() = default;
|
||||
|
||||
// Internal helper functions
|
||||
nsIntPoint GetMovementPoint();
|
||||
nsIntPoint GetLayerPoint() const;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> mView;
|
||||
int32_t mDetail;
|
||||
CSSIntPoint mDefaultClientPoint;
|
||||
// Screenpoint is mEvent->mRefPoint.
|
||||
nsIntPoint mLayerPoint;
|
||||
CSSIntPoint mPagePoint;
|
||||
nsIntPoint mMovementPoint;
|
||||
|
||||
static Modifiers ComputeModifierState(const nsAString& aModifiersList);
|
||||
bool GetModifierStateInternal(const nsAString& aKey);
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
* 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/. */
|
||||
|
||||
#include "WheelEvent.h"
|
||||
|
||||
#include "mozilla/dom/MouseEventBinding.h"
|
||||
#include "mozilla/dom/WheelEvent.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "prtime.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
|
@ -35,17 +35,17 @@ WheelEvent::WheelEvent(EventTarget* aOwner, nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
void WheelEvent::InitWheelEvent(
|
||||
void WheelEvent::InitWheelEventInternal(
|
||||
const nsAString& aType, bool aCanBubble, bool aCancelable,
|
||||
nsGlobalWindowInner* aView, int32_t aDetail, int32_t aScreenX,
|
||||
int32_t aScreenY, int32_t aClientX, int32_t aClientY, uint16_t aButton,
|
||||
nsGlobalWindowInner* aView, int32_t aDetail, double aScreenX,
|
||||
double aScreenY, double aClientX, double aClientY, uint16_t aButton,
|
||||
EventTarget* aRelatedTarget, const nsAString& aModifiersList,
|
||||
double aDeltaX, double aDeltaY, double aDeltaZ, uint32_t aDeltaMode) {
|
||||
NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
|
||||
|
||||
MouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable, aView, aDetail,
|
||||
aScreenX, aScreenY, aClientX, aClientY, aButton,
|
||||
aRelatedTarget, aModifiersList);
|
||||
MouseEvent::InitMouseEventInternal(
|
||||
aType, aCanBubble, aCancelable, aView, aDetail, aScreenX, aScreenY,
|
||||
aClientX, aClientY, aButton, aRelatedTarget, aModifiersList);
|
||||
|
||||
WidgetWheelEvent* wheelEvent = mEvent->AsWheelEvent();
|
||||
// When specified by the caller (for JS-created events), don't mess with the
|
||||
|
@ -154,11 +154,11 @@ already_AddRefed<WheelEvent> WheelEvent::Constructor(
|
|||
nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
RefPtr<WheelEvent> e = new WheelEvent(t, nullptr, nullptr);
|
||||
bool trusted = e->Init(t);
|
||||
e->InitWheelEvent(aType, aParam.mBubbles, aParam.mCancelable, aParam.mView,
|
||||
aParam.mDetail, aParam.mScreenX, aParam.mScreenY,
|
||||
aParam.mClientX, aParam.mClientY, aParam.mButton,
|
||||
aParam.mRelatedTarget, u""_ns, aParam.mDeltaX,
|
||||
aParam.mDeltaY, aParam.mDeltaZ, aParam.mDeltaMode);
|
||||
e->InitWheelEventInternal(
|
||||
aType, aParam.mBubbles, aParam.mCancelable, aParam.mView, aParam.mDetail,
|
||||
aParam.mScreenX, aParam.mScreenY, aParam.mClientX, aParam.mClientY,
|
||||
aParam.mButton, aParam.mRelatedTarget, u""_ns, aParam.mDeltaX,
|
||||
aParam.mDeltaY, aParam.mDeltaZ, aParam.mDeltaMode);
|
||||
e->InitializeExtraMouseEventDictionaryMembers(aParam);
|
||||
e->SetTrusted(trusted);
|
||||
e->SetComposed(aParam.mComposed);
|
||||
|
|
|
@ -61,11 +61,25 @@ class WheelEvent : public MouseEvent {
|
|||
int32_t aClientY, uint16_t aButton,
|
||||
EventTarget* aRelatedTarget,
|
||||
const nsAString& aModifiersList, double aDeltaX,
|
||||
double aDeltaY, double aDeltaZ, uint32_t aDeltaMode);
|
||||
double aDeltaY, double aDeltaZ, uint32_t aDeltaMode) {
|
||||
InitWheelEventInternal(aType, aCanBubble, aCancelable, aView, aDetail,
|
||||
aScreenX, aScreenY, aClientX, aClientY, aButton,
|
||||
aRelatedTarget, aModifiersList, aDeltaX, aDeltaY,
|
||||
aDeltaZ, aDeltaMode);
|
||||
}
|
||||
|
||||
protected:
|
||||
~WheelEvent() = default;
|
||||
|
||||
void InitWheelEventInternal(const nsAString& aType, bool aCanBubble,
|
||||
bool aCancelable, nsGlobalWindowInner* aView,
|
||||
int32_t aDetail, double aScreenX, double aScreenY,
|
||||
double aClientX, double aClientY,
|
||||
uint16_t aButton, EventTarget* aRelatedTarget,
|
||||
const nsAString& aModifiersList, double aDeltaX,
|
||||
double aDeltaY, double aDeltaZ,
|
||||
uint32_t aDeltaMode);
|
||||
|
||||
double ToWebExposedDelta(WidgetWheelEvent&, double aDelta,
|
||||
nscoord aLineOrPageAmount, CallerType);
|
||||
|
||||
|
|
|
@ -11,8 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1303957
|
|||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1303957">Mozilla Bug 1303957</a>
|
||||
<p id="display"></p>
|
||||
<!-- DO NOT PUT any text before the test target to avoid fractional coordinates! -->
|
||||
<div id="target0" style="width: 50px; height: 50px; background: green"></div>
|
||||
<script type="text/javascript">
|
||||
/** Test for Bug 1303957 **/
|
||||
|
@ -33,8 +32,24 @@ SimpleTest.waitForFocus(async () => {
|
|||
ok(length >= 1, "Coalesced events should >= 1, got " + length);
|
||||
|
||||
let rect = target0.getBoundingClientRect();
|
||||
let prevOffsetX = 0;
|
||||
let prevOffsetY = 0;
|
||||
let prevOffsetX = undefined;
|
||||
let prevOffsetY = undefined;
|
||||
|
||||
function isExpectedOffset(aNewOffset, aPrevOffset) {
|
||||
if (aPrevOffset === undefined) {
|
||||
const roundedOffset = 5 * Math.max(Math.round(aNewOffset / 5), 1);
|
||||
return aNewOffset >= roundedOffset - 1 && aNewOffset <= roundedOffset + 1;
|
||||
}
|
||||
let candidateOffset = aPrevOffset + 5;
|
||||
while (candidateOffset < 25) {
|
||||
// Allow rounding issue.
|
||||
if (aNewOffset >= candidateOffset - 0.1 && aNewOffset <= candidateOffset + 0.1) {
|
||||
return true;
|
||||
}
|
||||
candidateOffset += 5;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < length; ++i) {
|
||||
let coalescedEvent = ev.getCoalescedEvents()[i];
|
||||
|
@ -49,13 +64,18 @@ SimpleTest.waitForFocus(async () => {
|
|||
is(coalescedEvent.cancelable, false, "getCoalescedEvents()[" + i + "].cancelable");
|
||||
is(coalescedEvent.bubbles, false, "getCoalescedEvents()[" + i + "].bubbles");
|
||||
|
||||
ok(coalescedEvent.offsetX >= prevOffsetX, "getCoalescedEvents()[" + i + "].offsetX = " + coalescedEvent.offsetX);
|
||||
ok(coalescedEvent.offsetX == 5 || coalescedEvent.offsetX == 10 ||
|
||||
coalescedEvent.offsetX == 15 || coalescedEvent.offsetX == 20, "expected offsetX");
|
||||
|
||||
ok(coalescedEvent.offsetY >= prevOffsetY, "getCoalescedEvents()[" + i + "].offsetY = " + coalescedEvent.offsetY);
|
||||
ok(coalescedEvent.offsetY == 5 || coalescedEvent.offsetY == 10 ||
|
||||
coalescedEvent.offsetY == 15 || coalescedEvent.offsetY == 20, "expected offsetY");
|
||||
ok(
|
||||
isExpectedOffset(coalescedEvent.offsetX, prevOffsetX),
|
||||
`getCoalescedEvents()[${i}].offsetX (${
|
||||
coalescedEvent.offsetX
|
||||
}) should be 5 * n + previous offsetX (${prevOffsetX})`
|
||||
);
|
||||
ok(
|
||||
isExpectedOffset(coalescedEvent.offsetY, prevOffsetY),
|
||||
`getCoalescedEvents()[${i}].offsetY (${
|
||||
coalescedEvent.offsetY
|
||||
}) should be 5 * n + previous offsetY (${prevOffsetY})`
|
||||
);
|
||||
|
||||
prevOffsetX = coalescedEvent.offsetX;
|
||||
prevOffsetY = coalescedEvent.offsetY;
|
||||
|
@ -70,6 +90,14 @@ SimpleTest.waitForFocus(async () => {
|
|||
}, { once: true });
|
||||
});
|
||||
|
||||
info(`mozInnerScreen={${SpecialPowers.wrap(window).mozInnerScreenX}, ${SpecialPowers.wrap(window).mozInnerScreenY}}`);
|
||||
info(`devicePixelRatio=${window.devicePixelRatio}`);
|
||||
try {
|
||||
info(`top.mozInnerScreen={${SpecialPowers.wrap(window.top).mozInnerScreenX}, ${SpecialPowers.wrap(window.top).mozInnerScreenY}}`);
|
||||
info(`top.getResolution()=${SpecialPowers.wrap(window.top).windowUtils.getResolution()}`);
|
||||
} catch (e) {}
|
||||
info(`target0.getBoundingClientRect()={${target0.getBoundingClientRect().x}, ${target0.getBoundingClientRect().y}}`);
|
||||
|
||||
info("Synthesizing native mouse moves....");
|
||||
await promiseNativeMouseEvent({ type: "mousemove", target: target0, offsetX: 5, offsetY: 5 });
|
||||
await promiseNativeMouseEvent({ type: "mousemove", target: target0, offsetX: 10, offsetY: 10 });
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "mozilla/Unused.h"
|
||||
|
||||
#include "Fetch.h"
|
||||
#include "FetchLog.h"
|
||||
#include "FetchUtil.h"
|
||||
#include "InternalRequest.h"
|
||||
#include "InternalResponse.h"
|
||||
|
@ -261,6 +262,8 @@ AlternativeDataStreamListener::OnDataAvailable(nsIRequest* aRequest,
|
|||
nsIInputStream* aInputStream,
|
||||
uint64_t aOffset,
|
||||
uint32_t aCount) {
|
||||
FETCH_LOG(
|
||||
("FetchDriver::OnDataAvailable this=%p, request=%p", this, aRequest));
|
||||
if (mStatus == AlternativeDataStreamListener::LOADING) {
|
||||
MOZ_ASSERT(mPipeAlternativeOutputStream);
|
||||
uint32_t read = 0;
|
||||
|
@ -1047,6 +1050,8 @@ void FetchDriver::FailWithNetworkError(nsresult rv) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
FetchDriver::OnStartRequest(nsIRequest* aRequest) {
|
||||
FETCH_LOG(
|
||||
("FetchDriver::OnStartRequest this=%p, request=%p", this, aRequest));
|
||||
AssertIsOnMainThread();
|
||||
|
||||
// Note, this can be called multiple times if we are doing an opaqueredirect.
|
||||
|
@ -1353,6 +1358,19 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Only retarget if not already retargeted
|
||||
nsCOMPtr<nsISerialEventTarget> target;
|
||||
nsCOMPtr<nsIThreadRetargetableRequest> req = do_QueryInterface(aRequest);
|
||||
if (req) {
|
||||
rv = req->GetDeliveryTarget(getter_AddRefs(target));
|
||||
if (NS_SUCCEEDED(rv) && target && !target->IsOnCurrentThread()) {
|
||||
FETCH_LOG(
|
||||
("FetchDriver::OnStartRequest this=%p, request=%p already retargeted",
|
||||
this, aRequest));
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEventTarget> sts =
|
||||
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
@ -1361,6 +1379,7 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
FETCH_LOG(("FetchDriver retargeting: request %p", aRequest));
|
||||
// Try to retarget off main thread.
|
||||
if (nsCOMPtr<nsIThreadRetargetableRequest> rr = do_QueryInterface(aRequest)) {
|
||||
RefPtr<TaskQueue> queue =
|
||||
|
@ -1510,6 +1529,7 @@ FetchDriver::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInputStream,
|
|||
|
||||
NS_IMETHODIMP
|
||||
FetchDriver::OnStopRequest(nsIRequest* aRequest, nsresult aStatusCode) {
|
||||
FETCH_LOG(("FetchDriver::OnStopRequest this=%p, request=%p", this, aRequest));
|
||||
AssertIsOnMainThread();
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mOnStopRequestCalled);
|
||||
|
|
|
@ -3361,7 +3361,7 @@ void HTMLInputElement::LegacyPreActivationBehavior(
|
|||
|
||||
if (aVisitor.mDOMEvent) {
|
||||
if (auto* mouseEvent = aVisitor.mDOMEvent->AsMouseEvent()) {
|
||||
CSSIntPoint pt = mouseEvent->OffsetPoint();
|
||||
const CSSIntPoint pt = RoundedToInt(mouseEvent->OffsetPoint());
|
||||
if (auto* imageClickedPoint = static_cast<CSSIntPoint*>(
|
||||
GetProperty(nsGkAtoms::imageClickedPoint))) {
|
||||
// Ensures that a dispatched event's clicked point is not the default
|
||||
|
|
|
@ -1574,8 +1574,15 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER>::CreateImageVAAPI(
|
|||
return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
|
||||
RESULT_DETAIL("VAAPI dmabuf allocation error"));
|
||||
}
|
||||
|
||||
surface->SetYUVColorSpace(GetFrameColorSpace());
|
||||
surface->SetColorRange(GetFrameColorRange());
|
||||
if (mInfo.mColorPrimaries) {
|
||||
surface->SetColorPrimaries(mInfo.mColorPrimaries.value());
|
||||
}
|
||||
if (mInfo.mTransferFunction) {
|
||||
surface->SetTransferFunction(mInfo.mTransferFunction.value());
|
||||
}
|
||||
|
||||
RefPtr<VideoData> vp = VideoData::CreateFromImage(
|
||||
mInfo.mDisplay, aOffset, TimeUnit::FromMicroseconds(aPts),
|
||||
|
|
|
@ -71,6 +71,12 @@ class VideoFrameSurface<LIBAV_VER> {
|
|||
void SetColorRange(mozilla::gfx::ColorRange aColorRange) {
|
||||
mSurface->GetAsDMABufSurfaceYUV()->SetColorRange(aColorRange);
|
||||
}
|
||||
void SetColorPrimaries(mozilla::gfx::ColorSpace2 aColorPrimaries) {
|
||||
mSurface->GetAsDMABufSurfaceYUV()->SetColorPrimaries(aColorPrimaries);
|
||||
}
|
||||
void SetTransferFunction(mozilla::gfx::TransferFunction aTransferFunction) {
|
||||
mSurface->GetAsDMABufSurfaceYUV()->SetTransferFunction(aTransferFunction);
|
||||
}
|
||||
|
||||
RefPtr<DMABufSurfaceYUV> GetDMABufSurface() {
|
||||
return mSurface->GetAsDMABufSurfaceYUV();
|
||||
|
|
240
dom/media/tools/checkGmpBalrog.py
Normal file
240
dom/media/tools/checkGmpBalrog.py
Normal file
|
@ -0,0 +1,240 @@
|
|||
# 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/.
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import re
|
||||
from datetime import datetime
|
||||
from urllib.parse import urlparse
|
||||
from xml.etree import ElementTree
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
def check_hash(plugin, url, valid_urls):
|
||||
if url in valid_urls:
|
||||
return
|
||||
valid_urls[url] = True
|
||||
|
||||
response = requests.get(url)
|
||||
response.raise_for_status()
|
||||
|
||||
if "hashValue" in plugin.attrib:
|
||||
hashValue = hashlib.sha512(response.content).hexdigest()
|
||||
if hashValue != plugin.attrib["hashValue"]:
|
||||
raise Exception(
|
||||
"Given hash {} and calculated hash {} differ",
|
||||
plugin.attrib["hashValue"],
|
||||
hashValue,
|
||||
)
|
||||
if "size" in plugin.attrib:
|
||||
size = len(response.content)
|
||||
if size != int(plugin.attrib["size"]):
|
||||
raise Exception(
|
||||
"Given size {} and calculated size {} differ",
|
||||
int(plugin.attrib["size"]),
|
||||
size,
|
||||
)
|
||||
|
||||
|
||||
def fetch_balrog_xml(
|
||||
url_base: str, plugin_id, version: str, buildid: str, channels, targets, checkHash
|
||||
) -> str:
|
||||
url = "{url_base}/{version}/{buildid}/{target}/en-US/{channel}/default/default/default/update.xml"
|
||||
valid_urls = {}
|
||||
results = {}
|
||||
for channel in channels:
|
||||
results[channel] = {}
|
||||
for target in targets:
|
||||
balrog_url = url.format_map(
|
||||
{
|
||||
"url_base": url_base,
|
||||
"buildid": buildid,
|
||||
"channel": channel,
|
||||
"version": version,
|
||||
"target": target,
|
||||
}
|
||||
)
|
||||
|
||||
response = requests.get(balrog_url)
|
||||
response.raise_for_status()
|
||||
|
||||
plugin_urls = []
|
||||
tree = ElementTree.fromstring(response.content)
|
||||
for plugin in tree.findall("./addons/addon"):
|
||||
if not "id" in plugin.attrib:
|
||||
continue
|
||||
if plugin.attrib["id"] != plugin_id:
|
||||
continue
|
||||
if "URL" in plugin.attrib:
|
||||
if checkHash:
|
||||
check_hash(plugin, plugin.attrib["URL"], valid_urls)
|
||||
plugin_urls.append(plugin.attrib["URL"])
|
||||
for mirror in plugin.findall("./mirror"):
|
||||
if "URL" in mirror.attrib:
|
||||
if checkHash:
|
||||
check_hash(plugin, plugin.attrib["URL"], valid_urls)
|
||||
plugin_urls.append(mirror.attrib["URL"])
|
||||
|
||||
results[channel][target] = plugin_urls
|
||||
|
||||
matching_channels = {}
|
||||
for channel in channels:
|
||||
matching_channels[channel] = [channel]
|
||||
for other_channel in channels:
|
||||
if (
|
||||
channel == other_channel
|
||||
or channel not in results
|
||||
or other_channel not in results
|
||||
):
|
||||
continue
|
||||
if results[channel] == results[other_channel]:
|
||||
matching_channels[channel].append(other_channel)
|
||||
del results[other_channel]
|
||||
|
||||
for channel in results:
|
||||
print(", ".join(matching_channels[channel]))
|
||||
for target in targets:
|
||||
print("\t{}".format(target))
|
||||
for url in results[channel][target]:
|
||||
print("\t\t{}".format(url))
|
||||
|
||||
|
||||
def main():
|
||||
examples = """examples:
|
||||
python dom/media/tools/checkGmpBalrog.py widevine 133.0
|
||||
python dom/media/tools/checkGmpBalrog.py widevine 133.0 --target Darwin_aarch64-gcc3 Darwin_x86_64-gcc3
|
||||
python dom/media/tools/checkGmpBalrog.py --url http://localhost:8080 openh264 125.0
|
||||
python dom/media/tools/checkGmpBalrog.py widevine_l1 115.14.0 --staging --channel nightly beta"""
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Check Balrog XML for GMP plugin updates",
|
||||
epilog=examples,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
)
|
||||
parser.add_argument(
|
||||
"plugin",
|
||||
help="which plugin: openh264, widevine, widevine_l1",
|
||||
)
|
||||
parser.add_argument("version", help="version of Firefox")
|
||||
parser.add_argument(
|
||||
"--channel", action="extend", nargs="+", help="check specific channel(s)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--list-channels", action="store_true", help="list the supported channels"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--target", action="extend", nargs="+", help="check specific target(s)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--list-targets", action="store_true", help="list the supported targets"
|
||||
)
|
||||
parser.add_argument("--buildid", help="override generated build ID to be specific")
|
||||
parser.add_argument(
|
||||
"--url", help="override base URL from which to fetch the balrog configuration"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--staging",
|
||||
action="store_true",
|
||||
help="using the balrog staging URL instead of production",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--checkHash",
|
||||
action="store_true",
|
||||
help="download plugins and validate the size/hash",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
valid_channels = ["esr", "release", "beta", "nightly", "nightlytest"]
|
||||
if args.list_channels:
|
||||
for channel in valid_channels:
|
||||
print(channel)
|
||||
return
|
||||
if args.channel is not None:
|
||||
for channel in args.channel:
|
||||
if channel not in valid_channels:
|
||||
parser.error("`%s` is invalid, see --list-channels" % channel)
|
||||
return
|
||||
channels = args.channel
|
||||
else:
|
||||
channels = valid_channels
|
||||
|
||||
valid_targets = [
|
||||
"Darwin_aarch64-gcc3",
|
||||
"Darwin_x86_64-gcc3",
|
||||
"Linux_aarch64-gcc3",
|
||||
"Linux_x86-gcc3",
|
||||
"Linux_x86_64-gcc3",
|
||||
"WINNT_aarch64-msvc-aarch64",
|
||||
"WINNT_x86-msvc",
|
||||
"WINNT_x86_64-msvc",
|
||||
]
|
||||
valid_aliases = [
|
||||
"Linux_x86_64-gcc3-asan",
|
||||
"WINNT_x86-msvc-x64",
|
||||
"WINNT_x86-msvc-x86",
|
||||
"WINNT_x86_64-msvc-x64",
|
||||
"WINNT_x86_64-msvc-x64-asan",
|
||||
]
|
||||
if args.list_targets:
|
||||
for target in valid_targets:
|
||||
print(target)
|
||||
for target in valid_aliases:
|
||||
print("%s (alias)" % target)
|
||||
return
|
||||
if args.target is not None:
|
||||
for target in args.target:
|
||||
if target not in valid_targets and target not in valid_aliases:
|
||||
parser.error("`%s` is invalid, see --list-targets" % target)
|
||||
return
|
||||
targets = args.target
|
||||
else:
|
||||
targets = valid_targets
|
||||
|
||||
if args.buildid is not None:
|
||||
if not re.match(r"^\d{14}$", args.buildid):
|
||||
parser.error("`%s` is invalid, build id must be 14 digits")
|
||||
return
|
||||
buildid = args.buildid
|
||||
|
||||
else:
|
||||
buildid = datetime.today().strftime("%y%m%d%H%M%S")
|
||||
|
||||
url_base = "https://aus5.mozilla.org"
|
||||
if args.staging:
|
||||
url_base = "https://stage.balrog.nonprod.cloudops.mozgcp.net"
|
||||
if args.url is not None:
|
||||
url_base = args.url
|
||||
if url_base[-1] == "/":
|
||||
url_base = url_base[:-1]
|
||||
url_base += "/update/3/GMP"
|
||||
|
||||
parsed_url = urlparse(url_base)
|
||||
if parsed_url.scheme not in ("http", "https"):
|
||||
parser.error("expected http(s) scheme, got `%s`" % parsed_url.scheme)
|
||||
return
|
||||
if parsed_url.path != "/update/3/GMP":
|
||||
parser.error("expected url path of `/update/3/GMP`, got `%s`" % parsed_url.path)
|
||||
return
|
||||
|
||||
if args.plugin == "openh264":
|
||||
plugin = "gmp-gmpopenh264"
|
||||
elif args.plugin == "widevine":
|
||||
plugin = "gmp-widevinecdm"
|
||||
elif args.plugin == "widevine_l1":
|
||||
plugin = "gmp-widevinecdm-l1"
|
||||
else:
|
||||
parser.error("plugin not recognized")
|
||||
return
|
||||
|
||||
if not re.match(r"^\d+\.\d+(\.\d+)?$", args.version):
|
||||
parser.error("version must be of the form ###.###(.###)")
|
||||
return
|
||||
|
||||
fetch_balrog_xml(
|
||||
url_base, plugin, args.version, buildid, channels, targets, args.checkHash
|
||||
)
|
||||
|
||||
|
||||
main()
|
|
@ -1491,17 +1491,6 @@ bool nsContentSecurityUtils::ValidateScriptFilename(JSContext* cx,
|
|||
}
|
||||
}
|
||||
|
||||
auto kAllowedFilenamesExact = {
|
||||
// Allow through the injection provided by about:sync addon
|
||||
"data:,new function() {\n const { AboutSyncRedirector } = ChromeUtils.import(\"chrome://aboutsync/content/AboutSyncRedirector.js\");\n AboutSyncRedirector.register();\n}"_ns,
|
||||
};
|
||||
|
||||
for (auto allowedFilename : kAllowedFilenamesExact) {
|
||||
if (filename == allowedFilename) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
auto kAllowedFilenamesPrefix = {
|
||||
// Until 371900 is fixed, we need to do something about about:downloads
|
||||
// and this is the most reasonable. See 1727770
|
||||
|
|
|
@ -198,6 +198,13 @@ static bool WindowCannotReceiveSensorEvent(nsPIDOMWindowInner* aWindow) {
|
|||
nsPIDOMWindowOuter* windowOuter = aWindow->GetOuterWindow();
|
||||
BrowsingContext* topBC = aWindow->GetBrowsingContext()->Top();
|
||||
if (windowOuter->IsBackground() || !topBC->GetIsActiveBrowserWindow()) {
|
||||
nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(aWindow);
|
||||
nsIPrincipal* principal = win->GetPrincipal();
|
||||
if (principal &&
|
||||
principal->Equals(
|
||||
nsContentUtils::GetFingerprintingProtectionPrincipal())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -328,6 +328,7 @@ nsTArray<uint8_t> NSDataToArray(NSData* data) {
|
|||
switch (platformCredential.attachment) {
|
||||
case ASAuthorizationPublicKeyCredentialAttachmentCrossPlatform:
|
||||
authenticatorAttachment.emplace(u"cross-platform"_ns);
|
||||
transports.AppendElement(u"hybrid"_ns);
|
||||
break;
|
||||
case ASAuthorizationPublicKeyCredentialAttachmentPlatform:
|
||||
authenticatorAttachment.emplace(u"platform"_ns);
|
||||
|
|
|
@ -299,9 +299,11 @@ WinWebAuthnService::MakeCredential(uint64_t aTransactionId,
|
|||
DWORD winUserVerificationReq =
|
||||
WEBAUTHN_USER_VERIFICATION_REQUIREMENT_ANY;
|
||||
|
||||
// Resident Key
|
||||
BOOL winRequireResidentKey = FALSE;
|
||||
BOOL winPreferResidentKey = FALSE;
|
||||
// Resident Key Requirement.
|
||||
BOOL winRequireResidentKey = FALSE; // Will be set to TRUE if and only
|
||||
// if residentKey = "required"
|
||||
BOOL winPreferResidentKey = FALSE; // Will be set to TRUE if and only
|
||||
// if residentKey = "preferred"
|
||||
|
||||
// AttestationConveyance
|
||||
DWORD winAttestation = WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_ANY;
|
||||
|
@ -391,7 +393,7 @@ WinWebAuthnService::MakeCredential(uint64_t aTransactionId,
|
|||
if (residentKey.EqualsLiteral(
|
||||
MOZ_WEBAUTHN_RESIDENT_KEY_REQUIREMENT_REQUIRED)) {
|
||||
winRequireResidentKey = TRUE;
|
||||
winPreferResidentKey = TRUE;
|
||||
winPreferResidentKey = FALSE;
|
||||
} else if (residentKey.EqualsLiteral(
|
||||
MOZ_WEBAUTHN_RESIDENT_KEY_REQUIREMENT_PREFERRED)) {
|
||||
winRequireResidentKey = FALSE;
|
||||
|
|
|
@ -24,7 +24,7 @@ interface DOMParser {
|
|||
constructor();
|
||||
|
||||
[NewObject, Throws, UseCounter]
|
||||
Document parseFromString(DOMString str, SupportedType type);
|
||||
Document parseFromString((TrustedHTML or DOMString) str, SupportedType type);
|
||||
|
||||
[NewObject, ChromeOnly, Throws]
|
||||
Document parseFromSafeString(DOMString str, SupportedType type);
|
||||
|
|
|
@ -19,23 +19,23 @@ interface MouseEvent : UIEvent {
|
|||
optional MouseEventInit mouseEventInitDict = {});
|
||||
|
||||
[NeedsCallerType]
|
||||
readonly attribute long screenX;
|
||||
readonly attribute double screenX;
|
||||
[NeedsCallerType]
|
||||
readonly attribute long screenY;
|
||||
readonly attribute double screenY;
|
||||
|
||||
[ChromeOnly]
|
||||
readonly attribute nsIScreen? screen;
|
||||
|
||||
readonly attribute long pageX;
|
||||
readonly attribute long pageY;
|
||||
readonly attribute long clientX;
|
||||
readonly attribute long clientY;
|
||||
readonly attribute double pageX;
|
||||
readonly attribute double pageY;
|
||||
readonly attribute double clientX;
|
||||
readonly attribute double clientY;
|
||||
[BinaryName="clientX"]
|
||||
readonly attribute long x;
|
||||
readonly attribute double x;
|
||||
[BinaryName="clientY"]
|
||||
readonly attribute long y;
|
||||
readonly attribute long offsetX;
|
||||
readonly attribute long offsetY;
|
||||
readonly attribute double y;
|
||||
readonly attribute double offsetX;
|
||||
readonly attribute double offsetY;
|
||||
readonly attribute boolean ctrlKey;
|
||||
readonly attribute boolean shiftKey;
|
||||
readonly attribute boolean altKey;
|
||||
|
@ -72,10 +72,10 @@ interface MouseEvent : UIEvent {
|
|||
// Suggested initMouseEvent replacement initializer:
|
||||
dictionary MouseEventInit : EventModifierInit {
|
||||
// Attributes for MouseEvent:
|
||||
long screenX = 0;
|
||||
long screenY = 0;
|
||||
long clientX = 0;
|
||||
long clientY = 0;
|
||||
double screenX = 0.0;
|
||||
double screenY = 0.0;
|
||||
double clientX = 0.0;
|
||||
double clientY = 0.0;
|
||||
short button = 0;
|
||||
// Note: "buttons" was not previously initializable through initMouseEvent!
|
||||
unsigned short buttons = 0;
|
||||
|
|
|
@ -14,8 +14,8 @@ interface PointerEvent : MouseEvent
|
|||
|
||||
readonly attribute long pointerId;
|
||||
|
||||
readonly attribute long width;
|
||||
readonly attribute long height;
|
||||
readonly attribute double width;
|
||||
readonly attribute double height;
|
||||
readonly attribute float pressure;
|
||||
readonly attribute float tangentialPressure;
|
||||
readonly attribute long tiltX;
|
||||
|
@ -35,8 +35,8 @@ interface PointerEvent : MouseEvent
|
|||
dictionary PointerEventInit : MouseEventInit
|
||||
{
|
||||
long pointerId = 0;
|
||||
long width = 1;
|
||||
long height = 1;
|
||||
double width = 1.0;
|
||||
double height = 1.0;
|
||||
float pressure = 0;
|
||||
float tangentialPressure = 0;
|
||||
long tiltX;
|
||||
|
|
|
@ -274,7 +274,8 @@ nsresult nsXULPopupListener::LaunchPopup(MouseEvent* aEvent) {
|
|||
pm->ShowPopup(mPopupContent, mElement, u""_ns, 0, 0, false, true, false,
|
||||
aEvent);
|
||||
} else {
|
||||
CSSIntPoint pos = aEvent->ScreenPoint(CallerType::System);
|
||||
const CSSIntPoint pos =
|
||||
RoundedToInt(aEvent->ScreenPoint(CallerType::System));
|
||||
pm->ShowPopupAtScreen(mPopupContent, pos.x, pos.y, mIsContext, aEvent);
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue