Merge mozilla-central to inbound

--HG--
rename : mobile/android/geckoview/src/main/aidl/org/mozilla/gecko/gfx/ISurfaceAllocator.aidl => mobile/android/geckoview/src/main/aidl/org/mozilla/gecko/gfx/SyncConfig.aidl
extra : rebase_source : a7f6628299f30b300a02932debe0cc92810f901d
This commit is contained in:
arthur.iakab 2018-12-18 00:04:04 +02:00
Родитель 32bb40cfd8 e67010fdec
Коммит e14d71a660
105 изменённых файлов: 3063 добавлений и 2583 удалений

Просмотреть файл

@ -215,7 +215,6 @@ dom/security/test/csp/**
dom/security/test/general/**
dom/security/test/mixedcontentblocker/**
dom/security/test/sri/**
dom/security/test/unit/**
dom/serviceworkers/**
dom/smil/**
dom/svg/**

Просмотреть файл

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<blocklist lastupdate="1544544484935" xmlns="http://www.mozilla.org/2006/addons-blocklist">
<blocklist lastupdate="1544811398633" xmlns="http://www.mozilla.org/2006/addons-blocklist">
<emItems>
<emItem blockID="i334" id="{0F827075-B026-42F3-885D-98981EE7B1AE}">
<prefs/>

Просмотреть файл

@ -5084,6 +5084,9 @@ class TabProgressListener {
if (topLevel) {
let isSameDocument = !!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT);
let isReload = !!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_RELOAD);
let isErrorPage = !!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE);
// We need to clear the typed value
// if the document failed to load, to make sure the urlbar reflects the
// failed URI (particularly for SSL errors). However, don't clear the value
@ -5094,8 +5097,7 @@ class TabProgressListener {
// Finally, we do insert the URL if this is a same-document navigation
// and the user cleared the URL manually.
if (this.mBrowser.didStartLoadSinceLastUserTyping() ||
((aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) &&
aLocation.spec != "about:blank") ||
(isErrorPage && aLocation.spec != "about:blank") ||
(isSameDocument && this.mBrowser.inLoadURI) ||
(isSameDocument && !this.mBrowser.userTypedValue)) {
this.mBrowser.userTypedValue = null;
@ -5107,8 +5109,7 @@ class TabProgressListener {
// isn't any (STATE_IS_NETWORK & STATE_STOP) state to cause busy
// attribute being removed. In this case we should remove the
// attribute here.
if ((aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) &&
this.mTab.hasAttribute("busy")) {
if (isErrorPage && this.mTab.hasAttribute("busy")) {
this.mTab.removeAttribute("busy");
gBrowser._tabAttrModified(this.mTab, ["busy"]);
}
@ -5135,7 +5136,9 @@ class TabProgressListener {
}
}
gBrowser.setTabTitle(this.mTab);
if (!isReload) {
gBrowser.setTabTitle(this.mTab);
}
// Don't clear the favicon if this tab is in the pending
// state, as SessionStore will have set the icon for us even

Просмотреть файл

@ -68,6 +68,7 @@ skip-if = (verify && (os == 'win' || os == 'mac'))
[browser_preloadedBrowser_zoom.js]
[browser_reload_deleted_file.js]
skip-if = (debug && os == 'mac') || (debug && os == 'linux' && bits == 64) #Bug 1421183, disabled on Linux/OSX for leaked windows
[browser_tab_label_during_reload.js]
[browser_tabCloseProbes.js]
[browser_tabContextMenu_keyboard.js]
[browser_tabReorder_overflow.js]

Просмотреть файл

@ -0,0 +1,30 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(async function() {
let tab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:preferences");
let browser = tab.linkedBrowser;
let labelChanges = 0;
let attrModifiedListener = event => {
if (event.detail.changed.includes("label")) {
labelChanges++;
}
};
tab.addEventListener("TabAttrModified", attrModifiedListener);
await BrowserTestUtils.browserLoaded(browser);
is(labelChanges, 1, "number of label changes during initial load");
isnot(tab.label, "", "about:preferences tab label isn't empty");
isnot(tab.label, "about:preferences", "about:preferences tab label isn't the URI");
is(tab.label, browser.contentTitle, "about:preferences tab label matches browser.contentTitle");
labelChanges = 0;
browser.reload();
await BrowserTestUtils.browserLoaded(browser);
is(labelChanges, 0, "number of label changes during reload");
tab.removeEventListener("TabAttrModified", attrModifiedListener);
gBrowser.removeTab(tab);
});

Просмотреть файл

@ -617,7 +617,7 @@ class UrlbarInput {
} else {
where = this.window.whereToOpenLink(event, false, false);
}
if (this.openInTab) {
if (UrlbarPrefs.get("openintab")) {
if (where == "current") {
where = "tab";
} else if (where == "tab") {

Просмотреть файл

@ -87,6 +87,10 @@ const PREF_URLBAR_DEFAULTS = new Map([
// The maximum number of results in the urlbar popup.
["maxRichResults", 10],
// Whether addresses and search results typed into the address bar
// should be opened in new tabs by default.
["openintab", false],
// Results will include the user's bookmarks when this is true.
["suggest.bookmark", true],

Просмотреть файл

@ -53,6 +53,7 @@ class FlexItemSizingOutline extends PureComponent {
flexItemSizing,
} = this.props.flexItem;
const {
mainAxisDirection,
mainBaseSize,
mainDeltaSize,
mainMaxSize,
@ -60,8 +61,6 @@ class FlexItemSizingOutline extends PureComponent {
clampState,
} = flexItemSizing;
const isRow = this.props.flexDirection.startsWith("row");
// Calculate the final size. This is base + delta, then clamped by min or max.
let mainFinalSize = mainBaseSize + mainDeltaSize;
mainFinalSize = Math.max(mainFinalSize, mainMinSize);
@ -142,9 +141,8 @@ class FlexItemSizingOutline extends PureComponent {
dom.div({ className: "flex-outline-container" },
dom.div(
{
className: "flex-outline" +
(isRow ? " row" : " column") +
(mainDeltaSize > 0 ? " growing" : " shrinking"),
className: `flex-outline ${mainAxisDirection}` +
(mainDeltaSize > 0 ? " growing" : " shrinking"),
style: {
gridTemplateColumns,
},

Просмотреть файл

@ -37,6 +37,7 @@ support-files =
[browser_flexbox_item_outline_hidden_when_useless.js]
[browser_flexbox_item_outline_renders_basisfinal_points_correctly.js]
[browser_flexbox_item_outline_rotates_for_column.js]
[browser_flexbox_item_outline_rotates_for_different_writing_modes.js]
[browser_flexbox_non_flex_item_is_not_shown.js]
[browser_flexbox_pseudo_elements_are_listed.js]
[browser_flexbox_sizing_flexibility_not_displayed_when_useless.js]

Просмотреть файл

@ -19,7 +19,8 @@ add_task(async function() {
await selectNode(".container .item", inspector);
let [flexOutline] = await onFlexItemOutlineRendered;
ok(flexOutline.classList.contains("row"), "The flex outline has the row class");
ok(flexOutline.classList.contains("horizontal-lr"),
"The flex outline has the horizontal-lr class");
// Check that the outline is wider than it is tall in the configuration.
let bounds = flexOutline.getBoxQuads()[0].getBounds();
@ -30,10 +31,10 @@ add_task(async function() {
".flex-outline-container .flex-outline");
await selectNode(".container.column .item", inspector);
await waitUntil(() => {
flexOutline = doc.querySelector(".flex-outline-container .flex-outline.column");
flexOutline = doc.querySelector(".flex-outline-container .flex-outline.vertical-tb");
return flexOutline;
});
ok(true, "The flex outline has the column class");
ok(true, "The flex outline has the vertical-tb class");
// Check that the outline is taller than it is wide in the configuration.
bounds = flexOutline.getBoxQuads()[0].getBounds();

Просмотреть файл

@ -0,0 +1,36 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the flex item outline is rotated to match its main axis direction.
const TEST_URI = URL_ROOT + "doc_flexbox_writing_modes.html";
add_task(async function() {
await addTab(TEST_URI);
const { inspector, flexboxInspector } = await openLayoutView();
const { document: doc } = flexboxInspector;
info("Check that a vertical row flex item rotates to vertical-tb.");
let onFlexItemOutlineRendered = waitForDOM(doc,
".flex-outline-container .flex-outline");
await selectNode(".row.vertical.item", inspector);
let [flexOutline] = await onFlexItemOutlineRendered;
ok(flexOutline.classList.contains("vertical-tb"),
"Horizontal item outline orientation has been rotated to vertical-tb.");
info("Check that a vertical-rl column flex item rotates to horizontal-rl.");
onFlexItemOutlineRendered = waitForDOM(doc,
".flex-outline-container .flex-outline");
await selectNode(".column.vertical.item", inspector);
await waitUntil(() => {
flexOutline =
doc.querySelector(".flex-outline-container .flex-outline.horizontal-rl");
return flexOutline;
});
ok(true, "Vertical-rl item outline orientation has been rotated to horizontal-rl.");
});

Просмотреть файл

@ -6,7 +6,7 @@
}
.flex-container.vertical-writing-mode {
writing-mode: vertical-lr;
writing-mode: vertical-rl;
}
.column {

Просмотреть файл

@ -135,6 +135,7 @@ skip-if = (verify && debug && os == 'win')
[browser_rules_edit-property_07.js]
[browser_rules_edit-property_08.js]
[browser_rules_edit-property_09.js]
[browser_rules_edit-property_10.js]
[browser_rules_edit-selector-click.js]
[browser_rules_edit-selector-click-on-scrollbar.js]
skip-if = os == "mac" # Bug 1245996 : click on scrollbar not working on OSX

Просмотреть файл

@ -0,0 +1,46 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that CSS property names are case insensitive when validating.
const TEST_URI = `
<style type='text/css'>
div {
color: red;
}
</style>
<div></div>
`;
add_task(async function() {
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
const { inspector, view: ruleView } = await openRuleView();
await selectNode("div", inspector);
const rule = getRuleViewRuleEditor(ruleView, 1).rule;
const prop = rule.textProps[0];
let onRuleViewChanged;
info(`Rename the CSS property name to "Color"`);
onRuleViewChanged = ruleView.once("ruleview-changed");
await renameProperty(ruleView, prop, "Color");
info("Wait for Rule view to update");
await onRuleViewChanged;
is(prop.overridden, false, "Titlecase property is not overriden");
is(prop.enabled, true, "Titlecase property is enabled");
is(prop.isNameValid(), true, "Titlecase property is valid");
info(`Rename the CSS property name to "COLOR"`);
onRuleViewChanged = ruleView.once("ruleview-changed");
await renameProperty(ruleView, prop, "COLOR");
info("Wait for Rule view to update");
await onRuleViewChanged;
is(prop.overridden, false, "Uppercase property is not overriden");
is(prop.enabled, true, "Uppercase property is enabled");
is(prop.isNameValid(), true, "Uppercase property is valid");
});

Просмотреть файл

@ -661,7 +661,7 @@ const ObjectWithURL = __webpack_require__(1853);
const GripArray = __webpack_require__(1797);
const GripMap = __webpack_require__(1799);
const GripMapEntry = __webpack_require__(1800);
const Grip = __webpack_require__(1784);
const Grip = __webpack_require__(1783);
// List of all registered template.
// XXX there should be a way for extensions to register a new
@ -796,7 +796,8 @@ StringRep.propTypes = {
member: PropTypes.object,
object: PropTypes.object.isRequired,
openLink: PropTypes.func,
className: PropTypes.string
className: PropTypes.string,
title: PropTypes.string
};
function StringRep(props) {
@ -808,7 +809,8 @@ function StringRep(props) {
useQuotes = true,
escapeWhitespace = true,
member,
openLink
openLink,
title
} = props;
let text = object;
@ -837,7 +839,8 @@ function StringRep(props) {
const config = getElementConfig({
className,
style,
actor: object.actor
actor: object.actor,
title
});
if (!isLong) {
@ -877,7 +880,7 @@ function formatText(opts, text) {
}
function getElementConfig(opts) {
const { className, style, actor } = opts;
const { className, style, actor, title } = opts;
const config = {};
@ -885,6 +888,10 @@ function getElementConfig(opts) {
config["data-link-actor-id"] = actor;
}
if (title) {
config.title = title;
}
const classNames = ["objectBox", "objectBox-string"];
if (className) {
classNames.push(className);
@ -1036,8 +1043,6 @@ module.exports = {
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
/* 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/>. */
@ -1107,13 +1112,17 @@ function arrayIterator(props, array, max) {
let item;
try {
item = ItemRep(_extends({}, props, config, {
item = ItemRep({
...props,
...config,
object: array[i]
}));
});
} catch (exc) {
item = ItemRep(_extends({}, props, config, {
item = ItemRep({
...props,
...config,
object: exc
}));
});
}
items.push(item);
}
@ -1141,10 +1150,11 @@ function ItemRep(props) {
const { Rep } = __webpack_require__(1767);
const { object, delim, mode } = props;
return span({}, Rep(_extends({}, props, {
return span({}, Rep({
...props,
object: object,
mode: mode
})), delim);
}), delim);
}
function getLength(object) {
@ -1176,8 +1186,6 @@ module.exports = {
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
/* 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/>. */
@ -1218,7 +1226,7 @@ PropRep.propTypes = {
* @return {Array} Array of React elements.
*/
function PropRep(props) {
const Grip = __webpack_require__(1784);
const Grip = __webpack_require__(1783);
const { Rep } = __webpack_require__(1767);
let { name, mode, equal, suppressQuotes } = props;
@ -1232,17 +1240,18 @@ function PropRep(props) {
}
key = span({ className: "nodeName" }, name);
} else {
key = Rep(_extends({}, props, {
key = Rep({
...props,
className: "nodeName",
object: name,
mode: mode || MODE.TINY,
defaultRep: Grip
}));
});
}
return [key, span({
className: "objectEqual"
}, equal), Rep(_extends({}, props))];
}, equal), Rep({ ...props })];
}
// Exports from this module
@ -1284,14 +1293,12 @@ module.exports = {
/***/ }),
/***/ 1784:
/***/ 1783:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
/* 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/>. */
@ -1419,7 +1426,7 @@ function propIterator(props, object, max) {
const propertiesLength = getPropertiesLength(object);
if (object.preview && object.preview.safeGetterValues) {
properties = _extends({}, properties, object.preview.safeGetterValues);
properties = { ...properties, ...object.preview.safeGetterValues };
}
let indexes = getPropIndexes(properties, max, isInterestingProp);
@ -1444,7 +1451,8 @@ function propIterator(props, object, max) {
const length = max - indexes.length;
const symbolsProps = ownSymbols.slice(0, length).map(symbolItem => {
return PropRep(_extends({}, props, {
return PropRep({
...props,
mode: MODE.TINY,
name: symbolItem,
object: symbolItem.descriptor.value,
@ -1452,7 +1460,7 @@ function propIterator(props, object, max) {
defaultRep: Grip,
title: null,
suppressQuotes
}));
});
});
propsArray.push(...symbolsProps);
@ -1494,7 +1502,8 @@ function getProps(componentProps, properties, indexes, suppressQuotes) {
const name = propertiesKeys[i];
const value = getPropValue(properties[name]);
return PropRep(_extends({}, componentProps, {
return PropRep({
...componentProps,
mode: MODE.TINY,
name,
object: value,
@ -1502,7 +1511,7 @@ function getProps(componentProps, properties, indexes, suppressQuotes) {
defaultRep: Grip,
title: null,
suppressQuotes
}));
});
});
}
@ -1589,14 +1598,12 @@ module.exports = Grip;
/***/ }),
/***/ 1785:
/***/ 1784:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
/* 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/>. */
@ -2079,7 +2086,7 @@ function makeNodesForProperties(objProps, parent) {
const parentValue = getValue(parent);
const allProperties = _extends({}, ownProperties, safeGetterValues);
const allProperties = { ...ownProperties, ...safeGetterValues };
// Ignore properties that are neither non-concrete nor getters/setters.
const propertiesNames = sortProperties(Object.keys(allProperties)).filter(name => {
@ -2230,9 +2237,10 @@ function getEvaluatedItem(item, evaluations) {
return item;
}
return _extends({}, item, {
return {
...item,
contents: evaluations.get(item.path)
});
};
}
function getChildrenWithEvaluations(options) {
@ -2394,20 +2402,6 @@ function getNonPrototypeParentGripValue(item) {
return getValue(parentGripNode);
}
function getParentGripValue(item) {
const parentNode = getParent(item);
if (!parentNode) {
return null;
}
const parentGripNode = getClosestGripNode(parentNode);
if (!parentGripNode) {
return null;
}
return getValue(parentGripNode);
}
module.exports = {
createNode,
createGetterNode,
@ -2418,7 +2412,6 @@ module.exports = {
getClosestGripNode,
getClosestNonBucketNode,
getParent,
getParentGripValue,
getNonPrototypeParentGripValue,
getNumericalPropertiesCount,
getValue,
@ -2464,14 +2457,12 @@ module.exports = {
/***/ }),
/***/ 1786:
/***/ 1785:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
function initialState() {
return {
expandedPaths: new Set(),
@ -2487,7 +2478,7 @@ function initialState() {
function reducer(state = initialState(), action = {}) {
const { type, data } = action;
const cloneState = overrides => _extends({}, state, overrides);
const cloneState = overrides => ({ ...state, ...overrides });
if (type === "NODE_EXPAND") {
return cloneState({
@ -2576,21 +2567,19 @@ module.exports.default = reducer;
/***/ }),
/***/ 1787:
/***/ 1786:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
/* 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/>. */
const client = __webpack_require__(1804);
const loadProperties = __webpack_require__(1803);
const node = __webpack_require__(1785);
const node = __webpack_require__(1784);
const { nodeIsError, nodeIsPrimitive } = node;
const selection = __webpack_require__(1859);
@ -2611,11 +2600,12 @@ function shouldRenderRootsInReps(roots) {
}
function renderRep(item, props) {
return Rep(_extends({}, props, {
return Rep({
...props,
object: node.getValue(item),
mode: props.mode || MODE.TINY,
defaultRep: Grip
}));
});
}
module.exports = {
@ -3082,8 +3072,6 @@ module.exports = {
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
/* 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/>. */
@ -3257,12 +3245,13 @@ function arrayIterator(props, grip, max) {
}
if (res.length < max) {
res.push(Rep(_extends({}, props, {
res.push(Rep({
...props,
object,
mode: MODE.TINY,
// Do not propagate title to array items reps
title: undefined
})));
}));
}
return res;
@ -3565,8 +3554,6 @@ module.exports = {
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
/* 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/>. */
@ -3599,13 +3586,14 @@ function GripMapEntry(props) {
return span({
className: "objectBox objectBox-map-entry"
}, PropRep(_extends({}, props, {
}, PropRep({
...props,
name: key,
object: value,
equal: " \u2192 ",
title: null,
suppressQuotes: false
})));
}));
}
function supportsObject(grip, noGrip = false) {
@ -4473,8 +4461,6 @@ exports.default = Tree;
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
/* 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/>. */
@ -4503,7 +4489,7 @@ const {
nodeIsProxy,
nodeNeedsNumericalBuckets,
nodeIsLongString
} = __webpack_require__(1785);
} = __webpack_require__(1784);
function loadItemProperties(item, createObjectClient, createLongStringClient, loadedProperties) {
const gripItem = getClosestGripNode(item);
@ -4547,7 +4533,7 @@ function mergeResponses(responses) {
for (const response of responses) {
if (response.hasOwnProperty("ownProperties")) {
data.ownProperties = _extends({}, data.ownProperties, response.ownProperties);
data.ownProperties = { ...data.ownProperties, ...response.ownProperties };
}
if (response.ownSymbols && response.ownSymbols.length > 0) {
@ -4626,7 +4612,7 @@ module.exports = {
"use strict";
const { getValue, nodeHasFullText } = __webpack_require__(1785); /* This Source Code Form is subject to the terms of the Mozilla Public
const { getValue, nodeHasFullText } = __webpack_require__(1784); /* 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/>. */
@ -4877,8 +4863,6 @@ module.exports = {
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
/* 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/>. */
@ -4961,13 +4945,14 @@ function propIterator(props, object, max) {
const propertiesNames = Object.keys(object);
const pushPropRep = (name, value) => {
elements.push(PropRep(_extends({}, props, {
elements.push(PropRep({
...props,
key: name,
mode: MODE.TINY,
name,
object: value,
equal: ": "
})));
}));
propertiesNumber++;
if (propertiesNumber < propertiesNames.length) {
@ -5175,8 +5160,6 @@ module.exports = {
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
/* 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/>. */
@ -5204,11 +5187,12 @@ function Accessor(props) {
const { Rep, Grip } = __webpack_require__(1767);
return span({
className: "objectBox objectBox-accessor objectTitle"
}, Rep(_extends({}, props, {
}, Rep({
...props,
object: evaluation.getterValue,
mode: props.mode || MODE.TINY,
defaultRep: Grip
})));
}));
}
if (hasGetter(object) && onInvokeGetterButtonClick) {
@ -5414,7 +5398,7 @@ function Attribute(props) {
return span({
"data-link-actor-id": object.actor,
className: "objectBox-Attr"
}, span({ className: "attrName" }, getTitle(object)), span({ className: "attrEqual" }, "="), StringRep({ className: "attrValue", object: value }));
}, span({ className: "attrName" }, getTitle(object)), span({ className: "attrEqual" }, "="), StringRep({ className: "attrValue", object: value, title: value }));
}
function getTitle(grip) {
@ -5628,8 +5612,6 @@ module.exports = {
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
/* 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/>. */
@ -5641,7 +5623,7 @@ const PropTypes = __webpack_require__(1758);
const { isGrip, wrapRender } = __webpack_require__(1760);
const { MODE } = __webpack_require__(1762);
const { rep } = __webpack_require__(1784);
const { rep } = __webpack_require__(1783);
/**
* Renders DOM event objects.
@ -5656,14 +5638,17 @@ Event.propTypes = {
};
function Event(props) {
const gripProps = _extends({}, props, {
const gripProps = {
...props,
title: getTitle(props),
object: _extends({}, props.object, {
preview: _extends({}, props.object.preview, {
object: {
...props.object,
preview: {
...props.object.preview,
ownProperties: {}
})
})
});
}
}
};
if (gripProps.object.preview.target) {
Object.assign(gripProps.object.preview.ownProperties, {
@ -5734,8 +5719,6 @@ module.exports = {
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
/* 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/>. */
@ -5804,13 +5787,14 @@ function getProps(props, promiseState) {
return keys.reduce((res, key, i) => {
const object = promiseState[key];
res = res.concat(PropRep(_extends({}, props, {
res = res.concat(PropRep({
...props,
mode: MODE.TINY,
name: `<${key}>`,
object,
equal: ": ",
suppressQuotes: true
})));
}));
// Interleave commas between elements
if (i !== keys.length - 1) {
@ -6041,13 +6025,15 @@ const PropTypes = __webpack_require__(1758);
// Utils
const { isGrip, wrapRender } = __webpack_require__(1760);
const { rep: StringRep } = __webpack_require__(1770);
const { rep: StringRep, isLongString } = __webpack_require__(1770);
const { MODE } = __webpack_require__(1762);
const nodeConstants = __webpack_require__(1795);
const dom = __webpack_require__(1759);
const { span } = dom;
const MAX_ATTRIBUTE_LENGTH = 50;
/**
* Renders DOM element node.
*/
@ -6157,7 +6143,18 @@ function getElements(grip, mode) {
}
const attributeElements = attributeKeys.reduce((arr, name, i, keys) => {
const value = attributes[name];
const attribute = span({}, span({ className: "attrName" }, name), span({ className: "attrEqual" }, "="), StringRep({ className: "attrValue", object: value }));
let title = isLongString(value) ? value.initial : value;
if (title.length < MAX_ATTRIBUTE_LENGTH) {
title = null;
}
const attribute = span({}, span({ className: "attrName" }, name), span({ className: "attrEqual" }, "="), StringRep({
className: "attrValue",
object: value,
cropLimit: MAX_ATTRIBUTE_LENGTH,
title
}));
return arr.concat([" ", attribute]);
}, []);
@ -6176,7 +6173,8 @@ function supportsObject(object, noGrip = false) {
// Exports from this module
module.exports = {
rep: wrapRender(ElementNode),
supportsObject
supportsObject,
MAX_ATTRIBUTE_LENGTH
};
/***/ }),
@ -6502,8 +6500,8 @@ module.exports = {
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
const ObjectInspector = __webpack_require__(1855);
const utils = __webpack_require__(1787);
const reducer = __webpack_require__(1786);
const utils = __webpack_require__(1786);
const reducer = __webpack_require__(1785);
module.exports = { ObjectInspector, utils, reducer };
@ -6515,8 +6513,6 @@ module.exports = { ObjectInspector, utils, reducer };
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _devtoolsComponents = __webpack_require__(1791);
var _devtoolsComponents2 = _interopRequireDefault(_devtoolsComponents);
@ -6531,7 +6527,7 @@ const { Component, createFactory, createElement } = __webpack_require__(0);
const { connect } = __webpack_require__(1763);
const actions = __webpack_require__(1856);
const selectors = __webpack_require__(1786);
const selectors = __webpack_require__(1785);
const Tree = createFactory(_devtoolsComponents2.default.Tree);
__webpack_require__(1857);
@ -6540,7 +6536,7 @@ const ObjectInspectorItem = createFactory(__webpack_require__(1858));
const classnames = __webpack_require__(175);
const Utils = __webpack_require__(1787);
const Utils = __webpack_require__(1786);
const { renderRep, shouldRenderRootsInReps } = Utils;
const {
getChildrenWithEvaluations,
@ -6750,14 +6746,15 @@ class ObjectInspector extends Component {
onCollapse: item => this.setExpanded(item, false),
onFocus: focusable ? this.focusItem : null,
renderItem: (item, depth, focused, arrow, expanded) => ObjectInspectorItem(_extends({}, this.props, {
renderItem: (item, depth, focused, arrow, expanded) => ObjectInspectorItem({
...this.props,
item,
depth,
focused,
arrow,
expanded,
setExpanded: this.setExpanded
}))
})
});
}
}
@ -6793,7 +6790,7 @@ const { loadItemProperties } = __webpack_require__(1803); /* This Source Code Fo
* 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/>. */
const { getLoadedProperties, getActors } = __webpack_require__(1786);
const { getLoadedProperties, getActors } = __webpack_require__(1785);
/**
* This action is responsible for expanding a given node, which also means that
@ -6917,8 +6914,6 @@ module.exports = {
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _devtoolsServices = __webpack_require__(22);
var _devtoolsServices2 = _interopRequireDefault(_devtoolsServices);
@ -6938,7 +6933,7 @@ const isMacOS = appinfo.OS === "Darwin";
const classnames = __webpack_require__(175);
const { MODE } = __webpack_require__(1762);
const Utils = __webpack_require__(1787);
const Utils = __webpack_require__(1786);
const {
getValue,
@ -7012,14 +7007,15 @@ class ObjectInspectorItem extends Component {
if (nodeIsFunction(item) && !nodeIsGetter(item) && !nodeIsSetter(item) && (mode === MODE.TINY || !mode)) {
return {
label: Utils.renderRep(item, _extends({}, this.props, {
label: Utils.renderRep(item, {
...this.props,
functionName: label
}))
})
};
}
if (nodeHasProperties(item) || nodeHasAccessors(item) || nodeIsMapEntry(item) || nodeIsLongString(item) || isPrimitive) {
const repProps = _extends({}, this.props);
const repProps = { ...this.props };
if (depth > 0) {
repProps.mode = mode === MODE.LONG ? MODE.SHORT : MODE.TINY;
}
@ -7119,10 +7115,10 @@ class ObjectInspectorItem extends Component {
onClick: onLabelClick ? event => {
event.stopPropagation();
const objectProperty = /([\w\d\$]+)$/;
const arrayProperty = /\[(.*?)\]$/;
const functionProperty = /([\w\d]+)[\/\.<]*?$/;
const annonymousProperty = /([\w\d]+)\(\^\)$/;
// If the user selected text, bail out.
if (Utils.selection.documentHasSelection()) {
return;
}
onLabelClick(item, {
depth,
@ -7190,4 +7186,4 @@ module.exports = __WEBPACK_EXTERNAL_MODULE_22__;
/***/ })
/******/ });
});
});

Просмотреть файл

@ -280,7 +280,7 @@ html[dir="rtl"] .flex-item-list .devtools-button::after {
min-width: 10px;
}
.flex-outline.column {
.flex-outline.vertical-tb {
transform: translate(50%, -2em) rotate(.25turn);
transform-origin: center left;
flex-basis: 150px;
@ -321,7 +321,7 @@ html[dir="rtl"] .flex-item-list .devtools-button::after {
drop-shadow(0px -1px 0px var(--theme-body-background));
}
.flex-outline.column .flex-outline-final.clamped::after {
.flex-outline.vertical-tb .flex-outline-final.clamped::after {
transform: rotate(-.25turn);
}
@ -404,8 +404,14 @@ html[dir="rtl"] .flex-item-list .devtools-button::after {
display: grid;
}
.flex-outline.horizontal-rl .flex-outline-point {
justify-self: start;
}
.flex-outline-point.basis,
.flex-outline-point.basisfinal {
.flex-outline-point.basisfinal,
.flex-outline.horizontal-rl .flex-outline-point.basis,
.flex-outline.horizontal-rl .flex-outline-point.basisfinal {
grid-column-end: basis-end;
justify-self: end;
color: var(--theme-highlight-blue);
@ -416,6 +422,11 @@ html[dir="rtl"] .flex-item-list .devtools-button::after {
justify-self: start;
}
.flex-outline.horizontal-rl.shrinking .flex-outline-point.basis {
grid-column-start: basis-start;
justify-self: unset;
}
.flex-outline-point.final {
grid-column-start: final-end;
left: -1px;
@ -453,7 +464,7 @@ html[dir="rtl"] .flex-item-list .devtools-button::after {
border-width: 0;
}
.flex-outline.column .flex-outline-point::before {
.flex-outline.vertical-tb .flex-outline-point::before {
padding: 0;
writing-mode: sideways-lr;
}
@ -469,25 +480,42 @@ html[dir="rtl"] .flex-item-list .devtools-button::after {
bottom: -12px;
}
.flex-outline.column .flex-outline-point.max::before,
.flex-outline.column .flex-outline-point.min::before {
.flex-outline.horizontal-rl .flex-outline-point.min::before,
.flex-outline.horizontal-rl .flex-outline-point.max::before {
bottom: -37px;
}
.flex-outline.vertical-tb .flex-outline-point.max::before,
.flex-outline.vertical-tb .flex-outline-point.min::before {
text-indent: -12px;
}
.flex-outline-point.final::before,
.flex-outline.shrinking .flex-outline-point.min::before,
.flex-outline-point.max::before,
.flex-outline.shrinking .flex-outline-point.basis::before {
.flex-outline.shrinking .flex-outline-point.basis::before,
.flex-outline.horizontal-rl .flex-outline-point.basis::before,
.flex-outline.horizontal-rl .flex-outline-point.basisfinal::before,
.flex-outline.horizontal-rl.shrinking .flex-outline-point.final::before {
border-width: 0 0 0 1px;
}
.flex-outline-point.basis::before,
.flex-outline-point.min::before,
.flex-outline.shrinking .flex-outline-point.final::before,
.flex-outline-point.basisfinal::before {
.flex-outline-point.basisfinal::before,
.flex-outline.horizontal-rl .flex-outline-point.final::before,
.flex-outline.horizontal-rl .flex-outline-point.min::before,
.flex-outline.horizontal-rl .flex-outline-point.max::before {
border-width: 0 1px 0 0;
}
.flex-outline.horizontal-rl,
.flex-outline.horizontal-rl .flex-outline-point,
.flex-outline.horizontal-rl .flex-outline-final.clamped::after {
transform: rotate(.5turn);
}
/**
* Flex Item Sizing Properties
*/

Просмотреть файл

@ -344,6 +344,7 @@ skip-if = true # Bug 1438979
[browser_webconsole_object_ctrl_click.js]
[browser_webconsole_object_in_sidebar_keyboard_nav.js]
[browser_webconsole_object_inspector.js]
[browser_webconsole_object_inspector__proto__.js]
[browser_webconsole_object_inspector_entries.js]
[browser_webconsole_object_inspector_getters.js]
[browser_webconsole_object_inspector_getters_prototype.js]

Просмотреть файл

@ -0,0 +1,36 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* 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";
// Check displaying object with __proto__ in the console.
const TEST_URI = "data:text/html;charset=utf8,<h1>test Object Inspector __proto__</h1>";
add_task(async function() {
const hud = await openNewTabAndConsole(TEST_URI);
logAllStoreChanges(hud);
await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
const obj = Object.create(null);
// eslint-disable-next-line no-proto
obj.__proto__ = [];
content.wrappedJSObject.console.log("oi-test", obj);
});
const node = await waitFor(() => findMessage(hud, "oi-test"));
const objectInspector = node.querySelector(".tree");
ok(objectInspector, "Object is printed in the console");
is(objectInspector.textContent.trim(), "Object { __proto__: [] }",
"Object is displayed as expected");
objectInspector.querySelector(".arrow").click();
await waitFor(() => node.querySelectorAll(".tree-node").length === 2);
const __proto__Node = node.querySelector(".tree-node:last-of-type");
ok(__proto__Node.textContent.includes("__proto__: Array []"),
"__proto__ node is displayed as expected");
});

Просмотреть файл

@ -103,6 +103,7 @@ CssProperties.prototype = {
* @return {Boolean}
*/
isKnown(property) {
property = property.toLowerCase();
return !!this.properties[property] || isCssVariable(property);
},
@ -197,6 +198,7 @@ CssProperties.prototype = {
* @return {Array} An array of subproperty names.
*/
getSubproperties(name) {
name = name.toLowerCase();
if (this.isKnown(name)) {
if (this.properties[name] && this.properties[name].subproperties) {
return this.properties[name].subproperties;

Просмотреть файл

@ -665,9 +665,13 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState) {
"Should not have these flags set");
MOZ_ASSERT(aLoadState->URI(), "Should have a valid URI to load");
if (mUseStrictSecurityChecks && !aLoadState->TriggeringPrincipal()) {
if (!aLoadState->TriggeringPrincipal()) {
#ifndef ANDROID
MOZ_ASSERT(false, "LoadURI must have a triggering principal");
return NS_ERROR_FAILURE;
#endif
if (mUseStrictSecurityChecks) {
return NS_ERROR_FAILURE;
}
}
// Note: we allow loads to get through here even if mFiredUnloadEvent is
@ -3863,9 +3867,6 @@ nsDocShell::LoadURI(const nsAString& aURI, uint32_t aLoadFlags,
nsIURI* aReferringURI, nsIInputStream* aPostStream,
nsIInputStream* aHeaderStream,
nsIPrincipal* aTriggeringPrincipal) {
#ifndef ANDROID
MOZ_ASSERT(aTriggeringPrincipal, "LoadURI: Need a valid triggeringPrincipal");
#endif
if (mUseStrictSecurityChecks && !aTriggeringPrincipal) {
return NS_ERROR_FAILURE;
}
@ -3901,11 +3902,6 @@ nsDocShell::LoadURIWithOptions(const nsAString& aURI, uint32_t aLoadFlags,
uriString.StripCRLF();
NS_ENSURE_TRUE(!uriString.IsEmpty(), NS_ERROR_FAILURE);
#ifndef ANDROID
MOZ_ASSERT(aTriggeringPrincipal,
"LoadURIWithOptions: Need a valid triggeringPrincipal");
#endif
if (mUseStrictSecurityChecks && !aTriggeringPrincipal) {
return NS_ERROR_FAILURE;
}
@ -8310,7 +8306,9 @@ nsresult nsDocShell::CreateContentViewer(const nsACString& aContentType,
FireOnLocationChange(this, failedChannel, failedURI,
LOCATION_CHANGE_ERROR_PAGE);
} else if (onLocationChangeNeeded) {
FireOnLocationChange(this, aRequest, mCurrentURI, 0);
uint32_t locationFlags =
(mLoadType & LOAD_CMD_RELOAD) ? uint32_t(LOCATION_CHANGE_RELOAD) : 0;
FireOnLocationChange(this, aRequest, mCurrentURI, locationFlags);
}
return NS_OK;

Просмотреть файл

@ -333,9 +333,6 @@ nsresult nsDocShellLoadState::SetupTriggeringPrincipal(
return NS_ERROR_FAILURE;
}
} else {
#ifndef ANDROID
MOZ_ASSERT(false, "LoadURI: System principal required.");
#endif
mTriggeringPrincipal = nsContentUtils::GetSystemPrincipal();
}
}

Просмотреть файл

@ -185,6 +185,7 @@ namespace dom {
JS::Rooted<JS::IdVector> ids(cx, JS::IdVector(cx));
JS::AutoValueVector values(cx);
JS::AutoIdVector valuesIds(cx);
{
JS::RootedObject obj(cx, js::CheckedUnwrap(aObj));
@ -200,7 +201,8 @@ namespace dom {
JSAutoRealm ar(cx, obj);
if (!JS_Enumerate(cx, obj, &ids) || !values.reserve(ids.length())) {
if (!JS_Enumerate(cx, obj, &ids) || !values.reserve(ids.length()) ||
!valuesIds.reserve(ids.length())) {
return;
}
@ -214,6 +216,7 @@ namespace dom {
if (desc.setter() || desc.getter()) {
continue;
}
valuesIds.infallibleAppend(id);
values.infallibleAppend(desc.value());
}
}
@ -237,8 +240,8 @@ namespace dom {
JS::RootedValue value(cx);
JS::RootedId id(cx);
for (uint32_t i = 0; i < ids.length(); i++) {
id = ids[i];
for (uint32_t i = 0; i < valuesIds.length(); i++) {
id = valuesIds[i];
value = values[i];
JS_MarkCrossZoneId(cx, id);

Просмотреть файл

@ -332,7 +332,6 @@ nsAtom* nsIContent::GetLang() const {
already_AddRefed<nsIURI> nsIContent::GetBaseURI(
bool aTryUseXHRDocBaseURI) const {
if (SVGUseElement* use = GetContainingSVGUseShadowHost()) {
// XXX Ignore xml:base as we are removing it.
if (URLExtraData* data = use->GetContentURLData()) {
return do_AddRef(data->BaseURI());
}
@ -342,60 +341,6 @@ already_AddRefed<nsIURI> nsIContent::GetBaseURI(
// Start with document base
nsCOMPtr<nsIURI> base = doc->GetBaseURI(aTryUseXHRDocBaseURI);
// Collect array of xml:base attribute values up the parent chain. This
// is slightly slower for the case when there are xml:base attributes, but
// faster for the far more common case of there not being any such
// attributes.
// Also check for SVG elements which require special handling
AutoTArray<nsString, 5> baseAttrs;
nsString attr;
const nsIContent* elem = this;
do {
// First check for SVG specialness (why is this SVG specific?)
if (elem->IsSVGElement()) {
nsIContent* bindingParent = elem->GetBindingParent();
if (bindingParent) {
nsXBLBinding* binding = bindingParent->GetXBLBinding();
if (binding) {
// XXX sXBL/XBL2 issue
// If this is an anonymous XBL element use the binding
// document for the base URI.
// XXX Will fail with xml:base
base = binding->PrototypeBinding()->DocURI();
break;
}
}
}
// Otherwise check for xml:base attribute
if (elem->IsElement()) {
elem->AsElement()->GetAttr(kNameSpaceID_XML, nsGkAtoms::base, attr);
if (!attr.IsEmpty()) {
baseAttrs.AppendElement(attr);
}
}
elem = elem->GetParent();
} while (elem);
if (!baseAttrs.IsEmpty()) {
doc->WarnOnceAbout(nsIDocument::eXMLBaseAttribute);
// Now resolve against all xml:base attrs
for (uint32_t i = baseAttrs.Length() - 1; i != uint32_t(-1); --i) {
nsCOMPtr<nsIURI> newBase;
nsresult rv = NS_NewURI(getter_AddRefs(newBase), baseAttrs[i],
doc->GetDocumentCharacterSet(), base);
// Do a security check, almost the same as nsDocument::SetBaseURL()
// Only need to do this on the final uri
if (NS_SUCCEEDED(rv) && i == 0) {
rv = nsContentUtils::GetSecurityManager()->CheckLoadURIWithPrincipal(
NodePrincipal(), newBase, nsIScriptSecurityManager::STANDARD);
}
if (NS_SUCCEEDED(rv)) {
base.swap(newBase);
}
}
}
return base.forget();
}

Просмотреть файл

@ -32,7 +32,6 @@ DEPRECATED_OPERATION(AppCacheInsecure)
DEPRECATED_OPERATION(PrefixedImageSmoothingEnabled)
DEPRECATED_OPERATION(LenientSetter)
DEPRECATED_OPERATION(ImageBitmapRenderingContext_TransferImageBitmap)
DEPRECATED_OPERATION(XMLBaseAttribute)
DEPRECATED_OPERATION(WindowContentUntrusted)
DEPRECATED_OPERATION(RegisterProtocolHandlerInsecure)
DEPRECATED_OPERATION(MixedDisplayObjectSubrequest)

Просмотреть файл

@ -5069,7 +5069,17 @@ void nsGlobalWindowOuter::NotifyContentBlockingState(unsigned aState,
state &= ~aState;
}
if (state == oldState) {
if (state == oldState
#ifdef ANDROID
// GeckoView always needs to notify about blocked trackers, since the
// GeckoView API always needs to report the URI and type of any blocked
// tracker.
// We use a platform-dependent code path here because reporting this
// notification on desktop platforms isn't necessary and doing so can have
// a big performance cost.
&& aState != nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT
#endif
) {
// Avoid dispatching repeated notifications when nothing has changed
return;
}

Просмотреть файл

@ -1231,15 +1231,6 @@ void nsTreeSanitizer::SanitizeAttributes(mozilla::dom::Element* aElement,
}
// else not allowed
} else if (kNameSpaceID_XML == attrNs) {
if (nsGkAtoms::base == attrLocal) {
if (SanitizeURL(aElement, attrNs, attrLocal)) {
// in case the attribute removal shuffled the attribute order, start
// the loop again.
--ac;
i = ac; // i will be decremented immediately thanks to the for loop
}
continue;
}
if (nsGkAtoms::lang == attrLocal || nsGkAtoms::space == attrLocal) {
continue;
}

Просмотреть файл

@ -437,8 +437,6 @@ support-files = file_bug503473-frame.sjs
skip-if = toolkit == 'android' #TIMED_OUT
[test_bug503481b.html]
skip-if = toolkit == 'android' #TIMED_OUT
[test_bug505783.html]
skip-if = toolkit == 'android' #TIMED_OUT
[test_bug513194.html]
[test_bug514487.html]
[test_bug515401.html]

Просмотреть файл

@ -21,12 +21,12 @@ addLoadEvent(function() {
"body base");
var expected =
["http://mochi.test:8888/tests/dom/base/supercalifragilisticexpialidocious",
"http://mochi.test:8888/tests/dom/base/supercalifragilisticexpialidocious",
"http://mochi.test:8888/tests/dom/base/hello/",
"http://mochi.test:8888/tests/dom/base/hello/world",
"http://mochi.test:8888/tests/dom/base/hello/world#iamtheverymodelofamodernmajorgeneral",
"http://mochi.test:8888/tests/dom/base/hello/world#iamtheverymodelofamodernmajorgeneral",
["http://mochi.test:8888/tests/dom/base/",
"http://mochi.test:8888/tests/dom/base/",
"http://mochi.test:8888/tests/dom/base/",
"http://mochi.test:8888/tests/dom/base/",
"http://mochi.test:8888/tests/dom/base/",
"http://mochi.test:8888/tests/dom/base/",
];
var node = document.getElementById("1");
while(node) {
@ -36,9 +36,9 @@ addLoadEvent(function() {
is(expected.length, 0, "found all expected nodes");
var svgExpected =
["http://mochi.test:8888/tests/dom/base/test/file_base_xbl.xml",
"http://mochi.test:8888/tests/dom/base/test/file_base_xbl.xml",
"http://mochi.test:8888/tests/dom/base/test/file_base_xbl.xml#shesellsseashellsbytheseashore",
["http://mochi.test:8888/tests/dom/base/",
"http://mochi.test:8888/tests/dom/base/",
"http://mochi.test:8888/tests/dom/base/",
];
node = SpecialPowers.wrap(document).getAnonymousNodes(document.getElementById("bound"))[0];
while(node) {

Просмотреть файл

@ -1,33 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=505783
-->
<head>
<title>Test for Bug 505783</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=505783">Mozilla Bug 505783</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 505783 **/
var a = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
a.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:base", "http://example.org/");
a.href = "page";
is(a.href, "http://example.org/page", "xml:base not used when not in doc");
document.getElementById("content").appendChild(a);
is(a.href, "http://example.org/page", "xml:base not used when in doc");
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -0,0 +1,45 @@
"use strict";
add_task(function test_shallowclone() {
// Check that shallow cloning an object with regular properties,
// results into a new object with all properties from the source object.
const fullyCloneableObject = {
numProp: 123,
strProp: "str",
boolProp: true,
arrayProp: [{item1: "1", item2: "2"}],
fnProp() { return "fn result"; },
promise: Promise.resolve("promised-value"),
weakmap: new WeakMap(),
proxy: new Proxy({}, {}),
};
let clonedObject = ChromeUtils.shallowClone(fullyCloneableObject);
Assert.deepEqual(clonedObject, fullyCloneableObject,
"Got the expected cloned object for an object with regular properties");
// Check that shallow cloning an object with getters and setters properties,
// results into a new object without all the properties from the source object excluded
// its getters and setters.
const objectWithGetterAndSetter = {
get myGetter() { return "getter result"; },
set mySetter(v) {},
myFunction() { return "myFunction result"; },
};
clonedObject = ChromeUtils.shallowClone(objectWithGetterAndSetter);
Assert.deepEqual(clonedObject, {
myFunction: objectWithGetterAndSetter.myFunction,
}, "Got the expected cloned object for an object with getters and setters");
// Check that shallow cloning a proxy object raises the expected exception..
const proxyObject = new Proxy(fullyCloneableObject, {});
Assert.throws(
() => { ChromeUtils.shallowClone(proxyObject); },
/Shallow cloning a proxy object is not allowed/,
"Got the expected error on ChromeUtils.shallowClone called on a proxy object");
});

Просмотреть файл

@ -54,6 +54,7 @@ head = head_xml.js
[test_xmlserializer.js]
[test_cancelPrefetch.js]
[test_chromeutils_base64.js]
[test_chromeutils_shallowclone.js]
[test_generate_xpath.js]
head = head_xml.js
[test_js_dev_error_interceptor.js]

Просмотреть файл

@ -120,8 +120,8 @@ void HTMLAnchorElement::UnbindFromTree(bool aDeep, bool aNullParent) {
CancelDNSPrefetch(HTML_ANCHOR_DNS_PREFETCH_DEFERRED,
HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
// If this link is ever reinserted into a document, it might
// be under a different xml:base, so forget the cached state now.
// Without removing the link state we risk a dangling pointer
// in the mStyledLinks hashtable
Link::ResetLinkState(false, Link::ElementHasHref());
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);

Просмотреть файл

@ -82,8 +82,8 @@ nsresult HTMLAreaElement::BindToTree(nsIDocument* aDocument,
}
void HTMLAreaElement::UnbindFromTree(bool aDeep, bool aNullParent) {
// If this link is ever reinserted into a document, it might
// be under a different xml:base, so forget the cached state now.
// Without removing the link state we risk a dangling pointer
// in the mStyledLinks hashtable
Link::ResetLinkState(false, Link::ElementHasHref());
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);

Просмотреть файл

@ -154,8 +154,8 @@ void HTMLLinkElement::UnbindFromTree(bool aDeep, bool aNullParent) {
HTML_LINK_DNS_PREFETCH_REQUESTED);
CancelPrefetchOrPreload();
// If this link is ever reinserted into a document, it might
// be under a different xml:base, so forget the cached state now.
// Without removing the link state we risk a dangling pointer
// in the mStyledLinks hashtable
Link::ResetLinkState(false, Link::ElementHasHref());
// If this is reinserted back into the document it will not be

Просмотреть файл

@ -10,6 +10,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=481335
a { color:blue; }
a:visited { color:red; }
</style>
<base href="http://www.example.com/" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=481335">Mozilla Bug 481335</a>
@ -17,7 +18,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=481335
<a id="t">A link</a>
<iframe id="i"></iframe>
</p>
<p id="newparent" xml:base="http://www.example.com/"></p>
<p id="newparent"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
@ -33,11 +34,9 @@ is($("t").href, "",
"Unexpected cached href before set");
$("t").setAttribute("href", rand);
is($("t").href,
window.location.href.replace(/test_bug481335.xhtml([\?].*)?/, rand),
is($("t").href, "http://www.example.com/" + rand,
"Unexpected href after set");
is($("t").href,
window.location.href.replace(/test_bug481335.xhtml([\?].*)?/, rand),
is($("t").href, "http://www.example.com/" + rand,
"Unexpected cached href after set");
const unvisitedColor = "rgb(0, 0, 255)";
const visitedColor = "rgb(255, 0, 0)";

Просмотреть файл

@ -317,8 +317,6 @@ LargeAllocationNonE10S=A Large-Allocation header was ignored due to the document
GeolocationInsecureRequestIsForbidden=A Geolocation request can only be fulfilled in a secure context.
# LOCALIZATION NOTE: Do not translate "Large-Allocation", as it is a literal header name.
LargeAllocationNonWin32=This page would be loaded in a new process due to a Large-Allocation header, however Large-Allocation process creation is disabled on non-Win32 platforms.
# LOCALIZATION NOTE: Do not translate xml:base.
XMLBaseAttributeWarning=Use of xml:base attribute is deprecated and will be removed soon. Please remove any use of it.
# LOCALIZATION NOTE: Do not translate "content", "Window", and "window.top"
WindowContentUntrustedWarning=The content attribute of Window objects is deprecated. Please use window.top instead.
# LOCALIZATION NOTE: The first %S is the tag name of the element that starts the loop, the second %S is the element's ID.

Просмотреть файл

@ -96,8 +96,8 @@ nsresult nsMathMLElement::BindToTree(nsIDocument* aDocument,
}
void nsMathMLElement::UnbindFromTree(bool aDeep, bool aNullParent) {
// If this link is ever reinserted into a document, it might
// be under a different xml:base, so forget the cached state now.
// Without removing the link state we risk a dangling pointer
// in the mStyledLinks hashtable
Link::ResetLinkState(false, Link::ElementHasHref());
nsMathMLElementBase::UnbindFromTree(aDeep, aNullParent);

Просмотреть файл

@ -2,7 +2,7 @@
* 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/. */
ChromeUtils.import('resource://gre/modules/NetUtil.jsm');
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://testing-common/httpd.js");
@ -33,7 +33,7 @@ function makeReportHandler(testpath, message, expectedJSON) {
? request.getHeader("Content-Type") : undefined;
if (contentType !== "application/csp-report") {
do_throw("violation report should have the 'application/csp-report' " +
"content-type, when in fact it is " + contentType.toString())
"content-type, when in fact it is " + contentType.toString());
}
// obtain violation report
@ -47,7 +47,7 @@ function makeReportHandler(testpath, message, expectedJSON) {
// dump("EXPECTED: \n" + JSON.stringify(expectedJSON) + "\n\n");
for (var i in expectedJSON)
Assert.equal(expectedJSON[i], reportObj['csp-report'][i]);
Assert.equal(expectedJSON[i], reportObj["csp-report"][i]);
testsToFinish--;
httpServer.registerPathHandler(testpath, null);
@ -80,9 +80,7 @@ function makeTest(id, expectedJSON, useReportOnlyPolicy, callback) {
dump("Created test " + id + " : " + policy + "\n\n");
let ssm = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager);
principal = ssm.createCodebasePrincipal(selfuri, {});
principal = Services.scriptSecurityManager.createCodebasePrincipal(selfuri, {});
csp.setRequestContext(null, principal);
// Load up the policy
@ -93,7 +91,7 @@ function makeTest(id, expectedJSON, useReportOnlyPolicy, callback) {
var handler = makeReportHandler("/test" + id, "Test " + id, expectedJSON);
httpServer.registerPathHandler("/test" + id, handler);
//trigger the violation
// trigger the violation
callback(csp);
}
@ -122,11 +120,11 @@ function run_test() {
// test that eval violations cause a report.
makeTest(1, {"blocked-uri": "eval",
// JSON script-sample is UTF8 encoded
"script-sample" : "\xc2\xa3\xc2\xa5\xc2\xb5\xe5\x8c\x97\xf0\xa0\x9d\xb9",
"script-sample": "\xc2\xa3\xc2\xa5\xc2\xb5\xe5\x8c\x97\xf0\xa0\x9d\xb9",
"line-number": 1,
"column-number": 2}, false,
function(csp) {
let evalOK = true, oReportViolation = {'value': false};
let evalOK = true, oReportViolation = {"value": false};
evalOK = csp.getAllowsEval(oReportViolation);
// this is not a report only policy, so it better block eval
@ -178,7 +176,7 @@ function run_test() {
// test that eval violations cause a report in report-only policy
makeTest(4, {"blocked-uri": "inline"}, true,
function(csp) {
let evalOK = true, oReportViolation = {'value': false};
let evalOK = true, oReportViolation = {"value": false};
evalOK = csp.getAllowsEval(oReportViolation);
// this is a report only policy, so it better allow eval
@ -225,7 +223,6 @@ function run_test() {
var selfSpec = REPORT_SERVER_URI + ":" + REPORT_SERVER_PORT + "/foo/self/foo.js";
makeTest(7, {"blocked-uri": selfSpec}, false,
function(csp) {
var uri = NetUtil
// shouldLoad creates and sends out the report here.
csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SCRIPT,
null, // nsICSPEventListener

Просмотреть файл

@ -1,14 +1,13 @@
ChromeUtils.import("resource://testing-common/httpd.js");
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
var prefs = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch);
// Since this test creates a TYPE_DOCUMENT channel via javascript, it will
// end up using the wrong LoadInfo constructor. Setting this pref will disable
// the ContentPolicyType assertion in the constructor.
prefs.setBoolPref("network.loadinfo.skip_type_assertion", true);
Services.prefs.setBoolPref("network.loadinfo.skip_type_assertion", true);
XPCOMUtils.defineLazyGetter(this, "URL", function() {
return "http://localhost:" + httpserver.identity.primaryPort;
@ -23,22 +22,22 @@ var tests = [
{
description: "should not set request header for TYPE_OTHER",
expectingHeader: false,
contentType: Ci.nsIContentPolicy.TYPE_OTHER
contentType: Ci.nsIContentPolicy.TYPE_OTHER,
},
{
description: "should set request header for TYPE_DOCUMENT",
expectingHeader: true,
contentType: Ci.nsIContentPolicy.TYPE_DOCUMENT
contentType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
},
{
description: "should set request header for TYPE_SUBDOCUMENT",
expectingHeader: true,
contentType: Ci.nsIContentPolicy.TYPE_SUBDOCUMENT
contentType: Ci.nsIContentPolicy.TYPE_SUBDOCUMENT,
},
{
description: "should not set request header for TYPE_IMG",
expectingHeader: false,
contentType: Ci.nsIContentPolicy.TYPE_IMG
contentType: Ci.nsIContentPolicy.TYPE_IMG,
},
];
@ -46,23 +45,22 @@ function ChannelListener() {
}
ChannelListener.prototype = {
onStartRequest: function(request, context) { },
onDataAvailable: function(request, context, stream, offset, count) {
onStartRequest(request, context) { },
onDataAvailable(request, context, stream, offset, count) {
do_throw("Should not get any data!");
},
onStopRequest: function(request, context, status) {
onStopRequest(request, context, status) {
var upgrade_insecure_header = false;
try {
if (request.getRequestHeader("Upgrade-Insecure-Requests")) {
upgrade_insecure_header = true;
}
}
catch (e) {
} catch (e) {
// exception is thrown if header is not available on the request
}
// debug
// dump("executing test: " + curTest.description);
Assert.equal(upgrade_insecure_header, curTest.expectingHeader)
Assert.equal(upgrade_insecure_header, curTest.expectingHeader);
run_next_test();
},
};
@ -71,7 +69,7 @@ function setupChannel(aContentType) {
var chan = NetUtil.newChannel({
uri: URL + testpath,
loadUsingSystemPrincipal: true,
contentPolicyType: aContentType
contentPolicyType: aContentType,
});
chan.QueryInterface(Ci.nsIHttpChannel);
chan.requestMethod = "GET";

Просмотреть файл

@ -8,6 +8,7 @@
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "gScriptSecurityManager",
"@mozilla.org/scriptsecuritymanager;1",
@ -17,8 +18,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "gContentSecurityManager",
"@mozilla.org/contentsecuritymanager;1",
"nsIContentSecurityManager");
var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
prefs.setCharPref("dom.securecontext.whitelist", "example.net,example.org");
Services.prefs.setCharPref("dom.securecontext.whitelist", "example.net,example.org");
add_task(async function test_isOriginPotentiallyTrustworthy() {
for (let [uriSpec, expectedResult] of [
@ -43,7 +43,7 @@ add_task(async function test_isOriginPotentiallyTrustworthy() {
}
// And now let's test whether .onion sites are properly treated when
// whitelisted, see bug 1382359.
prefs.setBoolPref("dom.securecontext.whitelist_onions", true);
Services.prefs.setBoolPref("dom.securecontext.whitelist_onions", true);
let uri = NetUtil.newURI("http://1234567890abcdef.onion/");
let principal = gScriptSecurityManager.createCodebasePrincipal(uri, {});
Assert.equal(gContentSecurityManager.isOriginPotentiallyTrustworthy(principal),

Просмотреть файл

@ -172,8 +172,8 @@ nsresult SVGAElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
}
void SVGAElement::UnbindFromTree(bool aDeep, bool aNullParent) {
// If this link is ever reinserted into a document, it might
// be under a different xml:base, so forget the cached state now.
// Without removing the link state we risk a dangling pointer
// in the mStyledLinks hashtable
Link::ResetLinkState(false, Link::ElementHasHref());
SVGAElementBase::UnbindFromTree(aDeep, aNullParent);

Просмотреть файл

@ -42,7 +42,7 @@ is(+contentBuildID, LEGACY_BUILD_ID,
let chromeScript = SpecialPowers.loadChromeScript(() => {
ChromeUtils.import("resource://gre/modules/Services.jsm");
addMessageListener("test:getBuildID", nav => {
let browser = Services.wm.getMostRecentWindow('navigator:browser');
const browser = Services.wm.getMostRecentBrowserWindow();
return browser.navigator.buildID;
});
});

Просмотреть файл

@ -38,8 +38,6 @@ function startTest() {
function testXMLDocURI(aDoc, aExpects) {
is(aDoc.documentURI, aExpects.documentURI, "wrong url");
is(aDoc.baseURI, aExpects.baseURI, "wrong base");
is(aDoc.documentElement.baseURI, aExpects.elementBaseURI,
"wrong base (xml:base)");
}
function testChromeXMLDocURI(aDoc, aExpects) {
@ -49,10 +47,6 @@ function testChromeXMLDocURI(aDoc, aExpects) {
is(aDoc.baseURI, aExpects.baseURI, "wrong base");
is(aDoc.baseURIObject.spec, aExpects.baseURI,
"wrong base (.baseURIObject)");
is(aDoc.documentElement.baseURI, aExpects.elementBaseURI,
"wrong base (xml:base)");
is(aDoc.documentElement.baseURIObject.spec, aExpects.elementBaseURI,
"wrong base (.baseURIObject, xml:base)");
}
function testHTMLDocURI(aDoc, aExpects) {
@ -74,18 +68,6 @@ function testChromeHTMLDocURI(aDoc, aNonChromeBaseURI, aExpects) {
is(aDoc.baseURIObject.spec, aExpects.baseURI,
"wrong url (.baseURIObject)");
aDoc.body.setAttributeNS("http://www.w3.org/XML/1998/namespace", "base",
aNonChromeBaseURI);
is(aDoc.body.baseURI, aNonChromeBaseURI,
"wrong base (doc base and xml:base are same)");
is(aDoc.body.baseURIObject.spec, aNonChromeBaseURI,
"wrong base (.baseURIObject, doc base and xml:base are same)")
var attr = aDoc.getElementById("data").getAttributeNode("id");
is(attr.baseURI, aNonChromeBaseURI,
"wrong attr base (doc base and xml:base are same)")
is(attr.baseURIObject.spec, aNonChromeBaseURI,
"wrong attr base (.baseURIObject, doc base and xml:base are same)")
var base = aDoc.createElement("base");
var newBaseURI = "http://www.example.com/";
base.href = newBaseURI;
@ -113,8 +95,7 @@ function* runTest() {
}
var expects = {
documentURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml",
baseURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml",
elementBaseURI: "http://www.example.com/"
baseURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml"
};
testXMLDocURI(xhr.responseXML, expects);
if (xhr.readyState == 4) {
@ -162,8 +143,7 @@ function* runTest() {
}
var expects = {
documentURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml",
baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml",
elementBaseURI: "http://www.example.com/"
baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml"
};
testXMLDocURI(xhr.responseXML, expects);
if (xhr.readyState == 4) {
@ -200,8 +180,7 @@ function* runTest() {
}
var expects = {
documentURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml",
baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml",
elementBaseURI: "http://www.example.com/"
baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml"
};
testXMLDocURI(xhr.responseXML, expects);
if (xhr.readyState == 4) {
@ -252,8 +231,7 @@ function* runTest() {
}
var expects = {
documentURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml",
baseURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml",
elementBaseURI: "http://www.example.com/"
baseURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml"
};
var xml = SpecialPowers.wrap(xhr.responseXML);
testChromeXMLDocURI(xml, expects);
@ -294,8 +272,7 @@ function* runTest() {
}
var expects = {
documentURI: document.documentURI,
baseURI: document.baseURI,
elementBaseURI: "http://www.example.com/"
baseURI: document.baseURI
};
var xml = SpecialPowers.wrap(xhr.responseXML);
testChromeXMLDocURI(xml, expects);
@ -336,8 +313,7 @@ function* runTest() {
}
var expects = {
documentURI: document.documentURI,
baseURI: document.baseURI,
elementBaseURI: "http://www.example.com/"
baseURI: document.baseURI
};
var xml = SpecialPowers.wrap(xhr.responseXML);
testChromeXMLDocURI(xml, expects);
@ -381,8 +357,7 @@ function* runTest() {
}
var expects = {
documentURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml",
baseURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml",
elementBaseURI: "http://www.example.com/"
baseURI: "http://mochi.test:8888/tests/dom/xhr/tests/file_XHRDocURI.xml"
};
testXMLDocURI(xhr.responseXML, expects);
if (xhr.readyState == 4) {
@ -419,8 +394,7 @@ function* runTest() {
}
var expects = {
documentURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml",
baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml",
elementBaseURI: "http://www.example.com/"
baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml"
};
testXMLDocURI(xhr.responseXML, expects);
if (xhr.readyState == 4) {
@ -457,8 +431,7 @@ function* runTest() {
}
var expects = {
documentURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml",
baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml",
elementBaseURI: "http://www.example.com/"
baseURI: "http://example.com/tests/dom/xhr/tests/file_XHRDocURI.xml"
};
testXMLDocURI(xhr.responseXML, expects);
if (xhr.readyState == 4) {

Просмотреть файл

@ -191,17 +191,6 @@ nsresult txStylesheetCompiler::startElementInternal(
}
}
// xml:base
if (attr->mNamespaceID == kNameSpaceID_XML &&
attr->mLocalName == nsGkAtoms::base && !attr->mValue.IsEmpty()) {
rv = ensureNewElementContext();
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString uri;
URIUtils::resolveHref(attr->mValue, mElementContext->mBaseURI, uri);
mElementContext->mBaseURI = uri;
}
// extension-element-prefixes
if ((attr->mNamespaceID == kNameSpaceID_XSLT &&
attr->mLocalName == nsGkAtoms::extensionElementPrefixes &&

Просмотреть файл

@ -8,6 +8,13 @@
#include "AndroidSurfaceTexture.h"
#include "GeneratedJNINatives.h"
#include "AndroidNativeWindow.h"
#include "GLContextEGL.h"
#include "GLBlitHelper.h"
#include "GLImages.h"
using namespace mozilla;
namespace mozilla {
@ -28,6 +35,149 @@ void AndroidSurfaceTexture::GetTransformMatrix(
env->ReleaseFloatArrayElements(jarray.Get(), array, 0);
}
class SharedGL {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedGL);
SharedGL(AndroidNativeWindow& window) {
MutexAutoLock lock(sMutex);
if (!sContext) {
MOZ_ASSERT(sInstanceCount == 0);
sContext = CreateContext();
if (!sContext) {
return;
}
}
InitSurface(window);
++sInstanceCount;
}
void Blit(const AndroidSurfaceTextureHandle& sourceTextureHandle,
const gfx::IntSize& imageSize) {
MutexAutoLock lock(sMutex);
MOZ_ASSERT(sContext);
// Setting overide also makes conext and surface current.
sContext->SetEGLSurfaceOverride(mTargetSurface);
RefPtr<layers::SurfaceTextureImage> img = new layers::SurfaceTextureImage(
sourceTextureHandle, imageSize, false, OriginPos::TopLeft);
sContext->BlitHelper()->BlitImage(img, imageSize, OriginPos::BottomLeft);
sContext->SwapBuffers();
// This method is called through binder IPC and could run on any thread in
// the pool. Release the context and surface from this thread after use so
// they can be bound to another thread later.
UnmakeCurrent(sContext);
}
private:
~SharedGL() {
MutexAutoLock lock(sMutex);
if (mTargetSurface != EGL_NO_SURFACE) {
GLLibraryEGL::Get()->fDestroySurface(EGL_DISPLAY(), mTargetSurface);
}
// Destroy shared GL context when no one uses it.
if (--sInstanceCount == 0) {
sContext = nullptr;
}
}
static already_AddRefed<GLContextEGL> CreateContext() {
sMutex.AssertCurrentThreadOwns();
MOZ_ASSERT(!sContext);
auto* egl = gl::GLLibraryEGL::Get();
EGLDisplay eglDisplay = egl->fGetDisplay(EGL_DEFAULT_DISPLAY);
EGLConfig eglConfig;
CreateConfig(&eglConfig, /* bpp */ 24, /* depth buffer? */ false);
EGLint attributes[] = {LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2, LOCAL_EGL_NONE};
EGLContext eglContext =
egl->fCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attributes);
RefPtr<GLContextEGL> gl = new GLContextEGL(
CreateContextFlags::NONE, SurfaceCaps::Any(),
/* offscreen? */ false, eglConfig, EGL_NO_SURFACE, eglContext);
if (!gl->Init()) {
NS_WARNING("Fail to create GL context for native blitter.");
return nullptr;
}
// Yield the current state made in constructor.
UnmakeCurrent(gl);
return gl.forget();
}
void InitSurface(AndroidNativeWindow& window) {
sMutex.AssertCurrentThreadOwns();
MOZ_ASSERT(sContext);
mTargetSurface = gl::GLLibraryEGL::Get()->fCreateWindowSurface(
sContext->GetEGLDisplay(), sContext->mConfig, window.NativeWindow(), 0);
}
static bool UnmakeCurrent(RefPtr<GLContextEGL>& gl) {
sMutex.AssertCurrentThreadOwns();
MOZ_ASSERT(gl);
if (!gl->IsCurrent()) {
return true;
}
return gl::GLLibraryEGL::Get()->fMakeCurrent(
EGL_DISPLAY(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
static Mutex sMutex;
static RefPtr<GLContextEGL> sContext;
static size_t sInstanceCount;
EGLSurface mTargetSurface;
};
Mutex SharedGL::sMutex("SharedGLContext::sMutex");
RefPtr<GLContextEGL> SharedGL::sContext(nullptr);
size_t SharedGL::sInstanceCount = 0;
class GLBlitterSupport final
: public java::GeckoSurfaceTexture::NativeGLBlitHelper::Natives<
GLBlitterSupport> {
public:
using Base =
java::GeckoSurfaceTexture::NativeGLBlitHelper::Natives<GLBlitterSupport>;
using Base::AttachNative;
using Base::DisposeNative;
using Base::GetNative;
static java::GeckoSurfaceTexture::NativeGLBlitHelper::LocalRef Create(
jint sourceTextureHandle, jni::Object::Param targetSurface, jint width,
jint height) {
AndroidNativeWindow win(java::GeckoSurface::Ref::From(targetSurface));
auto helper = java::GeckoSurfaceTexture::NativeGLBlitHelper::New();
RefPtr<SharedGL> gl = new SharedGL(win);
GLBlitterSupport::AttachNative(
helper, MakeUnique<GLBlitterSupport>(std::move(gl), sourceTextureHandle,
width, height));
return helper;
}
GLBlitterSupport(RefPtr<SharedGL>&& gl, jint sourceTextureHandle, jint width,
jint height)
: mGl(gl),
mSourceTextureHandle(sourceTextureHandle),
mSize(width, height) {}
void Blit() { mGl->Blit(mSourceTextureHandle, mSize); }
private:
const RefPtr<SharedGL> mGl;
const AndroidSurfaceTextureHandle mSourceTextureHandle;
const gfx::IntSize mSize;
};
void AndroidSurfaceTexture::Init() { GLBlitterSupport::Init(); }
} // namespace gl
} // namespace mozilla
#endif // MOZ_WIDGET_ANDROID

Просмотреть файл

@ -18,6 +18,7 @@ namespace gl {
class AndroidSurfaceTexture {
public:
static void Init();
static void GetTransformMatrix(
java::sdk::SurfaceTexture::Param surfaceTexture,
mozilla::gfx::Matrix4x4* outMatrix);

Просмотреть файл

@ -422,7 +422,6 @@ bool ClipManager::ItemClips::HasSameInputs(const ItemClips& aOther) {
void ClipManager::ItemClips::CopyOutputsFrom(const ItemClips& aOther) {
mScrollId = aOther.mScrollId;
mClipChainId = aOther.mClipChainId;
mSeparateLeaf = aOther.mSeparateLeaf;
}
} // namespace layers

Просмотреть файл

@ -1 +1 @@
fab59ceef070c11aba2a86c4ddf6ddc3c4e8f97d
3a4ce4b66a7bc9bd10773744d20530c609a61e90

8
gfx/wr/Cargo.lock сгенерированный
Просмотреть файл

@ -450,7 +450,7 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1229,12 +1229,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"expat-sys 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "servo-freetype-sys"
version = "4.0.3"
version = "4.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1901,7 +1901,7 @@ dependencies = [
"checksum serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f3ad6d546e765177cf3dded3c2e424a8040f870083a0e64064746b958ece9cb1"
"checksum servo-fontconfig 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a088f8d775a5c5314aae09bd77340bc9c67d72b9a45258be34c83548b4814cd9"
"checksum servo-fontconfig-sys 4.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "38b494f03009ee81914b0e7d387ad7c145cafcd69747c2ec89b0e17bb94f303a"
"checksum servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9232032c2e85118c0282c6562c84cab12316e655491ba0a5d1905b2320060d1b"
"checksum servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4ccb6d0d32d277d3ef7dea86203d8210945eb7a45fba89dd445b3595dd0dfc"
"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"
"checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0"
"checksum shared_library 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8254bf098ce4d8d7cc7cc6de438c5488adc5297e5b7ffef88816c0a91bd289c1"

Просмотреть файл

@ -1,5 +1,5 @@
before_test:
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/set-screenresolution.ps1'))
- ps: iex (Get-Content -Raw ci-scripts\set-screenresolution.ps1)
- ps: Set-ScreenResolution 1920 1080
environment:

Просмотреть файл

@ -0,0 +1,124 @@
# http://blogs.technet.com/b/heyscriptingguy/archive/2010/07/07/hey-scripting-guy-how-can-i-change-my-desktop-monitor-resolution-via-windows-powershell.aspx
Function Set-ScreenResolution {
param (
[Parameter(Mandatory=$true,
Position = 0)]
[int]
$Width,
[Parameter(Mandatory=$true,
Position = 1)]
[int]
$Height
)
$pinvokeCode = @"
using System;
using System.Runtime.InteropServices;
namespace Resolution
{
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE1
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public short dmOrientation;
public short dmPaperSize;
public short dmPaperLength;
public short dmPaperWidth;
public short dmScale;
public short dmCopies;
public short dmDefaultSource;
public short dmPrintQuality;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmFormName;
public short dmLogPixels;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
};
class User_32
{
[DllImport("user32.dll")]
public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE1 devMode);
[DllImport("user32.dll")]
public static extern int ChangeDisplaySettings(ref DEVMODE1 devMode, int flags);
public const int ENUM_CURRENT_SETTINGS = -1;
public const int CDS_UPDATEREGISTRY = 0x01;
public const int CDS_TEST = 0x02;
public const int DISP_CHANGE_SUCCESSFUL = 0;
public const int DISP_CHANGE_RESTART = 1;
public const int DISP_CHANGE_FAILED = -1;
}
public class PrmaryScreenResolution
{
static public string ChangeResolution(int width, int height)
{
DEVMODE1 dm = GetDevMode1();
if (0 != User_32.EnumDisplaySettings(null, User_32.ENUM_CURRENT_SETTINGS, ref dm))
{
dm.dmPelsWidth = width;
dm.dmPelsHeight = height;
int iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_TEST);
if (iRet == User_32.DISP_CHANGE_FAILED)
{
return "Unable To Process Your Request. Sorry For This Inconvenience.";
}
else
{
iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_UPDATEREGISTRY);
switch (iRet)
{
case User_32.DISP_CHANGE_SUCCESSFUL:
{
return "Success";
}
case User_32.DISP_CHANGE_RESTART:
{
return "You Need To Reboot For The Change To Happen.\n If You Feel Any Problem After Rebooting Your Machine\nThen Try To Change Resolution In Safe Mode.";
}
default:
{
return "Failed To Change The Resolution";
}
}
}
}
else
{
return "Failed To Change The Resolution.";
}
}
private static DEVMODE1 GetDevMode1()
{
DEVMODE1 dm = new DEVMODE1();
dm.dmDeviceName = new String(new char[32]);
dm.dmFormName = new String(new char[32]);
dm.dmSize = (short)Marshal.SizeOf(dm);
return dm;
}
}
}
"@
Add-Type $pinvokeCode -ErrorAction SilentlyContinue
[Resolution.PrmaryScreenResolution]::ChangeResolution($width,$height)
}

Просмотреть файл

@ -10,36 +10,26 @@
// for the various YUV modes. To save on the number of shaders we
// need to compile, it might be worth just doing this as an
// uber-shader instead.
// TODO(gw): Regardless of the above, we should remove the separate shader
// compilations for the different color space matrix below. That
// can be provided by a branch in the VS and pushed through the
// interpolators, or even as a uniform that breaks batches, rather
// that needing to compile to / select a different shader when
// there is a different color space.
#define YUV_COLOR_SPACE_REC601 0
#define YUV_COLOR_SPACE_REC709 1
#define YUV_FORMAT_NV12 0
#define YUV_FORMAT_PLANAR 1
#define YUV_FORMAT_INTERLEAVED 2
#ifdef WR_FEATURE_ALPHA_PASS
varying vec2 vLocalPos;
#endif
#if defined (WR_FEATURE_YUV_PLANAR)
varying vec3 vUv_Y;
flat varying vec4 vUvBounds_Y;
varying vec3 vUv_Y;
flat varying vec4 vUvBounds_Y;
varying vec3 vUv_U;
flat varying vec4 vUvBounds_U;
varying vec3 vUv_U;
flat varying vec4 vUvBounds_U;
varying vec3 vUv_V;
flat varying vec4 vUvBounds_V;
#elif defined (WR_FEATURE_YUV_NV12)
varying vec3 vUv_Y;
flat varying vec4 vUvBounds_Y;
varying vec3 vUv_UV;
flat varying vec4 vUvBounds_UV;
#elif defined (WR_FEATURE_YUV_INTERLEAVED)
varying vec3 vUv_YUV;
flat varying vec4 vUvBounds_YUV;
#endif
varying vec3 vUv_V;
flat varying vec4 vUvBounds_V;
#ifdef WR_FEATURE_TEXTURE_RECT
#define TEX_SIZE(sampler) vec2(1.0)
@ -48,8 +38,40 @@ varying vec2 vLocalPos;
#endif
flat varying float vCoefficient;
flat varying mat3 vYuvColorMatrix;
flat varying int vFormat;
#ifdef WR_VERTEX_SHADER
// The constants added to the Y, U and V components are applied in the fragment shader.
// From Rec601:
// [R] [1.1643835616438356, 0.0, 1.5960267857142858 ] [Y - 16]
// [G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708 ] x [U - 128]
// [B] [1.1643835616438356, 2.017232142857143, 8.862867620416422e-17] [V - 128]
//
// For the range [0,1] instead of [0,255].
//
// The matrix is stored in column-major.
const mat3 YuvColorMatrixRec601 = mat3(
1.16438, 1.16438, 1.16438,
0.0, -0.39176, 2.01723,
1.59603, -0.81297, 0.0
);
// From Rec709:
// [R] [1.1643835616438356, 4.2781193979771426e-17, 1.7927410714285714] [Y - 16]
// [G] = [1.1643835616438358, -0.21324861427372963, -0.532909328559444 ] x [U - 128]
// [B] [1.1643835616438356, 2.1124017857142854, 0.0 ] [V - 128]
//
// For the range [0,1] instead of [0,255]:
//
// The matrix is stored in column-major.
const mat3 YuvColorMatrixRec709 = mat3(
1.16438, 1.16438, 1.16438,
0.0 , -0.21325, 2.11240,
1.79274, -0.53291, 0.0
);
void write_uv_rect(
int resource_id,
vec2 f,
@ -74,11 +96,13 @@ void write_uv_rect(
struct YuvPrimitive {
float coefficient;
int color_space;
int yuv_format;
};
YuvPrimitive fetch_yuv_primitive(int address) {
vec4 data = fetch_from_gpu_cache_1(address);
return YuvPrimitive(data.x);
return YuvPrimitive(data.x, int(data.y), int(data.z));
}
void brush_vs(
@ -97,88 +121,60 @@ void brush_vs(
YuvPrimitive prim = fetch_yuv_primitive(prim_address);
vCoefficient = prim.coefficient;
if (prim.color_space == YUV_COLOR_SPACE_REC601) {
vYuvColorMatrix = YuvColorMatrixRec601;
} else {
vYuvColorMatrix = YuvColorMatrixRec709;
}
vFormat = prim.yuv_format;
#ifdef WR_FEATURE_ALPHA_PASS
vLocalPos = vi.local_pos;
#endif
#if defined (WR_FEATURE_YUV_PLANAR)
write_uv_rect(user_data.x, f, TEX_SIZE(sColor0), vUv_Y, vUvBounds_Y);
write_uv_rect(user_data.y, f, TEX_SIZE(sColor1), vUv_U, vUvBounds_U);
write_uv_rect(user_data.z, f, TEX_SIZE(sColor2), vUv_V, vUvBounds_V);
#elif defined (WR_FEATURE_YUV_NV12)
write_uv_rect(user_data.x, f, TEX_SIZE(sColor0), vUv_Y, vUvBounds_Y);
write_uv_rect(user_data.y, f, TEX_SIZE(sColor1), vUv_UV, vUvBounds_UV);
#elif defined (WR_FEATURE_YUV_INTERLEAVED)
write_uv_rect(user_data.x, f, TEX_SIZE(sColor0), vUv_YUV, vUvBounds_YUV);
#endif //WR_FEATURE_YUV_*
if (vFormat == YUV_FORMAT_PLANAR) {
write_uv_rect(user_data.x, f, TEX_SIZE(sColor0), vUv_Y, vUvBounds_Y);
write_uv_rect(user_data.y, f, TEX_SIZE(sColor1), vUv_U, vUvBounds_U);
write_uv_rect(user_data.z, f, TEX_SIZE(sColor2), vUv_V, vUvBounds_V);
} else if (vFormat == YUV_FORMAT_NV12) {
write_uv_rect(user_data.x, f, TEX_SIZE(sColor0), vUv_Y, vUvBounds_Y);
write_uv_rect(user_data.y, f, TEX_SIZE(sColor1), vUv_U, vUvBounds_U);
} else if (vFormat == YUV_FORMAT_INTERLEAVED) {
write_uv_rect(user_data.x, f, TEX_SIZE(sColor0), vUv_Y, vUvBounds_Y);
}
}
#endif
#ifdef WR_FRAGMENT_SHADER
#if !defined(WR_FEATURE_YUV_REC601) && !defined(WR_FEATURE_YUV_REC709)
#define WR_FEATURE_YUV_REC601
#endif
// The constants added to the Y, U and V components are applied in the fragment shader.
#if defined(WR_FEATURE_YUV_REC601)
// From Rec601:
// [R] [1.1643835616438356, 0.0, 1.5960267857142858 ] [Y - 16]
// [G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708 ] x [U - 128]
// [B] [1.1643835616438356, 2.017232142857143, 8.862867620416422e-17] [V - 128]
//
// For the range [0,1] instead of [0,255].
//
// The matrix is stored in column-major.
const mat3 YuvColorMatrix = mat3(
1.16438, 1.16438, 1.16438,
0.0, -0.39176, 2.01723,
1.59603, -0.81297, 0.0
);
#elif defined(WR_FEATURE_YUV_REC709)
// From Rec709:
// [R] [1.1643835616438356, 4.2781193979771426e-17, 1.7927410714285714] [Y - 16]
// [G] = [1.1643835616438358, -0.21324861427372963, -0.532909328559444 ] x [U - 128]
// [B] [1.1643835616438356, 2.1124017857142854, 0.0 ] [V - 128]
//
// For the range [0,1] instead of [0,255]:
//
// The matrix is stored in column-major.
const mat3 YuvColorMatrix = mat3(
1.16438, 1.16438, 1.16438,
0.0 , -0.21325, 2.11240,
1.79274, -0.53291, 0.0
);
#endif
Fragment brush_fs() {
vec3 yuv_value;
#if defined (WR_FEATURE_YUV_PLANAR)
// The yuv_planar format should have this third texture coordinate.
vec2 uv_y = clamp(vUv_Y.xy, vUvBounds_Y.xy, vUvBounds_Y.zw);
vec2 uv_u = clamp(vUv_U.xy, vUvBounds_U.xy, vUvBounds_U.zw);
vec2 uv_v = clamp(vUv_V.xy, vUvBounds_V.xy, vUvBounds_V.zw);
yuv_value.x = TEX_SAMPLE(sColor0, vec3(uv_y, vUv_Y.z)).r;
yuv_value.y = TEX_SAMPLE(sColor1, vec3(uv_u, vUv_U.z)).r;
yuv_value.z = TEX_SAMPLE(sColor2, vec3(uv_v, vUv_V.z)).r;
#elif defined (WR_FEATURE_YUV_NV12)
vec2 uv_y = clamp(vUv_Y.xy, vUvBounds_Y.xy, vUvBounds_Y.zw);
vec2 uv_uv = clamp(vUv_UV.xy, vUvBounds_UV.xy, vUvBounds_UV.zw);
yuv_value.x = TEX_SAMPLE(sColor0, vec3(uv_y, vUv_Y.z)).r;
yuv_value.yz = TEX_SAMPLE(sColor1, vec3(uv_uv, vUv_UV.z)).rg;
#elif defined (WR_FEATURE_YUV_INTERLEAVED)
// "The Y, Cb and Cr color channels within the 422 data are mapped into
// the existing green, blue and red color channels."
// https://www.khronos.org/registry/OpenGL/extensions/APPLE/APPLE_rgb_422.txt
vec2 uv_y = clamp(vUv_YUV.xy, vUvBounds_YUV.xy, vUvBounds_YUV.zw);
yuv_value = TEX_SAMPLE(sColor0, vec3(uv_y, vUv_YUV.z)).gbr;
#else
yuv_value = vec3(0.0);
#endif
if (vFormat == YUV_FORMAT_PLANAR) {
// The yuv_planar format should have this third texture coordinate.
vec2 uv_y = clamp(vUv_Y.xy, vUvBounds_Y.xy, vUvBounds_Y.zw);
vec2 uv_u = clamp(vUv_U.xy, vUvBounds_U.xy, vUvBounds_U.zw);
vec2 uv_v = clamp(vUv_V.xy, vUvBounds_V.xy, vUvBounds_V.zw);
yuv_value.x = TEX_SAMPLE(sColor0, vec3(uv_y, vUv_Y.z)).r;
yuv_value.y = TEX_SAMPLE(sColor1, vec3(uv_u, vUv_U.z)).r;
yuv_value.z = TEX_SAMPLE(sColor2, vec3(uv_v, vUv_V.z)).r;
} else if (vFormat == YUV_FORMAT_NV12) {
vec2 uv_y = clamp(vUv_Y.xy, vUvBounds_Y.xy, vUvBounds_Y.zw);
vec2 uv_uv = clamp(vUv_U.xy, vUvBounds_U.xy, vUvBounds_U.zw);
yuv_value.x = TEX_SAMPLE(sColor0, vec3(uv_y, vUv_Y.z)).r;
yuv_value.yz = TEX_SAMPLE(sColor1, vec3(uv_uv, vUv_U.z)).rg;
} else if (vFormat == YUV_FORMAT_INTERLEAVED) {
// "The Y, Cb and Cr color channels within the 422 data are mapped into
// the existing green, blue and red color channels."
// https://www.khronos.org/registry/OpenGL/extensions/APPLE/APPLE_rgb_422.txt
vec2 uv_y = clamp(vUv_Y.xy, vUvBounds_Y.xy, vUvBounds_Y.zw);
yuv_value = TEX_SAMPLE(sColor0, vec3(uv_y, vUv_Y.z)).gbr;
} else {
yuv_value = vec3(0.0);
}
// See the YuvColorMatrix definition for an explanation of where the constants come from.
vec3 rgb = YuvColorMatrix * (yuv_value * vCoefficient - vec3(0.06275, 0.50196, 0.50196));
vec3 rgb = vYuvColorMatrix * (yuv_value * vCoefficient - vec3(0.06275, 0.50196, 0.50196));
vec4 color = vec4(rgb, 1.0);
#ifdef WR_FEATURE_ALPHA_PASS

Просмотреть файл

@ -1155,12 +1155,10 @@ impl AlphaBatchBuilder {
get_shader_opacity(1.0),
]);
let shadow_rect = picture.local_rect.translate(&offset);
let shadow_clip_rect = picture.local_clip_rect.translate(&offset);
let shadow_rect = prim_header.local_rect.translate(&offset);
let shadow_prim_header = PrimitiveHeader {
local_rect: shadow_rect,
local_clip_rect: shadow_clip_rect,
specific_prim_address: shadow_prim_address,
..prim_header
};

Просмотреть файл

@ -527,7 +527,7 @@ impl ClipStore {
resource_cache: &mut ResourceCache,
device_pixel_scale: DevicePixelScale,
world_rect: &WorldRect,
clip_node_collector: &Option<ClipNodeCollector>,
clip_node_collector: Option<&ClipNodeCollector>,
clip_data_store: &mut ClipDataStore,
) -> Option<ClipChainInstance> {
let mut local_clip_rect = local_prim_clip_rect;
@ -898,6 +898,8 @@ impl ClipItemKey {
}
}
impl intern::InternDebug for ClipItemKey {}
#[derive(Debug)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]

Просмотреть файл

@ -184,8 +184,8 @@ fn get_shader_version(gl: &gl::Gl) -> &'static str {
// Get a shader string by name, from the built in resources or
// an override path, if supplied.
fn get_shader_source(shader_name: &str, base_path: &Option<PathBuf>) -> Option<Cow<'static, str>> {
if let Some(ref base) = *base_path {
fn get_shader_source(shader_name: &str, base_path: Option<&PathBuf>) -> Option<Cow<'static, str>> {
if let Some(ref base) = base_path {
let shader_path = base.join(&format!("{}.glsl", shader_name));
if shader_path.exists() {
let mut source = String::new();
@ -204,7 +204,7 @@ fn get_shader_source(shader_name: &str, base_path: &Option<PathBuf>) -> Option<C
// Parse a shader string for imports. Imports are recursively processed, and
// prepended to the output stream.
fn parse_shader_source<F: FnMut(&str)>(source: Cow<'static, str>, base_path: &Option<PathBuf>, output: &mut F) {
fn parse_shader_source<F: FnMut(&str)>(source: Cow<'static, str>, base_path: Option<&PathBuf>, output: &mut F) {
for line in source.lines() {
if line.starts_with(SHADER_IMPORT) {
let imports = line[SHADER_IMPORT.len() ..].split(',');
@ -228,7 +228,7 @@ pub fn build_shader_strings(
gl_version_string: &str,
features: &str,
base_filename: &str,
override_path: &Option<PathBuf>,
override_path: Option<&PathBuf>,
) -> (String, String) {
let mut vs_source = String::new();
do_build_shader_string(
@ -261,7 +261,7 @@ fn do_build_shader_string<F: FnMut(&str)>(
features: &str,
kind: &str,
base_filename: &str,
override_path: &Option<PathBuf>,
override_path: Option<&PathBuf>,
mut output: F,
) {
// GLSL requires that the version number comes first.
@ -2052,7 +2052,7 @@ impl Device {
features,
kind,
base_filename,
&self.resource_override_path,
self.resource_override_path.as_ref(),
output,
)
}

Просмотреть файл

@ -19,7 +19,7 @@ use frame_builder::{ChasePrimitive, FrameBuilder, FrameBuilderConfig};
use glyph_rasterizer::FontInstance;
use hit_test::{HitTestingItem, HitTestingRun};
use image::simplify_repeated_primitive;
use intern::{Handle, Internable};
use intern::{Handle, Internable, InternDebug};
use internal_types::{FastHashMap, FastHashSet};
use picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PrimitiveList};
use prim_store::{PrimitiveInstance, PrimitiveKeyKind};
@ -273,7 +273,7 @@ impl<'a> DisplayListFlattener<'a> {
main_scroll_root = Some(scroll_root);
true
}
}).unwrap_or(primitives.len());
});
let main_scroll_root = match main_scroll_root {
Some(main_scroll_root) => main_scroll_root,
@ -286,20 +286,38 @@ impl<'a> DisplayListFlattener<'a> {
Vec::new(),
);
// Split off the preceding primtives.
let mut remaining_prims = old_prim_list.split_off(first_index);
// In the simple case, there are no preceding or trailing primitives,
// because everything is anchored to the root scroll node. Handle
// this case specially to avoid underflow error in the Some(..)
// path below.
// Find the first primitive in reverse order that is not the root scroll node.
let last_index = remaining_prims.iter().rposition(|instance| {
let scroll_root = self.find_scroll_root(
instance.spatial_node_index,
);
let preceding_prims;
let mut remaining_prims;
let trailing_prims;
scroll_root != ROOT_SPATIAL_NODE_INDEX
}).unwrap_or(remaining_prims.len() - 1);
match first_index {
Some(first_index) => {
// Split off the preceding primtives.
remaining_prims = old_prim_list.split_off(first_index);
let preceding_prims = old_prim_list;
let trailing_prims = remaining_prims.split_off(last_index + 1);
// Find the first primitive in reverse order that is not the root scroll node.
let last_index = remaining_prims.iter().rposition(|instance| {
let scroll_root = self.find_scroll_root(
instance.spatial_node_index,
);
scroll_root != ROOT_SPATIAL_NODE_INDEX
}).unwrap_or(remaining_prims.len() - 1);
preceding_prims = old_prim_list;
trailing_prims = remaining_prims.split_off(last_index + 1);
}
None => {
preceding_prims = Vec::new();
remaining_prims = old_prim_list;
trailing_prims = Vec::new();
}
}
let prim_list = PrimitiveList::new(
remaining_prims,
@ -1027,7 +1045,7 @@ impl<'a> DisplayListFlattener<'a> {
) -> PrimitiveInstance
where
P: Internable<InternData=PrimitiveSceneData>,
P::Source: AsInstanceKind<Handle<P::Marker>>,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug,
DocumentResources: InternerMut<P>,
{
let offset = info.rect.origin.to_vector();
@ -1107,7 +1125,7 @@ impl<'a> DisplayListFlattener<'a> {
)
where
P: Internable<InternData = PrimitiveSceneData> + IsVisible,
P::Source: AsInstanceKind<Handle<P::Marker>>,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug,
DocumentResources: InternerMut<P>,
{
if prim.is_visible() {
@ -1134,7 +1152,7 @@ impl<'a> DisplayListFlattener<'a> {
)
where
P: Internable<InternData = PrimitiveSceneData> + IsVisible,
P::Source: AsInstanceKind<Handle<P::Marker>>,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug,
DocumentResources: InternerMut<P>,
ShadowItem: From<PendingPrimitive<P>>
{
@ -1164,7 +1182,7 @@ impl<'a> DisplayListFlattener<'a> {
)
where
P: Internable<InternData = PrimitiveSceneData>,
P::Source: AsInstanceKind<Handle<P::Marker>>,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug,
DocumentResources: InternerMut<P>,
{
let prim_instance = self.create_primitive(
@ -1899,7 +1917,7 @@ impl<'a> DisplayListFlattener<'a> {
)
where
P: Internable<InternData=PrimitiveSceneData> + CreateShadow,
P::Source: AsInstanceKind<Handle<P::Marker>>,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug,
DocumentResources: InternerMut<P>,
{
// Offset the local rect and clip rect by the shadow offset.
@ -1924,7 +1942,7 @@ impl<'a> DisplayListFlattener<'a> {
fn add_shadow_prim_to_draw_list<P>(&mut self, pending_primitive: PendingPrimitive<P>)
where
P: Internable<InternData = PrimitiveSceneData> + IsVisible,
P::Source: AsInstanceKind<Handle<P::Marker>>,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug,
DocumentResources: InternerMut<P>,
{
// For a normal primitive, if it has alpha > 0, then we add this
@ -2558,7 +2576,7 @@ impl FlattenedStackingContext {
return false;
}
// If different clipp chains
// If different clip chains
if self.clip_chain_id != parent.clip_chain_id {
return false;
}

Просмотреть файл

@ -490,8 +490,9 @@ impl FrameBuilder {
&mut z_generator,
);
if let RenderPassKind::OffScreen { ref texture_cache, .. } = pass.kind {
if let RenderPassKind::OffScreen { ref texture_cache, ref color, .. } = pass.kind {
has_texture_cache_tasks |= !texture_cache.is_empty();
has_texture_cache_tasks |= color.must_be_drawn();
}
}

Просмотреть файл

@ -352,11 +352,10 @@ impl SubpixelOffset {
let apos = ((pos - pos.floor()) * 8.0) as i32;
match apos {
0 | 7 => SubpixelOffset::Zero,
1...2 => SubpixelOffset::Quarter,
3...4 => SubpixelOffset::Half,
5...6 => SubpixelOffset::ThreeQuarters,
_ => unreachable!("bug: unexpected quantized result"),
_ => SubpixelOffset::Zero,
}
}
}

Просмотреть файл

@ -126,6 +126,10 @@ struct Item<T> {
data: T,
}
pub trait InternDebug {
fn on_interned(&self, _uid: ItemUid) {}
}
/// The data store lives in the frame builder thread. It
/// contains a free-list of items for fast access.
#[cfg_attr(feature = "capture", derive(Serialize))]
@ -252,7 +256,7 @@ where
impl<S, D, M> Interner<S, D, M>
where
S: Eq + Hash + Clone + Debug,
S: Eq + Hash + Clone + Debug + InternDebug,
M: Copy + Debug
{
/// Intern a data structure, and return a handle to
@ -309,6 +313,9 @@ where
_marker: PhantomData,
};
#[cfg(debug_assertions)]
data.on_interned(handle.uid);
// Store this handle so the next time it is
// interned, it gets re-used.
self.map.insert(data.clone(), handle);

Просмотреть файл

@ -22,6 +22,7 @@ use plane_split::{Clipper, Polygon, Splitter};
use prim_store::{PictureIndex, PrimitiveInstance, SpaceMapper, VisibleFace, PrimitiveInstanceKind};
use prim_store::{get_raster_rects, CoordinateSpaceMapping, PointKey};
use prim_store::{OpacityBindingStorage, PrimitiveTemplateKind, ImageInstanceStorage, OpacityBindingIndex, SizeKey};
use print_tree::PrintTreePrinter;
use render_backend::FrameResources;
use render_task::{ClearMode, RenderTask, RenderTaskCacheEntryHandle, TileBlit};
use render_task::{RenderTaskCacheKey, RenderTaskCacheKeyKind, RenderTaskId, RenderTaskLocation};
@ -81,6 +82,9 @@ pub type TileRect = TypedRect<i32, TileCoordinate>;
pub const TILE_SIZE_WIDTH: i32 = 1024;
pub const TILE_SIZE_HEIGHT: i32 = 256;
/// The maximum size of a picture before we disable tile caching.
const MAX_PICTURE_SIZE: f32 = 65536.0;
/// Information about the state of a transform dependency.
#[derive(Debug)]
pub struct TileTransformInfo {
@ -407,6 +411,13 @@ impl TileCache {
frame_context: &FrameBuildingContext,
pic_rect: LayoutRect,
) {
// If we previously disabled the tile cache due to an invalid
// picture rect, and then we re-enable it, force an update
// of all primitive dependencies.
if self.tile_rect.size.is_empty_or_negative() {
self.needs_update = true;
}
// Initialize the space mapper with current bounds,
// which is used during primitive dependency updates.
let world_mapper = SpaceMapper::new_with_target(
@ -674,6 +685,7 @@ impl TileCache {
pub fn update_prim_dependencies(
&mut self,
prim_instance: &PrimitiveInstance,
prim_list: &PrimitiveList,
surface_spatial_node_index: SpatialNodeIndex,
clip_scroll_tree: &ClipScrollTree,
resources: &FrameResources,
@ -687,6 +699,32 @@ impl TileCache {
return;
}
// We need to ensure that if a primitive belongs to a cluster that has
// been marked invisible, we exclude it here. Otherwise, we may end up
// with a primitive that is outside the bounding rect of the calculated
// picture rect (which takes the cluster visibility into account).
// TODO(gw): It turns out that we have ended up having only a single
// cluster per primitive rather than a range. In future,
// we should tidy this up to take advantage of this!
let mut in_visible_cluster = false;
for ci in prim_instance.cluster_range.start .. prim_instance.cluster_range.end {
// Map from the cluster range index to a cluster index
let cluster_index = prim_list.prim_cluster_map[ci as usize];
// Get the cluster and see if is visible
let cluster = &prim_list.clusters[cluster_index.0 as usize];
in_visible_cluster |= cluster.is_visible;
// As soon as a primitive is in a visible cluster, it's considered
// visible and we don't need to consult other clusters.
if cluster.is_visible {
break;
}
}
if !in_visible_cluster {
return;
}
self.space_mapper.set_target_spatial_node(
prim_instance.spatial_node_index,
clip_scroll_tree,
@ -694,13 +732,23 @@ impl TileCache {
let prim_data = &resources.as_common_data(&prim_instance);
let prim_rect = LayoutRect::new(
prim_instance.prim_origin,
prim_data.prim_size,
);
let clip_rect = prim_data
.prim_relative_clip_rect
.translate(&prim_instance.prim_origin.to_vector());
let (prim_rect, clip_rect) = match prim_instance.kind {
PrimitiveInstanceKind::Picture { pic_index, .. } => {
let pic = &pictures[pic_index.0];
(pic.local_rect, LayoutRect::max_rect())
}
_ => {
let prim_rect = LayoutRect::new(
prim_instance.prim_origin,
prim_data.prim_size,
);
let clip_rect = prim_data
.prim_relative_clip_rect
.translate(&prim_instance.prim_origin.to_vector());
(prim_rect, clip_rect)
}
};
// Map the primitive local rect into the picture space.
// TODO(gw): We should maybe store this in the primitive template
@ -812,7 +860,7 @@ impl TileCache {
// We only care about clip nodes that have transforms that are children
// of the surface, since clips that are positioned by parents will be
// handled by the clip collector when these tiles are composited.
if clip_chain_node.spatial_node_index > surface_spatial_node_index {
if clip_chain_node.spatial_node_index >= surface_spatial_node_index {
clip_chain_spatial_nodes.push(clip_chain_node.spatial_node_index);
clip_chain_uids.push(clip_chain_node.handle.uid());
}
@ -1502,6 +1550,29 @@ pub struct PicturePrimitive {
}
impl PicturePrimitive {
pub fn print<T: PrintTreePrinter>(
&self,
pictures: &[Self],
self_index: PictureIndex,
pt: &mut T,
) {
pt.new_level(format!("{:?}", self_index));
pt.add_item(format!("prim_count: {:?}", self.prim_list.prim_instances.len()));
pt.add_item(format!("local_rect: {:?}", self.local_rect));
if self.apply_local_clip_rect {
pt.add_item(format!("local_clip_rect: {:?}", self.local_clip_rect));
}
pt.add_item(format!("spatial_node_index: {:?}", self.spatial_node_index));
pt.add_item(format!("raster_config: {:?}", self.raster_config));
pt.add_item(format!("requested_composite_mode: {:?}", self.requested_composite_mode));
for index in &self.prim_list.pictures {
pictures[index.0].print(pictures, *index, pt);
}
pt.end_level();
}
fn resolve_scene_properties(&mut self, properties: &SceneProperties) -> bool {
match self.requested_composite_mode {
Some(PictureCompositeMode::Filter(ref mut filter)) => {
@ -1993,6 +2064,7 @@ impl PicturePrimitive {
for prim_instance in &self.prim_list.prim_instances {
tile_cache.update_prim_dependencies(
prim_instance,
&self.prim_list,
surface_spatial_node_index,
&frame_context.clip_scroll_tree,
resources,
@ -2094,9 +2166,28 @@ impl PicturePrimitive {
// If this picture establishes a surface, then map the surface bounding
// rect into the parent surface coordinate space, and propagate that up
// to the parent.
if let Some(ref raster_config) = self.raster_config {
if let Some(ref mut raster_config) = self.raster_config {
let surface_rect = state.current_surface().rect;
// Sometimes, Gecko supplies a huge picture rect. This is typically
// due to some weird startup condition, or a reftest that has an
// extreme scale in it. In these cases, disable the tile cache and
// just use the normal Blit composite mode for this picture. This
// is not ideal (we could skip the surface altogether in the future)
// but it's simple and works around this edge case for now.
if let Some(ref mut tile_cache) = self.tile_cache {
if surface_rect.size.width > MAX_PICTURE_SIZE ||
surface_rect.size.height > MAX_PICTURE_SIZE ||
surface_rect.size.width <= 0.0 ||
surface_rect.size.height <= 0.0
{
tile_cache.needs_update = false;
tile_cache.tiles.clear();
tile_cache.tile_rect = TileRect::zero();
raster_config.composite_mode = PictureCompositeMode::Blit;
}
}
let mut surface_rect = TypedRect::from_untyped(&surface_rect.to_untyped());
// Pop this surface from the stack

Просмотреть файл

@ -9,7 +9,7 @@ use api::{
use display_list_flattener::{AsInstanceKind, IsVisible};
use frame_builder::FrameBuildingState;
use gpu_cache::{GpuCacheHandle, GpuDataRequest};
use intern::{DataStore, Handle, Internable, Interner, UpdateList};
use intern::{DataStore, Handle, Internable, InternDebug, Interner, UpdateList};
use prim_store::{BrushSegment, GradientTileRange};
use prim_store::{PrimitiveInstanceKind, PrimitiveOpacity, PrimitiveSceneData};
use prim_store::{PrimKeyCommonData, PrimTemplateCommonData, PrimitiveStore};
@ -76,6 +76,8 @@ impl LinearGradientKey {
}
}
impl InternDebug for LinearGradientKey {}
impl AsInstanceKind<LinearGradientDataHandle> for LinearGradientKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
@ -333,6 +335,8 @@ impl RadialGradientKey {
}
}
impl InternDebug for RadialGradientKey {}
impl AsInstanceKind<RadialGradientDataHandle> for RadialGradientKey {
/// Construct a primitive instance that matches the type
/// of primitive key.

Просмотреть файл

@ -26,7 +26,7 @@ use gpu_types::BrushFlags;
use image::{self, Repetition};
use intern;
use picture::{PictureCompositeMode, PicturePrimitive, PictureUpdateState, TileCacheUpdateState};
use picture::{ClusterRange, PrimitiveList, SurfaceIndex, SurfaceInfo, RetainedTiles};
use picture::{ClusterRange, PrimitiveList, SurfaceIndex, SurfaceInfo, RetainedTiles, RasterConfig};
use prim_store::gradient::{LinearGradientDataHandle, RadialGradientDataHandle};
use prim_store::text_run::{TextRunDataHandle, TextRunPrimitive};
#[cfg(debug_assertions)]
@ -645,6 +645,8 @@ impl PrimitiveKey {
}
}
impl intern::InternDebug for PrimitiveKey {}
impl AsInstanceKind<PrimitiveDataHandle> for PrimitiveKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
@ -962,11 +964,11 @@ impl PrimitiveTemplateKind {
}
}
}
PrimitiveTemplateKind::YuvImage { color_depth, .. } => {
PrimitiveTemplateKind::YuvImage { color_depth, format, color_space, .. } => {
request.push([
color_depth.rescaling_factor(),
0.0,
0.0,
pack_as_float(color_space as u32),
pack_as_float(format as u32),
0.0
]);
}
@ -2120,6 +2122,13 @@ impl PrimitiveStore {
}
}
#[allow(unused)]
pub fn print_picture_tree(&self, root: PictureIndex) {
use print_tree::PrintTree;
let mut pt = PrintTree::new("picture tree");
self.pictures[root.0].print(&self.pictures, root, &mut pt);
}
/// Destroy an existing primitive store. This is called just before
/// a primitive store is replaced with a newly built scene.
pub fn destroy(
@ -2194,7 +2203,12 @@ impl PrimitiveStore {
) {
let children = {
let pic = &mut self.pictures[pic_index.0];
if let Some(PictureCompositeMode::TileCache { .. }) = pic.requested_composite_mode {
// Only update the tile cache if we ended up selecting tile caching for the
// composite mode of this picture. In some cases, even if the requested
// composite mode was tile caching, WR may choose not to draw this picture
// with tile cache enabled. For now, this is only in the case of very large
// picture rects, but in future we may do it for performance reasons too.
if let Some(RasterConfig { composite_mode: PictureCompositeMode::TileCache { .. }, .. }) = pic.raster_config {
debug_assert!(state.tile_cache.is_none());
let mut tile_cache = pic.tile_cache.take().unwrap();
@ -2246,7 +2260,7 @@ impl PrimitiveStore {
}
let pic = &mut self.pictures[pic_index.0];
if let Some(PictureCompositeMode::TileCache { .. }) = pic.requested_composite_mode {
if let Some(RasterConfig { composite_mode: PictureCompositeMode::TileCache { .. }, .. }) = pic.raster_config {
let mut tile_cache = state.tile_cache.take().unwrap().0;
// Build the dirty region(s) for this tile cache.
@ -2561,7 +2575,7 @@ impl PrimitiveStore {
frame_state.resource_cache,
frame_context.device_pixel_scale,
&pic_context.dirty_world_rect,
&clip_node_collector,
clip_node_collector.as_ref(),
&mut resources.clip_data_store,
);
@ -2621,7 +2635,7 @@ impl PrimitiveStore {
pic_state,
frame_context,
frame_state,
&clip_node_collector,
clip_node_collector.as_ref(),
self,
resources,
scratch,
@ -3580,7 +3594,7 @@ impl PrimitiveInstance {
pic_state: &mut PictureState,
frame_context: &FrameBuildingContext,
frame_state: &mut FrameBuildingState,
clip_node_collector: &Option<ClipNodeCollector>,
clip_node_collector: Option<&ClipNodeCollector>,
prim_store: &PrimitiveStore,
resources: &mut FrameResources,
scratch: &mut PrimitiveScratchBuffer,
@ -3748,7 +3762,7 @@ impl PrimitiveInstance {
pic_state: &mut PictureState,
frame_context: &FrameBuildingContext,
frame_state: &mut FrameBuildingState,
clip_node_collector: &Option<ClipNodeCollector>,
clip_node_collector: Option<&ClipNodeCollector>,
prim_store: &mut PrimitiveStore,
resources: &mut FrameResources,
scratch: &mut PrimitiveScratchBuffer,

Просмотреть файл

@ -52,6 +52,8 @@ impl TextRunKey {
}
}
impl intern::InternDebug for TextRunKey {}
impl AsInstanceKind<TextRunDataHandle> for TextRunKey {
/// Construct a primitive instance that matches the type
/// of primitive key.

Просмотреть файл

@ -2,10 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{
YUV_COLOR_SPACES, YUV_FORMATS,
YuvColorSpace, YuvFormat,
};
use batch::{BatchKey, BatchKind, BrushBatchKind};
use device::{Device, Program, ShaderError};
use euclid::{Transform3D};
@ -635,7 +631,7 @@ impl Shaders {
// All yuv_image configuration.
let mut yuv_features = Vec::new();
let yuv_shader_num = IMAGE_BUFFER_KINDS.len() * YUV_FORMATS.len() * YUV_COLOR_SPACES.len();
let yuv_shader_num = IMAGE_BUFFER_KINDS.len();
let mut brush_yuv_image = Vec::new();
// PrimitiveShader is not clonable. Use push() to initialize the vec.
for _ in 0 .. yuv_shader_num {
@ -643,37 +639,23 @@ impl Shaders {
}
for image_buffer_kind in &IMAGE_BUFFER_KINDS {
if image_buffer_kind.has_platform_support(&gl_type) {
for format_kind in &YUV_FORMATS {
for color_space_kind in &YUV_COLOR_SPACES {
let feature_string = image_buffer_kind.get_feature_string();
if feature_string != "" {
yuv_features.push(feature_string);
}
let feature_string = format_kind.get_feature_string();
if feature_string != "" {
yuv_features.push(feature_string);
}
let feature_string = color_space_kind.get_feature_string();
if feature_string != "" {
yuv_features.push(feature_string);
}
let shader = BrushShader::new(
"brush_yuv_image",
device,
&yuv_features,
options.precache_flags,
false,
)?;
let index = Self::get_yuv_shader_index(
*image_buffer_kind,
*format_kind,
*color_space_kind,
);
brush_yuv_image[index] = Some(shader);
yuv_features.clear();
}
let feature_string = image_buffer_kind.get_feature_string();
if feature_string != "" {
yuv_features.push(feature_string);
}
let shader = BrushShader::new(
"brush_yuv_image",
device,
&yuv_features,
options.precache_flags,
false,
)?;
let index = Self::get_yuv_shader_index(
*image_buffer_kind,
);
brush_yuv_image[index] = Some(shader);
yuv_features.clear();
}
}
@ -733,13 +715,8 @@ impl Shaders {
})
}
fn get_yuv_shader_index(
buffer_kind: ImageBufferKind,
format: YuvFormat,
color_space: YuvColorSpace,
) -> usize {
((buffer_kind as usize) * YUV_FORMATS.len() + (format as usize)) * YUV_COLOR_SPACES.len() +
(color_space as usize)
fn get_yuv_shader_index(buffer_kind: ImageBufferKind) -> usize {
(buffer_kind as usize)
}
pub fn get(&mut self, key: &BatchKey, debug_flags: DebugFlags) -> &mut LazilyCompiledShader {
@ -769,9 +746,9 @@ impl Shaders {
BrushBatchKind::LinearGradient => {
&mut self.brush_linear_gradient
}
BrushBatchKind::YuvImage(image_buffer_kind, format, _color_depth, color_space) => {
BrushBatchKind::YuvImage(image_buffer_kind, ..) => {
let shader_index =
Self::get_yuv_shader_index(image_buffer_kind, format, color_space);
Self::get_yuv_shader_index(image_buffer_kind);
self.brush_yuv_image[shader_index]
.as_mut()
.expect("Unsupported YUV shader kind")

Просмотреть файл

@ -110,6 +110,7 @@ pub trait RenderTarget {
);
fn needs_depth(&self) -> bool;
fn must_be_drawn(&self) -> bool;
fn used_rect(&self) -> DeviceIntRect;
fn add_used(&mut self, rect: DeviceIntRect);
@ -258,6 +259,10 @@ impl<T: RenderTarget> RenderTargetList<T> {
self.targets.iter().any(|target| target.needs_depth())
}
pub fn must_be_drawn(&self) -> bool {
self.targets.iter().any(|target| target.must_be_drawn())
}
pub fn check_ready(&self, t: &Texture) {
let dimensions = t.get_dimensions();
assert!(dimensions.width >= self.max_dynamic_size.width);
@ -544,6 +549,10 @@ impl RenderTarget for ColorRenderTarget {
}
}
fn must_be_drawn(&self) -> bool {
!self.tile_blits.is_empty()
}
fn needs_depth(&self) -> bool {
self.alpha_batch_containers.iter().any(|ab| {
!ab.opaque_batches.is_empty()
@ -674,6 +683,10 @@ impl RenderTarget for AlphaRenderTarget {
false
}
fn must_be_drawn(&self) -> bool {
false
}
fn used_rect(&self) -> DeviceIntRect {
self.used_rect
}

Просмотреть файл

@ -125,7 +125,7 @@ fn validate_shaders() {
}
let (vs, fs) =
webrender::build_shader_strings(VERSION_STRING, &features, shader.name, &None);
webrender::build_shader_strings(VERSION_STRING, &features, shader.name, None);
validate(&vs_validator, shader.name, vs);
validate(&fs_validator, shader.name, fs);

Просмотреть файл

@ -689,16 +689,6 @@ pub enum YuvColorSpace {
Rec601 = 0,
Rec709 = 1,
}
pub const YUV_COLOR_SPACES: [YuvColorSpace; 2] = [YuvColorSpace::Rec601, YuvColorSpace::Rec709];
impl YuvColorSpace {
pub fn get_feature_string(&self) -> &'static str {
match *self {
YuvColorSpace::Rec601 => "YUV_REC601",
YuvColorSpace::Rec709 => "YUV_REC709",
}
}
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum YuvData {
@ -723,11 +713,6 @@ pub enum YuvFormat {
PlanarYCbCr = 1,
InterleavedYCbCr = 2,
}
pub const YUV_FORMATS: [YuvFormat; 3] = [
YuvFormat::NV12,
YuvFormat::PlanarYCbCr,
YuvFormat::InterleavedYCbCr,
];
impl YuvFormat {
pub fn get_plane_num(&self) -> usize {
@ -737,14 +722,6 @@ impl YuvFormat {
YuvFormat::InterleavedYCbCr => 1,
}
}
pub fn get_feature_string(&self) -> &'static str {
match *self {
YuvFormat::NV12 => "YUV_NV12",
YuvFormat::PlanarYCbCr => "YUV_PLANAR",
YuvFormat::InterleavedYCbCr => "YUV_INTERLEAVED",
}
}
}
#[repr(C)]

Двоичные данные
gfx/wr/wrench/reftests/filters/filter-drop-shadow-clip.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 9.8 KiB

Просмотреть файл

@ -0,0 +1,22 @@
---
root:
items:
- type: clip
id: 2
bounds: [100, 100, 2000, 2000]
clip-rect: [100, 100, 2000, 2000]
items:
- type: stacking-context
bounds: [10, 10, 0, 0]
filters: drop-shadow([10, 10], 20, red)
clip-node: 2
items:
- type: clip
bounds: [0, 0, 256, 256]
complex:
- rect: [0, 0, 256, 256]
radius: 16
items:
- type: rect
bounds: 0 0 256 256
color: green

Просмотреть файл

@ -33,6 +33,7 @@ fuzzy(1,14) == filter-long-chain.yaml filter-long-chain.png
platform(linux,mac) == filter-drop-shadow.yaml filter-drop-shadow.png
platform(linux,mac) == filter-drop-shadow-on-viewport-edge.yaml filter-drop-shadow-on-viewport-edge.png
platform(linux,mac) == blend-clipped.yaml blend-clipped.png
platform(linux,mac) == filter-drop-shadow-clip.yaml filter-drop-shadow-clip.png
== filter-segments.yaml filter-segments-ref.yaml
== iframe-dropshadow.yaml iframe-dropshadow-ref.yaml
== filter-mix-blend-mode.yaml filter-mix-blend-mode-ref.yaml

Просмотреть файл

@ -9,6 +9,10 @@
#include "nsStreamUtils.h"
#include "gfxColor.h"
extern "C" {
#include "jpeglib.h"
}
#include <setjmp.h>
#include "jerror.h"
@ -17,6 +21,45 @@ using namespace mozilla;
NS_IMPL_ISUPPORTS(nsJPEGEncoder, imgIEncoder, nsIInputStream,
nsIAsyncInputStream)
class nsJPEGEncoderInternal {
friend class nsJPEGEncoder;
protected:
/**
* Initialize destination. This is called by jpeg_start_compress() before
* any data is actually written. It must initialize next_output_byte and
* free_in_buffer. free_in_buffer must be initialized to a positive value.
*/
static void initDestination(jpeg_compress_struct* cinfo);
/**
* This is called whenever the buffer has filled (free_in_buffer reaches
* zero). In typical applications, it should write out the *entire* buffer
* (use the saved start address and buffer length; ignore the current state
* of next_output_byte and free_in_buffer). Then reset the pointer & count
* to the start of the buffer, and return TRUE indicating that the buffer
* has been dumped. free_in_buffer must be set to a positive value when
* TRUE is returned. A FALSE return should only be used when I/O suspension
* is desired (this operating mode is discussed in the next section).
*/
static boolean emptyOutputBuffer(jpeg_compress_struct* cinfo);
/**
* Terminate destination --- called by jpeg_finish_compress() after all data
* has been written. In most applications, this must flush any data
* remaining in the buffer. Use either next_output_byte or free_in_buffer
* to determine how much data is in the buffer.
*/
static void termDestination(jpeg_compress_struct* cinfo);
/**
* Override the standard error method in the IJG JPEG decoder code. This
* was mostly copied from nsJPEGDecoder.cpp
*/
static void errorExit(jpeg_common_struct* cinfo);
};
// used to pass error info through the JPEG library
struct encoder_error_mgr {
jpeg_error_mgr pub;
@ -111,7 +154,7 @@ nsJPEGEncoder::InitFromData(const uint8_t* aData,
// This must be done before the call to create_compress
encoder_error_mgr errmgr;
cinfo.err = jpeg_std_error(&errmgr.pub);
errmgr.pub.error_exit = errorExit;
errmgr.pub.error_exit = nsJPEGEncoderInternal::errorExit;
// Establish the setjmp return context for my_error_exit to use.
if (setjmp(errmgr.setjmp_buffer)) {
// If we get here, the JPEG code has signaled an error.
@ -138,9 +181,9 @@ nsJPEGEncoder::InitFromData(const uint8_t* aData,
// set up the destination manager
jpeg_destination_mgr destmgr;
destmgr.init_destination = initDestination;
destmgr.empty_output_buffer = emptyOutputBuffer;
destmgr.term_destination = termDestination;
destmgr.init_destination = nsJPEGEncoderInternal::initDestination;
destmgr.empty_output_buffer = nsJPEGEncoderInternal::emptyOutputBuffer;
destmgr.term_destination = nsJPEGEncoderInternal::termDestination;
cinfo.dest = &destmgr;
cinfo.client_data = this;
@ -347,14 +390,39 @@ void nsJPEGEncoder::ConvertRGBARow(const uint8_t* aSrc, uint8_t* aDest,
}
}
// nsJPEGEncoder::initDestination
//
// Initialize destination. This is called by jpeg_start_compress() before
// any data is actually written. It must initialize next_output_byte and
// free_in_buffer. free_in_buffer must be initialized to a positive value.
void // static
nsJPEGEncoder::initDestination(jpeg_compress_struct* cinfo) {
void nsJPEGEncoder::NotifyListener() {
// We might call this function on multiple threads (any threads that call
// AsyncWait and any that do encoding) so we lock to avoid notifying the
// listener twice about the same data (which generally leads to a truncated
// image).
ReentrantMonitorAutoEnter autoEnter(mReentrantMonitor);
if (mCallback &&
(mImageBufferUsed - mImageBufferReadPoint >= mNotifyThreshold ||
mFinished)) {
nsCOMPtr<nsIInputStreamCallback> callback;
if (mCallbackTarget) {
callback = NS_NewInputStreamReadyEvent("nsJPEGEncoder::NotifyListener",
mCallback, mCallbackTarget);
} else {
callback = mCallback;
}
NS_ASSERTION(callback, "Shouldn't fail to make the callback");
// Null the callback first because OnInputStreamReady could reenter
// AsyncWait
mCallback = nullptr;
mCallbackTarget = nullptr;
mNotifyThreshold = 0;
callback->OnInputStreamReady(this);
}
}
/* static */ void
nsJPEGEncoderInternal::initDestination(jpeg_compress_struct* cinfo) {
nsJPEGEncoder* that = static_cast<nsJPEGEncoder*>(cinfo->client_data);
NS_ASSERTION(!that->mImageBuffer, "Image buffer already initialized");
@ -366,19 +434,8 @@ nsJPEGEncoder::initDestination(jpeg_compress_struct* cinfo) {
cinfo->dest->free_in_buffer = that->mImageBufferSize;
}
// nsJPEGEncoder::emptyOutputBuffer
//
// This is called whenever the buffer has filled (free_in_buffer reaches
// zero). In typical applications, it should write out the *entire* buffer
// (use the saved start address and buffer length; ignore the current state
// of next_output_byte and free_in_buffer). Then reset the pointer & count
// to the start of the buffer, and return TRUE indicating that the buffer
// has been dumped. free_in_buffer must be set to a positive value when
// TRUE is returned. A FALSE return should only be used when I/O suspension
// is desired (this operating mode is discussed in the next section).
boolean // static
nsJPEGEncoder::emptyOutputBuffer(jpeg_compress_struct* cinfo) {
/* static */ boolean
nsJPEGEncoderInternal::emptyOutputBuffer(jpeg_compress_struct* cinfo) {
nsJPEGEncoder* that = static_cast<nsJPEGEncoder*>(cinfo->client_data);
NS_ASSERTION(that->mImageBuffer, "No buffer to empty!");
@ -413,15 +470,8 @@ nsJPEGEncoder::emptyOutputBuffer(jpeg_compress_struct* cinfo) {
return 1;
}
// nsJPEGEncoder::termDestination
//
// Terminate destination --- called by jpeg_finish_compress() after all data
// has been written. In most applications, this must flush any data
// remaining in the buffer. Use either next_output_byte or free_in_buffer
// to determine how much data is in the buffer.
void // static
nsJPEGEncoder::termDestination(jpeg_compress_struct* cinfo) {
/* static */ void
nsJPEGEncoderInternal::termDestination(jpeg_compress_struct* cinfo) {
nsJPEGEncoder* that = static_cast<nsJPEGEncoder*>(cinfo->client_data);
if (!that->mImageBuffer) {
return;
@ -432,13 +482,8 @@ nsJPEGEncoder::termDestination(jpeg_compress_struct* cinfo) {
that->NotifyListener();
}
// nsJPEGEncoder::errorExit
//
// Override the standard error method in the IJG JPEG decoder code. This
// was mostly copied from nsJPEGDecoder.cpp
void // static
nsJPEGEncoder::errorExit(jpeg_common_struct* cinfo) {
/* static */ void
nsJPEGEncoderInternal::errorExit(jpeg_common_struct* cinfo) {
nsresult error_code;
encoder_error_mgr* err = (encoder_error_mgr*)cinfo->err;
@ -454,33 +499,4 @@ nsJPEGEncoder::errorExit(jpeg_common_struct* cinfo) {
// Return control to the setjmp point. We pass an nsresult masquerading as
// an int, which works because the setjmp() caller casts it back.
longjmp(err->setjmp_buffer, static_cast<int>(error_code));
}
void nsJPEGEncoder::NotifyListener() {
// We might call this function on multiple threads (any threads that call
// AsyncWait and any that do encoding) so we lock to avoid notifying the
// listener twice about the same data (which generally leads to a truncated
// image).
ReentrantMonitorAutoEnter autoEnter(mReentrantMonitor);
if (mCallback &&
(mImageBufferUsed - mImageBufferReadPoint >= mNotifyThreshold ||
mFinished)) {
nsCOMPtr<nsIInputStreamCallback> callback;
if (mCallbackTarget) {
callback = NS_NewInputStreamReadyEvent("nsJPEGEncoder::NotifyListener",
mCallback, mCallbackTarget);
} else {
callback = mCallback;
}
NS_ASSERTION(callback, "Shouldn't fail to make the callback");
// Null the callback first because OnInputStreamReady could reenter
// AsyncWait
mCallback = nullptr;
mCallbackTarget = nullptr;
mNotifyThreshold = 0;
callback->OnInputStreamReady(this);
}
}
}

Просмотреть файл

@ -13,12 +13,8 @@
#include "nsCOMPtr.h"
// needed for JPEG library
#include <stdio.h>
extern "C" {
#include "jpeglib.h"
}
struct jpeg_compress_struct;
struct jpeg_common_struct;
#define NS_JPEGENCODER_CID \
{ \
@ -30,8 +26,10 @@ extern "C" {
// Provides JPEG encoding functionality. Use InitFromData() to do the
// encoding. See that function definition for encoding options.
class nsJPEGEncoderInternal;
class nsJPEGEncoder final : public imgIEncoder {
friend class nsJPEGEncoderInternal;
typedef mozilla::ReentrantMonitor ReentrantMonitor;
public:
@ -51,12 +49,6 @@ class nsJPEGEncoder final : public imgIEncoder {
void ConvertRGBARow(const uint8_t* aSrc, uint8_t* aDest,
uint32_t aPixelWidth);
static void initDestination(jpeg_compress_struct* cinfo);
static boolean emptyOutputBuffer(jpeg_compress_struct* cinfo);
static void termDestination(jpeg_compress_struct* cinfo);
static void errorExit(jpeg_common_struct* cinfo);
void NotifyListener();
bool mFinished;

Просмотреть файл

@ -54,6 +54,7 @@ EXPORTS += [
]
EXPORTS.mozilla.image += [
'encoders/jpeg/nsJPEGEncoder.h',
'ImageMemoryReporter.h',
'RecyclingSourceSurface.h',
]

Просмотреть файл

@ -689,18 +689,15 @@ class ExprDeref(ExprPrefixUnop):
class ExprCast(Node):
def __init__(self, expr, type,
dynamic=0, static=0, reinterpret=0, const=False, C=0):
assert 1 == sum([dynamic, static, reinterpret, const, C])
assert isinstance(const, bool)
static=False, const=False):
# Exactly one of these should be set
assert static ^ const
Node.__init__(self)
self.expr = expr
self.type = type
self.dynamic = dynamic
self.static = static
self.reinterpret = reinterpret
self.const = const
self.C = C
class ExprBinary(Node):

Просмотреть файл

@ -329,17 +329,11 @@ class CxxCodeGen(CodePrinter, Visitor):
self.write(')')
def visitExprCast(self, c):
pfx, sfx = '', ''
if c.dynamic:
pfx, sfx = 'dynamic_cast<', '>'
elif c.static:
if c.static:
pfx, sfx = 'static_cast<', '>'
elif c.reinterpret:
pfx, sfx = 'reinterpret_cast<', '>'
elif c.const:
else:
assert c.const
pfx, sfx = 'const_cast<', '>'
elif c.C:
pfx, sfx = '(', ')'
self.write(pfx)
c.type.accept(self)
self.write(sfx + '(')

Просмотреть файл

@ -1955,7 +1955,7 @@ class _ParamTraits():
Whitespace.NL,
StmtExpr(ExprAssn(ExprDeref(cls.var),
ExprCast(ExprCall(ExprSelect(actorvar, '.', 'value')),
cxxtype, static=1))),
cxxtype, static=True))),
StmtReturn.TRUE,
]
@ -2360,7 +2360,7 @@ def _generateCxxUnion(ud):
return ifdied
def voidCast(expr):
return ExprCast(expr, Type.VOID, static=1)
return ExprCast(expr, Type.VOID, static=True)
# compute all the typedefs and forward decls we need to make
gettypedeps = _ComputeTypeDeps(ud.decl.type)
@ -2635,7 +2635,7 @@ def _generateCxxUnion(ud):
# The void cast prevents Coverity from complaining about missing return
# value checks.
StmtBlock([StmtExpr(ExprCast(callMaybeDestroy(rhstypevar), Type.VOID,
static=1)),
static=True)),
StmtBreak()])
)
opeqswitch.addcase(
@ -3248,7 +3248,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
'Manager', ret=managertype, const=True))
managerexp = ExprCall(ExprVar('IProtocol::Manager'), args=[])
managermeth.addstmt(StmtReturn(
ExprCast(managerexp, managertype, static=1)))
ExprCast(managerexp, managertype, static=True)))
self.cls.addstmts([managermeth, Whitespace.NL])
@ -3665,7 +3665,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
case.addstmts([
StmtDecl(Decl(manageecxxtype, actorvar.name),
ExprCast(listenervar, manageecxxtype, static=1)),
ExprCast(listenervar, manageecxxtype, static=True)),
# Use a temporary variable here so all the assertion expressions
# in the _abortIfFalse call below are textually identical; the
# linker can then merge the strings from the assertion macro(s).
@ -4028,7 +4028,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
init=ExprCast(ExprCall(ExprSelect(ExprVar('untypedCallback'),
'.', 'get')),
callbackptr,
static=1)),
static=True)),
ifnocallback]
resolvecallback = [StmtExpr(ExprCall(ExprSelect(callback, '->', 'Resolve'),

Просмотреть файл

@ -3,14 +3,14 @@
== xbl-basic-02.svg pass.svg
== xbl-basic-03.svg pass.svg
== xbl-grad-ref--grad-in-binding-01.svg pass.svg
== xbl-grad-ref--grad-in-binding-02.svg pass.svg
fails == xbl-grad-ref--grad-in-binding-02.svg pass.svg
== xbl-grad-ref--grad-in-bound-01.svg pass.svg
fails == xbl-grad-ref--grad-in-bound-02.svg pass-black.svg
fails == xbl-grad-ref--grad-in-resources-01.svg pass.svg
fails == xbl-grad-ref--grad-in-resources-02.svg pass.svg
== xbl-grad-ref--grad-in-binding-03.svg pass.svg
== xbl-grad-ref--grad-in-bound-03.svg pass.svg
== xbl-grad-ref--grad-in-binding-04.svg pass.svg
fails == xbl-grad-ref--grad-in-binding-04.svg pass.svg
== xbl-grad-ref--grad-in-bound-04.svg pass.svg
# Tests for zooming with the full page zoom UI

Просмотреть файл

@ -5,8 +5,11 @@
package org.mozilla.gecko.gfx;
import org.mozilla.gecko.gfx.GeckoSurface;
import org.mozilla.gecko.gfx.SyncConfig;
interface ISurfaceAllocator {
GeckoSurface acquireSurface(in int width, in int height, in boolean singleBufferMode);
void releaseSurface(in int handle);
void configureSync(in SyncConfig config);
void sync(in int handle);
}

Просмотреть файл

@ -0,0 +1,7 @@
/* 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/. */
package org.mozilla.gecko.gfx;
parcelable SyncConfig;

Просмотреть файл

@ -10,28 +10,30 @@ import android.graphics.SurfaceTexture;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.Surface;
import android.util.Log;
import java.util.HashMap;
import org.mozilla.gecko.annotation.WrapForJNI;
import static org.mozilla.geckoview.BuildConfig.DEBUG_BUILD;
public final class GeckoSurface extends Surface {
private static final String LOGTAG = "GeckoSurface";
private static final HashMap<Integer, GeckoSurfaceTexture> sSurfaceTextures = new HashMap<Integer, GeckoSurfaceTexture>();
private int mHandle;
private boolean mIsSingleBuffer;
private volatile boolean mIsAvailable;
private boolean mOwned = true;
private int mMyPid;
// Locally allocated surface/texture. Do not pass it over IPC.
private GeckoSurface mSyncSurface;
@WrapForJNI(exceptionMode = "nsresult")
public GeckoSurface(GeckoSurfaceTexture gst) {
super(gst);
mHandle = gst.getHandle();
mIsSingleBuffer = gst.isSingleBuffer();
mIsAvailable = true;
mMyPid = android.os.Process.myPid();
}
public GeckoSurface(Parcel p, SurfaceTexture dummy) {
@ -44,6 +46,7 @@ public final class GeckoSurface extends Surface {
mHandle = p.readInt();
mIsSingleBuffer = p.readByte() == 1 ? true : false;
mIsAvailable = (p.readByte() == 1 ? true : false);
mMyPid = p.readInt();
dummy.release();
}
@ -64,12 +67,22 @@ public final class GeckoSurface extends Surface {
out.writeInt(mHandle);
out.writeByte((byte) (mIsSingleBuffer ? 1 : 0));
out.writeByte((byte) (mIsAvailable ? 1 : 0));
out.writeInt(mMyPid);
mOwned = false;
}
@Override
public void release() {
if (mSyncSurface != null) {
mSyncSurface.release();
GeckoSurfaceTexture gst = GeckoSurfaceTexture.lookup(mSyncSurface.getHandle());
if (gst != null) {
gst.decrementUse();
}
mSyncSurface = null;
}
if (mOwned) {
super.release();
}
@ -89,4 +102,25 @@ public final class GeckoSurface extends Surface {
public void setAvailable(boolean available) {
mIsAvailable = available;
}
/* package */ boolean inProcess() {
return android.os.Process.myPid() == mMyPid;
}
/* package */ SyncConfig initSyncSurface(int width, int height) {
if (DEBUG_BUILD) {
if (inProcess()) {
throw new AssertionError("no need for sync when allocated in process");
}
}
if (GeckoSurfaceTexture.lookup(mHandle) != null) {
throw new AssertionError("texture#" + mHandle + " already in use.");
}
GeckoSurfaceTexture texture = GeckoSurfaceTexture.acquire(false, mHandle);
texture.setDefaultBufferSize(width, height);
texture.track(mHandle);
mSyncSurface = new GeckoSurface(texture);
return new SyncConfig(mHandle, mSyncSurface, width, height);
}
}

Просмотреть файл

@ -15,6 +15,7 @@ import java.util.HashMap;
import java.util.LinkedList;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.mozglue.JNIObject;
/* package */ final class GeckoSurfaceTexture extends SurfaceTexture {
private static final String LOGTAG = "GeckoSurfaceTexture";
@ -36,6 +37,9 @@ import org.mozilla.gecko.annotation.WrapForJNI;
private AtomicInteger mUseCount;
private boolean mFinalized;
private int mUpstream;
private NativeGLBlitHelper mBlitter;
private GeckoSurfaceTexture(int handle) {
super(0);
init(handle, false);
@ -111,6 +115,9 @@ import org.mozilla.gecko.annotation.WrapForJNI;
@WrapForJNI
public synchronized void updateTexImage() {
try {
if (mUpstream != 0) {
SurfaceAllocator.sync(mUpstream);
}
super.updateTexImage();
if (mListener != null) {
mListener.onUpdateTexImage();
@ -122,6 +129,10 @@ import org.mozilla.gecko.annotation.WrapForJNI;
@Override
public synchronized void release() {
mUpstream = 0;
if (mBlitter != null) {
mBlitter.disposeNative();
}
try {
super.release();
synchronized (sSurfaceTextures) {
@ -237,7 +248,7 @@ import org.mozilla.gecko.annotation.WrapForJNI;
}
}
public static GeckoSurfaceTexture acquire(boolean singleBufferMode) {
public static GeckoSurfaceTexture acquire(boolean singleBufferMode, int handle) {
if (singleBufferMode && !isSingleBufferSupported()) {
throw new IllegalArgumentException("single buffer mode not supported on API version < 19");
}
@ -250,7 +261,10 @@ import org.mozilla.gecko.annotation.WrapForJNI;
return null;
}
int handle = sNextHandle++;
if (handle == 0) {
// Generate new handle value when none specified.
handle = sNextHandle++;
}
final GeckoSurfaceTexture gst;
if (isSingleBufferSupported()) {
@ -276,8 +290,32 @@ import org.mozilla.gecko.annotation.WrapForJNI;
}
}
/* package */ synchronized void track(int upstream) {
mUpstream = upstream;
}
/* package */ synchronized void configureSnapshot(GeckoSurface target, int width, int height) {
mBlitter = NativeGLBlitHelper.create(mHandle, target, width, height);
}
/* package */ synchronized void takeSnapshot() {
mBlitter.blit();
}
public interface Callbacks {
void onUpdateTexImage();
void onReleaseTexImage();
}
@WrapForJNI
public static final class NativeGLBlitHelper extends JNIObject {
public native static NativeGLBlitHelper create(int textureHandle,
GeckoSurface targetSurface,
int width,
int height);
public native void blit();
@Override
protected native void disposeNative();
}
}

Просмотреть файл

@ -10,12 +10,9 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.SurfaceTexture;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
import android.view.Surface;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.GeckoAppShell;
@ -49,8 +46,12 @@ import org.mozilla.gecko.GeckoAppShell;
if (singleBufferMode && !GeckoSurfaceTexture.isSingleBufferSupported()) {
return null;
}
return sConnection.getAllocator().acquireSurface(width, height, singleBufferMode);
ISurfaceAllocator allocator = sConnection.getAllocator();
GeckoSurface surface = allocator.acquireSurface(width, height, singleBufferMode);
if (surface != null && !surface.inProcess()) {
allocator.configureSync(surface.initSyncSurface(width, height));
}
return surface;
} catch (Exception e) {
Log.w(LOGTAG, "Failed to acquire GeckoSurface", e);
return null;
@ -81,6 +82,22 @@ import org.mozilla.gecko.GeckoAppShell;
}
}
public static void sync(int upstream) {
try {
ensureConnection();
} catch (Exception e) {
Log.w(LOGTAG, "Failed to sync texture, no connection");
return;
}
// Release the SurfaceTexture on the other side
try {
sConnection.getAllocator().sync(upstream);
} catch (RemoteException e) {
Log.w(LOGTAG, "Failed to sync texture", e);
}
}
private static final class SurfaceAllocatorConnection implements ServiceConnection {
private ISurfaceAllocator mAllocator;

Просмотреть файл

@ -9,8 +9,6 @@ import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public final class SurfaceAllocatorService extends Service {
@ -22,7 +20,7 @@ public final class SurfaceAllocatorService extends Service {
private Binder mBinder = new ISurfaceAllocator.Stub() {
public GeckoSurface acquireSurface(int width, int height, boolean singleBufferMode) {
GeckoSurfaceTexture gst = GeckoSurfaceTexture.acquire(singleBufferMode);
GeckoSurfaceTexture gst = GeckoSurfaceTexture.acquire(singleBufferMode, 0);
if (gst == null) {
return null;
@ -41,6 +39,20 @@ public final class SurfaceAllocatorService extends Service {
gst.decrementUse();
}
}
public void configureSync(SyncConfig config) {
final GeckoSurfaceTexture gst = GeckoSurfaceTexture.lookup(config.sourceTextureHandle);
if (gst != null) {
gst.configureSnapshot(config.targetSurface, config.width, config.height);
}
}
public void sync(int handle) {
final GeckoSurfaceTexture gst = GeckoSurfaceTexture.lookup(handle);
if (gst != null) {
gst.takeSnapshot();
}
}
};
public IBinder onBind(final Intent intent) {

Просмотреть файл

@ -0,0 +1,54 @@
package org.mozilla.gecko.gfx;
import android.os.Parcel;
import android.os.Parcelable;
/* package */ final class SyncConfig implements Parcelable {
final int sourceTextureHandle;
final GeckoSurface targetSurface;
final int width;
final int height;
/* package */ SyncConfig(int sourceTextureHandle,
GeckoSurface targetSurface,
int width,
int height) {
this.sourceTextureHandle = sourceTextureHandle;
this.targetSurface = targetSurface;
this.width = width;
this.height = height;
}
public static final Creator<SyncConfig> CREATOR =
new Creator<SyncConfig>() {
@Override
public SyncConfig createFromParcel(Parcel parcel) {
return new SyncConfig(parcel);
}
@Override
public SyncConfig[] newArray(int i) {
return new SyncConfig[i];
}
};
private SyncConfig(Parcel parcel) {
sourceTextureHandle = parcel.readInt();
targetSurface = GeckoSurface.CREATOR.createFromParcel(parcel);
width = parcel.readInt();
height = parcel.readInt();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(sourceTextureHandle);
targetSurface.writeToParcel(parcel, flags);
parcel.writeInt(width);
parcel.writeInt(height);
}
}

Просмотреть файл

@ -55,7 +55,7 @@ public class SharedMemory implements Parcelable {
@Override
public int describeContents() {
return 0;
return CONTENTS_FILE_DESCRIPTOR;
}
@Override

Просмотреть файл

@ -462,7 +462,8 @@ class nsHttpChannel final : public HttpBaseChannel,
inline static bool DoNotRender3xxBody(nsresult rv) {
return rv == NS_ERROR_REDIRECT_LOOP || rv == NS_ERROR_CORRUPTED_CONTENT ||
rv == NS_ERROR_UNKNOWN_PROTOCOL || rv == NS_ERROR_MALFORMED_URI;
rv == NS_ERROR_UNKNOWN_PROTOCOL || rv == NS_ERROR_MALFORMED_URI ||
rv == NS_ERROR_PORT_ACCESS_NOT_ALLOWED;
}
// Report net vs cache time telemetry

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -204,7 +204,6 @@ class nsHtml5AttributeName {
static nsHtml5AttributeName* ATTR_K4;
static nsHtml5AttributeName* ATTR_XML_SPACE;
static nsHtml5AttributeName* ATTR_XML_LANG;
static nsHtml5AttributeName* ATTR_XML_BASE;
static nsHtml5AttributeName* ATTR_ARIA_GRAB;
static nsHtml5AttributeName* ATTR_ARIA_VALUEMAX;
static nsHtml5AttributeName* ATTR_ARIA_LABELLEDBY;

Просмотреть файл

@ -1171,4 +1171,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1553170230614000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1553515916483000);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -5,7 +5,7 @@
//! Collects a series of applicable rules for a given element.
use crate::applicable_declarations::{ApplicableDeclarationBlock, ApplicableDeclarationList};
use crate::dom::{TElement, TShadowRoot};
use crate::dom::{TElement, TNode, TShadowRoot};
use crate::properties::{AnimationRules, PropertyDeclarationBlock};
use crate::rule_tree::{CascadeLevel, ShadowCascadeOrder};
use crate::selector_map::SelectorMap;
@ -17,6 +17,43 @@ use selectors::matching::{ElementSelectorFlags, MatchingContext};
use servo_arc::ArcBorrow;
use smallvec::SmallVec;
/// This is a bit of a hack so <svg:use> matches the rules of the enclosing
/// tree.
///
/// This function returns the containing shadow host ignoring <svg:use> shadow
/// trees, since those match the enclosing tree's rules.
///
/// Only a handful of places need to really care about this. This is not a
/// problem for invalidation and that kind of stuff because they still don't
/// match rules based on elements outside of the shadow tree, and because the
/// <svg:use> subtrees are immutable and recreated each time the source tree
/// changes.
///
/// We historically allow cross-document <svg:use> to have these rules applied,
/// but I think that's not great. Gecko is the only engine supporting that.
///
/// See https://github.com/w3c/svgwg/issues/504 for the relevant spec
/// discussion.
#[inline]
pub fn containing_shadow_ignoring_svg_use<E: TElement>(
element: E,
) -> Option<<E::ConcreteNode as TNode>::ConcreteShadowRoot> {
let mut shadow = element.containing_shadow()?;
loop {
let host = shadow.host();
let host_is_svg_use_element =
host.is_svg_element() && host.local_name() == &*local_name!("use");
if !host_is_svg_use_element {
return Some(shadow);
}
debug_assert!(
shadow.style_data().is_none(),
"We allow no stylesheets in <svg:use> subtrees"
);
shadow = host.containing_shadow()?;
}
}
/// An object that we use with all the intermediate state needed for the
/// cascade.
///
@ -213,43 +250,19 @@ where
return;
}
let mut current_containing_shadow = self.rule_hash_target.containing_shadow();
while let Some(containing_shadow) = current_containing_shadow {
let cascade_data = containing_shadow.style_data();
let host = containing_shadow.host();
if let Some(map) = cascade_data.and_then(|data| data.normal_rules(self.pseudo_element))
{
self.collect_rules_in_shadow_tree(host, map, CascadeLevel::SameTreeAuthorNormal);
}
let host_is_svg_use_element =
host.is_svg_element() && host.local_name() == &*local_name!("use");
if !host_is_svg_use_element {
self.matches_document_author_rules = false;
break;
}
let containing_shadow = containing_shadow_ignoring_svg_use(self.rule_hash_target);
let containing_shadow = match containing_shadow {
Some(s) => s,
None => return,
};
debug_assert!(
cascade_data.is_none(),
"We allow no stylesheets in <svg:use> subtrees"
);
self.matches_document_author_rules = false;
// NOTE(emilio): Hack so <svg:use> matches the rules of the
// enclosing tree.
//
// This is not a problem for invalidation and that kind of stuff
// because they still don't match rules based on elements
// outside of the shadow tree, and because the <svg:use>
// subtrees are immutable and recreated each time the source
// tree changes.
//
// We historically allow cross-document <svg:use> to have these
// rules applied, but I think that's not great. Gecko is the
// only engine supporting that.
//
// See https://github.com/w3c/svgwg/issues/504 for the relevant
// spec discussion.
current_containing_shadow = host.containing_shadow();
self.matches_document_author_rules = current_containing_shadow.is_none();
let cascade_data = containing_shadow.style_data();
let host = containing_shadow.host();
if let Some(map) = cascade_data.and_then(|data| data.normal_rules(self.pseudo_element))
{
self.collect_rules_in_shadow_tree(host, map, CascadeLevel::SameTreeAuthorNormal);
}
}

Просмотреть файл

@ -17,7 +17,7 @@ use crate::media_queries::Device;
use crate::properties::{self, CascadeMode, ComputedValues};
use crate::properties::{AnimationRules, PropertyDeclarationBlock};
use crate::rule_cache::{RuleCache, RuleCacheConditions};
use crate::rule_collector::RuleCollector;
use crate::rule_collector::{RuleCollector, containing_shadow_ignoring_svg_use};
use crate::rule_tree::{CascadeLevel, RuleTree, ShadowCascadeOrder, StrongRuleNode, StyleSource};
use crate::selector_map::{PrecomputedHashMap, PrecomputedHashSet, SelectorMap, SelectorMapEntry};
use crate::selector_parser::{PerPseudoElementMap, PseudoElement, SelectorImpl, SnapshotMap};
@ -1190,7 +1190,9 @@ impl Stylist {
}
}
if let Some(shadow) = element.containing_shadow() {
// Use the same rules to look for the containing host as we do for rule
// collection.
if let Some(shadow) = containing_shadow_ignoring_svg_use(element) {
if let Some(data) = shadow.style_data() {
try_find_in!(data);
}

Просмотреть файл

@ -1,4 +0,0 @@
[clip-filter-order.html]
expected:
if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL

Просмотреть файл

@ -1,61 +0,0 @@
[historical.sub.xhtml]
[The 'src' attribute of the 'iframe' element]
expected: FAIL
[The 'href' attribute of the 'a' element]
expected: FAIL
[The 'formaction' attribute of the 'button' element]
expected: FAIL
[The 'src' attribute of the 'input' element]
expected: FAIL
[The 'data' attribute of the 'object' element]
expected: FAIL
[The 'href' attribute of the 'area' element]
expected: FAIL
[Change the base URL must not effect the descendant elements]
expected: FAIL
[The 'src' attribute of the 'audio' element]
expected: FAIL
[The 'src' attribute of the 'script' element]
expected: FAIL
[The 'src' attribute of the 'img' element]
expected: FAIL
[The 'src' attribute of the 'track' element]
expected: FAIL
[The 'cite' attribute of the 'q' element]
expected: FAIL
[The 'cite' attribute of the 'ins' element]
expected: FAIL
[The 'href' attribute of the 'link' element]
expected: FAIL
[The 'cite' attribute of the 'del' element]
expected: FAIL
[The 'action' attribute of the 'form' element]
expected: FAIL
[The 'src' attribute of the 'embed' element]
expected: FAIL
[The 'src' attribute of the 'source' element]
expected: FAIL
[The 'src' attribute of the 'video' element]
expected: FAIL
[The 'cite' attribute of the 'blockquote' element]
expected: FAIL

Просмотреть файл

@ -9,25 +9,23 @@
// Run captureStream() on different videos, and assert data is flowing.
var makeAsyncTest = function(filename) {
async_test(function(test) {
var video = document.createElement('video');
function makeAsyncTest(filename) {
promise_test(async test => {
const video = document.createElement('video');
video.src = "/media/" + filename;
video.onerror = this.unreached_func("<video> error");
video.play();
var stream = video.captureStream();
const stream = video.captureStream();
// onactive event is marked for deprecation (https://crbug.com/649328)
stream.onactive = this.step_func_done(function() {
var recorder = new MediaRecorder(stream);
recorder.ondataavailable = test.step_func_done(function(event) {
assert_true(event.data.size > 0, 'Recorded data size should be > 0');
});
recorder.start(0);
});
}), "<video>.captureStream() and assert data flows.";
};
await new Promise(r => stream.onaddtrack = r);
const recorder = new MediaRecorder(stream);
recorder.start(0);
const {data} = await new Promise(r => recorder.ondataavailable = r);
assert_true(data.size > 0, 'Recorded data size should be > 0');
}), "<video>.captureStream() and assert data flows.";
}
generate_tests(makeAsyncTest, [
[ "video-only", "test-v-128k-320x240-24fps-8kfr.webm" ],

Просмотреть файл

@ -0,0 +1,6 @@
<!doctype html>
<meta charset="utf-8">
<title>CSS Test Reference</title>
<svg width="100" height="100" viewBox="0 0 100 100">
<rect width="100%" height="100%" fill="lime" />
</svg>

Просмотреть файл

@ -0,0 +1,19 @@
<!doctype html>
<meta charset="utf-8">
<title>CSS Test: Keyframe animations from the document match in use elements</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1513920">
<link rel="match" href="use-keyframes-ref.html">
<style>
@keyframes animationname {
from { fill: lime; }
to { fill: lime; }
}
</style>
<svg width="100" height="100" viewBox="0 0 100 100">
<symbol id="symbol">
<rect width="100%" height="100%" fill="red" style="animation: animationname 1s infinite;" />
</symbol>
<use href="#symbol" />
</svg>

Просмотреть файл

@ -52,7 +52,7 @@ either hg or git. To enable a pre-push hg hook, add the following to hgrc:
.. parsed-literal::
[hooks]
pre-push.lint = python:/path/to/gecko/tools/lint/hooks.py:hg
pre-push.lint = python:./tools/lint/hooks.py:hg
To enable a pre-commit hg hook, add the following to hgrc:
@ -60,7 +60,7 @@ To enable a pre-commit hg hook, add the following to hgrc:
.. parsed-literal::
[hooks]
pretxncommit.lint = python:/path/to/gecko/tools/lint/hooks.py:hg
pretxncommit.lint = python:./tools/lint/hooks.py:hg
To enable a pre-push git hook, run the following command:

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше