Merge m-c to autoland, a=merge

This commit is contained in:
Wes Kocher 2017-04-06 15:10:53 -07:00
Родитель 8f857ca1d0 0c3144c6f6
Коммит 4778bff897
48 изменённых файлов: 18199 добавлений и 17276 удалений

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

@ -209,7 +209,7 @@ skip-if = true # Needs to be rewritten as Marionette test, bug 995916
[browser_739531.js]
[browser_739805.js]
[browser_819510_perwindowpb.js]
skip-if = (os == 'win' && bits == 64) # Bug 1284312
skip-if = (os == 'win' && bits == 64) || (os == "mac") # Win: Bug 1284312, Mac: Bug 1341980
[browser_not_collect_when_idle.js]
# Disabled for frequent intermittent failures

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

@ -30,6 +30,14 @@ module.exports = createClass({
mixins: [ addons.PureRenderMixin ],
onKeyDown(event) {
let { target } = event;
if (target == this.boxModelContainer) {
this.boxModelMain.onKeyDown(event);
}
},
render() {
let {
boxModel,
@ -45,10 +53,19 @@ module.exports = createClass({
return dom.div(
{
className: "boxmodel-container",
tabIndex: 0,
ref: div => {
this.boxModelContainer = div;
},
onKeyDown: this.onKeyDown,
},
BoxModelMain({
boxModel,
boxModelContainer: this.boxModelContainer,
setSelectedNode,
ref: boxModelMain => {
this.boxModelMain = boxModelMain;
},
onHideBoxModelHighlighter,
onShowBoxModelEditor,
onShowBoxModelHighlighter,

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

@ -17,6 +17,8 @@ module.exports = createClass({
propTypes: {
box: PropTypes.string.isRequired,
direction: PropTypes.string,
focusable: PropTypes.bool.isRequired,
level: PropTypes.string.isRequired,
property: PropTypes.string.isRequired,
textContent: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
onShowBoxModelEditor: PropTypes.func.isRequired,
@ -28,7 +30,7 @@ module.exports = createClass({
let { property, onShowBoxModelEditor } = this.props;
editableItem({
element: this.refs.span,
element: this.boxModelEditable,
}, (element, event) => {
onShowBoxModelEditor(element, event, property);
});
@ -38,6 +40,8 @@ module.exports = createClass({
let {
box,
direction,
focusable,
level,
property,
textContent,
} = this.props;
@ -57,8 +61,11 @@ module.exports = createClass({
{
className: "boxmodel-editable",
"data-box": box,
tabIndex: box === level && focusable ? 0 : -1,
title: property,
ref: "span",
ref: span => {
this.boxModelEditable = span;
},
},
textContent
)

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

@ -6,10 +6,13 @@
const { addons, createClass, createFactory, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
const { KeyCodes } = require("devtools/client/shared/keycodes");
const { LocalizationHelper } = require("devtools/shared/l10n");
const BoxModelEditable = createFactory(require("./BoxModelEditable"));
// Reps
const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
const Rep = createFactory(REPS.Rep);
@ -28,6 +31,7 @@ module.exports = createClass({
propTypes: {
boxModel: PropTypes.shape(Types.boxModel).isRequired,
boxModelContainer: PropTypes.object.isRequired,
setSelectedNode: PropTypes.func.isRequired,
onHideBoxModelHighlighter: PropTypes.func.isRequired,
onShowBoxModelEditor: PropTypes.func.isRequired,
@ -37,11 +41,90 @@ module.exports = createClass({
mixins: [ addons.PureRenderMixin ],
getInitialState() {
return {
activeDescendant: null,
focusable: false,
};
},
componentDidUpdate() {
let displayPosition = this.getDisplayPosition();
let isContentBox = this.getContextBox();
this.layouts = {
"position": new Map([
[KeyCodes.DOM_VK_ESCAPE, this.positionLayout],
[KeyCodes.DOM_VK_DOWN, this.marginLayout],
[KeyCodes.DOM_VK_RETURN, this.positionEditable],
[KeyCodes.DOM_VK_UP, null],
["click", this.positionLayout]
]),
"margin": new Map([
[KeyCodes.DOM_VK_ESCAPE, this.marginLayout],
[KeyCodes.DOM_VK_DOWN, this.borderLayout],
[KeyCodes.DOM_VK_RETURN, this.marginEditable],
[KeyCodes.DOM_VK_UP, displayPosition ? this.positionLayout : null],
["click", this.marginLayout]
]),
"border": new Map([
[KeyCodes.DOM_VK_ESCAPE, this.borderLayout],
[KeyCodes.DOM_VK_DOWN, this.paddingLayout],
[KeyCodes.DOM_VK_RETURN, this.borderEditable],
[KeyCodes.DOM_VK_UP, this.marginLayout],
["click", this.borderLayout]
]),
"padding": new Map([
[KeyCodes.DOM_VK_ESCAPE, this.paddingLayout],
[KeyCodes.DOM_VK_DOWN, isContentBox ? this.contentLayout : null],
[KeyCodes.DOM_VK_RETURN, this.paddingEditable],
[KeyCodes.DOM_VK_UP, this.borderLayout],
["click", this.paddingLayout]
]),
"content": new Map([
[KeyCodes.DOM_VK_ESCAPE, this.contentLayout],
[KeyCodes.DOM_VK_DOWN, null],
[KeyCodes.DOM_VK_RETURN, this.contentEditable],
[KeyCodes.DOM_VK_UP, this.paddingLayout],
["click", this.contentLayout]
])
};
},
getAriaActiveDescendant() {
let { activeDescendant } = this.state;
if (!activeDescendant) {
let displayPosition = this.getDisplayPosition();
let nextLayout = displayPosition ? this.positionLayout : this.marginLayout;
activeDescendant = nextLayout.getAttribute("data-box");
this.setAriaActive(nextLayout);
}
return activeDescendant;
},
getBorderOrPaddingValue(property) {
let { layout } = this.props.boxModel;
return layout[property] ? parseFloat(layout[property]) : "-";
},
/**
* Returns true if the layout box sizing is context box and false otherwise.
*/
getContextBox() {
let { layout } = this.props.boxModel;
return layout["box-sizing"] == "content-box";
},
/**
* Returns true if the position is displayed and false otherwise.
*/
getDisplayPosition() {
let { layout } = this.props.boxModel;
return layout.position && layout.position != "static";
},
getHeightValue(property) {
let { layout } = this.props.boxModel;
@ -117,13 +200,64 @@ module.exports = createClass({
return value;
},
/**
* Move the focus to the next/previous editable element of the current layout.
*
* @param {Element} target
* Node to be observed
* @param {Boolean} shiftKey
* Determines if shiftKey was pressed
* @param {String} level
* Current active layout
*/
moveFocus: function ({ target, shiftKey }, level) {
let editBoxes = [
...findDOMNode(this).querySelectorAll(`[data-box="${level}"].boxmodel-editable`)
];
let editingMode = target.tagName === "input";
// target.nextSibling is input field
let position = editingMode ? editBoxes.indexOf(target.nextSibling)
: editBoxes.indexOf(target);
if (position === editBoxes.length - 1 && !shiftKey) {
position = 0;
} else if (position === 0 && shiftKey) {
position = editBoxes.length - 1;
} else {
shiftKey ? position-- : position++;
}
let editBox = editBoxes[position];
editBox.focus();
if (editingMode) {
editBox.click();
}
},
/**
* Active aria-level set to current layout.
*
* @param {Element} nextLayout
* Element of next layout that user has navigated to
*/
setAriaActive(nextLayout) {
let { boxModelContainer } = this.props;
// We set this attribute for testing purposes.
boxModelContainer.setAttribute("activedescendant", nextLayout.className);
this.setState({
activeDescendant: nextLayout.getAttribute("data-box"),
});
},
/**
* While waiting for a reps fix in https://github.com/devtools-html/reps/issues/92,
* translate nodeFront to a grip-like object that can be used with an ElementNode rep.
*
* @params {NodeFront} nodeFront
* The NodeFront for which we want to create a grip-like object.
* @returns {Object} a grip-like object that can be used with Reps.
* @param {NodeFront} nodeFront
* The NodeFront for which we want to create a grip-like object.
* @return {Object} a grip-like object that can be used with Reps.
*/
translateNodeFrontToGrip(nodeFront) {
let {
@ -180,6 +314,95 @@ module.exports = createClass({
});
},
/**
* Handle keyboard navigation and focus for box model layouts.
*
* Updates active layout on arrow key navigation
* Focuses next layout's editboxes on enter key
* Unfocuses current layout's editboxes when active layout changes
* Controls tabbing between editBoxes
*
* @param {Event} event
* The event triggered by a keypress on the box model
*/
onKeyDown(event) {
let { target, keyCode } = event;
let isEditable = target._editable || target.editor;
let level = this.getAriaActiveDescendant();
let editingMode = target.tagName === "input";
switch (keyCode) {
case KeyCodes.DOM_VK_RETURN:
if (!isEditable) {
this.setState({ focusable: true });
let editableBox = this.layouts[level].get(keyCode);
if (editableBox) {
editableBox.boxModelEditable.focus();
}
}
break;
case KeyCodes.DOM_VK_DOWN:
case KeyCodes.DOM_VK_UP:
if (!editingMode) {
event.preventDefault();
this.setState({ focusable: false });
let nextLayout = this.layouts[level].get(keyCode);
this.setAriaActive(nextLayout);
if (target && target._editable) {
target.blur();
}
this.props.boxModelContainer.focus();
}
break;
case KeyCodes.DOM_VK_TAB:
if (isEditable) {
event.preventDefault();
this.moveFocus(event, level);
}
break;
case KeyCodes.DOM_VK_ESCAPE:
if (target._editable) {
event.preventDefault();
event.stopPropagation();
this.setState({ focusable: false });
this.props.boxModelContainer.focus();
}
break;
default:
break;
}
},
/**
* Update aria-active on mouse click.
*
* @param {Event} event
* The event triggered by a mouse click on the box model
*/
onLevelClick(event) {
let { target } = event;
let displayPosition = this.getDisplayPosition();
let isContentBox = this.getContextBox();
// Avoid switching the aria active descendant to the position or content layout
// if those are not editable.
if ((!displayPosition && target == this.positionLayout) ||
(!isContentBox && target == this.contentLayout)) {
return;
}
let nextLayout = this.layouts[target.getAttribute("data-box")].get("click");
this.setAriaActive(nextLayout);
if (target && target._editable) {
target.blur();
}
},
render() {
let {
boxModel,
@ -201,7 +424,7 @@ module.exports = createClass({
let paddingBottom = this.getBorderOrPaddingValue("padding-bottom");
let paddingLeft = this.getBorderOrPaddingValue("padding-left");
let displayPosition = layout.position && layout.position != "static";
let displayPosition = this.getDisplayPosition();
let positionTop = this.getPositionValue("top");
let positionRight = this.getPositionValue("right");
let positionBottom = this.getPositionValue("bottom");
@ -215,6 +438,8 @@ module.exports = createClass({
height = this.getHeightValue(height);
width = this.getWidthValue(width);
let { activeDescendant: level, focusable } = this.state;
let contentBox = layout["box-sizing"] == "content-box" ?
dom.p(
{
@ -222,7 +447,12 @@ module.exports = createClass({
},
BoxModelEditable({
box: "content",
focusable,
level,
property: "width",
ref: editable => {
this.contentEditable = editable;
},
textContent: width,
onShowBoxModelEditor
}),
@ -232,6 +462,8 @@ module.exports = createClass({
),
BoxModelEditable({
box: "content",
focusable,
level,
property: "height",
textContent: height,
onShowBoxModelEditor
@ -253,6 +485,12 @@ module.exports = createClass({
return dom.div(
{
className: "boxmodel-main",
"data-box": "position",
ref: div => {
this.positionLayout = div;
},
onClick: this.onLevelClick,
onKeyDown: this.onKeyDown,
onMouseOver: this.onHighlightMouseOver,
onMouseOut: this.props.onHideBoxModelHighlighter,
},
@ -301,6 +539,9 @@ module.exports = createClass({
className: "boxmodel-margins",
"data-box": "margin",
title: BOXMODEL_L10N.getStr("boxmodel.margin"),
ref: div => {
this.marginLayout = div;
},
},
dom.span(
{
@ -315,6 +556,9 @@ module.exports = createClass({
className: "boxmodel-borders",
"data-box": "border",
title: BOXMODEL_L10N.getStr("boxmodel.border"),
ref: div => {
this.borderLayout = div;
},
},
dom.span(
{
@ -329,11 +573,17 @@ module.exports = createClass({
className: "boxmodel-paddings",
"data-box": "padding",
title: BOXMODEL_L10N.getStr("boxmodel.padding"),
ref: div => {
this.paddingLayout = div;
},
},
dom.div({
className: "boxmodel-contents",
"data-box": "content",
title: BOXMODEL_L10N.getStr("boxmodel.content"),
ref: div => {
this.contentLayout = div;
},
})
)
)
@ -343,7 +593,12 @@ module.exports = createClass({
BoxModelEditable({
box: "position",
direction: "top",
focusable,
level,
property: "position-top",
ref: editable => {
this.positionEditable = editable;
},
textContent: positionTop,
onShowBoxModelEditor,
})
@ -353,6 +608,8 @@ module.exports = createClass({
BoxModelEditable({
box: "position",
direction: "right",
focusable,
level,
property: "position-right",
textContent: positionRight,
onShowBoxModelEditor,
@ -363,6 +620,8 @@ module.exports = createClass({
BoxModelEditable({
box: "position",
direction: "bottom",
focusable,
level,
property: "position-bottom",
textContent: positionBottom,
onShowBoxModelEditor,
@ -373,6 +632,8 @@ module.exports = createClass({
BoxModelEditable({
box: "position",
direction: "left",
focusable,
level,
property: "position-left",
textContent: positionLeft,
onShowBoxModelEditor,
@ -382,13 +643,20 @@ module.exports = createClass({
BoxModelEditable({
box: "margin",
direction: "top",
focusable,
level,
property: "margin-top",
ref: editable => {
this.marginEditable = editable;
},
textContent: marginTop,
onShowBoxModelEditor,
}),
BoxModelEditable({
box: "margin",
direction: "right",
focusable,
level,
property: "margin-right",
textContent: marginRight,
onShowBoxModelEditor,
@ -396,6 +664,8 @@ module.exports = createClass({
BoxModelEditable({
box: "margin",
direction: "bottom",
focusable,
level,
property: "margin-bottom",
textContent: marginBottom,
onShowBoxModelEditor,
@ -403,6 +673,8 @@ module.exports = createClass({
BoxModelEditable({
box: "margin",
direction: "left",
focusable,
level,
property: "margin-left",
textContent: marginLeft,
onShowBoxModelEditor,
@ -410,13 +682,20 @@ module.exports = createClass({
BoxModelEditable({
box: "border",
direction: "top",
focusable,
level,
property: "border-top-width",
ref: editable => {
this.borderEditable = editable;
},
textContent: borderTop,
onShowBoxModelEditor,
}),
BoxModelEditable({
box: "border",
direction: "right",
focusable,
level,
property: "border-right-width",
textContent: borderRight,
onShowBoxModelEditor,
@ -424,6 +703,8 @@ module.exports = createClass({
BoxModelEditable({
box: "border",
direction: "bottom",
focusable,
level,
property: "border-bottom-width",
textContent: borderBottom,
onShowBoxModelEditor,
@ -431,6 +712,8 @@ module.exports = createClass({
BoxModelEditable({
box: "border",
direction: "left",
focusable,
level,
property: "border-left-width",
textContent: borderLeft,
onShowBoxModelEditor,
@ -438,13 +721,20 @@ module.exports = createClass({
BoxModelEditable({
box: "padding",
direction: "top",
focusable,
level,
property: "padding-top",
ref: editable => {
this.paddingEditable = editable;
},
textContent: paddingTop,
onShowBoxModelEditor,
}),
BoxModelEditable({
box: "padding",
direction: "right",
focusable,
level,
property: "padding-right",
textContent: paddingRight,
onShowBoxModelEditor,
@ -452,6 +742,8 @@ module.exports = createClass({
BoxModelEditable({
box: "padding",
direction: "bottom",
focusable,
level,
property: "padding-bottom",
textContent: paddingBottom,
onShowBoxModelEditor,
@ -459,6 +751,8 @@ module.exports = createClass({
BoxModelEditable({
box: "padding",
direction: "left",
focusable,
level,
property: "padding-left",
textContent: paddingLeft,
onShowBoxModelEditor,

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

@ -22,7 +22,6 @@ support-files =
[browser_boxmodel_editablemodel_stylerules.js]
[browser_boxmodel_guides.js]
[browser_boxmodel_navigation.js]
skip-if = true # Bug 1336198
[browser_boxmodel_offsetparent.js]
[browser_boxmodel_positions.js]
[browser_boxmodel_properties.js]

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

@ -28,49 +28,65 @@ add_task(function* () {
function* testInitialFocus(inspector, view) {
info("Test that the focus is on margin layout.");
let viewdoc = view.doc;
let boxmodel = viewdoc.getElementById("boxmodel-wrapper");
let viewdoc = view.document;
let boxmodel = viewdoc.querySelector(".boxmodel-container");
boxmodel.focus();
EventUtils.synthesizeKey("VK_RETURN", {});
is(boxmodel.getAttribute("aria-activedescendant"), "boxmodel-margins",
"Should be set to the margin layout.");
is(boxmodel.getAttribute("activedescendant"), "boxmodel-main",
"Should be set to the position layout.");
}
function* testChangingLevels(inspector, view) {
info("Test that using arrow keys updates level.");
let viewdoc = view.doc;
let boxmodel = viewdoc.getElementById("boxmodel-wrapper");
let viewdoc = view.document;
let boxmodel = viewdoc.querySelector(".boxmodel-container");
boxmodel.focus();
EventUtils.synthesizeKey("VK_RETURN", {});
EventUtils.synthesizeKey("VK_ESCAPE", {});
EventUtils.synthesizeKey("VK_DOWN", {});
is(boxmodel.getAttribute("aria-activedescendant"), "boxmodel-borders",
is(boxmodel.getAttribute("activedescendant"), "boxmodel-margins",
"Should be set to the margin layout.");
EventUtils.synthesizeKey("VK_DOWN", {});
is(boxmodel.getAttribute("activedescendant"), "boxmodel-borders",
"Should be set to the border layout.");
EventUtils.synthesizeKey("VK_DOWN", {});
is(boxmodel.getAttribute("aria-activedescendant"), "boxmodel-padding",
is(boxmodel.getAttribute("activedescendant"), "boxmodel-paddings",
"Should be set to the padding layout.");
EventUtils.synthesizeKey("VK_DOWN", {});
is(boxmodel.getAttribute("activedescendant"), "boxmodel-contents",
"Should be set to the content layout.");
EventUtils.synthesizeKey("VK_UP", {});
is(boxmodel.getAttribute("activedescendant"), "boxmodel-paddings",
"Should be set to the padding layout.");
EventUtils.synthesizeKey("VK_UP", {});
is(boxmodel.getAttribute("aria-activedescendant"), "boxmodel-borders",
is(boxmodel.getAttribute("activedescendant"), "boxmodel-borders",
"Should be set to the border layout.");
EventUtils.synthesizeKey("VK_UP", {});
is(boxmodel.getAttribute("aria-activedescendant"), "boxmodel-margins",
is(boxmodel.getAttribute("activedescendant"), "boxmodel-margins",
"Should be set to the margin layout.");
EventUtils.synthesizeKey("VK_UP", {});
is(boxmodel.getAttribute("activedescendant"), "boxmodel-main",
"Should be set to the position layout.");
}
function* testTabbingWrapAround(inspector, view) {
info("Test that using arrow keys updates level.");
let viewdoc = view.doc;
let boxmodel = viewdoc.getElementById("boxmodel-wrapper");
let viewdoc = view.document;
let boxmodel = viewdoc.querySelector(".boxmodel-container");
boxmodel.focus();
EventUtils.synthesizeKey("VK_RETURN", {});
let editLevel = boxmodel.getAttribute("aria-activedescendant");
let dataLevel = viewdoc.getElementById(editLevel).getAttribute("data-box");
let editLevel = boxmodel.getAttribute("activedescendant");
let dataLevel = viewdoc.querySelector(`.${editLevel}`).getAttribute("data-box");
let editBoxes = [...viewdoc.querySelectorAll(
`[data-box="${dataLevel}"].boxmodel-editable`)];
@ -86,18 +102,19 @@ function* testTabbingWrapAround(inspector, view) {
function* testChangingLevelsByClicking(inspector, view) {
info("Test that clicking on levels updates level.");
let viewdoc = view.doc;
let boxmodel = viewdoc.getElementById("boxmodel-wrapper");
let viewdoc = view.document;
let boxmodel = viewdoc.querySelector(".boxmodel-container");
boxmodel.focus();
let marginLayout = viewdoc.getElementById("boxmodel-margins");
let borderLayout = viewdoc.getElementById("boxmodel-borders");
let paddingLayout = viewdoc.getElementById("boxmodel-padding");
let layouts = [paddingLayout, borderLayout, marginLayout];
let marginLayout = viewdoc.querySelector(".boxmodel-margins");
let borderLayout = viewdoc.querySelector(".boxmodel-borders");
let paddingLayout = viewdoc.querySelector(".boxmodel-paddings");
let contentLayout = viewdoc.querySelector(".boxmodel-contents");
let layouts = [contentLayout, paddingLayout, borderLayout, marginLayout];
layouts.forEach(layout => {
layout.click();
is(boxmodel.getAttribute("aria-activedescendant"), layout.id,
is(boxmodel.getAttribute("activedescendant"), layout.className,
"Should be set to" + layout.getAttribute("data-box") + "layout.");
});
}

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

@ -135,7 +135,7 @@
<div id="computedview-container">
<div id="computedview-container-focusable" tabindex="-1">
<div id="boxmodel-wrapper" tabindex="0">
<div id="boxmodel-wrapper">
</div>
<div id="propertyContainer" class="theme-separator" tabindex="0" dir="ltr">

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

@ -7,10 +7,6 @@
*/
.boxmodel-container {
/* The view will grow bigger as the window gets resized, until 400px */
max-width: 400px;
margin: 0px auto;
padding: 0;
overflow: auto;
}
@ -33,9 +29,11 @@
position: relative;
color: var(--theme-selection-color);
/* Make sure there is some space between the window's edges and the regions */
margin: 14px 14px 4px 14px;
margin: 14px auto;
width: calc(100% - 2 * 14px);
min-width: 240px;
/* The view will grow bigger as the window gets resized, until 400px */
max-width: 400px;
}
.boxmodel-box {

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

@ -335,10 +335,10 @@ Parameter.prototype.toJson = function() {
};
// Values do not need to be serializable, so we don't try. For the client
// side (which doesn't do any executing) we don't actually care what the
// default value is, just that it exists
// side (which doesn't do any executing) we only care whether default value is
// undefined, null, or something else.
if (this.paramSpec.defaultValue !== undefined) {
json.defaultValue = {};
json.defaultValue = (this.paramSpec.defaultValue === null) ? null : {};
}
if (this.paramSpec.description != null) {
json.description = this.paramSpec.description;

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

@ -69,7 +69,7 @@ function getHelpManData(commandData, context) {
}
else {
// We need defaultText to work the text version of defaultValue
input = l10n.lookupFormat('helpManOptional');
input = l10n.lookup('helpManOptional');
/*
var val = param.type.stringify(param.defaultValue);
input = Promise.resolve(val).then(function(defaultValue) {

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

@ -47,6 +47,11 @@ DocGroup::DocGroup(TabGroup* aTabGroup, const nsACString& aKey)
DocGroup::~DocGroup()
{
MOZ_ASSERT(mDocuments.IsEmpty());
if (!NS_IsMainThread()) {
nsIEventTarget* target = EventTargetFor(TaskCategory::Other);
NS_ProxyRelease(target, mReactionsStack.forget());
}
mTabGroup->mDocGroups.RemoveEntry(mKey);
}

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

@ -5331,7 +5331,7 @@ static bool sRemovingScriptBlockers = false;
void
nsContentUtils::RemoveScriptBlocker()
{
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!sRemovingScriptBlockers);
NS_ASSERTION(sScriptBlockerCount != 0, "Negative script blockers");
--sScriptBlockerCount;

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

@ -16,6 +16,7 @@
<script>
var io = new IntersectionObserver(function (records) {
window.parent.postMessage(records[0].rootBounds == null, 'http://mochi.test:8888');
io.disconnect();
}, {});
io.observe(document.getElementById("target5"));
</script>

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

@ -27,6 +27,7 @@
records[0].rootBounds.bottom === viewportHeight &&
records[0].rootBounds.height === viewportHeight;
window.opener.postMessage(passed, '*');
io.disconnect();
});
io.observe(document.getElementById("target"));
</script>

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

@ -112,6 +112,18 @@ public:
_31 == 0.0 && _32 == 0.0;
}
/* Returns true if the matrix is a rectilinear transformation (i.e.
* grid-aligned rectangles are transformed to grid-aligned rectangles)
*/
bool IsRectilinear() const {
if (FuzzyEqual(_12, 0) && FuzzyEqual(_21, 0)) {
return true;
} else if (FuzzyEqual(_22, 0) && FuzzyEqual(_11, 0)) {
return true;
}
return false;
}
/**
* Inverts this matrix, if possible. Otherwise, the matrix is left
* unchanged.

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

@ -25,7 +25,7 @@ namespace image {
// AnimationState implementation.
///////////////////////////////////////////////////////////////////////////////
void
const gfx::IntRect
AnimationState::UpdateState(bool aAnimationFinished,
RasterImage *aImage,
const gfx::IntSize& aSize)
@ -36,12 +36,13 @@ AnimationState::UpdateState(bool aAnimationFinished,
DefaultSurfaceFlags(),
PlaybackType::eAnimated));
UpdateStateInternal(result, aAnimationFinished);
return UpdateStateInternal(result, aAnimationFinished, aSize);
}
void
const gfx::IntRect
AnimationState::UpdateStateInternal(LookupResult& aResult,
bool aAnimationFinished)
bool aAnimationFinished,
const gfx::IntSize& aSize)
{
// Update mDiscarded and mIsCurrentlyDecoded.
if (aResult.Type() == MatchType::NOT_FOUND) {
@ -73,6 +74,8 @@ AnimationState::UpdateStateInternal(LookupResult& aResult,
}
}
gfx::IntRect ret;
// Update the value of mCompositedFrameInvalid.
if (mIsCurrentlyDecoded || aAnimationFinished) {
// Animated images that have finished their animation (ie because it is a
@ -84,6 +87,10 @@ AnimationState::UpdateStateInternal(LookupResult& aResult,
// to do for images that aren't finished animating because before we paint
// the refresh driver will call into us to advance to the correct frame,
// and that will succeed because we have all the frames.
if (mCompositedFrameInvalid) {
// Invalidate if we are marking the composited frame valid.
ret.SizeTo(aSize);
}
mCompositedFrameInvalid = false;
} else if (aResult.Type() == MatchType::NOT_FOUND ||
aResult.Type() == MatchType::PENDING) {
@ -94,6 +101,8 @@ AnimationState::UpdateStateInternal(LookupResult& aResult,
}
// Otherwise don't change the value of mCompositedFrameInvalid, it will be
// updated by RequestRefresh.
return ret;
}
void
@ -372,8 +381,11 @@ FrameAnimator::RequestRefresh(AnimationState& aState,
DefaultSurfaceFlags(),
PlaybackType::eAnimated));
aState.UpdateStateInternal(result, aAnimationFinished);
ret.mDirtyRect = aState.UpdateStateInternal(result, aAnimationFinished, mSize);
if (aState.IsDiscarded() || !result) {
if (!ret.mDirtyRect.IsEmpty()) {
ret.mFrameAdvanced = true;
}
return ret;
}

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

@ -42,14 +42,16 @@ public:
/**
* Call this whenever a decode completes, a decode starts, or the image is
* discarded. It will update the internal state. Specifically mDiscarded,
* mCompositedFrameInvalid, and mIsCurrentlyDecoded.
* mCompositedFrameInvalid, and mIsCurrentlyDecoded. Returns a rect to
* invalidate.
*/
void UpdateState(bool aAnimationFinished,
RasterImage *aImage,
const gfx::IntSize& aSize);
const gfx::IntRect UpdateState(bool aAnimationFinished,
RasterImage *aImage,
const gfx::IntSize& aSize);
private:
void UpdateStateInternal(LookupResult& aResult,
bool aAnimationFinished);
const gfx::IntRect UpdateStateInternal(LookupResult& aResult,
bool aAnimationFinished,
const gfx::IntSize& aSize);
public:
/**

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

@ -415,9 +415,16 @@ RasterImage::WillDrawOpaqueNow()
return false;
}
if (mAnimationState && !gfxPrefs::ImageMemAnimatedDiscardable()) {
// We never discard frames of animated images.
return true;
if (mAnimationState) {
if (!gfxPrefs::ImageMemAnimatedDiscardable()) {
// We never discard frames of animated images.
return true;
} else {
if (mAnimationState->GetCompositedFrameInvalid()) {
// We're not going to draw anything at all.
return false;
}
}
}
// If we are not locked our decoded data could get discard at any time (ie
@ -464,7 +471,9 @@ RasterImage::OnSurfaceDiscardedInternal(bool aAnimatedFramesDiscarded)
if (aAnimatedFramesDiscarded && mAnimationState) {
MOZ_ASSERT(gfxPrefs::ImageMemAnimatedDiscardable());
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
gfx::IntRect rect =
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
NotifyProgress(NoProgress, rect);
}
if (mProgressTracker) {
@ -1077,7 +1086,9 @@ RasterImage::Discard()
SurfaceCache::RemoveImage(ImageKey(this));
if (mAnimationState) {
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
gfx::IntRect rect =
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
NotifyProgress(NoProgress, rect);
}
// Notify that we discarded.
@ -1250,6 +1261,11 @@ RasterImage::Decode(const IntSize& aSize,
task = DecoderFactory::CreateAnimationDecoder(mDecoderType, WrapNotNull(this),
mSourceBuffer, mSize,
decoderFlags, surfaceFlags);
// We may not be able to send an invalidation right here because of async
// notifications but that's not a problem because the first frame
// invalidation (when it comes) will invalidate for us. So we can ignore
// the return value of UpdateState. This also handles the invalidation
// from setting the composited frame as valid below.
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
// If the animation is finished we can draw right away because we just draw
// the final frame all the time from now on. See comment in
@ -1714,7 +1730,10 @@ RasterImage::NotifyDecodeComplete(const DecoderFinalStatus& aStatus,
// We've finished a full decode of all animation frames and our AnimationState
// has been notified about them all, so let it know not to expect anymore.
mAnimationState->NotifyDecodeComplete();
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
gfx::IntRect rect = mAnimationState->UpdateState(mAnimationFinished, this, mSize);
if (!rect.IsEmpty()) {
NotifyProgress(NoProgress, rect);
}
}
// Do some telemetry if this isn't a metadata decode.

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

@ -129,23 +129,30 @@ function addCallbacks(anImage, arrayIndex) {
if (!gCountingFrameUpdates) {
return;
}
gNumFrameUpdates[arrayIndex]++;
var r = document.getElementById(gImgs[arrayIndex]).getBoundingClientRect();
var snapshot = snapshotRect(window, r, "rgba(0,0,0,0)");
if (gLastSnapShot[arrayIndex] != null) {
if (snapshot.toDataURL() != gLastSnapShot[arrayIndex].toDataURL()) {
gNumSnapShotChanges[arrayIndex]++;
// Do this off a setTimeout since nsImageLoadingContent uses a scriptblocker
// when it notifies us and calling drawWindow can call will paint observers
// which can dispatch a scrollport event, and events assert if dispatched
// when there is a scriptblocker.
setTimeout(function () {
gNumFrameUpdates[arrayIndex]++;
var r = document.getElementById(gImgs[arrayIndex]).getBoundingClientRect();
var snapshot = snapshotRect(window, r, "rgba(0,0,0,0)");
if (gLastSnapShot[arrayIndex] != null) {
if (snapshot.toDataURL() != gLastSnapShot[arrayIndex].toDataURL()) {
gNumSnapShotChanges[arrayIndex]++;
}
}
}
gLastSnapShot[arrayIndex] = snapshot;
gLastSnapShot[arrayIndex] = snapshot;
if (gNumFrameUpdates[arrayIndex] >= kNumFrameUpdatesToExpect &&
gNumSnapShotChanges[arrayIndex] >= kNumFrameUpdatesToExpect) {
imgLoadingContent.removeObserver(scriptedObserver);
}
ok(true, "got frame update");
checkIfFinished();
if (gNumFrameUpdates[arrayIndex] >= kNumFrameUpdatesToExpect &&
gNumSnapShotChanges[arrayIndex] >= kNumFrameUpdatesToExpect) {
imgLoadingContent.removeObserver(scriptedObserver);
}
ok(true, "got frame update");
checkIfFinished();
}, 0);
};
observer = SpecialPowers.wrapCallbackObject(observer);

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

@ -516,17 +516,22 @@ js::obj_toString(JSContext* cx, unsigned argc, Value* vp)
// Non-standard (bug 1277801): Use ClassName as a fallback in the interim
if (!builtinTag) {
const char* className = GetObjectClassName(cx, obj);
// "[object Object]" is by far the most common case at this point,
// so we optimize it here.
if (strcmp(className, "Object") == 0) {
builtinTag = cx->names().objectObject;
} else {
StringBuffer sb(cx);
if (!sb.append("[object ") || !sb.append(className, strlen(className)) ||
!sb.append("]"))
{
return false;
}
StringBuffer sb(cx);
if (!sb.append("[object ") || !sb.append(className, strlen(className)) ||
!sb.append("]"))
{
return false;
builtinTag = sb.finishAtom();
if (!builtinTag)
return false;
}
builtinTag = sb.finishString();
if (!builtinTag)
return false;
}
args.rval().setString(builtinTag);
@ -538,7 +543,7 @@ js::obj_toString(JSContext* cx, unsigned argc, Value* vp)
if (!sb.append("[object ") || !sb.append(tag.toString()) || !sb.append("]"))
return false;
RootedString str(cx, sb.finishString());
JSString* str = sb.finishAtom();
if (!str)
return false;

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

@ -1013,7 +1013,7 @@ BaselineScript::toggleTraceLoggerScripts(JSRuntime* runtime, JSScript* script, b
// Patch the logging script textId to be correct.
// When logging log the specific textId else the global Scripts textId.
if (enable && !traceLoggerScriptEvent_.hasPayload())
if (enable && !traceLoggerScriptEvent_.hasTextId())
traceLoggerScriptEvent_ = TraceLoggerEvent(TraceLogger_Scripts, script);
AutoWritableJitCode awjc(method());

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

@ -7976,13 +7976,13 @@ JitRuntime::generateTLEventVM(JSContext* cx, MacroAssembler& masm, const VMFunct
}
if (vmSpecificEventEnabled) {
TraceLoggerEvent event(f.name());
if (!event.hasPayload())
if (!event.hasTextId())
return false;
if (enter)
masm.tracelogStartId(loggerReg, event.payload()->textId(), /* force = */ true);
masm.tracelogStartId(loggerReg, event.textId(), /* force = */ true);
else
masm.tracelogStopId(loggerReg, event.payload()->textId(), /* force = */ true);
masm.tracelogStopId(loggerReg, event.textId(), /* force = */ true);
}
masm.Pop(loggerReg);
@ -9942,22 +9942,22 @@ CodeGenerator::link(JSContext* cx, CompilerConstraintList* constraints)
for (uint32_t i = 0; i < patchableTLEvents_.length(); i++) {
TraceLoggerEvent event(patchableTLEvents_[i].event);
if (!event.hasPayload() || !ionScript->addTraceLoggerEvent(event)) {
if (!event.hasTextId() || !ionScript->addTraceLoggerEvent(event)) {
TLFailed = true;
break;
}
Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, patchableTLEvents_[i].offset),
ImmPtr((void*) uintptr_t(event.payload()->textId())),
ImmPtr((void*) uintptr_t(event.textId())),
ImmPtr((void*)0));
}
if (!TLFailed && patchableTLScripts_.length() > 0) {
MOZ_ASSERT(TraceLogTextIdEnabled(TraceLogger_Scripts));
TraceLoggerEvent event(TraceLogger_Scripts, script);
if (!event.hasPayload() || !ionScript->addTraceLoggerEvent(event))
if (!event.hasTextId() || !ionScript->addTraceLoggerEvent(event))
TLFailed = true;
if (!TLFailed) {
uint32_t textId = event.payload()->textId();
uint32_t textId = event.textId();
for (uint32_t i = 0; i < patchableTLScripts_.length(); i++) {
Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, patchableTLScripts_[i]),
ImmPtr((void*) uintptr_t(textId)),

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

@ -447,7 +447,7 @@ struct IonScript
return hasProfilingInstrumentation_;
}
MOZ_MUST_USE bool addTraceLoggerEvent(TraceLoggerEvent& event) {
MOZ_ASSERT(event.hasPayload());
MOZ_ASSERT(event.hasTextId());
return traceLoggerEvents_.append(Move(event));
}
const uint8_t* snapshots() const {

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

@ -258,6 +258,7 @@
macro(objectFunction, objectFunction, "[object Function]") \
macro(objectNull, objectNull, "[object Null]") \
macro(objectNumber, objectNumber, "[object Number]") \
macro(objectObject, objectObject, "[object Object]") \
macro(objectRegExp, objectRegExp, "[object RegExp]") \
macro(objects, objects, "objects") \
macro(objectString, objectString, "[object String]") \

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

@ -357,29 +357,6 @@ TraceLoggerThread::extractScriptDetails(uint32_t textId, const char** filename,
*colno_len = strlen(*colno);
}
TraceLoggerEventPayload*
TraceLoggerThreadState::getOrCreateEventPayload(TraceLoggerTextId textId)
{
LockGuard<Mutex> guard(lock);
TextIdHashMap::AddPtr p = textIdPayloads.lookupForAdd(textId);
if (p) {
MOZ_ASSERT(p->value()->textId() == textId); // Sanity check.
p->value()->use();
return p->value();
}
TraceLoggerEventPayload* payload = js_new<TraceLoggerEventPayload>(textId, (char*)nullptr);
if (!payload)
return nullptr;
if (!textIdPayloads.add(p, textId, payload))
return nullptr;
payload->use();
return payload;
}
TraceLoggerEventPayload*
TraceLoggerThreadState::getOrCreateEventPayload(const char* text)
{
@ -423,20 +400,12 @@ TraceLoggerThreadState::getOrCreateEventPayload(const char* text)
}
TraceLoggerEventPayload*
TraceLoggerThreadState::getOrCreateEventPayload(TraceLoggerTextId type, const char* filename,
TraceLoggerThreadState::getOrCreateEventPayload(const char* filename,
size_t lineno, size_t colno, const void* ptr)
{
MOZ_ASSERT(type == TraceLogger_Scripts || type == TraceLogger_AnnotateScripts ||
type == TraceLogger_InlinedScripts || type == TraceLogger_Frontend);
if (!filename)
filename = "<unknown>";
// Only log scripts when enabled otherwise return the global Scripts textId,
// which will get filtered out.
if (!isTextIdEnabled(type))
return getOrCreateEventPayload(type);
LockGuard<Mutex> guard(lock);
PointerHashMap::AddPtr p;
@ -494,10 +463,9 @@ TraceLoggerThreadState::getOrCreateEventPayload(TraceLoggerTextId type, const ch
}
TraceLoggerEventPayload*
TraceLoggerThreadState::getOrCreateEventPayload(TraceLoggerTextId type, JSScript* script)
TraceLoggerThreadState::getOrCreateEventPayload(JSScript* script)
{
return getOrCreateEventPayload(type, script->filename(), script->lineno(), script->column(),
nullptr);
return getOrCreateEventPayload(script->filename(), script->lineno(), script->column(), nullptr);
}
void
@ -533,7 +501,7 @@ TraceLoggerThread::startEvent(TraceLoggerTextId id) {
void
TraceLoggerThread::startEvent(const TraceLoggerEvent& event) {
if (!event.hasPayload()) {
if (!event.hasTextId()) {
if (!enabled())
return;
startEvent(TraceLogger_Error);
@ -542,7 +510,7 @@ TraceLoggerThread::startEvent(const TraceLoggerEvent& event) {
"this event. Disabling TraceLogger.");
return;
}
startEvent(event.payload()->textId());
startEvent(event.textId());
}
void
@ -576,11 +544,11 @@ TraceLoggerThread::stopEvent(TraceLoggerTextId id) {
void
TraceLoggerThread::stopEvent(const TraceLoggerEvent& event) {
if (!event.hasPayload()) {
if (!event.hasTextId()) {
stopEvent(TraceLogger_Error);
return;
}
stopEvent(event.payload()->textId());
stopEvent(event.textId());
}
void
@ -1009,43 +977,60 @@ js::TraceLogDisableTextId(JSContext* cx, uint32_t textId)
traceLoggerState->disableTextId(cx, textId);
}
TraceLoggerEvent::TraceLoggerEvent(TraceLoggerTextId textId)
{
payload_ = traceLoggerState ? traceLoggerState->getOrCreateEventPayload(textId) : nullptr;
}
TraceLoggerEvent::TraceLoggerEvent(TraceLoggerTextId type, JSScript* script)
{
payload_ = traceLoggerState ? traceLoggerState->getOrCreateEventPayload(type, script) : nullptr;
}
: TraceLoggerEvent(type, script->filename(), script->lineno(), script->column())
{ }
TraceLoggerEvent::TraceLoggerEvent(TraceLoggerTextId type, const char* filename, size_t line,
size_t column)
: payload_()
{
payload_ = traceLoggerState
? traceLoggerState->getOrCreateEventPayload(type, filename, line, column, nullptr)
: nullptr;
MOZ_ASSERT(type == TraceLogger_Scripts || type == TraceLogger_AnnotateScripts ||
type == TraceLogger_InlinedScripts || type == TraceLogger_Frontend);
if (!traceLoggerState)
return;
// Only log scripts when enabled, otherwise use the more generic type
// (which will get filtered out).
if (!traceLoggerState->isTextIdEnabled(type)) {
payload_.setTextId(type);
return;
}
payload_.setEventPayload(
traceLoggerState->getOrCreateEventPayload(filename, line, column, nullptr));
}
TraceLoggerEvent::TraceLoggerEvent(const char* text)
: payload_()
{
payload_ = traceLoggerState ? traceLoggerState->getOrCreateEventPayload(text) : nullptr;
if (traceLoggerState)
payload_.setEventPayload(traceLoggerState->getOrCreateEventPayload(text));
}
TraceLoggerEvent::~TraceLoggerEvent()
{
if (payload_)
payload_->release();
if (hasExtPayload())
extPayload()->release();
}
uint32_t
TraceLoggerEvent::textId() const
{
MOZ_ASSERT(hasTextId());
if (hasExtPayload())
return extPayload()->textId();
return payload_.textId();
}
TraceLoggerEvent&
TraceLoggerEvent::operator=(const TraceLoggerEvent& other)
{
if (other.hasPayload())
other.payload()->use();
if (hasPayload())
payload()->release();
if (other.hasExtPayload())
other.extPayload()->use();
if (hasExtPayload())
extPayload()->release();
payload_ = other.payload_;
@ -1053,8 +1038,8 @@ TraceLoggerEvent::operator=(const TraceLoggerEvent& other)
}
TraceLoggerEvent::TraceLoggerEvent(const TraceLoggerEvent& other)
: payload_(other.payload_)
{
payload_ = other.payload_;
if (hasPayload())
payload()->use();
if (hasExtPayload())
extPayload()->use();
}

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

@ -80,12 +80,56 @@ class TraceLoggerThread;
* this payload, so it cannot get removed.
*/
class TraceLoggerEvent {
#ifdef JS_TRACE_LOGGING
private:
TraceLoggerEventPayload* payload_;
class EventPayloadOrTextId {
/**
* Payload can be a pointer to a TraceLoggerEventPayload* or a
* TraceLoggerTextId. The last bit decides how to read the payload.
*
* payload_ = [ | 0 ]
* ------------------------ = TraceLoggerEventPayload* (incl. last bit)
* payload_ = [ | 1 ]
* ------------------- = TraceLoggerTextId (excl. last bit)
*/
uintptr_t payload_;
public:
EventPayloadOrTextId()
: payload_(0)
{ }
bool isEventPayload() const {
return (payload_ & 1) == 0;
}
TraceLoggerEventPayload* eventPayload() const {
MOZ_ASSERT(isEventPayload());
return (TraceLoggerEventPayload*) payload_;
}
void setEventPayload(TraceLoggerEventPayload* payload) {
payload_ = (uintptr_t)payload;
MOZ_ASSERT((payload_ & 1) == 0);
}
bool isTextId() const {
return (payload_ & 1) == 1;
}
uint32_t textId() const {
MOZ_ASSERT(isTextId());
return payload_ >> 1;
}
void setTextId(TraceLoggerTextId textId) {
static_assert(TraceLogger_Last < (UINT32_MAX >> 1), "Too many predefined text ids.");
payload_ = (((uint32_t)textId) << 1) | 1;
}
};
EventPayloadOrTextId payload_;
public:
TraceLoggerEvent() { payload_ = nullptr; };
#ifdef JS_TRACE_LOGGING
TraceLoggerEvent()
: payload_()
{}
explicit TraceLoggerEvent(TraceLoggerTextId textId);
TraceLoggerEvent(TraceLoggerTextId type, JSScript* script);
TraceLoggerEvent(TraceLoggerTextId type, const char* filename, size_t line, size_t column);
@ -93,7 +137,22 @@ class TraceLoggerEvent {
TraceLoggerEvent(const TraceLoggerEvent& event);
TraceLoggerEvent& operator=(const TraceLoggerEvent& other);
~TraceLoggerEvent();
uint32_t textId() const;
bool hasTextId() const {
return hasExtPayload() || payload_.isTextId();
}
private:
TraceLoggerEventPayload* extPayload() const {
MOZ_ASSERT(hasExtPayload());
return payload_.eventPayload();
}
bool hasExtPayload() const {
return payload_.isEventPayload() && !!payload_.eventPayload();
}
#else
public:
TraceLoggerEvent() {}
explicit TraceLoggerEvent(TraceLoggerTextId textId) {}
TraceLoggerEvent(TraceLoggerTextId type, JSScript* script) {}
TraceLoggerEvent(TraceLoggerTextId type, const char* filename, size_t line, size_t column) {}
@ -101,15 +160,10 @@ class TraceLoggerEvent {
TraceLoggerEvent(const TraceLoggerEvent& event) {}
TraceLoggerEvent& operator=(const TraceLoggerEvent& other) { return *this; };
~TraceLoggerEvent() {}
uint32_t textId() const { return 0; }
bool hasTextId() const { return false; }
#endif
TraceLoggerEventPayload* payload() const {
MOZ_ASSERT(hasPayload());
return payload_;
}
bool hasPayload() const {
return !!payload_;
}
};
#ifdef DEBUG
@ -378,11 +432,10 @@ class TraceLoggerThreadState
// This can be used to give start and stop events. Calls to these functions should be
// limited if possible, because of the overhead.
// Note: it is not allowed to use them in logTimestamp.
TraceLoggerEventPayload* getOrCreateEventPayload(TraceLoggerTextId textId);
TraceLoggerEventPayload* getOrCreateEventPayload(const char* text);
TraceLoggerEventPayload* getOrCreateEventPayload(TraceLoggerTextId type, JSScript* script);
TraceLoggerEventPayload* getOrCreateEventPayload(TraceLoggerTextId type, const char* filename,
size_t lineno, size_t colno, const void* p);
TraceLoggerEventPayload* getOrCreateEventPayload(JSScript* script);
TraceLoggerEventPayload* getOrCreateEventPayload(const char* filename, size_t lineno,
size_t colno, const void* p);
#endif
};

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

@ -1021,21 +1021,47 @@ nsSVGOuterSVGAnonChildFrame::GetType() const
}
bool
nsSVGOuterSVGAnonChildFrame::HasChildrenOnlyTransform(gfx::Matrix *aTransform) const
nsSVGOuterSVGAnonChildFrame::IsSVGTransformed(Matrix* aOwnTransform,
Matrix* aFromParentTransform) const
{
// We must claim our nsSVGOuterSVGFrame's children-only transforms as our own
// so that the children we are used to wrap are transformed properly.
// Our elements 'transform' attribute is applied to our nsSVGOuterSVGFrame
// parent, and the element's children-only transforms are applied to us, the
// anonymous child frame. Since we are the child frame, we apply the
// children-only transforms as if they are our own transform.
SVGSVGElement *content = static_cast<SVGSVGElement*>(mContent);
SVGSVGElement* content = static_cast<SVGSVGElement*>(mContent);
bool hasTransform = content->HasChildrenOnlyTransform();
if (hasTransform && aTransform) {
// Outer-<svg> doesn't use x/y, so we can pass eChildToUserSpace here.
gfxMatrix identity;
*aTransform = gfx::ToMatrix(
content->PrependLocalTransformsTo(identity, eChildToUserSpace));
if (!content->HasChildrenOnlyTransform()) {
return false;
}
return hasTransform;
// Outer-<svg> doesn't use x/y, so we can pass eChildToUserSpace here.
gfxMatrix ownMatrix =
content->PrependLocalTransformsTo(gfxMatrix(), eChildToUserSpace);
if (ownMatrix.IsIdentity()) {
return false;
}
if (aOwnTransform) {
if (ownMatrix.HasNonTranslation()) {
// viewBox, currentScale and currentTranslate should only produce a
// rectilinear transform.
MOZ_ASSERT(ownMatrix.IsRectilinear(),
"Non-rectilinear transform will break the following logic");
// The nsDisplayTransform code will apply this transform to our frame,
// including to our frame position. We don't want our frame position to
// be scaled though, so we need to correct for that in the transform.
// XXX Yeah, this is a bit hacky.
CSSPoint pos = CSSPixel::FromAppUnits(GetPosition());
CSSPoint scaledPos = CSSPoint(ownMatrix._11 * pos.x, ownMatrix._22 * pos.y);
CSSPoint deltaPos = scaledPos - pos;
ownMatrix *= gfxMatrix::Translation(-deltaPos.x, -deltaPos.y);
}
*aOwnTransform = gfx::ToMatrix(ownMatrix);
}
return true;
}

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

@ -265,9 +265,7 @@ public:
virtual nsIAtom* GetType() const override;
bool IsSVGTransformed(Matrix *aOwnTransform,
Matrix *aFromParentTransform) const override {
return false;
}
Matrix *aFromParentTransform) const override;
// nsSVGContainerFrame methods:
virtual gfxMatrix GetCanvasTM() override {
@ -276,8 +274,6 @@ public:
// set on us for any CSS border or padding on our nsSVGOuterSVGFrame.
return static_cast<nsSVGOuterSVGFrame*>(GetParent())->GetCanvasTM();
}
virtual bool HasChildrenOnlyTransform(Matrix *aTransform) const override;
};
#endif

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

@ -1,15 +1,87 @@
{
"an": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"ar": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"as": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"ast": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"az": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"bg": {
"platforms": [
"android",
"android-api-15"
],
"revision": "default"
},
"bn-BD": {
"platforms": [
"android",
"android-api-15"
],
"revision": "default"
},
"bn-IN": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"br": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"ca": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"cak": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
@ -21,6 +93,14 @@
],
"revision": "default"
},
"cy": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"da": {
"platforms": [
"android",
@ -37,13 +117,61 @@
],
"revision": "default"
},
"es-AR": {
"dsb": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"el": {
"platforms": [
"android",
"android-api-15"
],
"revision": "default"
},
"en-GB": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"en-ZA": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"eo": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"es-AR": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"es-CL": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"es-ES": {
"platforms": [
"android",
@ -52,24 +180,43 @@
],
"revision": "default"
},
"es-MX": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"et": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"eu": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"fa": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"ff": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
@ -92,49 +239,112 @@
"fy-NL": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"ga-IE": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"gd": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"gl": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"gn": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"gu-IN": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"he": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"hi-IN": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"hr": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"hsb": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"hu": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"hy-AM": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"id": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"is": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
@ -154,6 +364,37 @@
],
"revision": "default"
},
"ka": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"kab": {
"platforms": [
"android",
"android-api-15"
],
"revision": "default"
},
"kk": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"kn": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"ko": {
"platforms": [
"android",
@ -162,13 +403,69 @@
],
"revision": "default"
},
"lt": {
"lo": {
"platforms": [
"android",
"android-api-15"
],
"revision": "default"
},
"lt": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"lv": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"mai": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"ml": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"mr": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"ms": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"my": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"nb-NO": {
"platforms": [
"android",
@ -177,6 +474,13 @@
],
"revision": "default"
},
"ne-NP": {
"platforms": [
"android",
"android-api-15"
],
"revision": "default"
},
"nl": {
"platforms": [
"android",
@ -188,14 +492,24 @@
"nn-NO": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"or": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"pa-IN": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
@ -223,10 +537,19 @@
],
"revision": "default"
},
"rm": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"ro": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
@ -249,21 +572,32 @@
"sl": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"son": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"sq": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"sr": {
"platforms": [
"android",
"android-api-15"
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
@ -275,14 +609,46 @@
],
"revision": "default"
},
"ta": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"te": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"th": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"tr": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"trs": {
"platforms": [
"android",
"android-api-15"
],
"revision": "default"
},
"tr": {
"tsz": {
"platforms": [
"android",
"android-api-15"
@ -290,6 +656,45 @@
"revision": "default"
},
"uk": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"ur": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"uz": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"wo": {
"platforms": [
"android",
"android-api-15"
],
"revision": "default"
},
"xh": {
"platforms": [
"android",
"android-api-15",
"android-multilocale"
],
"revision": "default"
},
"zam": {
"platforms": [
"android",
"android-api-15"

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

@ -8,6 +8,7 @@
#include "nsStreamUtils.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "mozilla/UniquePtrExtensions.h"
NS_IMPL_ISUPPORTS(ArrayBufferInputStream, nsIArrayBufferInputStream, nsIInputStream);
@ -34,9 +35,14 @@ ArrayBufferInputStream::SetData(JS::Handle<JS::Value> aBuffer,
uint32_t buflen = JS_GetArrayBufferByteLength(arrayBuffer);
uint32_t offset = std::min(buflen, aByteOffset);
mBufferLength = std::min(buflen - offset, aLength);
uint32_t bufferLength = std::min(buflen - offset, aLength);
mArrayBuffer = mozilla::MakeUnique<char[]>(mBufferLength);
mArrayBuffer = mozilla::MakeUniqueFallible<char[]>(bufferLength);
if (!mArrayBuffer) {
return NS_ERROR_OUT_OF_MEMORY;
}
mBufferLength = bufferLength;
JS::AutoCheckCannotGC nogc;
bool isShared;

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

@ -1157,4 +1157,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1499872531802000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1499957787273000);

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

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

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

@ -404,6 +404,7 @@ HistoryStore.prototype = {
},
remove: function HistStore_remove(record) {
this._log.trace("Removing page: " + record.id);
return PlacesUtils.history.remove(record.id).then(
(removed) => {
if (removed) {
@ -412,7 +413,6 @@ HistoryStore.prototype = {
this._log.debug("Page already removed: " + record.id);
}
});
this._log.trace("Removing page: " + record.id);
},
itemExists: function HistStore_itemExists(id) {

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

@ -39,10 +39,8 @@ config = {
"update_verify_channel": "release-localtest",
"mar_channel_ids": [],
"channel_names": ["release", "release-localtest", "release-cdntest"],
"rules_to_update": ["firefox-release-cdntest", "firefox-release-localtest", "firefox-release-localtest-nowebsense-bypass",
"firefox-release-localtest-knownwebsense-bypass", "firefox-release-cdntest-nowebsense-bypass",
"firefox-release-cdntest-knownwebsense-bypass"],
"publish_rules": ["firefox-release", "firefox-release-nowebsense-bypass", "firefox-release-knownwebsense-bypass"],
"rules_to_update": ["firefox-release-cdntest", "firefox-release-localtest"],
"publish_rules": ["firefox-release"],
},
},
"balrog_use_dummy_suffix": False,

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

@ -1,5 +1,6 @@
[nomodule-set-on-async-classic-script.html]
type: testharness
[An asynchronously loaded classic script with noModule set to false must run]
expected: FAIL
[An asynchronously loaded classic script with noModule set to true must not run]
expected: FAIL

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

@ -11,6 +11,7 @@
</head>
<body>
<script>
let supportsNoModule = "noModule" in document.getElementsByTagName("script")[0];
waitForLoadEvent = new Promise((resolve) => {
window.onload = resolve;
@ -22,13 +23,13 @@ waitForAsyncScript = () => {
});
}
let readyForSecondTest;
promise_test(() => {
window.executed = false;
let loaded = false;
let errored = false;
let script = document.createElement('script');
script.src = './resources/set-script-executed.js';
script.onload = () => loaded = true;
script.onerror = () => errored = true;
@ -36,6 +37,7 @@ promise_test(() => {
document.body.appendChild(script);
return waitForAsyncScript().then(() => {
assert_true(supportsNoModule);
assert_true(executed);
assert_true(loaded);
assert_false(errored);
@ -55,6 +57,7 @@ promise_test(() => {
document.body.appendChild(script);
return waitForAsyncScript().then(() => {
assert_true(supportsNoModule);
assert_false(executed);
assert_false(loaded);
assert_false(errored);

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

@ -576,7 +576,11 @@ this.DownloadIntegration = {
// to match Windows behavior.
if (zone >= Ci.mozIDownloadPlatform.ZONE_INTERNET) {
let streamPath = aDownload.target.path + ":Zone.Identifier";
let stream = yield OS.File.open(streamPath, { create: true });
let stream = yield OS.File.open(
streamPath,
{ create: true },
{ winAllowLengthBeyondMaxPathWithCaveats: true }
);
try {
yield stream.write(new TextEncoder().encode("[ZoneTransfer]\r\nZoneId=" + zone + "\r\n"));
} finally {

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

@ -299,6 +299,15 @@
/*buf*/ Type.out_path
);
libc.declareLazyFFI(SysFile, "GetFullPathName",
"GetFullPathNameW", ctypes.winapi_abi,
/*return*/ Type.zero_or_DWORD,
/*fileName*/ Type.path,
/*length*/ Type.DWORD,
/*buf*/ Type.out_path,
/*filePart*/ Type.DWORD
);
libc.declareLazyFFI(SysFile, "GetDiskFreeSpaceEx",
"GetDiskFreeSpaceExW", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,

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

@ -343,6 +343,33 @@
mode = OS.Shared.AbstractFile.normalizeOpenMode(mode);
// The following option isn't a generic implementation of access to paths
// of arbitrary lengths. It allows for the specific case of writing to an
// Alternate Data Stream on a file whose path length is already close to
// MAX_PATH. This implementation is safe with a full path as input, if
// the first part of the path comes from local configuration and the
// file without the ADS was successfully opened before, so we know the
// path is valid.
if (options.winAllowLengthBeyondMaxPathWithCaveats) {
// Use the \\?\ syntax to allow lengths beyond MAX_PATH. This limited
// implementation only supports a DOS local path or UNC path as input.
let isUNC = path.length >= 2 && (path[0] == "\\" || path[0] == "/") &&
(path[1] == "\\" || path[1] == "/");
let pathToUse = "\\\\?\\" + (isUNC ? "UNC\\" + path.slice(2) : path);
// Use GetFullPathName to normalize slashes into backslashes. This is
// required because CreateFile won't do this for the \\?\ syntax.
let buffer_size = 512;
let array = new (ctypes.ArrayType(ctypes.char16_t, buffer_size))();
let expected_size = throw_on_zero("open",
WinFile.GetFullPathName(pathToUse, buffer_size, array, 0)
);
if (expected_size > buffer_size) {
// We don't need to allow an arbitrary path length for now.
throw new File.Error("open", ctypes.winLastError, path);
}
path = array.readString();
}
if ("winAccess" in options && "winDisposition" in options) {
access = options.winAccess;
disposition = options.winDisposition;

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

@ -456,7 +456,7 @@ var Impl = {
* @param {Boolean} [aOptions.usePingSender=false] if true, send the ping using the PingSender.
* @returns {Promise} Test-only - a promise that is resolved with the ping id once the ping is stored or sent.
*/
_submitPingLogic: Task.async(function* (aType, aPayload, aOptions) {
async _submitPingLogic(aType, aPayload, aOptions) {
// Make sure to have a clientId if we need one. This cover the case of submitting
// a ping early during startup, before Telemetry is initialized, if no client id was
// cached.
@ -464,7 +464,7 @@ var Impl = {
Telemetry.getHistogramById("TELEMETRY_PING_SUBMISSION_WAITING_CLIENTID").add();
// We can safely call |getClientID| here and during initialization: we would still
// spawn and return one single loading task.
this._clientID = yield ClientID.getClientID();
this._clientID = await ClientID.getClientID();
}
const pingData = this.assemblePing(aType, aPayload, aOptions);
@ -479,7 +479,7 @@ var Impl = {
p.push(TelemetrySend.submitPing(pingData, {usePingSender: aOptions.usePingSender}));
return Promise.all(p).then(() => pingData.id);
}),
},
/**
* Submit ping payloads to Telemetry.
@ -591,22 +591,22 @@ var Impl = {
*
* @return {Promise} Promise that is resolved when the ping is submitted and archived.
*/
checkAbortedSessionPing: Task.async(function*() {
let ping = yield TelemetryStorage.loadAbortedSessionPing();
async checkAbortedSessionPing() {
let ping = await TelemetryStorage.loadAbortedSessionPing();
this._log.trace("checkAbortedSessionPing - found aborted-session ping: " + !!ping);
if (!ping) {
return;
}
try {
yield TelemetryStorage.addPendingPing(ping);
yield TelemetryArchive.promiseArchivePing(ping);
await TelemetryStorage.addPendingPing(ping);
await TelemetryArchive.promiseArchivePing(ping);
} catch (e) {
this._log.error("checkAbortedSessionPing - Unable to add the pending ping", e);
} finally {
yield TelemetryStorage.removeAbortedSessionPing();
await TelemetryStorage.removeAbortedSessionPing();
}
}),
},
/**
* Save an aborted-session ping to disk without adding it to the pending pings.
@ -777,7 +777,7 @@ var Impl = {
},
// Do proper shutdown waiting and cleanup.
_cleanupOnShutdown: Task.async(function*() {
async _cleanupOnShutdown() {
if (!this._initialized) {
return;
}
@ -792,25 +792,25 @@ var Impl = {
TelemetryEnvironment.shutdown();
// Stop any ping sending.
yield TelemetrySend.shutdown();
await TelemetrySend.shutdown();
yield TelemetrySession.shutdown();
await TelemetrySession.shutdown();
// First wait for clients processing shutdown.
yield this._shutdownBarrier.wait();
await this._shutdownBarrier.wait();
// ... and wait for any outstanding async ping activity.
yield this._connectionsBarrier.wait();
await this._connectionsBarrier.wait();
// Perform final shutdown operations.
yield TelemetryStorage.shutdown();
await TelemetryStorage.shutdown();
} finally {
// Reset state.
this._initialized = false;
this._initStarted = false;
this._shuttingDown = true;
}
}),
},
shutdown() {
this._log.trace("shutdown");
@ -949,11 +949,11 @@ var Impl = {
return ping;
},
reset: Task.async(function*() {
async reset() {
this._clientID = null;
this._detachObservers();
yield TelemetrySession.testReset();
let sessionReset = TelemetrySession.testReset();
this._connectionsBarrier = new AsyncShutdown.Barrier(
"TelemetryController: Waiting for pending ping activity"
@ -966,10 +966,11 @@ var Impl = {
// cached client id.
let controllerSetup = this.setupTelemetry(true);
yield TelemetrySend.reset();
yield TelemetryStorage.reset();
yield TelemetryEnvironment.testReset();
await sessionReset;
await TelemetrySend.reset();
await TelemetryStorage.reset();
await TelemetryEnvironment.testReset();
yield controllerSetup;
}),
await controllerSetup;
},
};

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

@ -8,8 +8,8 @@ support-files =
[test_crash_moz_crash.js]
[test_crash_purevirtual.js]
[test_crash_rust_panic.js]
# Fails on Win64, bug 1302078.
fail-if = os == 'win' && bits == 64
# Fails on Win64, bug 1302078 (but sometimes passes, so just skip it)
skip-if = os == 'win' && bits == 64
[test_crash_after_js_oom_reported.js]
[test_crash_after_js_oom_recovered.js]
[test_crash_after_js_oom_reported_2.js]

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

@ -4,6 +4,9 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Core", "Window Management")
MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
XPIDL_SOURCES += [

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

@ -4,4 +4,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/.
with Files("**"):
BUG_COMPONENT = ("SeaMonkey", "Autocomplete")
JAR_MANIFESTS += ['jar.mn']

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

@ -4,6 +4,9 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Core", "Window Management")
SOURCES += [
'nsModule.cpp',
]

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

@ -4,6 +4,9 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Core", "Window Management")
XPIDL_SOURCES += [
'nsIHTTPIndex.idl',
]

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

@ -4,6 +4,9 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Core", "Window Management")
DIRS += [
'windowds',
'directory',

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

@ -4,6 +4,9 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Core", "Window Management")
XPIDL_SOURCES += [
'nsIWindowDataSource.idl',
]