Merge mozilla-central to inbound. CLOSED TREE

This commit is contained in:
Narcis Beleuzu 2018-11-28 12:02:34 +02:00
commit fbd301ecde
88 changed files with 2131 additions and 9730 deletions

View File

@ -102,7 +102,7 @@ LogDocShellState(nsIDocument* aDocumentNode)
nsAutoCString docShellBusy;
nsCOMPtr<nsIDocShell> docShell = aDocumentNode->GetDocShell();
uint32_t busyFlags = nsIDocShell::BUSY_FLAGS_NONE;
nsIDocShell::BusyFlags busyFlags = nsIDocShell::BUSY_FLAGS_NONE;
docShell->GetBusyFlags(&busyFlags);
if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE) {
printf("'none'");

View File

@ -1707,6 +1707,8 @@ pref("extensions.formautofill.creditCards.enabled", true);
pref("extensions.formautofill.creditCards.used", 0);
pref("extensions.formautofill.firstTimeUse", true);
pref("extensions.formautofill.heuristics.enabled", true);
// Whether the user enabled the OS re-auth dialog.
pref("extensions.formautofill.reauth.enabled", false);
pref("extensions.formautofill.section.enabled", true);
pref("extensions.formautofill.loglevel", "Warn");

View File

@ -375,20 +375,6 @@ async function gLazyFindCommand(cmd, ...args) {
}
}
Object.defineProperty(this, "AddonManager", {
configurable: true,
enumerable: true,
get() {
let tmp = {};
ChromeUtils.import("resource://gre/modules/AddonManager.jsm", tmp);
return this.AddonManager = tmp.AddonManager;
},
set(val) {
delete this.AddonManager;
return this.AddonManager = val;
},
});
var gInitialPages = [
"about:blank",

View File

@ -4,6 +4,7 @@ prefs =
browser.pagethumbnails.capturing_disabled=true
dom.payments.request.enabled=true
extensions.formautofill.creditCards.available=true
extensions.formautofill.reauth.enabled=true
skip-if = !e10s # Bug 1365964 - Payment Request isn't implemented for non-e10s
support-files =
blank_page.html

View File

@ -109,7 +109,7 @@ var OSKeyStore = {
let unlockPromise;
// Decides who should handle reauth
if (typeof reauth == "boolean" && !reauth) {
if (!this._reauthEnabledByUser || (typeof reauth == "boolean" && !reauth)) {
unlockPromise = Promise.resolve();
} else if (!AppConstants.MOZILLA_OFFICIAL && this._testReauth) {
unlockPromise = this._reauthInTests();
@ -252,3 +252,5 @@ XPCOMUtils.defineLazyGetter(this, "log", () => {
});
XPCOMUtils.defineLazyPreferenceGetter(OSKeyStore, "_testReauth", TEST_ONLY_REAUTH, "");
XPCOMUtils.defineLazyPreferenceGetter(OSKeyStore, "_reauthEnabledByUser",
"extensions.formautofill.reauth.enabled", false);

View File

@ -2,6 +2,7 @@
head = head.js
prefs =
extensions.formautofill.creditCards.available=true
extensions.formautofill.reauth.enabled=true
support-files =
../fixtures/autocomplete_basic.html
../fixtures/autocomplete_simple_basic.html

View File

@ -1,6 +1,7 @@
[DEFAULT]
prefs =
extensions.formautofill.creditCards.available=true
extensions.formautofill.reauth.enabled=true
support-files =
../../../../../toolkit/components/satchel/test/satchel_common.js
../../../../../toolkit/components/satchel/test/parent_utils.js

View File

@ -6,6 +6,8 @@
let OSKeyStore;
add_task(async function setup() {
Services.prefs.setBoolPref("extensions.formautofill.reauth.enabled", true);
({OSKeyStore} = ChromeUtils.import("resource://formautofill/OSKeyStore.jsm", {}));
});
@ -59,6 +61,11 @@ add_task(async function test_reauth() {
await new Promise(resolve => TestUtils.executeSoon(resolve));
Assert.equal(await OSKeyStore.ensureLoggedIn(true), true, "Reauth logged in.");
await reauthObserved;
Services.prefs.setBoolPref("extensions.formautofill.reauth.enabled", false);
Assert.equal(await OSKeyStore.ensureLoggedIn(true), true,
"Reauth disabled so logged in without prompt");
Services.prefs.setBoolPref("extensions.formautofill.reauth.enabled", true);
});
add_task(async function test_decryption_failure() {

View File

@ -1,9 +1,9 @@
This is the debugger.html project output.
See https://github.com/devtools-html/debugger.html
Version 104
Version 103
Comparison: https://github.com/devtools-html/debugger.html/compare/release-103...release-104
Comparison: https://github.com/devtools-html/debugger.html/compare/release-102...release-103
Packages:
- babel-plugin-transform-es2015-modules-commonjs @6.26.2

View File

@ -2286,6 +2286,16 @@ menuseparator {
background: var(--theme-body-color);
}
.source-footer .commands .coverage {
color: var(--theme-body-color);
}
.coverage-on .source-footer .commands .coverage {
color: var(--theme-highlight-blue);
border: 1px solid var(--theme-body-color-inactive);
border-radius: 2px;
}
.source-footer > .commands > .blackboxed > img.blackBox {
background: var(--theme-highlight-blue);
}
@ -2862,6 +2872,11 @@ html[dir="rtl"] .editor-mount {
background: var(--theme-selection-background-hover);
}
.coverage-on .CodeMirror-code :not(.hit-marker) .CodeMirror-line,
.coverage-on .CodeMirror-code :not(.hit-marker) .CodeMirror-gutter-wrapper {
opacity: 0.5;
}
.editor.new-breakpoint svg {
fill: var(--theme-selection-background);
width: 60px;

View File

@ -15,10 +15,7 @@ import {
import { mapFrames, fetchExtra } from "./pause";
import { updateTab } from "./tabs";
import { PROMISE } from "./utils/middleware/promise";
import { setInScopeLines } from "./ast/setInScopeLines";
import { updateSymbolLocations } from "./utils/symbols";
import {
getSymbols,
findOutOfScopeLocations,
@ -27,6 +24,7 @@ import {
type AstPosition
} from "../workers/parser";
import { PROMISE } from "./utils/middleware/promise";
import { features } from "../utils/prefs";
import { isLoaded, isGenerated } from "../utils/source";
@ -58,7 +56,7 @@ export function setSourceMetaData(sourceId: SourceId) {
}
export function setSymbols(sourceId: SourceId) {
return async ({ dispatch, getState, sourceMaps }: ThunkArgs) => {
return async ({ dispatch, getState }: ThunkArgs) => {
const source = getSourceFromId(getState(), sourceId);
if (source.isWasm || hasSymbols(getState(), source) || !isLoaded(source)) {
@ -68,15 +66,7 @@ export function setSymbols(sourceId: SourceId) {
await dispatch({
type: "SET_SYMBOLS",
sourceId,
[PROMISE]: (async function() {
const symbols = await getSymbols(sourceId);
const mappedSymbols = updateSymbolLocations(
symbols,
source,
sourceMaps
);
return mappedSymbols;
})()
[PROMISE]: getSymbols(sourceId)
});
if (isPaused(getState())) {

View File

@ -45,7 +45,7 @@ async function addBreakpointPromise(getState, client, sourceMaps, breakpoint) {
return { breakpoint: newBreakpoint };
}
const { id, actualLocation } = await client.setBreakpoint(
const { id, hitCount, actualLocation } = await client.setBreakpoint(
generatedLocation,
breakpoint.condition,
isOriginalId(location.sourceId)
@ -70,6 +70,7 @@ async function addBreakpointPromise(getState, client, sourceMaps, breakpoint) {
condition: breakpoint.condition,
location: newLocation,
astLocation,
hitCount,
generatedLocation: newGeneratedLocation,
text,
originalText

View File

@ -12,6 +12,7 @@ import * as navigation from "./navigation";
import * as ui from "./ui";
import * as fileSearch from "./file-search";
import * as ast from "./ast";
import * as coverage from "./coverage";
import * as projectTextSearch from "./project-text-search";
import * as quickOpen from "./quick-open";
import * as sourceTree from "./source-tree";
@ -32,6 +33,7 @@ export default {
...ui,
...fileSearch,
...ast,
...coverage,
...projectTextSearch,
...quickOpen,
...sourceTree,

View File

@ -13,6 +13,7 @@ DIRS += [
DebuggerModules(
'ast.js',
'coverage.js',
'debuggee.js',
'event-listeners.js',
'expressions.js',

View File

@ -9,5 +9,4 @@ DIRS += [
DebuggerModules(
'create-store.js',
'symbols.js',
)

View File

@ -1,50 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
// @flow
import {
type SymbolDeclaration,
type SymbolDeclarations
} from "../../workers/parser";
import type { Source } from "../../types";
function updateSymbolLocation(
site: SymbolDeclaration,
source: Source,
sourceMaps: any
) {
return sourceMaps
.getGeneratedLocation(
{ ...site.location.start, sourceId: source.id },
source
)
.then(loc => {
return {
...site,
generatedLocation: { line: loc.line, column: loc.column }
};
});
}
export async function updateSymbolLocations(
symbols: SymbolDeclarations,
source: Source,
sourceMaps: any
): Promise<SymbolDeclarations> {
if (!symbols || !symbols.callExpressions) {
return Promise.resolve(symbols);
}
const mappedCallExpressions = await Promise.all(
symbols.callExpressions.map(site =>
updateSymbolLocation(site, source, sourceMaps)
)
);
const newSymbols = { ...symbols, callExpressions: mappedCallExpressions };
return Promise.resolve(newSymbols);
}

View File

@ -242,15 +242,6 @@ class App extends Component<Props, State> {
}));
}
// Important so that the tabs chevron updates appropriately when
// the user resizes the left or right columns
triggerEditorPaneResize() {
const editorPane = window.document.querySelector(".editor-pane");
if (editorPane) {
editorPane.dispatchEvent(new Event("resizeend"));
}
}
renderLayout = () => {
const { startPanelCollapsed, endPanelCollapsed } = this.props;
const horizontal = this.isHorizontal();
@ -291,7 +282,6 @@ class App extends Component<Props, State> {
/>
}
endPanelCollapsed={endPanelCollapsed}
onResizeEnd={this.triggerEditorPaneResize}
/>
);
};

View File

@ -5,7 +5,7 @@
import React, { Component } from "react";
import { connect } from "react-redux";
import { range, keyBy, isEqualWith, uniqBy, groupBy, flatten } from "lodash";
import { range, keyBy, isEqualWith } from "lodash";
import CallSite from "./CallSite";
@ -121,43 +121,23 @@ class CallSites extends Component {
filterCallSitesByLineNumber() {
const { callSites, breakpoints } = this.props;
// Get unique lines from breakpoints so we can filter out unwated call sites
const uniqueBreakpointLines = new Set(
breakpoints.map(bp => bp.location.line)
);
const breakpointLines = new Set(breakpoints.map(bp => bp.location.line));
// Get call sites based on activated breakpoint lines
const callSitesInRange = callSites.filter(({ location }) =>
uniqueBreakpointLines.has(location.start.line)
);
// Group call sites by line
const callSitesByLineObj = groupBy(callSitesInRange, "location.start.line");
// Per group, ensure all call sites are unique
return flatten(
Object.values(callSitesByLineObj).map(arr => {
const uniques = uniqBy(
arr,
site =>
`${site.generatedLocation.line}:${site.generatedLocation.column}`
);
// Only return call sites for a line when more than 1 is found
return uniques.length > 1 ? uniques : [];
})
return callSites.filter(({ location }) =>
breakpointLines.has(location.start.line)
);
}
render() {
const { editor, callSites, selectedSource, breakpoints } = this.props;
const { editor, callSites, selectedSource } = this.props;
if (!callSites || breakpoints.length === 0) {
let sites;
if (!callSites || (selectedSource && selectedSource.isPrettyPrinted)) {
return null;
}
const callSitesFiltered = this.filterCallSitesByLineNumber();
let sites;
editor.codeMirror.operation(() => {
const childCallSites = callSitesFiltered.map((callSite, index) => {
const props = {

View File

@ -14,6 +14,7 @@ import {
getPaneCollapse
} from "../../selectors";
import { features } from "../../utils/prefs";
import {
isPretty,
isLoaded,
@ -38,6 +39,7 @@ type Props = {
togglePrettyPrint: string => void,
toggleBlackBox: Object => void,
jumpToMappedLocation: (Source: any) => void,
recordCoverage: () => void,
togglePaneCollapse: () => void
};
@ -120,6 +122,25 @@ class SourceFooter extends PureComponent<Props> {
);
}
coverageButton() {
const { recordCoverage } = this.props;
if (!features.codeCoverage) {
return;
}
return (
<button
className="coverage action"
title={L10N.getStr("sourceFooter.codeCoverage")}
onClick={() => recordCoverage()}
aria-label={L10N.getStr("sourceFooter.codeCoverage")}
>
C
</button>
);
}
renderToggleButton() {
if (this.props.horizontal) {
return;
@ -141,6 +162,7 @@ class SourceFooter extends PureComponent<Props> {
{this.prettyPrintButton()}
{this.blackBoxButton()}
{this.blackBoxSummary()}
{this.coverageButton()}
</div>
);
}
@ -209,6 +231,7 @@ export default connect(
togglePrettyPrint: actions.togglePrettyPrint,
toggleBlackBox: actions.toggleBlackBox,
jumpToMappedLocation: actions.jumpToMappedLocation,
recordCoverage: actions.recordCoverage,
togglePaneCollapse: actions.togglePaneCollapse
}
)(SourceFooter);

View File

@ -76,12 +76,10 @@ class Tabs extends PureComponent<Props, State> {
componentDidMount() {
window.requestIdleCallback(this.updateHiddenTabs);
window.addEventListener("resize", this.onResize);
window.document.querySelector(".editor-pane").addEventListener("resizeend", this.onResize);
}
componentWillUnmount() {
window.removeEventListener("resize", this.onResize);
window.document.querySelector(".editor-pane").removeEventListener("resizeend", this.onResize);
}
/*

View File

@ -18,6 +18,8 @@ import {
getActiveSearch,
getSelectedLocation,
getSelectedSource,
getHitCountForSource,
getCoverageEnabled,
getConditionalPanelLine,
getSymbols
} from "../../selectors";
@ -30,6 +32,7 @@ import SearchBar from "./SearchBar";
import HighlightLines from "./HighlightLines";
import Preview from "./Preview";
import Breakpoints from "./Breakpoints";
import HitMarker from "./HitMarker";
import CallSites from "./CallSites";
import DebugLine from "./DebugLine";
import HighlightLine from "./HighlightLine";
@ -73,9 +76,11 @@ const cssVars = {
};
export type Props = {
hitCount: Object,
selectedLocation: ?Location,
selectedSource: ?Source,
searchOn: boolean,
coverageOn: boolean,
horizontal: boolean,
startPanelSize: number,
endPanelSize: number,
@ -528,6 +533,29 @@ class Editor extends PureComponent<Props, State> {
};
}
renderHitCounts() {
const { hitCount, selectedSource } = this.props;
if (
!selectedSource ||
!isLoaded(selectedSource) ||
!hitCount ||
!this.state.editor
) {
return;
}
return hitCount
.filter(marker => marker.get("count") > 0)
.map(marker => (
<HitMarker
key={marker.get("line")}
hitData={marker.toJS()}
editor={this.state.editor.codeMirror}
/>
));
}
renderItems() {
const { horizontal, selectedSource } = this.props;
const { editor } = this.state;
@ -549,6 +577,7 @@ class Editor extends PureComponent<Props, State> {
<GutterMenu editor={editor} />
<ConditionalPanel editor={editor} />
{features.columnBreakpoints ? <CallSites editor={editor} /> : null}
{this.renderHitCounts()}
</div>
);
}
@ -564,9 +593,13 @@ class Editor extends PureComponent<Props, State> {
}
render() {
const { coverageOn } = this.props;
return (
<div
className={classnames("editor-wrapper")}
className={classnames("editor-wrapper", {
"coverage-on": coverageOn
})}
ref={c => (this.$editorWrapper = c)}
>
<div
@ -586,11 +619,14 @@ Editor.contextTypes = {
const mapStateToProps = state => {
const selectedSource = getSelectedSource(state);
const sourceId = selectedSource ? selectedSource.id : "";
return {
selectedLocation: getSelectedLocation(state),
selectedSource,
searchOn: getActiveSearch(state) === "file",
hitCount: getHitCountForSource(state, sourceId),
coverageOn: getCoverageEnabled(state),
conditionalPanelLine: getConditionalPanelLine(state),
symbols: getSymbols(state, selectedSource)
};

View File

@ -20,6 +20,7 @@ DebuggerModules(
'GutterMenu.js',
'HighlightLine.js',
'HighlightLines.js',
'HitMarker.js',
'index.js',
'SearchBar.js',
'Tab.js',

View File

@ -35,10 +35,6 @@ export default class OutlineFilter extends Component<Props, State> {
// also bound to the ESC key
e.preventDefault();
this.props.updateFilter("");
} else if (e.key === "Enter") {
// We must prevent the form submission from taking any action
// https://github.com/devtools-html/debugger.html/pull/7308
e.preventDefault();
}
};

View File

@ -49,7 +49,6 @@ type Props = {
removeBreakpoints: typeof actions.removeBreakpoints,
removeAllBreakpoints: typeof actions.removeAllBreakpoints,
disableBreakpoint: typeof actions.disableBreakpoint,
setBreakpointCondition: typeof actions.setBreakpointCondition,
toggleAllBreakpoints: typeof actions.toggleAllBreakpoints,
toggleBreakpoints: typeof actions.toggleBreakpoints,
openConditionalPanel: typeof actions.openConditionalPanel,
@ -202,7 +201,6 @@ export default connect(
disableBreakpoint: actions.disableBreakpoint,
selectSpecificLocation: actions.selectSpecificLocation,
selectLocation: actions.selectLocation,
setBreakpointCondition: actions.setBreakpointCondition,
toggleAllBreakpoints: actions.toggleAllBreakpoints,
toggleBreakpoints: actions.toggleBreakpoints,
openConditionalPanel: actions.openConditionalPanel

View File

@ -18,6 +18,7 @@ import pause from "./pause";
import ui from "./ui";
import fileSearch from "./file-search";
import ast from "./ast";
import coverage from "./coverage";
import projectTextSearch from "./project-text-search";
import quickOpen from "./quick-open";
import sourceTree from "./source-tree";
@ -36,6 +37,7 @@ export default {
ui,
fileSearch,
ast,
coverage,
projectTextSearch,
quickOpen,
sourceTree,

View File

@ -11,6 +11,7 @@ DebuggerModules(
'ast.js',
'async-requests.js',
'breakpoints.js',
'coverage.js',
'debuggee.js',
'event-listeners.js',
'expressions.js',

View File

@ -431,19 +431,13 @@ function getSourcesByUrlInSources(
return urls[url].map(id => sources[id]);
}
export function getSourcesUrlsInSources(
state: OuterState,
url: string
): string[] {
export function getSourcesUrlsInSources(state: OuterState, url: string) {
const urls = getUrls(state);
if (!url || !urls[url]) {
return [];
}
const plainUrl = url.split("?")[0];
return Object.keys(urls)
.filter(Boolean)
.filter(sourceUrl => sourceUrl.split("?")[0] === plainUrl);
return [...new Set(Object.keys(urls).filter(Boolean))];
}
export function getHasSiblingOfSameName(state: OuterState, source: ?Source) {

View File

@ -14,6 +14,7 @@ export * from "../reducers/pending-breakpoints";
export * from "../reducers/ui";
export * from "../reducers/file-search";
export * from "../reducers/ast";
export * from "../reducers/coverage";
export * from "../reducers/project-text-search";
export * from "../reducers/source-tree";

View File

@ -18,12 +18,12 @@ type AnnotatedFrame =
| Frame;
export function annotateFrames(frames: Frame[]): AnnotatedFrame[] {
const annotatedFrames = frames.map(f => annotateFrame(f, frames));
const annotatedFrames = frames.map(annotateFrame);
return annotateBabelAsyncFrames(annotatedFrames);
}
function annotateFrame(frame: Frame, frames: Frame[]): AnnotatedFrame {
const library = getLibraryFromUrl(frame, frames);
function annotateFrame(frame: Frame): AnnotatedFrame {
const library = getLibraryFromUrl(frame);
if (library) {
return { ...frame, library };
}

View File

@ -128,15 +128,9 @@ export function getLibraryFromUrl(frame: Frame, callStack: Array<Frame> = []) {
o => o.contextPattern && frameUrl.match(o.contextPattern)
);
if (match) {
const contextMatch = callStack.some(f => {
const url = getFrameUrl(f);
if (!url) {
return false;
}
return libraryMap.some(o => url.match(o.pattern));
});
const contextMatch = callStack.some(f =>
libraryMap.find(o => frameUrl.match(o.pattern))
);
if (contextMatch) {
return match.label;
}

View File

@ -50,6 +50,7 @@ if (isDevelopment()) {
pref("devtools.debugger.features.root", true);
pref("devtools.debugger.features.map-scopes", true);
pref("devtools.debugger.features.remove-command-bar-options", true);
pref("devtools.debugger.features.code-coverage", false);
pref("devtools.debugger.features.event-listeners", false);
pref("devtools.debugger.features.code-folding", false);
pref("devtools.debugger.features.outline", true);
@ -104,6 +105,7 @@ export const features = new PrefsHelper("devtools.debugger.features", {
mapScopes: ["Bool", "map-scopes"],
removeCommandBarOptions: ["Bool", "remove-command-bar-options"],
workers: ["Bool", "workers"],
codeCoverage: ["Bool", "code-coverage"],
eventListeners: ["Bool", "event-listeners"],
outline: ["Bool", "outline"],
codeFolding: ["Bool", "code-folding"],

View File

@ -81,13 +81,4 @@ add_task(async function() {
bp = findBreakpoint(dbg, "simple2", 5);
is(bp.condition, "1", "breakpoint is created with the condition");
assertEditorBreakpoint(dbg, 5, true);
const bpCondition = waitForDispatch(dbg, "SET_BREAKPOINT_CONDITION");
//right click breakpoint in breakpoints list
rightClickElement(dbg, "breakpointItem", 3)
// select "remove condition";
selectMenuItem(dbg, 8);
await bpCondition;
bp = findBreakpoint(dbg, "simple2", 5);
is(bp.condition, undefined, "breakpoint condition removed");
});

View File

@ -52,5 +52,5 @@ add_task(async function() {
is(getValue(dbg, 4), 2);
await toggleExpressionNode(dbg, 1);
is(findAllElements(dbg, "expressionNodes").length, 37);
is(findAllElements(dbg, "expressionNodes").length, 20);
});

View File

@ -88,7 +88,7 @@ add_task(async function() {
await resume(dbg);
await addExpression(dbg, "location");
is(findAllElements(dbg, "expressionNodes").length, 34);
is(findAllElements(dbg, "expressionNodes").length, 17);
await toggleExpressionNode(dbg, 1);
is(findAllElements(dbg, "expressionNodes").length, 1);

View File

@ -70,10 +70,6 @@ add_task(async function() {
pressKey(dbg, "Escape");
is(getItems(dbg).length, 9, "9 items in the list after escape pressed");
// Ensure no action is taken when Enter key is pressed
pressKey(dbg, "Enter");
is(getItems(dbg).length, 9, "9 items in the list after enter pressed");
// check that the term 'todo' includes items with todo
type(dbg, "todo");
is(getItems(dbg).length, 2, "2 items in the list after 'todo' filter");

View File

@ -3283,6 +3283,32 @@ function getNodeSetter(item) {
return item && item.contents ? item.contents.set : undefined;
}
function makeNodesForAccessors(item) {
const accessors = [];
const getter = getNodeGetter(item);
if (getter && getter.type !== "undefined") {
accessors.push(createNode({
parent: item,
name: "<get>",
contents: { value: getter },
type: NODE_TYPES.GET
}));
}
const setter = getNodeSetter(item);
if (setter && setter.type !== "undefined") {
accessors.push(createNode({
parent: item,
name: "<set>",
contents: { value: setter },
type: NODE_TYPES.SET
}));
}
return accessors;
}
function sortProperties(properties) {
return properties.sort((a, b) => {
// Sort numbers in ascending order and sort strings lexicographically
@ -3416,18 +3442,6 @@ function makeNodesForProperties(objProps, parent) {
nodes.push(makeNodesForEntries(parent));
}
// Add accessor nodes if needed
for (const name of propertiesNames) {
const property = allProperties[name];
if (property.get && property.get.type !== "undefined") {
nodes.push(createGetterNode({ parent, property, name }));
}
if (property.set && property.set.type !== "undefined") {
nodes.push(createSetterNode({ parent, property, name }));
}
}
// Add the prototype if it exists and is not null
if (prototype && prototype.type !== "null") {
nodes.push(makeNodeForPrototype(objProps, parent));
@ -3497,24 +3511,6 @@ function createNode(options) {
};
}
function createGetterNode({ parent, property, name }) {
return createNode({
parent,
name: `<get ${name}()>`,
contents: { value: property.get },
type: NODE_TYPES.GET
});
}
function createSetterNode({ parent, property, name }) {
return createNode({
parent,
name: `<set ${name}()>`,
contents: { value: property.set },
type: NODE_TYPES.SET
});
}
function getSymbolDescriptor(symbol) {
return symbol.toString().replace(/^(Symbol\()(.*)(\))$/, "$2");
}
@ -3556,6 +3552,10 @@ function getChildren(options) {
return addToCache(item.contents);
}
if (nodeHasAccessors(item)) {
return addToCache(makeNodesForAccessors(item));
}
if (nodeIsMapEntry(item)) {
return addToCache(makeNodesForMapEntry(item));
}
@ -3647,8 +3647,6 @@ function getClosestNonBucketNode(item) {
module.exports = {
createNode,
createGetterNode,
createSetterNode,
getActor,
getChildren,
getClosestGripNode,
@ -6489,7 +6487,7 @@ class ObjectInspector extends Component {
const parentElementProps = {
className: classnames("node object-node", {
focused,
lessen: !expanded && (nodeIsDefaultProperties(item) || nodeIsPrototype(item) || nodeIsGetter(item) || nodeIsSetter(item) || dimTopLevelWindow === true && nodeIsWindow(item) && depth === 0),
lessen: !expanded && (nodeIsDefaultProperties(item) || nodeIsPrototype(item) || dimTopLevelWindow === true && nodeIsWindow(item) && depth === 0),
block: nodeIsBlock(item)
}),
onClick: e => {
@ -6559,9 +6557,7 @@ class ObjectInspector extends Component {
autoExpandDepth,
isExpanded: item => expandedPaths && expandedPaths.has(item.path),
// TODO: We don't want property with getters to be expandable until we
// do have a mechanism to invoke the getter (See #6140).
isExpandable: item => !nodeIsPrimitive(item) && !nodeHasAccessors(item),
isExpandable: item => nodeIsPrimitive(item) === false,
focused: this.focusedItem,
getRoots: this.getRoots,

File diff suppressed because one or more lines are too long

View File

@ -531,7 +531,10 @@ BrowserTabList.prototype.receiveMessage = DevToolsUtils.makeInfallible(
*/
BrowserTabList.prototype.handleEvent =
DevToolsUtils.makeInfallible(function(event) {
const browser = event.target.linkedBrowser;
// If event target has `linkedBrowser`, the event target can be assumed <tab> element.
// Else (in Android case), because event target is assumed <browser> element,
// use the target as it is.
const browser = event.target.linkedBrowser || event.target;
switch (event.type) {
case "TabOpen":
case "TabSelect": {

View File

@ -791,9 +791,9 @@ void
nsDocShell::MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState)
{
// First, verify if this is a subframe.
nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
GetSameTypeParent(getter_AddRefs(parentAsItem));
nsCOMPtr<nsIDocShell> parentDS(do_QueryInterface(parentAsItem));
nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
GetSameTypeParent(getter_AddRefs(parentAsItem));
nsCOMPtr<nsIDocShell> parentDS(do_QueryInterface(parentAsItem));
if (!parentDS || parentDS == static_cast<nsIDocShell*>(this)) {
// This is the root docshell. If we got here while
@ -813,58 +813,57 @@ nsDocShell::MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState)
* back/forward. If the parent was loaded through any other loadType, set the
* child's loadType too accordingly, so that session history does not get
* confused.
*/
*/
// Get the parent's load type
// Get the parent's load type
uint32_t parentLoadType;
parentDS->GetLoadType(&parentLoadType);
parentDS->GetLoadType(&parentLoadType);
// Get the ShEntry for the child from the parent
nsCOMPtr<nsISHEntry> currentSH;
bool oshe = false;
parentDS->GetCurrentSHEntry(getter_AddRefs(currentSH), &oshe);
bool dynamicallyAddedChild = mDynamicallyCreated;
// Get the ShEntry for the child from the parent
nsCOMPtr<nsISHEntry> currentSH;
bool oshe = false;
parentDS->GetCurrentSHEntry(getter_AddRefs(currentSH), &oshe);
bool dynamicallyAddedChild = mDynamicallyCreated;
if (!dynamicallyAddedChild && !oshe && currentSH) {
currentSH->HasDynamicallyAddedChild(&dynamicallyAddedChild);
}
if (!dynamicallyAddedChild && !oshe && currentSH) {
currentSH->HasDynamicallyAddedChild(&dynamicallyAddedChild);
}
if (!dynamicallyAddedChild) {
// Only use the old SHEntry, if we're sure enough that
// it wasn't originally for some other frame.
if (!dynamicallyAddedChild) {
// Only use the old SHEntry, if we're sure enough that
// it wasn't originally for some other frame.
nsCOMPtr<nsISHEntry> shEntry;
parentDS->GetChildSHEntry(mChildOffset, getter_AddRefs(shEntry));
parentDS->GetChildSHEntry(mChildOffset, getter_AddRefs(shEntry));
aLoadState->SetSHEntry(shEntry);
}
}
// Make some decisions on the child frame's loadType based on the
// parent's loadType, if the subframe hasn't loaded anything into it.
//
// In some cases privileged scripts may try to get the DOMWindow
// reference of this docshell before the loading starts, causing the
// initial about:blank content viewer being created and mCurrentURI being
// set. To handle this case we check if mCurrentURI is about:blank and
// currentSHEntry is null.
nsCOMPtr<nsISHEntry> currentChildEntry;
GetCurrentSHEntry(getter_AddRefs(currentChildEntry), &oshe);
// Make some decisions on the child frame's loadType based on the
// parent's loadType, if the subframe hasn't loaded anything into it.
//
// In some cases privileged scripts may try to get the DOMWindow
// reference of this docshell before the loading starts, causing the
// initial about:blank content viewer being created and mCurrentURI being
// set. To handle this case we check if mCurrentURI is about:blank and
// currentSHEntry is null.
nsCOMPtr<nsISHEntry> currentChildEntry;
GetCurrentSHEntry(getter_AddRefs(currentChildEntry), &oshe);
if (mCurrentURI && (!NS_IsAboutBlank(mCurrentURI) || currentChildEntry)) {
// This is a pre-existing subframe. If
// 1. The load of this frame was not originally initiated by session
// history directly (i.e. (!shEntry) condition succeeded, but it can
// still be a history load on parent which causes this frame being
// This is a pre-existing subframe. If
// 1. The load of this frame was not originally initiated by session
// history directly (i.e. (!shEntry) condition succeeded, but it can
// still be a history load on parent which causes this frame being
// loaded), which we checked with the above assert, and
// 2. mCurrentURI is not null, nor the initial about:blank,
// it is possible that a parent's onLoadHandler or even self's
// onLoadHandler is loading a new page in this child. Check parent's and
// self's busy flag and if it is set, we don't want this onLoadHandler
// load to get in to session history.
uint32_t parentBusy = BUSY_FLAGS_NONE;
uint32_t selfBusy = BUSY_FLAGS_NONE;
parentDS->GetBusyFlags(&parentBusy);
GetBusyFlags(&selfBusy);
if (parentBusy & BUSY_FLAGS_BUSY ||
selfBusy & BUSY_FLAGS_BUSY) {
// 2. mCurrentURI is not null, nor the initial about:blank,
// it is possible that a parent's onLoadHandler or even self's
// onLoadHandler is loading a new page in this child. Check parent's and
// self's busy flag and if it is set, we don't want this onLoadHandler
// load to get in to session history.
BusyFlags parentBusy = parentDS->GetBusyFlags();
BusyFlags selfBusy = GetBusyFlags();
if (parentBusy & BUSY_FLAGS_BUSY ||
selfBusy & BUSY_FLAGS_BUSY) {
aLoadState->SetLoadType(LOAD_NORMAL_REPLACE);
aLoadState->SetSHEntry(nullptr);
}
@ -882,9 +881,9 @@ nsDocShell::MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState)
// in the onLoadHandler. We don't want this url to get into session
// history. Clear off shEntry, and set load type to
// LOAD_BYPASS_HISTORY.
bool inOnLoadHandler = false;
bool inOnLoadHandler = false;
parentDS->GetIsExecutingOnLoadHandler(&inOnLoadHandler);
if (inOnLoadHandler) {
if (inOnLoadHandler) {
aLoadState->SetLoadType(LOAD_NORMAL_REPLACE);
aLoadState->SetSHEntry(nullptr);
}
@ -2010,7 +2009,7 @@ nsDocShell::GetMayEnableCharacterEncodingMenu(
}
NS_IMETHODIMP
nsDocShell::GetDocShellEnumerator(int32_t aItemType, int32_t aDirection,
nsDocShell::GetDocShellEnumerator(int32_t aItemType, DocShellEnumeratorDirection aDirection,
nsISimpleEnumerator** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
@ -2045,14 +2044,14 @@ nsDocShell::GetDocShellEnumerator(int32_t aItemType, int32_t aDirection,
}
NS_IMETHODIMP
nsDocShell::GetAppType(uint32_t* aAppType)
nsDocShell::GetAppType(AppType* aAppType)
{
*aAppType = mAppType;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetAppType(uint32_t aAppType)
nsDocShell::SetAppType(AppType aAppType)
{
mAppType = aAppType;
return NS_OK;
@ -2119,7 +2118,7 @@ nsDocShell::SetMarginHeight(int32_t aHeight)
}
NS_IMETHODIMP
nsDocShell::GetBusyFlags(uint32_t* aBusyFlags)
nsDocShell::GetBusyFlags(BusyFlags* aBusyFlags)
{
NS_ENSURE_ARG_POINTER(aBusyFlags);
@ -2521,18 +2520,20 @@ nsDocShell::SetCustomUserAgent(const nsAString& aCustomUserAgent)
}
NS_IMETHODIMP
nsDocShell::GetTouchEventsOverride(uint32_t* aTouchEventsOverride)
nsDocShell::GetTouchEventsOverride(TouchEventsOverride* aTouchEventsOverride)
{
*aTouchEventsOverride = mTouchEventsOverride;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetTouchEventsOverride(uint32_t aTouchEventsOverride)
nsDocShell::SetTouchEventsOverride(TouchEventsOverride aTouchEventsOverride)
{
if (!(aTouchEventsOverride == nsIDocShell::TOUCHEVENTS_OVERRIDE_NONE ||
aTouchEventsOverride == nsIDocShell::TOUCHEVENTS_OVERRIDE_ENABLED ||
aTouchEventsOverride == nsIDocShell::TOUCHEVENTS_OVERRIDE_DISABLED)) {
// We don't have a way to verify this coming from Javascript, so this check is
// still needed.
if (!(aTouchEventsOverride == TOUCHEVENTS_OVERRIDE_NONE ||
aTouchEventsOverride == TOUCHEVENTS_OVERRIDE_ENABLED ||
aTouchEventsOverride == TOUCHEVENTS_OVERRIDE_DISABLED)) {
return NS_ERROR_INVALID_ARG;
}
@ -2549,7 +2550,7 @@ nsDocShell::SetTouchEventsOverride(uint32_t aTouchEventsOverride)
}
NS_IMETHODIMP
nsDocShell::GetMetaViewportOverride(uint32_t* aMetaViewportOverride)
nsDocShell::GetMetaViewportOverride(MetaViewportOverride* aMetaViewportOverride)
{
NS_ENSURE_ARG_POINTER(aMetaViewportOverride);
@ -2558,11 +2559,13 @@ nsDocShell::GetMetaViewportOverride(uint32_t* aMetaViewportOverride)
}
NS_IMETHODIMP
nsDocShell::SetMetaViewportOverride(uint32_t aMetaViewportOverride)
nsDocShell::SetMetaViewportOverride(MetaViewportOverride aMetaViewportOverride)
{
if (!(aMetaViewportOverride == nsIDocShell::META_VIEWPORT_OVERRIDE_NONE ||
aMetaViewportOverride == nsIDocShell::META_VIEWPORT_OVERRIDE_ENABLED ||
aMetaViewportOverride == nsIDocShell::META_VIEWPORT_OVERRIDE_DISABLED)) {
// We don't have a way to verify this coming from Javascript, so this check is
// still needed.
if (!(aMetaViewportOverride == META_VIEWPORT_OVERRIDE_NONE ||
aMetaViewportOverride == META_VIEWPORT_OVERRIDE_ENABLED ||
aMetaViewportOverride == META_VIEWPORT_OVERRIDE_DISABLED)) {
return NS_ERROR_INVALID_ARG;
}
@ -2827,10 +2830,9 @@ nsDocShell::SetDocLoaderParent(nsDocLoader* aParent)
if (NS_SUCCEEDED(parentAsDocShell->GetDefaultLoadFlags(&flags))) {
SetDefaultLoadFlags(flags);
}
uint32_t touchEventsOverride;
if (NS_SUCCEEDED(parentAsDocShell->GetTouchEventsOverride(&touchEventsOverride))) {
SetTouchEventsOverride(touchEventsOverride);
}
SetTouchEventsOverride(parentAsDocShell->GetTouchEventsOverride());
// We don't need to inherit metaViewportOverride, because the viewport
// is only relevant for the outermost nsDocShell, not for any iframes
// like this that might be embedded within it.
@ -6114,8 +6116,7 @@ nsDocShell::RefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal,
nsCOMPtr<nsITimerCallback> refreshTimer =
new nsRefreshTimer(this, aURI, aPrincipal, aDelay, aRepeat, aMetaRefresh);
uint32_t busyFlags = 0;
GetBusyFlags(&busyFlags);
BusyFlags busyFlags = GetBusyFlags();
if (!mRefreshURIList) {
mRefreshURIList = nsArray::Create();
@ -6798,7 +6799,7 @@ nsDocShell::OnStateChange(nsIWebProgress* aProgress, nsIRequest* aRequest,
}
}
// Page has begun to load
mBusyFlags = BUSY_FLAGS_BUSY | BUSY_FLAGS_BEFORE_PAGE_LOAD;
mBusyFlags = (BusyFlags)(BUSY_FLAGS_BUSY | BUSY_FLAGS_BEFORE_PAGE_LOAD);
if ((aStateFlags & STATE_RESTORING) == 0) {
// Show the progress cursor if the pref is set
@ -6812,7 +6813,7 @@ nsDocShell::OnStateChange(nsIWebProgress* aProgress, nsIRequest* aRequest,
}
} else if ((~aStateFlags & (STATE_TRANSFERRING | STATE_IS_DOCUMENT)) == 0) {
// Page is loading
mBusyFlags = BUSY_FLAGS_BUSY | BUSY_FLAGS_PAGE_LOADING;
mBusyFlags = (BusyFlags)(BUSY_FLAGS_BUSY | BUSY_FLAGS_PAGE_LOADING);
} else if ((aStateFlags & STATE_STOP) && (aStateFlags & STATE_IS_NETWORK)) {
// Page has finished loading
mBusyFlags = BUSY_FLAGS_NONE;
@ -13599,14 +13600,14 @@ nsDocShell::GetCanExecuteScripts(bool* aResult)
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::SetFrameType(uint32_t aFrameType)
nsDocShell::SetFrameType(FrameType aFrameType)
{
mFrameType = aFrameType;
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetFrameType(uint32_t* aFrameType)
nsDocShell::GetFrameType(FrameType* aFrameType)
{
*aFrameType = mFrameType;
return NS_OK;
@ -14089,15 +14090,17 @@ nsIDocShell::SetHTMLEditor(HTMLEditor* aHTMLEditor)
}
NS_IMETHODIMP
nsDocShell::GetDisplayMode(uint32_t* aDisplayMode)
nsDocShell::GetDisplayMode(DisplayMode* aDisplayMode)
{
*aDisplayMode = mDisplayMode;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetDisplayMode(uint32_t aDisplayMode)
nsDocShell::SetDisplayMode(DisplayMode aDisplayMode)
{
// We don't have a way to verify this coming from Javascript, so this check is
// still needed.
if (!(aDisplayMode == nsIDocShell::DISPLAY_MODE_BROWSER ||
aDisplayMode == nsIDocShell::DISPLAY_MODE_STANDALONE ||
aDisplayMode == nsIDocShell::DISPLAY_MODE_FULLSCREEN ||

View File

@ -132,6 +132,40 @@ class nsDocShell final
, public mozilla::SupportsWeakPtr<nsDocShell>
{
public:
enum InternalLoad : uint32_t {
INTERNAL_LOAD_FLAGS_NONE = 0x0,
INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL = 0x1,
INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER = 0x2,
INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP = 0x4,
// This flag marks the first load in this object
// @see nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD
INTERNAL_LOAD_FLAGS_FIRST_LOAD = 0x8,
// The set of flags that should not be set before calling into
// nsDocShell::LoadURI and other nsDocShell loading functions.
INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS = 0xf,
INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER = 0x10,
INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES = 0x20,
// Whether the load should be treated as srcdoc load, rather than a URI one.
INTERNAL_LOAD_FLAGS_IS_SRCDOC = 0x40,
// Whether this is the load of a frame's original src attribute
INTERNAL_LOAD_FLAGS_ORIGINAL_FRAME_SRC = 0x80,
INTERNAL_LOAD_FLAGS_NO_OPENER = 0x100,
// Whether a top-level data URI navigation is allowed for that load
INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI = 0x200,
// Whether the load was triggered by user interaction.
INTERNAL_LOAD_FLAGS_IS_USER_TRIGGERED = 0x1000,
};
// Event type dispatched by RestorePresentation
class RestorePresentationEvent : public mozilla::Runnable
{
@ -1055,15 +1089,15 @@ private: // data members
int32_t mChildOffset;
uint32_t mSandboxFlags;
uint32_t mBusyFlags;
uint32_t mAppType;
BusyFlags mBusyFlags;
AppType mAppType;
uint32_t mLoadType;
uint32_t mDefaultLoadFlags;
uint32_t mReferrerPolicy;
uint32_t mFailedLoadType;
// Are we a regular frame, a browser frame, or an app frame?
uint32_t mFrameType;
FrameType mFrameType;
// This represents the state of private browsing in the docshell.
// Currently treated as a binary value: 1 - in private mode, 0 - not private mode
@ -1072,17 +1106,9 @@ private: // data members
// origin attribute set.
uint32_t mPrivateBrowsingId;
// This represents the CSS display-mode we are currently using.
// It can be any of the following values from nsIDocShell.idl:
//
// DISPLAY_MODE_BROWSER = 0
// DISPLAY_MODE_MINIMAL_UI = 1
// DISPLAY_MODE_STANDALONE = 2
// DISPLAY_MODE_FULLSCREEN = 3
//
// This is mostly used for media queries. The integer values above
// match those used in nsStyleConsts.h
uint32_t mDisplayMode;
// This represents the CSS display-mode we are currently using. This is mostly
// used for media queries.
DisplayMode mDisplayMode;
// A depth count of how many times NotifyRunToCompletionStart
// has been called without a matching NotifyRunToCompletionStop.
@ -1090,11 +1116,11 @@ private: // data members
// Whether or not touch events are overridden. Possible values are defined
// as constants in the nsIDocShell.idl file.
uint32_t mTouchEventsOverride;
TouchEventsOverride mTouchEventsOverride;
// Whether or not handling of the <meta name="viewport"> tag is overridden.
// Possible values are defined as constants in nsIDocShell.idl.
uint32_t mMetaViewportOverride;
MetaViewportOverride mMetaViewportOverride;
// mFullscreenAllowed stores how we determine whether fullscreen is allowed
// when GetFullscreenAllowed() is called. Fullscreen is allowed in a

View File

@ -515,44 +515,44 @@ nsDocShellLoadState::CalculateDocShellInternalLoadFlags()
MOZ_ASSERT(!nsContentUtils::IsSystemPrincipal(mPrincipalToInherit),
"Should not inherit SystemPrincipal");
mDocShellInternalLoadFlags |=
nsIDocShell::INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL;
nsDocShell::INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL;
}
if (!mSendReferrer) {
mDocShellInternalLoadFlags |=
nsIDocShell::INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER;
nsDocShell::INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER;
}
if (mLoadFlags & nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
mDocShellInternalLoadFlags |=
nsIDocShell::INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
nsDocShell::INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
}
if (mLoadFlags & nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD) {
mDocShellInternalLoadFlags |= nsIDocShell::INTERNAL_LOAD_FLAGS_FIRST_LOAD;
mDocShellInternalLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_FIRST_LOAD;
}
if (mLoadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_CLASSIFIER) {
mDocShellInternalLoadFlags |=
nsIDocShell::INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER;
nsDocShell::INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER;
}
if (mLoadFlags & nsIWebNavigation::LOAD_FLAGS_FORCE_ALLOW_COOKIES) {
mDocShellInternalLoadFlags |=
nsIDocShell::INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES;
nsDocShell::INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES;
}
if (mIsSrcdocLoad) {
mDocShellInternalLoadFlags |= nsIDocShell::INTERNAL_LOAD_FLAGS_IS_SRCDOC;
mDocShellInternalLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_IS_SRCDOC;
}
if (mForceAllowDataURI) {
mDocShellInternalLoadFlags |=
nsIDocShell::INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
nsDocShell::INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
}
if (mOriginalFrameSrc) {
mDocShellInternalLoadFlags |=
nsIDocShell::INTERNAL_LOAD_FLAGS_ORIGINAL_FRAME_SRC;
nsDocShell::INTERNAL_LOAD_FLAGS_ORIGINAL_FRAME_SRC;
}
}

View File

@ -82,38 +82,6 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
[noscript]void loadURI(in nsDocShellLoadStatePtr loadState);
const long INTERNAL_LOAD_FLAGS_NONE = 0x0;
const long INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL = 0x1;
const long INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER = 0x2;
const long INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP = 0x4;
// This flag marks the first load in this object
// @see nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD
const long INTERNAL_LOAD_FLAGS_FIRST_LOAD = 0x8;
// The set of flags that should not be set before calling into
// nsDocShell::LoadURI and other nsDocShell loading functions.
const long INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS = 0xf;
const long INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER = 0x10;
const long INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES = 0x20;
// Whether the load should be treated as srcdoc load, rather than a URI one.
const long INTERNAL_LOAD_FLAGS_IS_SRCDOC = 0x40;
// Whether this is the load of a frame's original src attribute
const long INTERNAL_LOAD_FLAGS_ORIGINAL_FRAME_SRC = 0x80;
const long INTERNAL_LOAD_FLAGS_NO_OPENER = 0x100;
// Whether a top-level data URI navigation is allowed for that load
const long INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI = 0x200;
// Whether the load was triggered by user interaction.
const long INTERNAL_LOAD_FLAGS_IS_USER_TRIGGERED = 0x1000;
/**
* Loads the given URI. This method is identical to loadURI(...) except
* that its parameter list is broken out instead of being packaged inside
@ -355,20 +323,29 @@ interface nsIDocShell : nsIDocShellTreeItem
* @param aDirection - Whether to enumerate forwards or backwards.
*/
const long ENUMERATE_FORWARDS = 0;
const long ENUMERATE_BACKWARDS = 1;
cenum DocShellEnumeratorDirection : 8 {
ENUMERATE_FORWARDS = 0,
ENUMERATE_BACKWARDS = 1
};
nsISimpleEnumerator getDocShellEnumerator(in long aItemType,
in long aDirection);
in nsIDocShell_DocShellEnumeratorDirection aDirection);
/**
* The type of application that created this window
* The type of application that created this window.
*
* DO NOT DELETE, see bug 176166. For firefox, this value will always be
* UNKNOWN. However, it is used heavily in Thunderbird/comm-central and we
* don't really have a great replacement at the moment, so we'll just leave it
* here.
*/
const unsigned long APP_TYPE_UNKNOWN = 0;
const unsigned long APP_TYPE_MAIL = 1;
const unsigned long APP_TYPE_EDITOR = 2;
cenum AppType : 8 {
APP_TYPE_UNKNOWN = 0,
APP_TYPE_MAIL = 1,
APP_TYPE_EDITOR = 2
};
attribute unsigned long appType;
[infallible] attribute nsIDocShell_AppType appType;
/**
* certain dochshells (like the message pane)
@ -416,25 +393,30 @@ interface nsIDocShell : nsIDocShellTreeItem
/**
* Current busy state for DocShell
*/
const unsigned long BUSY_FLAGS_NONE = 0;
const unsigned long BUSY_FLAGS_BUSY = 1;
const unsigned long BUSY_FLAGS_BEFORE_PAGE_LOAD = 2;
const unsigned long BUSY_FLAGS_PAGE_LOADING = 4;
cenum BusyFlags : 8 {
BUSY_FLAGS_NONE = 0,
BUSY_FLAGS_BUSY = 1,
BUSY_FLAGS_BEFORE_PAGE_LOAD = 2,
BUSY_FLAGS_PAGE_LOADING = 4,
};
[infallible] readonly attribute nsIDocShell_BusyFlags busyFlags;
/**
* Load commands for the document
*/
const unsigned long LOAD_CMD_NORMAL = 0x1; // Normal load
const unsigned long LOAD_CMD_RELOAD = 0x2; // Reload
const unsigned long LOAD_CMD_HISTORY = 0x4; // Load from history
const unsigned long LOAD_CMD_PUSHSTATE = 0x8; // History.pushState()
readonly attribute unsigned long busyFlags;
cenum LoadCommand : 8 {
LOAD_CMD_NORMAL = 0x1, // Normal load
LOAD_CMD_RELOAD = 0x2, // Reload
LOAD_CMD_HISTORY = 0x4, // Load from history
LOAD_CMD_PUSHSTATE = 0x8, // History.pushState()
};
/*
* attribute to access the loadtype for the document
* Attribute to access the loadtype for the document. LoadType Enum is
* defined in nsDocShellLoadTypes.h
*/
attribute unsigned long loadType;
[infallible] attribute unsigned long loadType;
/*
* Default load flags (as defined in nsIRequest) that will be set on all
@ -819,10 +801,11 @@ interface nsIDocShell : nsIDocShellTreeItem
/**
* The type of iframe that this docshell lives.
*/
const unsigned long FRAME_TYPE_REGULAR = 0;
const unsigned long FRAME_TYPE_BROWSER = 1;
[infallible] attribute unsigned long frameType;
cenum FrameType : 8 {
FRAME_TYPE_REGULAR = 0,
FRAME_TYPE_BROWSER = 1,
};
[infallible] attribute nsIDocShell_FrameType frameType;
/**
* Returns true if this docshell corresponds to an <iframe mozbrowser>.
@ -1131,45 +1114,51 @@ interface nsIDocShell : nsIDocShellTreeItem
[noscript,nostdcall,notxpcom] nsICommandManager GetCommandManager();
cenum TouchEventsOverride: 8 {
/**
* Override platform/pref default behaviour and force-disable touch events.
*/
TOUCHEVENTS_OVERRIDE_DISABLED = 0,
/**
* Override platform/pref default behaviour and force-enable touch events.
*/
TOUCHEVENTS_OVERRIDE_ENABLED = 1,
/**
* Don't override the platform/pref default behaviour for touch events.
*/
TOUCHEVENTS_OVERRIDE_NONE = 2,
};
/**
* This allows chrome to override the default choice of whether touch events
* are available on a specific docshell. Possible values are listed below.
*/
[infallible] attribute unsigned long touchEventsOverride;
/**
* Override platform/pref default behaviour and force-disable touch events.
*/
const unsigned long TOUCHEVENTS_OVERRIDE_DISABLED = 0;
/**
* Override platform/pref default behaviour and force-enable touch events.
*/
const unsigned long TOUCHEVENTS_OVERRIDE_ENABLED = 1;
/**
* Don't override the platform/pref default behaviour for touch events.
*/
const unsigned long TOUCHEVENTS_OVERRIDE_NONE = 2;
[infallible] attribute nsIDocShell_TouchEventsOverride touchEventsOverride;
cenum MetaViewportOverride: 8 {
/**
* Override platform/pref default behaviour and force-disable support for
* <meta name="viewport">.
*/
META_VIEWPORT_OVERRIDE_DISABLED = 0,
/**
* Override platform/pref default behaviour and force-enable support for
* <meta name="viewport">.
*/
META_VIEWPORT_OVERRIDE_ENABLED = 1,
/**
* Don't override the platform/pref default behaviour for support for
* <meta name="viewport">.
*/
META_VIEWPORT_OVERRIDE_NONE = 2,
};
/**
* Override platform/pref default behaviour and force-disable support for
* <meta name="viewport">.
*/
const unsigned long META_VIEWPORT_OVERRIDE_DISABLED = 0;
/**
* Override platform/pref default behaviour and force-enable support for
* <meta name="viewport">.
*/
const unsigned long META_VIEWPORT_OVERRIDE_ENABLED = 1;
/**
* Don't override the platform/pref default behaviour for support for
* <meta name="viewport">.
*/
const unsigned long META_VIEWPORT_OVERRIDE_NONE = 2;
/**
* This allows chrome to override the default choice of whether the
* <meta name="viewport"> tag is respected in a specific docshell.
* Possible values are listed above.
*/
attribute unsigned long metaViewportOverride;
[infallible] attribute nsIDocShell_MetaViewportOverride metaViewportOverride;
/**
* This value is `true` if its corresponding unit of related browsing contexts
@ -1240,18 +1229,20 @@ interface nsIDocShell : nsIDocShellTreeItem
/**
* Allowed CSS display modes. This needs to be kept in
* sync with similar values in nsStyleConsts.h
* sync with similar values in ServoStyleConsts.h
*/
const unsigned long DISPLAY_MODE_BROWSER = 0;
const unsigned long DISPLAY_MODE_MINIMAL_UI = 1;
const unsigned long DISPLAY_MODE_STANDALONE = 2;
const unsigned long DISPLAY_MODE_FULLSCREEN = 3;
cenum DisplayMode: 8 {
DISPLAY_MODE_BROWSER = 0,
DISPLAY_MODE_MINIMAL_UI = 1,
DISPLAY_MODE_STANDALONE = 2,
DISPLAY_MODE_FULLSCREEN = 3,
};
/**
* Display mode for this docshell. Defaults to DISPLAY_MODE_BROWSER.
* Media queries only look at the value in the top-most docshell.
*/
[infallible] attribute unsigned long displayMode;
[infallible] attribute nsIDocShell_DisplayMode displayMode;
/**
* The message manager for this docshell. This does not throw, but

View File

@ -1894,6 +1894,23 @@ KeyframeEffect::IsMatchForCompositor(
return KeyframeEffect::MatchForCompositor::NoAndBlockThisProperty;
}
if (aProperty == eCSSProperty_background_color) {
if (!StaticPrefs::gfx_omta_background_color()) {
return KeyframeEffect::MatchForCompositor::No;
}
if (nsIContent* content = aFrame->GetContent()) {
RefPtr<layers::LayerManager> layerManager =
nsContentUtils::LayerManagerForContent(content);
if (layerManager &&
layerManager->GetBackendType() == layers::LayersBackend::LAYERS_WR) {
// Bug 1510030: We don't yet support background-color animations on the
// compositor for WebRender.
return KeyframeEffect::MatchForCompositor::No;
}
}
}
return mAnimation->IsPlaying()
? KeyframeEffect::MatchForCompositor::Yes
: KeyframeEffect::MatchForCompositor::IfNeeded;

View File

@ -50,7 +50,9 @@ div {
/** Test for bug 1045994 - Add a chrome-only property to inspect if an
animation is running on the compositor or not **/
var omtaEnabled = isOMTAEnabled();
const omtaEnabled = isOMTAEnabled();
const isWebRender =
SpecialPowers.DOMWindowUtils.layerManagerType == 'WebRender';
function assert_animation_is_running_on_compositor(animation, desc) {
assert_equals(animation.isRunningOnCompositor, omtaEnabled,
@ -988,5 +990,41 @@ promise_test(async t => {
'Transform animation on table element should be running on the compositor');
}, 'Transform animation on table element runs on the compositor');
promise_test(async t => {
const div = addDiv(t);
const animation = div.animate({ backgroundColor: ['blue', 'green'] },
100 * MS_PER_SEC);
await waitForAnimationReadyToRestyle(animation);
await waitForPaints();
if (!isWebRender) {
assert_animation_is_running_on_compositor(animation,
'background-color animation should be running on the compositor');
} else {
assert_animation_is_not_running_on_compositor(animation,
'background-color animation is not yet able to run on the compositor ' +
'on WebRender');
}
}, 'backgound-color animation runs on the compositor');
promise_test(async t => {
await SpecialPowers.pushPrefEnv({
set: [["gfx.omta.background-color", false]]
});
const div = addDiv(t);
const animation = div.animate({ backgroundColor: ['blue', 'green'] },
100 * MS_PER_SEC);
await waitForAnimationReadyToRestyle(animation);
await waitForPaints();
assert_animation_is_not_running_on_compositor(animation,
'background-color animation should NOT be running on the compositor ' +
'if the pref is disabled');
}, 'backgound-color animation does not run on the compositor if the pref ' +
'is disabled');
</script>
</body>

View File

@ -5,6 +5,7 @@ prefs =
dom.animations-api.getAnimations.enabled=true
dom.animations-api.implicit-keyframes.enabled=true
dom.animations-api.timelines.enabled=true
gfx.omta.background-color=true
layout.css.motion-path.enabled=true
layout.css.individual-transform.enabled=true
# Support files for chrome tests that we want to load over HTTP need

View File

@ -3443,7 +3443,7 @@ nsContentUtils::CanLoadImage(nsIURI* aURI, nsINode* aNode,
nsresult rv;
uint32_t appType = nsIDocShell::APP_TYPE_UNKNOWN;
auto appType = nsIDocShell::APP_TYPE_UNKNOWN;
{
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = aLoadingDocument->GetDocShell();
@ -3453,8 +3453,8 @@ nsContentUtils::CanLoadImage(nsIURI* aURI, nsINode* aNode,
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(root));
if (!docShell || NS_FAILED(docShell->GetAppType(&appType))) {
appType = nsIDocShell::APP_TYPE_UNKNOWN;
if (docShell) {
appType = docShell->GetAppType();
}
}
}
@ -7669,9 +7669,8 @@ nsContentUtils::PrefetchPreloadEnabled(nsIDocShell* aDocShell)
nsCOMPtr<nsIDocShellTreeItem> parentItem;
do {
uint32_t appType = 0;
nsresult rv = docshell->GetAppType(&appType);
if (NS_FAILED(rv) || appType == nsIDocShell::APP_TYPE_MAIL) {
auto appType = docshell->GetAppType();
if (appType == nsIDocShell::APP_TYPE_MAIL) {
return false; // do not prefetch, preload, preconnect from mailnews
}

View File

@ -3733,6 +3733,14 @@ nsDOMWindowUtils::GetOMTAStyle(Element* aElement,
if (value.type() == OMTAValue::TMatrix4x4) {
cssValue = nsComputedDOMStyle::MatrixToCSSValue(value.get_Matrix4x4());
}
} else if (aProperty.EqualsLiteral("background-color")) {
OMTAValue value = GetOMTAValue(frame,
DisplayItemType::TYPE_BACKGROUND_COLOR,
GetWebRenderBridge());
if (value.type() == OMTAValue::Tnscolor) {
cssValue = new nsROCSSPrimitiveValue;
nsComputedDOMStyle::SetToRGBAColor(cssValue, value.get_nscolor());
}
}
}

View File

@ -3129,9 +3129,8 @@ nsGlobalWindowOuter::GetSanitizedOpener(nsPIDOMWindowOuter* aOpener)
openerDocShell->GetRootTreeItem(getter_AddRefs(openerRootItem));
nsCOMPtr<nsIDocShell> openerRootDocShell(do_QueryInterface(openerRootItem));
if (openerRootDocShell) {
uint32_t appType;
nsresult rv = openerRootDocShell->GetAppType(&appType);
if (NS_SUCCEEDED(rv) && appType != nsIDocShell::APP_TYPE_MAIL) {
nsIDocShell::AppType appType = openerRootDocShell->GetAppType();
if (appType != nsIDocShell::APP_TYPE_MAIL) {
return aOpener;
}
}

View File

@ -3885,13 +3885,12 @@ EventStateManager::UpdateCursor(nsPresContext* aPresContext,
// Check whether or not to show the busy cursor
nsCOMPtr<nsIDocShell> docShell(aPresContext->GetDocShell());
if (!docShell) return;
uint32_t busyFlags = nsIDocShell::BUSY_FLAGS_NONE;
docShell->GetBusyFlags(&busyFlags);
auto busyFlags = docShell->GetBusyFlags();
// Show busy cursor everywhere before page loads
// and just replace the arrow cursor after page starts loading
if (busyFlags & nsIDocShell::BUSY_FLAGS_BUSY &&
(cursor == NS_STYLE_CURSOR_AUTO || cursor == NS_STYLE_CURSOR_DEFAULT))
(cursor == NS_STYLE_CURSOR_AUTO || cursor == NS_STYLE_CURSOR_DEFAULT))
{
cursor = NS_STYLE_CURSOR_SPINNING;
container = nullptr;

View File

@ -253,9 +253,9 @@ TouchEvent::PrefEnabled(nsIDocShell* aDocShell)
static bool sPrefCached = false;
static int32_t sPrefCacheValue = 0;
uint32_t touchEventsOverride = nsIDocShell::TOUCHEVENTS_OVERRIDE_NONE;
auto touchEventsOverride = nsIDocShell::TOUCHEVENTS_OVERRIDE_NONE;
if (aDocShell) {
aDocShell->GetTouchEventsOverride(&touchEventsOverride);
touchEventsOverride = aDocShell->GetTouchEventsOverride();
}
if (!sPrefCached) {

View File

@ -4694,6 +4694,19 @@ HTMLInputElement::UnbindFromTree(bool aDeep, bool aNullParent)
WillRemoveFromRadioGroup();
}
if (GetShadowRoot() && IsInComposedDoc()) {
nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
"HTMLInputElement::UnbindFromTree::UAWidgetUnbindFromTree",
[self = RefPtr<Element>(this)]() {
nsContentUtils::DispatchChromeEvent(
self->OwnerDoc(), self,
NS_LITERAL_STRING("UAWidgetUnbindFromTree"),
CanBubble::eYes, Cancelable::eNo);
self->UnattachShadow();
})
);
}
nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
nsGenericHTMLFormElementWithState::UnbindFromTree(aDeep, aNullParent);
@ -4705,20 +4718,6 @@ HTMLInputElement::UnbindFromTree(bool aDeep, bool aNullParent)
// And now make sure our state is up to date
UpdateState(false);
if (GetShadowRoot() && IsInComposedDoc()) {
RefPtr<Element> self = this;
nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
"HTMLInputElement::UnbindFromTree::UAWidgetUnbindFromTree",
[self]() {
nsContentUtils::DispatchChromeEvent(
self->OwnerDoc(), self,
NS_LITERAL_STRING("UAWidgetUnbindFromTree"),
CanBubble::eYes, Cancelable::eNo);
self->UnattachShadow();
})
);
}
}
void

View File

@ -4693,18 +4693,24 @@ HTMLMediaElement::UnbindFromTree(bool aDeep, bool aNullParent)
mUnboundFromTree = true;
mVisibilityState = Visibility::UNTRACKED;
if (GetShadowRoot() && IsInComposedDoc()) {
nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
"HTMLMediaElement::UnbindFromTree::UAWidgetUnbindFromTree",
[self = RefPtr<Element>(this)]() {
nsContentUtils::DispatchChromeEvent(
self->OwnerDoc(), self,
NS_LITERAL_STRING("UAWidgetUnbindFromTree"),
CanBubble::eYes, Cancelable::eNo);
self->UnattachShadow();
})
);
}
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
MOZ_ASSERT(IsHidden());
NotifyDecoderActivityChanges();
AsyncEventDispatcher* dispatcher =
new AsyncEventDispatcher(this,
NS_LITERAL_STRING("UAWidgetUnbindFromTree"),
CanBubble::eYes,
ChromeOnlyDispatch::eYes);
dispatcher->RunDOMEventWhenSafe();
RefPtr<HTMLMediaElement> self(this);
nsCOMPtr<nsIRunnable> task =
NS_NewRunnableFunction("dom::HTMLMediaElement::UnbindFromTree", [self]() {

View File

@ -370,7 +370,7 @@ class DecoderDoctorLogger {
// ...
template <typename T>
class DecoderDoctorLifeLogger {
public:
protected:
DecoderDoctorLifeLogger() {
DecoderDoctorLogger::LogConstruction(NonDereferenceable<const T>(this));
}

View File

@ -179,11 +179,7 @@ PresentationResponderLoadingCallback::Init(nsIDocShell* aDocShell)
return NS_ERROR_NOT_AVAILABLE;
}
uint32_t busyFlags = nsIDocShell::BUSY_FLAGS_NONE;
nsresult rv = aDocShell->GetBusyFlags(&busyFlags);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
auto busyFlags = aDocShell->GetBusyFlags();
if ((busyFlags == nsIDocShell::BUSY_FLAGS_NONE) ||
(busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING)) {

View File

@ -270,7 +270,7 @@ static bool IsImageLoadInEditorAppType(nsILoadInfo* aLoadInfo)
return false;
}
uint32_t appType = nsIDocShell::APP_TYPE_UNKNOWN;
auto appType = nsIDocShell::APP_TYPE_UNKNOWN;
nsINode* node = aLoadInfo->LoadingNode();
if (!node) {
return false;
@ -288,8 +288,8 @@ static bool IsImageLoadInEditorAppType(nsILoadInfo* aLoadInfo)
nsCOMPtr<nsIDocShellTreeItem> root;
docShellTreeItem->GetRootTreeItem(getter_AddRefs(root));
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(root));
if (!docShell || NS_FAILED(docShell->GetAppType(&appType))) {
appType = nsIDocShell::APP_TYPE_UNKNOWN;
if (docShell) {
appType = docShell->GetAppType();
}
return appType == nsIDocShell::APP_TYPE_EDITOR;

View File

@ -488,10 +488,9 @@ TextEditor::IsSafeToInsertData(nsIDocument* aSourceDoc)
dsti->GetRootTreeItem(getter_AddRefs(root));
}
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(root);
uint32_t appType;
if (docShell && NS_SUCCEEDED(docShell->GetAppType(&appType))) {
isSafe = appType == nsIDocShell::APP_TYPE_EDITOR;
}
isSafe = docShell && docShell->GetAppType() == nsIDocShell::APP_TYPE_EDITOR;
if (!isSafe && aSourceDoc) {
nsIPrincipal* srcPrincipal = aSourceDoc->NodePrincipal();
nsIPrincipal* destPrincipal = destdoc->NodePrincipal();

View File

@ -55,6 +55,9 @@ CompositorAnimationStorage::GetOMTAValue(const uint64_t& aId) const
}
switch (animatedValue->mType) {
case AnimatedValue::COLOR:
omtaValue = animatedValue->mColor;
break;
case AnimatedValue::OPACITY:
omtaValue = animatedValue->mOpacity;
break;
@ -118,6 +121,18 @@ CompositorAnimationStorage::SetAnimatedValue(uint64_t aId,
dontCare);
}
void
CompositorAnimationStorage::SetAnimatedValue(uint64_t aId, nscolor aColor)
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
auto count = mAnimatedValues.Count();
AnimatedValue* value = mAnimatedValues.LookupOrAdd(aId, aColor);
if (count == mAnimatedValues.Count()) {
MOZ_ASSERT(value->mType == AnimatedValue::COLOR);
value->mColor = aColor;
}
}
void
CompositorAnimationStorage::SetAnimatedValue(uint64_t aId,
const float& aOpacity)
@ -519,7 +534,7 @@ CreateCSSValueList(const InfallibleTArray<TransformFunction>& aFunctions)
}
static already_AddRefed<RawServoAnimationValue>
ToAnimationValue(const Animatable& aAnimatable)
ToAnimationValue(nsCSSPropertyID aProperty, const Animatable& aAnimatable)
{
RefPtr<RawServoAnimationValue> result;
@ -540,6 +555,10 @@ ToAnimationValue(const Animatable& aAnimatable)
case Animatable::Tfloat:
result = Servo_AnimationValue_Opacity(aAnimatable.get_float()).Consume();
break;
case Animatable::Tnscolor:
result = Servo_AnimationValue_Color(aProperty,
aAnimatable.get_nscolor()).Consume();
break;
default:
MOZ_ASSERT_UNREACHABLE("Unsupported type");
}
@ -580,7 +599,8 @@ AnimationHelper::SetAnimations(
}
if (animation.baseStyle().type() != Animatable::Tnull_t) {
aBaseAnimationStyle = ToAnimationValue(animation.baseStyle());
aBaseAnimationStyle = ToAnimationValue(animation.property(),
animation.baseStyle());
}
AnimData* data = aAnimData.AppendElement();
@ -605,8 +625,10 @@ AnimationHelper::SetAnimations(
const InfallibleTArray<AnimationSegment>& segments = animation.segments();
for (const AnimationSegment& segment : segments) {
startValues.AppendElement(ToAnimationValue(segment.startState()));
endValues.AppendElement(ToAnimationValue(segment.endState()));
startValues.AppendElement(ToAnimationValue(animation.property(),
segment.startState()));
endValues.AppendElement(ToAnimationValue(animation.property(),
segment.endState()));
TimingFunction tf = segment.sampleFn();
Maybe<ComputedTimingFunction> ctf =

View File

@ -55,12 +55,14 @@ struct AnimatedValue {
enum {
TRANSFORM,
OPACITY,
COLOR,
NONE
} mType {NONE};
union {
AnimationTransform mTransform;
float mOpacity;
nscolor mColor;
};
AnimatedValue(gfx::Matrix4x4&& aTransformInDevSpace,
@ -80,6 +82,12 @@ struct AnimatedValue {
{
}
explicit AnimatedValue(nscolor aValue)
: mType(AnimatedValue::COLOR)
, mColor(aValue)
{
}
~AnimatedValue() {}
private:
@ -128,6 +136,11 @@ public:
*/
void SetAnimatedValue(uint64_t aId, const float& aOpacity);
/**
* Set the animation color based on the unique id
*/
void SetAnimatedValue(uint64_t aId, nscolor aColor);
/**
* Return the animated value if a given id can map to its animated value
*/

View File

@ -633,6 +633,19 @@ ApplyAnimatedValue(Layer* aLayer,
HostLayer* layerCompositor = aLayer->AsHostLayer();
switch (aProperty) {
case eCSSProperty_background_color: {
// We don't support 'color' animations on the compositor yet so we never
// meet currentColor on the compositor.
nscolor color = Servo_AnimationValue_GetColor(aValue, NS_RGBA(0, 0, 0, 0));
aLayer->AsColorLayer()->SetColor(gfx::Color::FromABGR(color));
aStorage->SetAnimatedValue(aLayer->GetCompositorAnimationsId(), color);
layerCompositor->SetShadowOpacity(aLayer->GetOpacity());
layerCompositor->SetShadowOpacitySetByAnimation(false);
layerCompositor->SetShadowBaseTransform(aLayer->GetBaseTransform());
layerCompositor->SetShadowTransformSetByAnimation(false);
break;
}
case eCSSProperty_opacity: {
float opacity = Servo_AnimationValue_GetOpacity(aValue);
layerCompositor->SetShadowOpacity(opacity);
@ -709,19 +722,22 @@ SampleAnimations(Layer* aLayer,
}
case AnimationHelper::SampleResult::Skipped:
switch (animations[0].property()) {
case eCSSProperty_background_color:
case eCSSProperty_opacity: {
MOZ_ASSERT(
layer->AsHostLayer()->GetShadowOpacitySetByAnimation());
if (animations[0].property() == eCSSProperty_opacity) {
MOZ_ASSERT(
layer->AsHostLayer()->GetShadowOpacitySetByAnimation());
#ifdef DEBUG
// Disable this assertion until the root cause is fixed in bug
// 1459775.
// MOZ_ASSERT(FuzzyEqualsMultiplicative(
// Servo_AnimationValue_GetOpacity(animationValue),
// *(aStorage->GetAnimationOpacity(layer->GetCompositorAnimationsId()))));
// Disable this assertion until the root cause is fixed in bug
// 1459775.
// MOZ_ASSERT(FuzzyEqualsMultiplicative(
// Servo_AnimationValue_GetOpacity(animationValue),
// *(aStorage->GetAnimationOpacity(layer->GetCompositorAnimationsId()))));
#endif
// Even if opacity animation value has unchanged, we have to set
// the shadow base transform value here since the value might
// have been changed by APZC.
}
// Even if opacity or background-color animation value has
// unchanged, we have to set the shadow base transform value
// here since the value might have been changed by APZC.
HostLayer* layerCompositor = layer->AsHostLayer();
layerCompositor->SetShadowBaseTransform(
layer->GetBaseTransform());

View File

@ -19,6 +19,7 @@ using struct mozilla::gfx::Color from "mozilla/gfx/2D.h";
using struct mozilla::gfx::Point3D from "mozilla/gfx/Point.h";
using mozilla::gfx::IntPoint from "mozilla/gfx/Point.h";
using class mozilla::gfx::Matrix4x4 from "mozilla/gfx/Matrix.h";
using nscolor from "nsColor.h";
using nscoord from "nsCoord.h";
using struct nsRect from "nsRect.h";
using struct nsPoint from "nsPoint.h";
@ -160,6 +161,7 @@ union MaybeTimeDuration {
union Animatable {
null_t;
float;
nscolor;
TransformFunction[];
};
@ -565,6 +567,7 @@ union MaybeTransform {
union OMTAValue {
null_t;
nscolor;
float;
Matrix4x4;
};

View File

@ -3830,9 +3830,8 @@ nsDocumentViewer::Print(nsIPrintSettings* aPrintSettings,
// Check to see if this document is still busy
// If it is busy and we aren't already "queued" up to print then
// Indicate there is a print pending and cache the args for later
uint32_t busyFlags = nsIDocShell::BUSY_FLAGS_NONE;
if ((NS_FAILED(docShell->GetBusyFlags(&busyFlags)) ||
(busyFlags != nsIDocShell::BUSY_FLAGS_NONE && busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING)) &&
auto busyFlags = docShell->GetBusyFlags();
if (busyFlags != nsIDocShell::BUSY_FLAGS_NONE && busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING &&
!mPrintDocIsFullyLoaded) {
if (!mPrintIsPending) {
mCachedPrintSettings = aPrintSettings;

View File

@ -10347,10 +10347,10 @@ nsLayoutUtils::ComputeSystemFont(nsFont* aSystemFont, LookAndFeel::FontID aFontI
/* static */ bool
nsLayoutUtils::ShouldHandleMetaViewport(nsIDocument* aDocument)
{
uint32_t metaViewportOverride = nsIDocShell::META_VIEWPORT_OVERRIDE_NONE;
auto metaViewportOverride = nsIDocShell::META_VIEWPORT_OVERRIDE_NONE;
if (aDocument) {
if (nsIDocShell* docShell = aDocument->GetDocShell()) {
docShell->GetMetaViewportOverride(&metaViewportOverride);
metaViewportOverride = docShell->GetMetaViewportOverride();
}
}
switch (metaViewportOverride) {

View File

@ -441,6 +441,23 @@ SetAnimatable(nsCSSPropertyID aProperty,
}
switch (aProperty) {
case eCSSProperty_background_color: {
// We don't support color animation on the compositor yet so that we can
// resolve currentColor at this moment.
nscolor foreground;
if (aFrame->Style()->RelevantLinkVisited()) {
if (ComputedStyle* styleIfVisited =
aFrame->Style()->GetStyleIfVisited()) {
foreground = styleIfVisited->StyleColor()->mColor;
} else {
foreground = aFrame->Style()->StyleColor()->mColor;
}
} else {
foreground = aFrame->Style()->StyleColor()->mColor;
}
aAnimatable = aAnimationValue.GetColor(foreground);
break;
}
case eCSSProperty_opacity:
aAnimatable = aAnimationValue.GetOpacity();
break;
@ -676,7 +693,7 @@ AddAnimationsForProperty(nsIFrame* aFrame,
scaleX,
scaleY,
hasPerspectiveParent);
} else if (aProperty == eCSSProperty_opacity) {
} else {
data = null_t();
}
@ -3532,6 +3549,7 @@ nsDisplaySolidColor::GetLayerState(nsDisplayListBuilder* aBuilder,
if (ForceActiveLayers()) {
return LAYER_ACTIVE;
}
return LAYER_NONE;
}
@ -5025,6 +5043,12 @@ nsDisplayBackgroundColor::GetLayerState(
if (ForceActiveLayers() && clip != StyleGeometryBox::Text) {
return LAYER_ACTIVE;
}
if (EffectCompositor::HasAnimationsForCompositor(
mFrame, eCSSProperty_background_color)) {
return LAYER_ACTIVE_FORCE;
}
return LAYER_NONE;
}
@ -5052,6 +5076,11 @@ nsDisplayBackgroundColor::BuildLayer(
layer->SetBaseTransform(gfx::Matrix4x4::Translation(
aContainerParameters.mOffset.x, aContainerParameters.mOffset.y, 0));
nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(
layer, aBuilder,
this, mFrame,
eCSSProperty_background_color);
return layer.forget();
}
@ -8574,6 +8603,14 @@ nsDisplayTransform::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder)
return mAllowAsyncAnimation;
}
bool
nsDisplayBackgroundColor::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder)
{
LayerManager* layerManager = aBuilder->GetWidgetLayerManager();
return layerManager &&
layerManager->GetBackendType() != layers::LayersBackend::LAYERS_WR;
}
/* static */ auto
nsDisplayTransform::ShouldPrerenderTransformedContent(
nsDisplayListBuilder* aBuilder,

View File

@ -5074,6 +5074,8 @@ public:
void WriteDebugInfo(std::stringstream& aStream) override;
bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) override;
protected:
const nsRect mBackgroundRect;
RefPtr<mozilla::ComputedStyle> mBackgroundStyle;

View File

@ -1049,9 +1049,8 @@ nsPrintJob::PrintPreview(nsIPrintSettings* aPrintSettings,
nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
NS_ENSURE_STATE(docShell);
uint32_t busyFlags = nsIDocShell::BUSY_FLAGS_NONE;
if (NS_FAILED(docShell->GetBusyFlags(&busyFlags)) ||
busyFlags != nsIDocShell::BUSY_FLAGS_NONE) {
auto busyFlags = docShell->GetBusyFlags();
if (busyFlags != nsIDocShell::BUSY_FLAGS_NONE) {
CloseProgressDialog(aWebProgressListener);
FirePrintingErrorEvent(NS_ERROR_GFX_PRINTER_DOC_IS_BUSY);
return NS_ERROR_FAILURE;

View File

@ -6,11 +6,13 @@ div {
height: 100px;
background-color: blue;
}
span {
#child {
background-color: green;
width: 50px;
height: 50px;
}
</style>
<div>
<span>child</span>
<div id="child"></div>
</div>
</html>

View File

@ -9,12 +9,14 @@ Child element in animating element that display property is changed from none
width: 100px;
height: 100px;
}
span {
#child {
background-color: green;
width: 50px;
height: 50px;
}
</style>
<div id="test">
<span>child</span>
<div id="child"></div>
</div>
<script>
var anim = test.animate({ backgroundColor: [ 'blue', 'blue' ] },

View File

@ -14,6 +14,7 @@ namespace mozilla {
/* static */ const Array<DisplayItemType,
nsCSSPropertyIDSet::CompositorAnimatableCount()>
LayerAnimationInfo::sDisplayItemTypes = {
DisplayItemType::TYPE_BACKGROUND_COLOR,
DisplayItemType::TYPE_OPACITY,
DisplayItemType::TYPE_TRANSFORM,
};
@ -22,6 +23,8 @@ namespace mozilla {
LayerAnimationInfo::GetDisplayItemTypeForProperty(nsCSSPropertyID aProperty)
{
switch (aProperty) {
case eCSSProperty_background_color:
return DisplayItemType::TYPE_BACKGROUND_COLOR;
case eCSSProperty_opacity:
return DisplayItemType::TYPE_OPACITY;
case eCSSProperty_transform:

View File

@ -34,9 +34,13 @@ struct LayerAnimationInfo {
nsCSSPropertyIDSet{ eCSSProperty_transform };
static const nsCSSPropertyIDSet opacityProperties =
nsCSSPropertyIDSet{ eCSSProperty_opacity };
static const nsCSSPropertyIDSet backgroundColorProperties =
nsCSSPropertyIDSet{ eCSSProperty_background_color };
static const nsCSSPropertyIDSet empty = nsCSSPropertyIDSet();
switch (aDisplayItemType) {
case DisplayItemType::TYPE_BACKGROUND_COLOR:
return backgroundColorProperties;
case DisplayItemType::TYPE_OPACITY:
return opacityProperties;
case DisplayItemType::TYPE_TRANSFORM:
@ -58,6 +62,8 @@ struct LayerAnimationInfo {
GetChangeHintFor(DisplayItemType aDisplayItemType)
{
switch (aDisplayItemType) {
case DisplayItemType::TYPE_BACKGROUND_COLOR:
return nsChangeHint_RepaintFrame;
case DisplayItemType::TYPE_OPACITY:
return nsChangeHint_UpdateOpacityLayer;
case DisplayItemType::TYPE_TRANSFORM:

View File

@ -676,6 +676,11 @@ void Servo_AnimationValue_Serialize(
nsCSSPropertyID property,
nsAString* buffer);
nscolor Servo_AnimationValue_GetColor(RawServoAnimationValueBorrowed value,
nscolor foregroundColor);
RawServoAnimationValueStrong Servo_AnimationValue_Color(nsCSSPropertyID,
nscolor);
float Servo_AnimationValue_GetOpacity(RawServoAnimationValueBorrowed value);
RawServoAnimationValueStrong Servo_AnimationValue_Opacity(float);

View File

@ -120,6 +120,13 @@ AnimationValue::GetOpacity() const
return Servo_AnimationValue_GetOpacity(mServo);
}
nscolor
AnimationValue::GetColor(nscolor aForegroundColor) const
{
MOZ_ASSERT(mServo);
return Servo_AnimationValue_GetColor(mServo, aForegroundColor);
}
already_AddRefed<const nsCSSValueSharedList>
AnimationValue::GetTransformList() const
{

View File

@ -78,6 +78,10 @@ struct AnimationValue
float GetOpacity() const;
// Returns nscolor value in this AnimationValue.
// Currently only background-color is supported.
nscolor GetColor(nscolor aForegroundColor) const;
// Return the transform list as a RefPtr.
already_AddRefed<const nsCSSValueSharedList> GetTransformList() const;

View File

@ -1117,7 +1117,7 @@ nsComputedDOMStyle::DoGetBottom()
return GetOffsetWidthFor(eSideBottom);
}
void
/* static */ void
nsComputedDOMStyle::SetToRGBAColor(nsROCSSPrimitiveValue* aValue,
nscolor aColor)
{

View File

@ -131,6 +131,7 @@ public:
static already_AddRefed<nsROCSSPrimitiveValue>
MatrixToCSSValue(const mozilla::gfx::Matrix4x4& aMatrix);
static void SetToRGBAColor(nsROCSSPrimitiveValue* aValue, nscolor aColor);
static void RegisterPrefChangeCallbacks();
static void UnregisterPrefChangeCallbacks();
@ -428,7 +429,6 @@ private:
already_AddRefed<CSSValue> DummyGetter();
/* Helper functions */
void SetToRGBAColor(nsROCSSPrimitiveValue* aValue, nscolor aColor);
void SetValueFromComplexColor(nsROCSSPrimitiveValue* aValue,
const mozilla::StyleComplexColor& aColor);
void SetValueToPositionCoord(const mozilla::Position::Coord& aCoord,

View File

@ -422,19 +422,30 @@ const ExpectComparisonTo = {
runningOn, desc, expectedComparisonResult,
pseudo) {
// Check input
const omtaProperties = [ "transform", "opacity" ];
// FIXME: Auto generate this array.
const omtaProperties = [ "transform", "opacity", "background-color" ];
if (!omtaProperties.includes(property)) {
ok(false, property + " is not an OMTA property");
return;
}
var isTransform = property == "transform";
var normalize = isTransform ? convertTo3dMatrix : parseFloat;
var compare = isTransform ?
matricesRoughlyEqual :
function(a, b, error) { return Math.abs(a - b) <= error; };
var normalizedToString = isTransform ?
convert3dMatrixToString :
JSON.stringify;
var normalize;
var compare;
var normalizedToString = JSON.stringify;
switch (property) {
case "transform":
normalize = convertTo3dMatrix;
compare = matricesRoughlyEqual;
normalizedToString = convert3dMatrixToString;
break;
case "opacity":
normalize = parseFloat;
compare = function(a, b, error) { return Math.abs(a - b) <= error; };
break;
default:
normalize = function(value) { return value; };
compare = function(a, b, error) { return a == b; };
break;
}
// Get actual values
var compositorStr =

View File

@ -5,6 +5,7 @@ prefs =
dom.animations-api.getAnimations.enabled=true
dom.animations-api.implicit-keyframes.enabled=true
dom.animations-api.timelines.enabled=true
gfx.omta.background-color=true
layout.css.step-position-jump.enabled=true
support-files =
animation_utils.js

View File

@ -2391,5 +2391,122 @@ addAsyncAnimTest(async function() {
done_div();
});
if (SpecialPowers.DOMWindowUtils.layerManagerType != 'WebRender') {
// Normal background-color animation.
addAsyncAnimTest(async function() {
new_div("background-color: rgb(255, 0, 0); " +
"transition: background-color 10s linear");
await waitForPaintsFlushed();
gDiv.style.backgroundColor = "rgb(0, 255, 0)";
await waitForPaintsFlushed();
omta_is("background-color", "rgb(255, 0, 0)", RunningOn.Compositor,
"background-color transition runs on compositor thread");
advance_clock(5000);
omta_is("background-color", "rgb(128, 128, 0)", RunningOn.Compositor,
"background-color on compositor at 5s");
done_div();
});
// background-color animation with currentColor.
addAsyncAnimTest(async function() {
new_div("color: rgb(255, 0, 0); " +
"background-color: currentColor; " +
"transition: background-color 10s linear");
await waitForPaintsFlushed();
gDiv.style.backgroundColor = "rgb(0, 255, 0)";
await waitForPaintsFlushed();
omta_is("background-color", "rgb(255, 0, 0)", RunningOn.Compositor,
"background-color transition starting with current-color runs on " +
"compositor thread");
advance_clock(5000);
omta_is("background-color", "rgb(128, 128, 0)", RunningOn.Compositor,
"background-color on compositor at 5s");
done_div();
});
// Tests that a background-color animation from inherited currentColor to
// a normal color on the compositor is updated when the parent color is
// changed.
addAsyncAnimTest(async function() {
new_div("");
const parent = document.createElement("div");
gDiv.parentNode.insertBefore(parent, gDiv);
parent.style.color = "rgb(255, 0, 0)";
parent.appendChild(gDiv);
gDiv.animate({ backgroundColor: [ "currentColor", "rgb(0, 255, 0)" ] }, 1000);
await waitForPaintsFlushed();
omta_is("background-color", "rgb(255, 0, 0)", RunningOn.Compositor,
"background-color animation starting with current-color runs on " +
"compositor thread");
advance_clock(500);
omta_is("background-color", "rgb(128, 128, 0)", RunningOn.Compositor,
"background-color on compositor at 5s");
// Change the parent's color in the middle of the animation.
parent.style.color = "rgb(0, 0, 255)";
await waitForPaintsFlushed();
omta_is("background-color", "rgb(0, 128, 128)", RunningOn.Compositor,
"background-color on compositor is reflected by the parent's " +
"color change");
done_div();
parent.remove();
});
// Tests that a background-color animation from currentColor to a normal color
// on <a> element is updated when the link is visited.
addAsyncAnimTest(async function() {
[ gDiv ] = new_element("a", "display: block");
gDiv.setAttribute("href", "not-exist.html");
gDiv.classList.add("visited");
const extraStyle = document.createElement('style');
document.head.appendChild(extraStyle);
extraStyle.sheet.insertRule(".visited:visited { color: rgb(0, 0, 255); }", 0);
extraStyle.sheet.insertRule(".visited:link { color: rgb(255, 0, 0); }", 1);
gDiv.animate({ backgroundColor: [ "currentColor", "rgb(0, 255, 0)" ] }, 1000);
await waitForPaintsFlushed();
omta_is("background-color", "rgb(255, 0, 0)", RunningOn.Compositor,
"background-color animation starting with current-color runs on " +
"compositor thread");
advance_clock(500);
omta_is("background-color", "rgb(128, 128, 0)", RunningOn.Compositor,
"background-color on compositor at 5s");
gDiv.setAttribute("href", window.top.location.href);
await waitForVisitedLinkColoring(gDiv, "color", "rgb(0, 0, 255)");
await waitForPaintsFlushed();
// `omta_is` checks that the result on the compositor equals to the value by
// getComputedValue() but getComputedValue lies for visited link values so
// we use getOMTAStyle directly instead.
is(SpecialPowers.DOMWindowUtils.getOMTAStyle(gDiv, "background-color"),
"rgb(0, 128, 128)",
"background-color on <a> element after the link is visited");
extraStyle.remove();
done_element();
gDiv = null;
});
}
</script>
</html>

View File

@ -516,6 +516,18 @@ VARCACHE_PREF(
RelaxedAtomicBool, false
)
#ifdef RELEASE_OR_BETA
# define PREF_VALUE false
#else
# define PREF_VALUE true
#endif
VARCACHE_PREF(
"gfx.omta.background-color",
gfx_omta_background_color,
bool, PREF_VALUE
)
#undef PREF_VALUE
//---------------------------------------------------------------------------
// HTML5 parser prefs
//---------------------------------------------------------------------------

View File

@ -15,7 +15,8 @@ ${helpers.predefined_type(
animation_value_type="AnimatedColor",
ignored_when_colors_disabled=True,
allow_quirks=True,
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER \
CAN_ANIMATE_ON_COMPOSITOR",
)}
${helpers.predefined_type(

View File

@ -797,6 +797,27 @@ pub extern "C" fn Servo_AnimationValue_Serialize(
debug_assert!(rv.is_ok());
}
#[no_mangle]
pub extern "C" fn Servo_AnimationValue_GetColor(
value: RawServoAnimationValueBorrowed,
foreground_color: structs::nscolor,
) -> structs::nscolor {
use style::gecko::values::convert_nscolor_to_rgba;
use style::gecko::values::convert_rgba_to_nscolor;
use style::values::animated::ToAnimatedValue;
use style::values::computed::color::Color as ComputedColor;
let value = AnimationValue::as_arc(&value);
match **value {
AnimationValue::BackgroundColor(color) => {
let computed: ComputedColor = ToAnimatedValue::from_animated_value(color);
let foreground_color = convert_nscolor_to_rgba(foreground_color);
convert_rgba_to_nscolor(&computed.to_rgba(foreground_color))
}
_ => panic!("Other color properties are not supported yet"),
}
}
#[no_mangle]
pub extern "C" fn Servo_AnimationValue_GetOpacity(value: RawServoAnimationValueBorrowed) -> f32 {
let value = AnimationValue::as_arc(&value);
@ -812,6 +833,30 @@ pub extern "C" fn Servo_AnimationValue_Opacity(opacity: f32) -> RawServoAnimatio
Arc::new(AnimationValue::Opacity(opacity)).into_strong()
}
#[no_mangle]
pub extern "C" fn Servo_AnimationValue_Color(
color_property: nsCSSPropertyID,
color: structs::nscolor
) -> RawServoAnimationValueStrong {
use style::gecko::values::convert_nscolor_to_rgba;
use style::values::animated::color::RGBA as AnimatedRGBA;
let property = LonghandId::from_nscsspropertyid(color_property)
.expect("We don't have shorthand property animation value");
let rgba = convert_nscolor_to_rgba(color);
let animatedRGBA = AnimatedRGBA::new(rgba.red_f32(),
rgba.green_f32(),
rgba.blue_f32(),
rgba.alpha_f32());
match property {
LonghandId::BackgroundColor =>
Arc::new(AnimationValue::BackgroundColor(animatedRGBA.into())).into_strong(),
_ => panic!("Should be background-color property"),
}
}
#[no_mangle]
pub extern "C" fn Servo_AnimationValue_GetTransform(
value: RawServoAnimationValueBorrowed,

View File

@ -63,6 +63,7 @@ jobs:
- deb7-gtk3
- deb7-harfbuzz
- deb7-libxkbcommon
- deb7-nasm
- deb7-pango
- deb7-pcre3
- deb7-valgrind
@ -88,6 +89,7 @@ jobs:
- deb7-glib
- deb7-gtk3
- deb7-harfbuzz
- deb7-nasm
- deb7-python-defaults
- deb7-pcre3
- deb7-valgrind

View File

@ -32,6 +32,7 @@ RUN apt-get update && \
gawk \
gcc-multilib \
gnupg \
nasm \
p7zip-full \
procps \
python-pip \

View File

@ -127,8 +127,9 @@ nsWebBrowserFind::FindNext(bool* aResult)
return NS_ERROR_FAILURE;
}
int32_t enumDirection = mFindBackwards ? nsIDocShell::ENUMERATE_BACKWARDS :
nsIDocShell::ENUMERATE_FORWARDS;
auto enumDirection =
mFindBackwards ? nsIDocShell::ENUMERATE_BACKWARDS :
nsIDocShell::ENUMERATE_FORWARDS;
nsCOMPtr<nsISimpleEnumerator> docShellEnumerator;
rv = rootDocShell->GetDocShellEnumerator(nsIDocShellTreeItem::typeAll,

View File

@ -25,37 +25,28 @@ support-files =
videomask.css
[test_audiocontrols_dimensions.html]
skip-if = toolkit == 'android' # Bug 1483656
[test_mousecapture_area.html]
skip-if = (verify && debug) || toolkit == 'android' # Bug 1483656 (android)
[test_ua_widget.html]
skip-if = toolkit == 'android' # Bug 1483656
skip-if = (verify && debug)
[test_ua_widget_sandbox.html]
[test_ua_widget_unbind.html]
[test_videocontrols.html]
tags = fullscreen
skip-if = toolkit == 'android' || (verify && debug && (os == 'linux')) #TIMED_OUT
[test_videocontrols_keyhandler.html]
skip-if = (toolkit == 'android') || (os == 'linux') #Bug 1366957
[test_videocontrols_vtt.html]
skip-if = toolkit == 'android' # Bug 1483656
[test_videocontrols_iframe_fullscreen.html]
skip-if = toolkit == 'android' # Bug 1483656
[test_videocontrols_size.html]
skip-if = toolkit == 'android' # Bug 1483656
[test_videocontrols_audio.html]
skip-if = toolkit == 'android' # Bug 1483656
[test_videocontrols_audio_direction.html]
skip-if = toolkit == 'android' # Bug 1483656
[test_videocontrols_jsdisabled.html]
skip-if = toolkit == 'android' # bug 1272646 & bug 1483656
skip-if = toolkit == 'android' # bug 1272646
[test_videocontrols_standalone.html]
skip-if = toolkit == 'android' # bug 1075573 & bug 1483656
skip-if = toolkit == 'android' # bug 1075573
[test_videocontrols_video_direction.html]
skip-if = os == 'win' || toolkit == 'android' # Bug 1483656 (android)
skip-if = os == 'win'
[test_videocontrols_video_noaudio.html]
skip-if = toolkit == 'android' # Bug 1483656
[test_bug898940.html]
skip-if = toolkit == 'android' # Bug 1483656
[test_videocontrols_error.html]
skip-if = toolkit == 'android' # Bug 1483656
[test_videocontrols_orientation.html]
skip-if = true # Bug 1483656

View File

@ -1,7 +1,7 @@
<!DOCTYPE HTML>
<html>
<head>
<title>UA Widget test</title>
<title>UA Widget sandbox test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>

View File

@ -0,0 +1,57 @@
<!DOCTYPE HTML>
<html>
<head>
<title>UA Widget unbind test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
<script type="text/javascript" src="head.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content">
</div>
<pre id="test">
<script class="testbody">
const content = document.getElementById("content");
add_task(function() {
const video = document.createElement("video");
video.controls = true;
ok(!SpecialPowers.wrap(video).openOrClosedShadowRoot, "UA Widget Shadow Root is not created");
content.appendChild(video);
ok(!!SpecialPowers.wrap(video).openOrClosedShadowRoot, "UA Widget Shadow Root is created");
ok(!!SpecialPowers.wrap(video).openOrClosedShadowRoot.firstChild, "Widget is constructed");
content.removeChild(video);
ok(!SpecialPowers.wrap(video).openOrClosedShadowRoot, "UA Widget Shadow Root is removed");
});
add_task(function() {
const marquee = document.createElement("marquee");
ok(!SpecialPowers.wrap(marquee).openOrClosedShadowRoot, "UA Widget Shadow Root is not created");
content.appendChild(marquee);
ok(!!SpecialPowers.wrap(marquee).openOrClosedShadowRoot, "UA Widget Shadow Root is created");
ok(!!SpecialPowers.wrap(marquee).openOrClosedShadowRoot.firstChild, "Widget is constructed");
content.removeChild(marquee);
ok(SpecialPowers.wrap(marquee).openOrClosedShadowRoot, "UA Widget Shadow Root is not removed for marquee");
});
add_task(function() {
const input = document.createElement("input");
input.type = "date";
ok(!SpecialPowers.wrap(input).openOrClosedShadowRoot, "UA Widget Shadow Root is not created");
content.appendChild(input);
ok(!!SpecialPowers.wrap(input).openOrClosedShadowRoot, "UA Widget Shadow Root is created");
ok(!!SpecialPowers.wrap(input).openOrClosedShadowRoot.firstChild, "Widget is constructed");
content.removeChild(input);
ok(!SpecialPowers.wrap(input).openOrClosedShadowRoot, "UA Widget Shadow Root is removed");
});
</script>
</pre>
</body>
</html>

View File

@ -394,7 +394,7 @@ SetArgv0ToFullBinaryPath(wchar_t* aArgv[])
#endif // defined(XP_WIN)
// Save literal putenv string to environment variable.
inline void
MOZ_NEVER_INLINE inline void
SaveToEnv(const char *aEnvString)
{
#if defined(MOZILLA_INTERNAL_API)

View File

@ -319,7 +319,7 @@ using mozilla::dom::ContentChild;
using mozilla::intl::LocaleService;
// Save the given word to the specified environment variable.
static void
static void MOZ_NEVER_INLINE
SaveWordToEnv(const char *name, const nsACString & word)
{
char *expr = Smprintf("%s=%s", name, PromiseFlatCString(word).get()).release();