зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound. a=merge
This commit is contained in:
Коммит
4bf41d68cf
|
@ -45,6 +45,7 @@
|
|||
# taskGroupId, // targetted taskGroupId
|
||||
# action: {name, title, description, taskGroupId, symbol, repo_scope, cb_name}
|
||||
# ownTaskId: // taskId of the task that will be created
|
||||
# clientId: // clientId that triggered this hook
|
||||
# }
|
||||
|
||||
version: 1
|
||||
|
@ -58,6 +59,11 @@ tasks:
|
|||
ownerEmail: {$if: '"@" in push.owner', then: '${push.owner}', else: '${push.owner}@noreply.mozilla.org'}
|
||||
# ensure there's no trailing `/` on the repo URL
|
||||
repoUrl: {$if: 'repository.url[-1] == "/"', then: {$eval: 'repository.url[:-1]'}, else: {$eval: 'repository.url'}}
|
||||
# expire try earlier than other branches
|
||||
expires:
|
||||
$if: 'repository.project == "try"'
|
||||
then: {$fromNow: '28 days'}
|
||||
else: {$fromNow: '1 year'}
|
||||
in:
|
||||
taskId: {$if: 'tasks_for != "action"', then: '${ownTaskId}'}
|
||||
taskGroupId:
|
||||
|
@ -70,7 +76,7 @@ tasks:
|
|||
|
||||
created: {$fromNow: ''}
|
||||
deadline: {$fromNow: '1 day'}
|
||||
expires: {$fromNow: '1 year 1 second'} # 1 second so artifacts expire first, despite rounding errors
|
||||
expires: {$eval: 'expires'}
|
||||
metadata:
|
||||
$merge:
|
||||
- owner: "${ownerEmail}"
|
||||
|
@ -254,7 +260,7 @@ tasks:
|
|||
'public':
|
||||
type: 'directory'
|
||||
path: '/builds/worker/artifacts'
|
||||
expires: {$fromNow: '1 year'}
|
||||
expires: {$eval: expires}
|
||||
|
||||
extra:
|
||||
$merge:
|
||||
|
|
|
@ -483,16 +483,6 @@ class NetErrorChild extends ActorChild {
|
|||
if (Math.abs(difference) > 60 * 60 * 24 && (now - lastFetched) <= 60 * 60 * 24 * 5 &&
|
||||
certRange.notBefore < approximateDate && certRange.notAfter > approximateDate) {
|
||||
clockSkew = true;
|
||||
let systemDate = formatter.format(new Date());
|
||||
// negative difference means local time is behind server time
|
||||
approximateDate = formatter.format(new Date(approximateDate));
|
||||
|
||||
doc.getElementById("wrongSystemTime_URL").textContent = doc.location.hostname;
|
||||
doc.getElementById("wrongSystemTime_systemDate").textContent = systemDate;
|
||||
doc.getElementById("wrongSystemTime_actualDate").textContent = approximateDate;
|
||||
|
||||
doc.getElementById("errorShortDesc").style.display = "none";
|
||||
doc.getElementById("wrongSystemTimePanel").style.display = "block";
|
||||
|
||||
// If there is no clock skew with Kinto servers, check against the build date.
|
||||
// (The Kinto ping could have happened when the time was still right, or not at all)
|
||||
|
@ -512,11 +502,6 @@ class NetErrorChild extends ActorChild {
|
|||
// since the build date.
|
||||
if (buildDate > systemDate && new Date(certRange.notAfter) > buildDate) {
|
||||
clockSkew = true;
|
||||
|
||||
doc.getElementById("wrongSystemTimeWithoutReference_URL")
|
||||
.textContent = doc.location.hostname;
|
||||
doc.getElementById("wrongSystemTimeWithoutReference_systemDate")
|
||||
.textContent = formatter.format(systemDate);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -530,7 +515,6 @@ class NetErrorChild extends ActorChild {
|
|||
doc.querySelector(".title-text").textContent = clockErrTitle.textContent;
|
||||
let desc = doc.getElementById("errorShortDescText");
|
||||
doc.getElementById("errorShortDesc").style.display = "block";
|
||||
doc.getElementById("wrongSystemTimePanel").style.display = "none";
|
||||
doc.getElementById("certificateErrorReporting").style.display = "none";
|
||||
if (desc) {
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
|
|
|
@ -170,14 +170,6 @@
|
|||
<p id="badStsCertExplanation" hidden="true">&certerror.whatShouldIDo.badStsCertExplanation1;</p>
|
||||
</div>
|
||||
|
||||
<div id="wrongSystemTimePanel">
|
||||
&certerror.wrongSystemTime2;
|
||||
</div>
|
||||
|
||||
<div id="wrongSystemTimeWithoutReferencePanel">
|
||||
&certerror.wrongSystemTimeWithoutReference;
|
||||
</div>
|
||||
|
||||
<!-- Long Description (Note: See netError.dtd for used XHTML tags) -->
|
||||
<div id="errorLongDesc" />
|
||||
|
||||
|
|
|
@ -3726,10 +3726,8 @@ var browserDragAndDrop = {
|
|||
return Services.droppedLinkHandler.getCSP(aEvent);
|
||||
},
|
||||
|
||||
validateURIsForDrop(aEvent, aURIsCount, aURIs) {
|
||||
return Services.droppedLinkHandler.validateURIsForDrop(aEvent,
|
||||
aURIsCount,
|
||||
aURIs);
|
||||
validateURIsForDrop(aEvent, aURIs) {
|
||||
return Services.droppedLinkHandler.validateURIsForDrop(aEvent, aURIs);
|
||||
},
|
||||
|
||||
dropLinks(aEvent, aDisallowInherit) {
|
||||
|
@ -3752,7 +3750,7 @@ var homeButtonObserver = {
|
|||
}
|
||||
|
||||
try {
|
||||
browserDragAndDrop.validateURIsForDrop(aEvent, urls.length, urls);
|
||||
browserDragAndDrop.validateURIsForDrop(aEvent, urls);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -781,7 +781,10 @@ nsContextMenu.prototype = {
|
|||
},
|
||||
|
||||
openPasswordManager() {
|
||||
LoginHelper.openPasswordManager(window, gContextMenuContentData.documentURIObject.host);
|
||||
LoginHelper.openPasswordManager(window, {
|
||||
filterString: gContextMenuContentData.documentURIObject.host,
|
||||
entryPoint: "contextmenu",
|
||||
});
|
||||
},
|
||||
|
||||
inspectNode() {
|
||||
|
|
|
@ -180,7 +180,10 @@ var security = {
|
|||
* Open the login manager window
|
||||
*/
|
||||
viewPasswords() {
|
||||
LoginHelper.openPasswordManager(window, this._getSecurityInfo().hostName);
|
||||
LoginHelper.openPasswordManager(window, {
|
||||
filterString: this._getSecurityInfo().hostName,
|
||||
entryPoint: "pageinfo",
|
||||
});
|
||||
},
|
||||
|
||||
_cert: null,
|
||||
|
|
|
@ -114,3 +114,4 @@ support-files =
|
|||
support-files =
|
||||
file_mixedPassiveContent.html
|
||||
file_bug1045809_1.html
|
||||
[browser_deprecatedTLSVersions.js]
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*
|
||||
* Tests for Bug 1535210 - Set SSL STATE_IS_BROKEN flag for TLS1.0 and TLS 1.1 connections
|
||||
*/
|
||||
|
||||
const HTTPS_TLS1_0 = "https://tls1.example.com";
|
||||
const HTTPS_TLS1_1 = "https://tls11.example.com";
|
||||
const HTTPS_TLS1_2 = "https://tls12.example.com";
|
||||
const HTTPS_TLS1_3 = "https://tls13.example.com";
|
||||
|
||||
|
||||
function getIdentityMode(aWindow = window) {
|
||||
return aWindow.document.getElementById("identity-box").className;
|
||||
}
|
||||
|
||||
function getConnectionState() {
|
||||
// Prevents items that are being lazy loaded causing issues
|
||||
document.getElementById("identity-box").click();
|
||||
gIdentityHandler.refreshIdentityPopup();
|
||||
return document.getElementById("identity-popup").getAttribute("connection");
|
||||
}
|
||||
|
||||
add_task(async function() {
|
||||
await BrowserTestUtils.withNewTab("about:blank", async function(browser) {
|
||||
// Try deprecated versions
|
||||
await BrowserTestUtils.loadURI(browser, HTTPS_TLS1_0);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
isSecurityState(browser, "broken");
|
||||
is(getIdentityMode(), "unknownIdentity weakCipher", "Identity should be unknownIdentity");
|
||||
is(getConnectionState(), "not-secure", "connectionState should be not-secure");
|
||||
|
||||
await BrowserTestUtils.loadURI(browser, HTTPS_TLS1_1);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
isSecurityState(browser, "broken");
|
||||
is(getIdentityMode(), "unknownIdentity weakCipher", "Identity should be unknownIdentity");
|
||||
is(getConnectionState(), "not-secure", "connectionState should be not-secure");
|
||||
|
||||
// Transition to secure
|
||||
await BrowserTestUtils.loadURI(browser, HTTPS_TLS1_2);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
isSecurityState(browser, "secure");
|
||||
is(getIdentityMode(), "verifiedDomain", "Identity should be verified");
|
||||
is(getConnectionState(), "secure", "connectionState should be secure");
|
||||
|
||||
// Transition back to broken
|
||||
await BrowserTestUtils.loadURI(browser, HTTPS_TLS1_1);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
isSecurityState(browser, "broken");
|
||||
is(getIdentityMode(), "unknownIdentity weakCipher", "Identity should be unknownIdentity");
|
||||
is(getConnectionState(), "not-secure", "connectionState should be not-secure");
|
||||
|
||||
// TLS1.3 for completeness
|
||||
await BrowserTestUtils.loadURI(browser, HTTPS_TLS1_3);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
isSecurityState(browser, "secure");
|
||||
is(getIdentityMode(), "verifiedDomain", "Identity should be verified");
|
||||
is(getConnectionState(), "secure", "connectionState should be secure");
|
||||
});
|
||||
});
|
|
@ -32,14 +32,6 @@ let gWhitelist = [{
|
|||
file: "netError.dtd",
|
||||
key: "inadequateSecurityError.longDesc",
|
||||
type: "single-quote",
|
||||
}, {
|
||||
file: "netError.dtd",
|
||||
key: "certerror.wrongSystemTime2",
|
||||
type: "single-quote",
|
||||
}, {
|
||||
file: "netError.dtd",
|
||||
key: "certerror.wrongSystemTimeWithoutReference",
|
||||
type: "single-quote",
|
||||
}, {
|
||||
file: "netError.dtd",
|
||||
key: "clockSkewError.longDesc",
|
||||
|
|
|
@ -336,7 +336,7 @@
|
|||
<toolbarbutton id="appMenu-logins-button"
|
||||
class="subviewbutton subviewbutton-iconic"
|
||||
label="&logins.label;"
|
||||
oncommand="LoginHelper.openPasswordManager(window)"
|
||||
oncommand="LoginHelper.openPasswordManager(window, { entryPoint: 'mainmenu' })"
|
||||
/>
|
||||
<toolbarbutton id="appMenu-addons-button"
|
||||
class="subviewbutton subviewbutton-iconic"
|
||||
|
@ -425,7 +425,7 @@
|
|||
<toolbarbutton id="appMenuViewHistorySidebar"
|
||||
label="&appMenuHistory.viewSidebar.label;"
|
||||
label-checked="&appMenuHistory.hideSidebar.label;"
|
||||
label-unchecked="&appMenuHistory.viewSidebar.label;"
|
||||
label-unchecked="&appMenuHistory.viewSidebar.label;"
|
||||
type="checkbox"
|
||||
class="subviewbutton subviewbutton-iconic"
|
||||
key="key_gotoHistory"
|
||||
|
|
|
@ -294,6 +294,8 @@ var gPrivacyPane = {
|
|||
this.networkCookieBehaviorReadPrefs();
|
||||
this._initTrackingProtectionExtensionControl();
|
||||
|
||||
Services.telemetry.setEventRecordingEnabled("pwmgr", true);
|
||||
|
||||
Preferences.get("media.autoplay.default").on("change",
|
||||
gPrivacyPane.blockAutoplayReadPrefs.bind(gPrivacyPane));
|
||||
|
||||
|
@ -1422,9 +1424,12 @@ var gPrivacyPane = {
|
|||
*/
|
||||
showPasswords() {
|
||||
if (LoginHelper.managementURI) {
|
||||
window.docShell.messageManager.sendAsyncMessage("PasswordManager:OpenPreferences", {});
|
||||
window.docShell.messageManager.sendAsyncMessage("PasswordManager:OpenPreferences", {
|
||||
entryPoint: "preferences",
|
||||
});
|
||||
return;
|
||||
}
|
||||
Services.telemetry.recordEvent("pwmgr", "open_management", "preferences");
|
||||
gSubDialog.open("chrome://passwordmgr/content/passwordManager.xul");
|
||||
},
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
ChromeUtils.import("resource://testing-common/TelemetryTestUtils.jsm", this);
|
||||
|
||||
const PM_URL = "chrome://passwordmgr/content/passwordManager.xul";
|
||||
const PREF_MANAGEMENT_URI = "signon.management.overrideURI";
|
||||
|
||||
|
@ -21,6 +24,7 @@ add_task(async function test_setup() {
|
|||
});
|
||||
|
||||
add_task(async function test_openPasswordSubDialog() {
|
||||
Services.telemetry.clearEvents();
|
||||
await openPreferencesViaOpenPreferencesAPI("privacy", {leaveOpen: true});
|
||||
|
||||
let dialogOpened = promiseLoadSubDialog(PM_URL);
|
||||
|
@ -37,6 +41,11 @@ add_task(async function test_openPasswordSubDialog() {
|
|||
});
|
||||
|
||||
passwordsDialog = await dialogOpened;
|
||||
|
||||
// check telemetry events while we are in here
|
||||
TelemetryTestUtils.assertEvents(
|
||||
[["pwmgr", "open_management", "preferences"]],
|
||||
{category: "pwmgr", method: "open_management"});
|
||||
});
|
||||
|
||||
add_task(async function test_deletePasswordWithKey() {
|
||||
|
@ -60,6 +69,7 @@ add_task(async function test_deletePasswordWithKey() {
|
|||
});
|
||||
|
||||
add_task(async function subdialog_cleanup() {
|
||||
Services.telemetry.clearEvents();
|
||||
// Undo the save password change.
|
||||
await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
|
||||
let doc = content.document;
|
||||
|
|
|
@ -2,22 +2,30 @@
|
|||
# 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/.
|
||||
|
||||
## UI strings for the simplified onboarding modal
|
||||
### UI strings for the simplified onboarding modal / about:welcome
|
||||
### Various strings use a non-breaking space to avoid a single dangling /
|
||||
### widowed word, so test on various window sizes if you also want this.
|
||||
|
||||
## These button action text can be split onto multiple lines, so use explicit
|
||||
## newlines in translations to control where the line break appears (e.g., to
|
||||
## avoid breaking quoted text).
|
||||
|
||||
onboarding-button-label-learn-more = Learn More
|
||||
onboarding-button-label-try-now = Try It Now
|
||||
onboarding-button-label-get-started = Get Started
|
||||
|
||||
## Welcome modal dialog strings
|
||||
|
||||
onboarding-welcome-header = Welcome to { -brand-short-name }
|
||||
onboarding-welcome-body = You’ve got the browser.<br/>Meet the rest of { -brand-product-name }.
|
||||
onboarding-welcome-learn-more = Learn more about the benefits.
|
||||
|
||||
onboarding-join-form-header = Join { -brand-product-name }
|
||||
onboarding-join-form-body = Enter your email address to get started.
|
||||
onboarding-join-form-body = Enter your email address to get started.
|
||||
onboarding-join-form-email =
|
||||
.placeholder = Enter email
|
||||
onboarding-join-form-email-error = Valid email required
|
||||
onboarding-join-form-legal = By proceeding, you agree to the <a data-l10n-name="terms">Terms of Service</a> and <a data-l10n-name="privacy">Privacy Notice</a>.
|
||||
onboarding-join-form-legal = By proceeding, you agree to the <a data-l10n-name="terms">Terms of Service</a> and <a data-l10n-name="privacy">Privacy Notice</a>.
|
||||
onboarding-join-form-continue = Continue
|
||||
|
||||
onboarding-start-browsing-button-label = Start Browsing
|
||||
|
@ -29,7 +37,7 @@ onboarding-benefit-products-title = Useful Products
|
|||
onboarding-benefit-products-text = Get things done with a family of tools that respects your privacy across your devices.
|
||||
|
||||
onboarding-benefit-knowledge-title = Practical Knowledge
|
||||
onboarding-benefit-knowledge-text = Learn everything you need to know to stay smarter and safer online.
|
||||
onboarding-benefit-knowledge-text = Learn everything you need to know to stay smarter and safer online.
|
||||
|
||||
onboarding-benefit-privacy-title = True Privacy
|
||||
# "Personal Data Promise" is a concept that should be translated consistently
|
||||
|
@ -65,12 +73,12 @@ onboarding-tracking-protection-title2 = Protection From Tracking
|
|||
onboarding-tracking-protection-text2 = { -brand-short-name } helps stop websites from tracking you online, making it harder for ads to follow you around the web.
|
||||
onboarding-tracking-protection-button2 = How it Works
|
||||
|
||||
onboarding-data-sync-title = Take Your Settings with You
|
||||
onboarding-data-sync-title = Take Your Settings with You
|
||||
# "Sync" is short for synchronize.
|
||||
onboarding-data-sync-text2 = Sync your bookmarks, passwords, and more everywhere you use { -brand-product-name }.
|
||||
onboarding-data-sync-button2 = Sign in to { -sync-brand-short-name }
|
||||
|
||||
onboarding-firefox-monitor-title = Stay Alert to Data Breaches
|
||||
onboarding-firefox-monitor-title = Stay Alert to Data Breaches
|
||||
onboarding-firefox-monitor-text = { -monitor-brand-name } monitors if your email has appeared in a data breach and alerts you if it appears in a new breach.
|
||||
onboarding-firefox-monitor-button = Sign up for Alerts
|
||||
|
||||
|
@ -78,7 +86,7 @@ onboarding-browse-privately-title = Browse Privately
|
|||
onboarding-browse-privately-text = Private Browsing clears your search and browsing history to keep it secret from anyone who uses your computer.
|
||||
onboarding-browse-privately-button = Open a Private Window
|
||||
|
||||
onboarding-firefox-send-title = Keep Your Shared Files Private
|
||||
onboarding-firefox-send-title = Keep Your Shared Files Private
|
||||
onboarding-firefox-send-text2 = Upload your files to { -send-brand-name } to share them with end-to-end encryption and a link that automatically expires.
|
||||
onboarding-firefox-send-button = Try { -send-brand-name }
|
||||
|
||||
|
@ -88,21 +96,21 @@ onboarding-mobile-phone-text = Download { -brand-product-name } for iOS or Andro
|
|||
# browser.
|
||||
onboarding-mobile-phone-button = Download Mobile Browser
|
||||
|
||||
onboarding-send-tabs-title = Instantly Send Yourself Tabs
|
||||
onboarding-send-tabs-title = Instantly Send Yourself Tabs
|
||||
# "Send Tabs" refers to "Send Tab to Device" feature that appears when opening a
|
||||
# tab's context menu.
|
||||
onboarding-send-tabs-text = Send Tabs instantly shares pages between your devices without having to copy, paste, or leave the browser.
|
||||
onboarding-send-tabs-button = Start Using Send Tabs
|
||||
|
||||
onboarding-pocket-anywhere-title = Read and Listen Anywhere
|
||||
onboarding-pocket-anywhere-text2 = Save your favorite content offline with the { -pocket-brand-name } App and read, listen, and watch whenever it’s convenient for you.
|
||||
onboarding-pocket-anywhere-text2 = Save your favorite content offline with the { -pocket-brand-name } App and read, listen, and watch whenever it’s convenient for you.
|
||||
onboarding-pocket-anywhere-button = Try { -pocket-brand-name }
|
||||
|
||||
onboarding-lockwise-passwords-title = Take Your Passwords Everywhere
|
||||
onboarding-lockwise-passwords-title = Take Your Passwords Everywhere
|
||||
onboarding-lockwise-passwords-text2 = Keep the passwords you save secure and easily log in to your accounts with { -lockwise-brand-name }.
|
||||
onboarding-lockwise-passwords-button2 = Get the App
|
||||
|
||||
onboarding-facebook-container-title = Set Boundaries with Facebook
|
||||
onboarding-facebook-container-title = Set Boundaries with Facebook
|
||||
onboarding-facebook-container-text2 = { -facebook-container-brand-name } keeps your profile separate from everything else, making it harder for Facebook to target you with ads.
|
||||
onboarding-facebook-container-button = Add the Extension
|
||||
|
||||
|
|
|
@ -205,12 +205,6 @@ was trying to connect. -->
|
|||
"SSL_ERROR_UNSUPPORTED_VERSION". -->
|
||||
<!ENTITY sslv3Used.longDesc2 "Advanced info: SSL_ERROR_UNSUPPORTED_VERSION">
|
||||
|
||||
<!-- LOCALIZATION NOTE (certerror.wrongSystemTime2,
|
||||
certerror.wrongSystemTimeWithoutReference) - The <span id='..' />
|
||||
tags will be injected with actual values, please leave them unchanged. -->
|
||||
<!ENTITY certerror.wrongSystemTime2 "<p> &brandShortName; did not connect to <span id='wrongSystemTime_URL'/> because your computer’s clock appears to show the wrong time and this is preventing a secure connection.</p> <p>Your computer is set to <span id='wrongSystemTime_systemDate'/>, when it should be <span id='wrongSystemTime_actualDate'/>. To fix this problem, change your date and time settings to match the correct time.</p>">
|
||||
<!ENTITY certerror.wrongSystemTimeWithoutReference "<p>&brandShortName; did not connect to <span id='wrongSystemTimeWithoutReference_URL'/> because your computer’s clock appears to show the wrong time and this is preventing a secure connection.</p> <p>Your computer is set to <span id='wrongSystemTimeWithoutReference_systemDate'/>. To fix this problem, change your date and time settings to match the correct time.</p>">
|
||||
|
||||
<!ENTITY certerror.pagetitle2 "Warning: Potential Security Risk Ahead">
|
||||
<!ENTITY certerror.sts.pagetitle "Did Not Connect: Potential Security Issue">
|
||||
<!ENTITY certerror.whatShouldIDo.badStsCertExplanation1 "<span class='hostname'></span> has a security policy called HTTP Strict Transport Security (HSTS), which means that &brandShortName; can only connect to it securely. You can’t add an exception to visit this site.">
|
||||
|
|
|
@ -149,16 +149,17 @@ async function allTabTitlesDisplayed(browserWindow) {
|
|||
|
||||
let tabTitlePromises = [];
|
||||
for (let tab of browserWindow.gBrowser.tabs) {
|
||||
function tabTitleLoaded(spec) {
|
||||
return () => {
|
||||
return spec ? tab.label == specToTitleMap[spec] : false;
|
||||
};
|
||||
function getSpec() {
|
||||
return tab.linkedBrowser &&
|
||||
tab.linkedBrowser.documentURI &&
|
||||
tab.linkedBrowser.documentURI.spec;
|
||||
}
|
||||
function tabTitleLoaded() {
|
||||
let spec = getSpec();
|
||||
return spec ? tab.label == specToTitleMap[spec] : false;
|
||||
}
|
||||
let spec = tab.linkedBrowser &&
|
||||
tab.linkedBrowser.documentURI &&
|
||||
tab.linkedBrowser.documentURI.spec;
|
||||
let promise =
|
||||
TestUtils.waitForCondition(tabTitleLoaded(spec), `Tab (${spec}) should be showing "${specToTitleMap[spec]}". Got "${tab.label}"`);
|
||||
TestUtils.waitForCondition(tabTitleLoaded, `Tab (${getSpec()}) should be showing "${specToTitleMap[getSpec()]}". Got "${tab.label}"`);
|
||||
tabTitlePromises.push(promise);
|
||||
}
|
||||
|
||||
|
|
Двоичные данные
build/pgo/certs/cert9.db
Двоичные данные
build/pgo/certs/cert9.db
Двоичный файл не отображается.
Двоичные данные
build/pgo/certs/key4.db
Двоичные данные
build/pgo/certs/key4.db
Двоичный файл не отображается.
Двоичные данные
build/pgo/certs/mochitest.client
Двоичные данные
build/pgo/certs/mochitest.client
Двоичный файл не отображается.
|
@ -286,11 +286,14 @@ https://sha256ee.example.com:443 privileged,cer
|
|||
# Hosts for imminent distrust warning tests
|
||||
https://imminently-distrusted.example.com:443 privileged,cert=imminently_distrusted
|
||||
|
||||
# Hosts for ssl3/rc4 console warning tests
|
||||
https://ssl3.example.com:443 privileged,ssl3
|
||||
https://rc4.example.com:443 privileged,rc4
|
||||
https://ssl3rc4.example.com:443 privileged,ssl3,rc4
|
||||
https://tls1.example.com:443 privileged,tls1
|
||||
# Hosts for ssl3/rc4/tls1 warning tests
|
||||
https://ssl3.example.com:443 privileged,ssl3
|
||||
https://rc4.example.com:443 privileged,rc4
|
||||
https://ssl3rc4.example.com:443 privileged,ssl3,rc4
|
||||
https://tls1.example.com:443 privileged,tls1
|
||||
https://tls11.example.com:443 privileged,tls1_1
|
||||
https://tls12.example.com:443 privileged,tls1_2
|
||||
https://tls13.example.com:443 privileged,tls1,tls1_3
|
||||
|
||||
# Hosts for youtube rewrite tests
|
||||
https://mochitest.youtube.com:443
|
||||
|
|
|
@ -17945,18 +17945,22 @@ const { workerHandler } = _devtoolsUtils.workerUtils; /* This Source Code Form i
|
|||
* 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/>. */
|
||||
|
||||
function clearState() {
|
||||
(0, _ast.clearASTs)();
|
||||
(0, _getScopes.clearScopes)();
|
||||
(0, _sources.clearSources)();
|
||||
(0, _getSymbols.clearSymbols)();
|
||||
}
|
||||
|
||||
self.onmessage = workerHandler({
|
||||
findOutOfScopeLocations: _findOutOfScopeLocations2.default,
|
||||
getSymbols: _getSymbols.getSymbols,
|
||||
getScopes: _getScopes2.default,
|
||||
clearSymbols: _getSymbols.clearSymbols,
|
||||
clearScopes: _getScopes.clearScopes,
|
||||
clearASTs: _ast.clearASTs,
|
||||
setSource: _sources.setSource,
|
||||
clearSources: _sources.clearSources,
|
||||
clearState,
|
||||
getNextStep: _steps.getNextStep,
|
||||
hasSyntaxError: _validate.hasSyntaxError,
|
||||
mapExpression: _mapExpression2.default
|
||||
mapExpression: _mapExpression2.default,
|
||||
setSource: _sources.setSource
|
||||
});
|
||||
|
||||
/***/ }),
|
||||
|
|
|
@ -33,7 +33,10 @@ DebuggerPanel.prototype = {
|
|||
threadClient: this.toolbox.threadClient,
|
||||
tabTarget: this.toolbox.target,
|
||||
debuggerClient: this.toolbox.target.client,
|
||||
sourceMaps: this.toolbox.sourceMapService,
|
||||
workers: {
|
||||
sourceMaps: this.toolbox.sourceMapService,
|
||||
evaluationsParser: this.toolbox.parserService
|
||||
},
|
||||
panel: this
|
||||
});
|
||||
|
||||
|
|
|
@ -8,13 +8,11 @@ import { getSourceWithContent, getSelectedLocation } from "../selectors";
|
|||
|
||||
import { setInScopeLines } from "./ast/setInScopeLines";
|
||||
|
||||
import * as parser from "../workers/parser";
|
||||
|
||||
import type { Context } from "../types";
|
||||
import type { ThunkArgs, Action } from "./types";
|
||||
|
||||
export function setOutOfScopeLocations(cx: Context) {
|
||||
return async ({ dispatch, getState }: ThunkArgs) => {
|
||||
return async ({ dispatch, getState, parser }: ThunkArgs) => {
|
||||
const location = getSelectedLocation(getState());
|
||||
if (!location) {
|
||||
return;
|
||||
|
|
|
@ -44,6 +44,7 @@ async function mapLocations(
|
|||
}
|
||||
|
||||
const { sourceId } = generatedLocations[0];
|
||||
|
||||
const originalLocations = await sourceMaps.getOriginalLocations(
|
||||
sourceId,
|
||||
generatedLocations
|
||||
|
|
|
@ -22,7 +22,6 @@ import { wrapExpression } from "../utils/expressions";
|
|||
import { features } from "../utils/prefs";
|
||||
import { isOriginal } from "../utils/source";
|
||||
|
||||
import * as parser from "../workers/parser";
|
||||
import type { Expression, ThreadContext } from "../types";
|
||||
import type { ThunkArgs } from "./types";
|
||||
|
||||
|
@ -35,12 +34,12 @@ import type { ThunkArgs } from "./types";
|
|||
* @static
|
||||
*/
|
||||
export function addExpression(cx: ThreadContext, input: string) {
|
||||
return async ({ dispatch, getState }: ThunkArgs) => {
|
||||
return async ({ dispatch, getState, evaluationsParser }: ThunkArgs) => {
|
||||
if (!input) {
|
||||
return;
|
||||
}
|
||||
|
||||
const expressionError = await parser.hasSyntaxError(input);
|
||||
const expressionError = await evaluationsParser.hasSyntaxError(input);
|
||||
|
||||
const expression = getExpression(getState(), input);
|
||||
if (expression) {
|
||||
|
@ -80,7 +79,7 @@ export function updateExpression(
|
|||
input: string,
|
||||
expression: Expression
|
||||
) {
|
||||
return async ({ dispatch, getState }: ThunkArgs) => {
|
||||
return async ({ dispatch, getState, parser }: ThunkArgs) => {
|
||||
if (!input) {
|
||||
return;
|
||||
}
|
||||
|
@ -177,14 +176,20 @@ function evaluateExpression(cx: ThreadContext, expression: Expression) {
|
|||
* and replaces all posible generated names.
|
||||
*/
|
||||
export function getMappedExpression(expression: string) {
|
||||
return async function({ dispatch, getState, client, sourceMaps }: ThunkArgs) {
|
||||
return async function({
|
||||
dispatch,
|
||||
getState,
|
||||
client,
|
||||
sourceMaps,
|
||||
evaluationsParser
|
||||
}: ThunkArgs) {
|
||||
const thread = getCurrentThread(getState());
|
||||
const mappings = getSelectedScopeMappings(getState(), thread);
|
||||
const bindings = getSelectedFrameBindings(getState(), thread);
|
||||
|
||||
// We bail early if we do not need to map the expression. This is important
|
||||
// because mapping an expression can be slow if the parser worker is
|
||||
// busy doing other work.
|
||||
// because mapping an expression can be slow if the evaluationsParser
|
||||
// worker is busy doing other work.
|
||||
//
|
||||
// 1. there are no mappings - we do not need to map original expressions
|
||||
// 2. does not contain `await` - we do not need to map top level awaits
|
||||
|
@ -194,7 +199,7 @@ export function getMappedExpression(expression: string) {
|
|||
return null;
|
||||
}
|
||||
|
||||
return parser.mapExpression(
|
||||
return evaluationsParser.mapExpression(
|
||||
expression,
|
||||
mappings,
|
||||
bindings || [],
|
||||
|
|
|
@ -12,13 +12,6 @@ import { waitForMs } from "../utils/utils";
|
|||
import { newGeneratedSources } from "./sources";
|
||||
import { updateWorkers } from "./debuggee";
|
||||
|
||||
import {
|
||||
clearASTs,
|
||||
clearSymbols,
|
||||
clearScopes,
|
||||
clearSources
|
||||
} from "../workers/parser";
|
||||
|
||||
import { clearWasmStates } from "../utils/wasm";
|
||||
import { getMainThread } from "../selectors";
|
||||
import type { Action, ThunkArgs } from "./types";
|
||||
|
@ -33,15 +26,18 @@ import type { Action, ThunkArgs } from "./types";
|
|||
* @static
|
||||
*/
|
||||
export function willNavigate(event: Object) {
|
||||
return function({ dispatch, getState, client, sourceMaps }: ThunkArgs) {
|
||||
return async function({
|
||||
dispatch,
|
||||
getState,
|
||||
client,
|
||||
sourceMaps,
|
||||
parser
|
||||
}: ThunkArgs) {
|
||||
sourceQueue.clear();
|
||||
sourceMaps.clearSourceMaps();
|
||||
clearWasmStates();
|
||||
clearDocuments();
|
||||
clearSymbols();
|
||||
clearASTs();
|
||||
clearScopes();
|
||||
clearSources();
|
||||
parser.clear();
|
||||
client.detachWorkers();
|
||||
const thread = getMainThread(getState());
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ import {
|
|||
getThreadContext
|
||||
} from "../../selectors";
|
||||
import { PROMISE } from "../utils/middleware/promise";
|
||||
import { getNextStep } from "../../workers/parser";
|
||||
import { addHiddenBreakpoint } from "../breakpoints";
|
||||
import { evaluateExpressions } from "../expressions";
|
||||
import { selectLocation } from "../sources";
|
||||
|
@ -213,7 +212,7 @@ function hasAwait(content: AsyncValue<SourceContent> | null, pauseLocation) {
|
|||
* @returns {function(ThunkArgs)}
|
||||
*/
|
||||
export function astCommand(cx: ThreadContext, stepType: Command) {
|
||||
return async ({ dispatch, getState, sourceMaps }: ThunkArgs) => {
|
||||
return async ({ dispatch, getState, sourceMaps, parser }: ThunkArgs) => {
|
||||
if (!features.asyncStepping) {
|
||||
return dispatch(command(cx, stepType));
|
||||
}
|
||||
|
@ -225,7 +224,10 @@ export function astCommand(cx: ThreadContext, stepType: Command) {
|
|||
const content = source ? getSourceContent(getState(), source.id) : null;
|
||||
|
||||
if (source && hasAwait(content, frame.location)) {
|
||||
const nextLocation = await getNextStep(source.id, frame.location);
|
||||
const nextLocation = await parser.getNextStep(
|
||||
source.id,
|
||||
frame.location
|
||||
);
|
||||
if (nextLocation) {
|
||||
await dispatch(addHiddenBreakpoint(cx, nextLocation));
|
||||
return dispatch(command(cx, "resume"));
|
||||
|
|
|
@ -55,7 +55,8 @@ export function mapScopes(
|
|||
scopes: Promise<Scope>,
|
||||
frame: Frame
|
||||
) {
|
||||
return async function({ dispatch, getState, client, sourceMaps }: ThunkArgs) {
|
||||
return async function(thunkArgs: ThunkArgs) {
|
||||
const { dispatch, getState } = thunkArgs;
|
||||
assert(cx.thread == frame.thread, "Thread mismatch");
|
||||
|
||||
const generatedSource = getSource(
|
||||
|
@ -99,8 +100,7 @@ export function mapScopes(
|
|||
: { type: "text", value: "", contentType: undefined },
|
||||
frame,
|
||||
await scopes,
|
||||
sourceMaps,
|
||||
client
|
||||
thunkArgs
|
||||
);
|
||||
} catch (e) {
|
||||
log(e);
|
||||
|
|
|
@ -21,7 +21,6 @@ import { prettyPrintSource } from "./prettyPrint";
|
|||
import { setBreakableLines } from "./breakableLines";
|
||||
import { isFulfilled } from "../../utils/async-value";
|
||||
|
||||
import * as parser from "../../workers/parser";
|
||||
import { isOriginal, isPretty } from "../../utils/source";
|
||||
import {
|
||||
memoizeableAction,
|
||||
|
@ -93,7 +92,7 @@ async function loadSource(
|
|||
async function loadSourceTextPromise(
|
||||
cx: Context,
|
||||
source: Source,
|
||||
{ dispatch, getState, client, sourceMaps }: ThunkArgs
|
||||
{ dispatch, getState, client, sourceMaps, parser }: ThunkArgs
|
||||
): Promise<?Source> {
|
||||
const epoch = getSourcesEpoch(getState());
|
||||
await dispatch({
|
||||
|
|
|
@ -10,8 +10,6 @@ import { PROMISE } from "../utils/middleware/promise";
|
|||
import { updateTab } from "../tabs";
|
||||
import { loadSourceText } from "./loadSourceText";
|
||||
|
||||
import * as parser from "../../workers/parser";
|
||||
|
||||
import {
|
||||
memoizeableAction,
|
||||
type MemoizedAction
|
||||
|
@ -20,7 +18,7 @@ import {
|
|||
import type { Source, Context } from "../../types";
|
||||
import type { Symbols } from "../../reducers/types";
|
||||
|
||||
async function doSetSymbols(cx, source, { dispatch, getState }) {
|
||||
async function doSetSymbols(cx, source, { dispatch, getState, parser }) {
|
||||
const sourceId = source.id;
|
||||
|
||||
await dispatch(loadSourceText({ cx, source }));
|
||||
|
|
|
@ -124,6 +124,27 @@ Array [
|
|||
]
|
||||
`;
|
||||
|
||||
exports[`project text search should search a specific source 2`] = `
|
||||
Array [
|
||||
Object {
|
||||
"filepath": "http://localhost:8000/examples/bar",
|
||||
"matches": Array [
|
||||
Object {
|
||||
"column": 9,
|
||||
"line": 1,
|
||||
"match": "bla",
|
||||
"matchIndex": 9,
|
||||
"sourceId": "bar",
|
||||
"type": "MATCH",
|
||||
"value": "function bla(x, y) {",
|
||||
},
|
||||
],
|
||||
"sourceId": "bar",
|
||||
"type": "RESULT",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`project text search should search all the loaded sources based on the query 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
|
|
|
@ -19,6 +19,7 @@ import type { PauseAction } from "./PauseAction";
|
|||
import type { ASTAction } from "./ASTAction";
|
||||
import { clientCommands } from "../../client/firefox";
|
||||
import type { Panel } from "../../client/firefox/types";
|
||||
import type { ParserDispatcher } from "../../workers/parser";
|
||||
|
||||
/**
|
||||
* Flow types
|
||||
|
@ -38,6 +39,8 @@ export type ThunkArgs = {
|
|||
getState: () => State,
|
||||
client: typeof clientCommands,
|
||||
sourceMaps: SourceMaps,
|
||||
parser: ParserDispatcher,
|
||||
evaluationsParser: ParserDispatcher,
|
||||
panel: Panel
|
||||
};
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@ const blacklist = [
|
|||
"REMOVE_BREAKPOINT",
|
||||
"NODE_PROPERTIES_LOADED",
|
||||
"SET_FOCUSED_SOURCE_ITEM",
|
||||
"NODE_EXPAND"
|
||||
"NODE_EXPAND",
|
||||
"IN_SCOPE_LINES"
|
||||
];
|
||||
|
||||
function cloneAction(action: any) {
|
||||
|
|
|
@ -59,7 +59,7 @@ function getClient(connection: any) {
|
|||
|
||||
export async function onConnect(
|
||||
connection: Object,
|
||||
sourceMaps: Object,
|
||||
panelWorkers: Object,
|
||||
panel: Panel
|
||||
) {
|
||||
// NOTE: the landing page does not connect to a JS process
|
||||
|
@ -73,15 +73,15 @@ export async function onConnect(
|
|||
const commands = client.clientCommands;
|
||||
|
||||
const initialState = await loadInitialState();
|
||||
const workers = bootstrapWorkers(panelWorkers);
|
||||
|
||||
const { store, actions, selectors } = bootstrapStore(
|
||||
commands,
|
||||
sourceMaps,
|
||||
workers,
|
||||
panel,
|
||||
initialState
|
||||
);
|
||||
|
||||
const workers = bootstrapWorkers();
|
||||
await client.onConnect(connection, actions);
|
||||
|
||||
await syncBreakpoints();
|
||||
|
@ -90,7 +90,7 @@ export async function onConnect(
|
|||
store,
|
||||
actions,
|
||||
selectors,
|
||||
workers: { ...workers, sourceMaps },
|
||||
workers,
|
||||
connection,
|
||||
client: client.clientCommands
|
||||
});
|
||||
|
|
|
@ -19,7 +19,7 @@ module.exports = {
|
|||
threadClient,
|
||||
tabTarget,
|
||||
debuggerClient,
|
||||
sourceMaps,
|
||||
workers,
|
||||
panel
|
||||
}: any) =>
|
||||
onConnect(
|
||||
|
@ -31,7 +31,7 @@ module.exports = {
|
|||
debuggerClient
|
||||
}
|
||||
},
|
||||
sourceMaps,
|
||||
workers,
|
||||
panel
|
||||
),
|
||||
destroy: () => {
|
||||
|
|
|
@ -23,12 +23,7 @@ import {
|
|||
stop as stopPrettyPrintWorker
|
||||
} from "../workers/pretty-print";
|
||||
|
||||
import {
|
||||
start as startParserWorker,
|
||||
stop as stopParserWorker,
|
||||
clearSymbols,
|
||||
clearASTs
|
||||
} from "../workers/parser";
|
||||
import { ParserDispatcher } from "../workers/parser";
|
||||
import {
|
||||
start as startSearchWorker,
|
||||
stop as stopSearchWorker
|
||||
|
@ -68,6 +63,8 @@ function formatException(reason, p) {
|
|||
console && console.log("Unhandled Rejection at:", p, "reason:", reason);
|
||||
}
|
||||
|
||||
export const parserWorker = new ParserDispatcher();
|
||||
|
||||
beforeAll(() => {
|
||||
startSourceMapWorker(
|
||||
path.join(rootPath, "node_modules/devtools-source-map/src/worker.js"),
|
||||
|
@ -76,7 +73,7 @@ beforeAll(() => {
|
|||
startPrettyPrintWorker(
|
||||
path.join(rootPath, "src/workers/pretty-print/worker.js")
|
||||
);
|
||||
startParserWorker(path.join(rootPath, "src/workers/parser/worker.js"));
|
||||
parserWorker.start(path.join(rootPath, "src/workers/parser/worker.js"));
|
||||
startSearchWorker(path.join(rootPath, "src/workers/search/worker.js"));
|
||||
process.on("unhandledRejection", formatException);
|
||||
});
|
||||
|
@ -84,7 +81,7 @@ beforeAll(() => {
|
|||
afterAll(() => {
|
||||
stopSourceMapWorker();
|
||||
stopPrettyPrintWorker();
|
||||
stopParserWorker();
|
||||
parserWorker.stop();
|
||||
stopSearchWorker();
|
||||
process.removeListener("unhandledRejection", formatException);
|
||||
});
|
||||
|
@ -92,8 +89,7 @@ afterAll(() => {
|
|||
afterEach(() => {});
|
||||
|
||||
beforeEach(async () => {
|
||||
clearASTs();
|
||||
await clearSymbols();
|
||||
parserWorker.clear();
|
||||
clearHistory();
|
||||
clearDocuments();
|
||||
prefs.projectDirectoryRoot = "";
|
||||
|
|
|
@ -16,7 +16,7 @@ import SourceMaps, {
|
|||
} from "devtools-source-map";
|
||||
import * as search from "../workers/search";
|
||||
import * as prettyPrint from "../workers/pretty-print";
|
||||
import * as parser from "../workers/parser";
|
||||
import { ParserDispatcher } from "../workers/parser";
|
||||
|
||||
import configureStore from "../actions/utils/create-store";
|
||||
import reducers from "../reducers";
|
||||
|
@ -26,6 +26,8 @@ import { asyncStore, prefs } from "./prefs";
|
|||
|
||||
import type { Panel } from "../client/firefox/types";
|
||||
|
||||
let parser;
|
||||
|
||||
function renderPanel(component, store) {
|
||||
const root = document.createElement("div");
|
||||
root.className = "launchpad-root theme-body";
|
||||
|
@ -42,9 +44,14 @@ function renderPanel(component, store) {
|
|||
);
|
||||
}
|
||||
|
||||
type Workers = {
|
||||
sourceMaps: typeof SourceMaps,
|
||||
evaluationsParser: typeof ParserDispatcher
|
||||
};
|
||||
|
||||
export function bootstrapStore(
|
||||
client: any,
|
||||
sourceMaps: typeof SourceMaps,
|
||||
workers: Workers,
|
||||
panel: Panel,
|
||||
initialState: Object
|
||||
) {
|
||||
|
@ -52,7 +59,7 @@ export function bootstrapStore(
|
|||
log: prefs.logging || isTesting(),
|
||||
timing: isDevelopment(),
|
||||
makeThunkArgs: (args, state) => {
|
||||
return { ...args, client, sourceMaps, panel };
|
||||
return { ...args, client, ...workers, panel };
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -67,7 +74,7 @@ export function bootstrapStore(
|
|||
return { store, actions, selectors };
|
||||
}
|
||||
|
||||
export function bootstrapWorkers() {
|
||||
export function bootstrapWorkers(panelWorkers: Workers) {
|
||||
const workerPath = isDevelopment()
|
||||
? "assets/build"
|
||||
: "resource://devtools/client/debugger/dist";
|
||||
|
@ -82,9 +89,11 @@ export function bootstrapWorkers() {
|
|||
}
|
||||
|
||||
prettyPrint.start(`${workerPath}/pretty-print-worker.js`);
|
||||
parser = new ParserDispatcher();
|
||||
|
||||
parser.start(`${workerPath}/parser-worker.js`);
|
||||
search.start(`${workerPath}/search-worker.js`);
|
||||
return { prettyPrint, parser, search };
|
||||
return { ...panelWorkers, prettyPrint, parser, search };
|
||||
}
|
||||
|
||||
export function teardownWorkers() {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
import typeof SourceMaps from "devtools-source-map";
|
||||
|
||||
import {
|
||||
getScopes,
|
||||
type SourceScope,
|
||||
type BindingData,
|
||||
type BindingLocation
|
||||
|
@ -37,6 +36,8 @@ import {
|
|||
} from "./getApplicableBindingsForOriginalPosition";
|
||||
|
||||
import { log } from "../../log";
|
||||
import type { ThunkArgs } from "../../../actions/types";
|
||||
|
||||
import type {
|
||||
PartialPosition,
|
||||
Frame,
|
||||
|
@ -54,16 +55,15 @@ export async function buildMappedScopes(
|
|||
content: SourceContent,
|
||||
frame: Frame,
|
||||
scopes: Scope,
|
||||
sourceMaps: any,
|
||||
client: any
|
||||
{ client, parser, sourceMaps }: ThunkArgs
|
||||
): Promise<?{
|
||||
mappings: {
|
||||
[string]: string
|
||||
},
|
||||
scope: OriginalScope
|
||||
}> {
|
||||
const originalAstScopes = await getScopes(frame.location);
|
||||
const generatedAstScopes = await getScopes(frame.generatedLocation);
|
||||
const originalAstScopes = await parser.getScopes(frame.location);
|
||||
const generatedAstScopes = await parser.getScopes(frame.generatedLocation);
|
||||
|
||||
if (!originalAstScopes || !generatedAstScopes) {
|
||||
return null;
|
||||
|
|
|
@ -15,6 +15,7 @@ import reducers from "../reducers";
|
|||
import actions from "../actions";
|
||||
import * as selectors from "../selectors";
|
||||
import { getHistory } from "../test/utils/history";
|
||||
import { parserWorker } from "../test/tests-setup";
|
||||
import configureStore from "../actions/utils/create-store";
|
||||
import sourceQueue from "../utils/source-queue";
|
||||
import type { Source, OriginalSourceData, GeneratedSourceData } from "../types";
|
||||
|
@ -41,7 +42,8 @@ function createStore(client: any, initialState: any = {}, sourceMapsMock: any) {
|
|||
return {
|
||||
...args,
|
||||
client,
|
||||
sourceMaps: sourceMapsMock !== undefined ? sourceMapsMock : sourceMaps
|
||||
sourceMaps: sourceMapsMock !== undefined ? sourceMapsMock : sourceMaps,
|
||||
parser: parserWorker
|
||||
};
|
||||
}
|
||||
})(combineReducers(reducers), initialState);
|
||||
|
|
|
@ -12,77 +12,71 @@ import type { SourceLocation, SourceId, SourceContent } from "../../types";
|
|||
import type { SourceScope } from "./getScopes/visitor";
|
||||
import type { SymbolDeclarations } from "./getSymbols";
|
||||
|
||||
const dispatcher = new WorkerDispatcher();
|
||||
export const start = (url: string, win: any = window) =>
|
||||
dispatcher.start(url, win);
|
||||
export const stop = () => dispatcher.stop();
|
||||
export class ParserDispatcher extends WorkerDispatcher {
|
||||
async findOutOfScopeLocations(
|
||||
sourceId: string,
|
||||
position: AstPosition
|
||||
): Promise<AstLocation[]> {
|
||||
return this.invoke("findOutOfScopeLocations", sourceId, position);
|
||||
}
|
||||
|
||||
export const findOutOfScopeLocations = async (
|
||||
sourceId: string,
|
||||
position: AstPosition
|
||||
): Promise<AstLocation[]> =>
|
||||
dispatcher.invoke("findOutOfScopeLocations", sourceId, position);
|
||||
async getNextStep(
|
||||
sourceId: SourceId,
|
||||
pausedPosition: AstPosition
|
||||
): Promise<?SourceLocation> {
|
||||
return this.invoke("getNextStep", sourceId, pausedPosition);
|
||||
}
|
||||
|
||||
export const getNextStep = async (
|
||||
sourceId: SourceId,
|
||||
pausedPosition: AstPosition
|
||||
): Promise<?SourceLocation> =>
|
||||
dispatcher.invoke("getNextStep", sourceId, pausedPosition);
|
||||
async clearState(): Promise<void> {
|
||||
return this.invoke("clearState");
|
||||
}
|
||||
|
||||
export const clearASTs = async (): Promise<void> =>
|
||||
dispatcher.invoke("clearASTs");
|
||||
async getScopes(location: SourceLocation): Promise<SourceScope[]> {
|
||||
return this.invoke("getScopes", location);
|
||||
}
|
||||
|
||||
export const getScopes = async (
|
||||
location: SourceLocation
|
||||
): Promise<SourceScope[]> => dispatcher.invoke("getScopes", location);
|
||||
async getSymbols(sourceId: string): Promise<SymbolDeclarations> {
|
||||
return this.invoke("getSymbols", sourceId);
|
||||
}
|
||||
|
||||
export const clearScopes = async (): Promise<void> =>
|
||||
dispatcher.invoke("clearScopes");
|
||||
async setSource(sourceId: SourceId, content: SourceContent): Promise<void> {
|
||||
const astSource: AstSource = {
|
||||
id: sourceId,
|
||||
text: content.type === "wasm" ? "" : content.value,
|
||||
contentType: content.contentType || null,
|
||||
isWasm: content.type === "wasm"
|
||||
};
|
||||
|
||||
export const clearSymbols = async (): Promise<void> =>
|
||||
dispatcher.invoke("clearSymbols");
|
||||
return this.invoke("setSource", astSource);
|
||||
}
|
||||
|
||||
export const getSymbols = async (
|
||||
sourceId: string
|
||||
): Promise<SymbolDeclarations> => dispatcher.invoke("getSymbols", sourceId);
|
||||
async hasSyntaxError(input: string): Promise<string | false> {
|
||||
return this.invoke("hasSyntaxError", input);
|
||||
}
|
||||
|
||||
export const setSource = async (
|
||||
sourceId: SourceId,
|
||||
content: SourceContent
|
||||
): Promise<void> => {
|
||||
const astSource: AstSource = {
|
||||
id: sourceId,
|
||||
text: content.type === "wasm" ? "" : content.value,
|
||||
contentType: content.contentType || null,
|
||||
isWasm: content.type === "wasm"
|
||||
};
|
||||
async mapExpression(
|
||||
expression: string,
|
||||
mappings: {
|
||||
[string]: string | null
|
||||
} | null,
|
||||
bindings: string[],
|
||||
shouldMapBindings?: boolean,
|
||||
shouldMapAwait?: boolean
|
||||
): Promise<{ expression: string }> {
|
||||
return this.invoke(
|
||||
"mapExpression",
|
||||
expression,
|
||||
mappings,
|
||||
bindings,
|
||||
shouldMapBindings,
|
||||
shouldMapAwait
|
||||
);
|
||||
}
|
||||
|
||||
await dispatcher.invoke("setSource", astSource);
|
||||
};
|
||||
|
||||
export const clearSources = async (): Promise<void> =>
|
||||
dispatcher.invoke("clearSources");
|
||||
|
||||
export const hasSyntaxError = async (input: string): Promise<string | false> =>
|
||||
dispatcher.invoke("hasSyntaxError", input);
|
||||
|
||||
export const mapExpression = async (
|
||||
expression: string,
|
||||
mappings: {
|
||||
[string]: string | null
|
||||
} | null,
|
||||
bindings: string[],
|
||||
shouldMapBindings?: boolean,
|
||||
shouldMapAwait?: boolean
|
||||
): Promise<{ expression: string }> =>
|
||||
dispatcher.invoke(
|
||||
"mapExpression",
|
||||
expression,
|
||||
mappings,
|
||||
bindings,
|
||||
shouldMapBindings,
|
||||
shouldMapAwait
|
||||
);
|
||||
async clear() {
|
||||
await this.clearState();
|
||||
}
|
||||
}
|
||||
|
||||
export type {
|
||||
SourceScope,
|
||||
|
|
|
@ -16,16 +16,20 @@ import mapExpression from "./mapExpression";
|
|||
import { workerUtils } from "devtools-utils";
|
||||
const { workerHandler } = workerUtils;
|
||||
|
||||
function clearState() {
|
||||
clearASTs();
|
||||
clearScopes();
|
||||
clearSources();
|
||||
clearSymbols();
|
||||
}
|
||||
|
||||
self.onmessage = workerHandler({
|
||||
findOutOfScopeLocations,
|
||||
getSymbols,
|
||||
getScopes,
|
||||
clearSymbols,
|
||||
clearScopes,
|
||||
clearASTs,
|
||||
setSource,
|
||||
clearSources,
|
||||
clearState,
|
||||
getNextStep,
|
||||
hasSyntaxError,
|
||||
mapExpression
|
||||
mapExpression,
|
||||
setSource
|
||||
});
|
||||
|
|
|
@ -1060,8 +1060,8 @@ const keyMappings = {
|
|||
fileSearchPrev: { code: "g", modifiers: cmdShift },
|
||||
Enter: { code: "VK_RETURN" },
|
||||
ShiftEnter: { code: "VK_RETURN", modifiers: shiftOrAlt },
|
||||
AltEnter: {
|
||||
code: "VK_RETURN",
|
||||
AltEnter: {
|
||||
code: "VK_RETURN",
|
||||
modifiers: { altKey: true }
|
||||
},
|
||||
Up: { code: "VK_UP" },
|
||||
|
|
|
@ -937,6 +937,24 @@ Toolbox.prototype = {
|
|||
return this._createSourceMapService();
|
||||
},
|
||||
|
||||
/**
|
||||
* A common access point for the client-side parser service that any panel can use.
|
||||
*/
|
||||
get parserService() {
|
||||
if (this._parserService) {
|
||||
return this._parserService;
|
||||
}
|
||||
|
||||
const { ParserDispatcher } =
|
||||
require("devtools/client/debugger/src/workers/parser/index");
|
||||
|
||||
this._parserService = new ParserDispatcher();
|
||||
this._parserService.start(
|
||||
"resource://devtools/client/debugger/dist/parser-worker.js",
|
||||
this.win);
|
||||
return this._parserService;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clients wishing to use source maps but that want the toolbox to
|
||||
* track the source and style sheet actor mapping can use this
|
||||
|
@ -3074,11 +3092,17 @@ Toolbox.prototype = {
|
|||
this._sourceMapURLService.destroy();
|
||||
this._sourceMapURLService = null;
|
||||
}
|
||||
|
||||
if (this._sourceMapService) {
|
||||
this._sourceMapService.stopSourceMapWorker();
|
||||
this._sourceMapService = null;
|
||||
}
|
||||
|
||||
if (this._parserService) {
|
||||
this._parserService.stop();
|
||||
this._parserService = null;
|
||||
}
|
||||
|
||||
if (this.webconsolePanel) {
|
||||
this._saveSplitConsoleHeight();
|
||||
this.webconsolePanel.removeEventListener("resize",
|
||||
|
|
|
@ -301,17 +301,15 @@ class WebConsole {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A common access point for the client-side parser service that any panel can use.
|
||||
*/
|
||||
get parserService() {
|
||||
if (this._parserService) {
|
||||
return this._parserService;
|
||||
}
|
||||
|
||||
this._parserService =
|
||||
const { ParserDispatcher } =
|
||||
require("devtools/client/debugger/src/workers/parser/index");
|
||||
|
||||
this._parserService = new ParserDispatcher();
|
||||
this._parserService.start(
|
||||
"resource://devtools/client/debugger/dist/parser-worker.js",
|
||||
this.chromeUtilsWindow);
|
||||
|
|
|
@ -293,6 +293,8 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
|
|||
"bottom",
|
||||
"column-gap",
|
||||
"column-width",
|
||||
"cx",
|
||||
"cy",
|
||||
"flex-basis",
|
||||
"height",
|
||||
"left",
|
||||
|
@ -315,6 +317,9 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
|
|||
"padding-right",
|
||||
"padding-top",
|
||||
"perspective",
|
||||
"r",
|
||||
"rx",
|
||||
"ry",
|
||||
"right",
|
||||
"row-gap",
|
||||
"scroll-padding-block-start",
|
||||
|
@ -342,6 +347,8 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
|
|||
"vertical-align",
|
||||
"width",
|
||||
"word-spacing",
|
||||
"x",
|
||||
"y",
|
||||
"z-index",
|
||||
])],
|
||||
["float", new Set([
|
||||
|
|
|
@ -3315,6 +3315,13 @@ exports.CSS_PROPERTIES = {
|
|||
"mask-size",
|
||||
"mask-composite",
|
||||
"mask-image",
|
||||
"x",
|
||||
"y",
|
||||
"cx",
|
||||
"cy",
|
||||
"rx",
|
||||
"ry",
|
||||
"r",
|
||||
"-moz-box-align",
|
||||
"-moz-box-direction",
|
||||
"-moz-box-flex",
|
||||
|
@ -5832,6 +5839,32 @@ exports.CSS_PROPERTIES = {
|
|||
"zoom-out"
|
||||
]
|
||||
},
|
||||
"cx": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"cx"
|
||||
],
|
||||
"supports": [],
|
||||
"values": [
|
||||
"inherit",
|
||||
"initial",
|
||||
"revert",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
"cy": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"cy"
|
||||
],
|
||||
"supports": [],
|
||||
"values": [
|
||||
"inherit",
|
||||
"initial",
|
||||
"revert",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
"direction": {
|
||||
"isInherited": true,
|
||||
"subproperties": [
|
||||
|
@ -8915,6 +8948,19 @@ exports.CSS_PROPERTIES = {
|
|||
"unset"
|
||||
]
|
||||
},
|
||||
"r": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"r"
|
||||
],
|
||||
"supports": [],
|
||||
"values": [
|
||||
"inherit",
|
||||
"initial",
|
||||
"revert",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
"resize": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
|
@ -8994,6 +9040,34 @@ exports.CSS_PROPERTIES = {
|
|||
"unset"
|
||||
]
|
||||
},
|
||||
"rx": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"rx"
|
||||
],
|
||||
"supports": [],
|
||||
"values": [
|
||||
"auto",
|
||||
"inherit",
|
||||
"initial",
|
||||
"revert",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
"ry": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"ry"
|
||||
],
|
||||
"supports": [],
|
||||
"values": [
|
||||
"auto",
|
||||
"inherit",
|
||||
"initial",
|
||||
"revert",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
"scroll-behavior": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
|
@ -10444,6 +10518,32 @@ exports.CSS_PROPERTIES = {
|
|||
"vertical-rl"
|
||||
]
|
||||
},
|
||||
"x": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"x"
|
||||
],
|
||||
"supports": [],
|
||||
"values": [
|
||||
"inherit",
|
||||
"initial",
|
||||
"revert",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"y"
|
||||
],
|
||||
"supports": [],
|
||||
"values": [
|
||||
"inherit",
|
||||
"initial",
|
||||
"revert",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
"z-index": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
|
@ -10596,38 +10696,6 @@ exports.PREFERENCES = [
|
|||
"-moz-binding",
|
||||
"layout.css.moz-binding.content.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-block-end",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-block-start",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-bottom",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-inline-end",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-inline-start",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-left",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-right",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-top",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-margin-block-end",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
|
@ -10660,6 +10728,38 @@ exports.PREFERENCES = [
|
|||
"scroll-margin-top",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-block-end",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-block-start",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-bottom",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-inline-end",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-inline-start",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-left",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-right",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-padding-top",
|
||||
"layout.css.scroll-snap-v1.enabled"
|
||||
],
|
||||
[
|
||||
"-webkit-text-stroke-width",
|
||||
"layout.css.prefixes.webkit"
|
||||
|
|
|
@ -873,11 +873,9 @@ nsDocShellTreeOwner::HandleEvent(Event* aEvent) {
|
|||
} else if (eventType.EqualsLiteral("drop")) {
|
||||
nsIWebNavigation* webnav = static_cast<nsIWebNavigation*>(mWebBrowser);
|
||||
|
||||
uint32_t linksCount;
|
||||
nsIDroppedLinkItem** links;
|
||||
if (webnav && NS_SUCCEEDED(handler->DropLinks(dragEvent, true, &linksCount,
|
||||
&links))) {
|
||||
if (linksCount >= 1) {
|
||||
nsTArray<RefPtr<nsIDroppedLinkItem>> links;
|
||||
if (webnav && NS_SUCCEEDED(handler->DropLinks(dragEvent, true, links))) {
|
||||
if (links.Length() >= 1) {
|
||||
nsCOMPtr<nsIPrincipal> triggeringPrincipal;
|
||||
handler->GetTriggeringPrincipal(dragEvent,
|
||||
getter_AddRefs(triggeringPrincipal));
|
||||
|
@ -888,11 +886,7 @@ nsDocShellTreeOwner::HandleEvent(Event* aEvent) {
|
|||
nsCOMPtr<nsIBrowserChild> browserChild =
|
||||
do_QueryInterface(webBrowserChrome);
|
||||
if (browserChild) {
|
||||
nsresult rv = browserChild->RemoteDropLinks(linksCount, links);
|
||||
for (uint32_t i = 0; i < linksCount; i++) {
|
||||
NS_RELEASE(links[i]);
|
||||
}
|
||||
free(links);
|
||||
nsresult rv = browserChild->RemoteDropLinks(links);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
@ -912,11 +906,6 @@ nsDocShellTreeOwner::HandleEvent(Event* aEvent) {
|
|||
webnav->LoadURI(url, loadURIOptions);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < linksCount; i++) {
|
||||
NS_RELEASE(links[i]);
|
||||
}
|
||||
free(links);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -276,7 +276,7 @@ ContentAreaDropListener.prototype =
|
|||
return url;
|
||||
},
|
||||
|
||||
dropLinks: function(aEvent, aDisallowInherit, aCount)
|
||||
dropLinks: function(aEvent, aDisallowInherit)
|
||||
{
|
||||
if (aEvent && this._eventTargetIsDisabled(aEvent))
|
||||
return [];
|
||||
|
@ -297,13 +297,11 @@ ContentAreaDropListener.prototype =
|
|||
throw ex;
|
||||
}
|
||||
}
|
||||
if (aCount)
|
||||
aCount.value = links.length;
|
||||
|
||||
return links;
|
||||
},
|
||||
|
||||
validateURIsForDrop: function(aEvent, aURIsCount, aURIs, aDisallowInherit)
|
||||
validateURIsForDrop: function(aEvent, aURIs, aDisallowInherit)
|
||||
{
|
||||
let dataTransfer = aEvent.dataTransfer;
|
||||
let triggeringPrincipal = this._getTriggeringPrincipalFromDataTransfer(dataTransfer, false);
|
||||
|
@ -314,13 +312,9 @@ ContentAreaDropListener.prototype =
|
|||
}
|
||||
},
|
||||
|
||||
queryLinks: function(aDataTransfer, aCount)
|
||||
queryLinks: function(aDataTransfer)
|
||||
{
|
||||
let links = this._getDropLinks(aDataTransfer);
|
||||
if (aCount) {
|
||||
aCount.value = links.length;
|
||||
}
|
||||
return links;
|
||||
return this._getDropLinks(aDataTransfer);
|
||||
},
|
||||
|
||||
_eventTargetIsDisabled: function(aEvent)
|
||||
|
|
|
@ -293,6 +293,7 @@ void DOMIntersectionObserver::Update(Document* aDocument,
|
|||
for (size_t i = 0; i < mObservationTargets.Length(); ++i) {
|
||||
Element* target = mObservationTargets.ElementAt(i);
|
||||
nsIFrame* targetFrame = target->GetPrimaryFrame();
|
||||
nsIFrame* originalTargetFrame = targetFrame;
|
||||
nsRect targetRect;
|
||||
Maybe<nsRect> intersectionRect;
|
||||
bool isSameDoc = root && root->GetComposedDoc() == target->GetComposedDoc();
|
||||
|
@ -374,7 +375,7 @@ void DOMIntersectionObserver::Update(Document* aDocument,
|
|||
intersectionRectRelativeToRoot, rootIntersectionRect);
|
||||
if (intersectionRect.isSome() && !isSameDoc) {
|
||||
nsRect rect = intersectionRect.value();
|
||||
nsPresContext* presContext = targetFrame->PresContext();
|
||||
nsPresContext* presContext = originalTargetFrame->PresContext();
|
||||
nsIFrame* rootScrollFrame =
|
||||
presContext->PresShell()->GetRootScrollFrame();
|
||||
if (rootScrollFrame) {
|
||||
|
|
|
@ -65,7 +65,7 @@ interface nsIDroppedLinkHandler : nsISupports
|
|||
/**
|
||||
* Given a drop event aEvent, determines links being dragged and returns
|
||||
* them. If links are returned the caller can, for instance, load them. If
|
||||
* the count of links is 0, there is no valid link to be dropped.
|
||||
* the returned array is empty, there is no valid link to be dropped.
|
||||
*
|
||||
* A NS_ERROR_DOM_SECURITY_ERR error will be thrown and the event cancelled if
|
||||
* the receiving target should not load the uri for security reasons. This
|
||||
|
@ -76,10 +76,8 @@ interface nsIDroppedLinkHandler : nsISupports
|
|||
* - aDisallowInherit is true, and the URI being dropped would inherit the
|
||||
* current document's security context (URI_INHERITS_SECURITY_CONTEXT).
|
||||
*/
|
||||
void dropLinks(in DragEvent aEvent,
|
||||
[optional] in boolean aDisallowInherit,
|
||||
[optional] out unsigned long aCount,
|
||||
[retval, array, size_is(aCount)] out nsIDroppedLinkItem aLinks);
|
||||
Array<nsIDroppedLinkItem> dropLinks(in DragEvent aEvent,
|
||||
[optional] in boolean aDisallowInherit);
|
||||
|
||||
/**
|
||||
* Given a drop event aEvent, validate the extra URIs for the event,
|
||||
|
@ -87,8 +85,7 @@ interface nsIDroppedLinkHandler : nsISupports
|
|||
* text, like home button that splits the text with "|".
|
||||
*/
|
||||
void validateURIsForDrop(in DragEvent aEvent,
|
||||
in unsigned long aURIsCount,
|
||||
[array, size_is(aURIsCount)] in wstring aURIs,
|
||||
in Array<AString> aURIs,
|
||||
[optional] in boolean aDisallowInherit);
|
||||
|
||||
/**
|
||||
|
@ -97,9 +94,7 @@ interface nsIDroppedLinkHandler : nsISupports
|
|||
* it allows the parent to verify that the child did not modify links
|
||||
* being dropped.
|
||||
*/
|
||||
void queryLinks(in DataTransfer aDataTransfer,
|
||||
[optional] out unsigned long aCount,
|
||||
[retval, array, size_is(aCount)] out nsIDroppedLinkItem aLinks);
|
||||
Array<nsIDroppedLinkItem> queryLinks(in DataTransfer aDataTransfer);
|
||||
|
||||
/**
|
||||
* Given a drop event aEvent, determines the triggering principal for the
|
||||
|
|
|
@ -45,7 +45,8 @@ function handleEventMessage(event) {
|
|||
window.addEventListener("message", handleEventMessage);
|
||||
SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]]},
|
||||
["security.webauth.webauthn_enable_usbtoken", false],
|
||||
["security.webauth.webauthn_enable_android_fido2", false]]},
|
||||
function() {
|
||||
document.getElementById("frame_top").src = "https://example.com/tests/dom/credentialmanagement/tests/mochitest/frame_credman_iframes.html";
|
||||
|
||||
|
|
|
@ -25,14 +25,12 @@ interface nsIBrowser : nsISupports
|
|||
* Called by the child to inform the parent that links are dropped into
|
||||
* content area.
|
||||
*
|
||||
* @param linksCount length of links
|
||||
* @param links a flat array of url, name, and type for each link
|
||||
* @param triggeringPrincipal a principal that initiated loading
|
||||
* of the dropped links
|
||||
*/
|
||||
void dropLinks(in unsigned long linksCount,
|
||||
[array, size_is(linksCount)] in wstring links,
|
||||
in nsIPrincipal aTriggeringPrincipal);
|
||||
void dropLinks(in Array<AString> links,
|
||||
in nsIPrincipal triggeringPrincipal);
|
||||
|
||||
/**
|
||||
* Swapping of frameloaders are usually initiated from a frameloader owner
|
||||
|
@ -73,16 +71,12 @@ interface nsIBrowser : nsISupports
|
|||
* and the supplied set of commands are now enabled and disabled.
|
||||
*
|
||||
* @param action command updater action
|
||||
* @param enabledLength length of enabledCommands array
|
||||
* @param enabledCommands commands to enable
|
||||
* @param disabledLength length of disabledCommands array
|
||||
* @param disabledCommand commands to disable
|
||||
*/
|
||||
void enableDisableCommandsRemoteOnly(in AString action,
|
||||
in unsigned long enabledLength,
|
||||
[array, size_is(enabledLength)] in string enabledCommands,
|
||||
in unsigned long disabledLength,
|
||||
[array, size_is(disabledLength)] in string disabledCommands);
|
||||
in Array<ACString> enabledCommands,
|
||||
in Array<ACString> disabledCommands);
|
||||
|
||||
readonly attribute nsIPrincipal contentPrincipal;
|
||||
readonly attribute nsIContentSecurityPolicy csp;
|
||||
|
|
|
@ -29,8 +29,7 @@ interface nsIBrowserChild : nsISupports
|
|||
[noscript] void remoteSizeShellTo(in int32_t width, in int32_t height,
|
||||
in int32_t shellItemWidth, in int32_t shellItemHeight);
|
||||
|
||||
[noscript] void remoteDropLinks(in unsigned long linksCount,
|
||||
[array, size_is(linksCount)] in nsIDroppedLinkItem links);
|
||||
void remoteDropLinks(in Array<nsIDroppedLinkItem> links);
|
||||
|
||||
readonly attribute uint64_t tabId;
|
||||
|
||||
|
|
|
@ -735,25 +735,25 @@ BrowserChild::RemoteSizeShellTo(int32_t aWidth, int32_t aHeight,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BrowserChild::RemoteDropLinks(uint32_t aLinksCount,
|
||||
nsIDroppedLinkItem** aLinks) {
|
||||
BrowserChild::RemoteDropLinks(
|
||||
const nsTArray<RefPtr<nsIDroppedLinkItem>>& aLinks) {
|
||||
nsTArray<nsString> linksArray;
|
||||
nsresult rv = NS_OK;
|
||||
for (uint32_t i = 0; i < aLinksCount; i++) {
|
||||
for (nsIDroppedLinkItem* link : aLinks) {
|
||||
nsString tmp;
|
||||
rv = aLinks[i]->GetUrl(tmp);
|
||||
rv = link->GetUrl(tmp);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
linksArray.AppendElement(tmp);
|
||||
|
||||
rv = aLinks[i]->GetName(tmp);
|
||||
rv = link->GetName(tmp);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
linksArray.AppendElement(tmp);
|
||||
|
||||
rv = aLinks[i]->GetType(tmp);
|
||||
rv = link->GetType(tmp);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -1816,7 +1816,8 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealTouchEvent(
|
|||
}
|
||||
UniquePtr<DisplayportSetListener> postLayerization =
|
||||
APZCCallbackHelper::SendSetTargetAPZCNotification(
|
||||
mPuppetWidget, document, localEvent, aGuid.mLayersId, aInputBlockId);
|
||||
mPuppetWidget, document, localEvent, aGuid.mLayersId,
|
||||
aInputBlockId);
|
||||
if (postLayerization && postLayerization->Register()) {
|
||||
Unused << postLayerization.release();
|
||||
}
|
||||
|
|
|
@ -809,15 +809,12 @@ mozilla::ipc::IPCResult BrowserParent::RecvDropLinks(
|
|||
if (aLinks.Length() != mVerifyDropLinks.Length()) {
|
||||
loadUsingSystemPrincipal = false;
|
||||
}
|
||||
UniquePtr<const char16_t*[]> links;
|
||||
links = MakeUnique<const char16_t*[]>(aLinks.Length());
|
||||
for (uint32_t i = 0; i < aLinks.Length(); i++) {
|
||||
if (loadUsingSystemPrincipal) {
|
||||
if (!aLinks[i].Equals(mVerifyDropLinks[i])) {
|
||||
loadUsingSystemPrincipal = false;
|
||||
}
|
||||
}
|
||||
links[i] = aLinks[i].get();
|
||||
}
|
||||
mVerifyDropLinks.Clear();
|
||||
nsCOMPtr<nsIPrincipal> triggeringPrincipal;
|
||||
|
@ -826,7 +823,7 @@ mozilla::ipc::IPCResult BrowserParent::RecvDropLinks(
|
|||
} else {
|
||||
triggeringPrincipal = NullPrincipal::CreateWithoutOriginAttributes();
|
||||
}
|
||||
browser->DropLinks(aLinks.Length(), links.get(), triggeringPrincipal);
|
||||
browser->DropLinks(aLinks, triggeringPrincipal);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -1394,42 +1391,36 @@ bool BrowserParent::QueryDropLinksForVerification() {
|
|||
// verification array and store all links that are being dragged.
|
||||
mVerifyDropLinks.Clear();
|
||||
|
||||
uint32_t linksCount = 0;
|
||||
nsIDroppedLinkItem** droppedLinkedItems = nullptr;
|
||||
dropHandler->QueryLinks(initialDataTransfer, &linksCount,
|
||||
&droppedLinkedItems);
|
||||
nsTArray<RefPtr<nsIDroppedLinkItem>> droppedLinkItems;
|
||||
dropHandler->QueryLinks(initialDataTransfer, droppedLinkItems);
|
||||
|
||||
// Since the entire event is cancelled if one of the links is invalid,
|
||||
// we can store all links on the parent side without any prior
|
||||
// validation checks.
|
||||
nsresult rv = NS_OK;
|
||||
for (uint32_t i = 0; i < linksCount; i++) {
|
||||
for (nsIDroppedLinkItem* item : droppedLinkItems) {
|
||||
nsString tmp;
|
||||
rv = droppedLinkedItems[i]->GetUrl(tmp);
|
||||
rv = item->GetUrl(tmp);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to query url for verification");
|
||||
break;
|
||||
}
|
||||
mVerifyDropLinks.AppendElement(tmp);
|
||||
|
||||
rv = droppedLinkedItems[i]->GetName(tmp);
|
||||
rv = item->GetName(tmp);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to query name for verification");
|
||||
break;
|
||||
}
|
||||
mVerifyDropLinks.AppendElement(tmp);
|
||||
|
||||
rv = droppedLinkedItems[i]->GetType(tmp);
|
||||
rv = item->GetType(tmp);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to query type for verification");
|
||||
break;
|
||||
}
|
||||
mVerifyDropLinks.AppendElement(tmp);
|
||||
}
|
||||
for (uint32_t i = 0; i < linksCount; i++) {
|
||||
NS_IF_RELEASE(droppedLinkedItems[i]);
|
||||
}
|
||||
free(droppedLinkedItems);
|
||||
if (NS_FAILED(rv)) {
|
||||
mVerifyDropLinks.Clear();
|
||||
return false;
|
||||
|
@ -2163,25 +2154,8 @@ mozilla::ipc::IPCResult BrowserParent::RecvEnableDisableCommands(
|
|||
browser->GetIsRemoteBrowser(&isRemoteBrowser);
|
||||
}
|
||||
if (isRemoteBrowser) {
|
||||
UniquePtr<const char*[]> enabledCommands, disabledCommands;
|
||||
|
||||
if (aEnabledCommands.Length()) {
|
||||
enabledCommands = MakeUnique<const char*[]>(aEnabledCommands.Length());
|
||||
for (uint32_t c = 0; c < aEnabledCommands.Length(); c++) {
|
||||
enabledCommands[c] = aEnabledCommands[c].get();
|
||||
}
|
||||
}
|
||||
|
||||
if (aDisabledCommands.Length()) {
|
||||
disabledCommands = MakeUnique<const char*[]>(aDisabledCommands.Length());
|
||||
for (uint32_t c = 0; c < aDisabledCommands.Length(); c++) {
|
||||
disabledCommands[c] = aDisabledCommands[c].get();
|
||||
}
|
||||
}
|
||||
|
||||
browser->EnableDisableCommandsRemoteOnly(
|
||||
aAction, aEnabledCommands.Length(), enabledCommands.get(),
|
||||
aDisabledCommands.Length(), disabledCommands.get());
|
||||
browser->EnableDisableCommandsRemoteOnly(aAction, aEnabledCommands,
|
||||
aDisabledCommands);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "SMILCompositor.h"
|
||||
|
||||
#include "mozilla/dom/SVGSVGElement.h"
|
||||
#include "nsComputedDOMStyle.h"
|
||||
#include "nsCSSProps.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
@ -147,19 +148,21 @@ nsCSSPropertyID SMILCompositor::GetCSSPropertyToAnimate() const {
|
|||
|
||||
// If we are animating the 'width' or 'height' of an outer SVG
|
||||
// element we should animate it as a CSS property, but for other elements
|
||||
// (e.g. <rect>) we should animate it as a length attribute.
|
||||
// The easiest way to test for an outer SVG element, is to see if it is an
|
||||
// SVG-namespace element mapping its width/height attribute to style.
|
||||
//
|
||||
// If we have animation of 'width' or 'height' on an SVG element that is
|
||||
// NOT mapping that attributes to style then it must not be an outermost SVG
|
||||
// element so we should return eCSSProperty_UNKNOWN to indicate that we
|
||||
// should animate as an attribute instead.
|
||||
// in SVG namespace (e.g. <rect>) we should animate it as a length attribute.
|
||||
if ((mKey.mAttributeName == nsGkAtoms::width ||
|
||||
mKey.mAttributeName == nsGkAtoms::height) &&
|
||||
mKey.mElement->GetNameSpaceID() == kNameSpaceID_SVG &&
|
||||
!mKey.mElement->IsAttributeMapped(mKey.mAttributeName)) {
|
||||
return eCSSProperty_UNKNOWN;
|
||||
mKey.mElement->GetNameSpaceID() == kNameSpaceID_SVG) {
|
||||
// Not an <svg> element.
|
||||
if (!mKey.mElement->IsSVGElement(nsGkAtoms::svg)) {
|
||||
return eCSSProperty_UNKNOWN;
|
||||
}
|
||||
|
||||
// An inner <svg> element
|
||||
if (static_cast<dom::SVGSVGElement const&>(*mKey.mElement).IsInner()) {
|
||||
return eCSSProperty_UNKNOWN;
|
||||
}
|
||||
|
||||
// Indeed an outer <svg> element, fall through.
|
||||
}
|
||||
|
||||
return propID;
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
* 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 "ComputedStyle.h"
|
||||
#include "mozilla/dom/SVGCircleElement.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "mozilla/dom/SVGCircleElementBinding.h"
|
||||
#include "mozilla/dom/SVGLengthBinding.h"
|
||||
#include "SVGGeometryProperty.h"
|
||||
|
||||
NS_IMPL_NS_NEW_SVG_ELEMENT(Circle)
|
||||
|
||||
|
@ -37,6 +39,13 @@ SVGCircleElement::SVGCircleElement(
|
|||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
||||
: SVGCircleElementBase(std::move(aNodeInfo)) {}
|
||||
|
||||
bool SVGCircleElement::IsAttributeMapped(const nsAtom* aAttribute) const {
|
||||
return IsInLengthInfo(aAttribute, sLengthInfo) ||
|
||||
SVGCircleElementBase::IsAttributeMapped(aAttribute);
|
||||
}
|
||||
|
||||
namespace SVGT = SVGGeometryProperty::Tags;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsINode methods
|
||||
|
||||
|
@ -61,8 +70,11 @@ already_AddRefed<DOMSVGAnimatedLength> SVGCircleElement::R() {
|
|||
|
||||
/* virtual */
|
||||
bool SVGCircleElement::HasValidDimensions() const {
|
||||
return mLengthAttributes[ATTR_R].IsExplicitlySet() &&
|
||||
mLengthAttributes[ATTR_R].GetAnimValInSpecifiedUnits() > 0;
|
||||
float r;
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::R>(this, &r);
|
||||
return r > 0;
|
||||
}
|
||||
|
||||
SVGElement::LengthAttributesInfo SVGCircleElement::GetLengthInfo() {
|
||||
|
@ -77,7 +89,10 @@ bool SVGCircleElement::GetGeometryBounds(
|
|||
Rect* aBounds, const StrokeOptions& aStrokeOptions,
|
||||
const Matrix& aToBoundsSpace, const Matrix* aToNonScalingStrokeSpace) {
|
||||
float x, y, r;
|
||||
GetAnimatedLengthValues(&x, &y, &r, nullptr);
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::Cx, SVGT::Cy, SVGT::R>(this, &x, &y,
|
||||
&r);
|
||||
|
||||
if (r <= 0.f) {
|
||||
// Rendering of the element is disabled
|
||||
|
@ -112,7 +127,9 @@ bool SVGCircleElement::GetGeometryBounds(
|
|||
|
||||
already_AddRefed<Path> SVGCircleElement::BuildPath(PathBuilder* aBuilder) {
|
||||
float x, y, r;
|
||||
GetAnimatedLengthValues(&x, &y, &r, nullptr);
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::Cx, SVGT::Cy, SVGT::R>(this, &x, &y,
|
||||
&r);
|
||||
|
||||
if (r <= 0.0f) {
|
||||
return nullptr;
|
||||
|
@ -123,5 +140,30 @@ already_AddRefed<Path> SVGCircleElement::BuildPath(PathBuilder* aBuilder) {
|
|||
return aBuilder->Finish();
|
||||
}
|
||||
|
||||
bool SVGCircleElement::IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
|
||||
const ComputedStyle& aOldStyle) {
|
||||
auto *newSVGReset = aNewStyle.StyleSVGReset(),
|
||||
*oldSVGReset = aOldStyle.StyleSVGReset();
|
||||
|
||||
return newSVGReset->mCx != oldSVGReset->mCx ||
|
||||
newSVGReset->mCy != oldSVGReset->mCy ||
|
||||
newSVGReset->mR != oldSVGReset->mR;
|
||||
}
|
||||
|
||||
nsCSSPropertyID SVGCircleElement::GetCSSPropertyIdForAttrEnum(
|
||||
uint8_t aAttrEnum) {
|
||||
switch (aAttrEnum) {
|
||||
case ATTR_CX:
|
||||
return eCSSProperty_cx;
|
||||
case ATTR_CY:
|
||||
return eCSSProperty_cy;
|
||||
case ATTR_R:
|
||||
return eCSSProperty_r;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown attr enum");
|
||||
return eCSSProperty_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef mozilla_dom_SVGCircleElement_h
|
||||
#define mozilla_dom_SVGCircleElement_h
|
||||
|
||||
#include "nsCSSPropertyID.h"
|
||||
#include "SVGGeometryElement.h"
|
||||
#include "SVGAnimatedLength.h"
|
||||
|
||||
|
@ -14,6 +15,8 @@ nsresult NS_NewSVGCircleElement(
|
|||
nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
|
||||
|
||||
namespace mozilla {
|
||||
class ComputedStyle;
|
||||
|
||||
namespace dom {
|
||||
|
||||
typedef SVGGeometryElement SVGCircleElementBase;
|
||||
|
@ -29,6 +32,8 @@ class SVGCircleElement final : public SVGCircleElementBase {
|
|||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
|
||||
|
||||
public:
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
|
||||
// nsSVGSVGElement methods:
|
||||
virtual bool HasValidDimensions() const override;
|
||||
|
||||
|
@ -41,6 +46,10 @@ class SVGCircleElement final : public SVGCircleElementBase {
|
|||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
static bool IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
|
||||
const ComputedStyle& aOldStyle);
|
||||
static nsCSSPropertyID GetCSSPropertyIdForAttrEnum(uint8_t aAttrEnum);
|
||||
|
||||
// WebIDL
|
||||
already_AddRefed<DOMSVGAnimatedLength> Cx();
|
||||
already_AddRefed<DOMSVGAnimatedLength> Cy();
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "nsAttrValueOrString.h"
|
||||
#include "nsCSSProps.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDOMCSSAttrDeclaration.h"
|
||||
#include "nsICSSDeclaration.h"
|
||||
#include "nsIContentInlines.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
|
@ -53,6 +54,7 @@
|
|||
#include "SVGAnimatedOrient.h"
|
||||
#include "SVGAnimatedString.h"
|
||||
#include "SVGAnimatedViewBox.h"
|
||||
#include "SVGGeometryProperty.h"
|
||||
#include "SVGMotionSMILAttr.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
|
@ -1020,6 +1022,41 @@ already_AddRefed<DOMSVGAnimatedString> SVGElement::ClassName() {
|
|||
return mClassAttribute.ToDOMAnimatedString(this);
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool SVGElement::UpdateDeclarationBlockFromLength(
|
||||
DeclarationBlock& aBlock, nsCSSPropertyID aPropId,
|
||||
const SVGAnimatedLength& aLength, ValToUse aValToUse) {
|
||||
aBlock.AssertMutable();
|
||||
|
||||
float value;
|
||||
if (aValToUse == ValToUse::Anim) {
|
||||
value = aLength.GetAnimValInSpecifiedUnits();
|
||||
} else {
|
||||
MOZ_ASSERT(aValToUse == ValToUse::Base);
|
||||
value = aLength.GetBaseValInSpecifiedUnits();
|
||||
}
|
||||
|
||||
// SVG parser doesn't check non-negativity of some parsed value,
|
||||
// we should not pass those to CSS side.
|
||||
if (value < 0 &&
|
||||
SVGGeometryProperty::IsNonNegativeGeometryProperty(aPropId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCSSUnit cssUnit = SVGGeometryProperty::SpecifiedUnitTypeToCSSUnit(
|
||||
aLength.GetSpecifiedUnitType());
|
||||
|
||||
if (cssUnit == eCSSUnit_Percent) {
|
||||
Servo_DeclarationBlock_SetPercentValue(aBlock.Raw(), aPropId,
|
||||
value / 100.f);
|
||||
} else {
|
||||
Servo_DeclarationBlock_SetLengthValue(aBlock.Raw(), aPropId, value,
|
||||
cssUnit);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Helper class: MappedAttrParser, for parsing values of mapped attributes
|
||||
|
||||
|
@ -1035,6 +1072,9 @@ class MOZ_STACK_CLASS MappedAttrParser {
|
|||
void ParseMappedAttrValue(nsAtom* aMappedAttrName,
|
||||
const nsAString& aMappedAttrValue);
|
||||
|
||||
void TellStyleAlreadyParsedResult(nsAtom const* aAtom,
|
||||
SVGAnimatedLength const& aLength);
|
||||
|
||||
// If we've parsed any values for mapped attributes, this method returns the
|
||||
// already_AddRefed css::Declaration that incorporates the parsed
|
||||
// values. Otherwise, this method returns null.
|
||||
|
@ -1122,6 +1162,18 @@ void MappedAttrParser::ParseMappedAttrValue(nsAtom* aMappedAttrName,
|
|||
}
|
||||
}
|
||||
|
||||
void MappedAttrParser::TellStyleAlreadyParsedResult(
|
||||
nsAtom const* aAtom, SVGAnimatedLength const& aLength) {
|
||||
if (!mDecl) {
|
||||
mDecl = new DeclarationBlock();
|
||||
}
|
||||
nsCSSPropertyID propertyID =
|
||||
nsCSSProps::LookupProperty(nsDependentAtomString(aAtom));
|
||||
|
||||
SVGElement::UpdateDeclarationBlockFromLength(*mDecl, propertyID, aLength,
|
||||
SVGElement::ValToUse::Base);
|
||||
}
|
||||
|
||||
already_AddRefed<DeclarationBlock> MappedAttrParser::GetDeclarationBlock() {
|
||||
return mDecl.forget();
|
||||
}
|
||||
|
@ -1145,6 +1197,9 @@ void SVGElement::UpdateContentDeclarationBlock() {
|
|||
MappedAttrParser mappedAttrParser(doc->CSSLoader(), doc->GetDocumentURI(),
|
||||
GetBaseURI(), this);
|
||||
|
||||
bool lengthAffectsStyle =
|
||||
SVGGeometryProperty::ElementMapsLengthsToStyle(this);
|
||||
|
||||
for (uint32_t i = 0; i < attrCount; ++i) {
|
||||
const nsAttrName* attrName = mAttrs.AttrNameAt(i);
|
||||
if (!attrName->IsAtom() || !IsAttributeMapped(attrName->Atom())) continue;
|
||||
|
@ -1177,6 +1232,20 @@ void SVGElement::UpdateContentDeclarationBlock() {
|
|||
}
|
||||
}
|
||||
|
||||
if (lengthAffectsStyle) {
|
||||
auto const* length = GetAnimatedLength(attrName->Atom());
|
||||
|
||||
if (length && length->HasBaseVal()) {
|
||||
// This is an element with geometry property set via SVG attribute,
|
||||
// and the attribute is already successfully parsed. We want to go
|
||||
// through the optimized path to tell the style system the result
|
||||
// directly, rather than let it parse the same thing again.
|
||||
mappedAttrParser.TellStyleAlreadyParsedResult(attrName->Atom(),
|
||||
*length);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString value;
|
||||
mAttrs.AttrAt(i)->ToString(value);
|
||||
mappedAttrParser.ParseMappedAttrValue(attrName->Atom(), value);
|
||||
|
@ -1391,6 +1460,15 @@ void SVGElement::DidChangeLength(uint8_t aAttrEnum,
|
|||
}
|
||||
|
||||
void SVGElement::DidAnimateLength(uint8_t aAttrEnum) {
|
||||
if (SVGGeometryProperty::ElementMapsLengthsToStyle(this)) {
|
||||
nsCSSPropertyID propId =
|
||||
SVGGeometryProperty::AttrEnumToCSSPropId(this, aAttrEnum);
|
||||
|
||||
SMILOverrideStyle()->SetSMILValue(propId,
|
||||
GetLengthInfo().mLengths[aAttrEnum]);
|
||||
return;
|
||||
}
|
||||
|
||||
ClearAnyCachedPath();
|
||||
|
||||
nsIFrame* frame = GetPrimaryFrame();
|
||||
|
@ -1411,7 +1489,6 @@ SVGAnimatedLength* SVGElement::GetAnimatedLength(const nsAtom* aAttrName) {
|
|||
return &lengthInfo.mLengths[i];
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(false, "no matching length found");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -165,6 +165,12 @@ class SVGElement : public SVGElementBase // nsIContent
|
|||
virtual bool HasValidDimensions() const { return true; }
|
||||
void SetLength(nsAtom* aName, const SVGAnimatedLength& aLength);
|
||||
|
||||
enum class ValToUse { Base, Anim };
|
||||
static bool UpdateDeclarationBlockFromLength(DeclarationBlock& aBlock,
|
||||
nsCSSPropertyID aPropId,
|
||||
const SVGAnimatedLength& aLength,
|
||||
ValToUse aValToUse);
|
||||
|
||||
nsAttrValue WillChangeLength(uint8_t aAttrEnum);
|
||||
nsAttrValue WillChangeNumberPair(uint8_t aAttrEnum);
|
||||
nsAttrValue WillChangeIntegerPair(uint8_t aAttrEnum);
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
* 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 "ComputedStyle.h"
|
||||
#include "mozilla/dom/SVGEllipseElement.h"
|
||||
#include "mozilla/dom/SVGEllipseElementBinding.h"
|
||||
#include "mozilla/dom/SVGLengthBinding.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/PathHelpers.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "SVGGeometryProperty.h"
|
||||
|
||||
NS_IMPL_NS_NEW_SVG_ELEMENT(Ellipse)
|
||||
|
||||
|
@ -41,6 +43,13 @@ SVGEllipseElement::SVGEllipseElement(
|
|||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
||||
: SVGEllipseElementBase(std::move(aNodeInfo)) {}
|
||||
|
||||
bool SVGEllipseElement::IsAttributeMapped(const nsAtom* aAttribute) const {
|
||||
return IsInLengthInfo(aAttribute, sLengthInfo) ||
|
||||
SVGEllipseElementBase::IsAttributeMapped(aAttribute);
|
||||
}
|
||||
|
||||
namespace SVGT = SVGGeometryProperty::Tags;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsINode methods
|
||||
|
||||
|
@ -70,10 +79,12 @@ already_AddRefed<DOMSVGAnimatedLength> SVGEllipseElement::Ry() {
|
|||
|
||||
/* virtual */
|
||||
bool SVGEllipseElement::HasValidDimensions() const {
|
||||
return mLengthAttributes[RX].IsExplicitlySet() &&
|
||||
mLengthAttributes[RX].GetAnimValInSpecifiedUnits() > 0 &&
|
||||
mLengthAttributes[RY].IsExplicitlySet() &&
|
||||
mLengthAttributes[RY].GetAnimValInSpecifiedUnits() > 0;
|
||||
float rx, ry;
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::Rx, SVGT::Ry>(this, &rx, &ry);
|
||||
|
||||
return rx > 0 && ry > 0;
|
||||
}
|
||||
|
||||
SVGElement::LengthAttributesInfo SVGEllipseElement::GetLengthInfo() {
|
||||
|
@ -88,7 +99,10 @@ bool SVGEllipseElement::GetGeometryBounds(
|
|||
Rect* aBounds, const StrokeOptions& aStrokeOptions,
|
||||
const Matrix& aToBoundsSpace, const Matrix* aToNonScalingStrokeSpace) {
|
||||
float x, y, rx, ry;
|
||||
GetAnimatedLengthValues(&x, &y, &rx, &ry, nullptr);
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::Cx, SVGT::Cy, SVGT::Rx, SVGT::Ry>(
|
||||
this, &x, &y, &rx, &ry);
|
||||
|
||||
if (rx <= 0.f || ry <= 0.f) {
|
||||
// Rendering of the element is disabled
|
||||
|
@ -124,7 +138,10 @@ bool SVGEllipseElement::GetGeometryBounds(
|
|||
|
||||
already_AddRefed<Path> SVGEllipseElement::BuildPath(PathBuilder* aBuilder) {
|
||||
float x, y, rx, ry;
|
||||
GetAnimatedLengthValues(&x, &y, &rx, &ry, nullptr);
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::Cx, SVGT::Cy, SVGT::Rx, SVGT::Ry>(
|
||||
this, &x, &y, &rx, &ry);
|
||||
|
||||
if (rx <= 0.0f || ry <= 0.0f) {
|
||||
return nullptr;
|
||||
|
@ -135,5 +152,33 @@ already_AddRefed<Path> SVGEllipseElement::BuildPath(PathBuilder* aBuilder) {
|
|||
return aBuilder->Finish();
|
||||
}
|
||||
|
||||
bool SVGEllipseElement::IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
|
||||
const ComputedStyle& aOldStyle) {
|
||||
auto *newSVGReset = aNewStyle.StyleSVGReset(),
|
||||
*oldSVGReset = aOldStyle.StyleSVGReset();
|
||||
|
||||
return newSVGReset->mCx != oldSVGReset->mCx ||
|
||||
newSVGReset->mCy != oldSVGReset->mCy ||
|
||||
newSVGReset->mRx != oldSVGReset->mRx ||
|
||||
newSVGReset->mRy != oldSVGReset->mRy;
|
||||
}
|
||||
|
||||
nsCSSPropertyID SVGEllipseElement::GetCSSPropertyIdForAttrEnum(
|
||||
uint8_t aAttrEnum) {
|
||||
switch (aAttrEnum) {
|
||||
case CX:
|
||||
return eCSSProperty_cx;
|
||||
case CY:
|
||||
return eCSSProperty_cy;
|
||||
case RX:
|
||||
return eCSSProperty_rx;
|
||||
case RY:
|
||||
return eCSSProperty_ry;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown attr enum");
|
||||
return eCSSProperty_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef mozilla_dom_SVGEllipseElement_h
|
||||
#define mozilla_dom_SVGEllipseElement_h
|
||||
|
||||
#include "nsCSSPropertyID.h"
|
||||
#include "SVGAnimatedLength.h"
|
||||
#include "SVGGeometryElement.h"
|
||||
|
||||
|
@ -14,6 +15,8 @@ nsresult NS_NewSVGEllipseElement(
|
|||
nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
|
||||
|
||||
namespace mozilla {
|
||||
class ComputedStyle;
|
||||
|
||||
namespace dom {
|
||||
|
||||
typedef SVGGeometryElement SVGEllipseElementBase;
|
||||
|
@ -29,6 +32,8 @@ class SVGEllipseElement final : public SVGEllipseElementBase {
|
|||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
|
||||
|
||||
public:
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
|
||||
// nsSVGSVGElement methods:
|
||||
virtual bool HasValidDimensions() const override;
|
||||
|
||||
|
@ -41,6 +46,10 @@ class SVGEllipseElement final : public SVGEllipseElementBase {
|
|||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
static bool IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
|
||||
const ComputedStyle& aOldStyle);
|
||||
static nsCSSPropertyID GetCSSPropertyIdForAttrEnum(uint8_t aAttrEnum);
|
||||
|
||||
// WebIDL
|
||||
already_AddRefed<DOMSVGAnimatedLength> Cx();
|
||||
already_AddRefed<DOMSVGAnimatedLength> Cy();
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "mozilla/dom/SVGDocument.h"
|
||||
#include "mozilla/dom/SVGForeignObjectElementBinding.h"
|
||||
#include "mozilla/dom/SVGLengthBinding.h"
|
||||
#include "SVGGeometryProperty.h"
|
||||
|
||||
NS_IMPL_NS_NEW_SVG_ELEMENT(ForeignObject)
|
||||
|
||||
|
@ -40,6 +41,8 @@ SVGForeignObjectElement::SVGForeignObjectElement(
|
|||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
||||
: SVGGraphicsElement(std::move(aNodeInfo)) {}
|
||||
|
||||
namespace SVGT = SVGGeometryProperty::Tags;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsINode methods
|
||||
|
||||
|
@ -77,8 +80,16 @@ gfxMatrix SVGForeignObjectElement::PrependLocalTransformsTo(
|
|||
}
|
||||
// our 'x' and 'y' attributes:
|
||||
float x, y;
|
||||
const_cast<SVGForeignObjectElement*>(this)->GetAnimatedLengthValues(&x, &y,
|
||||
nullptr);
|
||||
|
||||
if (GetPrimaryFrame()) {
|
||||
SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y>(this, &x, &y);
|
||||
} else {
|
||||
// This function might be called for element in display:none subtree
|
||||
// (e.g. getScreenCTM), we fall back to use SVG attributes.
|
||||
const_cast<SVGForeignObjectElement*>(this)->GetAnimatedLengthValues(
|
||||
&x, &y, nullptr);
|
||||
}
|
||||
|
||||
gfxMatrix toUserSpace = gfxMatrix::Translation(x, y);
|
||||
if (aWhich == eChildToUserSpace) {
|
||||
return toUserSpace * aMatrix;
|
||||
|
@ -89,10 +100,12 @@ gfxMatrix SVGForeignObjectElement::PrependLocalTransformsTo(
|
|||
|
||||
/* virtual */
|
||||
bool SVGForeignObjectElement::HasValidDimensions() const {
|
||||
return mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() &&
|
||||
mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0 &&
|
||||
mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() &&
|
||||
mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0;
|
||||
float width, height;
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::Width, SVGT::Height>(
|
||||
const_cast<SVGForeignObjectElement*>(this), &width, &height);
|
||||
return width > 0 && height > 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -109,7 +122,8 @@ SVGForeignObjectElement::IsAttributeMapped(const nsAtom* name) const {
|
|||
sTextContentElementsMap,
|
||||
sViewportsMap};
|
||||
|
||||
return FindAttributeDependence(name, map) ||
|
||||
return IsInLengthInfo(name, sLengthInfo) ||
|
||||
FindAttributeDependence(name, map) ||
|
||||
SVGGraphicsElement::IsAttributeMapped(name);
|
||||
}
|
||||
|
||||
|
@ -121,5 +135,22 @@ SVGElement::LengthAttributesInfo SVGForeignObjectElement::GetLengthInfo() {
|
|||
ArrayLength(sLengthInfo));
|
||||
}
|
||||
|
||||
nsCSSPropertyID SVGForeignObjectElement::GetCSSPropertyIdForAttrEnum(
|
||||
uint8_t aAttrEnum) {
|
||||
switch (aAttrEnum) {
|
||||
case ATTR_X:
|
||||
return eCSSProperty_x;
|
||||
case ATTR_Y:
|
||||
return eCSSProperty_y;
|
||||
case ATTR_WIDTH:
|
||||
return eCSSProperty_width;
|
||||
case ATTR_HEIGHT:
|
||||
return eCSSProperty_height;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown attr enum");
|
||||
return eCSSProperty_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define mozilla_dom_SVGForeignObjectElement_h
|
||||
|
||||
#include "mozilla/dom/SVGGraphicsElement.h"
|
||||
#include "nsCSSPropertyID.h"
|
||||
#include "SVGAnimatedLength.h"
|
||||
|
||||
nsresult NS_NewSVGForeignObjectElement(
|
||||
|
@ -42,6 +43,8 @@ class SVGForeignObjectElement final : public SVGGraphicsElement {
|
|||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
static nsCSSPropertyID GetCSSPropertyIdForAttrEnum(uint8_t aAttrEnum);
|
||||
|
||||
// WebIDL
|
||||
already_AddRefed<DOMSVGAnimatedLength> X();
|
||||
already_AddRefed<DOMSVGAnimatedLength> Y();
|
||||
|
|
|
@ -10,8 +10,11 @@
|
|||
#include "gfxPlatform.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsComputedDOMStyle.h"
|
||||
#include "SVGAnimatedLength.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "SVGAnimatedLength.h"
|
||||
#include "SVGCircleElement.h"
|
||||
#include "SVGEllipseElement.h"
|
||||
#include "SVGRectElement.h"
|
||||
#include "mozilla/dom/SVGLengthBinding.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
@ -111,6 +114,22 @@ already_AddRefed<Path> SVGGeometryElement::GetOrBuildPathForMeasuring() {
|
|||
return GetOrBuildPath(drawTarget, fillRule);
|
||||
}
|
||||
|
||||
bool SVGGeometryElement::IsGeometryChangedViaCSS(
|
||||
ComputedStyle const& aNewStyle, ComputedStyle const& aOldStyle) const {
|
||||
if (IsSVGElement(nsGkAtoms::rect)) {
|
||||
return SVGRectElement::IsLengthChangedViaCSS(aNewStyle, aOldStyle);
|
||||
}
|
||||
|
||||
if (IsSVGElement(nsGkAtoms::circle)) {
|
||||
return SVGCircleElement::IsLengthChangedViaCSS(aNewStyle, aOldStyle);
|
||||
}
|
||||
|
||||
if (IsSVGElement(nsGkAtoms::ellipse)) {
|
||||
return SVGEllipseElement::IsLengthChangedViaCSS(aNewStyle, aOldStyle);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FillRule SVGGeometryElement::GetFillRule() {
|
||||
FillRule fillRule =
|
||||
FillRule::FILL_WINDING; // Equivalent to StyleFillRule::Nonzero
|
||||
|
|
|
@ -191,6 +191,13 @@ class SVGGeometryElement : public SVGGeometryElementBase {
|
|||
*/
|
||||
virtual already_AddRefed<Path> GetOrBuildPathForMeasuring();
|
||||
|
||||
/**
|
||||
* Return |true| if some geometry properties (|x|, |y|, etc) are changed
|
||||
* because of CSS change.
|
||||
*/
|
||||
bool IsGeometryChangedViaCSS(ComputedStyle const& aNewStyle,
|
||||
ComputedStyle const& aOldStyle) const;
|
||||
|
||||
/**
|
||||
* Returns the current computed value of the CSS property 'fill-rule' for
|
||||
* this element.
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#include "SVGGeometryProperty.h"
|
||||
#include "SVGCircleElement.h"
|
||||
#include "SVGEllipseElement.h"
|
||||
#include "SVGForeignObjectElement.h"
|
||||
#include "SVGRectElement.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace SVGGeometryProperty {
|
||||
|
||||
nsCSSUnit SpecifiedUnitTypeToCSSUnit(uint8_t aSpecifiedUnit) {
|
||||
switch (aSpecifiedUnit) {
|
||||
case SVGLength_Binding::SVG_LENGTHTYPE_NUMBER:
|
||||
case SVGLength_Binding::SVG_LENGTHTYPE_PX:
|
||||
return nsCSSUnit::eCSSUnit_Pixel;
|
||||
|
||||
case SVGLength_Binding::SVG_LENGTHTYPE_MM:
|
||||
return nsCSSUnit::eCSSUnit_Millimeter;
|
||||
|
||||
case SVGLength_Binding::SVG_LENGTHTYPE_CM:
|
||||
return nsCSSUnit::eCSSUnit_Centimeter;
|
||||
|
||||
case SVGLength_Binding::SVG_LENGTHTYPE_IN:
|
||||
return nsCSSUnit::eCSSUnit_Inch;
|
||||
|
||||
case SVGLength_Binding::SVG_LENGTHTYPE_PT:
|
||||
return nsCSSUnit::eCSSUnit_Point;
|
||||
|
||||
case SVGLength_Binding::SVG_LENGTHTYPE_PC:
|
||||
return nsCSSUnit::eCSSUnit_Pica;
|
||||
|
||||
case SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE:
|
||||
return nsCSSUnit::eCSSUnit_Percent;
|
||||
|
||||
case SVGLength_Binding::SVG_LENGTHTYPE_EMS:
|
||||
return nsCSSUnit::eCSSUnit_EM;
|
||||
|
||||
case SVGLength_Binding::SVG_LENGTHTYPE_EXS:
|
||||
return nsCSSUnit::eCSSUnit_XHeight;
|
||||
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown unit type");
|
||||
return nsCSSUnit::eCSSUnit_Pixel;
|
||||
}
|
||||
}
|
||||
|
||||
nsCSSPropertyID AttrEnumToCSSPropId(const SVGElement* aElement,
|
||||
uint8_t aAttrEnum) {
|
||||
// This is a very trivial function only applied to a few elements,
|
||||
// so we want to avoid making it virtual.
|
||||
if (aElement->IsSVGElement(nsGkAtoms::rect)) {
|
||||
return SVGRectElement::GetCSSPropertyIdForAttrEnum(aAttrEnum);
|
||||
}
|
||||
if (aElement->IsSVGElement(nsGkAtoms::circle)) {
|
||||
return SVGCircleElement::GetCSSPropertyIdForAttrEnum(aAttrEnum);
|
||||
}
|
||||
if (aElement->IsSVGElement(nsGkAtoms::ellipse)) {
|
||||
return SVGEllipseElement::GetCSSPropertyIdForAttrEnum(aAttrEnum);
|
||||
}
|
||||
if (aElement->IsSVGElement(nsGkAtoms::foreignObject)) {
|
||||
return SVGForeignObjectElement::GetCSSPropertyIdForAttrEnum(aAttrEnum);
|
||||
}
|
||||
return eCSSProperty_UNKNOWN;
|
||||
}
|
||||
|
||||
bool IsNonNegativeGeometryProperty(nsCSSPropertyID aProp) {
|
||||
return aProp == eCSSProperty_r || aProp == eCSSProperty_rx ||
|
||||
aProp == eCSSProperty_ry || aProp == eCSSProperty_width ||
|
||||
aProp == eCSSProperty_height;
|
||||
}
|
||||
|
||||
bool ElementMapsLengthsToStyle(SVGElement const* aElement) {
|
||||
return aElement->IsSVGElement(nsGkAtoms::rect) ||
|
||||
aElement->IsSVGElement(nsGkAtoms::circle) ||
|
||||
aElement->IsSVGElement(nsGkAtoms::ellipse) ||
|
||||
aElement->IsSVGElement(nsGkAtoms::foreignObject);
|
||||
}
|
||||
|
||||
} // namespace SVGGeometryProperty
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,162 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_SVGGeometryProperty_SVGGeometryProperty_h
|
||||
#define mozilla_dom_SVGGeometryProperty_SVGGeometryProperty_h
|
||||
|
||||
#include "mozilla/dom/SVGElement.h"
|
||||
#include "SVGAnimatedLength.h"
|
||||
#include "ComputedStyle.h"
|
||||
#include "nsIFrame.h"
|
||||
#include <type_traits>
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
namespace SVGGeometryProperty {
|
||||
namespace ResolverTypes {
|
||||
struct LengthPercentNoAuto {};
|
||||
struct LengthPercentRXY {};
|
||||
struct LengthPercentWidthHeight {};
|
||||
} // namespace ResolverTypes
|
||||
|
||||
namespace Tags {
|
||||
|
||||
#define SVGGEOMETRYPROPERTY_GENERATETAG(tagName, resolver, direction, \
|
||||
styleStruct) \
|
||||
struct tagName { \
|
||||
using ResolverType = ResolverTypes::resolver; \
|
||||
constexpr static auto CtxDirection = SVGContentUtils::direction; \
|
||||
constexpr static auto Getter = &styleStruct::m##tagName; \
|
||||
}
|
||||
|
||||
SVGGEOMETRYPROPERTY_GENERATETAG(X, LengthPercentNoAuto, X, nsStyleSVGReset);
|
||||
SVGGEOMETRYPROPERTY_GENERATETAG(Y, LengthPercentNoAuto, Y, nsStyleSVGReset);
|
||||
SVGGEOMETRYPROPERTY_GENERATETAG(Cx, LengthPercentNoAuto, X, nsStyleSVGReset);
|
||||
SVGGEOMETRYPROPERTY_GENERATETAG(Cy, LengthPercentNoAuto, Y, nsStyleSVGReset);
|
||||
SVGGEOMETRYPROPERTY_GENERATETAG(R, LengthPercentNoAuto, XY, nsStyleSVGReset);
|
||||
SVGGEOMETRYPROPERTY_GENERATETAG(Width, LengthPercentWidthHeight, X,
|
||||
nsStylePosition);
|
||||
SVGGEOMETRYPROPERTY_GENERATETAG(Height, LengthPercentWidthHeight, Y,
|
||||
nsStylePosition);
|
||||
|
||||
#undef SVGGEOMETRYPROPERTY_GENERATETAG
|
||||
|
||||
struct Ry;
|
||||
struct Rx {
|
||||
using ResolverType = ResolverTypes::LengthPercentRXY;
|
||||
constexpr static auto CtxDirection = SVGContentUtils::X;
|
||||
constexpr static auto Getter = &nsStyleSVGReset::mRx;
|
||||
using CounterPart = Ry;
|
||||
};
|
||||
struct Ry {
|
||||
using ResolverType = ResolverTypes::LengthPercentRXY;
|
||||
constexpr static auto CtxDirection = SVGContentUtils::Y;
|
||||
constexpr static auto Getter = &nsStyleSVGReset::mRy;
|
||||
using CounterPart = Rx;
|
||||
};
|
||||
|
||||
} // namespace Tags
|
||||
|
||||
namespace details {
|
||||
template <class T>
|
||||
using AlwaysFloat = float;
|
||||
|
||||
using CtxDirectionType = decltype(SVGContentUtils::X);
|
||||
|
||||
template <CtxDirectionType CTD>
|
||||
float ResolvePureLengthPercentage(SVGElement* aElement,
|
||||
const LengthPercentage& aLP) {
|
||||
return aLP.ResolveToCSSPixelsWith(
|
||||
[&] { return CSSCoord{SVGElementMetrics(aElement).GetAxisLength(CTD)}; });
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
float ResolveImpl(ComputedStyle const& aStyle, SVGElement* aElement,
|
||||
ResolverTypes::LengthPercentNoAuto) {
|
||||
auto const& value = aStyle.StyleSVGReset()->*Tag::Getter;
|
||||
return ResolvePureLengthPercentage<Tag::CtxDirection>(aElement, value);
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
float ResolveImpl(ComputedStyle const& aStyle, SVGElement* aElement,
|
||||
ResolverTypes::LengthPercentWidthHeight) {
|
||||
static_assert(
|
||||
std::is_same<Tag, Tags::Width>{} || std::is_same<Tag, Tags::Height>{},
|
||||
"Wrong tag");
|
||||
|
||||
auto const& value = aStyle.StylePosition()->*Tag::Getter;
|
||||
if (value.IsLengthPercentage()) {
|
||||
return ResolvePureLengthPercentage<Tag::CtxDirection>(
|
||||
aElement, value.AsLengthPercentage());
|
||||
}
|
||||
|
||||
// |auto| and |max-content| etc. are treated as 0.
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
float ResolveImpl(ComputedStyle const& aStyle, SVGElement* aElement,
|
||||
ResolverTypes::LengthPercentRXY) {
|
||||
static_assert(std::is_same<Tag, Tags::Rx>{} || std::is_same<Tag, Tags::Ry>{},
|
||||
"Wrong tag");
|
||||
|
||||
auto const& value = aStyle.StyleSVGReset()->*Tag::Getter;
|
||||
if (value.IsLengthPercentage()) {
|
||||
return ResolvePureLengthPercentage<Tag::CtxDirection>(
|
||||
aElement, value.AsLengthPercentage());
|
||||
}
|
||||
|
||||
MOZ_ASSERT(value.IsAuto());
|
||||
using Rother = typename Tag::CounterPart;
|
||||
auto const& valueOther = aStyle.StyleSVGReset()->*Rother::Getter;
|
||||
|
||||
if (valueOther.IsAuto()) {
|
||||
// Per SVG2, |Rx|, |Ry| resolve to 0 if both are |auto|
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
// If |Rx| is auto while |Ry| not, |Rx| gets the value of |Ry|.
|
||||
return ResolvePureLengthPercentage<Rother::CtxDirection>(
|
||||
aElement, valueOther.AsLengthPercentage());
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
template <class Tag>
|
||||
float ResolveWith(const ComputedStyle& aStyle, const SVGElement* aElement) {
|
||||
// TODO: There are a lot of utilities lacking const-ness in dom/svg.
|
||||
// We should fix that problem and remove this `const_cast`.
|
||||
return details::ResolveImpl<Tag>(aStyle, const_cast<SVGElement*>(aElement),
|
||||
typename Tag::ResolverType{});
|
||||
}
|
||||
|
||||
// To add support for new properties, or to handle special cases for
|
||||
// existing properties, you can add a new tag in |Tags| and |ResolverTypes|
|
||||
// namespace, then implement the behavior in |details::ResolveImpl|.
|
||||
template <class... Tags>
|
||||
bool ResolveAll(const SVGElement* aElement,
|
||||
details::AlwaysFloat<Tags>*... aRes) {
|
||||
if (nsIFrame const* f = aElement->GetPrimaryFrame()) {
|
||||
using dummy = int[];
|
||||
(void)dummy{0, (*aRes = ResolveWith<Tags>(*f->Style(), aElement), 0)...};
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCSSUnit SpecifiedUnitTypeToCSSUnit(uint8_t aSpecifiedUnit);
|
||||
nsCSSPropertyID AttrEnumToCSSPropId(const SVGElement* aElement,
|
||||
uint8_t aAttrEnum);
|
||||
|
||||
bool IsNonNegativeGeometryProperty(nsCSSPropertyID aProp);
|
||||
bool ElementMapsLengthsToStyle(SVGElement const* aElement);
|
||||
|
||||
} // namespace SVGGeometryProperty
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -32,6 +32,16 @@ class SVGGraphicsElement : public SVGGraphicsElementBase, public SVGTests {
|
|||
// returns true if focusability has been definitively determined otherwise
|
||||
// false
|
||||
bool IsSVGFocusable(bool* aIsFocusable, int32_t* aTabIndex);
|
||||
|
||||
template <typename T>
|
||||
bool IsInLengthInfo(const nsAtom* aAttribute, const T& aLengthInfos) const {
|
||||
for (auto const& e : aLengthInfos) {
|
||||
if (e.mName == aAttribute) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -218,7 +218,8 @@ SVGImageElement::IsAttributeMapped(const nsAtom* name) const {
|
|||
sViewportsMap,
|
||||
};
|
||||
|
||||
return FindAttributeDependence(name, map) ||
|
||||
return IsInLengthInfo(name, sLengthInfo) ||
|
||||
FindAttributeDependence(name, map) ||
|
||||
SVGImageElementBase::IsAttributeMapped(name);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,13 +5,14 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/SVGRectElement.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "mozilla/dom/SVGLengthBinding.h"
|
||||
#include "mozilla/dom/SVGRectElementBinding.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/Matrix.h"
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
#include "mozilla/gfx/PathHelpers.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "SVGGeometryProperty.h"
|
||||
#include <algorithm>
|
||||
|
||||
NS_IMPL_NS_NEW_SVG_ELEMENT(Rect)
|
||||
|
@ -49,6 +50,13 @@ SVGRectElement::SVGRectElement(
|
|||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
||||
: SVGRectElementBase(std::move(aNodeInfo)) {}
|
||||
|
||||
bool SVGRectElement::IsAttributeMapped(const nsAtom* aAttribute) const {
|
||||
return IsInLengthInfo(aAttribute, sLengthInfo) ||
|
||||
SVGRectElementBase::IsAttributeMapped(aAttribute);
|
||||
}
|
||||
|
||||
namespace SVGT = SVGGeometryProperty::Tags;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsINode methods
|
||||
|
||||
|
@ -85,10 +93,13 @@ already_AddRefed<DOMSVGAnimatedLength> SVGRectElement::Ry() {
|
|||
|
||||
/* virtual */
|
||||
bool SVGRectElement::HasValidDimensions() const {
|
||||
return mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() &&
|
||||
mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0 &&
|
||||
mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() &&
|
||||
mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0;
|
||||
float width, height;
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::Width, SVGT::Height>(this, &width,
|
||||
&height);
|
||||
|
||||
return width > 0 && height > 0;
|
||||
}
|
||||
|
||||
SVGElement::LengthAttributesInfo SVGRectElement::GetLengthInfo() {
|
||||
|
@ -105,8 +116,11 @@ bool SVGRectElement::GetGeometryBounds(Rect* aBounds,
|
|||
const Matrix* aToNonScalingStrokeSpace) {
|
||||
Rect rect;
|
||||
Float rx, ry;
|
||||
GetAnimatedLengthValues(&rect.x, &rect.y, &rect.width, &rect.height, &rx, &ry,
|
||||
nullptr);
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y, SVGT::Width, SVGT::Height,
|
||||
SVGT::Rx, SVGT::Ry>(
|
||||
this, &rect.x, &rect.y, &rect.width, &rect.height, &rx, &ry);
|
||||
|
||||
if (rect.IsEmpty()) {
|
||||
// Rendering of the element disabled
|
||||
|
@ -155,7 +169,11 @@ bool SVGRectElement::GetGeometryBounds(Rect* aBounds,
|
|||
|
||||
void SVGRectElement::GetAsSimplePath(SimplePath* aSimplePath) {
|
||||
float x, y, width, height, rx, ry;
|
||||
GetAnimatedLengthValues(&x, &y, &width, &height, &rx, &ry, nullptr);
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y, SVGT::Width, SVGT::Height,
|
||||
SVGT::Rx, SVGT::Ry>(this, &x, &y, &width,
|
||||
&height, &rx, &ry);
|
||||
|
||||
if (width <= 0 || height <= 0) {
|
||||
aSimplePath->Reset();
|
||||
|
@ -175,7 +193,11 @@ void SVGRectElement::GetAsSimplePath(SimplePath* aSimplePath) {
|
|||
|
||||
already_AddRefed<Path> SVGRectElement::BuildPath(PathBuilder* aBuilder) {
|
||||
float x, y, width, height, rx, ry;
|
||||
GetAnimatedLengthValues(&x, &y, &width, &height, &rx, &ry, nullptr);
|
||||
|
||||
MOZ_ASSERT(GetPrimaryFrame());
|
||||
SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y, SVGT::Width, SVGT::Height,
|
||||
SVGT::Rx, SVGT::Ry>(this, &x, &y, &width,
|
||||
&height, &rx, &ry);
|
||||
|
||||
if (width <= 0 || height <= 0) {
|
||||
return nullptr;
|
||||
|
@ -193,18 +215,6 @@ already_AddRefed<Path> SVGRectElement::BuildPath(PathBuilder* aBuilder) {
|
|||
aBuilder->LineTo(r.BottomLeft());
|
||||
aBuilder->Close();
|
||||
} else {
|
||||
// If either the 'rx' or the 'ry' attribute isn't set, then we have to
|
||||
// set it to the value of the other:
|
||||
bool hasRx = mLengthAttributes[ATTR_RX].IsExplicitlySet();
|
||||
bool hasRy = mLengthAttributes[ATTR_RY].IsExplicitlySet();
|
||||
MOZ_ASSERT(hasRx || hasRy);
|
||||
|
||||
if (hasRx && !hasRy) {
|
||||
ry = rx;
|
||||
} else if (hasRy && !hasRx) {
|
||||
rx = ry;
|
||||
}
|
||||
|
||||
// Clamp rx and ry to half the rect's width and height respectively:
|
||||
rx = std::min(rx, width / 2);
|
||||
ry = std::min(ry, height / 2);
|
||||
|
@ -216,5 +226,40 @@ already_AddRefed<Path> SVGRectElement::BuildPath(PathBuilder* aBuilder) {
|
|||
return aBuilder->Finish();
|
||||
}
|
||||
|
||||
bool SVGRectElement::IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
|
||||
const ComputedStyle& aOldStyle) {
|
||||
auto *newSVGReset = aNewStyle.StyleSVGReset(),
|
||||
*oldSVGReset = aOldStyle.StyleSVGReset();
|
||||
auto *newPosition = aNewStyle.StylePosition(),
|
||||
*oldPosition = aOldStyle.StylePosition();
|
||||
|
||||
return newSVGReset->mX != oldSVGReset->mX ||
|
||||
newSVGReset->mY != oldSVGReset->mY ||
|
||||
newPosition->mWidth != oldPosition->mWidth ||
|
||||
newPosition->mHeight != oldPosition->mHeight ||
|
||||
newSVGReset->mRx != oldSVGReset->mRx ||
|
||||
newSVGReset->mRy != oldSVGReset->mRy;
|
||||
}
|
||||
|
||||
nsCSSPropertyID SVGRectElement::GetCSSPropertyIdForAttrEnum(uint8_t aAttrEnum) {
|
||||
switch (aAttrEnum) {
|
||||
case ATTR_X:
|
||||
return eCSSProperty_x;
|
||||
case ATTR_Y:
|
||||
return eCSSProperty_y;
|
||||
case ATTR_WIDTH:
|
||||
return eCSSProperty_width;
|
||||
case ATTR_HEIGHT:
|
||||
return eCSSProperty_height;
|
||||
case ATTR_RX:
|
||||
return eCSSProperty_rx;
|
||||
case ATTR_RY:
|
||||
return eCSSProperty_ry;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown attr enum");
|
||||
return eCSSProperty_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef mozilla_dom_SVGRectElement_h
|
||||
#define mozilla_dom_SVGRectElement_h
|
||||
|
||||
#include "nsCSSPropertyID.h"
|
||||
#include "SVGAnimatedLength.h"
|
||||
#include "SVGGeometryElement.h"
|
||||
|
||||
|
@ -14,6 +15,8 @@ nsresult NS_NewSVGRectElement(
|
|||
nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
|
||||
|
||||
namespace mozilla {
|
||||
class ComputedStyle;
|
||||
|
||||
namespace dom {
|
||||
|
||||
typedef SVGGeometryElement SVGRectElementBase;
|
||||
|
@ -28,6 +31,8 @@ class SVGRectElement final : public SVGRectElementBase {
|
|||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
|
||||
|
||||
public:
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
|
||||
// nsSVGSVGElement methods:
|
||||
virtual bool HasValidDimensions() const override;
|
||||
|
||||
|
@ -42,6 +47,10 @@ class SVGRectElement final : public SVGRectElementBase {
|
|||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
static bool IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
|
||||
const ComputedStyle& aOldStyle);
|
||||
static nsCSSPropertyID GetCSSPropertyIdForAttrEnum(uint8_t aAttrEnum);
|
||||
|
||||
// WebIDL
|
||||
already_AddRefed<DOMSVGAnimatedLength> X();
|
||||
already_AddRefed<DOMSVGAnimatedLength> Y();
|
||||
|
|
|
@ -124,6 +124,17 @@ class SVGViewportElement : public SVGGraphicsElement {
|
|||
mViewportHeight = aSize.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if either this is an SVG <svg> element that is the child of
|
||||
* another non-foreignObject SVG element, or this is a SVG <symbol> element
|
||||
* this is the root of a use-element shadow tree.
|
||||
*/
|
||||
bool IsInner() const {
|
||||
const nsIContent* parent = GetFlattenedTreeParent();
|
||||
return parent && parent->IsSVGElement() &&
|
||||
!parent->IsSVGElement(nsGkAtoms::foreignObject);
|
||||
}
|
||||
|
||||
// WebIDL
|
||||
already_AddRefed<SVGAnimatedRect> ViewBox();
|
||||
already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
|
||||
|
@ -139,17 +150,6 @@ class SVGViewportElement : public SVGGraphicsElement {
|
|||
return IsInUncomposedDoc() && !GetParent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if either this is an SVG <svg> element that is the child of
|
||||
* another non-foreignObject SVG element, or this is a SVG <symbol> element
|
||||
* this is the root of a use-element shadow tree.
|
||||
*/
|
||||
bool IsInner() const {
|
||||
const nsIContent* parent = GetFlattenedTreeParent();
|
||||
return parent && parent->IsSVGElement() &&
|
||||
!parent->IsSVGElement(nsGkAtoms::foreignObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the explicit or default preserveAspectRatio, unless we're
|
||||
* synthesizing a viewBox, in which case it returns the "none" value.
|
||||
|
|
|
@ -181,6 +181,7 @@ UNIFIED_SOURCES += [
|
|||
'SVGFragmentIdentifier.cpp',
|
||||
'SVGGElement.cpp',
|
||||
'SVGGeometryElement.cpp',
|
||||
'SVGGeometryProperty.cpp',
|
||||
'SVGGradientElement.cpp',
|
||||
'SVGGraphicsElement.cpp',
|
||||
'SVGImageElement.cpp',
|
||||
|
|
|
@ -70,6 +70,7 @@ add_task(async function test_abort() {
|
|||
Services.prefs.setBoolPref("security.webauth.u2f", true);
|
||||
Services.prefs.setBoolPref("security.webauth.webauthn_enable_softtoken", false);
|
||||
Services.prefs.setBoolPref("security.webauth.webauthn_enable_usbtoken", true);
|
||||
Services.prefs.setBoolPref("security.webauth.webauthn_enable_android_fido2", false);
|
||||
|
||||
// Create a new tab for the MakeCredential() request.
|
||||
let tab_create = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
|
||||
|
|
|
@ -25,6 +25,7 @@ add_task(async function () {
|
|||
Services.prefs.setBoolPref("security.webauth.u2f", true);
|
||||
Services.prefs.setBoolPref("security.webauth.webauthn_enable_softtoken", true);
|
||||
Services.prefs.setBoolPref("security.webauth.webauthn_enable_usbtoken", false);
|
||||
Services.prefs.setBoolPref("security.webauth.webauthn_enable_android_fido2", false);
|
||||
|
||||
// Open a new tab.
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
|
||||
|
|
|
@ -33,6 +33,7 @@ SimpleTest.waitForExplicitFinish();
|
|||
window.addEventListener("message", handleEventMessage);
|
||||
SpecialPowers.pushPrefEnv({"set": [["security.webauth.u2f", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]]},
|
||||
function(){
|
||||
document.getElementById('testing_frame').src = "https://example.com/tests/dom/u2f/tests/frame_appid_facet.html";
|
||||
|
|
|
@ -33,6 +33,7 @@ SimpleTest.waitForExplicitFinish();
|
|||
window.addEventListener("message", handleEventMessage);
|
||||
SpecialPowers.pushPrefEnv({"set": [["security.webauth.u2f", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]]},
|
||||
function(){
|
||||
document.getElementById('testing_frame').src = "http://test2.example.com/tests/dom/u2f/tests/frame_appid_facet_insecure.html";
|
||||
|
|
|
@ -33,6 +33,7 @@ SimpleTest.waitForExplicitFinish();
|
|||
window.addEventListener("message", handleEventMessage);
|
||||
SpecialPowers.pushPrefEnv({"set": [["security.webauth.u2f", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]]},
|
||||
function(){
|
||||
document.getElementById('testing_frame').src = "https://test1.example.com/tests/dom/u2f/tests/frame_appid_facet_subdomain.html";
|
||||
|
|
|
@ -33,6 +33,7 @@ SimpleTest.waitForExplicitFinish();
|
|||
window.addEventListener("message", handleEventMessage);
|
||||
SpecialPowers.pushPrefEnv({"set": [["security.webauth.u2f", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]]},
|
||||
function(){
|
||||
document.getElementById('testing_frame').src = "https://test2.example.com/tests/dom/u2f/tests/frame_multiple_keys.html";
|
||||
|
|
|
@ -31,6 +31,7 @@ SimpleTest.waitForExplicitFinish();
|
|||
|
||||
SpecialPowers.pushPrefEnv({"set": [["security.webauth.u2f", true],
|
||||
["security.webauth.webauthn_enable_softtoken", false],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]]},
|
||||
function() {
|
||||
// listen for messages from the test harness
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.webauth.u2f", true],
|
||||
["security.webauth.webauthn_enable_softtoken", false],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", true],
|
||||
]}, () => {
|
||||
addEventListener("message", handleEventMessage);
|
||||
|
|
|
@ -31,6 +31,7 @@ SimpleTest.waitForExplicitFinish();
|
|||
|
||||
SpecialPowers.pushPrefEnv({"set": [["security.webauth.u2f", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]]},
|
||||
function() {
|
||||
// listen for messages from the test harness
|
||||
|
|
|
@ -27,6 +27,7 @@ SimpleTest.waitForExplicitFinish();
|
|||
|
||||
SpecialPowers.pushPrefEnv({"set": [["security.webauth.u2f", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]]},
|
||||
function() {
|
||||
// listen for messages from the test harness
|
||||
|
|
|
@ -86,6 +86,7 @@ add_task(async function test_setup() {
|
|||
"set": [
|
||||
["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", false],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", true]
|
||||
]
|
||||
});
|
||||
|
|
|
@ -93,6 +93,7 @@ function promiseWebAuthnSign(tab, key_handle, extensions = {}) {
|
|||
add_task(function test_setup() {
|
||||
Services.prefs.setBoolPref("security.webauth.u2f", true);
|
||||
Services.prefs.setBoolPref("security.webauth.webauthn", true);
|
||||
Services.prefs.setBoolPref("security.webauth.webauthn_enable_android_fido2", false);
|
||||
Services.prefs.setBoolPref("security.webauth.webauthn_enable_softtoken", true);
|
||||
Services.prefs.setBoolPref("security.webauth.webauthn_enable_usbtoken", false);
|
||||
});
|
||||
|
|
|
@ -99,6 +99,7 @@ add_task(async function test_setup_usbtoken() {
|
|||
["security.webauth.u2f", false],
|
||||
["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", false],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", true]
|
||||
]
|
||||
});
|
||||
|
|
|
@ -98,6 +98,7 @@ add_task(async function test_setup() {
|
|||
["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_usbtoken", false],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_testing_allow_direct_attestation", true]
|
||||
]
|
||||
});
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", true],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
]});
|
||||
});
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_usbtoken", false],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_testing_allow_direct_attestation", true],
|
||||
]});
|
||||
});
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_usbtoken", false],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
]});
|
||||
});
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_usbtoken", false],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
]});
|
||||
});
|
||||
|
||||
|
|
|
@ -62,7 +62,8 @@
|
|||
return SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]
|
||||
["security.webauth.webauthn_enable_usbtoken", false],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
]});
|
||||
});
|
||||
|
||||
|
|
|
@ -23,7 +23,9 @@ SimpleTest.waitForExplicitFinish();
|
|||
|
||||
SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]]},
|
||||
["security.webauth.webauthn_enable_usbtoken", false],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
]},
|
||||
function() {
|
||||
PublicKeyCredential.isExternalCTAP2SecurityKeySupported()
|
||||
.then(aResult => ok(true, `Should always return either true or false: ${aResult}`))
|
||||
|
|
|
@ -23,7 +23,9 @@ SimpleTest.waitForExplicitFinish();
|
|||
|
||||
SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]]},
|
||||
["security.webauth.webauthn_enable_usbtoken", false],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
]},
|
||||
async function() {
|
||||
// This test ensures that isUserVerifyingPlatformAuthenticatorAvailable()
|
||||
// is a callable method, but with the softtoken enabled, it's not useful to
|
||||
|
|
|
@ -25,6 +25,7 @@ SimpleTest.waitForExplicitFinish();
|
|||
SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_usbtoken", false],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_testing_allow_direct_attestation", true]]},
|
||||
function() {
|
||||
is(navigator.authentication, undefined, "navigator.authentication does not exist any longer");
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
|
||||
SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]]}, runTests);
|
||||
function runTests() {
|
||||
is(navigator.authentication, undefined, "navigator.authentication does not exist any longer");
|
||||
|
|
|
@ -24,6 +24,7 @@ SimpleTest.waitForExplicitFinish();
|
|||
// Turn off all tokens. This should result in "not allowed" failures
|
||||
SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", false],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]]},
|
||||
function() {
|
||||
is(navigator.authentication, undefined, "navigator.authentication does not exist any longer");
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
return SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", false],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", true],
|
||||
]});
|
||||
});
|
||||
|
|
|
@ -299,6 +299,7 @@
|
|||
};
|
||||
SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]]},
|
||||
runTests);
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
add_task(async function(){
|
||||
await SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_android_fido2", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]]});
|
||||
|
||||
isnot(navigator.credentials, undefined, "Credential Management API endpoint must exist");
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче