Merge mozilla-central to mozilla-inbound

This commit is contained in:
Dorel Luca 2018-05-16 01:01:29 +03:00
commit f76b1b99de
143 changed files with 1840 additions and 1117 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please # changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more. # don't change CLOBBER for WebIDL changes any more.
Merge day clobber Bug 1454912 - Changed out GENERATED_FILES are handled in the RecursiveMake backend

View File

@ -698,7 +698,6 @@ DocAccessible::OnPivotChanged(nsIAccessiblePivot* aPivot,
NS_IMPL_NSIDOCUMENTOBSERVER_CORE_STUB(DocAccessible) NS_IMPL_NSIDOCUMENTOBSERVER_CORE_STUB(DocAccessible)
NS_IMPL_NSIDOCUMENTOBSERVER_LOAD_STUB(DocAccessible) NS_IMPL_NSIDOCUMENTOBSERVER_LOAD_STUB(DocAccessible)
NS_IMPL_NSIDOCUMENTOBSERVER_STYLE_STUB(DocAccessible)
void void
DocAccessible::AttributeWillChange(dom::Element* aElement, DocAccessible::AttributeWillChange(dom::Element* aElement,

View File

@ -63,6 +63,27 @@ function initRow(aPartId) {
var {state, scope} = SitePermissions.get(gPermURI, aPartId); var {state, scope} = SitePermissions.get(gPermURI, aPartId);
let defaultState = SitePermissions.getDefault(aPartId); let defaultState = SitePermissions.getDefault(aPartId);
// Since cookies preferences have many different possible configuration states
// we don't consider any permission except "no permission" to be default.
if (aPartId == "cookie") {
state = Services.perms.testPermissionFromPrincipal(gPermPrincipal, "cookie");
if (state == SitePermissions.UNKNOWN) {
checkbox.checked = true;
command.setAttribute("disabled", "true");
// Don't select any item in the radio group, as we can't
// confidently say that all cookies on the site will be allowed.
let radioGroup = document.getElementById("cookieRadioGroup");
radioGroup.selectedItem = null;
} else {
checkbox.checked = false;
command.removeAttribute("disabled");
}
setRadioState(aPartId, state);
return;
}
// When flash permission state is "Hide", we show it as "Always Ask" in page info. // When flash permission state is "Hide", we show it as "Always Ask" in page info.
if (aPartId.startsWith("plugin") && state == SitePermissions.PROMPT_HIDE) { if (aPartId.startsWith("plugin") && state == SitePermissions.PROMPT_HIDE) {
defaultState == SitePermissions.UNKNOWN ? state = defaultState : state = SitePermissions.PROMPT; defaultState == SitePermissions.UNKNOWN ? state = defaultState : state = SitePermissions.PROMPT;
@ -146,8 +167,6 @@ function onCheckboxClick(aPartId) {
if (checkbox.checked) { if (checkbox.checked) {
SitePermissions.remove(gPermURI, aPartId); SitePermissions.remove(gPermURI, aPartId);
command.setAttribute("disabled", "true"); command.setAttribute("disabled", "true");
var perm = SitePermissions.getDefault(aPartId);
setRadioState(aPartId, perm);
} else { } else {
onRadioClick(aPartId); onRadioClick(aPartId);
command.removeAttribute("disabled"); command.removeAttribute("disabled");
@ -156,7 +175,7 @@ function onCheckboxClick(aPartId) {
function onRadioClick(aPartId) { function onRadioClick(aPartId) {
var radioGroup = document.getElementById(aPartId + "RadioGroup"); var radioGroup = document.getElementById(aPartId + "RadioGroup");
var id = radioGroup.selectedItem.id; var id = radioGroup.selectedItem ? radioGroup.selectedItem.id : "#1";
var permission = parseInt(id.split("#")[1]); var permission = parseInt(id.split("#")[1]);
SitePermissions.set(gPermURI, aPartId, permission); SitePermissions.set(gPermURI, aPartId, permission);
} }

View File

@ -13,6 +13,7 @@ support-files =
[browser_pageinfo_image_info.js] [browser_pageinfo_image_info.js]
uses-unsafe-cpows = true uses-unsafe-cpows = true
skip-if = (os == 'linux' && e10s) # bug 1161699 skip-if = (os == 'linux' && e10s) # bug 1161699
[browser_pageinfo_permissions.js]
[browser_pageinfo_security.js] [browser_pageinfo_security.js]
[browser_pageinfo_svg_image.js] [browser_pageinfo_svg_image.js]
support-files = support-files =

View File

@ -0,0 +1,109 @@
ChromeUtils.import("resource:///modules/SitePermissions.jsm");
const TEST_ORIGIN = "https://example.com";
async function testPermissions(defaultPermission) {
await BrowserTestUtils.withNewTab(TEST_ORIGIN, async function(browser) {
let pageInfo = BrowserPageInfo(TEST_ORIGIN, "permTab");
await BrowserTestUtils.waitForEvent(pageInfo, "load");
let defaultCheckbox = await TestUtils.waitForCondition(() => pageInfo.document.getElementById("geoDef"));
let radioGroup = pageInfo.document.getElementById("geoRadioGroup");
let defaultRadioButton = pageInfo.document.getElementById("geo#" + defaultPermission);
let blockRadioButton = pageInfo.document.getElementById("geo#2");
ok(defaultCheckbox.checked, "The default checkbox should be checked.");
SitePermissions.set(gBrowser.currentURI, "geo", SitePermissions.BLOCK);
ok(!defaultCheckbox.checked, "The default checkbox should not be checked.");
defaultCheckbox.checked = true;
defaultCheckbox.dispatchEvent(new Event("command"));
is(SitePermissions.get(gBrowser.currentURI, "geo").state, defaultPermission,
"Checking the default checkbox should reset the permission.");
defaultCheckbox.checked = false;
defaultCheckbox.dispatchEvent(new Event("command"));
is(SitePermissions.get(gBrowser.currentURI, "geo").state, defaultPermission,
"Unchecking the default checkbox should pick the default permission.");
is(radioGroup.selectedItem, defaultRadioButton,
"The unknown radio button should be selected.");
radioGroup.selectedItem = blockRadioButton;
blockRadioButton.dispatchEvent(new Event("command"));
is(SitePermissions.get(gBrowser.currentURI, "geo").state, SitePermissions.BLOCK,
"Selecting a value in the radio group should set the corresponding permission");
radioGroup.selectedItem = defaultRadioButton;
defaultRadioButton.dispatchEvent(new Event("command"));
is(SitePermissions.get(gBrowser.currentURI, "geo").state, defaultPermission,
"Selecting the default value should reset the permission.");
ok(defaultCheckbox.checked, "The default checkbox should be checked.");
pageInfo.close();
SitePermissions.remove(gBrowser.currentURI, "geo");
});
}
// Test some standard operations in the permission tab.
add_task(async function test_geo_permission() {
await testPermissions(SitePermissions.UNKNOWN);
});
// Test some standard operations in the permission tab, falling back to a custom
// default permission instead of UNKNOWN.
add_task(async function test_default_geo_permission() {
await SpecialPowers.pushPrefEnv({set: [["permissions.default.geo", SitePermissions.ALLOW]]});
await testPermissions(SitePermissions.ALLOW);
});
// Test special behavior for cookie permissions.
add_task(async function test_cookie_permission() {
await BrowserTestUtils.withNewTab(TEST_ORIGIN, async function(browser) {
let pageInfo = BrowserPageInfo(TEST_ORIGIN, "permTab");
await BrowserTestUtils.waitForEvent(pageInfo, "load");
let defaultCheckbox = await TestUtils.waitForCondition(() => pageInfo.document.getElementById("cookieDef"));
let radioGroup = pageInfo.document.getElementById("cookieRadioGroup");
let allowRadioButton = pageInfo.document.getElementById("cookie#1");
let blockRadioButton = pageInfo.document.getElementById("cookie#2");
ok(defaultCheckbox.checked, "The default checkbox should be checked.");
defaultCheckbox.checked = false;
defaultCheckbox.dispatchEvent(new Event("command"));
is(Services.perms.testPermission(gBrowser.currentURI, "cookie"), SitePermissions.ALLOW,
"Unchecking the default checkbox should pick the default permission.");
is(radioGroup.selectedItem, allowRadioButton,
"The unknown radio button should be selected.");
radioGroup.selectedItem = blockRadioButton;
blockRadioButton.dispatchEvent(new Event("command"));
is(Services.perms.testPermission(gBrowser.currentURI, "cookie"), SitePermissions.BLOCK,
"Selecting a value in the radio group should set the corresponding permission");
radioGroup.selectedItem = allowRadioButton;
allowRadioButton.dispatchEvent(new Event("command"));
is(Services.perms.testPermission(gBrowser.currentURI, "cookie"), SitePermissions.ALLOW,
"Selecting a value in the radio group should set the corresponding permission");
ok(!defaultCheckbox.checked, "The default checkbox should not be checked.");
defaultCheckbox.checked = true;
defaultCheckbox.dispatchEvent(new Event("command"));
is(Services.perms.testPermission(gBrowser.currentURI, "cookie"), SitePermissions.UNKNOWN,
"Checking the default checkbox should reset the permission.");
is(radioGroup.selectedItem, null, "For cookies, no item should be selected when the checkbox is checked.");
pageInfo.close();
SitePermissions.remove(gBrowser.currentURI, "cookie");
});
});

View File

@ -18,14 +18,17 @@ async function testNewTabPosition(expectedPosition, modifiers = {}) {
// Test that a tab opened from a pinned tab is not in the pinned region. // Test that a tab opened from a pinned tab is not in the pinned region.
add_task(async function test_pinned_content_click() { add_task(async function test_pinned_content_click() {
let testUri = "data:text/html;charset=utf-8,<a href=\"http://mochi.test:8888/\" target=\"_blank\" id=\"link\">link</a>"; let testUri = "data:text/html;charset=utf-8,<a href=\"http://mochi.test:8888/\" target=\"_blank\" id=\"link\">link</a>";
let tabs = [gBrowser.selectedTab, BrowserTestUtils.addTab(gBrowser, testUri), BrowserTestUtils.addTab(gBrowser)]; let tabs = [
gBrowser.selectedTab,
await BrowserTestUtils.openNewForegroundTab(gBrowser, testUri),
BrowserTestUtils.addTab(gBrowser),
];
gBrowser.pinTab(tabs[1]); gBrowser.pinTab(tabs[1]);
gBrowser.pinTab(tabs[2]); gBrowser.pinTab(tabs[2]);
// First test new active tabs open at the start of non-pinned tabstrip. // First test new active tabs open at the start of non-pinned tabstrip.
await BrowserTestUtils.switchTab(gBrowser, tabs[1]);
let newtab1 = await testNewTabPosition(2); let newtab1 = await testNewTabPosition(2);
// Switch back to our test tab.
await BrowserTestUtils.switchTab(gBrowser, tabs[1]); await BrowserTestUtils.switchTab(gBrowser, tabs[1]);
let newtab2 = await testNewTabPosition(2); let newtab2 = await testNewTabPosition(2);

View File

@ -178,12 +178,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
--> -->
<field name="handleEnterInstance">null</field> <field name="handleEnterInstance">null</field>
<!--
For performance reasons we want to limit the size of the text runs we
build and show to the user.
-->
<field name="textRunsMaxLen">255</field>
<!-- <!--
Since we never want scrollbars, we always use the maxResults value. Since we never want scrollbars, we always use the maxResults value.
--> -->
@ -1799,6 +1793,12 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
</content> </content>
<implementation> <implementation>
<!--
For performance reasons we want to limit the size of the text runs we
build and show to the user.
-->
<field name="textRunsMaxLen">255</field>
<field name="DOMWindowUtils"> <field name="DOMWindowUtils">
window.QueryInterface(Ci.nsIInterfaceRequestor) window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils); .getInterface(Ci.nsIDOMWindowUtils);

View File

@ -21,6 +21,10 @@ export default class AddressForm extends PaymentStateSubscriberMixin(HTMLElement
this.pageTitle = document.createElement("h1"); this.pageTitle = document.createElement("h1");
this.genericErrorText = document.createElement("div"); this.genericErrorText = document.createElement("div");
this.cancelButton = document.createElement("button");
this.cancelButton.id = "address-page-cancel-button";
this.cancelButton.addEventListener("click", this);
this.backButton = document.createElement("button"); this.backButton = document.createElement("button");
this.backButton.addEventListener("click", this); this.backButton.addEventListener("click", this);
@ -63,6 +67,7 @@ export default class AddressForm extends PaymentStateSubscriberMixin(HTMLElement
}); });
this.appendChild(this.genericErrorText); this.appendChild(this.genericErrorText);
this.appendChild(this.cancelButton);
this.appendChild(this.backButton); this.appendChild(this.backButton);
this.appendChild(this.saveButton); this.appendChild(this.saveButton);
// Only call the connected super callback(s) once our markup is fully // Only call the connected super callback(s) once our markup is fully
@ -72,6 +77,7 @@ export default class AddressForm extends PaymentStateSubscriberMixin(HTMLElement
} }
render(state) { render(state) {
this.cancelButton.textContent = this.dataset.cancelButtonLabel;
this.backButton.textContent = this.dataset.backButtonLabel; this.backButton.textContent = this.dataset.backButtonLabel;
this.saveButton.textContent = this.dataset.saveButtonLabel; this.saveButton.textContent = this.dataset.saveButtonLabel;
@ -81,6 +87,8 @@ export default class AddressForm extends PaymentStateSubscriberMixin(HTMLElement
savedAddresses, savedAddresses,
} = state; } = state;
this.backButton.hidden = page.onboardingWizard;
if (page.addressFields) { if (page.addressFields) {
this.setAttribute("address-fields", page.addressFields); this.setAttribute("address-fields", page.addressFields);
} else { } else {
@ -114,6 +122,10 @@ export default class AddressForm extends PaymentStateSubscriberMixin(HTMLElement
onClick(evt) { onClick(evt) {
switch (evt.target) { switch (evt.target) {
case this.cancelButton: {
paymentRequest.cancel();
break;
}
case this.backButton: { case this.backButton: {
this.requestStore.setState({ this.requestStore.setState({
page: { page: {
@ -142,6 +154,7 @@ export default class AddressForm extends PaymentStateSubscriberMixin(HTMLElement
errorStateChange: { errorStateChange: {
page: { page: {
id: "address-page", id: "address-page",
onboardingWizard: page.onboardingWizard,
error: this.dataset.errorGenericSave, error: this.dataset.errorGenericSave,
}, },
}, },

View File

@ -17,6 +17,8 @@ export let requestStore = new PaymentsStore({
orderDetailsShowing: false, orderDetailsShowing: false,
page: { page: {
id: "payment-summary", id: "payment-summary",
// onboardingWizard: true,
// error: "My error",
}, },
request: { request: {
tabId: null, tabId: null,

View File

@ -114,12 +114,25 @@ var paymentRequest = {
log.debug("onShowPaymentRequest: domReadyPromise resolved"); log.debug("onShowPaymentRequest: domReadyPromise resolved");
log.debug("onShowPaymentRequest, isPrivate?", detail.isPrivate); log.debug("onShowPaymentRequest, isPrivate?", detail.isPrivate);
document.querySelector("payment-dialog").setStateFromParent({
let state = {
request: detail.request, request: detail.request,
savedAddresses: detail.savedAddresses, savedAddresses: detail.savedAddresses,
savedBasicCards: detail.savedBasicCards, savedBasicCards: detail.savedBasicCards,
isPrivate: detail.isPrivate, isPrivate: detail.isPrivate,
}); page: {
id: "payment-summary",
},
};
if (Object.keys(detail.savedAddresses).length == 0) {
state.page = {
id: "address-page",
onboardingWizard: true,
};
}
document.querySelector("payment-dialog").setStateFromParent(state);
}, },
cancel() { cancel() {

View File

@ -43,6 +43,7 @@
<!ENTITY basicCardPage.saveButton.label "Save"> <!ENTITY basicCardPage.saveButton.label "Save">
<!ENTITY basicCardPage.persistCheckbox.label "Save credit card to Firefox (Security code will not be saved)"> <!ENTITY basicCardPage.persistCheckbox.label "Save credit card to Firefox (Security code will not be saved)">
<!ENTITY addressPage.error.genericSave "There was an error saving the address."> <!ENTITY addressPage.error.genericSave "There was an error saving the address.">
<!ENTITY addressPage.cancelButton.label "Cancel">
<!ENTITY addressPage.backButton.label "Back"> <!ENTITY addressPage.backButton.label "Back">
<!ENTITY addressPage.saveButton.label "Save"> <!ENTITY addressPage.saveButton.label "Save">
]> ]>
@ -143,6 +144,7 @@
<address-form id="address-page" <address-form id="address-page"
class="page" class="page"
data-error-generic-save="&addressPage.error.genericSave;" data-error-generic-save="&addressPage.error.genericSave;"
data-cancel-button-label="&addressPage.cancelButton.label;"
data-back-button-label="&addressPage.backButton.label;" data-back-button-label="&addressPage.backButton.label;"
data-save-button-label="&addressPage.saveButton.label;" data-save-button-label="&addressPage.saveButton.label;"
hidden="hidden"></address-form> hidden="hidden"></address-form>

View File

@ -10,6 +10,7 @@ support-files =
[browser_card_edit.js] [browser_card_edit.js]
[browser_change_shipping.js] [browser_change_shipping.js]
[browser_host_name.js] [browser_host_name.js]
[browser_payments_onboarding_wizard.js]
[browser_profile_storage.js] [browser_profile_storage.js]
[browser_request_serialization.js] [browser_request_serialization.js]
[browser_request_shipping.js] [browser_request_shipping.js]

View File

@ -0,0 +1,78 @@
"use strict";
add_task(async function test_onboarding_wizard_without_saved_addresses() {
await BrowserTestUtils.withNewTab({
gBrowser,
url: BLANK_PAGE_URL,
}, async browser => {
cleanupFormAutofillStorage();
info("Opening the payment dialog");
let {win, frame} =
await setupPaymentDialog(browser, {
methodData: [PTU.MethodData.basicCard],
details: PTU.Details.total60USD,
options: PTU.Options.requestShippingOption,
merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
});
info("Checking if the address page has been rendered");
await spawnPaymentDialogTask(frame, async function() {
let {
PaymentTestUtils: PTU,
} = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
await ContentTaskUtils.waitForCondition(() =>
content.document.getElementById("address-page-cancel-button"), "Address page is rendered");
await PTU.DialogContentUtils.waitForState(content, (state) => {
return state.page.id == "address-page";
}, "Address page is shown first if there are no saved addresses");
});
info("Closing the payment dialog");
spawnPaymentDialogTask(frame, async function() {
content.document.getElementById("address-page-cancel-button").click();
});
await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
});
});
add_task(async function test_onboarding_wizard_with_saved_addresses() {
await BrowserTestUtils.withNewTab({
gBrowser,
url: BLANK_PAGE_URL,
}, async browser => {
addSampleAddressesAndBasicCard();
info("Opening the payment dialog");
let {win, frame} =
await setupPaymentDialog(browser, {
methodData: [PTU.MethodData.basicCard],
details: PTU.Details.total60USD,
merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
});
info("Checking if the payment summary page is now visible");
await spawnPaymentDialogTask(frame, async function() {
let {
PaymentTestUtils: PTU,
} = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
await ContentTaskUtils.waitForCondition(() => content.document.getElementById("cancel"),
"Payment summary page is rendered");
await PTU.DialogContentUtils.waitForState(content, (state) => {
return state.page.id == "payment-summary";
}, "Payment summary page is shown when there are saved addresses");
});
info("Closing the payment dialog");
spawnPaymentDialogTask(frame, async function() {
content.document.getElementById("address-page-cancel-button").click();
});
await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
cleanupFormAutofillStorage();
});
});

View File

@ -1,18 +1,7 @@
"use strict"; "use strict";
add_task(async function setup() { add_task(async function setup() {
let onChanged = TestUtils.topicObserved("formautofill-storage-changed", await addSampleAddressesAndBasicCard();
(subject, data) => data == "add");
let card = {
"cc-exp-month": 1,
"cc-exp-year": 9999,
"cc-name": "John Doe",
"cc-number": "999999999999",
};
formAutofillStorage.creditCards.add(card);
await onChanged;
}); });
add_task(async function test_request_shipping_present() { add_task(async function test_request_shipping_present() {

View File

@ -136,6 +136,7 @@ add_task(async function test_saveButton() {
page: { page: {
id: "address-page", id: "address-page",
error: "Generic error", error: "Generic error",
onboardingWizard: undefined,
}, },
}, },
guid: undefined, guid: undefined,

View File

@ -5,7 +5,7 @@ Full Installer Configuration
Command-line Options Command-line Options
-------------------- --------------------
The full installer provides a number of options that can be used either from the GUI or from the command line. The following command line options are accepted. The full installer provides a number of options that can be used either from the GUI or from the command line. The following command line options are accepted. The list is valid for Firefox 62 and later. Prior to Firefox 62, only ``/S`` and ``/INI`` are accepted, and ``/StartMenuShortcut`` is not available in INI files, only the plural ``/StartMenuShortcuts`` works (even though only one shortcut is created).
The presence of **any** command-line option implicitly enables silent mode (see the ``/S`` option). The presence of **any** command-line option implicitly enables silent mode (see the ``/S`` option).

View File

@ -5,7 +5,7 @@ Installer Build
How to build the installers How to build the installers
--------------------------- ---------------------------
The easiest way to build an installer in your local tree is to run ``mach build installer``. The finished installers will be in ``$OBJDIR/dist/install/sea/``. You have to have a build of the application already done before that will work, but `artifact builds <https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Artifact_builds>`_ are supported, so that can save you a lot of time if you're only doing installer work. The easiest way to build an installer in your local tree is to run ``mach package``. The finished installers will be in ``$OBJDIR/dist/install/sea/``. You have to have a build of the application already done before that will work, but `artifact builds <https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Artifact_builds>`_ are supported, so that can save you a lot of time if you're only doing installer work.
You'll also need to be on a Windows machine; the installer build depends on tools that aren't available for other platforms. You'll also need to be on a Windows machine; the installer build depends on tools that aren't available for other platforms.
@ -33,9 +33,9 @@ Build process
Both the full and stub installers are built through a similar process, which is summarized here along with references to the relevant bits of code. Both the full and stub installers are built through a similar process, which is summarized here along with references to the relevant bits of code.
Most of this procedure is done in `makensis.mk <http://searchfox.org/mozilla-central/source/toolkit/mozapps/installer/windows/nsis/makensis.mk>`_. Most of this procedure is done in `makensis.mk <http://searchfox.org/mozilla-central/source/toolkit/mozapps/installer/windows/nsis/makensis.mk>`_ and in the `mach repackage <https://searchfox.org/mozilla-central/rev/2b9779c59390ecc47be7a70d99753653d8eb5afc/python/mozbuild/mozbuild/mach_commands.py#2166>`_ command.
0. The application has to be in a packaged state, so the equivalent of ``mach package`` is run. 0. A prerequisite is for the application to be in a packaged state, so ``mach package`` first creates a release-style package and puts it in ``$OBJDIR/dist/firefox``.
1. All required files are copied into the instgen directory. This includes .nsi and .nsh script files, plugin DLL files, image and icon files, and the 7-zip SFX module and its configuration files. 1. All required files are copied into the instgen directory. This includes .nsi and .nsh script files, plugin DLL files, image and icon files, and the 7-zip SFX module and its configuration files.
2. The NSIS scripts are compiled, resulting in setup.exe and setup-stub.exe (if building the stub is enabled). 2. The NSIS scripts are compiled, resulting in setup.exe and setup-stub.exe (if building the stub is enabled).
3. The 7-zip SFX module is run through UPX. 3. The 7-zip SFX module is run through UPX.

View File

@ -405,9 +405,14 @@ var SitePermissions = {
*/ */
set(uri, permissionID, state, scope = this.SCOPE_PERSISTENT, browser = null) { set(uri, permissionID, state, scope = this.SCOPE_PERSISTENT, browser = null) {
if (state == this.UNKNOWN || state == this.getDefault(permissionID)) { if (state == this.UNKNOWN || state == this.getDefault(permissionID)) {
// Because they are controlled by two prefs with many states that do not
// correspond to the classical ALLOW/DENY/PROMPT model, we want to always
// allow the user to add exceptions to their cookie rules without removing them.
if (permissionID != "cookie") {
this.remove(uri, permissionID, browser); this.remove(uri, permissionID, browser);
return; return;
} }
}
if (state == this.ALLOW_COOKIES_FOR_SESSION && permissionID != "cookie") { if (state == this.ALLOW_COOKIES_FOR_SESSION && permissionID != "cookie") {
throw "ALLOW_COOKIES_FOR_SESSION can only be set on the cookie permission"; throw "ALLOW_COOKIES_FOR_SESSION can only be set on the cookie permission";
@ -617,10 +622,10 @@ var gPermissionObject = {
"cookie": { "cookie": {
states: [ SitePermissions.ALLOW, SitePermissions.ALLOW_COOKIES_FOR_SESSION, SitePermissions.BLOCK ], states: [ SitePermissions.ALLOW, SitePermissions.ALLOW_COOKIES_FOR_SESSION, SitePermissions.BLOCK ],
getDefault() { getDefault() {
if (Services.prefs.getIntPref("network.cookie.cookieBehavior") == 2) if (Services.prefs.getIntPref("network.cookie.cookieBehavior") == Ci.nsICookieService.BEHAVIOR_REJECT)
return SitePermissions.BLOCK; return SitePermissions.BLOCK;
if (Services.prefs.getIntPref("network.cookie.lifetimePolicy") == 2) if (Services.prefs.getIntPref("network.cookie.lifetimePolicy") == Ci.nsICookieService.ACCEPT_SESSION)
return SitePermissions.ALLOW_COOKIES_FOR_SESSION; return SitePermissions.ALLOW_COOKIES_FOR_SESSION;
return SitePermissions.ALLOW; return SitePermissions.ALLOW;

View File

@ -29,6 +29,9 @@ endif
-include $(DEPTH)/.mozconfig.mk -include $(DEPTH)/.mozconfig.mk
# MDDEPDIR is the subdirectory where dependency files are stored
MDDEPDIR := .deps
ifndef EXTERNALLY_MANAGED_MAKE_FILE ifndef EXTERNALLY_MANAGED_MAKE_FILE
# Import the automatically generated backend file. If this file doesn't exist, # Import the automatically generated backend file. If this file doesn't exist,
# the backend hasn't been properly configured. We want this to be a fatal # the backend hasn't been properly configured. We want this to be a fatal
@ -413,9 +416,6 @@ ifdef MOZ_DEBUG
JAVAC_FLAGS += -g JAVAC_FLAGS += -g
endif endif
# MDDEPDIR is the subdirectory where dependency files are stored
MDDEPDIR := .deps
# $(call CHECK_SYMBOLS,lib,PREFIX,dep_name,test) # $(call CHECK_SYMBOLS,lib,PREFIX,dep_name,test)
# Checks that the given `lib` doesn't contain dependency on symbols with a # Checks that the given `lib` doesn't contain dependency on symbols with a
# version starting with `PREFIX`_ and matching the `test`. `dep_name` is only # version starting with `PREFIX`_ and matching the `test`. `dep_name` is only

View File

@ -101,9 +101,20 @@ $(TOPOBJDIR)/build/application.ini: $(TOPOBJDIR)/buildid.h $(TOPOBJDIR)/source-r
# The manifest of allowed system add-ons should be re-built when using # The manifest of allowed system add-ons should be re-built when using
# "build faster". # "build faster".
ifeq ($(MOZ_BUILD_APP),browser/app) #
# Note the dependency on install-dist/bin. The form of this
# dependency is critical: it's triggering the stem rule (install-%)
# above to force the dist/bin manifest to be processed. The more
# obvious `$(TOPOBJDIR)/install-dist_bin` doesn't work because
# dist/bin isn't in $(INSTALL_MANIFESTS) in the
# FasterMake+RecursiveMake (artifact build) situation.
ifeq ($(MOZ_BUILD_APP),browser)
$(TOPOBJDIR)/browser/app/features: install-dist/bin
default: $(TOPOBJDIR)/browser/app/features default: $(TOPOBJDIR)/browser/app/features
endif endif
ifeq ($(MOZ_BUILD_APP),mobile/android) ifeq ($(MOZ_BUILD_APP),mobile/android)
$(TOPOBJDIR)/mobile/android/base/features: install-dist/bin
default: $(TOPOBJDIR)/mobile/android/base/features default: $(TOPOBJDIR)/mobile/android/base/features
endif endif

View File

@ -11,6 +11,7 @@ const {
UPDATE_CUSTOM_INSTANCE, UPDATE_CUSTOM_INSTANCE,
UPDATE_EDITOR_VISIBILITY, UPDATE_EDITOR_VISIBILITY,
UPDATE_EDITOR_STATE, UPDATE_EDITOR_STATE,
UPDATE_PROPERTY_VALUE,
} = require("./index"); } = require("./index");
module.exports = { module.exports = {
@ -59,4 +60,12 @@ module.exports = {
}; };
}, },
updateFontProperty(property, value) {
return {
type: UPDATE_PROPERTY_VALUE,
property,
value,
};
},
}; };

View File

@ -32,4 +32,7 @@ createEnum([
// Update the preview text. // Update the preview text.
"UPDATE_PREVIEW_TEXT", "UPDATE_PREVIEW_TEXT",
// Update the value of a CSS font property
"UPDATE_PROPERTY_VALUE",
], module.exports); ], module.exports);

View File

@ -8,8 +8,11 @@ const { createFactory, PureComponent } = require("devtools/client/shared/vendor/
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const FontAxis = createFactory(require("./FontAxis"));
const FontMeta = createFactory(require("./FontMeta")); const FontMeta = createFactory(require("./FontMeta"));
const FontPropertyValue = createFactory(require("./FontPropertyValue"));
const FontSize = createFactory(require("./FontSize"));
const FontStyle = createFactory(require("./FontStyle"));
const FontWeight = createFactory(require("./FontWeight"));
const { getStr } = require("../utils/l10n"); const { getStr } = require("../utils/l10n");
const Types = require("../types"); const Types = require("../types");
@ -18,8 +21,8 @@ class FontEditor extends PureComponent {
static get propTypes() { static get propTypes() {
return { return {
fontEditor: PropTypes.shape(Types.fontEditor).isRequired, fontEditor: PropTypes.shape(Types.fontEditor).isRequired,
onAxisUpdate: PropTypes.func.isRequired,
onInstanceChange: PropTypes.func.isRequired, onInstanceChange: PropTypes.func.isRequired,
onPropertyChange: PropTypes.func.isRequired,
}; };
} }
@ -50,7 +53,7 @@ class FontEditor extends PureComponent {
} }
/** /**
* Get an array of FontAxis components for of the given variable font axis instances. * Get an array of FontPropertyValue components for of the given variable font axes.
* If an axis is defined in the fontEditor store, use its value, else use the default. * If an axis is defined in the fontEditor store, use its value, else use the default.
* *
* @param {Array} fontAxes * @param {Array} fontAxes
@ -59,19 +62,19 @@ class FontEditor extends PureComponent {
* Object with axes and values edited by the user or predefined in the CSS * Object with axes and values edited by the user or predefined in the CSS
* declaration for font-variation-settings. * declaration for font-variation-settings.
* @return {Array} * @return {Array}
* Array of FontAxis components * Array of FontPropertyValue components
*/ */
renderAxes(fontAxes = [], editedAxes) { renderAxes(fontAxes = [], editedAxes) {
return fontAxes.map(axis => { return fontAxes.map(axis => {
return FontAxis({ return FontPropertyValue({
min: axis.minValue, min: axis.minValue,
max: axis.maxValue, max: axis.maxValue,
value: editedAxes[axis.tag] || axis.defaultValue, value: editedAxes[axis.tag] || axis.defaultValue,
step: this.getAxisStep(axis.minValue, axis.maxValue), step: this.getAxisStep(axis.minValue, axis.maxValue),
label: axis.name, label: axis.name,
name: axis.tag, name: axis.tag,
onChange: this.props.onAxisUpdate, onChange: this.props.onPropertyChange,
showInput: true unit: null
}); });
}); });
} }
@ -96,6 +99,27 @@ class FontEditor extends PureComponent {
); );
} }
renderFontSize(value) {
return FontSize({
onChange: this.props.onPropertyChange,
value,
});
}
renderFontStyle(value) {
return FontStyle({
onChange: this.props.onPropertyChange,
value,
});
}
renderFontWeight(value) {
return FontWeight({
onChange: this.props.onPropertyChange,
value,
});
}
/** /**
* Get a dropdown which allows selecting between variation instances defined by a font. * Get a dropdown which allows selecting between variation instances defined by a font.
* *
@ -155,34 +179,37 @@ class FontEditor extends PureComponent {
); );
} }
// Placeholder for non-variable font UI.
// Bug https://bugzilla.mozilla.org/show_bug.cgi?id=1450695
renderPlaceholder() {
return dom.div({}, "No fonts with variation axes apply to this element.");
}
render() { render() {
const { fonts, axes, instance } = this.props.fontEditor; const { fonts, axes, instance, properties } = this.props.fontEditor;
// For MVP use ony first font to show axes if available. // For MVP use ony first font to show axes if available.
// Future implementations will allow switching between multiple fonts. // Future implementations will allow switching between multiple fonts.
const font = fonts[0]; const font = fonts[0];
const fontAxes = (font && font.variationAxes) ? font.variationAxes : null; const hasFontAxes = font && font.variationAxes;
const fontInstances = (font && font.variationInstances.length) ? const hasFontInstances = font && font.variationInstances.length > 0;
font.variationInstances const hasSlantOrItalicAxis = hasFontAxes && font.variationAxes.find(axis => {
: return axis.tag === "slnt" || axis.tag === "ital";
null; });
const hasWeightAxis = hasFontAxes && font.variationAxes.find(axis => {
return axis.tag === "wght";
});
return dom.div( return dom.div(
{ {
className: "theme-sidebar inspector-tabpanel", className: "theme-sidebar inspector-tabpanel",
id: "sidebar-panel-fontinspector" id: "sidebar-panel-fontinspector"
}, },
// Always render UI for font family, format and font file URL.
this.renderFontFamily(font), this.renderFontFamily(font),
fontInstances && this.renderInstances(fontInstances, instance), // Render UI for font variation instances if they are defined.
fontAxes ? hasFontInstances && this.renderInstances(font.variationInstances, instance),
this.renderAxes(fontAxes, axes) // Always render UI for font size.
: this.renderFontSize(properties["font-size"]),
this.renderPlaceholder() // Render UI for font weight if no "wght" registered axis is defined.
!hasWeightAxis && this.renderFontWeight(properties["font-weight"]),
// Render UI for font style if no "slnt" or "ital" registered axis is defined.
!hasSlantOrItalicAxis && this.renderFontStyle(properties["font-style"]),
// Render UI for each variable font axis if any are defined.
hasFontAxes && this.renderAxes(font.variationAxes, axes)
); );
} }
} }

View File

@ -8,7 +8,9 @@ const { PureComponent } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
class FontAxis extends PureComponent { const UNITS = ["px", "%", "em", "rem", "vh", "vw", "pt"];
class FontPropertyValue extends PureComponent {
static get propTypes() { static get propTypes() {
return { return {
defaultValue: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]), defaultValue: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
@ -17,9 +19,10 @@ class FontAxis extends PureComponent {
max: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]), max: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
showInput: PropTypes.bool, showUnit: PropTypes.bool,
step: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]), step: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
value: PropTypes.string, unit: PropTypes.oneOfType([ PropTypes.string, null ]),
value: PropTypes.number,
}; };
} }
@ -27,10 +30,17 @@ class FontAxis extends PureComponent {
super(props); super(props);
this.onChange = this.onChange.bind(this); this.onChange = this.onChange.bind(this);
this.onUnitChange = this.onUnitChange.bind(this);
} }
onChange(e) { onChange(e) {
this.props.onChange(this.props.name, e.target.value); this.props.onChange(this.props.name, e.target.value, this.props.unit);
}
onUnitChange(e) {
// TODO implement conversion.
// Bug 1459898: https://bugzilla.mozilla.org/show_bug.cgi?id=1459898
this.props.onChange(this.props.name, this.props.value, e.target.value);
} }
render() { render() {
@ -45,7 +55,7 @@ class FontAxis extends PureComponent {
const range = dom.input( const range = dom.input(
{ {
...defaults, ...defaults,
className: "font-axis-slider", className: "font-value-slider",
title: this.props.label, title: this.props.label,
type: "range", type: "range",
} }
@ -54,11 +64,37 @@ class FontAxis extends PureComponent {
const input = dom.input( const input = dom.input(
{ {
...defaults, ...defaults,
className: "font-axis-input", className: "font-value-input",
type: "number", type: "number",
} }
); );
let unitDropdown = null;
if (this.props.showUnit) {
// Ensure the dropdown has the current unit type even if we don't recognize it.
// The unit conversion function will use a 1-to-1 scale for unrecognized units.
const options = UNITS.includes(this.props.unit) ?
UNITS
:
UNITS.concat([this.props.unit]);
unitDropdown = dom.select(
{
className: "font-unit-select",
onChange: this.onUnitChange,
},
options.map(unit => {
return dom.option(
{
selected: unit === this.props.unit,
value: unit,
},
unit
);
})
);
}
return dom.label( return dom.label(
{ {
className: "font-control", className: "font-control",
@ -74,10 +110,11 @@ class FontAxis extends PureComponent {
className: "font-control-input" className: "font-control-input"
}, },
range, range,
this.props.showInput ? input : null input,
this.props.showUnit && unitDropdown
) )
); );
} }
} }
module.exports = FontAxis; module.exports = FontPropertyValue;

View File

@ -0,0 +1,59 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const FontPropertyValue = createFactory(require("./FontPropertyValue"));
const { getStr } = require("../utils/l10n");
const { getUnitFromValue, getStepForUnit } = require("../utils/font-utils");
class FontSize extends PureComponent {
static get propTypes() {
return {
onChange: PropTypes.func.isRequired,
value: PropTypes.string.isRequired,
};
}
render() {
const unit = getUnitFromValue(this.props.value);
let max;
switch (unit) {
case "em":
case "rem":
max = 10;
break;
case "vh":
case "vw":
case "vmin":
case "vmax":
max = 100;
break;
case "%":
max = 500;
break;
default:
max = 300;
break;
}
return FontPropertyValue({
label: getStr("fontinspector.fontSizeLabel"),
min: 0,
max,
name: "font-size",
onChange: this.props.onChange,
showUnit: true,
step: getStepForUnit(unit),
unit,
value: parseFloat(this.props.value),
});
}
}
module.exports = FontSize;

View File

@ -0,0 +1,57 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { PureComponent } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { getStr } = require("../utils/l10n");
class FontStyle extends PureComponent {
static get propTypes() {
return {
onChange: PropTypes.func.isRequired,
value: PropTypes.string.isRequired,
};
}
constructor(props) {
super(props);
this.onToggle = this.onToggle.bind(this);
}
onToggle(e) {
this.props.onChange("font-style", e.target.checked ? "italic" : "normal", null);
}
render() {
return dom.label(
{
className: "font-control",
},
dom.span(
{
className: "font-control-label",
},
getStr("fontinspector.fontItalicLabel")
),
dom.div(
{
className: "font-control-input"
},
dom.input(
{
checked: this.props.value === "italic" || this.props.value === "oblique",
onChange: this.onToggle,
type: "checkbox",
}
)
)
);
}
}
module.exports = FontStyle;

View File

@ -0,0 +1,36 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const FontPropertyValue = createFactory(require("./FontPropertyValue"));
const { getStr } = require("../utils/l10n");
class FontWeight extends PureComponent {
static get propTypes() {
return {
onChange: PropTypes.func.isRequired,
value: PropTypes.string.isRequired,
};
}
render() {
return FontPropertyValue({
label: getStr("fontinspector.fontWeightLabel"),
min: 100,
max: 900,
name: "font-weight",
onChange: this.props.onChange,
step: 100,
unit: null,
value: parseFloat(this.props.value),
});
}
}
module.exports = FontWeight;

View File

@ -20,9 +20,9 @@ class FontsApp extends PureComponent {
fontData: PropTypes.shape(Types.fontData).isRequired, fontData: PropTypes.shape(Types.fontData).isRequired,
fontEditor: PropTypes.shape(Types.fontEditor).isRequired, fontEditor: PropTypes.shape(Types.fontEditor).isRequired,
fontOptions: PropTypes.shape(Types.fontOptions).isRequired, fontOptions: PropTypes.shape(Types.fontOptions).isRequired,
onAxisUpdate: PropTypes.func.isRequired,
onInstanceChange: PropTypes.func.isRequired, onInstanceChange: PropTypes.func.isRequired,
onPreviewFonts: PropTypes.func.isRequired, onPreviewFonts: PropTypes.func.isRequired,
onPropertyChange: PropTypes.func.isRequired,
onToggleFontHighlight: PropTypes.func.isRequired, onToggleFontHighlight: PropTypes.func.isRequired,
}; };
} }
@ -32,9 +32,9 @@ class FontsApp extends PureComponent {
fontData, fontData,
fontEditor, fontEditor,
fontOptions, fontOptions,
onAxisUpdate,
onInstanceChange, onInstanceChange,
onPreviewFonts, onPreviewFonts,
onPropertyChange,
onToggleFontHighlight, onToggleFontHighlight,
} = this.props; } = this.props;
@ -46,8 +46,8 @@ class FontsApp extends PureComponent {
fontEditor.isVisible ? fontEditor.isVisible ?
FontEditor({ FontEditor({
fontEditor, fontEditor,
onAxisUpdate,
onInstanceChange, onInstanceChange,
onPropertyChange,
}) })
: :
FontOverview({ FontOverview({

View File

@ -6,11 +6,14 @@
DevToolsModules( DevToolsModules(
'Font.js', 'Font.js',
'FontAxis.js',
'FontEditor.js', 'FontEditor.js',
'FontList.js', 'FontList.js',
'FontMeta.js', 'FontMeta.js',
'FontOverview.js', 'FontOverview.js',
'FontPreview.js', 'FontPreview.js',
'FontPropertyValue.js',
'FontsApp.js', 'FontsApp.js',
'FontSize.js',
'FontStyle.js',
'FontWeight.js',
) )

View File

@ -28,6 +28,7 @@ const {
updateAxis, updateAxis,
updateCustomInstance, updateCustomInstance,
updateFontEditor, updateFontEditor,
updateFontProperty,
} = require("./actions/font-editor"); } = require("./actions/font-editor");
const { updatePreviewText } = require("./actions/font-options"); const { updatePreviewText } = require("./actions/font-options");
@ -69,10 +70,10 @@ class FontInspector {
this.snapshotChanges = debounce(this.snapshotChanges, 100, this); this.snapshotChanges = debounce(this.snapshotChanges, 100, this);
this.syncChanges = throttle(this.syncChanges, 100, this); this.syncChanges = throttle(this.syncChanges, 100, this);
this.onAxisUpdate = this.onAxisUpdate.bind(this);
this.onInstanceChange = this.onInstanceChange.bind(this); this.onInstanceChange = this.onInstanceChange.bind(this);
this.onNewNode = this.onNewNode.bind(this); this.onNewNode = this.onNewNode.bind(this);
this.onPreviewFonts = this.onPreviewFonts.bind(this); this.onPreviewFonts = this.onPreviewFonts.bind(this);
this.onPropertyChange = this.onPropertyChange.bind(this);
this.onRuleSelected = this.onRuleSelected.bind(this); this.onRuleSelected = this.onRuleSelected.bind(this);
this.onToggleFontHighlight = this.onToggleFontHighlight.bind(this); this.onToggleFontHighlight = this.onToggleFontHighlight.bind(this);
this.onRuleUnselected = this.onRuleUnselected.bind(this); this.onRuleUnselected = this.onRuleUnselected.bind(this);
@ -90,10 +91,10 @@ class FontInspector {
} }
let fontsApp = FontsApp({ let fontsApp = FontsApp({
onAxisUpdate: this.onAxisUpdate,
onInstanceChange: this.onInstanceChange, onInstanceChange: this.onInstanceChange,
onToggleFontHighlight: this.onToggleFontHighlight, onToggleFontHighlight: this.onToggleFontHighlight,
onPreviewFonts: this.onPreviewFonts, onPreviewFonts: this.onPreviewFonts,
onPropertyChange: this.onPropertyChange,
}); });
let provider = createElement(Provider, { let provider = createElement(Provider, {
@ -346,7 +347,7 @@ class FontInspector {
this.writers.set(name, this.getWriterForAxis(name)); this.writers.set(name, this.getWriterForAxis(name));
} else if (FONT_PROPERTIES.includes(name)) { } else if (FONT_PROPERTIES.includes(name)) {
this.writers.set(name, (value) => { this.writers.set(name, (value) => {
this.updateFontProperty(name, value); this.updatePropertyValue(name, value);
}); });
} else { } else {
this.writers.set(name, this.updateFontVariationSettings); this.writers.set(name, this.updateFontVariationSettings);
@ -380,8 +381,7 @@ class FontInspector {
} }
/** /**
* Handler for changes of font axis value. Updates the value in the store and previews * Handler for changes of a font axis value coming from the FontEditor.
* the change on the page.
* *
* @param {String} tag * @param {String} tag
* Tag name of the font axis. * Tag name of the font axis.
@ -397,6 +397,23 @@ class FontInspector {
writer(value); writer(value);
} }
/**
* Handler for changes of a CSS font property value coming from the FontEditor.
*
* @param {String} property
* CSS font property name.
* @param {String} value
* CSS font property numeric value.
* @param {String|null} unit
* CSS unit or null
*/
onFontPropertyUpdate(property, value, unit) {
value = (unit !== null) ? value + unit : value;
this.store.dispatch(updateFontProperty(property, value));
const writer = this.getWriterForProperty(property);
writer(value);
}
/** /**
* Handler for selecting a font variation instance. Dispatches an action which updates * Handler for selecting a font variation instance. Dispatches an action which updates
* the axes and their values as defined by that variation instance. * the axes and their values as defined by that variation instance.
@ -432,6 +449,29 @@ class FontInspector {
this.update(); this.update();
} }
/**
* Handler for changes to any CSS font property value or variable font axis value coming
* from the Font Editor. This handler calls the appropriate method to preview the
* changes on the page and update the store.
*
* If the property parameter is not a recognized CSS font property name, assume it's a
* variable font axis name.
*
* @param {String} property
* CSS font property name or axis name
* @param {String} value
* CSS font property numeric value or axis value
* @param {String|null} unit
* CSS unit or null
*/
onPropertyChange(property, value, unit) {
if (FONT_PROPERTIES.includes(property)) {
this.onFontPropertyUpdate(property, value, unit);
} else {
this.onAxisUpdate(property, value);
}
}
/** /**
* Handler for "ruleview-rule-selected" event emitted from the rule view when a rule is * Handler for "ruleview-rule-selected" event emitted from the rule view when a rule is
* marked as selected for an editor. * marked as selected for an editor.

View File

@ -13,6 +13,7 @@ const {
UPDATE_CUSTOM_INSTANCE, UPDATE_CUSTOM_INSTANCE,
UPDATE_EDITOR_STATE, UPDATE_EDITOR_STATE,
UPDATE_EDITOR_VISIBILITY, UPDATE_EDITOR_VISIBILITY,
UPDATE_PROPERTY_VALUE,
} = require("../actions/index"); } = require("../actions/index");
const INITIAL_STATE = { const INITIAL_STATE = {
@ -115,6 +116,12 @@ let reducers = {
return { ...state, isVisible, selector }; return { ...state, isVisible, selector };
}, },
[UPDATE_PROPERTY_VALUE](state, { property, value }) {
let newState = { ...state };
newState.properties[property] = value;
return newState;
}
}; };
module.exports = function(state = INITIAL_STATE, action) { module.exports = function(state = INITIAL_STATE, action) {

View File

@ -0,0 +1,43 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
module.exports = {
/**
* Given a CSS unit type, get the amount by which to increment a numeric value.
* Used as the step attribute in inputs of type "range" or "number".
*
* @param {String} unit
* CSS unit type (px, %, em, rem, vh, vw, ...)
* @return {Number}
* Amount by which to increment.
*/
getStepForUnit(unit) {
let step = 1;
if (unit === "em" || unit === "rem") {
step = 0.1;
}
return step;
},
/**
* Get the unit type from the end of a CSS value string.
* Returns null for non-string input or unitless values.
*
* @param {String} value
* CSS value string.
* @return {String|null}
* CSS unit type, like "px", "em", "rem", etc or null.
*/
getUnitFromValue(value) {
if (typeof value !== "string") {
return null;
}
const match = value.match(/\D+?$/);
return match && match.length ? match[0] : null;
},
};

View File

@ -5,5 +5,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules( DevToolsModules(
'font-utils.js',
'l10n.js', 'l10n.js',
) )

View File

@ -43,3 +43,15 @@ fontinspector.fontFamilyLabel=Family
# dropdown. An instance is like a preset. A "font instance" is the term used by the font # dropdown. An instance is like a preset. A "font instance" is the term used by the font
# authors to mean a group of predefined font settings. # authors to mean a group of predefined font settings.
fontinspector.fontInstanceLabel=Instance fontinspector.fontInstanceLabel=Instance
# LOCALIZATION NOTE (fontinspector.fontSizeLabel): This label is shown next to the UI
# in the font editor which allows the user to change the font size.
fontinspector.fontSizeLabel=Size
# LOCALIZATION NOTE (fontinspector.fontWeightLabel): This label is shown next to the UI
# in the font editor which allows the user to change the font weight.
fontinspector.fontWeightLabel=Weight
# LOCALIZATION NOTE (fontinspector.fontItalicLabel): This label is shown next to the UI
# in the font editor which allows the user to change the style of the font to italic.
fontinspector.fontItalicLabel=Italic

View File

@ -292,8 +292,12 @@ pref("devtools.webconsole.timestampMessages", false);
// to automatically trigger multiline editing (equivalent to shift + enter). // to automatically trigger multiline editing (equivalent to shift + enter).
pref("devtools.webconsole.autoMultiline", true); pref("devtools.webconsole.autoMultiline", true);
// Enable the webconsole sidebar toggle // Enable the webconsole sidebar toggle in Nightly builds.
#if defined(NIGHTLY_BUILD)
pref("devtools.webconsole.sidebarToggle", true);
#else
pref("devtools.webconsole.sidebarToggle", false); pref("devtools.webconsole.sidebarToggle", false);
#endif
// Disable the new performance recording panel by default // Disable the new performance recording panel by default
pref("devtools.performance.new-panel-enabled", false); pref("devtools.performance.new-panel-enabled", false);

View File

@ -142,36 +142,41 @@
font-size: 12px; font-size: 12px;
min-width: 80px; min-width: 80px;
margin-right: 10px; margin-right: 10px;
} -moz-user-select: none;
.font-axis-input {
margin-left: 10px;
width: 60px;
}
.font-axis-slider {
flex: 1;
margin: 0;
min-width: 50px;
} }
.font-instance-select:active{ .font-instance-select:active{
outline: none; outline: none;
} }
.font-axis-slider::-moz-focus-outer { .font-value-input {
margin-left: 10px;
width: 60px;
}
.font-value-slider {
flex: 1;
margin: 0;
min-width: 50px;
}
.font-value-slider:-moz-focusring {
outline: none;
}
.font-value-slider::-moz-focus-outer {
border: 0; border: 0;
} }
.font-axis-slider::-moz-range-thumb { .font-value-slider::-moz-range-thumb {
background: var(--grey-50); background: var(--grey-50);
border-color: rgba(0, 0, 0, 0); border-color: rgba(0, 0, 0, 0);
} }
.font-axis-slider::-moz-range-track { .font-value-slider::-moz-range-track {
background: var(--grey-30); background: var(--grey-30);
} }
.font-axis-slider:focus::-moz-range-thumb { .font-value-slider:focus::-moz-range-thumb {
background: var(--blue-55); background: var(--blue-55);
} }

View File

@ -26,14 +26,14 @@ add_task(async function() {
let menuPopup = await openContextMenu(hud, networkMessage.node); let menuPopup = await openContextMenu(hud, networkMessage.node);
ok(menuPopup, "The context menu is displayed on a network message"); ok(menuPopup, "The context menu is displayed on a network message");
let expectedContextMenu = [ let expectedContextMenu = addPrefBasedEntries([
"#console-menu-copy-url (a)", "#console-menu-copy-url (a)",
"#console-menu-open-url (T)", "#console-menu-open-url (T)",
"#console-menu-store (S) [disabled]", "#console-menu-store (S) [disabled]",
"#console-menu-copy (C)", "#console-menu-copy (C)",
"#console-menu-copy-object (o) [disabled]", "#console-menu-copy-object (o) [disabled]",
"#console-menu-select (A)" "#console-menu-select (A)",
]; ]);
is(getSimplifiedContextMenu(menuPopup).join("\n"), expectedContextMenu.join("\n"), is(getSimplifiedContextMenu(menuPopup).join("\n"), expectedContextMenu.join("\n"),
"The context menu has the expected entries for a network message"); "The context menu has the expected entries for a network message");
@ -47,18 +47,26 @@ add_task(async function() {
menuPopup = await openContextMenu(hud, logMessage.node); menuPopup = await openContextMenu(hud, logMessage.node);
ok(menuPopup, "The context menu is displayed on a log message"); ok(menuPopup, "The context menu is displayed on a log message");
expectedContextMenu = [ expectedContextMenu = addPrefBasedEntries([
"#console-menu-store (S) [disabled]", "#console-menu-store (S) [disabled]",
"#console-menu-copy (C)", "#console-menu-copy (C)",
"#console-menu-copy-object (o) [disabled]", "#console-menu-copy-object (o) [disabled]",
"#console-menu-select (A)" "#console-menu-select (A)",
]; ]);
is(getSimplifiedContextMenu(menuPopup).join("\n"), expectedContextMenu.join("\n"), is(getSimplifiedContextMenu(menuPopup).join("\n"), expectedContextMenu.join("\n"),
"The context menu has the expected entries for a simple log message"); "The context menu has the expected entries for a simple log message");
await hideContextMenu(hud); await hideContextMenu(hud);
}); });
function addPrefBasedEntries(expectedEntries) {
if (Services.prefs.getBoolPref("devtools.webconsole.sidebarToggle", false)) {
expectedEntries.push("#console-menu-open-sidebar (V) [disabled]");
}
return expectedEntries;
}
function getSimplifiedContextMenu(popupElement) { function getSimplifiedContextMenu(popupElement) {
return [...popupElement.querySelectorAll("menuitem")] return [...popupElement.querySelectorAll("menuitem")]
.map(entry => { .map(entry => {

View File

@ -266,7 +266,7 @@ CharacterData::SetTextInternal(uint32_t aOffset, uint32_t aCount,
} }
nsIDocument *document = GetComposedDoc(); nsIDocument *document = GetComposedDoc();
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify); mozAutoDocUpdate updateBatch(document, aNotify);
bool haveMutationListeners = aNotify && bool haveMutationListeners = aNotify &&
nsContentUtils::HasMutationListeners(this, nsContentUtils::HasMutationListeners(this,

View File

@ -34,6 +34,35 @@ DocumentOrShadowRoot::EnsureDOMStyleSheets()
return *mDOMStyleSheets; return *mDOMStyleSheets;
} }
void
DocumentOrShadowRoot::AppendSheet(StyleSheet& aSheet)
{
aSheet.SetAssociatedDocumentOrShadowRoot(
this, StyleSheet::OwnedByDocumentOrShadowRoot);
mStyleSheets.AppendElement(&aSheet);
}
void
DocumentOrShadowRoot::InsertSheetAt(size_t aIndex, StyleSheet& aSheet)
{
aSheet.SetAssociatedDocumentOrShadowRoot(
this, StyleSheet::OwnedByDocumentOrShadowRoot);
mStyleSheets.InsertElementAt(aIndex, &aSheet);
}
already_AddRefed<StyleSheet>
DocumentOrShadowRoot::RemoveSheet(StyleSheet& aSheet)
{
auto index = mStyleSheets.IndexOf(&aSheet);
if (index == mStyleSheets.NoIndex) {
return nullptr;
}
RefPtr<StyleSheet> sheet = Move(mStyleSheets[index]);
mStyleSheets.RemoveElementAt(index);
sheet->ClearAssociatedDocumentOrShadowRoot();
return sheet.forget();
}
Element* Element*
DocumentOrShadowRoot::GetElementById(const nsAString& aElementId) DocumentOrShadowRoot::GetElementById(const nsAString& aElementId)
{ {

View File

@ -7,6 +7,8 @@
#ifndef mozilla_dom_DocumentOrShadowRoot_h__ #ifndef mozilla_dom_DocumentOrShadowRoot_h__
#define mozilla_dom_DocumentOrShadowRoot_h__ #define mozilla_dom_DocumentOrShadowRoot_h__
#include "mozilla/dom/NameSpaceConstants.h"
#include "nsContentListDeclarations.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "nsIdentifierMapEntry.h" #include "nsIdentifierMapEntry.h"
@ -65,21 +67,6 @@ public:
return mStyleSheets.IndexOf(&aSheet); return mStyleSheets.IndexOf(&aSheet);
} }
void InsertSheetAt(size_t aIndex, StyleSheet& aSheet)
{
mStyleSheets.InsertElementAt(aIndex, &aSheet);
}
void RemoveSheet(StyleSheet& aSheet)
{
mStyleSheets.RemoveElement(&aSheet);
}
void AppendStyleSheet(StyleSheet& aSheet)
{
mStyleSheets.AppendElement(&aSheet);
}
StyleSheetList& EnsureDOMStyleSheets(); StyleSheetList& EnsureDOMStyleSheets();
Element* GetElementById(const nsAString& aElementId); Element* GetElementById(const nsAString& aElementId);
@ -188,6 +175,11 @@ public:
void ReportEmptyGetElementByIdArg(); void ReportEmptyGetElementByIdArg();
protected: protected:
// Returns the reference to the sheet, if found in mStyleSheets.
already_AddRefed<StyleSheet> RemoveSheet(StyleSheet& aSheet);
void AppendSheet(StyleSheet& aSheet);
void InsertSheetAt(size_t aIndex, StyleSheet& aSheet);
nsIContent* Retarget(nsIContent* aContent) const; nsIContent* Retarget(nsIContent* aContent) const;
/** /**

View File

@ -2455,7 +2455,7 @@ Element::SetSingleClassFromParser(nsAtom* aSingleClassName)
nsAttrValue value(aSingleClassName); nsAttrValue value(aSingleClassName);
nsIDocument* document = GetComposedDoc(); nsIDocument* document = GetComposedDoc();
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, false); mozAutoDocUpdate updateBatch(document, false);
// In principle, BeforeSetAttr should be called here if a node type // In principle, BeforeSetAttr should be called here if a node type
// existed that wanted to do something special for class, but there // existed that wanted to do something special for class, but there
@ -2525,7 +2525,7 @@ Element::SetAttr(int32_t aNamespaceID, nsAtom* aName,
// Hold a script blocker while calling ParseAttribute since that can call // Hold a script blocker while calling ParseAttribute since that can call
// out to id-observers // out to id-observers
nsIDocument* document = GetComposedDoc(); nsIDocument* document = GetComposedDoc();
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify); mozAutoDocUpdate updateBatch(document, aNotify);
nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify); nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -2583,7 +2583,7 @@ Element::SetParsedAttr(int32_t aNamespaceID, nsAtom* aName,
PreIdMaybeChange(aNamespaceID, aName, &value); PreIdMaybeChange(aNamespaceID, aName, &value);
nsIDocument* document = GetComposedDoc(); nsIDocument* document = GetComposedDoc();
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify); mozAutoDocUpdate updateBatch(document, aNotify);
return SetAttrAndNotify(aNamespaceID, aName, aPrefix, return SetAttrAndNotify(aNamespaceID, aName, aPrefix,
oldValueSet ? &oldValue : nullptr, oldValueSet ? &oldValue : nullptr,
aParsedValue, nullptr, modType, hasListeners, aNotify, aParsedValue, nullptr, modType, hasListeners, aNotify,
@ -2915,7 +2915,7 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsAtom* aName,
} }
nsIDocument *document = GetComposedDoc(); nsIDocument *document = GetComposedDoc();
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify); mozAutoDocUpdate updateBatch(document, aNotify);
if (aNotify) { if (aNotify) {
nsNodeUtils::AttributeWillChange(this, aNameSpaceID, aName, nsNodeUtils::AttributeWillChange(this, aNameSpaceID, aName,
@ -3916,7 +3916,7 @@ Element::InsertAdjacentHTML(const nsAString& aPosition, const nsAString& aText,
nsIDocument* doc = OwnerDoc(); nsIDocument* doc = OwnerDoc();
// Needed when insertAdjacentHTML is used in combination with contenteditable // Needed when insertAdjacentHTML is used in combination with contenteditable
mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, true); mozAutoDocUpdate updateBatch(doc, true);
nsAutoScriptLoaderDisabler sld(doc); nsAutoScriptLoaderDisabler sld(doc);
// Batch possible DOMSubtreeModified events. // Batch possible DOMSubtreeModified events.

View File

@ -2279,7 +2279,7 @@ FragmentOrElement::SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult
target->FireNodeRemovedForChildren(); target->FireNodeRemovedForChildren();
// Needed when innerHTML is used in combination with contenteditable // Needed when innerHTML is used in combination with contenteditable
mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, true); mozAutoDocUpdate updateBatch(doc, true);
// Remove childnodes. // Remove childnodes.
nsAutoMutationBatch mb(target, true, false); nsAutoMutationBatch mb(target, true, false);

View File

@ -132,7 +132,7 @@ ShadowRoot::CloneInternalDataFrom(ShadowRoot* aOther)
StyleSheet* sheet = aOther->SheetAt(i); StyleSheet* sheet = aOther->SheetAt(i);
if (sheet->IsApplicable()) { if (sheet->IsApplicable()) {
RefPtr<StyleSheet> clonedSheet = RefPtr<StyleSheet> clonedSheet =
sheet->Clone(nullptr, nullptr, nullptr, nullptr); sheet->Clone(nullptr, nullptr, this, nullptr);
if (clonedSheet) { if (clonedSheet) {
AppendStyleSheet(*clonedSheet.get()); AppendStyleSheet(*clonedSheet.get());
} }
@ -308,9 +308,7 @@ ShadowRoot::ApplicableRulesChanged()
nsIDocument* doc = OwnerDoc(); nsIDocument* doc = OwnerDoc();
if (nsIPresShell* shell = doc->GetShell()) { if (nsIPresShell* shell = doc->GetShell()) {
doc->BeginUpdate(UPDATE_STYLE);
shell->RecordShadowStyleChange(*this); shell->RecordShadowStyleChange(*this);
doc->EndUpdate(UPDATE_STYLE);
} }
} }
@ -326,7 +324,7 @@ ShadowRoot::InsertSheetAt(size_t aIndex, StyleSheet& aSheet)
void void
ShadowRoot::AppendStyleSheet(StyleSheet& aSheet) ShadowRoot::AppendStyleSheet(StyleSheet& aSheet)
{ {
DocumentOrShadowRoot::AppendStyleSheet(aSheet); DocumentOrShadowRoot::AppendSheet(aSheet);
if (aSheet.IsApplicable()) { if (aSheet.IsApplicable()) {
Servo_AuthorStyles_AppendStyleSheet(mServoStyles.get(), &aSheet); Servo_AuthorStyles_AppendStyleSheet(mServoStyles.get(), &aSheet);
if (mStyleRuleMap) { if (mStyleRuleMap) {
@ -391,6 +389,8 @@ ShadowRoot::InsertSheetIntoAuthorData(size_t aIndex, StyleSheet& aSheet)
ApplicableRulesChanged(); ApplicableRulesChanged();
} }
// FIXME(emilio): This needs to notify document observers and such,
// presumably.
void void
ShadowRoot::StyleSheetApplicableStateChanged(StyleSheet& aSheet, bool aApplicable) ShadowRoot::StyleSheetApplicableStateChanged(StyleSheet& aSheet, bool aApplicable)
{ {
@ -411,12 +411,14 @@ ShadowRoot::StyleSheetApplicableStateChanged(StyleSheet& aSheet, bool aApplicabl
void void
ShadowRoot::RemoveSheet(StyleSheet* aSheet) ShadowRoot::RemoveSheet(StyleSheet* aSheet)
{ {
DocumentOrShadowRoot::RemoveSheet(*aSheet); MOZ_ASSERT(aSheet);
if (aSheet->IsApplicable()) { RefPtr<StyleSheet> sheet = DocumentOrShadowRoot::RemoveSheet(*aSheet);
MOZ_ASSERT(sheet);
if (sheet->IsApplicable()) {
if (mStyleRuleMap) { if (mStyleRuleMap) {
mStyleRuleMap->SheetRemoved(*aSheet); mStyleRuleMap->SheetRemoved(*sheet);
} }
Servo_AuthorStyles_RemoveStyleSheet(mServoStyles.get(), aSheet); Servo_AuthorStyles_RemoveStyleSheet(mServoStyles.get(), sheet);
ApplicableRulesChanged(); ApplicableRulesChanged();
} }
} }

View File

@ -9,6 +9,7 @@
#include "mozilla/dom/DocumentFragment.h" #include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/DocumentOrShadowRoot.h" #include "mozilla/dom/DocumentOrShadowRoot.h"
#include "mozilla/dom/NameSpaceConstants.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
#include "nsIdentifierMapEntry.h" #include "nsIdentifierMapEntry.h"
@ -36,25 +37,7 @@ class ShadowRoot final : public DocumentFragment,
public nsStubMutationObserver public nsStubMutationObserver
{ {
public: public:
static ShadowRoot* FromNode(nsINode* aNode) NS_IMPL_FROMNODE_HELPER(ShadowRoot, IsShadowRoot());
{
return aNode->IsShadowRoot() ? static_cast<ShadowRoot*>(aNode) : nullptr;
}
static const ShadowRoot* FromNode(const nsINode* aNode)
{
return aNode->IsShadowRoot() ? static_cast<const ShadowRoot*>(aNode) : nullptr;
}
static ShadowRoot* FromNodeOrNull(nsINode* aNode)
{
return aNode ? FromNode(aNode) : nullptr;
}
static const ShadowRoot* FromNodeOrNull(const nsINode* aNode)
{
return aNode ? FromNode(aNode) : nullptr;
}
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ShadowRoot, NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ShadowRoot,
DocumentFragment) DocumentFragment)

View File

@ -30,7 +30,7 @@ Text::SplitText(uint32_t aOffset, ErrorResult& aRv)
} }
nsIDocument* document = GetComposedDoc(); nsIDocument* document = GetComposedDoc();
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, true); mozAutoDocUpdate updateBatch(document, true);
// Use Clone for creating the new node so that the new node is of same class // Use Clone for creating the new node so that the new node is of same class
// as this node! // as this node!

View File

@ -21,15 +21,12 @@
class MOZ_STACK_CLASS mozAutoDocUpdate class MOZ_STACK_CLASS mozAutoDocUpdate
{ {
public: public:
mozAutoDocUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType, mozAutoDocUpdate(nsIDocument* aDocument, bool aNotify)
bool aNotify) : : mDocument(aNotify ? aDocument : nullptr)
mDocument(aNotify ? aDocument : nullptr),
mUpdateType(aUpdateType)
{ {
if (mDocument) { if (mDocument) {
mDocument->BeginUpdate(mUpdateType); mDocument->BeginUpdate();
} } else {
else {
nsContentUtils::AddScriptBlocker(); nsContentUtils::AddScriptBlocker();
} }
} }
@ -37,24 +34,22 @@ public:
~mozAutoDocUpdate() ~mozAutoDocUpdate()
{ {
if (mDocument) { if (mDocument) {
mDocument->EndUpdate(mUpdateType); mDocument->EndUpdate();
} } else {
else {
nsContentUtils::RemoveScriptBlocker(); nsContentUtils::RemoveScriptBlocker();
} }
} }
private: private:
nsCOMPtr<nsIDocument> mDocument; nsCOMPtr<nsIDocument> mDocument;
nsUpdateType mUpdateType;
}; };
#define MOZ_AUTO_DOC_UPDATE_PASTE2(tok,line) tok##line #define MOZ_AUTO_DOC_UPDATE_PASTE2(tok,line) tok##line
#define MOZ_AUTO_DOC_UPDATE_PASTE(tok,line) \ #define MOZ_AUTO_DOC_UPDATE_PASTE(tok,line) \
MOZ_AUTO_DOC_UPDATE_PASTE2(tok,line) MOZ_AUTO_DOC_UPDATE_PASTE2(tok,line)
#define MOZ_AUTO_DOC_UPDATE(doc,type,notify) \ #define MOZ_AUTO_DOC_UPDATE(doc,notify) \
mozAutoDocUpdate MOZ_AUTO_DOC_UPDATE_PASTE(_autoDocUpdater_, __LINE__) \ mozAutoDocUpdate MOZ_AUTO_DOC_UPDATE_PASTE(_autoDocUpdater_, __LINE__) \
(doc,type,notify) (doc,notify)
/** /**
@ -73,14 +68,14 @@ public:
mDocument(aNotify ? aDocument : nullptr) mDocument(aNotify ? aDocument : nullptr)
{ {
if (mDocument) { if (mDocument) {
mDocument->BeginUpdate(UPDATE_CONTENT_MODEL); mDocument->BeginUpdate();
} }
} }
~mozAutoDocConditionalContentUpdateBatch() ~mozAutoDocConditionalContentUpdateBatch()
{ {
if (mDocument) { if (mDocument) {
mDocument->EndUpdate(UPDATE_CONTENT_MODEL); mDocument->EndUpdate();
} }
} }

View File

@ -1295,7 +1295,7 @@ nsContentSink::NotifyAppend(nsIContent* aContainer, uint32_t aStartIndex)
{ {
// Scope so we call EndUpdate before we decrease mInNotification // Scope so we call EndUpdate before we decrease mInNotification
MOZ_AUTO_DOC_UPDATE(mDocument, UPDATE_CONTENT_MODEL, !mBeganUpdate); MOZ_AUTO_DOC_UPDATE(mDocument, !mBeganUpdate);
nsNodeUtils::ContentAppended(aContainer, nsNodeUtils::ContentAppended(aContainer,
aContainer->GetChildAt_Deprecated(aStartIndex)); aContainer->GetChildAt_Deprecated(aStartIndex));
mLastNotificationTime = PR_Now(); mLastNotificationTime = PR_Now();
@ -1487,7 +1487,7 @@ nsContentSink::FavorPerformanceHint(bool perfOverStarvation, uint32_t starvation
} }
void void
nsContentSink::BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType) nsContentSink::BeginUpdate(nsIDocument* aDocument)
{ {
// Remember nested updates from updates that we started. // Remember nested updates from updates that we started.
if (mInNotification > 0 && mUpdatesInNotification < 2) { if (mInNotification > 0 && mUpdatesInNotification < 2) {
@ -1506,7 +1506,7 @@ nsContentSink::BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
} }
void void
nsContentSink::EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType) nsContentSink::EndUpdate(nsIDocument* aDocument)
{ {
// If we're in a script and we didn't do the notification, // If we're in a script and we didn't do the notification,
// something else in the script processing caused the // something else in the script processing caused the

View File

@ -5271,8 +5271,7 @@ nsContentUtils::SetNodeTextContent(nsIContent* aContent,
// Might as well stick a batch around this since we're performing several // Might as well stick a batch around this since we're performing several
// mutations. // mutations.
mozAutoDocUpdate updateBatch(aContent->GetComposedDoc(), mozAutoDocUpdate updateBatch(aContent->GetComposedDoc(), true);
UPDATE_CONTENT_MODEL, true);
nsAutoMutationBatch mb; nsAutoMutationBatch mb;
if (aTryReuse && !aValue.IsEmpty()) { if (aTryReuse && !aValue.IsEmpty()) {

View File

@ -3469,7 +3469,7 @@ nsDOMWindowUtils::AddSheet(nsIPreloadedStyleSheet* aSheet, uint32_t aSheetType)
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE); NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
if (sheet->GetAssociatedDocument()) { if (sheet->GetAssociatedDocumentOrShadowRoot()) {
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
} }

View File

@ -1687,11 +1687,11 @@ nsDocument::~nsDocument()
// Let the stylesheets know we're going away // Let the stylesheets know we're going away
for (StyleSheet* sheet : mStyleSheets) { for (StyleSheet* sheet : mStyleSheets) {
sheet->ClearAssociatedDocument(); sheet->ClearAssociatedDocumentOrShadowRoot();
} }
for (auto& sheets : mAdditionalSheets) { for (auto& sheets : mAdditionalSheets) {
for (StyleSheet* sheet : sheets) { for (StyleSheet* sheet : sheets) {
sheet->ClearAssociatedDocument(); sheet->ClearAssociatedDocumentOrShadowRoot();
} }
} }
if (mAttrStyleSheet) { if (mAttrStyleSheet) {
@ -2246,7 +2246,7 @@ nsIDocument::ResetToURI(nsIURI* aURI,
mInUnlinkOrDeletion = true; mInUnlinkOrDeletion = true;
uint32_t count = mChildren.ChildCount(); uint32_t count = mChildren.ChildCount();
{ // Scope for update { // Scope for update
MOZ_AUTO_DOC_UPDATE(this, UPDATE_CONTENT_MODEL, true); MOZ_AUTO_DOC_UPDATE(this, true);
// Invalidate cached array of child nodes // Invalidate cached array of child nodes
InvalidateChildNodes(); InvalidateChildNodes();
@ -2422,7 +2422,7 @@ nsIDocument::RemoveDocStyleSheetsFromStyleSets()
{ {
// The stylesheets should forget us // The stylesheets should forget us
for (StyleSheet* sheet : Reversed(mStyleSheets)) { for (StyleSheet* sheet : Reversed(mStyleSheets)) {
sheet->ClearAssociatedDocument(); sheet->ClearAssociatedDocumentOrShadowRoot();
if (sheet->IsApplicable()) { if (sheet->IsApplicable()) {
nsCOMPtr<nsIPresShell> shell = GetShell(); nsCOMPtr<nsIPresShell> shell = GetShell();
@ -2441,7 +2441,7 @@ nsIDocument::RemoveStyleSheetsFromStyleSets(
{ {
// The stylesheets should forget us // The stylesheets should forget us
for (StyleSheet* sheet : Reversed(aSheets)) { for (StyleSheet* sheet : Reversed(aSheets)) {
sheet->ClearAssociatedDocument(); sheet->ClearAssociatedDocumentOrShadowRoot();
if (sheet->IsApplicable()) { if (sheet->IsApplicable()) {
nsCOMPtr<nsIPresShell> shell = GetShell(); nsCOMPtr<nsIPresShell> shell = GetShell();
@ -2458,7 +2458,6 @@ nsIDocument::ResetStylesheetsToURI(nsIURI* aURI)
{ {
MOZ_ASSERT(aURI); MOZ_ASSERT(aURI);
mozAutoDocUpdate upd(this, UPDATE_STYLE, true);
if (mStyleSetFilled) { if (mStyleSetFilled) {
// Skip removing style sheets from the style set if we know we haven't // Skip removing style sheets from the style set if we know we haven't
// filled the style set. (This allows us to avoid calling // filled the style set. (This allows us to avoid calling
@ -2501,9 +2500,11 @@ nsIDocument::ResetStylesheetsToURI(nsIURI* aURI)
} }
// Now set up our style sets // Now set up our style sets
nsCOMPtr<nsIPresShell> shell = GetShell(); if (nsIPresShell* shell = GetShell()) {
if (shell) {
FillStyleSet(shell->StyleSet()); FillStyleSet(shell->StyleSet());
if (shell->StyleSet()->StyleSheetsHaveChanged()) {
shell->ApplicableStylesChanged();
}
} }
} }
@ -4242,9 +4243,7 @@ nsIDocument::EnsureOnDemandBuiltInUASheet(StyleSheet* aSheet)
if (mOnDemandBuiltInUASheets.Contains(aSheet)) { if (mOnDemandBuiltInUASheets.Contains(aSheet)) {
return; return;
} }
BeginUpdate(UPDATE_STYLE);
AddOnDemandBuiltInUASheet(aSheet); AddOnDemandBuiltInUASheet(aSheet);
EndUpdate(UPDATE_STYLE);
} }
void void
@ -4258,13 +4257,13 @@ nsIDocument::AddOnDemandBuiltInUASheet(StyleSheet* aSheet)
if (aSheet->IsApplicable()) { if (aSheet->IsApplicable()) {
// This is like |AddStyleSheetToStyleSets|, but for an agent sheet. // This is like |AddStyleSheetToStyleSets|, but for an agent sheet.
nsCOMPtr<nsIPresShell> shell = GetShell(); if (nsIPresShell* shell = GetShell()) {
if (shell) {
// Note that prepending here is necessary to make sure that html.css etc. // Note that prepending here is necessary to make sure that html.css etc.
// do not override Firefox OS/Mobile's content.css sheet. Maybe we should // do not override Firefox OS/Mobile's content.css sheet. Maybe we should
// have an insertion point to match the order of // have an insertion point to match the order of
// nsDocumentViewer::CreateStyleSet though? // nsDocumentViewer::CreateStyleSet though?
shell->StyleSet()->PrependStyleSheet(SheetType::Agent, aSheet); shell->StyleSet()->PrependStyleSheet(SheetType::Agent, aSheet);
shell->ApplicableStylesChanged();
} }
} }
@ -4274,9 +4273,9 @@ nsIDocument::AddOnDemandBuiltInUASheet(StyleSheet* aSheet)
void void
nsIDocument::AddStyleSheetToStyleSets(StyleSheet* aSheet) nsIDocument::AddStyleSheetToStyleSets(StyleSheet* aSheet)
{ {
nsCOMPtr<nsIPresShell> shell = GetShell(); if (nsIPresShell* shell = GetShell()) {
if (shell) {
shell->StyleSet()->AddDocStyleSheet(aSheet, this); shell->StyleSet()->AddDocStyleSheet(aSheet, this);
shell->ApplicableStylesChanged();
} }
} }
@ -4301,8 +4300,6 @@ nsIDocument::AddStyleSheetToStyleSets(StyleSheet* aSheet)
void void
nsIDocument::NotifyStyleSheetAdded(StyleSheet* aSheet, bool aDocumentSheet) nsIDocument::NotifyStyleSheetAdded(StyleSheet* aSheet, bool aDocumentSheet)
{ {
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetAdded, (aSheet, aDocumentSheet));
if (StyleSheetChangeEventsEnabled()) { if (StyleSheetChangeEventsEnabled()) {
DO_STYLESHEET_NOTIFICATION(StyleSheetChangeEvent, DO_STYLESHEET_NOTIFICATION(StyleSheetChangeEvent,
"StyleSheetAdded", "StyleSheetAdded",
@ -4314,8 +4311,6 @@ nsIDocument::NotifyStyleSheetAdded(StyleSheet* aSheet, bool aDocumentSheet)
void void
nsIDocument::NotifyStyleSheetRemoved(StyleSheet* aSheet, bool aDocumentSheet) nsIDocument::NotifyStyleSheetRemoved(StyleSheet* aSheet, bool aDocumentSheet)
{ {
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetRemoved, (aSheet, aDocumentSheet));
if (StyleSheetChangeEventsEnabled()) { if (StyleSheetChangeEventsEnabled()) {
DO_STYLESHEET_NOTIFICATION(StyleSheetChangeEvent, DO_STYLESHEET_NOTIFICATION(StyleSheetChangeEvent,
"StyleSheetRemoved", "StyleSheetRemoved",
@ -4328,8 +4323,7 @@ void
nsIDocument::AddStyleSheet(StyleSheet* aSheet) nsIDocument::AddStyleSheet(StyleSheet* aSheet)
{ {
MOZ_ASSERT(aSheet); MOZ_ASSERT(aSheet);
mStyleSheets.AppendElement(aSheet); DocumentOrShadowRoot::AppendSheet(*aSheet);
aSheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
if (aSheet->IsApplicable()) { if (aSheet->IsApplicable()) {
AddStyleSheetToStyleSets(aSheet); AddStyleSheetToStyleSets(aSheet);
@ -4341,40 +4335,38 @@ nsIDocument::AddStyleSheet(StyleSheet* aSheet)
void void
nsIDocument::RemoveStyleSheetFromStyleSets(StyleSheet* aSheet) nsIDocument::RemoveStyleSheetFromStyleSets(StyleSheet* aSheet)
{ {
nsCOMPtr<nsIPresShell> shell = GetShell(); if (nsIPresShell* shell = GetShell()) {
if (shell) {
shell->StyleSet()->RemoveDocStyleSheet(aSheet); shell->StyleSet()->RemoveDocStyleSheet(aSheet);
shell->ApplicableStylesChanged();
} }
} }
void void
nsIDocument::RemoveStyleSheet(StyleSheet* aSheet) nsIDocument::RemoveStyleSheet(StyleSheet* aSheet)
{ {
MOZ_ASSERT(aSheet, "null arg"); MOZ_ASSERT(aSheet);
RefPtr<StyleSheet> sheet = aSheet; // hold ref so it won't die too soon RefPtr<StyleSheet> sheet = DocumentOrShadowRoot::RemoveSheet(*aSheet);
if (!mStyleSheets.RemoveElement(aSheet)) { if (!sheet) {
NS_ASSERTION(mInUnlinkOrDeletion, "stylesheet not found"); NS_ASSERTION(mInUnlinkOrDeletion, "stylesheet not found");
return; return;
} }
if (!mIsGoingAway) { if (!mIsGoingAway) {
if (aSheet->IsApplicable()) { if (sheet->IsApplicable()) {
RemoveStyleSheetFromStyleSets(aSheet); RemoveStyleSheetFromStyleSets(sheet);
} }
NotifyStyleSheetRemoved(aSheet, true); NotifyStyleSheetRemoved(sheet, true);
} }
aSheet->ClearAssociatedDocument(); sheet->ClearAssociatedDocumentOrShadowRoot();
} }
void void
nsIDocument::UpdateStyleSheets(nsTArray<RefPtr<StyleSheet>>& aOldSheets, nsIDocument::UpdateStyleSheets(nsTArray<RefPtr<StyleSheet>>& aOldSheets,
nsTArray<RefPtr<StyleSheet>>& aNewSheets) nsTArray<RefPtr<StyleSheet>>& aNewSheets)
{ {
BeginUpdate(UPDATE_STYLE);
// XXX Need to set the sheet on the ownernode, if any // XXX Need to set the sheet on the ownernode, if any
MOZ_ASSERT(aOldSheets.Length() == aNewSheets.Length(), MOZ_ASSERT(aOldSheets.Length() == aNewSheets.Length(),
"The lists must be the same length!"); "The lists must be the same length!");
@ -4393,8 +4385,7 @@ nsIDocument::UpdateStyleSheets(nsTArray<RefPtr<StyleSheet>>& aOldSheets,
// Now put the new one in its place. If it's null, just ignore it. // Now put the new one in its place. If it's null, just ignore it.
StyleSheet* newSheet = aNewSheets[i]; StyleSheet* newSheet = aNewSheets[i];
if (newSheet) { if (newSheet) {
mStyleSheets.InsertElementAt(oldIndex, newSheet); DocumentOrShadowRoot::InsertSheetAt(oldIndex, *newSheet);
newSheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
if (newSheet->IsApplicable()) { if (newSheet->IsApplicable()) {
AddStyleSheetToStyleSets(newSheet); AddStyleSheetToStyleSets(newSheet);
} }
@ -4402,8 +4393,6 @@ nsIDocument::UpdateStyleSheets(nsTArray<RefPtr<StyleSheet>>& aOldSheets,
NotifyStyleSheetAdded(newSheet, true); NotifyStyleSheetAdded(newSheet, true);
} }
} }
EndUpdate(UPDATE_STYLE);
} }
void void
@ -4411,11 +4400,7 @@ nsIDocument::InsertStyleSheetAt(StyleSheet* aSheet, size_t aIndex)
{ {
MOZ_ASSERT(aSheet); MOZ_ASSERT(aSheet);
// FIXME(emilio): Stop touching DocumentOrShadowRoot's members directly, and use an DocumentOrShadowRoot::InsertSheetAt(aIndex, *aSheet);
// accessor.
mStyleSheets.InsertElementAt(aIndex, aSheet);
aSheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
if (aSheet->IsApplicable()) { if (aSheet->IsApplicable()) {
AddStyleSheetToStyleSets(aSheet); AddStyleSheetToStyleSets(aSheet);
@ -4439,12 +4424,6 @@ nsIDocument::SetStyleSheetApplicableState(StyleSheet* aSheet, bool aApplicable)
} }
} }
// We have to always notify, since this will be called for sheets
// that are children of sheets in our style set, as well as some
// sheets for HTMLEditor.
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetApplicableStateChanged, (aSheet));
if (StyleSheetChangeEventsEnabled()) { if (StyleSheetChangeEventsEnabled()) {
DO_STYLESHEET_NOTIFICATION(StyleSheetApplicableStateChangeEvent, DO_STYLESHEET_NOTIFICATION(StyleSheetApplicableStateChangeEvent,
"StyleSheetApplicableStateChanged", "StyleSheetApplicableStateChanged",
@ -4543,7 +4522,8 @@ nsIDocument::LoadAdditionalStyleSheet(additionalSheetType aType,
nsresult rv = loader->LoadSheetSync(aSheetURI, parsingMode, true, &sheet); nsresult rv = loader->LoadSheetSync(aSheetURI, parsingMode, true, &sheet);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
sheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument); sheet->SetAssociatedDocumentOrShadowRoot(
this, StyleSheet::OwnedByDocumentOrShadowRoot);
MOZ_ASSERT(sheet->IsApplicable()); MOZ_ASSERT(sheet->IsApplicable());
return AddAdditionalStyleSheet(aType, sheet); return AddAdditionalStyleSheet(aType, sheet);
@ -4560,17 +4540,15 @@ nsIDocument::AddAdditionalStyleSheet(additionalSheetType aType, StyleSheet* aShe
mAdditionalSheets[aType].AppendElement(aSheet); mAdditionalSheets[aType].AppendElement(aSheet);
BeginUpdate(UPDATE_STYLE); if (nsIPresShell* shell = GetShell()) {
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
SheetType type = ConvertAdditionalSheetType(aType); SheetType type = ConvertAdditionalSheetType(aType);
shell->StyleSet()->AppendStyleSheet(type, aSheet); shell->StyleSet()->AppendStyleSheet(type, aSheet);
shell->ApplicableStylesChanged();
} }
// Passing false, so documet.styleSheets.length will not be affected by // Passing false, so documet.styleSheets.length will not be affected by
// these additional sheets. // these additional sheets.
NotifyStyleSheetAdded(aSheet, false); NotifyStyleSheetAdded(aSheet, false);
EndUpdate(UPDATE_STYLE);
return NS_OK; return NS_OK;
} }
@ -4586,22 +4564,19 @@ nsIDocument::RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* aShee
RefPtr<StyleSheet> sheetRef = sheets[i]; RefPtr<StyleSheet> sheetRef = sheets[i];
sheets.RemoveElementAt(i); sheets.RemoveElementAt(i);
BeginUpdate(UPDATE_STYLE);
if (!mIsGoingAway) { if (!mIsGoingAway) {
MOZ_ASSERT(sheetRef->IsApplicable()); MOZ_ASSERT(sheetRef->IsApplicable());
nsCOMPtr<nsIPresShell> shell = GetShell(); if (nsIPresShell* shell = GetShell()) {
if (shell) {
SheetType type = ConvertAdditionalSheetType(aType); SheetType type = ConvertAdditionalSheetType(aType);
shell->StyleSet()->RemoveStyleSheet(type, sheetRef); shell->StyleSet()->RemoveStyleSheet(type, sheetRef);
shell->ApplicableStylesChanged();
} }
} }
// Passing false, so documet.styleSheets.length will not be affected by // Passing false, so documet.styleSheets.length will not be affected by
// these additional sheets. // these additional sheets.
NotifyStyleSheetRemoved(sheetRef, false); NotifyStyleSheetRemoved(sheetRef, false);
EndUpdate(UPDATE_STYLE); sheetRef->ClearAssociatedDocumentOrShadowRoot();
sheetRef->ClearAssociatedDocument();
} }
} }
@ -5037,12 +5012,14 @@ nsIDocument::MaybeEndOutermostXBLUpdate()
} }
void void
nsIDocument::BeginUpdate(nsUpdateType aUpdateType) nsIDocument::BeginUpdate()
{ {
// If the document is going away, then it's probably okay to do things to it // If the document is going away, then it's probably okay to do things to it
// in the wrong DocGroup. We're unlikely to run JS or do anything else // in the wrong DocGroup. We're unlikely to run JS or do anything else
// observable at this point. We reach this point when cycle collecting a // observable at this point. We reach this point when cycle collecting a
// <link> element and the unlink code removes a style sheet. // <link> element and the unlink code removes a style sheet.
//
// TODO(emilio): Style updates are gone, can this happen now?
if (mDocGroup && !mIsGoingAway && !mInUnlinkOrDeletion && !mIgnoreDocGroupMismatches) { if (mDocGroup && !mIsGoingAway && !mInUnlinkOrDeletion && !mIgnoreDocGroupMismatches) {
mDocGroup->ValidateAccess(); mDocGroup->ValidateAccess();
} }
@ -5054,13 +5031,13 @@ nsIDocument::BeginUpdate(nsUpdateType aUpdateType)
++mUpdateNestLevel; ++mUpdateNestLevel;
nsContentUtils::AddScriptBlocker(); nsContentUtils::AddScriptBlocker();
NS_DOCUMENT_NOTIFY_OBSERVERS(BeginUpdate, (this, aUpdateType)); NS_DOCUMENT_NOTIFY_OBSERVERS(BeginUpdate, (this));
} }
void void
nsDocument::EndUpdate(nsUpdateType aUpdateType) nsDocument::EndUpdate()
{ {
NS_DOCUMENT_NOTIFY_OBSERVERS(EndUpdate, (this, aUpdateType)); NS_DOCUMENT_NOTIFY_OBSERVERS(EndUpdate, (this));
nsContentUtils::RemoveScriptBlocker(); nsContentUtils::RemoveScriptBlocker();
@ -5424,6 +5401,10 @@ nsIDocument::DocumentStatesChanged(EventStates aStateMask)
void void
nsIDocument::StyleRuleChanged(StyleSheet* aSheet, css::Rule* aStyleRule) nsIDocument::StyleRuleChanged(StyleSheet* aSheet, css::Rule* aStyleRule)
{ {
if (nsIPresShell* shell = GetShell()) {
shell->ApplicableStylesChanged();
}
if (!StyleSheetChangeEventsEnabled()) { if (!StyleSheetChangeEventsEnabled()) {
return; return;
} }
@ -5437,6 +5418,10 @@ nsIDocument::StyleRuleChanged(StyleSheet* aSheet, css::Rule* aStyleRule)
void void
nsIDocument::StyleRuleAdded(StyleSheet* aSheet, css::Rule* aStyleRule) nsIDocument::StyleRuleAdded(StyleSheet* aSheet, css::Rule* aStyleRule)
{ {
if (nsIPresShell* shell = GetShell()) {
shell->ApplicableStylesChanged();
}
if (!StyleSheetChangeEventsEnabled()) { if (!StyleSheetChangeEventsEnabled()) {
return; return;
} }
@ -5450,6 +5435,10 @@ nsIDocument::StyleRuleAdded(StyleSheet* aSheet, css::Rule* aStyleRule)
void void
nsIDocument::StyleRuleRemoved(StyleSheet* aSheet, css::Rule* aStyleRule) nsIDocument::StyleRuleRemoved(StyleSheet* aSheet, css::Rule* aStyleRule)
{ {
if (nsIPresShell* shell = GetShell()) {
shell->ApplicableStylesChanged();
}
if (!StyleSheetChangeEventsEnabled()) { if (!StyleSheetChangeEventsEnabled()) {
return; return;
} }
@ -6013,7 +6002,6 @@ void
nsIDocument::EnableStyleSheetsForSetInternal(const nsAString& aSheetSet, nsIDocument::EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
bool aUpdateCSSLoader) bool aUpdateCSSLoader)
{ {
BeginUpdate(UPDATE_STYLE);
size_t count = SheetCount(); size_t count = SheetCount();
nsAutoString title; nsAutoString title;
for (size_t index = 0; index < count; index++) { for (size_t index = 0; index < count; index++) {
@ -6028,7 +6016,11 @@ nsIDocument::EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
if (aUpdateCSSLoader) { if (aUpdateCSSLoader) {
CSSLoader()->DocumentStyleSheetSetChanged(); CSSLoader()->DocumentStyleSheetSetChanged();
} }
EndUpdate(UPDATE_STYLE); if (nsIPresShell* shell = GetShell()) {
if (shell->StyleSet()->StyleSheetsHaveChanged()) {
shell->ApplicableStylesChanged();
}
}
} }
void void
@ -6374,7 +6366,7 @@ nsIDocument::SetTitle(const nsAString& aTitle, ErrorResult& aRv)
// Batch updates so that mutation events don't change "the title // Batch updates so that mutation events don't change "the title
// element" under us // element" under us
mozAutoDocUpdate updateBatch(this, UPDATE_CONTENT_MODEL, true); mozAutoDocUpdate updateBatch(this, true);
nsCOMPtr<Element> title = GetTitleElement(); nsCOMPtr<Element> title = GetTitleElement();
if (rootElement->IsSVGElement(nsGkAtoms::svg)) { if (rootElement->IsSVGElement(nsGkAtoms::svg)) {
@ -11715,7 +11707,7 @@ SizeOfOwnedSheetArrayExcludingThis(const nsTArray<RefPtr<StyleSheet>>& aSheets,
size_t n = 0; size_t n = 0;
n += aSheets.ShallowSizeOfExcludingThis(aMallocSizeOf); n += aSheets.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (StyleSheet* sheet : aSheets) { for (StyleSheet* sheet : aSheets) {
if (!sheet->GetAssociatedDocument()) { if (!sheet->GetAssociatedDocumentOrShadowRoot()) {
// Avoid over-reporting shared sheets. // Avoid over-reporting shared sheets.
continue; continue;
} }

View File

@ -165,7 +165,7 @@ public:
static bool IsWebAnimationsEnabled(JSContext* aCx, JSObject* aObject); static bool IsWebAnimationsEnabled(JSContext* aCx, JSObject* aObject);
static bool IsWebAnimationsEnabled(mozilla::dom::CallerType aCallerType); static bool IsWebAnimationsEnabled(mozilla::dom::CallerType aCallerType);
virtual void EndUpdate(nsUpdateType aUpdateType) override; virtual void EndUpdate() override;
virtual void BeginLoad() override; virtual void BeginLoad() override;
virtual void EndLoad() override; virtual void EndLoad() override;

View File

@ -16,7 +16,6 @@
#include "nsIApplicationCache.h" #include "nsIApplicationCache.h"
#include "nsIApplicationCacheContainer.h" #include "nsIApplicationCacheContainer.h"
#include "nsIContentViewer.h" #include "nsIContentViewer.h"
#include "nsIDocumentObserver.h" // for typedef (nsUpdateType)
#include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestor.h"
#include "nsILoadContext.h" #include "nsILoadContext.h"
#include "nsILoadGroup.h" // for member (in nsCOMPtr) #include "nsILoadGroup.h" // for member (in nsCOMPtr)
@ -1860,8 +1859,8 @@ public:
// BeginUpdate must be called before any batch of modifications of the // BeginUpdate must be called before any batch of modifications of the
// content model or of style data, EndUpdate must be called afterward. // content model or of style data, EndUpdate must be called afterward.
// To make this easy and painless, use the mozAutoDocUpdate helper class. // To make this easy and painless, use the mozAutoDocUpdate helper class.
void BeginUpdate(nsUpdateType aUpdateType); void BeginUpdate();
virtual void EndUpdate(nsUpdateType aUpdateType) = 0; virtual void EndUpdate() = 0;
virtual void BeginLoad() = 0; virtual void BeginLoad() = 0;
virtual void EndLoad() = 0; virtual void EndLoad() = 0;

View File

@ -18,12 +18,6 @@ class nsIDocument;
{ 0x71041fa3, 0x6dd7, 0x4cde, \ { 0x71041fa3, 0x6dd7, 0x4cde, \
{ 0xbb, 0x76, 0xae, 0xcc, 0x69, 0xe1, 0x75, 0x78 } } { 0xbb, 0x76, 0xae, 0xcc, 0x69, 0xe1, 0x75, 0x78 } }
typedef uint32_t nsUpdateType;
#define UPDATE_CONTENT_MODEL 0x00000001
#define UPDATE_STYLE 0x00000002
#define UPDATE_ALL (UPDATE_CONTENT_MODEL | UPDATE_STYLE)
// Document observer interface // Document observer interface
class nsIDocumentObserver : public nsIMutationObserver class nsIDocumentObserver : public nsIMutationObserver
{ {
@ -34,14 +28,13 @@ public:
* Notify that a content model update is beginning. This call can be * Notify that a content model update is beginning. This call can be
* nested. * nested.
*/ */
virtual void BeginUpdate(nsIDocument *aDocument, virtual void BeginUpdate(nsIDocument* aDocument) = 0;
nsUpdateType aUpdateType) = 0;
/** /**
* Notify that a content model update is finished. This call can be * Notify that a content model update is finished. This call can be
* nested. * nested.
*/ */
virtual void EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType) = 0; virtual void EndUpdate(nsIDocument* aDocument) = 0;
/** /**
* Notify the observer that a document load is beginning. * Notify the observer that a document load is beginning.
@ -83,53 +76,15 @@ public:
*/ */
virtual void DocumentStatesChanged(nsIDocument* aDocument, virtual void DocumentStatesChanged(nsIDocument* aDocument,
mozilla::EventStates aStateMask) = 0; mozilla::EventStates aStateMask) = 0;
/**
* A StyleSheet has just been added to the document. This method is
* called automatically when a StyleSheet gets added to the
* document, even if the stylesheet is not applicable. The
* notification is passed on to all of the document observers.
*
* @param aStyleSheet the StyleSheet that has been added
* @param aDocumentSheet True if sheet is in document's style sheet list,
* false if sheet is not (i.e., UA or user sheet)
*/
virtual void StyleSheetAdded(mozilla::StyleSheet* aStyleSheet,
bool aDocumentSheet) = 0;
/**
* A StyleSheet has just been removed from the document. This
* method is called automatically when a StyleSheet gets removed
* from the document, even if the stylesheet is not applicable. The
* notification is passed on to all of the document observers.
*
* @param aStyleSheet the StyleSheet that has been removed
* @param aDocumentSheet True if sheet is in document's style sheet list,
* false if sheet is not (i.e., UA or user sheet)
*/
virtual void StyleSheetRemoved(mozilla::StyleSheet* aStyleSheet,
bool aDocumentSheet) = 0;
/**
* A StyleSheet has just changed its applicable state.
* This method is called automatically when the applicable state
* of a StyleSheet gets changed. The style sheet passes this
* notification to the document. The notification is passed on
* to all of the document observers.
*
* @param aStyleSheet the StyleSheet that has changed state
*/
virtual void StyleSheetApplicableStateChanged(mozilla::StyleSheet* aStyleSheet) = 0;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentObserver, NS_IDOCUMENT_OBSERVER_IID) NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentObserver, NS_IDOCUMENT_OBSERVER_IID)
#define NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE \ #define NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE \
virtual void BeginUpdate(nsIDocument* aDocument, \ virtual void BeginUpdate(nsIDocument* aDocument) override;
nsUpdateType aUpdateType) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_ENDUPDATE \ #define NS_DECL_NSIDOCUMENTOBSERVER_ENDUPDATE \
virtual void EndUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType) override; virtual void EndUpdate(nsIDocument* aDocument) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_BEGINLOAD \ #define NS_DECL_NSIDOCUMENTOBSERVER_BEGINLOAD \
virtual void BeginLoad(nsIDocument* aDocument) override; virtual void BeginLoad(nsIDocument* aDocument) override;
@ -146,18 +101,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentObserver, NS_IDOCUMENT_OBSERVER_IID)
virtual void DocumentStatesChanged(nsIDocument* aDocument, \ virtual void DocumentStatesChanged(nsIDocument* aDocument, \
mozilla::EventStates aStateMask) override; mozilla::EventStates aStateMask) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETADDED \
virtual void StyleSheetAdded(mozilla::StyleSheet* aStyleSheet, \
bool aDocumentSheet) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETREMOVED \
virtual void StyleSheetRemoved(mozilla::StyleSheet* aStyleSheet, \
bool aDocumentSheet) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETAPPLICABLESTATECHANGED \
virtual void StyleSheetApplicableStateChanged( \
mozilla::StyleSheet* aStyleSheet) override;
#define NS_DECL_NSIDOCUMENTOBSERVER \ #define NS_DECL_NSIDOCUMENTOBSERVER \
NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE \ NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE \
NS_DECL_NSIDOCUMENTOBSERVER_ENDUPDATE \ NS_DECL_NSIDOCUMENTOBSERVER_ENDUPDATE \
@ -165,19 +108,16 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentObserver, NS_IDOCUMENT_OBSERVER_IID)
NS_DECL_NSIDOCUMENTOBSERVER_ENDLOAD \ NS_DECL_NSIDOCUMENTOBSERVER_ENDLOAD \
NS_DECL_NSIDOCUMENTOBSERVER_CONTENTSTATECHANGED \ NS_DECL_NSIDOCUMENTOBSERVER_CONTENTSTATECHANGED \
NS_DECL_NSIDOCUMENTOBSERVER_DOCUMENTSTATESCHANGED \ NS_DECL_NSIDOCUMENTOBSERVER_DOCUMENTSTATESCHANGED \
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETADDED \
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETREMOVED \
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETAPPLICABLESTATECHANGED \
NS_DECL_NSIMUTATIONOBSERVER NS_DECL_NSIMUTATIONOBSERVER
#define NS_IMPL_NSIDOCUMENTOBSERVER_CORE_STUB(_class) \ #define NS_IMPL_NSIDOCUMENTOBSERVER_CORE_STUB(_class) \
void \ void \
_class::BeginUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType) \ _class::BeginUpdate(nsIDocument* aDocument) \
{ \ { \
} \ } \
void \ void \
_class::EndUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType) \ _class::EndUpdate(nsIDocument* aDocument) \
{ \ { \
} \ } \
NS_IMPL_NSIMUTATIONOBSERVER_CORE_STUB(_class) NS_IMPL_NSIMUTATIONOBSERVER_CORE_STUB(_class)
@ -209,20 +149,4 @@ _class::DocumentStatesChanged(nsIDocument* aDocument, \
#define NS_IMPL_NSIDOCUMENTOBSERVER_CONTENT(_class) \ #define NS_IMPL_NSIDOCUMENTOBSERVER_CONTENT(_class) \
NS_IMPL_NSIMUTATIONOBSERVER_CONTENT(_class) NS_IMPL_NSIMUTATIONOBSERVER_CONTENT(_class)
#define NS_IMPL_NSIDOCUMENTOBSERVER_STYLE_STUB(_class) \
void \
_class::StyleSheetAdded(mozilla::StyleSheet* aStyleSheet, \
bool aDocumentSheet) \
{ \
} \
void \
_class::StyleSheetRemoved(mozilla::StyleSheet* aStyleSheet, \
bool aDocumentSheet) \
{ \
} \
void \
_class::StyleSheetApplicableStateChanged(mozilla::StyleSheet* aStyleSheet)\
{ \
} \
#endif /* nsIDocumentObserver_h___ */ #endif /* nsIDocumentObserver_h___ */

View File

@ -597,7 +597,7 @@ nsINode::Normalize()
} }
} }
mozAutoDocUpdate batch(doc, UPDATE_CONTENT_MODEL, true); mozAutoDocUpdate batch(doc, true);
// Merge and remove all nodes // Merge and remove all nodes
nsAutoString tmpStr; nsAutoString tmpStr;
@ -1295,7 +1295,7 @@ nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
// Do this before checking the child-count since this could cause mutations // Do this before checking the child-count since this could cause mutations
nsIDocument* doc = GetUncomposedDoc(); nsIDocument* doc = GetUncomposedDoc();
mozAutoDocUpdate updateBatch(GetComposedDoc(), UPDATE_CONTENT_MODEL, aNotify); mozAutoDocUpdate updateBatch(GetComposedDoc(), aNotify);
if (OwnerDoc() != aKid->OwnerDoc()) { if (OwnerDoc() != aKid->OwnerDoc()) {
ErrorResult error; ErrorResult error;
@ -1644,7 +1644,7 @@ nsINode::doRemoveChildAt(uint32_t aIndex, bool aNotify,
MOZ_ASSERT(!IsAttr()); MOZ_ASSERT(!IsAttr());
nsMutationGuard::DidMutate(); nsMutationGuard::DidMutate();
mozAutoDocUpdate updateBatch(GetComposedDoc(), UPDATE_CONTENT_MODEL, aNotify); mozAutoDocUpdate updateBatch(GetComposedDoc(), aNotify);
nsIContent* previousSibling = aKid->GetPreviousSibling(); nsIContent* previousSibling = aKid->GetPreviousSibling();
@ -1965,8 +1965,7 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
// Scope for the mutation batch and scriptblocker, so they go away // Scope for the mutation batch and scriptblocker, so they go away
// while kungFuDeathGrip is still alive. // while kungFuDeathGrip is still alive.
{ {
mozAutoDocUpdate batch(newContent->GetComposedDoc(), mozAutoDocUpdate batch(newContent->GetComposedDoc(), true);
UPDATE_CONTENT_MODEL, true);
nsAutoMutationBatch mb(oldParent, true, true); nsAutoMutationBatch mb(oldParent, true, true);
oldParent->RemoveChildAt_Deprecated(removeIndex, true); oldParent->RemoveChildAt_Deprecated(removeIndex, true);
if (nsAutoMutationBatch::GetCurrentBatch() == &mb) { if (nsAutoMutationBatch::GetCurrentBatch() == &mb) {
@ -2043,8 +2042,7 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
// Scope for the mutation batch and scriptblocker, so they go away // Scope for the mutation batch and scriptblocker, so they go away
// while kungFuDeathGrip is still alive. // while kungFuDeathGrip is still alive.
{ {
mozAutoDocUpdate batch(newContent->GetComposedDoc(), mozAutoDocUpdate batch(newContent->GetComposedDoc(), true);
UPDATE_CONTENT_MODEL, true);
nsAutoMutationBatch mb(newContent, false, true); nsAutoMutationBatch mb(newContent, false, true);
for (uint32_t i = count; i > 0;) { for (uint32_t i = count; i > 0;) {
@ -2114,7 +2112,7 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
} }
} }
mozAutoDocUpdate batch(GetComposedDoc(), UPDATE_CONTENT_MODEL, true); mozAutoDocUpdate batch(GetComposedDoc(), true);
nsAutoMutationBatch mb; nsAutoMutationBatch mb;
// Figure out which index we want to insert at. Note that we use // Figure out which index we want to insert at. Note that we use

View File

@ -17,4 +17,3 @@ NS_IMPL_NSIDOCUMENTOBSERVER_CORE_STUB(nsStubDocumentObserver)
NS_IMPL_NSIDOCUMENTOBSERVER_LOAD_STUB(nsStubDocumentObserver) NS_IMPL_NSIDOCUMENTOBSERVER_LOAD_STUB(nsStubDocumentObserver)
NS_IMPL_NSIDOCUMENTOBSERVER_STATE_STUB(nsStubDocumentObserver) NS_IMPL_NSIDOCUMENTOBSERVER_STATE_STUB(nsStubDocumentObserver)
NS_IMPL_NSIDOCUMENTOBSERVER_CONTENT(nsStubDocumentObserver) NS_IMPL_NSIDOCUMENTOBSERVER_CONTENT(nsStubDocumentObserver)
NS_IMPL_NSIDOCUMENTOBSERVER_STYLE_STUB(nsStubDocumentObserver)

View File

@ -314,9 +314,7 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
if (aOldShadowRoot) { if (aOldShadowRoot) {
aOldShadowRoot->RemoveSheet(mStyleSheet); aOldShadowRoot->RemoveSheet(mStyleSheet);
} else { } else {
aOldDocument->BeginUpdate(UPDATE_STYLE);
aOldDocument->RemoveStyleSheet(mStyleSheet); aOldDocument->RemoveStyleSheet(mStyleSheet);
aOldDocument->EndUpdate(UPDATE_STYLE);
} }
nsStyleLinkElement::SetStyleSheet(nullptr); nsStyleLinkElement::SetStyleSheet(nullptr);
@ -355,9 +353,7 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
ShadowRoot* containingShadow = thisContent->GetContainingShadow(); ShadowRoot* containingShadow = thisContent->GetContainingShadow();
containingShadow->RemoveSheet(mStyleSheet); containingShadow->RemoveSheet(mStyleSheet);
} else { } else {
doc->BeginUpdate(UPDATE_STYLE);
doc->RemoveStyleSheet(mStyleSheet); doc->RemoveStyleSheet(mStyleSheet);
doc->EndUpdate(UPDATE_STYLE);
} }
nsStyleLinkElement::SetStyleSheet(nullptr); nsStyleLinkElement::SetStyleSheet(nullptr);

View File

@ -107,7 +107,7 @@ nsStyledElement::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration,
static_cast<uint8_t>(MutationEventBinding::ADDITION); static_cast<uint8_t>(MutationEventBinding::ADDITION);
nsIDocument* document = GetComposedDoc(); nsIDocument* document = GetComposedDoc();
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify); mozAutoDocUpdate updateBatch(document, aNotify);
return SetAttrAndNotify(kNameSpaceID_None, nsGkAtoms::style, nullptr, return SetAttrAndNotify(kNameSpaceID_None, nsGkAtoms::style, nullptr,
oldValueSet ? &oldValue : nullptr, attrValue, oldValueSet ? &oldValue : nullptr, attrValue,
nullptr, modType, nullptr, modType,

View File

@ -2292,30 +2292,22 @@ IMEContentObserver::DocumentObserver::Destroy()
} }
void void
IMEContentObserver::DocumentObserver::BeginUpdate(nsIDocument* aDocument, IMEContentObserver::DocumentObserver::BeginUpdate(nsIDocument* aDocument)
nsUpdateType aUpdateType)
{ {
if (NS_WARN_IF(Destroyed()) || NS_WARN_IF(!IsObserving())) { if (NS_WARN_IF(Destroyed()) || NS_WARN_IF(!IsObserving())) {
return; return;
} }
if (!(aUpdateType & UPDATE_CONTENT_MODEL)) {
return;
}
mDocumentUpdating++; mDocumentUpdating++;
mIMEContentObserver->BeginDocumentUpdate(); mIMEContentObserver->BeginDocumentUpdate();
} }
void void
IMEContentObserver::DocumentObserver::EndUpdate(nsIDocument* aDocument, IMEContentObserver::DocumentObserver::EndUpdate(nsIDocument* aDocument)
nsUpdateType aUpdateType)
{ {
if (NS_WARN_IF(Destroyed()) || NS_WARN_IF(!IsObserving()) || if (NS_WARN_IF(Destroyed()) || NS_WARN_IF(!IsObserving()) ||
NS_WARN_IF(!IsUpdating())) { NS_WARN_IF(!IsUpdating())) {
return; return;
} }
if (!(aUpdateType & UPDATE_CONTENT_MODEL)) {
return;
}
mDocumentUpdating--; mDocumentUpdating--;
mIMEContentObserver->EndDocumentUpdate(); mIMEContentObserver->EndDocumentUpdate();
} }

View File

@ -2959,8 +2959,7 @@ nsGenericHTMLElement::SetInnerText(const nsAString& aValue)
// Might as well stick a batch around this since we're performing several // Might as well stick a batch around this since we're performing several
// mutations. // mutations.
mozAutoDocUpdate updateBatch(GetComposedDoc(), mozAutoDocUpdate updateBatch(GetComposedDoc(), true);
UPDATE_CONTENT_MODEL, true);
nsAutoMutationBatch mb; nsAutoMutationBatch mb;
mb.Init(this, true, false); mb.Init(this, true, false);

View File

@ -493,8 +493,7 @@ SinkContext::FlushTags()
mSink->mUpdatesInNotification = 0; mSink->mUpdatesInNotification = 0;
{ {
// Scope so we call EndUpdate before we decrease mInNotification // Scope so we call EndUpdate before we decrease mInNotification
mozAutoDocUpdate updateBatch(mSink->mDocument, UPDATE_CONTENT_MODEL, mozAutoDocUpdate updateBatch(mSink->mDocument, true);
true);
mSink->mBeganUpdate = true; mSink->mBeganUpdate = true;
// Start from the base of the stack (growing downward) and do // Start from the base of the stack (growing downward) and do
@ -955,7 +954,7 @@ HTMLContentSink::NotifyInsert(nsIContent* aContent,
{ {
// Scope so we call EndUpdate before we decrease mInNotification // Scope so we call EndUpdate before we decrease mInNotification
MOZ_AUTO_DOC_UPDATE(mDocument, UPDATE_CONTENT_MODEL, !mBeganUpdate); MOZ_AUTO_DOC_UPDATE(mDocument, !mBeganUpdate);
nsNodeUtils::ContentInserted(NODE_FROM(aContent, mDocument), nsNodeUtils::ContentInserted(NODE_FROM(aContent, mDocument),
aChildContent); aChildContent);
mLastNotificationTime = PR_Now(); mLastNotificationTime = PR_Now();

View File

@ -2096,11 +2096,11 @@ nsHTMLDocument::MaybeEditingStateChanged()
} }
void void
nsHTMLDocument::EndUpdate(nsUpdateType aUpdateType) nsHTMLDocument::EndUpdate()
{ {
const bool reset = !mPendingMaybeEditingStateChanged; const bool reset = !mPendingMaybeEditingStateChanged;
mPendingMaybeEditingStateChanged = true; mPendingMaybeEditingStateChanged = true;
nsDocument::EndUpdate(aUpdateType); nsDocument::EndUpdate();
if (reset) { if (reset) {
mPendingMaybeEditingStateChanged = false; mPendingMaybeEditingStateChanged = false;
} }
@ -2250,7 +2250,7 @@ nsHTMLDocument::TearingDownEditor()
presShell->SetAgentStyleSheets(agentSheets); presShell->SetAgentStyleSheets(agentSheets);
presShell->RestyleForCSSRuleChanges(); presShell->ApplicableStylesChanged();
} }
} }
@ -2418,7 +2418,7 @@ nsHTMLDocument::EditingStateChanged()
rv = presShell->SetAgentStyleSheets(agentSheets); rv = presShell->SetAgentStyleSheets(agentSheets);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
presShell->RestyleForCSSRuleChanges(); presShell->ApplicableStylesChanged();
// Adjust focused element with new style but blur event shouldn't be fired // Adjust focused element with new style but blur event shouldn't be fired
// until mEditingState is modified with newState. // until mEditingState is modified with newState.

View File

@ -125,7 +125,7 @@ public:
}; };
friend class nsAutoEditingState; friend class nsAutoEditingState;
void EndUpdate(nsUpdateType aUpdateType) override; void EndUpdate() override;
virtual void SetMayStartLayout(bool aMayStartLayout) override; virtual void SetMayStartLayout(bool aMayStartLayout) override;

View File

@ -98,8 +98,6 @@ SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded()
mHasLoadedNonSVGUserAgentStyleSheets = true; mHasLoadedNonSVGUserAgentStyleSheets = true;
BeginUpdate(UPDATE_STYLE);
if (IsBeingUsedAsImage()) { if (IsBeingUsedAsImage()) {
// nsDocumentViewer::CreateStyleSet skipped loading all user-agent/user // nsDocumentViewer::CreateStyleSet skipped loading all user-agent/user
// style sheets in this case, but we'll need B2G/Fennec's // style sheets in this case, but we'll need B2G/Fennec's
@ -167,8 +165,6 @@ SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded()
EnsureOnDemandBuiltInUASheet(cache->NoScriptSheet()); EnsureOnDemandBuiltInUASheet(cache->NoScriptSheet());
} }
EnsureOnDemandBuiltInUASheet(cache->UASheet()); EnsureOnDemandBuiltInUASheet(cache->UASheet());
EndUpdate(UPDATE_STYLE);
} }
} // namespace dom } // namespace dom

View File

@ -1433,8 +1433,7 @@ nsSVGElement::DidChangeValue(nsAtom* aName,
: static_cast<uint8_t>(MutationEventBinding::ADDITION); : static_cast<uint8_t>(MutationEventBinding::ADDITION);
nsIDocument* document = GetComposedDoc(); nsIDocument* document = GetComposedDoc();
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, mozAutoDocUpdate updateBatch(document, kNotifyDocumentObservers);
kNotifyDocumentObservers);
// XXX Really, the fourth argument to SetAttrAndNotify should be null if // XXX Really, the fourth argument to SetAttrAndNotify should be null if
// aEmptyOrOldValue does not represent the actual previous value of the // aEmptyOrOldValue does not represent the actual previous value of the
// attribute, but currently SVG elements do not even use the old attribute // attribute, but currently SVG elements do not even use the old attribute

View File

@ -401,9 +401,9 @@ nsXMLContentSink::OnTransformDone(nsresult aResult,
if (rootElement) { if (rootElement) {
NS_ASSERTION(mDocument->ComputeIndexOf(rootElement) != -1, NS_ASSERTION(mDocument->ComputeIndexOf(rootElement) != -1,
"rootElement not in doc?"); "rootElement not in doc?");
mDocument->BeginUpdate(UPDATE_CONTENT_MODEL); mDocument->BeginUpdate();
nsNodeUtils::ContentInserted(mDocument, rootElement); nsNodeUtils::ContentInserted(mDocument, rootElement);
mDocument->EndUpdate(UPDATE_CONTENT_MODEL); mDocument->EndUpdate();
} }
// Start the layout process // Start the layout process
@ -1539,7 +1539,7 @@ nsXMLContentSink::FlushTags()
++mInNotification; ++mInNotification;
{ {
// Scope so we call EndUpdate before we decrease mInNotification // Scope so we call EndUpdate before we decrease mInNotification
mozAutoDocUpdate updateBatch(mDocument, UPDATE_CONTENT_MODEL, true); mozAutoDocUpdate updateBatch(mDocument, true);
mBeganUpdate = true; mBeganUpdate = true;
// Don't release last text node in case we need to add to it again // Don't release last text node in case we need to add to it again

View File

@ -2692,7 +2692,6 @@ XULDocument::DoneWalking()
// attribute. // attribute.
{ {
mozAutoDocUpdate updateBatch(this, UPDATE_STYLE, true);
uint32_t count = mOverlaySheets.Length(); uint32_t count = mOverlaySheets.Length();
for (uint32_t i = 0; i < count; ++i) { for (uint32_t i = 0; i < count; ++i) {
AddStyleSheet(mOverlaySheets[i]); AddStyleSheet(mOverlaySheets[i]);
@ -2895,10 +2894,9 @@ XULDocument::MaybeBroadcast()
} }
void void
XULDocument::EndUpdate(nsUpdateType aUpdateType) XULDocument::EndUpdate()
{ {
XMLDocument::EndUpdate(aUpdateType); XMLDocument::EndUpdate();
MaybeBroadcast(); MaybeBroadcast();
} }

View File

@ -120,7 +120,7 @@ public:
bool aWasAlternate, bool aWasAlternate,
nsresult aStatus) override; nsresult aStatus) override;
virtual void EndUpdate(nsUpdateType aUpdateType) override; virtual void EndUpdate() override;
virtual bool IsDocumentRightToLeft() override; virtual bool IsDocumentRightToLeft() override;

View File

@ -270,26 +270,12 @@ HTMLEditor::DeleteRefToAnonymousNode(ManualNACPtr aContent,
// Need to check whether aShell has been destroyed (but not yet deleted). // Need to check whether aShell has been destroyed (but not yet deleted).
// See bug 338129. // See bug 338129.
if (aContent->IsInComposedDoc() && aShell && !aShell->IsDestroying()) { if (aContent->IsInComposedDoc() && aShell && !aShell->IsDestroying()) {
// Call BeginUpdate() so that the nsCSSFrameConstructor/PresShell
// knows we're messing with the frame tree.
//
// FIXME(emilio): Shouldn't this use the document update mechanism instead?
// Also, is it really needed? This is NAC anyway.
nsCOMPtr<nsIDocument> document = GetDocument();
if (document) {
aShell->BeginUpdate(document, UPDATE_CONTENT_MODEL);
}
MOZ_ASSERT(aContent->IsRootOfAnonymousSubtree()); MOZ_ASSERT(aContent->IsRootOfAnonymousSubtree());
MOZ_ASSERT(!aContent->GetPreviousSibling(), "NAC has no siblings"); MOZ_ASSERT(!aContent->GetPreviousSibling(), "NAC has no siblings");
// FIXME(emilio): This is the only caller to PresShell::ContentRemoved that // FIXME(emilio): This is the only caller to PresShell::ContentRemoved that
// passes NAC into it. This is not great! // passes NAC into it. This is not great!
aShell->ContentRemoved(aContent, nullptr); aShell->ContentRemoved(aContent, nullptr);
if (document) {
aShell->EndUpdate(document, UPDATE_CONTENT_MODEL);
}
} }
// The ManualNACPtr destructor will invoke UnbindFromTree. // The ManualNACPtr destructor will invoke UnbindFromTree.

View File

@ -2985,8 +2985,7 @@ HTMLEditor::AddOverrideStyleSheet(const nsAString& aURL)
// Add the override style sheet // Add the override style sheet
// (This checks if already exists) // (This checks if already exists)
ps->AddOverrideStyleSheet(sheet); ps->AddOverrideStyleSheet(sheet);
ps->ApplicableStylesChanged();
ps->RestyleForCSSRuleChanges();
// Save as the last-loaded sheet // Save as the last-loaded sheet
mLastOverrideStyleSheetURL = aURL; mLastOverrideStyleSheetURL = aURL;
@ -3033,7 +3032,7 @@ HTMLEditor::RemoveOverrideStyleSheet(const nsAString& aURL)
NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED); NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED);
ps->RemoveOverrideStyleSheet(sheet); ps->RemoveOverrideStyleSheet(sheet);
ps->RestyleForCSSRuleChanges(); ps->ApplicableStylesChanged();
// Remove it from our internal list // Remove it from our internal list
return rv; return rv;
@ -3048,7 +3047,8 @@ HTMLEditor::EnableStyleSheet(const nsAString& aURL,
// Ensure the style sheet is owned by our document. // Ensure the style sheet is owned by our document.
nsCOMPtr<nsIDocument> document = GetDocument(); nsCOMPtr<nsIDocument> document = GetDocument();
sheet->SetAssociatedDocument(document, StyleSheet::NotOwnedByDocument); sheet->SetAssociatedDocumentOrShadowRoot(
document, StyleSheet::NotOwnedByDocumentOrShadowRoot);
sheet->SetDisabled(!aEnable); sheet->SetDisabled(!aEnable);
return NS_OK; return NS_OK;
@ -3066,7 +3066,8 @@ HTMLEditor::EnableExistingStyleSheet(const nsAString& aURL)
// Ensure the style sheet is owned by our document. // Ensure the style sheet is owned by our document.
nsCOMPtr<nsIDocument> document = GetDocument(); nsCOMPtr<nsIDocument> document = GetDocument();
sheet->SetAssociatedDocument(document, StyleSheet::NotOwnedByDocument); sheet->SetAssociatedDocumentOrShadowRoot(
document, StyleSheet::NotOwnedByDocumentOrShadowRoot);
// FIXME: This used to do sheet->SetDisabled(false), figure out if we can // FIXME: This used to do sheet->SetDisabled(false), figure out if we can
// just remove all this code in bug 1449522, since it seems unused. // just remove all this code in bug 1449522, since it seems unused.

View File

@ -14,29 +14,22 @@
#include "nsDebug.h" // for NS_ENSURE_TRUE #include "nsDebug.h" // for NS_ENSURE_TRUE
#include "nsError.h" // for NS_OK, etc. #include "nsError.h" // for NS_OK, etc.
#include "nsIDocument.h" // for nsIDocument #include "nsIDocument.h" // for nsIDocument
#include "nsIDocumentObserver.h" // for UPDATE_STYLE
namespace mozilla { namespace mozilla {
static void static void
AddStyleSheet(EditorBase& aEditor, StyleSheet* aSheet) AddStyleSheet(EditorBase& aEditor, StyleSheet* aSheet)
{ {
nsCOMPtr<nsIDocument> doc = aEditor.GetDocument(); if (nsCOMPtr<nsIDocument> doc = aEditor.GetDocument()) {
if (doc) {
doc->BeginUpdate(UPDATE_STYLE);
doc->AddStyleSheet(aSheet); doc->AddStyleSheet(aSheet);
doc->EndUpdate(UPDATE_STYLE);
} }
} }
static void static void
RemoveStyleSheet(EditorBase& aEditor, StyleSheet* aSheet) RemoveStyleSheet(EditorBase& aEditor, StyleSheet* aSheet)
{ {
nsCOMPtr<nsIDocument> doc = aEditor.GetDocument(); if (nsCOMPtr<nsIDocument> doc = aEditor.GetDocument()) {
if (doc) {
doc->BeginUpdate(UPDATE_STYLE);
doc->RemoveStyleSheet(aSheet); doc->RemoveStyleSheet(aSheet);
doc->EndUpdate(UPDATE_STYLE);
} }
} }

View File

@ -4184,6 +4184,9 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
// Note that even if the CancelAnimation call above requested a repaint // Note that even if the CancelAnimation call above requested a repaint
// this is fine because we already have repaint request deduplication. // this is fine because we already have repaint request deduplication.
needContentRepaint = true; needContentRepaint = true;
// Since the main-thread scroll offset changed we should trigger a
// recomposite to make sure it becomes user-visible.
ScheduleComposite();
} else if (scrollableRectChanged) { } else if (scrollableRectChanged) {
// Even if we didn't accept a new scroll offset from content, the // Even if we didn't accept a new scroll offset from content, the
// scrollable rect may have changed in a way that makes our local // scrollable rect may have changed in a way that makes our local

View File

@ -2107,6 +2107,13 @@ CompositorBridgeParent::LayerTreeState::InProcessSharingController() const
return mParent; return mParent;
} }
void
CompositorBridgeParent::DidComposite(LayersId aId, TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd)
{
MOZ_ASSERT(aId == mRootLayerTreeID);
DidComposite(aCompositeStart, aCompositeEnd);
}
void void
CompositorBridgeParent::DidComposite(TimeStamp& aCompositeStart, CompositorBridgeParent::DidComposite(TimeStamp& aCompositeStart,
TimeStamp& aCompositeEnd) TimeStamp& aCompositeEnd)

View File

@ -138,7 +138,7 @@ public:
virtual void ObserveLayerUpdate(LayersId aLayersId, uint64_t aEpoch, bool aActive) = 0; virtual void ObserveLayerUpdate(LayersId aLayersId, uint64_t aEpoch, bool aActive) = 0;
virtual void DidComposite(LayersId aId, TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd) {} virtual void DidComposite(LayersId aId, TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd) = 0;
virtual void NotifyPipelineRendered(const wr::PipelineId& aPipelineId, virtual void NotifyPipelineRendered(const wr::PipelineId& aPipelineId,
const wr::Epoch& aEpoch, const wr::Epoch& aEpoch,
@ -578,7 +578,7 @@ protected:
*/ */
bool CanComposite(); bool CanComposite();
using CompositorBridgeParentBase::DidComposite; void DidComposite(LayersId aId, TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd) override;
void DidComposite(TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd); void DidComposite(TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd);
void NotifyPipelineRendered(const wr::PipelineId& aPipelineId, void NotifyPipelineRendered(const wr::PipelineId& aPipelineId,

View File

@ -724,13 +724,7 @@ WebRenderBridgeParent::RecvEmptyTransaction(const FocusTarget& aFocusTarget,
// to early-return without doing so. // to early-return without doing so.
AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy); AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
if (!aCommands.IsEmpty()) { bool scheduleComposite = false;
mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
wr::TransactionBuilder txn;
ProcessWebRenderParentCommands(aCommands, txn);
mApi->SendTransaction(txn);
ScheduleGenerateFrame();
}
UpdateAPZFocusState(aFocusTarget); UpdateAPZFocusState(aFocusTarget);
if (!aUpdates.empty()) { if (!aUpdates.empty()) {
@ -739,28 +733,39 @@ WebRenderBridgeParent::RecvEmptyTransaction(const FocusTarget& aFocusTarget,
// const so that we can move this structure all the way to the desired // const so that we can move this structure all the way to the desired
// destination. // destination.
UpdateAPZScrollOffsets(Move(const_cast<ScrollUpdatesMap&>(aUpdates)), aPaintSequenceNumber); UpdateAPZScrollOffsets(Move(const_cast<ScrollUpdatesMap&>(aUpdates)), aPaintSequenceNumber);
scheduleComposite = true;
} }
if (!aCommands.IsEmpty()) { if (!aCommands.IsEmpty()) {
mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
wr::TransactionBuilder txn; wr::TransactionBuilder txn;
wr::Epoch wrEpoch = GetNextWrEpoch(); wr::Epoch wrEpoch = GetNextWrEpoch();
txn.UpdateEpoch(mPipelineId, wrEpoch); txn.UpdateEpoch(mPipelineId, wrEpoch);
ProcessWebRenderParentCommands(aCommands, txn);
mApi->SendTransaction(txn); mApi->SendTransaction(txn);
scheduleComposite = true;
HoldPendingTransactionId(wrEpoch, aTransactionId, aTxnStartTime, aFwdTime);
} else {
bool sendDidComposite = false;
if (mPendingTransactionIds.empty()) {
sendDidComposite = true;
} }
bool sendDidComposite = true;
if (scheduleComposite || !mPendingTransactionIds.empty()) {
// If we are going to kick off a new composite as a result of this
// transaction, or if there are already composite-triggering pending
// transactions inflight, then set sendDidComposite to false because we will
// send the DidComposite message after the composite occurs.
// If there are no pending transactions and we're not going to do a
// composite, then we leave sendDidComposite as true so we just send
// the DidComposite notification now.
sendDidComposite = false;
}
HoldPendingTransactionId(WrEpoch(), aTransactionId, aTxnStartTime, aFwdTime); HoldPendingTransactionId(WrEpoch(), aTransactionId, aTxnStartTime, aFwdTime);
// If WebRenderBridgeParent does not have pending DidComposites,
// send DidComposite now. if (scheduleComposite) {
if (sendDidComposite) { ScheduleGenerateFrame();
} else if (sendDidComposite) {
TimeStamp now = TimeStamp::Now(); TimeStamp now = TimeStamp::Now();
mCompositorBridge->DidComposite(GetLayersId(), now, now); mCompositorBridge->DidComposite(GetLayersId(), now, now);
} }
}
return IPC_OK(); return IPC_OK();
} }

View File

@ -799,7 +799,6 @@ PresShell::PresShell()
#ifdef DEBUG #ifdef DEBUG
, mInVerifyReflow(false) , mInVerifyReflow(false)
, mCurrentReflowRoot(nullptr) , mCurrentReflowRoot(nullptr)
, mUpdateCount(0)
#endif #endif
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
, mReflowCountMgr(nullptr) , mReflowCountMgr(nullptr)
@ -1442,7 +1441,7 @@ nsIPresShell::SetAuthorStyleDisabled(bool aStyleDisabled)
{ {
if (aStyleDisabled != mStyleSet->GetAuthorStyleDisabled()) { if (aStyleDisabled != mStyleSet->GetAuthorStyleDisabled()) {
mStyleSet->SetAuthorStyleDisabled(aStyleDisabled); mStyleSet->SetAuthorStyleDisabled(aStyleDisabled);
RestyleForCSSRuleChanges(); ApplicableStylesChanged();
nsCOMPtr<nsIObserverService> observerService = nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService(); mozilla::services::GetObserverService();
@ -1498,8 +1497,6 @@ PresShell::UpdatePreferenceStyles()
return; return;
} }
mStyleSet->BeginUpdate();
RemovePreferenceStyles(); RemovePreferenceStyles();
// NOTE(emilio): This sheet is added as an agent sheet, because we don't want // NOTE(emilio): This sheet is added as an agent sheet, because we don't want
@ -1508,8 +1505,6 @@ PresShell::UpdatePreferenceStyles()
// without too much trouble I'd think. // without too much trouble I'd think.
mStyleSet->AppendStyleSheet(SheetType::Agent, newPrefSheet); mStyleSet->AppendStyleSheet(SheetType::Agent, newPrefSheet);
mPrefStyleSheet = newPrefSheet; mPrefStyleSheet = newPrefSheet;
mStyleSet->EndUpdate();
} }
void void
@ -1532,8 +1527,6 @@ PresShell::AddUserSheet(StyleSheet* aSheet)
nsCOMPtr<nsIStyleSheetService> dummy = nsCOMPtr<nsIStyleSheetService> dummy =
do_GetService(NS_STYLESHEETSERVICE_CONTRACTID); do_GetService(NS_STYLESHEETSERVICE_CONTRACTID);
mStyleSet->BeginUpdate();
nsStyleSheetService* sheetService = nsStyleSheetService::gInstance; nsStyleSheetService* sheetService = nsStyleSheetService::gInstance;
nsTArray<RefPtr<StyleSheet>>& userSheets = *sheetService->UserStyleSheets(); nsTArray<RefPtr<StyleSheet>>& userSheets = *sheetService->UserStyleSheets();
// Iterate forwards when removing so the searches for RemoveStyleSheet are as // Iterate forwards when removing so the searches for RemoveStyleSheet are as
@ -1548,8 +1541,7 @@ PresShell::AddUserSheet(StyleSheet* aSheet)
mStyleSet->PrependStyleSheet(SheetType::User, sheet); mStyleSet->PrependStyleSheet(SheetType::User, sheet);
} }
mStyleSet->EndUpdate(); ApplicableStylesChanged();
RestyleForCSSRuleChanges();
} }
void void
@ -1558,7 +1550,7 @@ PresShell::AddAgentSheet(StyleSheet* aSheet)
// Make sure this does what nsDocumentViewer::CreateStyleSet does // Make sure this does what nsDocumentViewer::CreateStyleSet does
// wrt ordering. // wrt ordering.
mStyleSet->AppendStyleSheet(SheetType::Agent, aSheet); mStyleSet->AppendStyleSheet(SheetType::Agent, aSheet);
RestyleForCSSRuleChanges(); ApplicableStylesChanged();
} }
void void
@ -1575,14 +1567,14 @@ PresShell::AddAuthorSheet(StyleSheet* aSheet)
mStyleSet->AppendStyleSheet(SheetType::Doc, aSheet); mStyleSet->AppendStyleSheet(SheetType::Doc, aSheet);
} }
RestyleForCSSRuleChanges(); ApplicableStylesChanged();
} }
void void
PresShell::RemoveSheet(SheetType aType, StyleSheet* aSheet) PresShell::RemoveSheet(SheetType aType, StyleSheet* aSheet)
{ {
mStyleSet->RemoveStyleSheet(aType, aSheet); mStyleSet->RemoveStyleSheet(aType, aSheet);
RestyleForCSSRuleChanges(); ApplicableStylesChanged();
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -2528,32 +2520,6 @@ PresShell::GetCanvasFrame() const
return do_QueryFrame(frame); return do_QueryFrame(frame);
} }
void
PresShell::BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
{
#ifdef DEBUG
mUpdateCount++;
#endif
if (aUpdateType & UPDATE_STYLE)
mStyleSet->BeginUpdate();
}
void
PresShell::EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
{
#ifdef DEBUG
MOZ_ASSERT(0 != mUpdateCount, "too many EndUpdate's");
--mUpdateCount;
#endif
if (aUpdateType & UPDATE_STYLE) {
mStyleSet->EndUpdate();
if (mStyleSet->StyleSheetsHaveChanged()) {
RestyleForCSSRuleChanges();
}
}
}
void void
PresShell::RestoreRootScrollPosition() PresShell::RestoreRootScrollPosition()
{ {
@ -4614,7 +4580,7 @@ PresShell::ReconstructFrames()
} }
void void
nsIPresShell::RestyleForCSSRuleChanges() nsIPresShell::ApplicableStylesChanged()
{ {
if (mIsDestroying) { if (mIsDestroying) {
// We don't want to mess with restyles at this point // We don't want to mess with restyles at this point
@ -4627,14 +4593,8 @@ nsIPresShell::RestyleForCSSRuleChanges()
if (mPresContext) { if (mPresContext) {
mPresContext->MarkCounterStylesDirty(); mPresContext->MarkCounterStylesDirty();
mPresContext->MarkFontFeatureValuesDirty(); mPresContext->MarkFontFeatureValuesDirty();
mPresContext->RestyleManager()->NextRestyleIsForCSSRuleChanges();
} }
if (!mDidInitialize) {
// Nothing to do here, since we have no frames yet
return;
}
mStyleSet->InvalidateStyleForCSSRuleChanges();
} }
nsresult nsresult
@ -6185,6 +6145,7 @@ void
nsIPresShell::RecordShadowStyleChange(ShadowRoot& aShadowRoot) nsIPresShell::RecordShadowStyleChange(ShadowRoot& aShadowRoot)
{ {
mStyleSet->RecordShadowStyleChange(aShadowRoot); mStyleSet->RecordShadowStyleChange(aShadowRoot);
ApplicableStylesChanged();
} }
void void

View File

@ -283,8 +283,6 @@ public:
int16_t aEndOffset, bool* aRetval) override; int16_t aEndOffset, bool* aRetval) override;
// nsIDocumentObserver // nsIDocumentObserver
NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE
NS_DECL_NSIDOCUMENTOBSERVER_ENDUPDATE
NS_DECL_NSIDOCUMENTOBSERVER_BEGINLOAD NS_DECL_NSIDOCUMENTOBSERVER_BEGINLOAD
NS_DECL_NSIDOCUMENTOBSERVER_ENDLOAD NS_DECL_NSIDOCUMENTOBSERVER_ENDLOAD
NS_DECL_NSIDOCUMENTOBSERVER_CONTENTSTATECHANGED NS_DECL_NSIDOCUMENTOBSERVER_CONTENTSTATECHANGED
@ -756,7 +754,6 @@ private:
// The reflow root under which we're currently reflowing. Null when // The reflow root under which we're currently reflowing. Null when
// not in reflow. // not in reflow.
nsIFrame* mCurrentReflowRoot; nsIFrame* mCurrentReflowRoot;
uint32_t mUpdateCount;
#endif #endif
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF

View File

@ -2191,13 +2191,6 @@ RestyleManager::PostRestyleEvent(Element* aElement,
} }
} }
void
RestyleManager::PostRestyleEventForCSSRuleChanges()
{
mRestyleForCSSRuleChanges = true;
mPresContext->PresShell()->EnsureStyleFlush();
}
void void
RestyleManager::PostRestyleEventForAnimations( RestyleManager::PostRestyleEventForAnimations(
Element* aElement, Element* aElement,

View File

@ -336,7 +336,10 @@ public:
CSSPseudoElementType, CSSPseudoElementType,
nsRestyleHint); nsRestyleHint);
void PostRestyleEventForCSSRuleChanges(); void NextRestyleIsForCSSRuleChanges()
{
mRestyleForCSSRuleChanges = true;
}
void RebuildAllStyleData(nsChangeHint aExtraHint, nsRestyleHint aRestyleHint); void RebuildAllStyleData(nsChangeHint aExtraHint, nsRestyleHint aRestyleHint);
void PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint, void PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint,

View File

@ -0,0 +1,11 @@
<style>
* { counter-reset: c; }
</style>
<script>
function go() {
host.attachShadow({ mode: "open" }).innerHTML = form.outerHTML;
}
</script>
<body onload=go()>
<form id="form" style="counter-reset: c">
<div id="host">

View File

@ -530,3 +530,4 @@ load 1452839.html
load 1453702.html load 1453702.html
load 1453342.html load 1453342.html
load 1453196.html load 1453196.html
pref(dom.webcomponents.shadowdom.enabled,true) load 1414303.html

View File

@ -691,9 +691,6 @@ nsDocumentViewer::InitPresentationStuff(bool aDoInitialReflow)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
// We're done creating the style set
mPresShell->StyleSet()->EndUpdate();
if (aDoInitialReflow) { if (aDoInitialReflow) {
// Since Initialize() will create frames for *all* items // Since Initialize() will create frames for *all* items
// that are currently in the document tree, we need to flush // that are currently in the document tree, we need to flush
@ -2315,8 +2312,6 @@ nsDocumentViewer::CreateStyleSet(nsIDocument* aDocument)
UniquePtr<ServoStyleSet> styleSet = MakeUnique<ServoStyleSet>(); UniquePtr<ServoStyleSet> styleSet = MakeUnique<ServoStyleSet>();
styleSet->BeginUpdate();
// The document will fill in the document sheets when we create the presshell // The document will fill in the document sheets when we create the presshell
if (aDocument->IsBeingUsedAsImage()) { if (aDocument->IsBeingUsedAsImage()) {
@ -2328,8 +2323,6 @@ nsDocumentViewer::CreateStyleSet(nsIDocument* aDocument)
// xul.css) to be loaded on-demand. // xul.css) to be loaded on-demand.
// XXXjwatt Nothing else is loaded on-demand, but I don't think that // XXXjwatt Nothing else is loaded on-demand, but I don't think that
// should matter for SVG-as-an-image. If it does, I want to know why! // should matter for SVG-as-an-image. If it does, I want to know why!
// Caller will handle calling EndUpdate, per contract.
return styleSet; return styleSet;
} }
@ -2436,7 +2429,6 @@ nsDocumentViewer::CreateStyleSet(nsIDocument* aDocument)
} }
} }
// Caller will handle calling EndUpdate, per contract.
return styleSet; return styleSet;
} }

View File

@ -99,7 +99,7 @@ nsGenConList::NodeAfter(const nsGenConNode* aNode1, const nsGenConNode* aNode2)
return pseudoType1 == 1; return pseudoType1 == 1;
} }
} }
// XXX Switch to the frame version of DoCompareTreePosition?
int32_t cmp = nsLayoutUtils::DoCompareTreePosition(content1, content2, int32_t cmp = nsLayoutUtils::DoCompareTreePosition(content1, content2,
pseudoType1, -pseudoType2); pseudoType1, -pseudoType2);
MOZ_ASSERT(cmp != 0, "same content, different frames"); MOZ_ASSERT(cmp != 0, "same content, different frames");

View File

@ -291,26 +291,11 @@ public:
void SetAuthorStyleDisabled(bool aDisabled); void SetAuthorStyleDisabled(bool aDisabled);
bool GetAuthorStyleDisabled() const; bool GetAuthorStyleDisabled() const;
/* /**
* Called when stylesheets are added/removed/enabled/disabled to * Needs to be called any time the applicable style can has changed, in order
* recompute style and clear other cached data as needed. This will * to schedule a style flush and setup all the relevant state.
* not reconstruct style synchronously; if you need to do that, call
* FlushPendingNotifications to flush out style reresolves.
*
* This handles the the addition and removal of the various types of
* style rules that can be in CSS style sheets, such as @font-face
* rules and @counter-style rules.
*
* It requires that StyleSheetAdded, StyleSheetRemoved,
* StyleSheetApplicableStateChanged, StyleRuleAdded, StyleRuleRemoved,
* or StyleRuleChanged has been called on the style sheets that have
* changed.
*
* // XXXbz why do we have this on the interface anyway? The only consumer
* is calling AddOverrideStyleSheet/RemoveOverrideStyleSheet, and I think
* those should just handle reconstructing style data...
*/ */
void RestyleForCSSRuleChanges(); void ApplicableStylesChanged();
/** /**
* Update the style set somehow to take into account changed prefs which * Update the style set somehow to take into account changed prefs which

View File

@ -1628,7 +1628,9 @@ nsLayoutUtils::DoCompareTreePosition(nsIContent* aContent1,
AutoTArray<nsINode*, 32> content1Ancestors; AutoTArray<nsINode*, 32> content1Ancestors;
nsINode* c1; nsINode* c1;
for (c1 = aContent1; c1 && c1 != aCommonAncestor; c1 = c1->GetParentNode()) { for (c1 = aContent1;
c1 && c1 != aCommonAncestor;
c1 = c1->GetParentOrHostNode()) {
content1Ancestors.AppendElement(c1); content1Ancestors.AppendElement(c1);
} }
if (!c1 && aCommonAncestor) { if (!c1 && aCommonAncestor) {
@ -1639,7 +1641,9 @@ nsLayoutUtils::DoCompareTreePosition(nsIContent* aContent1,
AutoTArray<nsINode*, 32> content2Ancestors; AutoTArray<nsINode*, 32> content2Ancestors;
nsINode* c2; nsINode* c2;
for (c2 = aContent2; c2 && c2 != aCommonAncestor; c2 = c2->GetParentNode()) { for (c2 = aContent2;
c2 && c2 != aCommonAncestor;
c2 = c2->GetParentOrHostNode()) {
content2Ancestors.AppendElement(c2); content2Ancestors.AppendElement(c2);
} }
if (!c2 && aCommonAncestor) { if (!c2 && aCommonAncestor) {
@ -1675,7 +1679,7 @@ nsLayoutUtils::DoCompareTreePosition(nsIContent* aContent1,
} }
// content1Ancestor != content2Ancestor, so they must be siblings with the same parent // content1Ancestor != content2Ancestor, so they must be siblings with the same parent
nsINode* parent = content1Ancestor->GetParentNode(); nsINode* parent = content1Ancestor->GetParentOrHostNode();
#ifdef DEBUG #ifdef DEBUG
// TODO: remove the uglyness, see bug 598468. // TODO: remove the uglyness, see bug 598468.
NS_ASSERTION(gPreventAssertInCompareTreePosition || parent, NS_ASSERTION(gPreventAssertInCompareTreePosition || parent,

View File

@ -2365,11 +2365,8 @@ nsPrintJob::ReflowPrintObject(const UniquePtr<nsPrintObject>& aPO)
DeleteUnselectedNodes(aPO->mDocument->GetOriginalDocument(), aPO->mDocument); DeleteUnselectedNodes(aPO->mDocument->GetOriginalDocument(), aPO->mDocument);
} }
aPO->mPresShell->StyleSet()->EndUpdate();
// The pres shell now owns the style set object. // The pres shell now owns the style set object.
bool doReturn = false;; bool doReturn = false;;
bool documentIsTopLevel = false; bool documentIsTopLevel = false;
nsSize adjSize; nsSize adjSize;

View File

@ -177,6 +177,17 @@ ErrorReporter::ShouldReportErrors(const nsIDocument& aDoc)
return report; return report;
} }
static nsINode*
SheetOwner(const StyleSheet& aSheet)
{
if (nsINode* owner = aSheet.GetOwnerNode()) {
return owner;
}
auto* associated = aSheet.GetAssociatedDocumentOrShadowRoot();
return associated ? &associated->AsNode() : nullptr;
}
bool bool
ErrorReporter::ShouldReportErrors() ErrorReporter::ShouldReportErrors()
{ {
@ -194,10 +205,7 @@ ErrorReporter::ShouldReportErrors()
} }
if (mSheet) { if (mSheet) {
nsINode* owner = mSheet->GetOwnerNode() nsINode* owner = SheetOwner(*mSheet);
? mSheet->GetOwnerNode()
: mSheet->GetAssociatedDocument();
if (owner && ShouldReportErrors(*owner->OwnerDoc())) { if (owner && ShouldReportErrors(*owner->OwnerDoc())) {
return true; return true;
} }

View File

@ -1222,9 +1222,7 @@ Loader::InsertSheetInDoc(StyleSheet* aSheet,
linkingElement->SetStyleSheet(aSheet); // This sets the ownerNode on the sheet linkingElement->SetStyleSheet(aSheet); // This sets the ownerNode on the sheet
} }
aDocument->BeginUpdate(UPDATE_STYLE);
aDocument->InsertStyleSheetAt(aSheet, insertionPoint); aDocument->InsertStyleSheetAt(aSheet, insertionPoint);
aDocument->EndUpdate(UPDATE_STYLE);
LOG((" Inserting into document at position %d", insertionPoint)); LOG((" Inserting into document at position %d", insertionPoint));
return NS_OK; return NS_OK;
@ -1243,8 +1241,7 @@ Loader::InsertSheetInDoc(StyleSheet* aSheet,
* bug 1220506.) * bug 1220506.)
*/ */
nsresult nsresult
Loader::InsertChildSheet(StyleSheet* aSheet, Loader::InsertChildSheet(StyleSheet* aSheet, StyleSheet* aParentSheet)
StyleSheet* aParentSheet)
{ {
LOG(("css::Loader::InsertChildSheet")); LOG(("css::Loader::InsertChildSheet"));
MOZ_ASSERT(aSheet, "Nothing to insert"); MOZ_ASSERT(aSheet, "Nothing to insert");
@ -2161,11 +2158,9 @@ Loader::LoadChildSheet(StyleSheet* aParentSheet,
nsCOMPtr<nsINode> owningNode; nsCOMPtr<nsINode> owningNode;
// Check for an associated document: if none, don't bother walking up the // Check for an associated document or shadow root: if none, don't bother
// parent sheets. // walking up the parent sheets.
// if (aParentSheet->GetAssociatedDocumentOrShadowRoot()) {
// FIXME(emilio): This looks wrong for Shadow DOM.
if (aParentSheet->GetAssociatedDocument()) {
StyleSheet* topSheet = aParentSheet; StyleSheet* topSheet = aParentSheet;
while (StyleSheet* parent = topSheet->GetParentSheet()) { while (StyleSheet* parent = topSheet->GetParentSheet()) {
topSheet = parent; topSheet = parent;

View File

@ -45,11 +45,6 @@ template<typename Func>
nsresult nsresult
MediaList::DoMediaChange(Func aCallback) MediaList::DoMediaChange(Func aCallback)
{ {
nsCOMPtr<nsIDocument> doc;
if (mStyleSheet) {
doc = mStyleSheet->GetAssociatedDocument();
}
mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
if (mStyleSheet) { if (mStyleSheet) {
mStyleSheet->WillDirty(); mStyleSheet->WillDirty();
} }

View File

@ -9,6 +9,7 @@
#include "Rule.h" #include "Rule.h"
#include "mozilla/css/GroupRule.h" #include "mozilla/css/GroupRule.h"
#include "mozilla/dom/DocumentOrShadowRoot.h"
#include "nsCCUncollectableMarker.h" #include "nsCCUncollectableMarker.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsWrapperCacheInlines.h" #include "nsWrapperCacheInlines.h"
@ -47,12 +48,12 @@ Rule::IsKnownLive() const
return false; return false;
} }
if (!sheet->IsOwnedByDocument()) { if (!sheet->IsKeptAliveByDocument()) {
return false; return false;
} }
return nsCCUncollectableMarker::InGeneration( return nsCCUncollectableMarker::InGeneration(
sheet->GetAssociatedDocument()->GetMarkedCCGeneration()); GetComposedDoc()->GetMarkedCCGeneration());
} }
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(Rule) NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(Rule)

View File

@ -10,6 +10,7 @@
#define mozilla_css_Rule_h___ #define mozilla_css_Rule_h___
#include "mozilla/dom/CSSRuleBinding.h" #include "mozilla/dom/CSSRuleBinding.h"
#include "mozilla/dom/DocumentOrShadowRoot.h"
#include "mozilla/StyleSheet.h" #include "mozilla/StyleSheet.h"
#include "mozilla/MemoryReporting.h" #include "mozilla/MemoryReporting.h"
#include "nsISupports.h" #include "nsISupports.h"
@ -44,7 +45,7 @@ protected:
{ {
} }
virtual ~Rule() {} virtual ~Rule() = default;
public: public:
@ -60,11 +61,12 @@ public:
StyleSheet* GetStyleSheet() const { return mSheet; } StyleSheet* GetStyleSheet() const { return mSheet; }
// Return the document the rule lives in, if any // Return the document the rule applies to, if any.
nsIDocument* GetDocument() const //
// Suitable for style updates, and that's about it.
nsIDocument* GetComposedDoc() const
{ {
StyleSheet* sheet = GetStyleSheet(); return mSheet ? mSheet->GetComposedDoc() : nullptr;
return sheet ? sheet->GetAssociatedDocument() : nullptr;
} }
virtual void SetStyleSheet(StyleSheet* aSheet); virtual void SetStyleSheet(StyleSheet* aSheet);
@ -99,7 +101,14 @@ public:
void SetCssText(const nsAString& aCssText); void SetCssText(const nsAString& aCssText);
Rule* GetParentRule() const; Rule* GetParentRule() const;
StyleSheet* GetParentStyleSheet() const { return GetStyleSheet(); } StyleSheet* GetParentStyleSheet() const { return GetStyleSheet(); }
nsIDocument* GetParentObject() const { return GetDocument(); } nsINode* GetParentObject() const
{
if (!mSheet) {
return nullptr;
}
auto* associated = mSheet->GetAssociatedDocumentOrShadowRoot();
return associated ? &associated->AsNode() : nullptr;
}
protected: protected:
// True if we're known-live for cycle collection purposes. // True if we're known-live for cycle collection purposes.

View File

@ -2134,6 +2134,25 @@ Gecko_URLValue_SizeOfIncludingThis(URLValue* aURL)
return aURL->SizeOfIncludingThis(GeckoURLValueMallocSizeOf); return aURL->SizeOfIncludingThis(GeckoURLValueMallocSizeOf);
} }
void
Gecko_GetComputedURLSpec(const URLValueData* aURL, nsCString* aOut)
{
MOZ_ASSERT(aURL);
MOZ_ASSERT(aOut);
if (aURL->IsLocalRef()) {
aOut->Assign(aURL->GetString());
return;
}
if (nsIURI* uri = aURL->GetURI()) {
nsresult rv = uri->GetSpec(*aOut);
if (NS_SUCCEEDED(rv)) {
return;
}
}
aOut->AssignLiteral("about:invalid");
}
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(css::URLValue, CSSURLValue); NS_IMPL_THREADSAFE_FFI_REFCOUNTING(css::URLValue, CSSURLValue);
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(URLExtraData, URLExtraData); NS_IMPL_THREADSAFE_FFI_REFCOUNTING(URLExtraData, URLExtraData);

View File

@ -545,6 +545,7 @@ void Gecko_nsStyleSVG_CopyContextProperties(nsStyleSVG* dst, const nsStyleSVG* s
mozilla::css::URLValue* Gecko_NewURLValue(ServoBundledURI uri); mozilla::css::URLValue* Gecko_NewURLValue(ServoBundledURI uri);
size_t Gecko_URLValue_SizeOfIncludingThis(mozilla::css::URLValue* url); size_t Gecko_URLValue_SizeOfIncludingThis(mozilla::css::URLValue* url);
void Gecko_GetComputedURLSpec(const mozilla::css::URLValueData* url, nsCString* spec);
NS_DECL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::URLValue, CSSURLValue); NS_DECL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::URLValue, CSSURLValue);
NS_DECL_THREADSAFE_FFI_REFCOUNTING(RawGeckoURLExtraData, URLExtraData); NS_DECL_THREADSAFE_FFI_REFCOUNTING(RawGeckoURLExtraData, URLExtraData);

View File

@ -440,7 +440,7 @@ hide-types = [
"ComputedStyleBorrowedOrNull", "ComputedStyleBorrowedOrNull",
] ]
raw-lines = [ raw-lines = [
"pub use nsstring::{nsACString, nsAString, nsString, nsStringRepr};", "pub use nsstring::{nsACString, nsAString, nsCString, nsString, nsStringRepr};",
"use gecko_bindings::structs::nsStyleTransformMatrix;", "use gecko_bindings::structs::nsStyleTransformMatrix;",
"use gecko_bindings::structs::nsTArray;", "use gecko_bindings::structs::nsTArray;",
"type nsACString_internal = nsACString;", "type nsACString_internal = nsACString;",

View File

@ -56,10 +56,8 @@ ServoCounterStyleRule::GetName(nsAString& aName)
void void
ServoCounterStyleRule::SetName(const nsAString& aName) ServoCounterStyleRule::SetName(const nsAString& aName)
{ {
nsIDocument* doc = GetDocument();
NS_ConvertUTF16toUTF8 name(aName); NS_ConvertUTF16toUTF8 name(aName);
if (Servo_CounterStyleRule_SetName(mRawRule, &name)) { if (Servo_CounterStyleRule_SetName(mRawRule, &name)) {
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
if (StyleSheet* sheet = GetStyleSheet()) { if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this); sheet->RuleChanged(this);
} }
@ -80,8 +78,6 @@ ServoCounterStyleRule::SetName(const nsAString& aName)
NS_ConvertUTF16toUTF8 value(aValue); \ NS_ConvertUTF16toUTF8 value(aValue); \
if (Servo_CounterStyleRule_SetDescriptor( \ if (Servo_CounterStyleRule_SetDescriptor( \
mRawRule, eCSSCounterDesc_##method_, &value)) { \ mRawRule, eCSSCounterDesc_##method_, &value)) { \
nsIDocument* doc = GetDocument(); \
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true); \
if (StyleSheet* sheet = GetStyleSheet()) { \ if (StyleSheet* sheet = GetStyleSheet()) { \
sheet->RuleChanged(this); \ sheet->RuleChanged(this); \
} \ } \

View File

@ -131,7 +131,7 @@ ServoFontFaceRuleDecl::GetParentRule()
nsINode* nsINode*
ServoFontFaceRuleDecl::GetParentObject() ServoFontFaceRuleDecl::GetParentObject()
{ {
return ContainingRule()->GetDocument(); return ContainingRule()->GetParentObject();
} }
JSObject* JSObject*

View File

@ -66,7 +66,7 @@ public:
nsINode* GetParentObject() final nsINode* GetParentObject() final
{ {
return mRule ? mRule->GetDocument() : nullptr; return mRule ? mRule->GetParentObject() : nullptr;
} }
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
@ -149,9 +149,6 @@ template<typename Func>
void void
ServoKeyframeRule::UpdateRule(Func aCallback) ServoKeyframeRule::UpdateRule(Func aCallback)
{ {
nsIDocument* doc = GetDocument();
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
aCallback(); aCallback();
if (StyleSheet* sheet = GetStyleSheet()) { if (StyleSheet* sheet = GetStyleSheet()) {

View File

@ -232,11 +232,7 @@ template<typename Func>
void void
ServoKeyframesRule::UpdateRule(Func aCallback) ServoKeyframesRule::UpdateRule(Func aCallback)
{ {
nsIDocument* doc = GetDocument();
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
aCallback(); aCallback();
if (StyleSheet* sheet = GetStyleSheet()) { if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this); sheet->RuleChanged(this);
} }

View File

@ -55,7 +55,7 @@ ServoPageRuleDeclaration::GetParentRule()
nsINode* nsINode*
ServoPageRuleDeclaration::GetParentObject() ServoPageRuleDeclaration::GetParentObject()
{ {
return Rule()->GetDocument(); return Rule()->GetParentObject();
} }
DeclarationBlock* DeclarationBlock*

View File

@ -58,7 +58,7 @@ ServoStyleRuleDeclaration::GetParentRule()
nsINode* nsINode*
ServoStyleRuleDeclaration::GetParentObject() ServoStyleRuleDeclaration::GetParentObject()
{ {
return Rule()->GetDocument(); return Rule()->GetParentObject();
} }
DeclarationBlock* DeclarationBlock*
@ -72,8 +72,6 @@ ServoStyleRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl)
{ {
ServoStyleRule* rule = Rule(); ServoStyleRule* rule = Rule();
if (RefPtr<StyleSheet> sheet = rule->GetStyleSheet()) { if (RefPtr<StyleSheet> sheet = rule->GetStyleSheet()) {
nsCOMPtr<nsIDocument> doc = sheet->GetAssociatedDocument();
mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
if (aDecl != mDecls) { if (aDecl != mDecls) {
mDecls->SetOwningRule(nullptr); mDecls->SetOwningRule(nullptr);
RefPtr<ServoDeclarationBlock> decls = aDecl->AsServo(); RefPtr<ServoDeclarationBlock> decls = aDecl->AsServo();
@ -197,10 +195,6 @@ void
ServoStyleRule::SetSelectorText(const nsAString& aSelectorText) ServoStyleRule::SetSelectorText(const nsAString& aSelectorText)
{ {
if (RefPtr<StyleSheet> sheet = GetStyleSheet()) { if (RefPtr<StyleSheet> sheet = GetStyleSheet()) {
nsIDocument* doc = sheet->GetAssociatedDocument();
mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
// StyleRule lives inside of the Inner, it is unsafe to call WillDirty // StyleRule lives inside of the Inner, it is unsafe to call WillDirty
// if sheet does not already have a unique Inner. // if sheet does not already have a unique Inner.
sheet->AssertHasUniqueInner(); sheet->AssertHasUniqueInner();
@ -218,7 +212,6 @@ ServoStyleRule::GetSelectorCount()
{ {
uint32_t aCount; uint32_t aCount;
Servo_StyleRule_GetSelectorCount(mRawRule, &aCount); Servo_StyleRule_GetSelectorCount(mRawRule, &aCount);
return aCount; return aCount;
} }

View File

@ -194,15 +194,6 @@ ServoStyleSet::Shutdown()
mStyleRuleMap = nullptr; mStyleRuleMap = nullptr;
} }
void
ServoStyleSet::InvalidateStyleForCSSRuleChanges()
{
MOZ_ASSERT(StylistNeedsUpdate());
if (nsPresContext* pc = GetPresContext()) {
pc->RestyleManager()->PostRestyleEventForCSSRuleChanges();
}
}
void void
ServoStyleSet::RecordShadowStyleChange(ShadowRoot& aShadowRoot) ServoStyleSet::RecordShadowStyleChange(ShadowRoot& aShadowRoot)
{ {
@ -386,17 +377,6 @@ ServoStyleSet::SetAuthorStyleDisabled(bool aStyleDisabled)
SetStylistStyleSheetsDirty(); SetStylistStyleSheetsDirty();
} }
void
ServoStyleSet::BeginUpdate()
{
}
nsresult
ServoStyleSet::EndUpdate()
{
return NS_OK;
}
already_AddRefed<ComputedStyle> already_AddRefed<ComputedStyle>
ServoStyleSet::ResolveStyleFor(Element* aElement, ServoStyleSet::ResolveStyleFor(Element* aElement,
ComputedStyle* aParentContext, ComputedStyle* aParentContext,

Some files were not shown because too many files have changed in this diff Show More