mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
e078579f28
@ -39,35 +39,56 @@ support-files =
|
||||
plugin_zoom.html
|
||||
|
||||
[browser_bug743421.js]
|
||||
tags = blocklist
|
||||
[browser_bug744745.js]
|
||||
[browser_bug787619.js]
|
||||
[browser_bug797677.js]
|
||||
[browser_bug812562.js]
|
||||
tags = blocklist
|
||||
[browser_bug818118.js]
|
||||
[browser_bug820497.js]
|
||||
[browser_clearplugindata.js]
|
||||
tags = blocklist
|
||||
[browser_CTP_context_menu.js]
|
||||
skip-if = toolkit == "gtk2" || toolkit == "gtk3" # fails intermittently on Linux (bug 909342)
|
||||
tags = blocklist
|
||||
[browser_CTP_crashreporting.js]
|
||||
skip-if = !crashreporter
|
||||
tags = blocklist
|
||||
[browser_CTP_data_urls.js]
|
||||
tags = blocklist
|
||||
[browser_CTP_drag_drop.js]
|
||||
tags = blocklist
|
||||
[browser_CTP_hide_overlay.js]
|
||||
tags = blocklist
|
||||
[browser_CTP_iframe.js]
|
||||
tags = blocklist
|
||||
[browser_CTP_multi_allow.js]
|
||||
tags = blocklist
|
||||
[browser_CTP_nonplugins.js]
|
||||
tags = blocklist
|
||||
[browser_CTP_notificationBar.js]
|
||||
tags = blocklist
|
||||
[browser_CTP_outsideScrollArea.js]
|
||||
tags = blocklist
|
||||
[browser_CTP_remove_navigate.js]
|
||||
tags = blocklist
|
||||
[browser_CTP_resize.js]
|
||||
tags = blocklist
|
||||
[browser_CTP_zoom.js]
|
||||
tags = blocklist
|
||||
[browser_blocking.js]
|
||||
tags = blocklist
|
||||
[browser_iterate_hidden_plugins.js]
|
||||
[browser_plugins_added_dynamically.js]
|
||||
tags = blocklist
|
||||
[browser_pluginnotification.js]
|
||||
tags = blocklist
|
||||
[browser_plugin_reloading.js]
|
||||
tags = blocklist
|
||||
[browser_blocklist_content.js]
|
||||
skip-if = !e10s
|
||||
tags = blocklist
|
||||
[browser_globalplugin_crashinfobar.js]
|
||||
skip-if = !crashreporter
|
||||
[browser_pluginCrashCommentAndURL.js]
|
||||
|
@ -19,5 +19,6 @@ support-files =
|
||||
[browser_aboutHome_activation.js]
|
||||
[browser_addons.js]
|
||||
[browser_blocklist.js]
|
||||
tags = blocklist
|
||||
[browser_share.js]
|
||||
[browser_social_activation.js]
|
||||
|
@ -6,6 +6,7 @@ support-files =
|
||||
browser_legacy_webext.xpi
|
||||
browser_webext_permissions.xpi
|
||||
browser_webext_nopermissions.xpi
|
||||
browser_webext_unsigned.xpi
|
||||
browser_webext_update1.xpi
|
||||
browser_webext_update2.xpi
|
||||
browser_webext_update_icon1.xpi
|
||||
@ -21,5 +22,7 @@ support-files =
|
||||
[browser_permissions_installTrigger.js]
|
||||
[browser_permissions_local_file.js]
|
||||
[browser_permissions_mozAddonManager.js]
|
||||
[browser_permissions_unsigned.js]
|
||||
skip-if = require_signing
|
||||
[browser_update_interactive.js]
|
||||
[browser_update_interactive_noprompt.js]
|
||||
|
@ -0,0 +1,44 @@
|
||||
"use strict";
|
||||
|
||||
const ID = "permissions@test.mozilla.org";
|
||||
const WARNING_ICON = "chrome://browser/skin/warning.svg";
|
||||
|
||||
add_task(async function test_unsigned() {
|
||||
await SpecialPowers.pushPrefEnv({set: [
|
||||
["extensions.webapi.testing", true],
|
||||
["extensions.install.requireBuiltInCerts", false],
|
||||
|
||||
// XXX remove this when prompts are enabled by default
|
||||
["extensions.webextPermissionPrompts", true],
|
||||
]});
|
||||
|
||||
let testURI = makeURI("https://example.com/");
|
||||
Services.perms.add(testURI, "install", Services.perms.ALLOW_ACTION);
|
||||
registerCleanupFunction(() => Services.perms.remove(testURI, "install"));
|
||||
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
|
||||
|
||||
gBrowser.selectedBrowser.loadURI(`${BASE}/file_install_extensions.html`);
|
||||
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
|
||||
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, `${BASE}/browser_webext_unsigned.xpi`, function*(url) {
|
||||
content.wrappedJSObject.installTrigger(url);
|
||||
});
|
||||
|
||||
let panel = await promisePopupNotificationShown("addon-webext-permissions");
|
||||
|
||||
is(panel.getAttribute("icon"), WARNING_ICON);
|
||||
checkPermissionString(document.getElementById("addon-webext-perm-text").textContent,
|
||||
"webextPerms.unsignedWarning", null,
|
||||
"Install notification includes unsigned warning");
|
||||
|
||||
// cancel the install
|
||||
let promise = promiseInstallEvent({id: ID}, "onInstallCancelled");
|
||||
panel.secondaryButton.click();
|
||||
await promise;
|
||||
|
||||
let addon = await AddonManager.getAddonByID(ID);
|
||||
is(addon, null, "Extension is not installed");
|
||||
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
});
|
Binary file not shown.
@ -41,6 +41,8 @@ xpinstallDisabledButton.accesskey=n
|
||||
# Note, this string will be used as raw markup. Avoid characters like <, >, &
|
||||
webextPerms.header=Add %S?
|
||||
|
||||
webextPerms.unsignedWarning=Caution: This add-on is unverified. Malicious add-ons can steal your private information or compromise your computer. Only install this add-on if you trust the source.
|
||||
|
||||
# LOCALIZATION NOTE (webextPerms.listIntro)
|
||||
# This string will be followed by a list of permissions requested
|
||||
# by the webextension.
|
||||
|
@ -144,13 +144,17 @@ this.ExtensionsUI = {
|
||||
progressNotification.remove();
|
||||
}
|
||||
|
||||
info.unsigned = info.addon.signedState <= AddonManager.SIGNEDSTATE_MISSING;
|
||||
let strings = this._buildStrings(info);
|
||||
|
||||
// If this is an update with no promptable permissions, just apply it
|
||||
if (info.type == "update" && strings.msgs.length == 0) {
|
||||
info.resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
let icon = info.unsigned ? "chrome://browser/skin/warning.svg" : info.icon;
|
||||
|
||||
let histkey;
|
||||
if (info.type == "sideload") {
|
||||
histkey = "sideload";
|
||||
@ -164,7 +168,7 @@ this.ExtensionsUI = {
|
||||
histkey = "installWeb";
|
||||
}
|
||||
|
||||
this.showPermissionsPrompt(target, strings, info.icon, histkey)
|
||||
this.showPermissionsPrompt(target, strings, icon, histkey)
|
||||
.then(answer => {
|
||||
if (answer) {
|
||||
info.resolve();
|
||||
@ -298,7 +302,8 @@ this.ExtensionsUI = {
|
||||
let addonName = `<span class="addon-webext-name">${name}</span>`;
|
||||
|
||||
result.header = bundle.formatStringFromName("webextPerms.header", [addonName], 1);
|
||||
result.text = "";
|
||||
result.text = info.unsigned ?
|
||||
bundle.GetStringFromName("webextPerms.unsignedWarning") : "";
|
||||
result.listIntro = bundle.GetStringFromName("webextPerms.listIntro");
|
||||
|
||||
result.acceptText = bundle.GetStringFromName("webextPerms.add.label");
|
||||
|
@ -80,7 +80,7 @@ var SelfSupportBackendInternal = {
|
||||
|
||||
this._log.trace("init");
|
||||
|
||||
Preferences.observe(PREF_BRANCH_LOG, this._configureLogging, this);
|
||||
Services.prefs.addObserver(PREF_BRANCH_LOG, this, false);
|
||||
|
||||
// Only allow to use SelfSupport if Unified Telemetry is enabled.
|
||||
let reportingEnabled = IS_UNIFIED_TELEMETRY;
|
||||
@ -111,7 +111,7 @@ var SelfSupportBackendInternal = {
|
||||
uninit() {
|
||||
this._log.trace("uninit");
|
||||
|
||||
Preferences.ignore(PREF_BRANCH_LOG, this._configureLogging, this);
|
||||
Services.prefs.removeObserver(PREF_BRANCH_LOG, this);
|
||||
|
||||
// Cancel delayed loading, if still active, when shutting down.
|
||||
clearTimeout(this._delayedLoadTimerId);
|
||||
@ -148,6 +148,8 @@ var SelfSupportBackendInternal = {
|
||||
if (aTopic === "sessionstore-windows-restored") {
|
||||
Services.obs.removeObserver(this, "sessionstore-windows-restored");
|
||||
this._delayedLoadTimerId = setTimeout(this._loadSelfSupport.bind(this), STARTUP_DELAY_MS);
|
||||
} else if (aTopic === "nsPref:changed") {
|
||||
this._configureLogging();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1490,14 +1490,7 @@ toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
#urlbar[focused="true"],
|
||||
.searchbar-textbox[focused="true"] {
|
||||
border-color: -moz-mac-focusring;
|
||||
box-shadow: @focusRingShadow@;
|
||||
}
|
||||
|
||||
@media (-moz-mac-yosemite-theme) {
|
||||
#urlbar[focused="true"],
|
||||
.searchbar-textbox[focused="true"] {
|
||||
box-shadow: @yosemiteFocusRingShadow@;
|
||||
}
|
||||
box-shadow: var(--focus-ring-box-shadow);
|
||||
}
|
||||
|
||||
#urlbar-container {
|
||||
@ -1572,8 +1565,7 @@ toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
}
|
||||
|
||||
#identity-box:-moz-focusring {
|
||||
box-shadow: 0 0 2px 1px -moz-mac-focusring inset,
|
||||
0 0 2px 2px -moz-mac-focusring;
|
||||
box-shadow: var(--focus-ring-box-shadow);
|
||||
border-inline-end-style: none;
|
||||
padding-inline-end: 5px;
|
||||
}
|
||||
@ -2070,7 +2062,7 @@ html|span.ac-emphasize-text-url {
|
||||
#editBMPanel_rows > row > textbox[focused="true"],
|
||||
#editBMPanel_rows > row > hbox > textbox[focused="true"] {
|
||||
border-color: -moz-mac-focusring !important;
|
||||
box-shadow: @focusRingShadow@;
|
||||
box-shadow: var(--focus-ring-box-shadow);
|
||||
}
|
||||
|
||||
/**** HUD style buttons ****/
|
||||
@ -2090,7 +2082,7 @@ html|span.ac-emphasize-text-url {
|
||||
|
||||
.editBookmarkPanelHeaderButton:-moz-focusring,
|
||||
.editBookmarkPanelBottomButton:-moz-focusring {
|
||||
@hudButtonFocused@
|
||||
box-shadow: var(--focus-ring-box-shadow);
|
||||
}
|
||||
|
||||
.editBookmarkPanelBottomButton[default="true"] {
|
||||
@ -2144,7 +2136,7 @@ html|span.ac-emphasize-text-url {
|
||||
}
|
||||
|
||||
#editBMPanel_newFolderButton:-moz-focusring {
|
||||
@hudButtonFocused@
|
||||
box-shadow: var(--focus-ring-box-shadow);
|
||||
}
|
||||
|
||||
#editBMPanel_newFolderButton .button-text {
|
||||
@ -2163,7 +2155,7 @@ html|span.ac-emphasize-text-url {
|
||||
}
|
||||
|
||||
#editBMPanel_folderMenuList:-moz-focusring {
|
||||
@hudButtonFocused@
|
||||
box-shadow: var(--focus-ring-box-shadow);
|
||||
}
|
||||
|
||||
#editBMPanel_folderMenuList[open="true"],
|
||||
@ -2203,7 +2195,7 @@ html|span.ac-emphasize-text-url {
|
||||
#editBMPanel_folderTree:-moz-focusring,
|
||||
#editBMPanel_tagsSelector:-moz-focusring {
|
||||
border-color: -moz-mac-focusring;
|
||||
box-shadow: @focusRingShadow@;
|
||||
box-shadow: var(--focus-ring-box-shadow);
|
||||
}
|
||||
|
||||
#editBMPanel_folderTree {
|
||||
@ -2229,7 +2221,7 @@ html|span.ac-emphasize-text-url {
|
||||
|
||||
#editBookmarkPanel .expander-up:-moz-focusring,
|
||||
#editBookmarkPanel .expander-down:-moz-focusring {
|
||||
@hudButtonFocused@
|
||||
box-shadow: var(--focus-ring-box-shadow);
|
||||
}
|
||||
|
||||
#editBookmarkPanel .expander-up:hover:active,
|
||||
@ -2533,7 +2525,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
||||
.tabbrowser-tab:focus > .tab-stack > .tab-content > .tab-label-container:not([pinned]),
|
||||
.tabbrowser-tab:focus > .tab-stack > .tab-content > .tab-icon-image[pinned],
|
||||
.tabbrowser-tab:focus > .tab-stack > .tab-content > .tab-throbber[pinned] {
|
||||
box-shadow: @focusRingShadow@;
|
||||
box-shadow: var(--focus-ring-box-shadow);
|
||||
}
|
||||
|
||||
#TabsToolbar {
|
||||
|
@ -14,11 +14,11 @@
|
||||
}
|
||||
|
||||
.identity-popup-expander:-moz-focusring > .button-box {
|
||||
@hudButtonFocused@
|
||||
box-shadow: var(--focus-ring-box-shadow);
|
||||
}
|
||||
|
||||
.identity-popup-permission-remove-button:-moz-focusring {
|
||||
box-shadow: @focusRingShadow@;
|
||||
box-shadow: var(--focus-ring-box-shadow);
|
||||
}
|
||||
|
||||
#identity-popup-multiView > .panel-viewcontainer > .panel-viewstack > .panel-subviews {
|
||||
@ -49,6 +49,7 @@
|
||||
#tracking-action-unblock:-moz-focusring,
|
||||
#tracking-action-unblock-private:-moz-focusring,
|
||||
#identity-popup-securityView-body > button:-moz-focusring {
|
||||
@hudButtonFocused@
|
||||
box-shadow: var(--focus-ring-box-shadow);
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,4 +10,3 @@
|
||||
%define fgTabBackgroundColor transparent
|
||||
%define hudButton -moz-appearance: none; color: #434343; border-radius: 4px; border: 1px solid #b5b5b5; background: linear-gradient(#fff, #f2f2f2); box-shadow: inset 0 1px rgba(255,255,255,.8), inset 0 0 1px rgba(255,255, 255,.25), 0 1px rgba(255,255,255,.3); background-clip: padding-box; background-origin: padding-box; padding: 2px 6px;
|
||||
%define hudButtonPressed box-shadow: inset 0 1px 4px -3px #000, 0 1px rgba(255,255,255,.3);
|
||||
%define hudButtonFocused box-shadow: 0 0 1px -moz-mac-focusring inset, 0 0 4px 1px -moz-mac-focusring, 0 0 2px 1px -moz-mac-focusring;
|
||||
|
@ -85,6 +85,12 @@ function* spawnTest() {
|
||||
}
|
||||
]);
|
||||
|
||||
// Hide all highlighters before finishing the test.
|
||||
yield helpers.audit(options, [{
|
||||
setup: "unhighlight",
|
||||
exec: {}
|
||||
}]);
|
||||
|
||||
yield helpers.closeToolbar(options);
|
||||
yield helpers.closeTab(options);
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ function GridInspector(inspector, window) {
|
||||
|
||||
this.onGridLayoutChange = this.onGridLayoutChange.bind(this);
|
||||
this.onHighlighterChange = this.onHighlighterChange.bind(this);
|
||||
this.onMarkupMutation = this.onMarkupMutation.bind(this);
|
||||
this.onSetGridOverlayColor = this.onSetGridOverlayColor.bind(this);
|
||||
this.onShowBoxModelHighlighterForNode =
|
||||
this.onShowBoxModelHighlighterForNode.bind(this);
|
||||
@ -86,6 +87,7 @@ GridInspector.prototype = {
|
||||
|
||||
this.highlighters.on("grid-highlighter-hidden", this.onHighlighterChange);
|
||||
this.highlighters.on("grid-highlighter-shown", this.onHighlighterChange);
|
||||
this.inspector.on("markupmutation", this.onMarkupMutation);
|
||||
this.inspector.sidebar.on("select", this.onSidebarSelect);
|
||||
|
||||
this.onSidebarSelect();
|
||||
@ -98,6 +100,7 @@ GridInspector.prototype = {
|
||||
destroy() {
|
||||
this.highlighters.off("grid-highlighter-hidden", this.onHighlighterChange);
|
||||
this.highlighters.off("grid-highlighter-shown", this.onHighlighterChange);
|
||||
this.inspector.off("markupmutation", this.onMarkupMutation);
|
||||
this.inspector.sidebar.off("select", this.onSidebarSelect);
|
||||
this.layoutInspector.off("grid-layout-changed", this.onGridLayoutChange);
|
||||
|
||||
@ -298,6 +301,14 @@ GridInspector.prototype = {
|
||||
this.store.dispatch(updateGridColor(nodeFront, color));
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for the "markupmutation" event fired by the inspector. On markup mutations,
|
||||
* update the grid panel content.
|
||||
*/
|
||||
onMarkupMutation() {
|
||||
this.updateGridPanel();
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for a change in the grid overlay color picker for a grid container.
|
||||
*
|
||||
|
@ -86,6 +86,8 @@ const PORTRAIT_MODE_WIDTH = 700;
|
||||
* to source-mapped files)
|
||||
*/
|
||||
function Inspector(toolbox) {
|
||||
EventEmitter.decorate(this);
|
||||
|
||||
this._toolbox = toolbox;
|
||||
this._target = toolbox.target;
|
||||
this.panelDoc = window.document;
|
||||
@ -114,8 +116,6 @@ function Inspector(toolbox) {
|
||||
|
||||
this._target.on("will-navigate", this._onBeforeNavigate);
|
||||
this._detectingActorFeatures = this._detectActorFeatures();
|
||||
|
||||
EventEmitter.decorate(this);
|
||||
}
|
||||
|
||||
Inspector.prototype = {
|
||||
|
@ -150,6 +150,7 @@ skip-if = os == "mac" # Bug 1245996 : click on scrollbar not working on OSX
|
||||
[browser_rules_filtereditor-commit-on-ENTER.js]
|
||||
[browser_rules_filtereditor-revert-on-ESC.js]
|
||||
skip-if = (os == "win" && debug) # bug 963492: win.
|
||||
[browser_rules_grid-highlighter-on-mutation.js]
|
||||
[browser_rules_grid-highlighter-on-navigate.js]
|
||||
[browser_rules_grid-highlighter-on-reload.js]
|
||||
[browser_rules_grid-highlighter-restored-after-reload.js]
|
||||
|
@ -0,0 +1,44 @@
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Tests that the grid highlighter is hidden when the highlighted grid container is
|
||||
// removed from the page.
|
||||
|
||||
const TEST_URI = `
|
||||
<style type='text/css'>
|
||||
#grid {
|
||||
display: grid;
|
||||
}
|
||||
</style>
|
||||
<div id="grid">
|
||||
<div id="cell1">cell1</div>
|
||||
<div id="cell2">cell2</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view, testActor} = yield openRuleView();
|
||||
let highlighters = view.highlighters;
|
||||
|
||||
yield selectNode("#grid", inspector);
|
||||
let container = getRuleViewProperty(view, "#grid", "display").valueSpan;
|
||||
let gridToggle = container.querySelector(".ruleview-grid");
|
||||
|
||||
info("Toggling ON the CSS grid highlighter from the rule-view.");
|
||||
let onHighlighterShown = highlighters.once("grid-highlighter-shown");
|
||||
gridToggle.click();
|
||||
yield onHighlighterShown;
|
||||
ok(highlighters.gridHighlighterShown, "CSS grid highlighter is shown.");
|
||||
|
||||
let onHighlighterHidden = highlighters.once("grid-highlighter-hidden");
|
||||
info("Remove the #grid container in the content page");
|
||||
testActor.eval(`
|
||||
content.document.querySelector("#grid").remove();
|
||||
`);
|
||||
yield onHighlighterHidden;
|
||||
ok(!highlighters.gridHighlighterShown, "CSS grid highlighter is hidden.");
|
||||
});
|
@ -42,13 +42,15 @@ function HighlightersOverlay(inspector) {
|
||||
};
|
||||
|
||||
this.onClick = this.onClick.bind(this);
|
||||
this.onMarkupMutation = this.onMarkupMutation.bind(this);
|
||||
this.onMouseMove = this.onMouseMove.bind(this);
|
||||
this.onMouseOut = this.onMouseOut.bind(this);
|
||||
this.onWillNavigate = this.onWillNavigate.bind(this);
|
||||
this.onNavigate = this.onNavigate.bind(this);
|
||||
this._handleRejection = this._handleRejection.bind(this);
|
||||
|
||||
// Add target events, not specific to a given view.
|
||||
// Add inspector events, not specific to a given view.
|
||||
this.inspector.on("markupmutation", this.onMarkupMutation);
|
||||
this.inspector.target.on("navigate", this.onNavigate);
|
||||
this.inspector.target.on("will-navigate", this.onWillNavigate);
|
||||
|
||||
@ -428,6 +430,30 @@ HighlightersOverlay.prototype = {
|
||||
this._hideHoveredHighlighter();
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler function for "markupmutation" events. Hides the grid highlighter if the grid
|
||||
* container is no longer in the DOM tree.
|
||||
*/
|
||||
onMarkupMutation: Task.async(function* (evt, mutations) {
|
||||
let hasInterestingMutation = mutations.some(mut => mut.type === "childList");
|
||||
if (!hasInterestingMutation || !this.gridHighlighterShown) {
|
||||
// Bail out if the mutations did not remove nodes, or if no grid highlighter is
|
||||
// displayed.
|
||||
return;
|
||||
}
|
||||
|
||||
let nodeFront = this.gridHighlighterShown;
|
||||
|
||||
try {
|
||||
let isInTree = yield this.inspector.walker.isInDOMTree(nodeFront);
|
||||
if (!isInTree) {
|
||||
this.hideGridHighlighter(nodeFront);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Restore saved highlighter state after navigate.
|
||||
*/
|
||||
@ -464,7 +490,8 @@ HighlightersOverlay.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
// Remove target events.
|
||||
// Remove inspector events.
|
||||
this.inspector.off("markupmutation", this.onMarkupMutation);
|
||||
this.inspector.target.off("navigate", this.onNavigate);
|
||||
this.inspector.target.off("will-navigate", this.onWillNavigate);
|
||||
|
||||
|
@ -119,7 +119,7 @@ AutoRefreshHighlighter.prototype = {
|
||||
* Hide the highlighter
|
||||
*/
|
||||
hide: function () {
|
||||
if (!this._isNodeValid(this.currentNode)) {
|
||||
if (Cu.isDeadWrapper(this.highlighterEnv.window)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -52,11 +52,7 @@ const GRID_GAP_ALPHA = 0.5;
|
||||
/**
|
||||
* Cached used by `CssGridHighlighter.getGridGapPattern`.
|
||||
*/
|
||||
const gCachedGridPattern = new WeakMap();
|
||||
// WeakMap key for the Row grid pattern.
|
||||
const ROW_KEY = {};
|
||||
// WeakMap key for the Column grid pattern.
|
||||
const COLUMN_KEY = {};
|
||||
const gCachedGridPattern = new Map();
|
||||
|
||||
// That's the maximum size we can allocate for the canvas, in bytes. See:
|
||||
// http://searchfox.org/mozilla-central/source/gfx/thebes/gfxPrefs.h#401
|
||||
@ -362,22 +358,33 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the grid gap pattern used to render the gap regions.
|
||||
* Gets the grid gap pattern used to render the gap regions based on the device
|
||||
* pixel ratio given.
|
||||
*
|
||||
* @param {Number} devicePixelRatio
|
||||
* The device pixel ratio we want the pattern for.
|
||||
* @param {Object} dimension
|
||||
* Refers to the WeakMap key for the grid dimension type which is either the
|
||||
* constant COLUMN or ROW.
|
||||
* Refers to the Map key for the grid dimension type which is either the
|
||||
* constant COLUMNS or ROWS.
|
||||
* @return {CanvasPattern} grid gap pattern.
|
||||
*/
|
||||
getGridGapPattern(dimension) {
|
||||
if (gCachedGridPattern.has(dimension)) {
|
||||
return gCachedGridPattern.get(dimension);
|
||||
getGridGapPattern(devicePixelRatio, dimension) {
|
||||
let gridPatternMap = null;
|
||||
|
||||
if (gCachedGridPattern.has(devicePixelRatio)) {
|
||||
gridPatternMap = gCachedGridPattern.get(devicePixelRatio);
|
||||
} else {
|
||||
gridPatternMap = new Map();
|
||||
}
|
||||
|
||||
if (gridPatternMap.has(dimension)) {
|
||||
return gridPatternMap.get(dimension);
|
||||
}
|
||||
|
||||
// Create the diagonal lines pattern for the rendering the grid gaps.
|
||||
let canvas = createNode(this.win, { nodeType: "canvas" });
|
||||
canvas.width = GRID_GAP_PATTERN_WIDTH;
|
||||
canvas.height = GRID_GAP_PATTERN_HEIGHT;
|
||||
let width = canvas.width = GRID_GAP_PATTERN_WIDTH * devicePixelRatio;
|
||||
let height = canvas.height = GRID_GAP_PATTERN_HEIGHT * devicePixelRatio;
|
||||
|
||||
let ctx = canvas.getContext("2d");
|
||||
ctx.save();
|
||||
@ -385,12 +392,12 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
ctx.beginPath();
|
||||
ctx.translate(.5, .5);
|
||||
|
||||
if (dimension === COLUMN_KEY) {
|
||||
if (dimension === COLUMNS) {
|
||||
ctx.moveTo(0, 0);
|
||||
ctx.lineTo(GRID_GAP_PATTERN_WIDTH, GRID_GAP_PATTERN_HEIGHT);
|
||||
ctx.lineTo(width, height);
|
||||
} else {
|
||||
ctx.moveTo(GRID_GAP_PATTERN_WIDTH, 0);
|
||||
ctx.lineTo(0, GRID_GAP_PATTERN_HEIGHT);
|
||||
ctx.moveTo(width, 0);
|
||||
ctx.lineTo(0, height);
|
||||
}
|
||||
|
||||
ctx.strokeStyle = this.color;
|
||||
@ -399,7 +406,10 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
ctx.restore();
|
||||
|
||||
let pattern = ctx.createPattern(canvas, "repeat");
|
||||
gCachedGridPattern.set(dimension, pattern);
|
||||
|
||||
gridPatternMap.set(dimension, pattern);
|
||||
gCachedGridPattern.set(devicePixelRatio, gridPatternMap);
|
||||
|
||||
return pattern;
|
||||
},
|
||||
|
||||
@ -433,8 +443,7 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
},
|
||||
|
||||
_clearCache() {
|
||||
gCachedGridPattern.delete(ROW_KEY);
|
||||
gCachedGridPattern.delete(COLUMN_KEY);
|
||||
gCachedGridPattern.clear();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -555,7 +564,7 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
root.setAttribute("style",
|
||||
`position:absolute; width:${width}px;height:${height}px; overflow:hidden`);
|
||||
|
||||
setIgnoreLayoutChanges(false, this.highlighterEnv.window.document.documentElement);
|
||||
setIgnoreLayoutChanges(false, this.highlighterEnv.document.documentElement);
|
||||
return true;
|
||||
},
|
||||
|
||||
@ -695,7 +704,6 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
this.canvas.setAttribute("height", height);
|
||||
this.canvas.setAttribute("style",
|
||||
`width:${width / ratio}px;height:${height / ratio}px;`);
|
||||
this.ctx.scale(ratio, ratio);
|
||||
|
||||
this.ctx.clearRect(0, 0, width, height);
|
||||
},
|
||||
@ -821,6 +829,12 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
* The grid line type - "edge", "explicit", or "implicit".
|
||||
*/
|
||||
renderLine(linePos, startPos, endPos, dimensionType, lineType) {
|
||||
let ratio = this.win.devicePixelRatio;
|
||||
|
||||
linePos = Math.round(linePos * ratio);
|
||||
startPos = Math.round(startPos * ratio);
|
||||
endPos = Math.round(endPos * ratio);
|
||||
|
||||
this.ctx.save();
|
||||
this.ctx.setLineDash(GRID_LINES_PROPERTIES[lineType].lineDash);
|
||||
this.ctx.beginPath();
|
||||
@ -855,6 +869,11 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
* The grid dimension type which is either the constant COLUMNS or ROWS.
|
||||
*/
|
||||
renderGridLineNumber(lineNumber, linePos, startPos, dimensionType) {
|
||||
let ratio = this.win.devicePixelRatio;
|
||||
|
||||
linePos = Math.round(linePos * ratio);
|
||||
startPos = Math.round(startPos * ratio);
|
||||
|
||||
this.ctx.save();
|
||||
|
||||
let textWidth = this.ctx.measureText(lineNumber).width;
|
||||
@ -888,16 +907,21 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
* The grid dimension type which is either the constant COLUMNS or ROWS.
|
||||
*/
|
||||
renderGridGap(linePos, startPos, endPos, breadth, dimensionType) {
|
||||
let ratio = this.win.devicePixelRatio;
|
||||
|
||||
linePos = Math.round(linePos * ratio);
|
||||
startPos = Math.round(startPos * ratio);
|
||||
endPos = Math.round(endPos * ratio);
|
||||
breadth = Math.round(breadth * ratio);
|
||||
|
||||
this.ctx.save();
|
||||
this.ctx.fillStyle = this.getGridGapPattern(ratio, dimensionType);
|
||||
|
||||
if (dimensionType === COLUMNS) {
|
||||
this.ctx.fillStyle = this.getGridGapPattern(COLUMN_KEY);
|
||||
this.ctx.fillRect(linePos, startPos, breadth, endPos - startPos);
|
||||
} else {
|
||||
this.ctx.fillStyle = this.getGridGapPattern(ROW_KEY);
|
||||
this.ctx.fillRect(startPos, linePos, endPos - startPos, breadth);
|
||||
}
|
||||
|
||||
this.ctx.restore();
|
||||
},
|
||||
|
||||
@ -1004,7 +1028,7 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
this._hideGridElements();
|
||||
this._hideGridAreaInfoBar();
|
||||
this._hideGridCellInfoBar();
|
||||
setIgnoreLayoutChanges(false, this.highlighterEnv.window.document.documentElement);
|
||||
setIgnoreLayoutChanges(false, this.highlighterEnv.document.documentElement);
|
||||
},
|
||||
|
||||
_hideGrid() {
|
||||
|
@ -516,7 +516,7 @@ GeometryEditorHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
let node = this.currentNode;
|
||||
this.markup.scaleRootElement(node, this.ID_CLASS_PREFIX + "root");
|
||||
|
||||
setIgnoreLayoutChanges(false, node.ownerDocument.documentElement);
|
||||
setIgnoreLayoutChanges(false, this.highlighterEnv.document.documentElement);
|
||||
return true;
|
||||
},
|
||||
|
||||
@ -596,8 +596,7 @@ GeometryEditorHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
|
||||
this.definedProperties.clear();
|
||||
|
||||
setIgnoreLayoutChanges(false,
|
||||
this.currentNode.ownerDocument.documentElement);
|
||||
setIgnoreLayoutChanges(false, this.highlighterEnv.document.documentElement);
|
||||
},
|
||||
|
||||
hideArrows: function () {
|
||||
|
@ -253,13 +253,7 @@ function CanvasFrameAnonymousContentHelper(highlighterEnv, nodeBuilder) {
|
||||
|
||||
CanvasFrameAnonymousContentHelper.prototype = {
|
||||
destroy: function () {
|
||||
try {
|
||||
let doc = this.anonymousContentDocument;
|
||||
doc.removeAnonymousContent(this._content);
|
||||
} catch (e) {
|
||||
// If the current window isn't the one the content was inserted into, this
|
||||
// will fail, but that's fine.
|
||||
}
|
||||
this._remove();
|
||||
this.highlighterEnv.off("window-ready", this._onWindowReady);
|
||||
this.highlighterEnv = this.nodeBuilder = this._content = null;
|
||||
this.anonymousContentDocument = null;
|
||||
@ -306,8 +300,26 @@ CanvasFrameAnonymousContentHelper.prototype = {
|
||||
this._content = doc.insertAnonymousContent(node);
|
||||
},
|
||||
|
||||
_remove() {
|
||||
try {
|
||||
let doc = this.anonymousContentDocument;
|
||||
doc.removeAnonymousContent(this._content);
|
||||
} catch (e) {
|
||||
// If the current window isn't the one the content was inserted into, this
|
||||
// will fail, but that's fine.
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The "window-ready" event can be triggered when:
|
||||
* - a new window is created
|
||||
* - a window is unfrozen from bfcache
|
||||
* - when first attaching to a page
|
||||
* - when swapping frame loaders (moving tabs, toggling RDM)
|
||||
*/
|
||||
_onWindowReady: function (e, {isTopLevel}) {
|
||||
if (isTopLevel) {
|
||||
this._remove();
|
||||
this._removeAllListeners();
|
||||
this._insert();
|
||||
this.anonymousContentDocument = this.highlighterEnv.document;
|
||||
|
@ -152,7 +152,7 @@ function getInnerId(window) {
|
||||
* - navigate
|
||||
* This event is fired once the document's readyState is "complete".
|
||||
* - window-ready
|
||||
* This event is fired on three distinct scenarios:
|
||||
* This event is fired in various distinct scenarios:
|
||||
* * When a new Window object is crafted, equivalent of `DOMWindowCreated`.
|
||||
* It is dispatched before any page script is executed.
|
||||
* * We will have already received a window-ready event for this window
|
||||
@ -161,6 +161,8 @@ function getInnerId(window) {
|
||||
* this page, so it's now live again and we should resume handling it.
|
||||
* * For each existing document, when an `attach` request is received.
|
||||
* At this point scripts in the page will be already loaded.
|
||||
* * When `swapFrameLoaders` is used, such as with moving tabs between
|
||||
* windows or toggling Responsive Design Mode.
|
||||
* - window-destroyed
|
||||
* This event is fired in two cases:
|
||||
* * When the window object is destroyed, i.e. when the related document
|
||||
|
@ -598,22 +598,13 @@ KeyframeUtils::GetComputedKeyframeValues(
|
||||
const ServoComputedStyleValues& aServoValues)
|
||||
{
|
||||
MOZ_ASSERT(aElement);
|
||||
MOZ_ASSERT(aElement->OwnerDoc()->IsStyledByServo());
|
||||
MOZ_ASSERT(aElement->IsStyledByServo());
|
||||
|
||||
nsPresContext* presContext = nsContentUtils::GetContextForContent(aElement);
|
||||
MOZ_ASSERT(presContext);
|
||||
|
||||
nsTArray<ComputedKeyframeValues> result(aKeyframes.Length());
|
||||
|
||||
// Construct each nsTArray<PropertyStyleAnimationValuePair> here.
|
||||
result.AppendElements(aKeyframes.Length());
|
||||
|
||||
Servo_GetComputedKeyframeValues(&aKeyframes,
|
||||
aServoValues.mCurrentStyle,
|
||||
aServoValues.mParentStyle,
|
||||
presContext,
|
||||
&result);
|
||||
return result;
|
||||
return presContext->StyleSet()->AsServo()
|
||||
->GetComputedKeyframeValuesFor(aKeyframes, aElement, aServoValues);
|
||||
}
|
||||
|
||||
/* static */ nsTArray<ComputedKeyframeValues>
|
||||
|
@ -186,7 +186,6 @@ EXPORTS.mozilla.dom += [
|
||||
'ImageEncoder.h',
|
||||
'ImageTracker.h',
|
||||
'ImportManager.h',
|
||||
'IntlUtils.h',
|
||||
'Link.h',
|
||||
'Location.h',
|
||||
'NameSpaceConstants.h',
|
||||
@ -260,7 +259,6 @@ UNIFIED_SOURCES += [
|
||||
'ImageEncoder.cpp',
|
||||
'ImageTracker.cpp',
|
||||
'ImportManager.cpp',
|
||||
'IntlUtils.cpp',
|
||||
'Link.cpp',
|
||||
'Location.cpp',
|
||||
'Navigator.cpp',
|
||||
@ -375,6 +373,14 @@ if CONFIG['FUZZING']:
|
||||
'FuzzingFunctions.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['ENABLE_INTL_API']:
|
||||
UNIFIED_SOURCES += [
|
||||
'IntlUtils.cpp',
|
||||
]
|
||||
EXPORTS.mozilla.dom += [
|
||||
'IntlUtils.h',
|
||||
]
|
||||
|
||||
# these files couldn't be in UNIFIED_SOURCES for now for reasons given below:
|
||||
SOURCES += [
|
||||
# Several conflicts with other bindings.
|
||||
|
@ -1725,7 +1725,8 @@ nsAttrValue::ParseStyleAttribute(const nsAString& aString,
|
||||
|
||||
RefPtr<DeclarationBlock> decl;
|
||||
if (ownerDoc->GetStyleBackendType() == StyleBackendType::Servo) {
|
||||
decl = ServoDeclarationBlock::FromCssText(aString);
|
||||
GeckoParserExtraData data(baseURI, docURI, aElement->NodePrincipal());
|
||||
decl = ServoDeclarationBlock::FromCssText(aString, data);
|
||||
} else {
|
||||
css::Loader* cssLoader = ownerDoc->CSSLoader();
|
||||
nsCSSParser cssParser(cssLoader);
|
||||
|
@ -2214,6 +2214,7 @@ GK_ATOM(sans_serif, "sans-serif")
|
||||
GK_ATOM(cursive, "cursive")
|
||||
GK_ATOM(fantasy, "fantasy")
|
||||
GK_ATOM(monospace, "monospace")
|
||||
GK_ATOM(mozfixed, "-moz-fixed")
|
||||
|
||||
// IPC stuff
|
||||
GK_ATOM(Remote, "remote")
|
||||
|
@ -227,7 +227,9 @@
|
||||
#include "mozilla/dom/Fetch.h"
|
||||
#include "mozilla/dom/FunctionBinding.h"
|
||||
#include "mozilla/dom/HashChangeEvent.h"
|
||||
#ifdef ENABLE_INTL_API
|
||||
#include "mozilla/dom/IntlUtils.h"
|
||||
#endif
|
||||
#include "mozilla/dom/MozSelfSupportBinding.h"
|
||||
#include "mozilla/dom/PopStateEvent.h"
|
||||
#include "mozilla/dom/PopupBlockedEvent.h"
|
||||
@ -1921,7 +1923,9 @@ nsGlobalWindow::CleanUp()
|
||||
|
||||
mServiceWorkerRegistrationTable.Clear();
|
||||
|
||||
#ifdef ENABLE_INTL_API
|
||||
mIntlUtils = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -2212,7 +2216,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPaintWorklet)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExternal)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMozSelfSupport)
|
||||
#ifdef ENABLE_INTL_API
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIntlUtils)
|
||||
#endif
|
||||
|
||||
tmp->TraverseHostObjectURIs(cb);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
@ -2287,7 +2293,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPaintWorklet)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mExternal)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMozSelfSupport)
|
||||
#ifdef ENABLE_INTL_API
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIntlUtils)
|
||||
#endif
|
||||
|
||||
tmp->UnlinkHostObjectURIs();
|
||||
|
||||
@ -14931,6 +14939,7 @@ nsGlobalWindow::GetAppLocales(nsTArray<nsString>& aLocales)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_INTL_API
|
||||
IntlUtils*
|
||||
nsGlobalWindow::GetIntlUtils(ErrorResult& aError)
|
||||
{
|
||||
@ -14942,7 +14951,7 @@ nsGlobalWindow::GetIntlUtils(ErrorResult& aError)
|
||||
|
||||
return mIntlUtils;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template class nsPIDOMWindow<mozIDOMWindowProxy>;
|
||||
template class nsPIDOMWindow<mozIDOMWindow>;
|
||||
|
@ -122,7 +122,9 @@ enum class ImageBitmapFormat : uint8_t;
|
||||
class IdleRequest;
|
||||
class IdleRequestCallback;
|
||||
class IncrementalRunnable;
|
||||
#ifdef ENABLE_INTL_API
|
||||
class IntlUtils;
|
||||
#endif
|
||||
class Location;
|
||||
class MediaQueryList;
|
||||
class MozSelfSupport;
|
||||
@ -951,8 +953,10 @@ public:
|
||||
void
|
||||
GetAppLocales(nsTArray<nsString>& aLocales);
|
||||
|
||||
#ifdef ENABLE_INTL_API
|
||||
mozilla::dom::IntlUtils*
|
||||
GetIntlUtils(mozilla::ErrorResult& aRv);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
bool AlertOrConfirm(bool aAlert, const nsAString& aMessage,
|
||||
@ -2036,7 +2040,9 @@ protected:
|
||||
|
||||
RefPtr<mozilla::dom::VREventObserver> mVREventObserver;
|
||||
|
||||
#ifdef ENABLE_INTL_API
|
||||
RefPtr<mozilla::dom::IntlUtils> mIntlUtils;
|
||||
#endif
|
||||
|
||||
friend class nsDOMScriptableHelper;
|
||||
friend class nsDOMWindowUtils;
|
||||
|
@ -236,11 +236,6 @@ DOMInterfaces = {
|
||||
'wrapperCache': False
|
||||
},
|
||||
|
||||
'CSSMediaRule': {
|
||||
'nativeType': 'mozilla::css::MediaRule',
|
||||
'headerFile': 'nsCSSRules.h',
|
||||
},
|
||||
|
||||
'CSSMozDocumentRule': {
|
||||
'nativeType': 'mozilla::css::DocumentRule',
|
||||
'headerFile': 'nsCSSRules.h',
|
||||
@ -615,10 +610,6 @@ DOMInterfaces = {
|
||||
'nativeType': 'mozilla::DOMLocalMediaStream'
|
||||
},
|
||||
|
||||
'MediaList': {
|
||||
'nativeType': 'nsMediaList',
|
||||
},
|
||||
|
||||
'MediaKeys' : {
|
||||
'implicitJSContext': [ 'createSession']
|
||||
},
|
||||
|
@ -246,6 +246,12 @@ public:
|
||||
private:
|
||||
bool TakeBrowserMinidump(const PluginHangData& aPhd, nsString& aCrashId);
|
||||
|
||||
void SendHangNotification(const HangData& aHangData,
|
||||
const nsString& aBrowserDumpId,
|
||||
bool aTakeMinidump);
|
||||
|
||||
void ClearHangNotification();
|
||||
|
||||
void DispatchTabChildNotReady(TabId aTabId);
|
||||
|
||||
void ForcePaintOnThread(TabId aTabId, uint64_t aLayerObserverEpoch);
|
||||
@ -701,55 +707,45 @@ HangMonitorParent::Bind(Endpoint<PProcessHangMonitorParent>&& aEndpoint)
|
||||
MOZ_ASSERT(ok);
|
||||
}
|
||||
|
||||
class HangObserverNotifier final : public Runnable
|
||||
void
|
||||
HangMonitorParent::SendHangNotification(const HangData& aHangData,
|
||||
const nsString& aBrowserDumpId,
|
||||
bool aTakeMinidump)
|
||||
{
|
||||
public:
|
||||
HangObserverNotifier(HangMonitoredProcess* aProcess,
|
||||
HangMonitorParent *aParent,
|
||||
const HangData& aHangData,
|
||||
const nsString& aBrowserDumpId,
|
||||
bool aTakeMinidump)
|
||||
: mProcess(aProcess),
|
||||
mParent(aParent),
|
||||
mHangData(aHangData),
|
||||
mBrowserDumpId(aBrowserDumpId),
|
||||
mTakeMinidump(aTakeMinidump)
|
||||
{}
|
||||
// chrome process, main thread
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
// chrome process, main thread
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsString dumpId;
|
||||
if ((mHangData.type() == HangData::TPluginHangData) && mTakeMinidump) {
|
||||
// We've been handed a partial minidump; complete it with plugin and
|
||||
// content process dumps.
|
||||
const PluginHangData& phd = mHangData.get_PluginHangData();
|
||||
plugins::TakeFullMinidump(phd.pluginId(), phd.contentProcessId(),
|
||||
mBrowserDumpId, dumpId);
|
||||
mParent->UpdateMinidump(phd.pluginId(), dumpId);
|
||||
} else {
|
||||
// We already have a full minidump; go ahead and use it.
|
||||
dumpId = mBrowserDumpId;
|
||||
}
|
||||
|
||||
mProcess->SetHangData(mHangData, dumpId);
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
observerService->NotifyObservers(mProcess, "process-hang-report", nullptr);
|
||||
return NS_OK;
|
||||
nsString dumpId;
|
||||
if ((aHangData.type() == HangData::TPluginHangData) && aTakeMinidump) {
|
||||
// We've been handed a partial minidump; complete it with plugin and
|
||||
// content process dumps.
|
||||
const PluginHangData& phd = aHangData.get_PluginHangData();
|
||||
plugins::TakeFullMinidump(phd.pluginId(), phd.contentProcessId(),
|
||||
aBrowserDumpId, dumpId);
|
||||
UpdateMinidump(phd.pluginId(), dumpId);
|
||||
} else {
|
||||
// We already have a full minidump; go ahead and use it.
|
||||
dumpId = aBrowserDumpId;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<HangMonitoredProcess> mProcess;
|
||||
HangMonitorParent* mParent;
|
||||
HangData mHangData;
|
||||
nsAutoString mBrowserDumpId;
|
||||
bool mTakeMinidump;
|
||||
};
|
||||
mProcess->SetHangData(aHangData, dumpId);
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
observerService->NotifyObservers(mProcess, "process-hang-report", nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
HangMonitorParent::ClearHangNotification()
|
||||
{
|
||||
// chrome process, main thread
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
mProcess->ClearHang();
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
observerService->NotifyObservers(mProcess, "clear-hang-report", nullptr);
|
||||
}
|
||||
|
||||
// Take a minidump of the browser process if one wasn't already taken for the
|
||||
// plugin that caused the hang. Return false if a dump was already available or
|
||||
@ -817,37 +813,14 @@ HangMonitorParent::RecvHangEvidence(const HangData& aHangData)
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
nsCOMPtr<nsIRunnable> notifier =
|
||||
new HangObserverNotifier(mProcess, this, aHangData, crashId, takeMinidump);
|
||||
NS_DispatchToMainThread(notifier);
|
||||
NS_DispatchToMainThread(
|
||||
mMainThreadTaskFactory.NewRunnableMethod(
|
||||
&HangMonitorParent::SendHangNotification, aHangData, crashId,
|
||||
takeMinidump));
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
class ClearHangNotifier final : public Runnable
|
||||
{
|
||||
public:
|
||||
explicit ClearHangNotifier(HangMonitoredProcess* aProcess)
|
||||
: mProcess(aProcess)
|
||||
{}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
// chrome process, main thread
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
mProcess->ClearHang();
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
observerService->NotifyObservers(mProcess, "clear-hang-report", nullptr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<HangMonitoredProcess> mProcess;
|
||||
};
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
HangMonitorParent::RecvClearHang()
|
||||
{
|
||||
@ -862,9 +835,9 @@ HangMonitorParent::RecvClearHang()
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
nsCOMPtr<nsIRunnable> notifier =
|
||||
new ClearHangNotifier(mProcess);
|
||||
NS_DispatchToMainThread(notifier);
|
||||
NS_DispatchToMainThread(
|
||||
mMainThreadTaskFactory.NewRunnableMethod(
|
||||
&HangMonitorParent::ClearHangNotification));
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -7,9 +7,9 @@
|
||||
#ifndef MediaMIMETypes_h_
|
||||
#define MediaMIMETypes_h_
|
||||
|
||||
#include "VideoUtils.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "nsString.h"
|
||||
#include "VideoUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -52,7 +52,8 @@ public:
|
||||
// Implicit so MEDIAMIMETYPE can be used wherever a MediaMIMEType is expected.
|
||||
MOZ_IMPLICIT MediaMIMEType(const DependentMediaMIMEType& aType)
|
||||
: mMIMEType(aType.AsDependentString())
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
// MIME "type/subtype", always lowercase.
|
||||
const nsACString& AsString() const { return mMIMEType; }
|
||||
@ -106,16 +107,15 @@ Maybe<MediaMIMEType> MakeMediaMIMEType(const char* aType);
|
||||
class MediaCodecs
|
||||
{
|
||||
public:
|
||||
MediaCodecs() {}
|
||||
MediaCodecs() { }
|
||||
// Construction from a comma-separated list of codecs. Unchecked.
|
||||
explicit MediaCodecs(const nsAString& aCodecs)
|
||||
: mCodecs(aCodecs)
|
||||
{}
|
||||
explicit MediaCodecs(const nsAString& aCodecs) : mCodecs(aCodecs) { }
|
||||
// Construction from a literal comma-separated list of codecs. Unchecked.
|
||||
template <size_t N>
|
||||
explicit MediaCodecs(const char (&aCodecs)[N])
|
||||
: mCodecs(NS_ConvertUTF8toUTF16(aCodecs, N - 1))
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
bool IsEmpty() const { return mCodecs.IsEmpty(); }
|
||||
const nsAString& AsString() const { return mCodecs; }
|
||||
|
@ -4,16 +4,17 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "MediaSourceDemuxer.h"
|
||||
|
||||
#include "MediaSourceUtils.h"
|
||||
#include "OpusDecoder.h"
|
||||
#include "SourceBufferList.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "MediaSourceDemuxer.h"
|
||||
#include "MediaSourceUtils.h"
|
||||
#include "SourceBufferList.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "OpusDecoder.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
typedef TrackInfo::TrackType TrackType;
|
||||
@ -30,7 +31,8 @@ MediaSourceDemuxer::MediaSourceDemuxer(AbstractThread* aAbstractMainThread)
|
||||
|
||||
// Due to inaccuracies in determining buffer end
|
||||
// frames (Bug 1065207). This value is based on videos seen in the wild.
|
||||
const TimeUnit MediaSourceDemuxer::EOS_FUZZ = media::TimeUnit::FromMicroseconds(500000);
|
||||
const TimeUnit MediaSourceDemuxer::EOS_FUZZ =
|
||||
media::TimeUnit::FromMicroseconds(500000);
|
||||
|
||||
RefPtr<MediaSourceDemuxer::InitPromise>
|
||||
MediaSourceDemuxer::Init()
|
||||
@ -49,7 +51,8 @@ MediaSourceDemuxer::Init()
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceDemuxer::AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes)
|
||||
MediaSourceDemuxer::AddSizeOfResources(
|
||||
MediaSourceDecoder::ResourceSizes* aSizes)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
@ -252,36 +255,40 @@ MediaSourceDemuxer::GetMozDebugReaderData(nsACString& aString)
|
||||
nsAutoCString result;
|
||||
result += nsPrintfCString("Dumping Data for Demuxer: %p\n", this);
|
||||
if (mAudioTrack) {
|
||||
result += nsPrintfCString("\tDumping Audio Track Buffer(%s): mLastAudioTime=%f\n"
|
||||
"\t\tAudio Track Buffer Details: NumSamples=%"
|
||||
PRIuSIZE " Size=%u Evictable=%u "
|
||||
"NextGetSampleIndex=%u NextInsertionIndex=%d\n",
|
||||
mAudioTrack->mAudioTracks.mInfo->mMimeType.get(),
|
||||
mAudioTrack->mAudioTracks.mNextSampleTime.ToSeconds(),
|
||||
mAudioTrack->mAudioTracks.mBuffers[0].Length(),
|
||||
mAudioTrack->mAudioTracks.mSizeBuffer,
|
||||
mAudioTrack->Evictable(TrackInfo::kAudioTrack),
|
||||
mAudioTrack->mAudioTracks.mNextGetSampleIndex.valueOr(-1),
|
||||
mAudioTrack->mAudioTracks.mNextInsertionIndex.valueOr(-1));
|
||||
result += nsPrintfCString(
|
||||
"\tDumping Audio Track Buffer(%s): mLastAudioTime=%f\n"
|
||||
"\t\tAudio Track Buffer Details: NumSamples=%" PRIuSIZE
|
||||
" Size=%u Evictable=%u "
|
||||
"NextGetSampleIndex=%u NextInsertionIndex=%d\n",
|
||||
mAudioTrack->mAudioTracks.mInfo->mMimeType.get(),
|
||||
mAudioTrack->mAudioTracks.mNextSampleTime.ToSeconds(),
|
||||
mAudioTrack->mAudioTracks.mBuffers[0].Length(),
|
||||
mAudioTrack->mAudioTracks.mSizeBuffer,
|
||||
mAudioTrack->Evictable(TrackInfo::kAudioTrack),
|
||||
mAudioTrack->mAudioTracks.mNextGetSampleIndex.valueOr(-1),
|
||||
mAudioTrack->mAudioTracks.mNextInsertionIndex.valueOr(-1));
|
||||
|
||||
result += nsPrintfCString("\t\tAudio Track Buffered: ranges=%s\n",
|
||||
DumpTimeRanges(mAudioTrack->SafeBuffered(TrackInfo::kAudioTrack)).get());
|
||||
result += nsPrintfCString(
|
||||
"\t\tAudio Track Buffered: ranges=%s\n",
|
||||
DumpTimeRanges(mAudioTrack->SafeBuffered(TrackInfo::kAudioTrack)).get());
|
||||
}
|
||||
if (mVideoTrack) {
|
||||
result += nsPrintfCString("\tDumping Video Track Buffer(%s): mLastVideoTime=%f\n"
|
||||
"\t\tVideo Track Buffer Details: NumSamples=%"
|
||||
PRIuSIZE " Size=%u Evictable=%u "
|
||||
"NextGetSampleIndex=%u NextInsertionIndex=%d\n",
|
||||
mVideoTrack->mVideoTracks.mInfo->mMimeType.get(),
|
||||
mVideoTrack->mVideoTracks.mNextSampleTime.ToSeconds(),
|
||||
mVideoTrack->mVideoTracks.mBuffers[0].Length(),
|
||||
mVideoTrack->mVideoTracks.mSizeBuffer,
|
||||
mVideoTrack->Evictable(TrackInfo::kVideoTrack),
|
||||
mVideoTrack->mVideoTracks.mNextGetSampleIndex.valueOr(-1),
|
||||
mVideoTrack->mVideoTracks.mNextInsertionIndex.valueOr(-1));
|
||||
result += nsPrintfCString(
|
||||
"\tDumping Video Track Buffer(%s): mLastVideoTime=%f\n"
|
||||
"\t\tVideo Track Buffer Details: NumSamples=%" PRIuSIZE
|
||||
" Size=%u Evictable=%u "
|
||||
"NextGetSampleIndex=%u NextInsertionIndex=%d\n",
|
||||
mVideoTrack->mVideoTracks.mInfo->mMimeType.get(),
|
||||
mVideoTrack->mVideoTracks.mNextSampleTime.ToSeconds(),
|
||||
mVideoTrack->mVideoTracks.mBuffers[0].Length(),
|
||||
mVideoTrack->mVideoTracks.mSizeBuffer,
|
||||
mVideoTrack->Evictable(TrackInfo::kVideoTrack),
|
||||
mVideoTrack->mVideoTracks.mNextGetSampleIndex.valueOr(-1),
|
||||
mVideoTrack->mVideoTracks.mNextInsertionIndex.valueOr(-1));
|
||||
|
||||
result += nsPrintfCString("\t\tVideo Track Buffered: ranges=%s\n",
|
||||
DumpTimeRanges(mVideoTrack->SafeBuffered(TrackInfo::kVideoTrack)).get());
|
||||
result += nsPrintfCString(
|
||||
"\t\tVideo Track Buffered: ranges=%s\n",
|
||||
DumpTimeRanges(mVideoTrack->SafeBuffered(TrackInfo::kVideoTrack)).get());
|
||||
}
|
||||
aString += result;
|
||||
}
|
||||
@ -295,8 +302,15 @@ MediaSourceTrackDemuxer::MediaSourceTrackDemuxer(MediaSourceDemuxer* aParent,
|
||||
, mMonitor("MediaSourceTrackDemuxer")
|
||||
, mReset(true)
|
||||
, mPreRoll(TimeUnit::FromMicroseconds(
|
||||
OpusDataDecoder::IsOpus(mParent->GetTrackInfo(mType)->mMimeType) ? 80000
|
||||
: 0))
|
||||
OpusDataDecoder::IsOpus(mParent->GetTrackInfo(mType)->mMimeType)
|
||||
? 80000
|
||||
: mParent->GetTrackInfo(mType)->mMimeType.EqualsLiteral("audio/mp4a-latm")
|
||||
// AAC encoder delay is by default 2112 audio frames.
|
||||
// See https://developer.apple.com/library/content/documentation/QuickTime/QTFF/QTFFAppenG/QTFFAppenG.html
|
||||
// So we always seek 2112 frames
|
||||
? (2112 * 1000000ULL
|
||||
/ mParent->GetTrackInfo(mType)->GetAsAudioInfo()->mRate)
|
||||
: 0))
|
||||
{
|
||||
}
|
||||
|
||||
@ -335,9 +349,8 @@ MediaSourceTrackDemuxer::Reset()
|
||||
self->mManager->Seek(self->mType, TimeUnit(), TimeUnit());
|
||||
{
|
||||
MonitorAutoLock mon(self->mMonitor);
|
||||
self->mNextRandomAccessPoint =
|
||||
self->mManager->GetNextRandomAccessPoint(self->mType,
|
||||
MediaSourceDemuxer::EOS_FUZZ);
|
||||
self->mNextRandomAccessPoint = self->mManager->GetNextRandomAccessPoint(
|
||||
self->mType, MediaSourceDemuxer::EOS_FUZZ);
|
||||
}
|
||||
});
|
||||
mParent->GetTaskQueue()->Dispatch(task.forget());
|
||||
@ -352,7 +365,8 @@ MediaSourceTrackDemuxer::GetNextRandomAccessPoint(media::TimeUnit* aTime)
|
||||
}
|
||||
|
||||
RefPtr<MediaSourceTrackDemuxer::SkipAccessPointPromise>
|
||||
MediaSourceTrackDemuxer::SkipToNextRandomAccessPoint(const media::TimeUnit& aTimeThreshold)
|
||||
MediaSourceTrackDemuxer::SkipToNextRandomAccessPoint(
|
||||
const media::TimeUnit& aTimeThreshold)
|
||||
{
|
||||
return InvokeAsync<media::TimeUnit&&>(
|
||||
mParent->GetTaskQueue(), this, __func__,
|
||||
@ -440,8 +454,8 @@ MediaSourceTrackDemuxer::DoGetSamples(int32_t aNumSamples)
|
||||
__func__);
|
||||
}
|
||||
if (!buffered.ContainsWithStrictEnd(TimeUnit::FromMicroseconds(0))) {
|
||||
return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA,
|
||||
__func__);
|
||||
return SamplesPromise::CreateAndReject(
|
||||
NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA, __func__);
|
||||
}
|
||||
mReset = false;
|
||||
}
|
||||
@ -474,7 +488,8 @@ MediaSourceTrackDemuxer::DoGetSamples(int32_t aNumSamples)
|
||||
}
|
||||
|
||||
RefPtr<MediaSourceTrackDemuxer::SkipAccessPointPromise>
|
||||
MediaSourceTrackDemuxer::DoSkipToNextRandomAccessPoint(const media::TimeUnit& aTimeThreadshold)
|
||||
MediaSourceTrackDemuxer::DoSkipToNextRandomAccessPoint(
|
||||
const media::TimeUnit& aTimeThreadshold)
|
||||
{
|
||||
uint32_t parsed = 0;
|
||||
// Ensure that the data we are about to skip to is still available.
|
||||
|
@ -113,6 +113,8 @@ skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
|
||||
[test_SeekToEnd_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
|
||||
[test_SeekToLastFrame_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
|
||||
[test_SeekTwice_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
|
||||
[test_Sequence_mp4.html]
|
||||
|
40
dom/media/mediasource/test/test_SeekToLastFrame_mp4.html
Normal file
40
dom/media/mediasource/test/test_SeekToLastFrame_mp4.html
Normal file
@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=windows-1252">
|
||||
<title>MSE: Can seek to last frame</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="mediasource.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test"><script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
runWithMSE(function(ms, el) {
|
||||
el.controls = true;
|
||||
once(ms, 'sourceopen').then(function() {
|
||||
ok(true, "Receive a sourceopen event");
|
||||
var sb = ms.addSourceBuffer("video/mp4");
|
||||
fetchAndLoad(sb, 'bipbop/bipbop_480_624kbps-video', ['init'], '.mp4')
|
||||
.then(fetchAndLoad.bind(null, sb, 'bipbop/bipbop_480_624kbps-video', range(1, 3), '.m4s'))
|
||||
.then(function() {
|
||||
el.play();
|
||||
// let seek to the last audio frame.
|
||||
el.currentTime = 1.532517;
|
||||
return once(el, 'seeked');
|
||||
})
|
||||
.then(function() {
|
||||
ok(true, "seek completed");
|
||||
ms.endOfStream();
|
||||
return once(el, 'ended');
|
||||
}).then(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -271,6 +271,8 @@ skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emula
|
||||
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_remoteReofferRollback.html]
|
||||
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_threeUnbundledConnections.html]
|
||||
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_selftest.html]
|
||||
# Bug 1227781: Crash with bogus TURN server.
|
||||
[test_peerConnection_bug1227781.html]
|
||||
|
@ -0,0 +1,125 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript;version=1.8">
|
||||
createHTML({
|
||||
bug: "1342579",
|
||||
title: "Unbundled PC connects to two different PCs",
|
||||
visible: true
|
||||
});
|
||||
|
||||
const fakeFingerPrint = "a=fingerprint:sha-256 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11";
|
||||
|
||||
var pc1 = new RTCPeerConnection();
|
||||
var pc2 = new RTCPeerConnection();
|
||||
var pc3 = new RTCPeerConnection();
|
||||
|
||||
var add = (pc, can, failed) => can && pc.addIceCandidate(can).catch(failed);
|
||||
pc1.onicecandidate = e => {
|
||||
add(pc2, e.candidate, generateErrorCallback())
|
||||
add(pc3, e.candidate, generateErrorCallback())
|
||||
};
|
||||
pc2.onicecandidate = e => add(pc1, e.candidate, generateErrorCallback());
|
||||
pc3.onicecandidate = e => add(pc1, e.candidate, generateErrorCallback());
|
||||
|
||||
var ice1Finished, ice2Finished, ice3Finished;
|
||||
var ice1Done = new Promise(r => ice1Finished = r);
|
||||
var ice2Done = new Promise(r => ice2Finished = r);
|
||||
var ice3Done = new Promise(r => ice3Finished = r);
|
||||
|
||||
var icsc = (pc, str, resolve) => {
|
||||
var state = pc.iceConnectionState;
|
||||
info(str + " ICE connection state is: " + state);
|
||||
if (state == "connected") {
|
||||
ok(true, str + " ICE connected");
|
||||
resolve();
|
||||
} else if (state == "failed") {
|
||||
ok(false, str + " ICE failed")
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
|
||||
pc1.oniceconnectionstatechange = e => icsc(pc1, "PC1", ice1Finished);
|
||||
pc2.oniceconnectionstatechange = e => icsc(pc2, "PC2", ice2Finished);
|
||||
pc3.oniceconnectionstatechange = e => icsc(pc3, "PC3", ice3Finished);
|
||||
|
||||
|
||||
async function getAnswer(pc, offer, answer) {
|
||||
await pc.setLocalDescription(
|
||||
await pc.createAnswer(
|
||||
await pc.setRemoteDescription(offer)));
|
||||
const sdplines = pc.localDescription.sdp.split('\r\n');
|
||||
const fpIndex = sdplines.findIndex(l => l.match('^a=fingerprint'));
|
||||
const FP = sdplines[fpIndex];
|
||||
const audioIndex = sdplines.findIndex(l => l.match(/^m=audio [1-9]/));
|
||||
const videoIndex = sdplines.findIndex(l => l.match(/^m=video [1-9]/));
|
||||
if (audioIndex > -1) {
|
||||
var ss = sdplines.slice(0, audioIndex);
|
||||
ss.splice(fpIndex, 1);
|
||||
answer.sessionSection = ss;
|
||||
const rejectedVideoIndex = sdplines.findIndex(l => l.match('m=video 0'));
|
||||
var ams = sdplines.slice(audioIndex, rejectedVideoIndex);
|
||||
ams.push(FP);
|
||||
ams.push(fakeFingerPrint);
|
||||
answer.audioMsection = ams;
|
||||
}
|
||||
if (videoIndex > -1) {
|
||||
var vms = sdplines.slice(videoIndex, sdplines.length -1);
|
||||
vms.push(fakeFingerPrint);
|
||||
vms.push(FP);
|
||||
answer.videoMsection = vms;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
runNetworkTest(function() {
|
||||
var v1 = createMediaElement('video', 'v1');
|
||||
var v2 = createMediaElement('video', 'v2');
|
||||
var v3 = createMediaElement('video', 'v3');
|
||||
var offer, offerVideo, offerAudio;
|
||||
|
||||
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
|
||||
.then(stream => (v1.srcObject = stream).getTracks().forEach(t => pc1.addTrack(t, stream)))
|
||||
.then(() => navigator.mediaDevices.getUserMedia({ video: true }))
|
||||
.then(stream2 => (v2.srcObject = stream2).getTracks().forEach(t => pc2.addTrack(t, stream2)))
|
||||
.then(() => navigator.mediaDevices.getUserMedia({ audio: true }))
|
||||
.then(stream3 => (v3.srcObject = stream3).getTracks().forEach(t => pc3.addTrack(t, stream3)))
|
||||
.then(() => pc1.createOffer())
|
||||
.then(offer => pc1.setLocalDescription(offer))
|
||||
.then(() => {
|
||||
offer = pc1.localDescription;
|
||||
//info("Original OFFER: " + JSON.stringify(offer));
|
||||
offer.sdp = sdputils.removeBundle(offer.sdp);
|
||||
//info("OFFER w/o BUNDLE: " + JSON.stringify(offer));
|
||||
offerAudio = new RTCSessionDescription(JSON.parse(JSON.stringify(offer)));
|
||||
offerAudio.sdp = offerAudio.sdp.replace('m=video 9', 'm=video 0');
|
||||
//info("offerAudio: " + JSON.stringify(offerAudio));
|
||||
offerVideo = new RTCSessionDescription(JSON.parse(JSON.stringify(offer)));
|
||||
offerVideo.sdp = offerVideo.sdp.replace('m=audio 9', 'm=audio 0');
|
||||
//info("offerVideo: " + JSON.stringify(offerVideo));
|
||||
})
|
||||
.then(() => {
|
||||
return getAnswer(pc2, offerVideo, {});
|
||||
})
|
||||
.then((partialAnswer) => {
|
||||
return getAnswer(pc3, offerAudio, partialAnswer);
|
||||
})
|
||||
.then((answer) => {
|
||||
var fakeAnswer = answer.sessionSection.concat(answer.audioMsection, answer.videoMsection).join('\r\n');
|
||||
info("ANSWER: " + fakeAnswer);
|
||||
pc1.setRemoteDescription({type: 'answer', sdp: fakeAnswer});
|
||||
})
|
||||
|
||||
.then(() => Promise.all([ice1Done, ice2Done, ice3Done]))
|
||||
.then(() => ok(true, "Connected."))
|
||||
.catch(reason => ok(false, "unexpected failure: " + reason))
|
||||
.then(networkTestFinished);
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -534,10 +534,12 @@ partial interface Window {
|
||||
[Func="IsChromeOrXBL"]
|
||||
sequence<DOMString> getAppLocales();
|
||||
|
||||
#ifdef ENABLE_INTL_API
|
||||
/**
|
||||
* Getter funcion for IntlUtils, which provides helper functions for
|
||||
* localization.
|
||||
*/
|
||||
[Throws, Func="IsChromeOrXBL"]
|
||||
readonly attribute IntlUtils intlUtils;
|
||||
#endif
|
||||
};
|
||||
|
@ -649,7 +649,6 @@ WEBIDL_FILES = [
|
||||
'InputEvent.webidl',
|
||||
'InspectorUtils.webidl',
|
||||
'IntersectionObserver.webidl',
|
||||
'IntlUtils.webidl',
|
||||
'IterableIterator.webidl',
|
||||
'KeyAlgorithm.webidl',
|
||||
'KeyboardEvent.webidl',
|
||||
@ -1136,3 +1135,8 @@ if CONFIG['ACCESSIBILITY']:
|
||||
WEBIDL_FILES += [
|
||||
'AccessibleNode.webidl',
|
||||
]
|
||||
|
||||
if CONFIG['ENABLE_INTL_API']:
|
||||
WEBIDL_FILES += [
|
||||
'IntlUtils.webidl',
|
||||
]
|
||||
|
@ -113,12 +113,14 @@ class DeleteNodeTransaction;
|
||||
class DeleteTextTransaction;
|
||||
class EditAggregateTransaction;
|
||||
class ErrorResult;
|
||||
class HTMLEditor;
|
||||
class InsertNodeTransaction;
|
||||
class InsertTextTransaction;
|
||||
class JoinNodeTransaction;
|
||||
class RemoveStyleSheetTransaction;
|
||||
class SplitNodeTransaction;
|
||||
class TextComposition;
|
||||
class TextEditor;
|
||||
struct EditorDOMPoint;
|
||||
|
||||
namespace dom {
|
||||
@ -164,6 +166,11 @@ public:
|
||||
*/
|
||||
EditorBase();
|
||||
|
||||
virtual TextEditor* AsTextEditor() = 0;
|
||||
virtual const TextEditor* AsTextEditor() const = 0;
|
||||
virtual HTMLEditor* AsHTMLEditor() = 0;
|
||||
virtual const HTMLEditor* AsHTMLEditor() const = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* The default destructor. This should suffice. Should this be pure virtual
|
||||
|
@ -241,9 +241,16 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLEditRules, TextEditRules,
|
||||
NS_IMETHODIMP
|
||||
HTMLEditRules::Init(TextEditor* aTextEditor)
|
||||
{
|
||||
if (NS_WARN_IF(!aTextEditor)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
InitFields();
|
||||
|
||||
mHTMLEditor = static_cast<HTMLEditor*>(aTextEditor);
|
||||
mHTMLEditor = aTextEditor->AsHTMLEditor();
|
||||
if (NS_WARN_IF(!mHTMLEditor)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// call through to base class Init
|
||||
nsresult rv = TextEditRules::Init(aTextEditor);
|
||||
|
@ -510,7 +510,7 @@ HTMLEditor::InitRules()
|
||||
// instantiate the rules for the html editor
|
||||
mRules = new HTMLEditRules();
|
||||
}
|
||||
return mRules->Init(static_cast<TextEditor*>(this));
|
||||
return mRules->Init(this);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -99,6 +99,9 @@ public:
|
||||
|
||||
HTMLEditor();
|
||||
|
||||
virtual HTMLEditor* AsHTMLEditor() override { return this; }
|
||||
virtual const HTMLEditor* AsHTMLEditor() const override { return this; }
|
||||
|
||||
bool GetReturnInParagraphCreatesNewParagraph();
|
||||
Element* GetSelectionContainer();
|
||||
|
||||
|
@ -30,24 +30,18 @@ namespace mozilla {
|
||||
|
||||
using namespace dom;
|
||||
|
||||
#ifdef DEBUG
|
||||
nsresult
|
||||
HTMLEditorEventListener::Connect(EditorBase* aEditorBase)
|
||||
{
|
||||
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryObject(aEditorBase);
|
||||
nsCOMPtr<nsIHTMLInlineTableEditor> htmlInlineTableEditor =
|
||||
do_QueryObject(aEditorBase);
|
||||
NS_PRECONDITION(htmlEditor && htmlInlineTableEditor,
|
||||
"Set HTMLEditor or its sub class");
|
||||
return EditorEventListener::Connect(aEditorBase);
|
||||
}
|
||||
#endif
|
||||
|
||||
HTMLEditor*
|
||||
HTMLEditorEventListener::GetHTMLEditor()
|
||||
{
|
||||
// mEditor must be HTMLEditor or its subclass.
|
||||
return static_cast<HTMLEditor*>(mEditorBase);
|
||||
if (NS_WARN_IF(!aEditorBase)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
// Guarantee that mEditorBase is always HTMLEditor.
|
||||
HTMLEditor* htmlEditor = aEditorBase->AsHTMLEditor();
|
||||
if (NS_WARN_IF(!htmlEditor)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
return EditorEventListener::Connect(htmlEditor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -59,7 +53,8 @@ HTMLEditorEventListener::MouseUp(nsIDOMMouseEvent* aMouseEvent)
|
||||
|
||||
// FYI: We need to notify HTML editor of mouseup even if it's consumed
|
||||
// because HTML editor always needs to release grabbing resizer.
|
||||
HTMLEditor* htmlEditor = GetHTMLEditor();
|
||||
HTMLEditor* htmlEditor = mEditorBase->AsHTMLEditor();
|
||||
MOZ_ASSERT(htmlEditor);
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> target;
|
||||
nsresult rv = aMouseEvent->AsEvent()->GetTarget(getter_AddRefs(target));
|
||||
@ -93,7 +88,9 @@ HTMLEditorEventListener::MouseDown(nsIDOMMouseEvent* aMouseEvent)
|
||||
WidgetMouseEvent* mousedownEvent =
|
||||
aMouseEvent->AsEvent()->WidgetEventPtr()->AsMouseEvent();
|
||||
|
||||
HTMLEditor* htmlEditor = GetHTMLEditor();
|
||||
HTMLEditor* htmlEditor = mEditorBase->AsHTMLEditor();
|
||||
MOZ_ASSERT(htmlEditor);
|
||||
|
||||
// Contenteditable should disregard mousedowns outside it.
|
||||
// IsAcceptableInputEvent() checks it for a mouse event.
|
||||
if (!htmlEditor->IsAcceptableInputEvent(mousedownEvent)) {
|
||||
@ -222,13 +219,19 @@ HTMLEditorEventListener::MouseDown(nsIDOMMouseEvent* aMouseEvent)
|
||||
nsresult
|
||||
HTMLEditorEventListener::MouseClick(nsIDOMMouseEvent* aMouseEvent)
|
||||
{
|
||||
if (NS_WARN_IF(DetachedFromEditor())) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> target;
|
||||
nsresult rv = aMouseEvent->AsEvent()->GetTarget(getter_AddRefs(target));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(target, NS_ERROR_NULL_POINTER);
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target);
|
||||
|
||||
GetHTMLEditor()->DoInlineTableEditingAction(element);
|
||||
HTMLEditor* htmlEditor = mEditorBase->AsHTMLEditor();
|
||||
MOZ_ASSERT(htmlEditor);
|
||||
htmlEditor->DoInlineTableEditingAction(element);
|
||||
|
||||
return EditorEventListener::MouseClick(aMouseEvent);
|
||||
}
|
||||
|
@ -25,17 +25,15 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// WARNING: You must be use HTMLEditor or its sub class for this class.
|
||||
/**
|
||||
* Connect() fails if aEditorBase isn't an HTMLEditor instance.
|
||||
*/
|
||||
virtual nsresult Connect(EditorBase* aEditorBase) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual nsresult MouseDown(nsIDOMMouseEvent* aMouseEvent) override;
|
||||
virtual nsresult MouseUp(nsIDOMMouseEvent* aMouseEvent) override;
|
||||
virtual nsresult MouseClick(nsIDOMMouseEvent* aMouseEvent) override;
|
||||
|
||||
inline HTMLEditor* GetHTMLEditor();
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "gfxFontUtils.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/EditorUtils.h" // AutoEditBatch, AutoRules
|
||||
#include "mozilla/HTMLEditor.h"
|
||||
#include "mozilla/mozalloc.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/TextEditRules.h"
|
||||
@ -78,6 +79,18 @@ TextEditor::TextEditor()
|
||||
GetDefaultEditorPrefs(mNewlineHandling, mCaretStyle);
|
||||
}
|
||||
|
||||
HTMLEditor*
|
||||
TextEditor::AsHTMLEditor()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const HTMLEditor*
|
||||
TextEditor::AsHTMLEditor() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TextEditor::~TextEditor()
|
||||
{
|
||||
// Remove event listeners. Note that if we had an HTML editor,
|
||||
|
@ -56,6 +56,11 @@ public:
|
||||
|
||||
TextEditor();
|
||||
|
||||
virtual TextEditor* AsTextEditor() override { return this; }
|
||||
virtual const TextEditor* AsTextEditor() const override { return this; }
|
||||
virtual HTMLEditor* AsHTMLEditor() override;
|
||||
virtual const HTMLEditor* AsHTMLEditor() const override;
|
||||
|
||||
// nsIPlaintextEditor methods
|
||||
NS_DECL_NSIPLAINTEXTEDITOR
|
||||
|
||||
|
@ -66,10 +66,6 @@ public:
|
||||
|
||||
virtual already_AddRefed<mozilla::gfx::VsyncSource> CreateHardwareVsyncSource() override;
|
||||
|
||||
virtual bool SupportsApzTouchInput() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool AccelerateLayersByDefault() override {
|
||||
return true;
|
||||
|
@ -3642,7 +3642,7 @@ gfxFont::SanitizeMetrics(gfxFont::Metrics *aMetrics, bool aIsBadUnderlineFont)
|
||||
// usual font tables (which can happen in the case of a legacy bitmap or Type1
|
||||
// font for which the platform-specific backend used platform APIs instead of
|
||||
// sfnt tables to create the horizontal metrics).
|
||||
const gfxFont::Metrics*
|
||||
UniquePtr<const gfxFont::Metrics>
|
||||
gfxFont::CreateVerticalMetrics()
|
||||
{
|
||||
const uint32_t kHheaTableTag = TRUETYPE_TAG('h','h','e','a');
|
||||
@ -3651,8 +3651,8 @@ gfxFont::CreateVerticalMetrics()
|
||||
const uint32_t kOS_2TableTag = TRUETYPE_TAG('O','S','/','2');
|
||||
uint32_t len;
|
||||
|
||||
Metrics* metrics = new Metrics;
|
||||
::memset(metrics, 0, sizeof(Metrics));
|
||||
UniquePtr<Metrics> metrics = MakeUnique<Metrics>();
|
||||
::memset(metrics.get(), 0, sizeof(Metrics));
|
||||
|
||||
// Some basic defaults, in case the font lacks any real metrics tables.
|
||||
// TODO: consider what rounding (if any) we should apply to these.
|
||||
@ -3797,7 +3797,7 @@ gfxFont::CreateVerticalMetrics()
|
||||
metrics->xHeight = metrics->emHeight / 2;
|
||||
metrics->capHeight = metrics->maxAscent;
|
||||
|
||||
return metrics;
|
||||
return Move(metrics);
|
||||
}
|
||||
|
||||
gfxFloat
|
||||
@ -3848,8 +3848,8 @@ void
|
||||
gfxFont::AddGlyphChangeObserver(GlyphChangeObserver *aObserver)
|
||||
{
|
||||
if (!mGlyphChangeObservers) {
|
||||
mGlyphChangeObservers.reset(
|
||||
new nsTHashtable<nsPtrHashKey<GlyphChangeObserver>>);
|
||||
mGlyphChangeObservers =
|
||||
MakeUnique<nsTHashtable<nsPtrHashKey<GlyphChangeObserver>>>();
|
||||
}
|
||||
mGlyphChangeObservers->PutEntry(aObserver);
|
||||
}
|
||||
|
@ -1551,7 +1551,7 @@ public:
|
||||
return GetHorizontalMetrics();
|
||||
}
|
||||
if (!mVerticalMetrics) {
|
||||
mVerticalMetrics.reset(CreateVerticalMetrics());
|
||||
mVerticalMetrics = CreateVerticalMetrics();
|
||||
}
|
||||
return *mVerticalMetrics;
|
||||
}
|
||||
@ -1868,7 +1868,7 @@ public:
|
||||
protected:
|
||||
virtual const Metrics& GetHorizontalMetrics() = 0;
|
||||
|
||||
const Metrics* CreateVerticalMetrics();
|
||||
mozilla::UniquePtr<const Metrics> CreateVerticalMetrics();
|
||||
|
||||
// Output a single glyph at *aPt, which is updated by the glyph's advance.
|
||||
// Normal glyphs are simply accumulated in aBuffer until it is full and
|
||||
|
@ -137,6 +137,7 @@ class mozilla::gl::SkiaGLGlue : public GenericAtomicRefCounted {
|
||||
#include "SoftwareVsyncSource.h"
|
||||
#include "nscore.h" // for NS_FREE_PERMANENT_DATA
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/TouchEvent.h"
|
||||
#include "gfxVR.h"
|
||||
#include "VRManagerChild.h"
|
||||
#include "mozilla/gfx/GPUParent.h"
|
||||
@ -2644,6 +2645,12 @@ gfxPlatform::ImportGPUDeviceData(const mozilla::gfx::GPUDeviceData& aData)
|
||||
gfxConfig::ImportChange(Feature::OPENGL_COMPOSITING, aData.oglCompositing());
|
||||
}
|
||||
|
||||
bool
|
||||
gfxPlatform::SupportsApzTouchInput() const
|
||||
{
|
||||
return dom::TouchEvent::PrefEnabled(nullptr);
|
||||
}
|
||||
|
||||
bool
|
||||
gfxPlatform::SupportsApzDragInput() const
|
||||
{
|
||||
|
@ -626,9 +626,7 @@ public:
|
||||
virtual bool SupportsApzWheelInput() const {
|
||||
return false;
|
||||
}
|
||||
virtual bool SupportsApzTouchInput() const {
|
||||
return false;
|
||||
}
|
||||
bool SupportsApzTouchInput() const;
|
||||
bool SupportsApzDragInput() const;
|
||||
|
||||
virtual void FlushContentDrawing() {}
|
||||
|
@ -909,11 +909,4 @@ gfxPlatformGtk::CreateHardwareVsyncSource()
|
||||
return gfxPlatform::CreateHardwareVsyncSource();
|
||||
}
|
||||
|
||||
bool
|
||||
gfxPlatformGtk::SupportsApzTouchInput() const
|
||||
{
|
||||
int value = gfxPrefs::TouchEventsEnabled();
|
||||
return value == 1 || value == 2;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -123,8 +123,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SupportsApzTouchInput() const override;
|
||||
|
||||
void FontsPrefsChanged(const char *aPref) override;
|
||||
|
||||
// maximum number of fonts to substitute for a generic
|
||||
|
@ -1878,13 +1878,6 @@ gfxWindowsPlatform::CreateHardwareVsyncSource()
|
||||
return d3dVsyncSource.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
gfxWindowsPlatform::SupportsApzTouchInput() const
|
||||
{
|
||||
int value = gfxPrefs::TouchEventsEnabled();
|
||||
return value == 1 || value == 2;
|
||||
}
|
||||
|
||||
void
|
||||
gfxWindowsPlatform::GetAcceleratedCompositorBackends(nsTArray<LayersBackend>& aBackends)
|
||||
{
|
||||
|
@ -209,7 +209,6 @@ public:
|
||||
bool SupportsApzWheelInput() const override {
|
||||
return true;
|
||||
}
|
||||
bool SupportsApzTouchInput() const override;
|
||||
|
||||
// Recreate devices as needed for a device reset. Returns true if a device
|
||||
// reset occurred.
|
||||
|
@ -248,6 +248,7 @@ include('/ipc/chromium/chromium-config.mozbuild')
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/dom/base',
|
||||
'/dom/workers',
|
||||
'/dom/xml',
|
||||
]
|
||||
|
@ -27,12 +27,12 @@
|
||||
|
||||
# RUN TESTS NOT AFFECTED BY DOWNSCALE-DURING-DECODE:
|
||||
# #
|
||||
fails == downscale-svg-1a.html downscale-svg-1a.html
|
||||
fails == downscale-svg-1b.html downscale-svg-1b.html
|
||||
fails == downscale-svg-1c.html downscale-svg-1c.html
|
||||
fails == downscale-svg-1d.html downscale-svg-1d.html
|
||||
fails == downscale-svg-1e.html downscale-svg-1e.html
|
||||
fails == downscale-svg-1f.html downscale-svg-1f.html
|
||||
== downscale-svg-1a.html downscale-svg-1a.html
|
||||
== downscale-svg-1b.html downscale-svg-1b.html
|
||||
== downscale-svg-1c.html downscale-svg-1c.html
|
||||
== downscale-svg-1d.html downscale-svg-1d.html
|
||||
== downscale-svg-1e.html downscale-svg-1e.html
|
||||
== downscale-svg-1f.html downscale-svg-1f.html
|
||||
|
||||
# RUN TESTS WITH DOWNSCALE-DURING-DECODE DISABLED:
|
||||
# #
|
||||
|
@ -24,7 +24,7 @@ random == delaytest.html?transparent-animation.gif delaytest.html?transparent-an
|
||||
fails == one-color-offset.gif one-color-offset.gif
|
||||
|
||||
# Bug 1068230
|
||||
fails == tile-transform.html tile-transform.html
|
||||
== tile-transform.html tile-transform.html
|
||||
|
||||
# Bug 1234077
|
||||
== truncated-framerect.html truncated-framerect.html
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <algorithm> // find_if()
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/intl/OSPreferences.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIToolkitChromeRegistry.h"
|
||||
|
||||
@ -15,9 +17,18 @@
|
||||
#include "unicode/uloc.h"
|
||||
#endif
|
||||
|
||||
#define MATCH_OS_LOCALE_PREF "intl.locale.matchOS"
|
||||
#define SELECTED_LOCALE_PREF "general.useragent.locale"
|
||||
|
||||
static const char* kObservedPrefs[] = {
|
||||
MATCH_OS_LOCALE_PREF,
|
||||
SELECTED_LOCALE_PREF,
|
||||
nullptr
|
||||
};
|
||||
|
||||
using namespace mozilla::intl;
|
||||
|
||||
NS_IMPL_ISUPPORTS(LocaleService, mozILocaleService)
|
||||
NS_IMPL_ISUPPORTS(LocaleService, mozILocaleService, nsIObserver)
|
||||
|
||||
mozilla::StaticRefPtr<LocaleService> LocaleService::sInstance;
|
||||
|
||||
@ -53,11 +64,21 @@ LocaleService::GetInstance()
|
||||
{
|
||||
if (!sInstance) {
|
||||
sInstance = new LocaleService();
|
||||
|
||||
// We're going to observe for requested languages changes which come
|
||||
// from prefs.
|
||||
DebugOnly<nsresult> rv = Preferences::AddStrongObservers(sInstance, kObservedPrefs);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "Adding observers failed.");
|
||||
ClearOnShutdown(&sInstance);
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
LocaleService::~LocaleService()
|
||||
{
|
||||
Preferences::RemoveObservers(sInstance, kObservedPrefs);
|
||||
}
|
||||
|
||||
void
|
||||
LocaleService::GetAppLocales(nsTArray<nsCString>& aRetVal)
|
||||
{
|
||||
@ -67,6 +88,43 @@ LocaleService::GetAppLocales(nsTArray<nsCString>& aRetVal)
|
||||
aRetVal = mAppLocales;
|
||||
}
|
||||
|
||||
bool
|
||||
LocaleService::GetRequestedLocales(nsTArray<nsCString>& aRetVal)
|
||||
{
|
||||
nsAutoCString locale;
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefs(do_GetService("@mozilla.org/preferences-service;1"));
|
||||
|
||||
// First, we'll try to check if the user has `matchOS` pref selected
|
||||
bool matchOSLocale = Preferences::GetBool(MATCH_OS_LOCALE_PREF);
|
||||
|
||||
if (matchOSLocale) {
|
||||
// If he has, we'll pick the locale from the system
|
||||
if (OSPreferences::GetInstance()->GetSystemLocales(aRetVal)) {
|
||||
// If we succeeded, return.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, we'll try to get the requested locale from the prefs.
|
||||
|
||||
// In some cases, mainly on Fennec and on Linux version,
|
||||
// `general.useragent.locale` is a special 'localized' value, like:
|
||||
// "chrome://global/locale/intl.properties"
|
||||
if (!NS_SUCCEEDED(Preferences::GetLocalizedCString(SELECTED_LOCALE_PREF, &locale))) {
|
||||
// If not, we can attempt to retrieve it as a simple string value.
|
||||
//rv = prefs->GetCharPref(SELECTED_LOCALE_PREF, getter_Copies(locale));
|
||||
if (!NS_SUCCEEDED(Preferences::GetCString(SELECTED_LOCALE_PREF, &locale))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// At the moment we just take a single locale, but in the future
|
||||
// we'll want to allow user to specify a list of requested locales.
|
||||
aRetVal.AppendElement(locale);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
LocaleService::Refresh()
|
||||
{
|
||||
@ -245,10 +303,37 @@ LocaleService::NegotiateLanguages(const nsTArray<nsCString>& aRequested,
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LocaleService::Observe(nsISupports *aSubject, const char *aTopic,
|
||||
const char16_t *aData)
|
||||
{
|
||||
// At the moment the only thing we're observing are settings indicating
|
||||
// user requested locales.
|
||||
NS_ConvertUTF16toUTF8 pref(aData);
|
||||
if (pref.EqualsLiteral(MATCH_OS_LOCALE_PREF) || pref.EqualsLiteral(SELECTED_LOCALE_PREF)) {
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->NotifyObservers(nullptr, "intl:requested-locales-changed", nullptr);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* mozILocaleService methods
|
||||
*/
|
||||
|
||||
static char**
|
||||
CreateOutArray(const nsTArray<nsCString>& aArray)
|
||||
{
|
||||
uint32_t n = aArray.Length();
|
||||
char** result = static_cast<char**>(moz_xmalloc(n * sizeof(char*)));
|
||||
for (uint32_t i = 0; i < n; i++) {
|
||||
result[i] = moz_xstrdup(aArray[i].get());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LocaleService::GetAppLocales(uint32_t* aCount, char*** aOutArray)
|
||||
{
|
||||
@ -257,11 +342,7 @@ LocaleService::GetAppLocales(uint32_t* aCount, char*** aOutArray)
|
||||
}
|
||||
|
||||
*aCount = mAppLocales.Length();
|
||||
*aOutArray = static_cast<char**>(moz_xmalloc(*aCount * sizeof(char*)));
|
||||
|
||||
for (uint32_t i = 0; i < *aCount; i++) {
|
||||
(*aOutArray)[i] = moz_xstrdup(mAppLocales[i].get());
|
||||
}
|
||||
*aOutArray = CreateOutArray(mAppLocales);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -470,3 +551,20 @@ LocaleService::Locale::AddLikelySubtags()
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LocaleService::GetRequestedLocales(uint32_t* aCount, char*** aOutArray)
|
||||
{
|
||||
AutoTArray<nsCString, 16> requestedLocales;
|
||||
bool res = GetRequestedLocales(requestedLocales);
|
||||
|
||||
if (!res) {
|
||||
NS_ERROR("Couldn't retrieve selected locales from prefs!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aCount = requestedLocales.Length();
|
||||
*aOutArray = CreateOutArray(requestedLocales);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define mozilla_intl_LocaleService_h__
|
||||
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
@ -37,10 +38,12 @@ namespace intl {
|
||||
* try to be specific when naming APIs, so the service is for locales,
|
||||
* but we negotiate between languages etc.
|
||||
*/
|
||||
class LocaleService : public mozILocaleService
|
||||
class LocaleService : public mozILocaleService,
|
||||
public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_MOZILOCALESERVICE
|
||||
|
||||
/**
|
||||
@ -91,6 +94,26 @@ public:
|
||||
*/
|
||||
void GetAppLocales(nsTArray<nsCString>& aRetVal);
|
||||
|
||||
/**
|
||||
* Returns a list of locales that the user requested the app to be
|
||||
* localized to.
|
||||
*
|
||||
* The result is a sorted list of valid locale IDs and it should be
|
||||
* used as a requestedLocales input list for languages negotiation.
|
||||
*
|
||||
* Example: ["en-US", "de", "pl", "sr-Cyrl", "zh-Hans-HK"]
|
||||
*
|
||||
* Usage:
|
||||
* nsTArray<nsCString> appLocales;
|
||||
* LocaleService::GetInstance()->GetRequestedLocales(appLocales);
|
||||
*
|
||||
* Returns a boolean indicating if the attempt to retrieve prefs
|
||||
* was successful.
|
||||
*
|
||||
* (See mozILocaleService.idl for a JS-callable version of this.)
|
||||
*/
|
||||
bool GetRequestedLocales(nsTArray<nsCString>& aRetVal);
|
||||
|
||||
/**
|
||||
* Triggers a refresh of the language negotiation process.
|
||||
*
|
||||
@ -169,7 +192,7 @@ private:
|
||||
LangNegStrategy aStrategy,
|
||||
nsTArray<nsCString>& aRetVal);
|
||||
|
||||
virtual ~LocaleService() {};
|
||||
virtual ~LocaleService();
|
||||
|
||||
nsTArray<nsCString> mAppLocales;
|
||||
|
||||
|
@ -108,4 +108,16 @@ interface mozILocaleService : nsISupports
|
||||
* Example: "zh-Hans-HK"
|
||||
*/
|
||||
ACString getAppLocale();
|
||||
|
||||
/**
|
||||
* Returns a list of locales that the user requested the app to be
|
||||
* localized to.
|
||||
*
|
||||
* The result is an ordered list of locale IDs which should be
|
||||
* used as a requestedLocales input list for language negotiation.
|
||||
*
|
||||
* Example: ["en-US", "de", "pl", "sr-Cyrl", "zh-Hans-HK"]
|
||||
*/
|
||||
void getRequestedLocales([optional] out unsigned long aCount,
|
||||
[retval, array, size_is(aCount)] out string aLocales);
|
||||
};
|
||||
|
@ -40,6 +40,14 @@ TEST(Intl_Locale_LocaleService, GetAppLocales_lastIsEnUS) {
|
||||
ASSERT_TRUE(appLocales[len - 1].EqualsLiteral("en-US"));
|
||||
}
|
||||
|
||||
TEST(Intl_Locale_LocaleService, GetRequestedLocales) {
|
||||
nsTArray<nsCString> reqLocales;
|
||||
LocaleService::GetInstance()->GetRequestedLocales(reqLocales);
|
||||
|
||||
int32_t len = reqLocales.Length();
|
||||
ASSERT_TRUE(len > 0);
|
||||
}
|
||||
|
||||
TEST(Intl_Locale_LocaleService, GetAppLocale) {
|
||||
nsTArray<nsCString> appLocales;
|
||||
LocaleService::GetInstance()->GetAppLocales(appLocales);
|
||||
|
@ -2,26 +2,130 @@
|
||||
* 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/. */
|
||||
|
||||
/**
|
||||
* Make sure the locale service can be instantiated,
|
||||
* and returns something plausible for getAppLocale and getAppLocales.
|
||||
*/
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
const { Services } = Cu.import('resource://gre/modules/Services.jsm', {});
|
||||
const osPrefs = Cc["@mozilla.org/intl/ospreferences;1"].
|
||||
getService(Ci.mozIOSPreferences);
|
||||
|
||||
/**
|
||||
* Make sure the locale service can be instantiated.
|
||||
*/
|
||||
function run_test()
|
||||
{
|
||||
var localeService =
|
||||
const localeService =
|
||||
Components.classes["@mozilla.org/intl/localeservice;1"]
|
||||
.getService(Components.interfaces.mozILocaleService);
|
||||
|
||||
var appLocale = localeService.getAppLocale();
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_getAppLocales() {
|
||||
const localeService =
|
||||
Components.classes["@mozilla.org/intl/localeservice;1"]
|
||||
.getService(Components.interfaces.mozILocaleService);
|
||||
|
||||
const appLocale = localeService.getAppLocale();
|
||||
do_check_true(appLocale != "", "appLocale is non-empty");
|
||||
|
||||
var appLocales = localeService.getAppLocales();
|
||||
const appLocales = localeService.getAppLocales();
|
||||
do_check_true(Array.isArray(appLocales), "appLocales returns an array");
|
||||
|
||||
do_check_true(appLocale == appLocales[0], "appLocale matches first entry in appLocales");
|
||||
|
||||
var enUScount = 0;
|
||||
appLocales.forEach(function(loc) { if (loc == "en-US") { enUScount++; } });
|
||||
do_check_true(enUScount == 1, "en-US is present exactly one time");
|
||||
}
|
||||
const enUSLocales = appLocales.filter(loc => loc === "en-US");
|
||||
do_check_true(enUSLocales.length == 1, "en-US is present exactly one time");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
|
||||
const PREF_SELECTED_LOCALE = "general.useragent.locale";
|
||||
const REQ_LOC_CHANGE_EVENT = "intl:requested-locales-changed";
|
||||
|
||||
add_test(function test_getRequestedLocales() {
|
||||
const localeService =
|
||||
Components.classes["@mozilla.org/intl/localeservice;1"]
|
||||
.getService(Components.interfaces.mozILocaleService);
|
||||
|
||||
const requestedLocales = localeService.getRequestedLocales();
|
||||
do_check_true(Array.isArray(requestedLocales), "requestedLocales returns an array");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* In this test we verify that after we set an observer on the LocaleService
|
||||
* event for requested locales change, it will be fired when the
|
||||
* pref for matchOS is set to true.
|
||||
*
|
||||
* Then, we test that when the matchOS is set to true, we will retrieve
|
||||
* OS locale from getRequestedLocales.
|
||||
*/
|
||||
add_test(function test_getRequestedLocales_matchOS() {
|
||||
do_test_pending();
|
||||
|
||||
const localeService =
|
||||
Components.classes["@mozilla.org/intl/localeservice;1"]
|
||||
.getService(Components.interfaces.mozILocaleService);
|
||||
|
||||
Services.prefs.setBoolPref(PREF_MATCH_OS_LOCALE, false);
|
||||
Services.prefs.setCharPref(PREF_SELECTED_LOCALE, "ar-IR");
|
||||
|
||||
const observer = {
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case REQ_LOC_CHANGE_EVENT:
|
||||
const reqLocs = localeService.getRequestedLocales();
|
||||
do_check_true(reqLocs[0] === osPrefs.systemLocale);
|
||||
Services.obs.removeObserver(observer, REQ_LOC_CHANGE_EVENT);
|
||||
do_test_finished();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Services.obs.addObserver(observer, REQ_LOC_CHANGE_EVENT, false);
|
||||
Services.prefs.setBoolPref(PREF_MATCH_OS_LOCALE, true);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* In this test we verify that after we set an observer on the LocaleService
|
||||
* event for requested locales change, it will be fired when the
|
||||
* pref for browser UI locale changes.
|
||||
*/
|
||||
add_test(function test_getRequestedLocales_matchOS() {
|
||||
do_test_pending();
|
||||
|
||||
const localeService =
|
||||
Components.classes["@mozilla.org/intl/localeservice;1"]
|
||||
.getService(Components.interfaces.mozILocaleService);
|
||||
|
||||
Services.prefs.setBoolPref(PREF_MATCH_OS_LOCALE, false);
|
||||
Services.prefs.setCharPref(PREF_SELECTED_LOCALE, "ar-IR");
|
||||
|
||||
const observer = {
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case REQ_LOC_CHANGE_EVENT:
|
||||
const reqLocs = localeService.getRequestedLocales();
|
||||
do_check_true(reqLocs[0] === "sr-RU");
|
||||
Services.obs.removeObserver(observer, REQ_LOC_CHANGE_EVENT);
|
||||
do_test_finished();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Services.obs.addObserver(observer, REQ_LOC_CHANGE_EVENT, false);
|
||||
Services.prefs.setCharPref(PREF_SELECTED_LOCALE, "sr-RU");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
do_register_cleanup(() => {
|
||||
Services.prefs.clearUserPref(PREF_SELECTED_LOCALE);
|
||||
Services.prefs.clearUserPref(PREF_MATCH_OS_LOCALE);
|
||||
});
|
||||
|
@ -58,22 +58,16 @@ public:
|
||||
return task.forget();
|
||||
}
|
||||
|
||||
template <class Method>
|
||||
inline already_AddRefed<Runnable> NewRunnableMethod(Method method) {
|
||||
typedef TaskWrapper<RunnableMethod<Method, Tuple0> > TaskWrapper;
|
||||
template <class Method, typename... Args>
|
||||
inline already_AddRefed<Runnable>
|
||||
NewRunnableMethod(Method method, Args&&... args) {
|
||||
typedef decltype(base::MakeTuple(mozilla::Forward<Args>(args)...)) ArgTuple;
|
||||
typedef RunnableMethod<Method, ArgTuple> RunnableMethod;
|
||||
typedef TaskWrapper<RunnableMethod> TaskWrapper;
|
||||
|
||||
RefPtr<TaskWrapper> task = new TaskWrapper(this, object_, method,
|
||||
base::MakeTuple());
|
||||
|
||||
return task.forget();
|
||||
}
|
||||
|
||||
template <class Method, class A>
|
||||
inline already_AddRefed<Runnable> NewRunnableMethod(Method method, const A& a) {
|
||||
typedef TaskWrapper<RunnableMethod<Method, Tuple1<A> > > TaskWrapper;
|
||||
|
||||
RefPtr<TaskWrapper> task = new TaskWrapper(this, object_, method,
|
||||
base::MakeTuple(a));
|
||||
RefPtr<TaskWrapper> task =
|
||||
new TaskWrapper(this, object_, method,
|
||||
base::MakeTuple(mozilla::Forward<Args>(args)...));
|
||||
|
||||
return task.forget();
|
||||
}
|
||||
|
@ -62,16 +62,6 @@ ServoRestyleManager::PostRestyleEvent(Element* aElement,
|
||||
aRestyleHint |= eRestyle_Self | eRestyle_Subtree;
|
||||
}
|
||||
|
||||
// XXX For now, convert eRestyle_Subtree into (eRestyle_Self |
|
||||
// eRestyle_SomeDescendants), which Servo will interpret as
|
||||
// RESTYLE_SELF | RESTYLE_DESCENDANTS, since this is a commonly
|
||||
// posted restyle hint that doesn't yet align with RestyleHint's
|
||||
// bits.
|
||||
if (aRestyleHint & eRestyle_Subtree) {
|
||||
aRestyleHint &= ~eRestyle_Subtree;
|
||||
aRestyleHint |= eRestyle_Self | eRestyle_SomeDescendants;
|
||||
}
|
||||
|
||||
if (aRestyleHint || aMinChangeHint) {
|
||||
Servo_NoteExplicitHints(aElement, aRestyleHint, aMinChangeHint);
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
|
||||
fails == bg-fixed-1.html bg-fixed-1.html
|
||||
== bg-fixed-1.html bg-fixed-1.html
|
||||
== bg-fixed-cover-1.html bg-fixed-cover-1.html
|
||||
fails == bg-fixed-cover-2.html bg-fixed-cover-2.html
|
||||
== bg-fixed-cover-2.html bg-fixed-cover-2.html
|
||||
skip-if(!asyncPan) == bg-fixed-cover-3.html bg-fixed-cover-3.html
|
||||
skip-if(!asyncPan) == bg-fixed-child.html bg-fixed-child.html
|
||||
fails == bg-fixed-child-clip-1.html bg-fixed-child-clip-1.html
|
||||
fails == bg-fixed-child-clip-2.html bg-fixed-child-clip-2.html
|
||||
== bg-fixed-child-clip-1.html bg-fixed-child-clip-1.html
|
||||
== bg-fixed-child-clip-2.html bg-fixed-child-clip-2.html
|
||||
fuzzy(1,246) fuzzy-if(skiaContent,2,160) fuzzy-if(browserIsRemote&&d2d,53,185) skip-if(!asyncPan) == bg-fixed-child-mask.html bg-fixed-child-mask.html
|
||||
== bg-fixed-in-opacity.html bg-fixed-in-opacity.html
|
||||
fails == bg-fixed-child-no-culling-1.html bg-fixed-child-no-culling-1.html
|
||||
== bg-fixed-child-no-culling-1.html bg-fixed-child-no-culling-1.html
|
||||
== bg-fixed-child-no-culling-2.html bg-fixed-child-no-culling-2.html
|
||||
fuzzy-if(Android,2,4000) fuzzy-if(browserIsRemote&&cocoaWidget,2,179524) fuzzy-if(browserIsRemote&&winWidget,1,74590) fuzzy-if(gtkWidget&&layersGPUAccelerated,1,3528) skip-if(!asyncPan) == bg-fixed-transformed-image.html bg-fixed-transformed-image.html
|
||||
== element-1.html element-1.html
|
||||
|
@ -8,26 +8,26 @@ include vector/reftest-stylo.list
|
||||
== layers-layer-count-cascade-2.xhtml layers-layer-count-cascade-2.xhtml
|
||||
fails == layers-layer-count-inheritance-2.xhtml layers-layer-count-inheritance-2.xhtml
|
||||
== viewport-translucent-color-1.html viewport-translucent-color-1.html
|
||||
fails == viewport-translucent-color-2.html viewport-translucent-color-2.html
|
||||
fails == viewport-translucent-color-3.html viewport-translucent-color-3.html
|
||||
== viewport-translucent-color-2.html viewport-translucent-color-2.html
|
||||
== viewport-translucent-color-3.html viewport-translucent-color-3.html
|
||||
== viewport-translucent-color-ref.html viewport-translucent-color-ref.html
|
||||
== iframe-translucent-color-1.html iframe-translucent-color-1.html
|
||||
== translucent-color-1.html translucent-color-1.html
|
||||
fails == translucent-color-2.html translucent-color-2.html
|
||||
== translucent-color-2.html translucent-color-2.html
|
||||
fuzzy-if(skiaContent,1,1024) == translucent-color-3.html translucent-color-3.html
|
||||
== translucent-color-ref.html translucent-color-ref.html
|
||||
== root-element-display-none-1.html root-element-display-none-1.html
|
||||
fails == continuous-inline-1a.html continuous-inline-1a.html
|
||||
fails == continuous-inline-1b.html continuous-inline-1b.html
|
||||
fails == continuous-inline-1c.html continuous-inline-1c.html
|
||||
fails == continuous-inline-1d.html continuous-inline-1d.html
|
||||
fails == continuous-inline-2a.html continuous-inline-2a.html
|
||||
fails == continuous-inline-2b.html continuous-inline-2b.html
|
||||
fails == continuous-inline-3.html continuous-inline-3.html
|
||||
fails == continuous-inline-4a.html continuous-inline-4a.html
|
||||
fails == continuous-inline-4b.html continuous-inline-4b.html
|
||||
fails == continuous-inline-5a.html continuous-inline-5a.html
|
||||
fails == continuous-inline-5b.html continuous-inline-5b.html
|
||||
== continuous-inline-1a.html continuous-inline-1a.html
|
||||
== continuous-inline-1b.html continuous-inline-1b.html
|
||||
== continuous-inline-1c.html continuous-inline-1c.html
|
||||
== continuous-inline-1d.html continuous-inline-1d.html
|
||||
== continuous-inline-2a.html continuous-inline-2a.html
|
||||
== continuous-inline-2b.html continuous-inline-2b.html
|
||||
== continuous-inline-3.html continuous-inline-3.html
|
||||
== continuous-inline-4a.html continuous-inline-4a.html
|
||||
== continuous-inline-4b.html continuous-inline-4b.html
|
||||
== continuous-inline-5a.html continuous-inline-5a.html
|
||||
== continuous-inline-5b.html continuous-inline-5b.html
|
||||
== background-redraw-237766.html background-redraw-237766.html
|
||||
|
||||
== background-clip-1.html background-clip-1.html
|
||||
@ -135,8 +135,8 @@ fails == background-moz-default-background-color.html background-moz-default-bac
|
||||
fails == fixed-bg-with-transform-outside-viewport-1.html fixed-bg-with-transform-outside-viewport-1.html
|
||||
fuzzy(2,83) == fixed-bg-border-radius.html fixed-bg-border-radius.html
|
||||
|
||||
fails HTTP == root-background-1.html root-background-1.html
|
||||
fails HTTP == root-background-1.html root-background-1.html
|
||||
HTTP == root-background-1.html root-background-1.html
|
||||
HTTP == root-background-1.html root-background-1.html
|
||||
|
||||
fails == really-big-background.html really-big-background.html # Bug 1341690
|
||||
fails == body-background.html body-background.html # Bug 1339711
|
||||
|
@ -441,8 +441,8 @@ fails == 331809-1.html 331809-1.html
|
||||
fails == 332557-1.html 332557-1.html
|
||||
== 332975-1.html 332975-1.html
|
||||
== 333970-1.html 333970-1.html
|
||||
== 334829-1a.xhtml 334829-1a.xhtml
|
||||
== 334829-1b.xhtml 334829-1b.xhtml
|
||||
fails == 334829-1a.xhtml 334829-1a.xhtml
|
||||
fails == 334829-1b.xhtml 334829-1b.xhtml
|
||||
fails == 335628-1.html 335628-1.html
|
||||
== 335628-2.xul 335628-2.xul
|
||||
== 336096-1.xul 336096-1.xul
|
||||
@ -601,10 +601,10 @@ fails == 367247-l-scroll.html 367247-l-scroll.html
|
||||
== 367612-1e.html 367612-1e.html
|
||||
== 367612-1f.html 367612-1f.html
|
||||
== 367612-1g.html 367612-1g.html
|
||||
fails == 368020-1.html 368020-1.html
|
||||
fails == 368020-2.html 368020-2.html
|
||||
fails == 368020-3.html 368020-3.html
|
||||
fails pref(layout.css.box-decoration-break.enabled,true) == 368020-5.html 368020-5.html
|
||||
random == 368020-1.html 368020-1.html
|
||||
== 368020-2.html 368020-2.html
|
||||
== 368020-3.html 368020-3.html
|
||||
pref(layout.css.box-decoration-break.enabled,true) == 368020-5.html 368020-5.html
|
||||
== 368155-1.xhtml 368155-1.xhtml
|
||||
asserts(4-8) == 368155-negative-margins-1.html 368155-negative-margins-1.html
|
||||
# we can't test this because there's antialiasing involved, and our comparison
|
||||
@ -999,7 +999,7 @@ fails == 419531-1.html 419531-1.html
|
||||
== 420069-1.html 420069-1.html
|
||||
== 420069-2.html 420069-2.html
|
||||
== 420351-1.html 420351-1.html
|
||||
fails == 420790-1.xhtml 420790-1.xhtml
|
||||
== 420790-1.xhtml 420790-1.xhtml
|
||||
== 421069.html 421069.html
|
||||
== 421069.html 421069.html
|
||||
== 421069-ref.html 421069-ref.html
|
||||
@ -1211,21 +1211,21 @@ fails == 456330-1.gif 456330-1.gif
|
||||
fails == 458296-1b.html 458296-1b.html
|
||||
fails == 458296-1c.html 458296-1c.html
|
||||
fails == 458296-1d.html 458296-1d.html
|
||||
fails == 458487-1a.html 458487-1a.html
|
||||
fails == 458487-1b.html 458487-1b.html
|
||||
fails == 458487-1c.html 458487-1c.html
|
||||
fails == 458487-1d.html 458487-1d.html
|
||||
fails == 458487-1e.html 458487-1e.html
|
||||
fails == 458487-1f.html 458487-1f.html
|
||||
fails == 458487-1g.html 458487-1g.html
|
||||
fails == 458487-1h.html 458487-1h.html
|
||||
== 458487-1a.html 458487-1a.html
|
||||
== 458487-1b.html 458487-1b.html
|
||||
== 458487-1c.html 458487-1c.html
|
||||
== 458487-1d.html 458487-1d.html
|
||||
== 458487-1e.html 458487-1e.html
|
||||
== 458487-1f.html 458487-1f.html
|
||||
== 458487-1g.html 458487-1g.html
|
||||
== 458487-1h.html 458487-1h.html
|
||||
== 458487-2.html 458487-2.html
|
||||
== 458487-3.html 458487-3.html
|
||||
fails == 458487-4a.html 458487-4a.html
|
||||
fails == 458487-4b.html 458487-4b.html
|
||||
fails == 458487-4c.html 458487-4c.html
|
||||
fails == 458487-5a.html 458487-5a.html
|
||||
fails == 458487-5b.html 458487-5b.html
|
||||
== 458487-4a.html 458487-4a.html
|
||||
== 458487-4b.html 458487-4b.html
|
||||
== 458487-4c.html 458487-4c.html
|
||||
== 458487-5a.html 458487-5a.html
|
||||
== 458487-5b.html 458487-5b.html
|
||||
== 459443-1.html 459443-1.html
|
||||
== 459613-1.html 459613-1.html
|
||||
== 460012-1.html 460012-1.html
|
||||
@ -1237,10 +1237,10 @@ fails == 458487-5b.html 458487-5b.html
|
||||
== 462844-4.html 462844-4.html
|
||||
== 463204-1.html 463204-1.html
|
||||
== 463217-1.xul 463217-1.xul
|
||||
fails == 463952-1.html 463952-1.html
|
||||
fails == 464811-1.html 464811-1.html
|
||||
== 463952-1.html 463952-1.html
|
||||
== 464811-1.html 464811-1.html
|
||||
== 465574-1.html 465574-1.html
|
||||
fails == 466258-1.html 466258-1.html
|
||||
== 466258-1.html 466258-1.html
|
||||
== 466395-1.html 466395-1.html
|
||||
== 466395-2.html 466395-2.html
|
||||
fails == 467084-1.html 467084-1.html
|
||||
@ -1642,10 +1642,10 @@ fails == 617242-1.html 617242-1.html
|
||||
fails == 618071.html 618071.html
|
||||
fails == 619117-1.html 619117-1.html
|
||||
fails HTTP(..) == 619511-1.html 619511-1.html
|
||||
fails == 621253-1-externalFilter.html 621253-1-externalFilter.html
|
||||
fails == 621253-1-internalFilter.html 621253-1-internalFilter.html
|
||||
fails HTTP(..) == 621253-2-externalFilter.html 621253-2-externalFilter.html
|
||||
fails == 621253-2-internalFilter.html 621253-2-internalFilter.html
|
||||
== 621253-1-externalFilter.html 621253-1-externalFilter.html
|
||||
== 621253-1-internalFilter.html 621253-1-internalFilter.html
|
||||
HTTP(..) == 621253-2-externalFilter.html 621253-2-externalFilter.html
|
||||
== 621253-2-internalFilter.html 621253-2-internalFilter.html
|
||||
random-if(winWidget) fuzzy-if(OSX==1008,19,17) == 621918-1.svg 621918-1.svg
|
||||
random-if(winWidget) HTTP(..) == 621918-2.svg 621918-2.svg
|
||||
fails == 622585-1.html 622585-1.html
|
||||
@ -1834,7 +1834,7 @@ fails == 1018522-1.html 1018522-1.html
|
||||
== 1021564-2.html 1021564-2.html
|
||||
== 1021564-3.html 1021564-3.html
|
||||
== 1021564-4.html 1021564-4.html
|
||||
fails pref(browser.display.use_document_fonts,0) == 1022481-1.html 1022481-1.html
|
||||
pref(browser.display.use_document_fonts,0) == 1022481-1.html 1022481-1.html
|
||||
== 1022612-1.html 1022612-1.html
|
||||
== 1024473-1.html 1024473-1.html
|
||||
== 1025914-1.html 1025914-1.html
|
||||
|
@ -7,8 +7,8 @@
|
||||
== unit-rem-root-fontsize.html unit-rem-root-fontsize.html
|
||||
fails == unit-rem-root-width.html unit-rem-root-width.html
|
||||
== unit-rem.svg unit-rem.svg
|
||||
fails == unit-vh-vw.html unit-vh-vw.html
|
||||
fails == unit-vh-vw-zoom.html unit-vh-vw-zoom.html
|
||||
== unit-vh-vw.html unit-vh-vw.html
|
||||
random == unit-vh-vw-zoom.html unit-vh-vw-zoom.html
|
||||
fails == unit-vh-vw-overflow-auto.html unit-vh-vw-overflow-auto.html
|
||||
fails == unit-vh-vw-overflow-scroll.html unit-vh-vw-overflow-scroll.html
|
||||
fails == unit-vh-vw-overflow-scroll-x.html unit-vh-vw-overflow-scroll-x.html
|
||||
|
@ -32,7 +32,7 @@
|
||||
== insertmultiplemultiple-2.html insertmultiplemultiple-2.html
|
||||
|
||||
# testing bindings that have multiple insertion points
|
||||
fails == multipleinsertionpoints-ref2.xhtml multipleinsertionpoints-ref2.xhtml
|
||||
== multipleinsertionpoints-ref2.xhtml multipleinsertionpoints-ref2.xhtml
|
||||
# append a single element
|
||||
fails == multipleinsertionpoints-appendsingle-1.xhtml multipleinsertionpoints-appendsingle-1.xhtml
|
||||
fails == multipleinsertionpoints-appendsingle-2.xhtml multipleinsertionpoints-appendsingle-2.xhtml
|
||||
|
@ -63,7 +63,7 @@ pref(font.size.inflation.emPerLine,15) pref(font.size.inflation.forceEnabled,tru
|
||||
pref(font.size.inflation.emPerLine,15) pref(font.size.inflation.forceEnabled,true) pref(font.size.inflation.lineThreshold,0) == disable-fontinfl-on-mobile-2.html disable-fontinfl-on-mobile-2.html
|
||||
pref(font.size.inflation.emPerLine,15) pref(font.size.inflation.forceEnabled,true) pref(font.size.inflation.lineThreshold,0) == disable-fontinfl-on-mobile-3.html disable-fontinfl-on-mobile-3.html
|
||||
pref(font.size.inflation.emPerLine,15) pref(font.size.inflation.forceEnabled,true) pref(font.size.inflation.lineThreshold,0) == disable-fontinfl-on-mobile-5.html disable-fontinfl-on-mobile-5.html
|
||||
fails pref(font.size.inflation.emPerLine,15) pref(font.size.inflation.forceEnabled,true) pref(font.size.inflation.lineThreshold,0) == preformatted-text.html preformatted-text.html
|
||||
pref(font.size.inflation.emPerLine,15) pref(font.size.inflation.forceEnabled,true) pref(font.size.inflation.lineThreshold,0) == preformatted-text.html preformatted-text.html
|
||||
pref(font.size.inflation.emPerLine,15) pref(font.size.inflation.forceEnabled,true) pref(font.size.inflation.lineThreshold,0) == fixed-height-body.html fixed-height-body.html
|
||||
pref(font.size.inflation.emPerLine,15) pref(font.size.inflation.forceEnabled,true) pref(font.size.inflation.lineThreshold,0) == fixed-height-body-child.html fixed-height-body-child.html
|
||||
pref(font.size.inflation.emPerLine,15) pref(font.size.inflation.forceEnabled,true) pref(font.size.inflation.lineThreshold,0) == consecutive-inline.html consecutive-inline.html
|
||||
|
@ -1,11 +1,11 @@
|
||||
# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
|
||||
HTTP == deferred-anchor.xhtml#d deferred-anchor-ref.xhtml#d
|
||||
fuzzy-if(xulRuntime.widgetToolkit=="gtk3",1,23) == deferred-anchor2.xhtml deferred-anchor2.xhtml
|
||||
fails HTTP == fixed-1.html fixed-1.html
|
||||
fails == fixed-table-1.html fixed-table-1.html
|
||||
fails HTTP == fixed-opacity-1.html fixed-opacity-1.html
|
||||
fails HTTP == fixed-opacity-2.html fixed-opacity-2.html
|
||||
fails == fixed-text-1.html fixed-text-1.html
|
||||
HTTP == fixed-1.html fixed-1.html
|
||||
random == fixed-table-1.html fixed-table-1.html
|
||||
HTTP == fixed-opacity-1.html fixed-opacity-1.html
|
||||
HTTP == fixed-opacity-2.html fixed-opacity-2.html
|
||||
== fixed-text-1.html fixed-text-1.html
|
||||
HTTP == fixed-text-2.html fixed-text-2.html
|
||||
fails == iframe-border-radius.html iframe-border-radius.html
|
||||
== image-1.html image-1.html
|
||||
@ -22,7 +22,7 @@ fails == scroll-behavior-8.html scroll-behavior-8.html
|
||||
fails == scroll-behavior-9.html scroll-behavior-9.html
|
||||
skip-if(Android) pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-10.html scroll-behavior-10.html
|
||||
fails == scroll-behavior-textarea.html scroll-behavior-textarea.html
|
||||
fails HTTP == simple-1.html simple-1.html
|
||||
HTTP == simple-1.html simple-1.html
|
||||
fails HTTP == subpixel-1.html#d subpixel-1-ref.html#d
|
||||
== text-1.html text-1.html
|
||||
== text-2.html?up text-2.html?up
|
||||
|
@ -6,17 +6,17 @@ include zoom/reftest-stylo.list
|
||||
|
||||
# Background-image tests
|
||||
== background-display-none-1.html background-display-none-1.html
|
||||
fails == background-simple-1.html background-simple-1.html
|
||||
fails == background-simple-2.html background-simple-2.html
|
||||
== background-simple-1.html background-simple-1.html
|
||||
== background-simple-2.html background-simple-2.html
|
||||
|
||||
# Sightly trickier background-image test
|
||||
fails == background-viewBox-1.html background-viewBox-1.html
|
||||
== background-viewBox-1.html background-viewBox-1.html
|
||||
|
||||
# background tests with the background area getting resized
|
||||
fails == background-resize-1.html background-resize-1.html
|
||||
fails == background-resize-2.html background-resize-2.html
|
||||
fails == background-resize-3.html background-resize-3.html
|
||||
fails == background-resize-4.html background-resize-4.html
|
||||
== background-resize-1.html background-resize-1.html
|
||||
== background-resize-2.html background-resize-2.html
|
||||
== background-resize-3.html background-resize-3.html
|
||||
== background-resize-4.html background-resize-4.html
|
||||
|
||||
# Test for stretching background images by different amounts in each dimension
|
||||
== background-stretch-1.html background-stretch-1.html
|
||||
|
@ -2,21 +2,21 @@
|
||||
# clip-path tests
|
||||
include clip-path/reftest-stylo.list
|
||||
|
||||
fails == clipPath-html-01.xhtml clipPath-html-01.xhtml
|
||||
fails == clipPath-html-01-extref.xhtml clipPath-html-01-extref.xhtml
|
||||
fails == clipPath-html-02.xhtml clipPath-html-02.xhtml
|
||||
fails == clipPath-html-02-extref.xhtml clipPath-html-02-extref.xhtml
|
||||
fails == clipPath-html-03.xhtml clipPath-html-03.xhtml
|
||||
fails == clipPath-html-03-extref.xhtml clipPath-html-03-extref.xhtml
|
||||
fails == clipPath-html-04.xhtml clipPath-html-04.xhtml
|
||||
fails == clipPath-html-04-extref.xhtml clipPath-html-04-extref.xhtml
|
||||
fails == clipPath-html-05.xhtml clipPath-html-05.xhtml
|
||||
fails == clipPath-html-05-extref.xhtml clipPath-html-05-extref.xhtml
|
||||
fails == clipPath-html-06.xhtml clipPath-html-06.xhtml
|
||||
fails == clipPath-html-06-extref.xhtml clipPath-html-06-extref.xhtml
|
||||
== clipPath-html-01.xhtml clipPath-html-01.xhtml
|
||||
== clipPath-html-01-extref.xhtml clipPath-html-01-extref.xhtml
|
||||
== clipPath-html-02.xhtml clipPath-html-02.xhtml
|
||||
== clipPath-html-02-extref.xhtml clipPath-html-02-extref.xhtml
|
||||
== clipPath-html-03.xhtml clipPath-html-03.xhtml
|
||||
== clipPath-html-03-extref.xhtml clipPath-html-03-extref.xhtml
|
||||
== clipPath-html-04.xhtml clipPath-html-04.xhtml
|
||||
== clipPath-html-04-extref.xhtml clipPath-html-04-extref.xhtml
|
||||
== clipPath-html-05.xhtml clipPath-html-05.xhtml
|
||||
== clipPath-html-05-extref.xhtml clipPath-html-05-extref.xhtml
|
||||
== clipPath-html-06.xhtml clipPath-html-06.xhtml
|
||||
== clipPath-html-06-extref.xhtml clipPath-html-06-extref.xhtml
|
||||
== clipPath-html-07.xhtml clipPath-html-07.xhtml
|
||||
fails == clipPath-html-08.xhtml clipPath-html-08.xhtml
|
||||
fails == clipPath-html-zoomed-01.xhtml clipPath-html-zoomed-01.xhtml
|
||||
== clipPath-html-08.xhtml clipPath-html-08.xhtml
|
||||
== clipPath-html-zoomed-01.xhtml clipPath-html-zoomed-01.xhtml
|
||||
== clipPath-transformed-html-01.xhtml clipPath-transformed-html-01.xhtml
|
||||
== clipPath-transformed-html-02.xhtml clipPath-transformed-html-02.xhtml
|
||||
== conditions-outer-svg-01.xhtml conditions-outer-svg-01.xhtml
|
||||
@ -25,9 +25,9 @@ fails == dynamic-conditions-outer-svg-01.xhtml dynamic-conditions-outer-svg-01.x
|
||||
fails == dynamic-conditions-outer-svg-02.xhtml dynamic-conditions-outer-svg-02.xhtml
|
||||
fails == dynamic-conditions-outer-svg-03.xhtml dynamic-conditions-outer-svg-03.xhtml
|
||||
== dynamic-conditions-outer-svg-04.xhtml dynamic-conditions-outer-svg-04.xhtml
|
||||
fails == filter-html-01.xhtml filter-html-01.xhtml
|
||||
fails == filter-html-01-extref.xhtml filter-html-01-extref.xhtml
|
||||
fails == filter-html-zoomed-01.xhtml filter-html-zoomed-01.xhtml
|
||||
== filter-html-01.xhtml filter-html-01.xhtml
|
||||
random == filter-html-01-extref.xhtml filter-html-01-extref.xhtml
|
||||
== filter-html-zoomed-01.xhtml filter-html-zoomed-01.xhtml
|
||||
fails == mask-html-01.xhtml mask-html-01.xhtml
|
||||
fails == mask-html-01-extref-01.xhtml mask-html-01-extref-01.xhtml
|
||||
random == mask-html-01-extref-02.xhtml mask-html-01-extref-02.xhtml
|
||||
|
@ -131,8 +131,8 @@ fails == wordwrap-03.html wordwrap-03.html
|
||||
== overflowwrap-04.html overflowwrap-04.html
|
||||
fails == wordwrap-05.html wordwrap-05.html
|
||||
fails == overflowwrap-05.html overflowwrap-05.html
|
||||
fails == wordwrap-06.html wordwrap-06.html
|
||||
fails == overflowwrap-06.html overflowwrap-06.html
|
||||
== wordwrap-06.html wordwrap-06.html
|
||||
== overflowwrap-06.html overflowwrap-06.html
|
||||
== wordwrap-07.html wordwrap-07.html
|
||||
== overflowwrap-07.html overflowwrap-07.html
|
||||
fails == wordwrap-08.html wordwrap-08.html # Bug 1341637, bug 1321769?
|
||||
|
@ -39,7 +39,7 @@ fails == backface-visibility-1b.html backface-visibility-1b.html
|
||||
fails == backface-visibility-1c.html backface-visibility-1c.html
|
||||
fails == backface-visibility-2.html backface-visibility-2.html
|
||||
== backface-visibility-3.html backface-visibility-3.html
|
||||
fails == perspective-clipping-1.html perspective-clipping-1.html
|
||||
== perspective-clipping-1.html perspective-clipping-1.html
|
||||
fails == perspective-origin-1a.html perspective-origin-1a.html
|
||||
fails == perspective-origin-1b.html perspective-origin-1b.html
|
||||
fails == perspective-origin-2a.html perspective-origin-2a.html
|
||||
|
@ -226,18 +226,18 @@ fails == css-values-3/calc-in-media-queries-002.html css-values-3/calc-in-media-
|
||||
== css-values-3/calc-parenthesis-stack.html css-values-3/calc-parenthesis-stack.html
|
||||
fails == css-values-3/ch-unit-001.html css-values-3/ch-unit-001.html
|
||||
== css-values-3/initial-background-color.html css-values-3/initial-background-color.html
|
||||
fails == css-values-3/vh-calc-support-pct.html css-values-3/vh-calc-support-pct.html
|
||||
fails == css-values-3/vh-calc-support.html css-values-3/vh-calc-support.html
|
||||
fails == css-values-3/vh-em-inherit.html css-values-3/vh-em-inherit.html
|
||||
fails == css-values-3/vh-inherit.html css-values-3/vh-inherit.html
|
||||
fails == css-values-3/vh-interpolate-pct.html css-values-3/vh-interpolate-pct.html
|
||||
fails == css-values-3/vh-interpolate-px.html css-values-3/vh-interpolate-px.html
|
||||
fails == css-values-3/vh-interpolate-vh.html css-values-3/vh-interpolate-vh.html
|
||||
== css-values-3/vh-calc-support-pct.html css-values-3/vh-calc-support-pct.html
|
||||
== css-values-3/vh-calc-support.html css-values-3/vh-calc-support.html
|
||||
== css-values-3/vh-em-inherit.html css-values-3/vh-em-inherit.html
|
||||
== css-values-3/vh-inherit.html css-values-3/vh-inherit.html
|
||||
== css-values-3/vh-interpolate-pct.html css-values-3/vh-interpolate-pct.html
|
||||
== css-values-3/vh-interpolate-px.html css-values-3/vh-interpolate-px.html
|
||||
== css-values-3/vh-interpolate-vh.html css-values-3/vh-interpolate-vh.html
|
||||
fails == css-values-3/vh-support-atviewport.html css-values-3/vh-support-atviewport.html
|
||||
== css-values-3/vh-support-margin.html css-values-3/vh-support-margin.html
|
||||
== css-values-3/vh-support-transform-origin.html css-values-3/vh-support-transform-origin.html
|
||||
== css-values-3/vh-support-transform-translate.html css-values-3/vh-support-transform-translate.html
|
||||
fails == css-values-3/vh-support.html css-values-3/vh-support.html
|
||||
== css-values-3/vh-support.html css-values-3/vh-support.html
|
||||
== css-values-3/vh-zero-support.html css-values-3/vh-zero-support.html
|
||||
fails == css-values-3/vh_not_refreshing_on_chrome.html css-values-3/vh_not_refreshing_on_chrome.html
|
||||
skip-if(stylo) == css-values-3/vh_not_refreshing_on_chrome_iframe.html css-values-3/vh_not_refreshing_on_chrome_iframe.html # Why does this fail to load?
|
||||
|
@ -5,6 +5,7 @@
|
||||
<title>CSS transforms: perspective: 0px</title>
|
||||
<link rel="author" title="Miko Mynttinen" href="mailto:mmynttinen@mozilla.com">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#propdef-perspective">
|
||||
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/413">
|
||||
<meta name="assert" content="Test checks that perspective: 0px behaves like transform: perspective(0) on parent container">
|
||||
<link rel="match" href="perspective-zero-2-ref.html">
|
||||
|
@ -147,7 +147,7 @@ skip-if(stylo) == 1172774-percent-padding-1.html 1172774-percent-padding-1.html
|
||||
skip-if(stylo) == 1172774-percent-padding-2.html 1172774-percent-padding-2.html
|
||||
skip-if(stylo) == 1172774-percent-padding-3.html 1172774-percent-padding-3.html
|
||||
skip-if(stylo) == 1172774-percent-padding-4.html 1172774-percent-padding-4.html
|
||||
fails == 1174450-intrinsic-sizing.html 1174450-intrinsic-sizing.html
|
||||
== 1174450-intrinsic-sizing.html 1174450-intrinsic-sizing.html
|
||||
fails == 1175789-underline-overline-1.html 1175789-underline-overline-1.html
|
||||
== 1188061-1-nsChangeHint_ClearAncestorIntrinsics.html 1188061-1-nsChangeHint_ClearAncestorIntrinsics.html
|
||||
== 1188061-2-nsChangeHint_UpdateComputedBSize.html 1188061-2-nsChangeHint_UpdateComputedBSize.html
|
||||
|
72
layout/style/CSSMediaRule.cpp
Normal file
72
layout/style/CSSMediaRule.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/CSSMediaRule.h"
|
||||
|
||||
#include "mozilla/dom/CSSMediaRuleBinding.h"
|
||||
#include "mozilla/dom/MediaList.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(CSSMediaRule, css::ConditionRule)
|
||||
NS_IMPL_RELEASE_INHERITED(CSSMediaRule, css::ConditionRule)
|
||||
|
||||
// QueryInterface implementation for CSSMediaRule
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(CSSMediaRule)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule)
|
||||
NS_INTERFACE_MAP_END_INHERITING(css::ConditionRule)
|
||||
|
||||
// nsIDOMCSSGroupingRule methods
|
||||
NS_IMETHODIMP
|
||||
CSSMediaRule::GetCssRules(nsIDOMCSSRuleList** aRuleList)
|
||||
{
|
||||
return GroupRule::GetCssRules(aRuleList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSMediaRule::InsertRule(const nsAString& aRule,
|
||||
uint32_t aIndex, uint32_t* _retval)
|
||||
{
|
||||
return GroupRule::InsertRule(aRule, aIndex, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSMediaRule::DeleteRule(uint32_t aIndex)
|
||||
{
|
||||
return GroupRule::DeleteRule(aIndex);
|
||||
}
|
||||
|
||||
// nsIDOMCSSMediaRule methods
|
||||
NS_IMETHODIMP
|
||||
CSSMediaRule::GetMedia(nsIDOMMediaList* *aMedia)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aMedia);
|
||||
NS_IF_ADDREF(*aMedia = Media());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
CSSMediaRule::SetConditionText(const nsAString& aConditionText,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsresult rv = static_cast<nsIDOMCSSConditionRule*>(this)->
|
||||
SetConditionText(aConditionText);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */ JSObject*
|
||||
CSSMediaRule::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return CSSMediaRuleBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
54
layout/style/CSSMediaRule.h
Normal file
54
layout/style/CSSMediaRule.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_CSSMediaRule_h
|
||||
#define mozilla_dom_CSSMediaRule_h
|
||||
|
||||
#include "mozilla/css/GroupRule.h"
|
||||
#include "nsIDOMCSSMediaRule.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class CSSMediaRule : public css::ConditionRule
|
||||
, public nsIDOMCSSMediaRule
|
||||
{
|
||||
protected:
|
||||
using ConditionRule::ConditionRule;
|
||||
virtual ~CSSMediaRule() {}
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
int32_t GetType() const override { return css::Rule::MEDIA_RULE; }
|
||||
|
||||
// XPCOM interface
|
||||
using Rule::GetType;
|
||||
|
||||
// nsIDOMCSSGroupingRule interface
|
||||
NS_DECL_NSIDOMCSSGROUPINGRULE
|
||||
|
||||
// nsIDOMCSSConditionRule interface
|
||||
NS_IMETHOD SetConditionText(const nsAString& aConditionText) override = 0;
|
||||
|
||||
// nsIDOMCSSMediaRule interface
|
||||
NS_DECL_NSIDOMCSSMEDIARULE
|
||||
|
||||
// WebIDL interface
|
||||
uint16_t Type() const override { return nsIDOMCSSRule::MEDIA_RULE; }
|
||||
// Our XPCOM GetConditionText is OK
|
||||
void SetConditionText(const nsAString& aConditionText,
|
||||
ErrorResult& aRv) final;
|
||||
virtual MediaList* Media() = 0;
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_CSSMediaRule_h
|
@ -513,7 +513,8 @@ CSSStyleSheet::UseForPresentation(nsPresContext* aPresContext,
|
||||
nsMediaQueryResultCacheKey& aKey) const
|
||||
{
|
||||
if (mMedia) {
|
||||
return mMedia->Matches(aPresContext, &aKey);
|
||||
auto media = static_cast<nsMediaList*>(mMedia.get());
|
||||
return media->Matches(aPresContext, &aKey);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -900,48 +901,10 @@ CSSStyleSheet::DeleteRuleInternal(uint32_t aIndex, ErrorResult& aRv)
|
||||
}
|
||||
|
||||
nsresult
|
||||
CSSStyleSheet::DeleteRuleFromGroup(css::GroupRule* aGroup, uint32_t aIndex)
|
||||
CSSStyleSheet::InsertRuleIntoGroupInternal(const nsAString& aRule,
|
||||
css::GroupRule* aGroup,
|
||||
uint32_t aIndex)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aGroup);
|
||||
NS_ASSERTION(mInner->mComplete, "No deleting from an incomplete sheet!");
|
||||
RefPtr<css::Rule> rule = aGroup->GetStyleRuleAt(aIndex);
|
||||
NS_ENSURE_TRUE(rule, NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
// check that the rule actually belongs to this sheet!
|
||||
if (this != rule->GetStyleSheet()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
|
||||
|
||||
WillDirty();
|
||||
|
||||
nsresult result = aGroup->DeleteStyleRuleAt(aIndex);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
rule->SetStyleSheet(nullptr);
|
||||
|
||||
DidDirty();
|
||||
|
||||
if (mDocument) {
|
||||
mDocument->StyleRuleRemoved(this, rule);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
CSSStyleSheet::InsertRuleIntoGroup(const nsAString & aRule,
|
||||
css::GroupRule* aGroup,
|
||||
uint32_t aIndex,
|
||||
uint32_t* _retval)
|
||||
{
|
||||
NS_ASSERTION(mInner->mComplete, "No inserting into an incomplete sheet!");
|
||||
// check that the group actually belongs to this sheet!
|
||||
if (this != aGroup->GetStyleSheet()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Hold strong ref to the CSSLoader in case the document update
|
||||
// kills the document
|
||||
RefPtr<css::Loader> loader;
|
||||
@ -952,11 +915,6 @@ CSSStyleSheet::InsertRuleIntoGroup(const nsAString & aRule,
|
||||
|
||||
nsCSSParser css(loader, this);
|
||||
|
||||
// parse and grab the rule
|
||||
mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
|
||||
|
||||
WillDirty();
|
||||
|
||||
RefPtr<css::Rule> rule;
|
||||
nsresult result = css.ParseRule(aRule, mInner->mSheetURI, mInner->mBaseURI,
|
||||
mInner->mPrincipal, getter_AddRefs(rule));
|
||||
@ -984,16 +942,7 @@ CSSStyleSheet::InsertRuleIntoGroup(const nsAString & aRule,
|
||||
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
||||
}
|
||||
|
||||
result = aGroup->InsertStyleRuleAt(aIndex, rule);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
DidDirty();
|
||||
|
||||
if (mDocument) {
|
||||
mDocument->StyleRuleAdded(this, rule);
|
||||
}
|
||||
|
||||
*_retval = aIndex;
|
||||
return NS_OK;
|
||||
return aGroup->InsertStyleRuleAt(aIndex, rule);
|
||||
}
|
||||
|
||||
// nsICSSLoaderObserver implementation
|
||||
|
@ -116,9 +116,6 @@ public:
|
||||
int32_t StyleRuleCount() const;
|
||||
css::Rule* GetStyleRuleAt(int32_t aIndex) const;
|
||||
|
||||
nsresult DeleteRuleFromGroup(css::GroupRule* aGroup, uint32_t aIndex);
|
||||
nsresult InsertRuleIntoGroup(const nsAString& aRule, css::GroupRule* aGroup, uint32_t aIndex, uint32_t* _retval);
|
||||
|
||||
void SetOwnerRule(css::ImportRule* aOwnerRule) { mOwnerRule = aOwnerRule; /* Not ref counted */ }
|
||||
css::ImportRule* GetOwnerRule() const { return mOwnerRule; }
|
||||
// Workaround overloaded-virtual warning in GCC.
|
||||
@ -222,6 +219,9 @@ protected:
|
||||
uint32_t InsertRuleInternal(const nsAString& aRule,
|
||||
uint32_t aIndex, ErrorResult& aRv);
|
||||
void DeleteRuleInternal(uint32_t aIndex, ErrorResult& aRv);
|
||||
nsresult InsertRuleIntoGroupInternal(const nsAString& aRule,
|
||||
css::GroupRule* aGroup,
|
||||
uint32_t aIndex);
|
||||
|
||||
void EnabledStateChangedInternal();
|
||||
|
||||
|
420
layout/style/GroupRule.cpp
Normal file
420
layout/style/GroupRule.cpp
Normal file
@ -0,0 +1,420 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* internal interface representing CSS style rules that contain other
|
||||
* rules, such as @media rules
|
||||
*/
|
||||
|
||||
#include "mozilla/css/GroupRule.h"
|
||||
|
||||
#include "mozilla/dom/CSSRuleList.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
|
||||
#define CALL_INNER(inner_, call_) \
|
||||
((inner_).is<GeckoGroupRuleRules>() \
|
||||
? (inner_).as<GeckoGroupRuleRules>().call_ \
|
||||
: (inner_).as<ServoGroupRuleRules>().call_)
|
||||
|
||||
// -------------------------------
|
||||
// Style Rule List for group rules
|
||||
//
|
||||
|
||||
class GroupRuleRuleList final : public dom::CSSRuleList
|
||||
{
|
||||
public:
|
||||
explicit GroupRuleRuleList(GroupRule *aGroupRule);
|
||||
|
||||
virtual CSSStyleSheet* GetParentObject() override;
|
||||
|
||||
virtual Rule*
|
||||
IndexedGetter(uint32_t aIndex, bool& aFound) override;
|
||||
virtual uint32_t
|
||||
Length() override;
|
||||
|
||||
void DropReference() { mGroupRule = nullptr; }
|
||||
|
||||
private:
|
||||
~GroupRuleRuleList();
|
||||
|
||||
private:
|
||||
GroupRule* mGroupRule;
|
||||
};
|
||||
|
||||
GroupRuleRuleList::GroupRuleRuleList(GroupRule *aGroupRule)
|
||||
{
|
||||
// Not reference counted to avoid circular references.
|
||||
// The rule will tell us when its going away.
|
||||
mGroupRule = aGroupRule;
|
||||
}
|
||||
|
||||
GroupRuleRuleList::~GroupRuleRuleList()
|
||||
{
|
||||
}
|
||||
|
||||
CSSStyleSheet*
|
||||
GroupRuleRuleList::GetParentObject()
|
||||
{
|
||||
if (!mGroupRule) {
|
||||
return nullptr;
|
||||
}
|
||||
StyleSheet* sheet = mGroupRule->GetStyleSheet();
|
||||
return sheet ? sheet->AsGecko() : nullptr;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GroupRuleRuleList::Length()
|
||||
{
|
||||
if (!mGroupRule) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return AssertedCast<uint32_t>(mGroupRule->StyleRuleCount());
|
||||
}
|
||||
|
||||
Rule*
|
||||
GroupRuleRuleList::IndexedGetter(uint32_t aIndex, bool& aFound)
|
||||
{
|
||||
aFound = false;
|
||||
|
||||
if (mGroupRule) {
|
||||
RefPtr<Rule> rule = mGroupRule->GetStyleRuleAt(aIndex);
|
||||
if (rule) {
|
||||
aFound = true;
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
// GeckoGroupRuleRules
|
||||
//
|
||||
|
||||
GeckoGroupRuleRules::GeckoGroupRuleRules()
|
||||
{
|
||||
}
|
||||
|
||||
GeckoGroupRuleRules::GeckoGroupRuleRules(GeckoGroupRuleRules&& aOther)
|
||||
: mRules(Move(aOther.mRules))
|
||||
, mRuleCollection(Move(aOther.mRuleCollection))
|
||||
{
|
||||
}
|
||||
|
||||
GeckoGroupRuleRules::GeckoGroupRuleRules(const GeckoGroupRuleRules& aCopy)
|
||||
{
|
||||
for (const Rule* rule : aCopy.mRules) {
|
||||
RefPtr<Rule> clone = rule->Clone();
|
||||
mRules.AppendObject(clone);
|
||||
}
|
||||
}
|
||||
|
||||
GeckoGroupRuleRules::~GeckoGroupRuleRules()
|
||||
{
|
||||
for (Rule* rule : mRules) {
|
||||
rule->SetParentRule(nullptr);
|
||||
}
|
||||
if (mRuleCollection) {
|
||||
mRuleCollection->DropReference();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GeckoGroupRuleRules::Clear()
|
||||
{
|
||||
mRules.Clear();
|
||||
if (mRuleCollection) {
|
||||
mRuleCollection->DropReference();
|
||||
mRuleCollection = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GeckoGroupRuleRules::Traverse(nsCycleCollectionTraversalCallback& cb)
|
||||
{
|
||||
IncrementalClearCOMRuleArray& rules = mRules;
|
||||
for (int32_t i = 0, count = rules.Count(); i < count; ++i) {
|
||||
if (!rules[i]->IsCCLeaf()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRules[i]");
|
||||
cb.NoteXPCOMChild(rules[i]);
|
||||
}
|
||||
}
|
||||
ImplCycleCollectionTraverse(cb, mRuleCollection, "mRuleCollection");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
GeckoGroupRuleRules::List(FILE* out, int32_t aIndent) const
|
||||
{
|
||||
for (const Rule* rule : mRules) {
|
||||
rule->List(out, aIndent + 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
GeckoGroupRuleRules::DeleteStyleRuleAt(uint32_t aIndex)
|
||||
{
|
||||
Rule* rule = mRules.SafeObjectAt(aIndex);
|
||||
if (rule) {
|
||||
rule->SetStyleSheet(nullptr);
|
||||
rule->SetParentRule(nullptr);
|
||||
}
|
||||
return mRules.RemoveObjectAt(aIndex) ? NS_OK : NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
CSSRuleList*
|
||||
GeckoGroupRuleRules::CssRules(GroupRule* aParentRule)
|
||||
{
|
||||
if (!mRuleCollection) {
|
||||
mRuleCollection = new GroupRuleRuleList(aParentRule);
|
||||
}
|
||||
return mRuleCollection;
|
||||
}
|
||||
|
||||
size_t
|
||||
GeckoGroupRuleRules::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = mRules.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
for (const Rule* rule : mRules) {
|
||||
n += rule->SizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
// Measurement of the following members may be added later if DMD finds it is
|
||||
// worthwhile:
|
||||
// - mRuleCollection
|
||||
return n;
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
// ServoGroupRuleRules
|
||||
//
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
ServoGroupRuleRules::List(FILE* out, int32_t aIndent) const
|
||||
{
|
||||
// TODO list something reasonable?
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t
|
||||
ServoGroupRuleRules::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
// TODO how to implement?
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
// GroupRule
|
||||
//
|
||||
|
||||
GroupRule::GroupRule(uint32_t aLineNumber, uint32_t aColumnNumber)
|
||||
: Rule(aLineNumber, aColumnNumber)
|
||||
, mInner(GeckoGroupRuleRules())
|
||||
{
|
||||
}
|
||||
|
||||
GroupRule::GroupRule(already_AddRefed<ServoCssRules> aRules)
|
||||
: Rule(0, 0) // TODO
|
||||
, mInner(ServoGroupRuleRules(Move(aRules)))
|
||||
{
|
||||
mInner.as<ServoGroupRuleRules>().SetParentRule(this);
|
||||
}
|
||||
|
||||
GroupRule::GroupRule(const GroupRule& aCopy)
|
||||
: Rule(aCopy)
|
||||
, mInner(aCopy.mInner)
|
||||
{
|
||||
CALL_INNER(mInner, SetParentRule(this));
|
||||
}
|
||||
|
||||
GroupRule::~GroupRule()
|
||||
{
|
||||
MOZ_ASSERT(!mSheet, "SetStyleSheet should have been called");
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(GroupRule, Rule)
|
||||
NS_IMPL_RELEASE_INHERITED(GroupRule, Rule)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(GroupRule)
|
||||
NS_INTERFACE_MAP_END_INHERITING(Rule)
|
||||
|
||||
bool
|
||||
GroupRule::IsCCLeaf() const
|
||||
{
|
||||
// Let's not worry for now about sorting out whether we're a leaf or not.
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(GroupRule)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(GroupRule, Rule)
|
||||
CALL_INNER(tmp->mInner, SetParentRule(nullptr));
|
||||
// If tmp does not have a stylesheet, neither do its descendants. In that
|
||||
// case, don't try to null out their stylesheet, to avoid O(N^2) behavior in
|
||||
// depth of group rule nesting. But if tmp _does_ have a stylesheet (which
|
||||
// can happen if it gets unlinked earlier than its owning stylesheet), then we
|
||||
// need to null out the stylesheet pointer on descendants now, before we clear
|
||||
// tmp->mRules.
|
||||
if (tmp->GetStyleSheet()) {
|
||||
CALL_INNER(tmp->mInner, SetStyleSheet(nullptr));
|
||||
}
|
||||
CALL_INNER(tmp->mInner, Clear());
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(GroupRule, Rule)
|
||||
CALL_INNER(tmp->mInner, Traverse(cb));
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
/* virtual */ void
|
||||
GroupRule::SetStyleSheet(StyleSheet* aSheet)
|
||||
{
|
||||
// Don't set the sheet on the kids if it's already the same as the sheet we
|
||||
// already have. This is needed to avoid O(N^2) behavior in group nesting
|
||||
// depth when seting the sheet to null during unlink, if we happen to unlin in
|
||||
// order from most nested rule up to least nested rule.
|
||||
if (aSheet != GetStyleSheet()) {
|
||||
CALL_INNER(mInner, SetStyleSheet(aSheet));
|
||||
Rule::SetStyleSheet(aSheet);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GroupRule::AppendStyleRule(Rule* aRule)
|
||||
{
|
||||
GeckoRules().AppendObject(aRule);
|
||||
StyleSheet* sheet = GetStyleSheet();
|
||||
aRule->SetStyleSheet(sheet);
|
||||
aRule->SetParentRule(this);
|
||||
if (sheet) {
|
||||
sheet->AsGecko()->SetModifiedByChildRule();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
GroupRule::EnumerateRulesForwards(RuleEnumFunc aFunc, void * aData) const
|
||||
{
|
||||
for (const Rule* rule : GeckoRules()) {
|
||||
if (!aFunc(const_cast<Rule*>(rule), aData)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GroupRule::InsertStyleRuleAt(uint32_t aIndex, Rule* aRule)
|
||||
{
|
||||
aRule->SetStyleSheet(GetStyleSheet());
|
||||
aRule->SetParentRule(this);
|
||||
if (!GeckoRules().InsertObjectAt(aRule, aIndex)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GroupRule::AppendRulesToCssText(nsAString& aCssText) const
|
||||
{
|
||||
aCssText.AppendLiteral(" {\n");
|
||||
for (const Rule* rule : GeckoRules()) {
|
||||
nsAutoString cssText;
|
||||
rule->GetCssText(cssText);
|
||||
aCssText.AppendLiteral(" ");
|
||||
aCssText.Append(cssText);
|
||||
aCssText.Append('\n');
|
||||
}
|
||||
aCssText.Append('}');
|
||||
}
|
||||
|
||||
// nsIDOMCSSMediaRule or nsIDOMCSSMozDocumentRule methods
|
||||
nsresult
|
||||
GroupRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
|
||||
{
|
||||
NS_ADDREF(*aRuleList = CssRules());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
CSSRuleList*
|
||||
GroupRule::CssRules()
|
||||
{
|
||||
return CALL_INNER(mInner, CssRules(this));
|
||||
}
|
||||
|
||||
nsresult
|
||||
GroupRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
|
||||
{
|
||||
ErrorResult rv;
|
||||
*_retval = InsertRule(aRule, aIndex, rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GroupRule::InsertRule(const nsAString& aRule, uint32_t aIndex, ErrorResult& aRv)
|
||||
{
|
||||
StyleSheet* sheet = GetStyleSheet();
|
||||
if (NS_WARN_IF(!sheet)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t count = StyleRuleCount();
|
||||
if (aIndex > count) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NS_ASSERTION(count <= INT32_MAX, "Too many style rules!");
|
||||
|
||||
nsresult rv = sheet->InsertRuleIntoGroup(aRule, this, aIndex);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return 0;
|
||||
}
|
||||
return aIndex;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GroupRule::DeleteRule(uint32_t aIndex)
|
||||
{
|
||||
ErrorResult rv;
|
||||
DeleteRule(aIndex, rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
void
|
||||
GroupRule::DeleteRule(uint32_t aIndex, ErrorResult& aRv)
|
||||
{
|
||||
StyleSheet* sheet = GetStyleSheet();
|
||||
if (NS_WARN_IF(!sheet)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t count = StyleRuleCount();
|
||||
if (aIndex >= count) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ASSERTION(count <= INT32_MAX, "Too many style rules!");
|
||||
|
||||
nsresult rv = sheet->DeleteRuleFromGroup(this, aIndex);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
}
|
||||
}
|
||||
|
||||
#undef CALL_INNER
|
||||
|
||||
} // namespace css
|
||||
} // namespace mozilla
|
@ -15,6 +15,8 @@
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/IncrementalClearCOMRuleArray.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/ServoCSSRuleList.h"
|
||||
#include "mozilla/Variant.h"
|
||||
#include "mozilla/css/Rule.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
@ -31,14 +33,115 @@ class CSSRuleList;
|
||||
|
||||
namespace css {
|
||||
|
||||
class GroupRule;
|
||||
class GroupRuleRuleList;
|
||||
|
||||
struct GeckoGroupRuleRules
|
||||
{
|
||||
GeckoGroupRuleRules();
|
||||
GeckoGroupRuleRules(GeckoGroupRuleRules&& aOther);
|
||||
GeckoGroupRuleRules(const GeckoGroupRuleRules& aCopy);
|
||||
~GeckoGroupRuleRules();
|
||||
|
||||
void SetParentRule(GroupRule* aParentRule) {
|
||||
for (Rule* rule : mRules) {
|
||||
rule->SetParentRule(aParentRule);
|
||||
}
|
||||
}
|
||||
void SetStyleSheet(StyleSheet* aSheet) {
|
||||
for (Rule* rule : mRules) {
|
||||
rule->SetStyleSheet(aSheet);
|
||||
}
|
||||
}
|
||||
|
||||
void Clear();
|
||||
void Traverse(nsCycleCollectionTraversalCallback& cb);
|
||||
|
||||
#ifdef DEBUG
|
||||
void List(FILE* out, int32_t aIndent) const;
|
||||
#endif
|
||||
|
||||
int32_t StyleRuleCount() const { return mRules.Count(); }
|
||||
Rule* GetStyleRuleAt(int32_t aIndex) const {
|
||||
return mRules.SafeObjectAt(aIndex);
|
||||
}
|
||||
|
||||
nsresult DeleteStyleRuleAt(uint32_t aIndex);
|
||||
|
||||
dom::CSSRuleList* CssRules(GroupRule* aParentRule);
|
||||
|
||||
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
IncrementalClearCOMRuleArray mRules;
|
||||
RefPtr<GroupRuleRuleList> mRuleCollection; // lazily constructed
|
||||
};
|
||||
|
||||
struct ServoGroupRuleRules
|
||||
{
|
||||
explicit ServoGroupRuleRules(already_AddRefed<ServoCssRules> aRawRules)
|
||||
: mRuleList(new ServoCSSRuleList(Move(aRawRules))) {}
|
||||
ServoGroupRuleRules(ServoGroupRuleRules&& aOther)
|
||||
: mRuleList(Move(aOther.mRuleList)) {}
|
||||
ServoGroupRuleRules(const ServoGroupRuleRules& aCopy) {
|
||||
// Do we ever clone Servo rules?
|
||||
MOZ_ASSERT_UNREACHABLE("stylo: Cloning GroupRule not implemented");
|
||||
}
|
||||
|
||||
void SetParentRule(GroupRule* aParentRule) {
|
||||
if (mRuleList) {
|
||||
mRuleList->SetParentRule(aParentRule);
|
||||
}
|
||||
}
|
||||
void SetStyleSheet(StyleSheet* aSheet) {
|
||||
if (mRuleList) {
|
||||
mRuleList->SetStyleSheet(aSheet);
|
||||
}
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
mRuleList->DropReference();
|
||||
mRuleList = nullptr;
|
||||
}
|
||||
void Traverse(nsCycleCollectionTraversalCallback& cb) {
|
||||
ImplCycleCollectionTraverse(cb, mRuleList, "mRuleList");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void List(FILE* out, int32_t aIndent) const;
|
||||
#endif
|
||||
|
||||
int32_t StyleRuleCount() const { return mRuleList->Length(); }
|
||||
Rule* GetStyleRuleAt(int32_t aIndex) const {
|
||||
return mRuleList->GetRule(aIndex);
|
||||
}
|
||||
|
||||
nsresult DeleteStyleRuleAt(uint32_t aIndex) {
|
||||
return mRuleList->DeleteRule(aIndex);
|
||||
}
|
||||
|
||||
dom::CSSRuleList* CssRules(GroupRule* aParentRule) {
|
||||
return mRuleList;
|
||||
}
|
||||
|
||||
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
RefPtr<ServoCSSRuleList> mRuleList;
|
||||
};
|
||||
|
||||
#define REDIRECT_TO_INNER(call_) \
|
||||
if (mInner.is<GeckoGroupRuleRules>()) { \
|
||||
return mInner.as<GeckoGroupRuleRules>().call_; \
|
||||
} else { \
|
||||
return mInner.as<ServoGroupRuleRules>().call_; \
|
||||
} \
|
||||
|
||||
// inherits from Rule so it can be shared between
|
||||
// MediaRule and DocumentRule
|
||||
class GroupRule : public Rule
|
||||
{
|
||||
protected:
|
||||
GroupRule(uint32_t aLineNumber, uint32_t aColumnNumber);
|
||||
explicit GroupRule(already_AddRefed<ServoCssRules> aRules);
|
||||
GroupRule(const GroupRule& aCopy);
|
||||
virtual ~GroupRule();
|
||||
public:
|
||||
@ -48,32 +151,42 @@ public:
|
||||
virtual bool IsCCLeaf() const override;
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
|
||||
void List(FILE* out = stdout, int32_t aIndent = 0) const override {
|
||||
REDIRECT_TO_INNER(List(out, aIndent))
|
||||
}
|
||||
#endif
|
||||
virtual void SetStyleSheet(StyleSheet* aSheet) override;
|
||||
|
||||
public:
|
||||
void AppendStyleRule(Rule* aRule);
|
||||
|
||||
int32_t StyleRuleCount() const { return mRules.Count(); }
|
||||
Rule* GetStyleRuleAt(int32_t aIndex) const;
|
||||
int32_t StyleRuleCount() const {
|
||||
REDIRECT_TO_INNER(StyleRuleCount())
|
||||
}
|
||||
Rule* GetStyleRuleAt(uint32_t aIndex) const {
|
||||
REDIRECT_TO_INNER(GetStyleRuleAt(aIndex))
|
||||
}
|
||||
|
||||
typedef bool (*RuleEnumFunc)(Rule* aElement, void* aData);
|
||||
bool EnumerateRulesForwards(RuleEnumFunc aFunc, void * aData) const;
|
||||
|
||||
/*
|
||||
* The next three methods should never be called unless you have first
|
||||
* The next two methods should never be called unless you have first
|
||||
* called WillDirty() on the parent stylesheet. After they are
|
||||
* called, DidDirty() needs to be called on the sheet.
|
||||
*/
|
||||
nsresult DeleteStyleRuleAt(uint32_t aIndex);
|
||||
nsresult DeleteStyleRuleAt(uint32_t aIndex) {
|
||||
REDIRECT_TO_INNER(DeleteStyleRuleAt(aIndex));
|
||||
}
|
||||
nsresult InsertStyleRuleAt(uint32_t aIndex, Rule* aRule);
|
||||
|
||||
virtual bool UseForPresentation(nsPresContext* aPresContext,
|
||||
nsMediaQueryResultCacheKey& aKey) = 0;
|
||||
|
||||
// non-virtual -- it is only called by subclasses
|
||||
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
REDIRECT_TO_INNER(SizeOfExcludingThis(aMallocSizeOf))
|
||||
}
|
||||
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override = 0;
|
||||
|
||||
// WebIDL API
|
||||
@ -93,20 +206,27 @@ protected:
|
||||
uint32_t* _retval);
|
||||
nsresult DeleteRule(uint32_t aIndex);
|
||||
|
||||
IncrementalClearCOMRuleArray mRules;
|
||||
RefPtr<GroupRuleRuleList> mRuleCollection; // lazily constructed
|
||||
// Must only be called if this is a Gecko GroupRule.
|
||||
IncrementalClearCOMRuleArray& GeckoRules() {
|
||||
return mInner.as<GeckoGroupRuleRules>().mRules;
|
||||
}
|
||||
const IncrementalClearCOMRuleArray& GeckoRules() const {
|
||||
return mInner.as<GeckoGroupRuleRules>().mRules;
|
||||
}
|
||||
|
||||
private:
|
||||
Variant<GeckoGroupRuleRules, ServoGroupRuleRules> mInner;
|
||||
};
|
||||
|
||||
#undef REDIRECT_TO_INNER
|
||||
|
||||
// Implementation of WebIDL CSSConditionRule.
|
||||
class ConditionRule : public GroupRule
|
||||
{
|
||||
protected:
|
||||
ConditionRule(uint32_t aLineNumber, uint32_t aColumnNumber);
|
||||
ConditionRule(const ConditionRule& aCopy);
|
||||
virtual ~ConditionRule();
|
||||
using GroupRule::GroupRule;
|
||||
|
||||
public:
|
||||
|
||||
// GetConditionText signature matches nsIDOMCSSConditionRule, so subclasses
|
||||
// can implement this easily. The implementations should never return
|
||||
// anything other than NS_OK.
|
||||
|
@ -22,6 +22,10 @@ namespace mozilla {
|
||||
class CSSStyleSheet;
|
||||
class StyleSheet;
|
||||
|
||||
namespace dom {
|
||||
class MediaList;
|
||||
}
|
||||
|
||||
namespace css {
|
||||
|
||||
class ImportRule final : public Rule,
|
||||
@ -63,7 +67,7 @@ public:
|
||||
uint16_t Type() const override;
|
||||
void GetCssTextImpl(nsAString& aCssText) const override;
|
||||
// The XPCOM GetHref is fine, since it never fails.
|
||||
nsMediaList* Media() const { return mMedia; }
|
||||
dom::MediaList* Media() const;
|
||||
StyleSheet* GetStyleSheet() const;
|
||||
|
||||
private:
|
||||
|
117
layout/style/MediaList.cpp
Normal file
117
layout/style/MediaList.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* base class for representation of media lists */
|
||||
|
||||
#include "mozilla/dom/MediaList.h"
|
||||
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "mozilla/dom/MediaListBinding.h"
|
||||
#include "mozilla/StyleSheetInlines.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaList)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMediaList)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaList)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaList)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(MediaList)
|
||||
|
||||
JSObject*
|
||||
MediaList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return MediaListBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void
|
||||
MediaList::SetStyleSheet(StyleSheet* aSheet)
|
||||
{
|
||||
MOZ_ASSERT(aSheet == mStyleSheet || !aSheet || !mStyleSheet,
|
||||
"Multiple style sheets competing for one media list");
|
||||
mStyleSheet = aSheet;
|
||||
}
|
||||
|
||||
template<typename Func>
|
||||
nsresult
|
||||
MediaList::DoMediaChange(Func aCallback)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
if (mStyleSheet) {
|
||||
doc = mStyleSheet->GetAssociatedDocument();
|
||||
}
|
||||
mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
|
||||
if (mStyleSheet) {
|
||||
mStyleSheet->WillDirty();
|
||||
}
|
||||
|
||||
nsresult rv = aCallback();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (mStyleSheet) {
|
||||
mStyleSheet->DidDirty();
|
||||
}
|
||||
/* XXXldb Pass something meaningful? */
|
||||
if (doc) {
|
||||
doc->StyleRuleChanged(mStyleSheet, nullptr);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MediaList::GetMediaText(nsAString& aMediaText)
|
||||
{
|
||||
GetText(aMediaText);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MediaList::SetMediaText(const nsAString& aMediaText)
|
||||
{
|
||||
return DoMediaChange([&]() {
|
||||
SetText(aMediaText);
|
||||
return NS_OK;
|
||||
});
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MediaList::GetLength(uint32_t* aLength)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLength);
|
||||
|
||||
*aLength = Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MediaList::Item(uint32_t aIndex, nsAString& aReturn)
|
||||
{
|
||||
bool dummy;
|
||||
IndexedGetter(aIndex, dummy, aReturn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MediaList::DeleteMedium(const nsAString& aOldMedium)
|
||||
{
|
||||
return DoMediaChange([&]() { return Delete(aOldMedium); });
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MediaList::AppendMedium(const nsAString& aNewMedium)
|
||||
{
|
||||
return DoMediaChange([&]() { return Append(aNewMedium); });
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
84
layout/style/MediaList.h
Normal file
84
layout/style/MediaList.h
Normal file
@ -0,0 +1,84 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* base class for representation of media lists */
|
||||
|
||||
#ifndef mozilla_dom_MediaList_h
|
||||
#define mozilla_dom_MediaList_h
|
||||
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/ServoUtils.h"
|
||||
|
||||
#include "nsIDOMMediaList.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
namespace mozilla {
|
||||
class StyleSheet;
|
||||
|
||||
namespace dom {
|
||||
|
||||
// XXX This class doesn't use the branch dispatch approach that we use
|
||||
// elsewhere for stylo, but instead just relies on virtual call.
|
||||
// That's because this class should not be critical to performance,
|
||||
// and using branch dispatch would make it much more complicated.
|
||||
// Performance critical path should hold a subclass of this class
|
||||
// directly. We may want to determine in the future whether the
|
||||
// above is correct.
|
||||
|
||||
class MediaList : public nsIDOMMediaList
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaList)
|
||||
|
||||
virtual already_AddRefed<MediaList> Clone() = 0;
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
|
||||
nsISupports* GetParentObject() const { return nullptr; }
|
||||
|
||||
virtual void GetText(nsAString& aMediaText) = 0;
|
||||
virtual void SetText(const nsAString& aMediaText) = 0;
|
||||
|
||||
void SetStyleSheet(StyleSheet* aSheet);
|
||||
|
||||
NS_DECL_NSIDOMMEDIALIST
|
||||
|
||||
// WebIDL
|
||||
// XPCOM GetMediaText and SetMediaText are fine.
|
||||
virtual uint32_t Length() = 0;
|
||||
virtual void IndexedGetter(uint32_t aIndex, bool& aFound,
|
||||
nsAString& aReturn) = 0;
|
||||
// XPCOM Item is fine.
|
||||
void DeleteMedium(const nsAString& aMedium, ErrorResult& aRv)
|
||||
{
|
||||
aRv = DeleteMedium(aMedium);
|
||||
}
|
||||
void AppendMedium(const nsAString& aMedium, ErrorResult& aRv)
|
||||
{
|
||||
aRv = AppendMedium(aMedium);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual nsresult Delete(const nsAString& aOldMedium) = 0;
|
||||
virtual nsresult Append(const nsAString& aNewMedium) = 0;
|
||||
|
||||
virtual ~MediaList() {}
|
||||
|
||||
// not refcounted; sheet will let us know when it goes away
|
||||
// mStyleSheet is the sheet that needs to be dirtied when this
|
||||
// medialist changes
|
||||
StyleSheet* mStyleSheet = nullptr;
|
||||
|
||||
private:
|
||||
template<typename Func>
|
||||
inline nsresult DoMediaChange(Func aCallback);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_MediaList_h
|
@ -118,7 +118,7 @@ public:
|
||||
// WebIDL interface, aka helpers for nsIDOMCSSRule implementation.
|
||||
virtual uint16_t Type() const = 0;
|
||||
virtual void GetCssTextImpl(nsAString& aCssText) const = 0;
|
||||
// XPCOM GetCssText is OK, since it never throws.
|
||||
void GetCssText(nsAString& aCssText) const { GetCssTextImpl(aCssText); }
|
||||
// XPCOM SetCssText is OK, since it never throws.
|
||||
Rule* GetParentRule() const;
|
||||
StyleSheet* GetParentStyleSheet() const { return GetStyleSheet(); }
|
||||
|
@ -13,3 +13,5 @@ SERVO_ARC_TYPE(DeclarationBlock, RawServoDeclarationBlock)
|
||||
SERVO_ARC_TYPE(StyleRule, RawServoStyleRule)
|
||||
SERVO_ARC_TYPE(ImportRule, RawServoImportRule)
|
||||
SERVO_ARC_TYPE(AnimationValue, RawServoAnimationValue)
|
||||
SERVO_ARC_TYPE(MediaList, RawServoMediaList)
|
||||
SERVO_ARC_TYPE(MediaRule, RawServoMediaRule)
|
||||
|
@ -78,6 +78,8 @@ SERVO_BINDING_FUNC(Servo_CssRules_ListTypes, void,
|
||||
nsTArrayBorrowed_uintptr_t result)
|
||||
SERVO_BINDING_FUNC(Servo_CssRules_GetStyleRuleAt, RawServoStyleRuleStrong,
|
||||
ServoCssRulesBorrowed rules, uint32_t index)
|
||||
SERVO_BINDING_FUNC(Servo_CssRules_GetMediaRuleAt, RawServoMediaRuleStrong,
|
||||
ServoCssRulesBorrowed rules, uint32_t index)
|
||||
SERVO_BINDING_FUNC(Servo_CssRules_InsertRule, nsresult,
|
||||
ServoCssRulesBorrowed rules,
|
||||
RawServoStyleSheetBorrowed sheet, const nsACString* rule,
|
||||
@ -97,6 +99,14 @@ SERVO_BINDING_FUNC(Servo_StyleRule_GetCssText, void,
|
||||
RawServoStyleRuleBorrowed rule, nsAString* result)
|
||||
SERVO_BINDING_FUNC(Servo_StyleRule_GetSelectorText, void,
|
||||
RawServoStyleRuleBorrowed rule, nsAString* result)
|
||||
SERVO_BINDING_FUNC(Servo_MediaRule_Debug, void,
|
||||
RawServoMediaRuleBorrowed rule, nsACString* result)
|
||||
SERVO_BINDING_FUNC(Servo_MediaRule_GetMedia, RawServoMediaListStrong,
|
||||
RawServoMediaRuleBorrowed rule)
|
||||
SERVO_BINDING_FUNC(Servo_MediaRule_GetRules, ServoCssRulesStrong,
|
||||
RawServoMediaRuleBorrowed rule)
|
||||
SERVO_BINDING_FUNC(Servo_MediaRule_GetCssText, void,
|
||||
RawServoMediaRuleBorrowed rule, nsAString* result)
|
||||
|
||||
// Animations API
|
||||
SERVO_BINDING_FUNC(Servo_ParseProperty,
|
||||
@ -108,7 +118,7 @@ SERVO_BINDING_FUNC(Servo_GetComputedKeyframeValues, void,
|
||||
RawGeckoKeyframeListBorrowed keyframes,
|
||||
ServoComputedValuesBorrowed style,
|
||||
ServoComputedValuesBorrowedOrNull parent_style,
|
||||
RawGeckoPresContextBorrowed pres_context,
|
||||
RawServoStyleSetBorrowed set,
|
||||
RawGeckoComputedKeyframeValuesListBorrowedMut result)
|
||||
|
||||
// AnimationValues handling
|
||||
@ -135,7 +145,9 @@ SERVO_BINDING_FUNC(Servo_AnimationValue_DeepEqual, bool,
|
||||
|
||||
// Style attribute
|
||||
SERVO_BINDING_FUNC(Servo_ParseStyleAttribute, RawServoDeclarationBlockStrong,
|
||||
const nsACString* data)
|
||||
const nsACString* data,
|
||||
const nsACString* base,
|
||||
const GeckoParserExtraData* extraData)
|
||||
SERVO_BINDING_FUNC(Servo_DeclarationBlock_CreateEmpty,
|
||||
RawServoDeclarationBlockStrong)
|
||||
SERVO_BINDING_FUNC(Servo_DeclarationBlock_Clone, RawServoDeclarationBlockStrong,
|
||||
@ -222,6 +234,21 @@ SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetFontFamily, void,
|
||||
SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetTextDecorationColorOverride, void,
|
||||
RawServoDeclarationBlockBorrowed declarations)
|
||||
|
||||
// MediaList
|
||||
SERVO_BINDING_FUNC(Servo_MediaList_GetText, void,
|
||||
RawServoMediaListBorrowed list, nsAString* result)
|
||||
SERVO_BINDING_FUNC(Servo_MediaList_SetText, void,
|
||||
RawServoMediaListBorrowed list, const nsACString* text)
|
||||
SERVO_BINDING_FUNC(Servo_MediaList_GetLength, uint32_t,
|
||||
RawServoMediaListBorrowed list)
|
||||
SERVO_BINDING_FUNC(Servo_MediaList_GetMediumAt, bool,
|
||||
RawServoMediaListBorrowed list, uint32_t index,
|
||||
nsAString* result)
|
||||
SERVO_BINDING_FUNC(Servo_MediaList_AppendMedium, void,
|
||||
RawServoMediaListBorrowed list, const nsACString* new_medium)
|
||||
SERVO_BINDING_FUNC(Servo_MediaList_DeleteMedium, bool,
|
||||
RawServoMediaListBorrowed list, const nsACString* old_medium)
|
||||
|
||||
// CSS supports()
|
||||
SERVO_BINDING_FUNC(Servo_CSSSupports2, bool,
|
||||
const nsACString* name, const nsACString* value)
|
||||
|
@ -10,13 +10,12 @@
|
||||
|
||||
#include "mozilla/ServoBindings.h"
|
||||
#include "mozilla/ServoStyleRule.h"
|
||||
#include "mozilla/ServoMediaRule.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
ServoCSSRuleList::ServoCSSRuleList(ServoStyleSheet* aStyleSheet,
|
||||
already_AddRefed<ServoCssRules> aRawRules)
|
||||
: mStyleSheet(aStyleSheet)
|
||||
, mRawRules(aRawRules)
|
||||
ServoCSSRuleList::ServoCSSRuleList(already_AddRefed<ServoCssRules> aRawRules)
|
||||
: mRawRules(aRawRules)
|
||||
{
|
||||
Servo_CssRules_ListTypes(mRawRules, &mRules);
|
||||
// XXX We may want to eagerly create object for import rule, so that
|
||||
@ -34,14 +33,7 @@ NS_IMPL_RELEASE_INHERITED(ServoCSSRuleList, dom::CSSRuleList)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(ServoCSSRuleList)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ServoCSSRuleList)
|
||||
for (uintptr_t& rule : tmp->mRules) {
|
||||
if (rule > kMaxRuleType) {
|
||||
CastToPtr(rule)->Release();
|
||||
// Safest to set it to zero, in case someone else pokes at it
|
||||
// during their own unlinking process.
|
||||
rule = 0;
|
||||
}
|
||||
}
|
||||
tmp->DropAllRules();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(dom::CSSRuleList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoCSSRuleList,
|
||||
dom::CSSRuleList)
|
||||
@ -53,6 +45,24 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoCSSRuleList,
|
||||
});
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
void
|
||||
ServoCSSRuleList::SetParentRule(css::GroupRule* aParentRule)
|
||||
{
|
||||
mParentRule = aParentRule;
|
||||
EnumerateInstantiatedRules([aParentRule](css::Rule* rule) {
|
||||
rule->SetParentRule(aParentRule);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
ServoCSSRuleList::SetStyleSheet(StyleSheet* aStyleSheet)
|
||||
{
|
||||
mStyleSheet = aStyleSheet ? aStyleSheet->AsServo() : nullptr;
|
||||
EnumerateInstantiatedRules([aStyleSheet](css::Rule* rule) {
|
||||
rule->SetStyleSheet(aStyleSheet);
|
||||
});
|
||||
}
|
||||
|
||||
css::Rule*
|
||||
ServoCSSRuleList::GetRule(uint32_t aIndex)
|
||||
{
|
||||
@ -65,7 +75,11 @@ ServoCSSRuleList::GetRule(uint32_t aIndex)
|
||||
Servo_CssRules_GetStyleRuleAt(mRawRules, aIndex).Consume());
|
||||
break;
|
||||
}
|
||||
case nsIDOMCSSRule::MEDIA_RULE:
|
||||
case nsIDOMCSSRule::MEDIA_RULE: {
|
||||
ruleObj = new ServoMediaRule(
|
||||
Servo_CssRules_GetMediaRuleAt(mRawRules, aIndex).Consume());
|
||||
break;
|
||||
}
|
||||
case nsIDOMCSSRule::FONT_FACE_RULE:
|
||||
case nsIDOMCSSRule::KEYFRAMES_RULE:
|
||||
case nsIDOMCSSRule::NAMESPACE_RULE:
|
||||
@ -75,6 +89,7 @@ ServoCSSRuleList::GetRule(uint32_t aIndex)
|
||||
return nullptr;
|
||||
}
|
||||
ruleObj->SetStyleSheet(mStyleSheet);
|
||||
ruleObj->SetParentRule(mParentRule);
|
||||
rule = CastToUint(ruleObj.forget().take());
|
||||
mRules[aIndex] = rule;
|
||||
}
|
||||
@ -103,22 +118,36 @@ ServoCSSRuleList::EnumerateInstantiatedRules(Func aCallback)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DropRule(already_AddRefed<css::Rule> aRule)
|
||||
{
|
||||
RefPtr<css::Rule> rule = aRule;
|
||||
rule->SetStyleSheet(nullptr);
|
||||
rule->SetParentRule(nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
ServoCSSRuleList::DropAllRules()
|
||||
{
|
||||
EnumerateInstantiatedRules([](css::Rule* rule) {
|
||||
DropRule(already_AddRefed<css::Rule>(rule));
|
||||
});
|
||||
mRules.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
ServoCSSRuleList::DropReference()
|
||||
{
|
||||
mStyleSheet = nullptr;
|
||||
EnumerateInstantiatedRules([](css::Rule* rule) {
|
||||
rule->SetStyleSheet(nullptr);
|
||||
});
|
||||
mParentRule = nullptr;
|
||||
DropAllRules();
|
||||
}
|
||||
|
||||
nsresult
|
||||
ServoCSSRuleList::InsertRule(const nsAString& aRule, uint32_t aIndex)
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 rule(aRule);
|
||||
// XXX This needs to actually reflect whether it is nested when we
|
||||
// support using CSSRuleList in CSSGroupingRules.
|
||||
bool nested = false;
|
||||
bool nested = !!mParentRule;
|
||||
uint16_t type;
|
||||
nsresult rv = Servo_CssRules_InsertRule(mRawRules, mStyleSheet->RawSheet(),
|
||||
&rule, aIndex, nested, &type);
|
||||
@ -135,7 +164,7 @@ ServoCSSRuleList::DeleteRule(uint32_t aIndex)
|
||||
if (!NS_FAILED(rv)) {
|
||||
uintptr_t rule = mRules[aIndex];
|
||||
if (rule > kMaxRuleType) {
|
||||
CastToPtr(rule)->Release();
|
||||
DropRule(already_AddRefed<css::Rule>(CastToPtr(rule)));
|
||||
}
|
||||
mRules.RemoveElementAt(aIndex);
|
||||
}
|
||||
@ -144,7 +173,7 @@ ServoCSSRuleList::DeleteRule(uint32_t aIndex)
|
||||
|
||||
ServoCSSRuleList::~ServoCSSRuleList()
|
||||
{
|
||||
EnumerateInstantiatedRules([](css::Rule* rule) { rule->Release(); });
|
||||
DropAllRules();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -16,14 +16,17 @@ namespace mozilla {
|
||||
|
||||
class ServoStyleSheet;
|
||||
namespace css {
|
||||
class GroupRule;
|
||||
class Rule;
|
||||
} // namespace css
|
||||
|
||||
class ServoCSSRuleList final : public dom::CSSRuleList
|
||||
{
|
||||
public:
|
||||
ServoCSSRuleList(ServoStyleSheet* aStyleSheet,
|
||||
already_AddRefed<ServoCssRules> aRawRules);
|
||||
explicit ServoCSSRuleList(already_AddRefed<ServoCssRules> aRawRules);
|
||||
css::GroupRule* GetParentRule() const { return mParentRule; }
|
||||
void SetParentRule(css::GroupRule* aParentRule);
|
||||
void SetStyleSheet(StyleSheet* aSheet);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServoCSSRuleList, dom::CSSRuleList)
|
||||
@ -57,8 +60,12 @@ private:
|
||||
template<typename Func>
|
||||
void EnumerateInstantiatedRules(Func aCallback);
|
||||
|
||||
void DropAllRules();
|
||||
|
||||
// mStyleSheet may be nullptr when it drops the reference to us.
|
||||
ServoStyleSheet* mStyleSheet;
|
||||
ServoStyleSheet* mStyleSheet = nullptr;
|
||||
// mParentRule is nullptr if it isn't a nested rule list.
|
||||
css::GroupRule* mParentRule = nullptr;
|
||||
RefPtr<ServoCssRules> mRawRules;
|
||||
// Array stores either a number indicating rule type, or a pointer to
|
||||
// css::Rule. If the value is less than kMaxRuleType, the given rule
|
||||
|
@ -12,11 +12,15 @@
|
||||
namespace mozilla {
|
||||
|
||||
/* static */ already_AddRefed<ServoDeclarationBlock>
|
||||
ServoDeclarationBlock::FromCssText(const nsAString& aCssText)
|
||||
ServoDeclarationBlock::FromCssText(const nsAString& aCssText,
|
||||
const GeckoParserExtraData& aExtraData)
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 value(aCssText);
|
||||
nsCString baseString;
|
||||
// FIXME (bug 1343964): Figure out a better solution for sending the base uri to servo
|
||||
aExtraData.mBaseURI->get()->GetSpec(baseString);
|
||||
RefPtr<RawServoDeclarationBlock>
|
||||
raw = Servo_ParseStyleAttribute(&value).Consume();
|
||||
raw = Servo_ParseStyleAttribute(&value, &baseString, &aExtraData).Consume();
|
||||
RefPtr<ServoDeclarationBlock> decl = new ServoDeclarationBlock(raw.forget());
|
||||
return decl.forget();
|
||||
}
|
||||
|
@ -28,7 +28,8 @@ public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ServoDeclarationBlock)
|
||||
|
||||
static already_AddRefed<ServoDeclarationBlock>
|
||||
FromCssText(const nsAString& aCssText);
|
||||
FromCssText(const nsAString& aCssText,
|
||||
const GeckoParserExtraData& aExtraData);
|
||||
|
||||
RawServoDeclarationBlock* Raw() const { return mRaw; }
|
||||
RawServoDeclarationBlock* const* RefRaw() const {
|
||||
|
71
layout/style/ServoMediaList.cpp
Normal file
71
layout/style/ServoMediaList.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* representation of media lists for servo backend */
|
||||
|
||||
#include "mozilla/ServoMediaList.h"
|
||||
|
||||
#include "mozilla/ServoBindings.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
already_AddRefed<dom::MediaList>
|
||||
ServoMediaList::Clone()
|
||||
{
|
||||
// Currently MediaList::Clone() is only called from CSSStyleSheet's
|
||||
// constructor, so we don't need to support it at the moment.
|
||||
MOZ_ASSERT_UNREACHABLE("stylo: ServoMediaList doesn't support clone");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
ServoMediaList::GetText(nsAString& aMediaText)
|
||||
{
|
||||
Servo_MediaList_GetText(mRawList, &aMediaText);
|
||||
}
|
||||
|
||||
void
|
||||
ServoMediaList::SetText(const nsAString& aMediaText)
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 mediaText(aMediaText);
|
||||
Servo_MediaList_SetText(mRawList, &mediaText);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ServoMediaList::Length()
|
||||
{
|
||||
return Servo_MediaList_GetLength(mRawList);
|
||||
}
|
||||
|
||||
void
|
||||
ServoMediaList::IndexedGetter(uint32_t aIndex, bool& aFound,
|
||||
nsAString& aReturn)
|
||||
{
|
||||
aFound = Servo_MediaList_GetMediumAt(mRawList, aIndex, &aReturn);
|
||||
}
|
||||
|
||||
nsresult
|
||||
ServoMediaList::Append(const nsAString& aNewMedium)
|
||||
{
|
||||
if (aNewMedium.IsEmpty()) {
|
||||
return NS_ERROR_DOM_NOT_FOUND_ERR;
|
||||
}
|
||||
NS_ConvertUTF16toUTF8 newMedium(aNewMedium);
|
||||
Servo_MediaList_AppendMedium(mRawList, &newMedium);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
ServoMediaList::Delete(const nsAString& aOldMedium)
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 oldMedium(aOldMedium);
|
||||
if (Servo_MediaList_DeleteMedium(mRawList, &oldMedium)) {
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_DOM_NOT_FOUND_ERR;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
44
layout/style/ServoMediaList.h
Normal file
44
layout/style/ServoMediaList.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* representation of media lists for servo backend */
|
||||
|
||||
#ifndef mozilla_ServoMediaList_h
|
||||
#define mozilla_ServoMediaList_h
|
||||
|
||||
#include "mozilla/dom/MediaList.h"
|
||||
#include "mozilla/ServoBindingTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ServoMediaList final : public dom::MediaList
|
||||
{
|
||||
public:
|
||||
explicit ServoMediaList(already_AddRefed<RawServoMediaList> aRawList)
|
||||
: mRawList(aRawList) {}
|
||||
|
||||
already_AddRefed<dom::MediaList> Clone() final;
|
||||
|
||||
void GetText(nsAString& aMediaText) final;
|
||||
void SetText(const nsAString& aMediaText) final;
|
||||
|
||||
uint32_t Length() final;
|
||||
void IndexedGetter(uint32_t aIndex, bool& aFound,
|
||||
nsAString& aReturn) final;
|
||||
|
||||
protected:
|
||||
nsresult Delete(const nsAString& aOldMedium) final;
|
||||
nsresult Append(const nsAString& aNewMedium) final;
|
||||
|
||||
~ServoMediaList() {}
|
||||
|
||||
private:
|
||||
RefPtr<RawServoMediaList> mRawList;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_ServoMediaList_h
|
117
layout/style/ServoMediaRule.cpp
Normal file
117
layout/style/ServoMediaRule.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* representation of CSSMediaRule for stylo */
|
||||
|
||||
#include "mozilla/ServoMediaRule.h"
|
||||
|
||||
#include "mozilla/ServoBindings.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
ServoMediaRule::ServoMediaRule(RefPtr<RawServoMediaRule> aRawRule)
|
||||
: CSSMediaRule(Servo_MediaRule_GetRules(aRawRule).Consume())
|
||||
, mRawRule(Move(aRawRule))
|
||||
{
|
||||
}
|
||||
|
||||
ServoMediaRule::~ServoMediaRule()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(ServoMediaRule, CSSMediaRule)
|
||||
NS_IMPL_RELEASE_INHERITED(ServoMediaRule, CSSMediaRule)
|
||||
|
||||
// QueryInterface implementation for MediaRule
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServoMediaRule)
|
||||
NS_INTERFACE_MAP_END_INHERITING(CSSMediaRule)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServoMediaRule, CSSMediaRule,
|
||||
mMediaList)
|
||||
|
||||
/* virtual */ already_AddRefed<css::Rule>
|
||||
ServoMediaRule::Clone() const
|
||||
{
|
||||
// Rule::Clone is only used when CSSStyleSheetInner is cloned in
|
||||
// preparation of being mutated. However, ServoStyleSheet never clones
|
||||
// anything, so this method should never be called.
|
||||
MOZ_ASSERT_UNREACHABLE("Shouldn't be cloning ServoMediaRule");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* virtual */ bool
|
||||
ServoMediaRule::UseForPresentation(nsPresContext* aPresContext,
|
||||
nsMediaQueryResultCacheKey& aKey)
|
||||
{
|
||||
// GroupRule::UseForPresentation is only used in nsCSSRuleProcessor,
|
||||
// so this should never be called.
|
||||
MOZ_ASSERT_UNREACHABLE("Shouldn't be calling UseForPresentation");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
ServoMediaRule::SetStyleSheet(StyleSheet* aSheet)
|
||||
{
|
||||
if (mMediaList) {
|
||||
mMediaList->SetStyleSheet(aSheet);
|
||||
}
|
||||
CSSMediaRule::SetStyleSheet(aSheet);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* virtual */ void
|
||||
ServoMediaRule::List(FILE* out, int32_t aIndent) const
|
||||
{
|
||||
nsAutoCString str;
|
||||
for (int32_t i = 0; i < aIndent; i++) {
|
||||
str.AppendLiteral(" ");
|
||||
}
|
||||
Servo_MediaRule_Debug(mRawRule, &str);
|
||||
fprintf_stderr(out, "%s\n", str.get());
|
||||
}
|
||||
#endif
|
||||
|
||||
// nsIDOMCSSConditionRule methods
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServoMediaRule::GetConditionText(nsAString& aConditionText)
|
||||
{
|
||||
return Media()->GetMediaText(aConditionText);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServoMediaRule::SetConditionText(const nsAString& aConditionText)
|
||||
{
|
||||
return Media()->SetMediaText(aConditionText);
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
ServoMediaRule::GetCssTextImpl(nsAString& aCssText) const
|
||||
{
|
||||
Servo_MediaRule_GetCssText(mRawRule, &aCssText);
|
||||
}
|
||||
|
||||
/* virtual */ dom::MediaList*
|
||||
ServoMediaRule::Media()
|
||||
{
|
||||
if (!mMediaList) {
|
||||
mMediaList =
|
||||
new ServoMediaList(Servo_MediaRule_GetMedia(mRawRule).Consume());
|
||||
mMediaList->SetStyleSheet(GetStyleSheet());
|
||||
}
|
||||
return mMediaList;
|
||||
}
|
||||
|
||||
/* virtual */ size_t
|
||||
ServoMediaRule::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
// TODO Implement this!
|
||||
return aMallocSizeOf(this);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
57
layout/style/ServoMediaRule.h
Normal file
57
layout/style/ServoMediaRule.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* representation of CSSMediaRule for stylo */
|
||||
|
||||
#ifndef mozilla_ServoMediaRule_h
|
||||
#define mozilla_ServoMediaRule_h
|
||||
|
||||
#include "mozilla/dom/CSSMediaRule.h"
|
||||
#include "mozilla/ServoBindingTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ServoMediaList;
|
||||
|
||||
class ServoMediaRule final : public dom::CSSMediaRule
|
||||
{
|
||||
public:
|
||||
explicit ServoMediaRule(RefPtr<RawServoMediaRule> aRawRule);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServoMediaRule, dom::CSSMediaRule)
|
||||
|
||||
already_AddRefed<css::Rule> Clone() const override;
|
||||
bool UseForPresentation(nsPresContext* aPresContext,
|
||||
nsMediaQueryResultCacheKey& aKey) final;
|
||||
void SetStyleSheet(StyleSheet* aSheet) override;
|
||||
#ifdef DEBUG
|
||||
void List(FILE* out = stdout, int32_t aIndent = 0) const final;
|
||||
#endif
|
||||
|
||||
RawServoMediaRule* Raw() const { return mRawRule; }
|
||||
|
||||
// nsIDOMCSSConditionRule interface
|
||||
NS_DECL_NSIDOMCSSCONDITIONRULE
|
||||
|
||||
// WebIDL interface
|
||||
void GetCssTextImpl(nsAString& aCssText) const override;
|
||||
using CSSMediaRule::SetConditionText;
|
||||
dom::MediaList* Media() override;
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
|
||||
const override;
|
||||
|
||||
private:
|
||||
virtual ~ServoMediaRule();
|
||||
|
||||
RefPtr<RawServoMediaRule> mRawRule;
|
||||
RefPtr<ServoMediaList> mMediaList;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_ServoMediaRule_h
|
@ -11,6 +11,7 @@
|
||||
#include "mozilla/dom/ChildIterator.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ElementInlines.h"
|
||||
#include "mozilla/dom/KeyframeEffectReadOnly.h"
|
||||
#include "nsCSSAnonBoxes.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "nsHTMLStyleSheet.h"
|
||||
@ -710,6 +711,24 @@ ServoStyleSet::FillKeyframesForName(const nsString& aName,
|
||||
&aKeyframes);
|
||||
}
|
||||
|
||||
nsTArray<ComputedKeyframeValues>
|
||||
ServoStyleSet::GetComputedKeyframeValuesFor(const nsTArray<Keyframe>& aKeyframes,
|
||||
dom::Element* aElement,
|
||||
const ServoComputedStyleValues& aServoValues)
|
||||
{
|
||||
nsTArray<ComputedKeyframeValues> result(aKeyframes.Length());
|
||||
|
||||
// Construct each nsTArray<PropertyStyleAnimationValuePair> here.
|
||||
result.AppendElements(aKeyframes.Length());
|
||||
|
||||
Servo_GetComputedKeyframeValues(&aKeyframes,
|
||||
aServoValues.mCurrentStyle,
|
||||
aServoValues.mParentStyle,
|
||||
mRawSet.get(),
|
||||
&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
ServoStyleSet::RebuildData()
|
||||
{
|
||||
@ -728,7 +747,7 @@ ServoStyleSet::ClearNonInheritingStyleContexts()
|
||||
{
|
||||
for (RefPtr<nsStyleContext>& ptr : mNonInheritingStyleContexts) {
|
||||
ptr = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<ServoComputedValues>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user