Merge mozilla-central to autoland. a=merge CLOSED TREE

This commit is contained in:
shindli 2018-04-17 01:45:58 +03:00
Родитель ef69fa90f1 7b924dade9
Коммит 805cb19c1d
182 изменённых файлов: 3407 добавлений и 12953 удалений

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

@ -347,8 +347,8 @@ var DownloadsCommon = {
}
if (summary.totalSize != 0) {
summary.percentComplete = (summary.totalTransferred /
summary.totalSize) * 100;
summary.percentComplete =
Math.floor((summary.totalTransferred / summary.totalSize) * 100);
}
if (summary.slowestSpeed == Infinity) {

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

@ -1,9 +1,9 @@
This is the debugger.html project output.
See https://github.com/devtools-html/debugger.html
Version 38.0
Version 39.0
Comparison: https://github.com/devtools-html/debugger.html/compare/release-37...release-38
Comparison: https://github.com/devtools-html/debugger.html/compare/release-38...release-39
Packages:
- babel-plugin-transform-es2015-modules-commonjs @6.26.0

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

@ -2837,17 +2837,50 @@ debug-expression-error {
padding: 0.5em 1em 0.5em 0.5em;
}
.breakpoints-list .breakpoint {
.breakpoints-list .breakpoint-heading,
.breakpoints-list .breakpoint,
.breakpoints-exceptions {
padding: 0.5em 1em 0.5em 0.5em;
}
.breakpoints-exceptions-caught {
padding: 0 1em 0.5em 2em;
}
.breakpoints-exceptions-options:not(.empty) {
border-bottom: 1px solid var(--theme-splitter-color);
}
.breakpoints-exceptions input,
.breakpoints-exceptions-caught input {
padding-inline-start: 2px;
margin-inline-start: 0;
vertical-align: text-bottom;
}
.breakpoint-exceptions-label {
padding-top: 2px;
display: inline-block;
padding-inline-start: 2px;
padding-inline-end: 8px;
cursor: default;
}
.breakpoints-list .breakpoint,
.breakpoints-exceptions,
.breakpoints-exceptions-caught {
display: flex;
}
html[dir="rtl"] .breakpoints-list .breakpoint,
html[dir="rtl"] .breakpoints-list .breakpoint-heading {
html[dir="rtl"] .breakpoints-list .breakpoint-heading,
html[dir="rtl"] .breakpoints-exceptions {
border-right: 4px solid transparent;
}
html:not([dir="rtl"]) .breakpoints-list .breakpoint,
html:not([dir="rtl"]) .breakpoints-list .breakpoint-heading {
html:not([dir="rtl"]) .breakpoints-list .breakpoint-heading,
html:not([dir="rtl"]) .breakpoints-exceptions {
border-left: 4px solid transparent;
}
@ -2967,7 +3000,7 @@ html[dir="rtl"] .breakpoints-list .breakpoint .breakpoint-line {
opacity: 0.5;
}
.CodeMirror.cm-s-mozilla-breakpoint .CodeMirror-line span[role=presentation] {
.CodeMirror.cm-s-mozilla-breakpoint .CodeMirror-line span[role="presentation"] {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
@ -3512,23 +3545,6 @@ img.shortcuts {
transform: scaleX(-1);
}
.command-bar > .pause-exceptions.uncaught.enabled > img.pause-exceptions {
background-color: var(--theme-highlight-purple);
}
.command-bar > .pause-exceptions.all.enabled > img.pause-exceptions {
background-color: var(--theme-highlight-blue);
}
.command-bar > .pause-exceptions.enabled > img.pause-exceptions {
background-color: var(--theme-body-color);
}
.command-bar img.pause-exceptions {
mask: url("chrome://devtools/skin/images/debugger/pause-exceptions.svg") no-repeat;
margin-inline-start: 0.2em;
}
.command-bar .filler {
flex-grow: 1;
}
@ -3596,149 +3612,6 @@ img.shortcuts {
* 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/>. */
.dropdown {
--width: 150px;
background: var(--theme-body-background);
border: 1px solid var(--theme-splitter-color);
box-shadow: 0 4px 4px 0 var(--search-overlays-semitransparent);
max-height: 300px;
position: absolute;
right: 0;
top: 23px;
width: var(--width);
z-index: 1000;
overflow: auto;
}
html[dir="rtl"] .dropdown {
right: calc((var(--width) - 11px) * (-1));
}
.dropdown-block {
padding: 0px 2px;
position: relative;
align-self: center;
height: 100%;
}
.dropdown-button {
color: var(--theme-comment);
background: none;
border: none;
padding: 0;
font-weight: 100;
font-size: 14px;
height: 100%;
width: 24px;
}
.dropdown li {
transition: all 0.25s ease;
padding: 2px 10px 10px 5px;
overflow: hidden;
height: 30px;
text-overflow: ellipsis;
white-space: nowrap;
}
.dropdown li:hover {
background-color: var(--search-overlays-semitransparent);
}
.dropdown-icon {
width: var(--icon-size);
height: var(--icon-size);
margin-right: 5px;
vertical-align: middle;
display: inline-block;
}
.dropdown-icon.prettyPrint {
mask: url("chrome://devtools/skin/images/debugger/prettyPrint.svg") no-repeat;
mask-size: 100%;
background: var(--theme-highlight-blue);
}
.dropdown-icon.blackBox {
mask: url("chrome://devtools/skin/images/debugger/blackBox.svg") no-repeat;
mask-size: 100%;
background: var(--theme-highlight-blue);
}
.dropdown-icon.file {
mask: url("chrome://devtools/skin/images/debugger/file.svg") no-repeat;
mask-size: 100%;
}
.dropdown ul {
list-style: none;
line-height: 2em;
font-size: 1em;
margin: 0;
padding: 0;
}
.dropdown-mask {
position: fixed;
width: 100%;
height: 100%;
background: transparent;
z-index: 999;
left: 0;
top: 0;
}
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
.dropdown span.icon-spacer {
margin-left: 8px;
}
.dropdown li.first {
border-bottom: 1px solid var(--theme-toolbar-background-hover);
}
img.pause-next,
img.pause-on-exceptions,
img.pause-uncaught-exceptions,
img.ignore-exceptions {
vertical-align: middle;
width: 16px;
height: 20px;
display: inline-block;
}
.dropdown div > img.pause-next {
mask: url("chrome://devtools/skin/images/debugger/pause.svg") no-repeat;
background-color: var(--theme-body-color);
}
.dropdown div > img.ignore-exceptions {
mask: url("chrome://devtools/skin/images/debugger/pause-exceptions.svg") no-repeat;
background-color: var(--theme-body-color);
}
.dropdown div > img.pause-uncaught-exceptions {
mask: url("chrome://devtools/skin/images/debugger/pause-exceptions.svg") no-repeat;
background-color: var(--theme-highlight-purple);
}
.dropdown div > img.pause-on-exceptions {
mask: url("chrome://devtools/skin/images/debugger/pause-exceptions.svg") no-repeat;
background-color: var(--theme-highlight-blue);
}
.dropdown div.pause-next.active,
.dropdown div.pause-on-exceptions.active,
.dropdown div.pause-uncaught-exceptions.active,
.dropdown div.ignore-exceptions.active > span.icon-spacer {
color: var(--theme-highlight-blue);
}
/* 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/>. */
.object-node.default-property {
opacity: 0.6;
}
@ -4070,6 +3943,101 @@ html .welcomebox .toggle-button-end.collapsed {
* 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/>. */
.dropdown {
--width: 150px;
background: var(--theme-body-background);
border: 1px solid var(--theme-splitter-color);
box-shadow: 0 4px 4px 0 var(--search-overlays-semitransparent);
max-height: 300px;
position: absolute;
right: 0;
top: 23px;
width: var(--width);
z-index: 1000;
overflow: auto;
}
html[dir="rtl"] .dropdown {
right: calc((var(--width) - 11px) * (-1));
}
.dropdown-block {
padding: 0px 2px;
position: relative;
align-self: center;
height: 100%;
}
.dropdown-button {
color: var(--theme-comment);
background: none;
border: none;
padding: 0;
font-weight: 100;
font-size: 14px;
height: 100%;
width: 24px;
}
.dropdown li {
transition: all 0.25s ease;
padding: 2px 10px 10px 5px;
overflow: hidden;
height: 30px;
text-overflow: ellipsis;
white-space: nowrap;
}
.dropdown li:hover {
background-color: var(--search-overlays-semitransparent);
}
.dropdown-icon {
width: var(--icon-size);
height: var(--icon-size);
margin-right: 5px;
vertical-align: middle;
display: inline-block;
}
.dropdown-icon.prettyPrint {
mask: url("chrome://devtools/skin/images/debugger/prettyPrint.svg") no-repeat;
mask-size: 100%;
background: var(--theme-highlight-blue);
}
.dropdown-icon.blackBox {
mask: url("chrome://devtools/skin/images/debugger/blackBox.svg") no-repeat;
mask-size: 100%;
background: var(--theme-highlight-blue);
}
.dropdown-icon.file {
mask: url("chrome://devtools/skin/images/debugger/file.svg") no-repeat;
mask-size: 100%;
}
.dropdown ul {
list-style: none;
line-height: 2em;
font-size: 1em;
margin: 0;
padding: 0;
}
.dropdown-mask {
position: fixed;
width: 100%;
height: 100%;
background: transparent;
z-index: 999;
left: 0;
top: 0;
}
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
.result-list {
list-style: none;
margin: 0px;

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

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

@ -778,7 +778,7 @@ const {
isOriginalId
} = __webpack_require__(1389);
const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1363);
const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1390);
const dispatcher = new WorkerDispatcher();
@ -880,53 +880,81 @@ WorkerDispatcher.prototype = {
this.worker = null;
},
task(method) {
return (...args) => {
task(method, { queue = false } = {}) {
const calls = [];
const push = args => {
return new Promise((resolve, reject) => {
const id = this.msgId++;
this.worker.postMessage({ id, method, args });
if (queue && calls.length === 0) {
Promise.resolve().then(flush);
}
const listener = ({ data: result }) => {
if (result.id !== id) {
return;
}
calls.push([args, resolve, reject]);
if (!this.worker) {
return;
}
this.worker.removeEventListener("message", listener);
if (result.error) {
reject(result.error);
} else {
resolve(result.response);
}
};
this.worker.addEventListener("message", listener);
if (!queue) {
flush();
}
});
};
const flush = () => {
const items = calls.slice();
calls.length = 0;
const id = this.msgId++;
this.worker.postMessage({ id, method, calls: items.map(item => item[0]) });
const listener = ({ data: result }) => {
if (result.id !== id) {
return;
}
if (!this.worker) {
return;
}
this.worker.removeEventListener("message", listener);
result.results.forEach((resultData, i) => {
const [, resolve, reject] = items[i];
if (resultData.error) {
reject(resultData.error);
} else {
resolve(resultData.response);
}
});
};
this.worker.addEventListener("message", listener);
};
return (...args) => push(args);
}
};
function workerHandler(publicInterface) {
return function (msg) {
const { id, method, args } = msg.data;
try {
const response = publicInterface[method].apply(undefined, args);
if (response instanceof Promise) {
response.then(val => self.postMessage({ id, response: val }),
// Error can't be sent via postMessage, so be sure to
// convert to string.
err => self.postMessage({ id, error: err.toString() }));
} else {
self.postMessage({ id, response });
const { id, method, calls } = msg.data;
Promise.all(calls.map(args => {
try {
const response = publicInterface[method].apply(undefined, args);
if (response instanceof Promise) {
return response.then(val => ({ response: val }),
// Error can't be sent via postMessage, so be sure to
// convert to string.
err => ({ error: err.toString() }));
} else {
return { response };
}
} catch (error) {
// Error can't be sent via postMessage, so be sure to convert to
// string.
return { error: error.toString() };
}
} catch (error) {
// Error can't be sent via postMessage, so be sure to convert to
// string.
self.postMessage({ id, error: error.toString() });
}
})).then(results => {
self.postMessage({ id, results });
});
};
}
@ -1201,6 +1229,184 @@ module.exports = {
/***/ }),
/***/ 1390:
/***/ (function(module, exports, __webpack_require__) {
/* 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 networkRequest = __webpack_require__(1391);
const workerUtils = __webpack_require__(1392);
module.exports = {
networkRequest,
workerUtils
};
/***/ }),
/***/ 1391:
/***/ (function(module, exports) {
/* 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/. */
function networkRequest(url, opts) {
return fetch(url, {
cache: opts.loadFromCache ? "default" : "no-cache"
}).then(res => {
if (res.status >= 200 && res.status < 300) {
return res.text().then(text => ({ content: text }));
}
return Promise.reject(`request failed with status ${res.status}`);
});
}
module.exports = networkRequest;
/***/ }),
/***/ 1392:
/***/ (function(module, exports) {
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
function WorkerDispatcher() {
this.msgId = 1;
this.worker = null;
} /* 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/. */
WorkerDispatcher.prototype = {
start(url) {
this.worker = new Worker(url);
this.worker.onerror = () => {
console.error(`Error in worker ${url}`);
};
},
stop() {
if (!this.worker) {
return;
}
this.worker.terminate();
this.worker = null;
},
task(method) {
return (...args) => {
return new Promise((resolve, reject) => {
const id = this.msgId++;
this.worker.postMessage({ id, method, args });
const listener = ({ data: result }) => {
if (result.id !== id) {
return;
}
if (!this.worker) {
return;
}
this.worker.removeEventListener("message", listener);
if (result.error) {
reject(result.error);
} else {
resolve(result.response);
}
};
this.worker.addEventListener("message", listener);
});
};
}
};
function workerHandler(publicInterface) {
return function (msg) {
const { id, method, args } = msg.data;
try {
const response = publicInterface[method].apply(undefined, args);
if (response instanceof Promise) {
response.then(val => self.postMessage({ id, response: val }),
// Error can't be sent via postMessage, so be sure to
// convert to string.
err => self.postMessage({ id, error: err.toString() }));
} else {
self.postMessage({ id, response });
}
} catch (error) {
// Error can't be sent via postMessage, so be sure to convert to
// string.
self.postMessage({ id, error: error.toString() });
}
};
}
function streamingWorkerHandler(publicInterface, { timeout = 100 } = {}, worker = self) {
let streamingWorker = (() => {
var _ref = _asyncToGenerator(function* (id, tasks) {
let isWorking = true;
const intervalId = setTimeout(function () {
isWorking = false;
}, timeout);
const results = [];
while (tasks.length !== 0 && isWorking) {
const { callback, context, args } = tasks.shift();
const result = yield callback.call(context, args);
results.push(result);
}
worker.postMessage({ id, status: "pending", data: results });
clearInterval(intervalId);
if (tasks.length !== 0) {
yield streamingWorker(id, tasks);
}
});
return function streamingWorker(_x, _x2) {
return _ref.apply(this, arguments);
};
})();
return (() => {
var _ref2 = _asyncToGenerator(function* (msg) {
const { id, method, args } = msg.data;
const workerMethod = publicInterface[method];
if (!workerMethod) {
console.error(`Could not find ${method} defined in worker.`);
}
worker.postMessage({ id, status: "start" });
try {
const tasks = workerMethod(args);
yield streamingWorker(id, tasks);
worker.postMessage({ id, status: "done" });
} catch (error) {
worker.postMessage({ id, status: "error", error });
}
});
return function (_x3) {
return _ref2.apply(this, arguments);
};
})();
}
module.exports = {
WorkerDispatcher,
workerHandler,
streamingWorkerHandler
};
/***/ }),
/***/ 14:
/***/ (function(module, exports) {
@ -19228,7 +19434,8 @@ function parseSourceScopes(sourceId) {
freeVariables: new Map(),
freeVariableStack: [],
scope: lexical,
scopeStack: []
scopeStack: [],
declarationBindingIds: new Set()
};
t.traverse(ast, scopeCollectionVisitor, state);
@ -19255,7 +19462,7 @@ function parseSourceScopes(sourceId) {
return toParsedScopes([global], sourceId) || [];
} /* 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/. */
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
function toParsedScopes(children, sourceId) {
if (!children || children.length === 0) {
@ -19322,7 +19529,7 @@ function fromBabelLocation(location, sourceId) {
};
}
function parseDeclarator(declaratorId, targetScope, type, declaration, sourceId) {
function parseDeclarator(declaratorId, targetScope, type, declaration, state) {
if (isNode(declaratorId, "Identifier")) {
let existing = targetScope.bindings[declaratorId.name];
if (!existing) {
@ -19332,27 +19539,28 @@ function parseDeclarator(declaratorId, targetScope, type, declaration, sourceId)
};
targetScope.bindings[declaratorId.name] = existing;
}
state.declarationBindingIds.add(declaratorId);
existing.refs.push({
type: "decl",
start: fromBabelLocation(declaratorId.loc.start, sourceId),
end: fromBabelLocation(declaratorId.loc.end, sourceId),
start: fromBabelLocation(declaratorId.loc.start, state.sourceId),
end: fromBabelLocation(declaratorId.loc.end, state.sourceId),
declaration: {
start: fromBabelLocation(declaration.loc.start, sourceId),
end: fromBabelLocation(declaration.loc.end, sourceId)
start: fromBabelLocation(declaration.loc.start, state.sourceId),
end: fromBabelLocation(declaration.loc.end, state.sourceId)
}
});
} else if (isNode(declaratorId, "ObjectPattern")) {
declaratorId.properties.forEach(prop => {
parseDeclarator(prop.value, targetScope, type, declaration, sourceId);
parseDeclarator(prop.value, targetScope, type, declaration, state);
});
} else if (isNode(declaratorId, "ArrayPattern")) {
declaratorId.elements.forEach(item => {
parseDeclarator(item, targetScope, type, declaration, sourceId);
parseDeclarator(item, targetScope, type, declaration, state);
});
} else if (isNode(declaratorId, "AssignmentPattern")) {
parseDeclarator(declaratorId.left, targetScope, type, declaration, sourceId);
parseDeclarator(declaratorId.left, targetScope, type, declaration, state);
} else if (isNode(declaratorId, "RestElement")) {
parseDeclarator(declaratorId.argument, targetScope, type, declaration, sourceId);
parseDeclarator(declaratorId.argument, targetScope, type, declaration, state);
}
}
@ -19409,6 +19617,7 @@ const scopeCollectionVisitor = {
start: fromBabelLocation(node.loc.start, state.sourceId),
end: fromBabelLocation(node.loc.end, state.sourceId)
});
state.declarationBindingIds.add(node.id);
scope.bindings[node.id.name] = {
type: "const",
refs: [{
@ -19426,6 +19635,7 @@ const scopeCollectionVisitor = {
if (t.isFunctionDeclaration(node) && isNode(node.id, "Identifier")) {
// This ignores Annex B function declaration hoisting, which
// is probably a fine assumption.
state.declarationBindingIds.add(node.id);
const fnScope = getVarScope(scope);
scope.bindings[node.id.name] = {
type: fnScope === scope ? "var" : "let",
@ -19448,7 +19658,7 @@ const scopeCollectionVisitor = {
end: fromBabelLocation(node.loc.end, state.sourceId)
});
node.params.forEach(param => parseDeclarator(param, scope, "var", node, state.sourceId));
node.params.forEach(param => parseDeclarator(param, scope, "var", node, state));
if (!t.isArrowFunctionExpression(node)) {
scope.bindings.this = {
@ -19462,6 +19672,7 @@ const scopeCollectionVisitor = {
}
} else if (t.isClass(node)) {
if (t.isClassDeclaration(node) && t.isIdentifier(node.id)) {
state.declarationBindingIds.add(node.id);
state.scope.bindings[node.id.name] = {
type: "let",
refs: [{
@ -19482,6 +19693,7 @@ const scopeCollectionVisitor = {
end: fromBabelLocation(node.loc.end, state.sourceId)
});
state.declarationBindingIds.add(node.id);
scope.bindings[node.id.name] = {
type: "const",
refs: [{
@ -19511,7 +19723,7 @@ const scopeCollectionVisitor = {
start: fromBabelLocation(node.loc.start, state.sourceId),
end: fromBabelLocation(node.loc.end, state.sourceId)
});
parseDeclarator(node.param, scope, "var", node, state.sourceId);
parseDeclarator(node.param, scope, "var", node, state);
} else if (t.isBlockStatement(node) && hasLexicalDeclaration(node, parentNode)) {
// Debugger will create new lexical environment for the block.
pushTempScope(state, "block", "Block", {
@ -19524,11 +19736,13 @@ const scopeCollectionVisitor = {
// Finds right lexical environment
const hoistAt = !isLetOrConst(node) ? getVarScope(state.scope) : state.scope;
node.declarations.forEach(declarator => {
parseDeclarator(declarator.id, hoistAt, node.kind, node, state.sourceId);
parseDeclarator(declarator.id, hoistAt, node.kind, node, state);
});
} else if (t.isImportDeclaration(node) && (!node.importKind || node.importKind === "value")) {
node.specifiers.forEach(spec => {
if (t.isImportNamespaceSpecifier(spec)) {
state.declarationBindingIds.add(spec.local);
state.scope.bindings[spec.local.name] = {
// Imported namespaces aren't live import bindings, they are
// just normal const bindings.
@ -19536,10 +19750,16 @@ const scopeCollectionVisitor = {
refs: [{
type: "decl",
start: fromBabelLocation(spec.local.loc.start, state.sourceId),
end: fromBabelLocation(spec.local.loc.end, state.sourceId)
end: fromBabelLocation(spec.local.loc.end, state.sourceId),
declaration: {
start: fromBabelLocation(node.loc.start, state.sourceId),
end: fromBabelLocation(node.loc.end, state.sourceId)
}
}]
};
} else {
state.declarationBindingIds.add(spec.local);
state.scope.bindings[spec.local.name] = {
type: "import",
refs: [{
@ -19556,6 +19776,7 @@ const scopeCollectionVisitor = {
}
});
} else if (t.isTSEnumDeclaration(node)) {
state.declarationBindingIds.add(node.id);
state.scope.bindings[node.id.name] = {
type: "const",
refs: [{
@ -19571,7 +19792,11 @@ const scopeCollectionVisitor = {
} else if (t.isIdentifier(node) && t.isReferenced(node, parentNode) &&
// Babel doesn't cover this in 'isReferenced' yet, but it should
// eventually.
!t.isTSEnumMember(parentNode, { id: node })) {
!t.isTSEnumMember(parentNode, { id: node }) &&
// isReferenced above fails to see `var { foo } = ...` as a non-reference
// because the direct parent is not enough to know that the pattern is
// used within a variable declaration.
!state.declarationBindingIds.has(node)) {
let freeVariables = state.freeVariables.get(node.name);
if (!freeVariables) {
freeVariables = [];

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

@ -151,53 +151,81 @@ WorkerDispatcher.prototype = {
this.worker = null;
},
task(method) {
return (...args) => {
task(method, { queue = false } = {}) {
const calls = [];
const push = args => {
return new Promise((resolve, reject) => {
const id = this.msgId++;
this.worker.postMessage({ id, method, args });
if (queue && calls.length === 0) {
Promise.resolve().then(flush);
}
const listener = ({ data: result }) => {
if (result.id !== id) {
return;
}
calls.push([args, resolve, reject]);
if (!this.worker) {
return;
}
this.worker.removeEventListener("message", listener);
if (result.error) {
reject(result.error);
} else {
resolve(result.response);
}
};
this.worker.addEventListener("message", listener);
if (!queue) {
flush();
}
});
};
const flush = () => {
const items = calls.slice();
calls.length = 0;
const id = this.msgId++;
this.worker.postMessage({ id, method, calls: items.map(item => item[0]) });
const listener = ({ data: result }) => {
if (result.id !== id) {
return;
}
if (!this.worker) {
return;
}
this.worker.removeEventListener("message", listener);
result.results.forEach((resultData, i) => {
const [, resolve, reject] = items[i];
if (resultData.error) {
reject(resultData.error);
} else {
resolve(resultData.response);
}
});
};
this.worker.addEventListener("message", listener);
};
return (...args) => push(args);
}
};
function workerHandler(publicInterface) {
return function (msg) {
const { id, method, args } = msg.data;
try {
const response = publicInterface[method].apply(undefined, args);
if (response instanceof Promise) {
response.then(val => self.postMessage({ id, response: val }),
// Error can't be sent via postMessage, so be sure to
// convert to string.
err => self.postMessage({ id, error: err.toString() }));
} else {
self.postMessage({ id, response });
const { id, method, calls } = msg.data;
Promise.all(calls.map(args => {
try {
const response = publicInterface[method].apply(undefined, args);
if (response instanceof Promise) {
return response.then(val => ({ response: val }),
// Error can't be sent via postMessage, so be sure to
// convert to string.
err => ({ error: err.toString() }));
} else {
return { response };
}
} catch (error) {
// Error can't be sent via postMessage, so be sure to convert to
// string.
return { error: error.toString() };
}
} catch (error) {
// Error can't be sent via postMessage, so be sure to convert to
// string.
self.postMessage({ id, error: error.toString() });
}
})).then(results => {
self.postMessage({ id, results });
});
};
}

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

@ -340,53 +340,81 @@ WorkerDispatcher.prototype = {
this.worker = null;
},
task(method) {
return (...args) => {
task(method, { queue = false } = {}) {
const calls = [];
const push = args => {
return new Promise((resolve, reject) => {
const id = this.msgId++;
this.worker.postMessage({ id, method, args });
if (queue && calls.length === 0) {
Promise.resolve().then(flush);
}
const listener = ({ data: result }) => {
if (result.id !== id) {
return;
}
calls.push([args, resolve, reject]);
if (!this.worker) {
return;
}
this.worker.removeEventListener("message", listener);
if (result.error) {
reject(result.error);
} else {
resolve(result.response);
}
};
this.worker.addEventListener("message", listener);
if (!queue) {
flush();
}
});
};
const flush = () => {
const items = calls.slice();
calls.length = 0;
const id = this.msgId++;
this.worker.postMessage({ id, method, calls: items.map(item => item[0]) });
const listener = ({ data: result }) => {
if (result.id !== id) {
return;
}
if (!this.worker) {
return;
}
this.worker.removeEventListener("message", listener);
result.results.forEach((resultData, i) => {
const [, resolve, reject] = items[i];
if (resultData.error) {
reject(resultData.error);
} else {
resolve(resultData.response);
}
});
};
this.worker.addEventListener("message", listener);
};
return (...args) => push(args);
}
};
function workerHandler(publicInterface) {
return function (msg) {
const { id, method, args } = msg.data;
try {
const response = publicInterface[method].apply(undefined, args);
if (response instanceof Promise) {
response.then(val => self.postMessage({ id, response: val }),
// Error can't be sent via postMessage, so be sure to
// convert to string.
err => self.postMessage({ id, error: err.toString() }));
} else {
self.postMessage({ id, response });
const { id, method, calls } = msg.data;
Promise.all(calls.map(args => {
try {
const response = publicInterface[method].apply(undefined, args);
if (response instanceof Promise) {
return response.then(val => ({ response: val }),
// Error can't be sent via postMessage, so be sure to
// convert to string.
err => ({ error: err.toString() }));
} else {
return { response };
}
} catch (error) {
// Error can't be sent via postMessage, so be sure to convert to
// string.
return { error: error.toString() };
}
} catch (error) {
// Error can't be sent via postMessage, so be sure to convert to
// string.
self.postMessage({ id, error: error.toString() });
}
})).then(results => {
self.postMessage({ id, results });
});
};
}

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

@ -11,6 +11,8 @@ support-files =
examples/babel/fixtures/eval-source-maps/output.js.map
examples/babel/fixtures/for-of/output.js
examples/babel/fixtures/for-of/output.js.map
examples/babel/fixtures/line-start-bindings-es6/output.js
examples/babel/fixtures/line-start-bindings-es6/output.js.map
examples/babel/fixtures/shadowed-vars/output.js
examples/babel/fixtures/shadowed-vars/output.js.map
examples/babel/fixtures/this-arguments-bindings/output.js

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

@ -61,6 +61,22 @@ add_task(async function() {
["aVar", '"var3"']
]);
await breakpointScopes(
dbg,
"line-start-bindings-es6",
{ line: 19, column: 4 },
[
"Block",
["<this>", '{\u2026}'],
["one", "1"],
["two", "2"],
"root",
["aFunc", "(optimized away)"],
"Module",
"root()"
]
);
await breakpointScopes(
dbg,
"this-arguments-bindings",
@ -87,7 +103,7 @@ add_task(async function() {
{ line: 8, column: 6 },
[
"arrow",
["argArrow", "(unmapped)"],
["argArrow", "(optimized away)"],
"Block",
"arrow()",
"fn",

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

@ -0,0 +1,29 @@
export default function root() {
function aFunc(){
// Since these bindings are on their own linem, the mappings will
// extend to the start of the line, rather than starting at the first
// character of the binding.
const {
one,
two
} = {
one: 1,
two: 2,
};
// The 'this' binding here is also its own line, so the comment above
// applies here too.
this.thing = 4;
console.log("pause here");
}
aFunc.call({ });
}
// The build harness sets the wrong global, so just override it.
Promise.resolve().then(() => {
window.lineStartBindingsEs6 = root;
});

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

@ -0,0 +1,105 @@
var lineStartBindingsEs6 =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony export (immutable) */ __webpack_exports__["default"] = root;
function root() {
function aFunc() {
// Since these bindings are on their own linem, the mappings will
// extend to the start of the line, rather than starting at the first
// character of the binding.
const {
one,
two
} = {
one: 1,
two: 2
};
// The 'this' binding here is also its own line, so the comment above
// applies here too.
this.thing = 4;
console.log("pause here");
}
aFunc.call({});
}
// The build harness sets the wrong global, so just override it.
Promise.resolve().then(() => {
window.lineStartBindingsEs6 = root;
});
/***/ })
/******/ ]);
//# sourceMappingURL=output.js.map

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

@ -0,0 +1 @@
{"version":3,"sources":["webpack:///webpack/bootstrap 3fee9e40469b3fb786b0","webpack:///./fixtures/line-start-bindings-es6/input.js"],"names":["root","aFunc","one","two","thing","console","log","call","Promise","resolve","then","window","lineStartBindingsEs6"],"mappings":";;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;;;;;AC5De,SAASA,IAAT,GAAgB;AAC7B,WAASC,KAAT,GAAgB;AACd;AACA;AACA;AACA,UAAM;AACJC,SADI;AAEJC;AAFI,QAGF;AACFD,WAAK,CADH;AAEFC,WAAK;AAFH,KAHJ;;AAQA;AACA;AACA,SAAKC,KAAL,GAAa,CAAb;;AAEAC,YAAQC,GAAR,CAAY,YAAZ;AACD;;AAEDL,QAAMM,IAAN,CAAW,EAAX;AACD;;AAGD;AACAC,QAAQC,OAAR,GAAkBC,IAAlB,CAAuB,MAAM;AAC3BC,SAAOC,oBAAP,GAA8BZ,IAA9B;AACD,CAFD,E","file":"fixtures/line-start-bindings-es6/output.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 3fee9e40469b3fb786b0","\nexport default function root() {\n function aFunc(){\n // Since these bindings are on their own linem, the mappings will\n // extend to the start of the line, rather than starting at the first\n // character of the binding.\n const {\n one,\n two\n } = {\n one: 1,\n two: 2,\n };\n\n // The 'this' binding here is also its own line, so the comment above\n // applies here too.\n this.thing = 4;\n\n console.log(\"pause here\");\n }\n\n aFunc.call({ });\n}\n\n\n// The build harness sets the wrong global, so just override it.\nPromise.resolve().then(() => {\n window.lineStartBindingsEs6 = root;\n});\n\n\n\n// WEBPACK FOOTER //\n// ./fixtures/line-start-bindings-es6/input.js"],"sourceRoot":""}

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

@ -49,7 +49,7 @@ module.exports = [
].concat(
tests.map(({ name, dirname, input, output }) => {
const babelEnabled = name !== "webpackStandalone";
const babelEnv = name !== "webpackModulesEs6";
const babelEnv = !name.match(/Es6/);
const babelModules = name !== "webpackModules";
const devtool =
name === "evalSourceMaps" ? "eval-source-map" : "source-map";

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

@ -29,6 +29,8 @@
<button onclick="functions()">Run functions</button>
<script src="babel/fixtures/imported-bindings/output.js"></script>
<button onclick="importedBindings()">Run importedBindings</button>
<script src="babel/fixtures/line-start-bindings-es6/output.js"></script>
<button onclick="lineStartBindingsEs6()">Run lineStartBindingsEs6</button>
<script src="babel/fixtures/modules/output.js"></script>
<button onclick="modules()">Run modules</button>
<script src="babel/fixtures/non-modules/output.js"></script>

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

@ -1,4 +0,0 @@
### Building
* `ember build`

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

@ -1,14 +0,0 @@
import Application from '@ember/application';
import Resolver from './resolver';
import loadInitializers from 'ember-load-initializers';
import config from './config/environment';
const App = Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
Resolver
});
loadInitializers(App, config.modulePrefix);
export default App;

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

@ -1,25 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Quickstart</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
{{content-for "head"}}
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css">
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/quickstart.css">
{{content-for "head-footer"}}
</head>
<body>
{{content-for "body"}}
<script src="{{rootURL}}assets/vendor.js"></script>
<script src="{{rootURL}}assets/quickstart.js"></script>
{{content-for "body-footer"}}
</body>
</html>

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

@ -1,3 +0,0 @@
import Resolver from 'ember-resolver';
export default Resolver;

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

@ -1,16 +0,0 @@
import EmberRouter from '@ember/routing/router';
import config from './config/environment';
const Router = EmberRouter.extend({
location: config.locationType,
rootURL: config.rootURL
});
Router.map(function() {
});
window.mapTestFunction = () => {
window.console.log("pause here", config, Router);
};
export default Router;

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

@ -1,5 +0,0 @@
{{!-- The following component displays Ember's default welcome message. --}}
{{welcome-page}}
{{!-- Feel free to remove this! --}}
{{outlet}}

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

@ -1,58 +0,0 @@
'use strict';
module.exports = function(environment) {
let ENV = {
modulePrefix: 'quickstart',
environment,
locationType: 'auto',
EmberENV: {
FEATURES: {
// Here you can enable experimental features on an ember canary build
// e.g. 'with-controller': true
},
EXTEND_PROTOTYPES: {
// Prevent Ember Data from overriding Date.parse.
Date: false
}
},
APP: {
// Here you can pass flags/options to your application instance
// when it is created
},
// NOTE(logan): Hard-code the URL for the debugger example to allow it to
// function properly. The default "/" root makes assets fail to load.
rootURL: "/browser/devtools/client/debugger/new/test/mochitest/examples/ember/quickstart/dist/",
// If using "http://localhost:8000/integration/examples/ember/quickstart/dist/" to
// access this test example, uncomment this line and re-run "yarn build".
// rootURL: "/integration/examples/ember/quickstart/dist/",
};
if (environment === 'development') {
// ENV.APP.LOG_RESOLVER = true;
// ENV.APP.LOG_ACTIVE_GENERATION = true;
// ENV.APP.LOG_TRANSITIONS = true;
// ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
// ENV.APP.LOG_VIEW_LOOKUPS = true;
}
if (environment === 'test') {
// Testem prefers this...
ENV.locationType = 'none';
// keep test console output quieter
ENV.APP.LOG_ACTIVE_GENERATION = false;
ENV.APP.LOG_VIEW_LOOKUPS = false;
ENV.APP.rootElement = '#ember-testing';
ENV.APP.autoboot = false;
}
if (environment === 'production') {
// here you can enable a production-specific feature
}
return ENV;
};

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

@ -1,18 +0,0 @@
'use strict';
const browsers = [
'last 1 Chrome versions',
'last 1 Firefox versions',
'last 1 Safari versions'
];
const isCI = !!process.env.CI;
const isProduction = process.env.EMBER_ENV === 'production';
if (isCI || isProduction) {
browsers.push('ie 11');
}
module.exports = {
browsers
};

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

До

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

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

@ -1,39 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Quickstart Tests</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="quickstart/config/environment" content="%7B%22modulePrefix%22%3A%22quickstart%22%2C%22environment%22%3A%22test%22%2C%22locationType%22%3A%22none%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%7D%7D%2C%22APP%22%3A%7B%22LOG_ACTIVE_GENERATION%22%3Afalse%2C%22LOG_VIEW_LOOKUPS%22%3Afalse%2C%22rootElement%22%3A%22%23ember-testing%22%2C%22autoboot%22%3Afalse%2C%22name%22%3A%22quickstart%22%2C%22version%22%3A%220.0.0+1dde1d7f%22%7D%2C%22rootURL%22%3A%22/browser/devtools/client/debugger/new/test/mochitest/examples/ember/quickstart/dist/%22%2C%22exportApplicationGlobal%22%3Atrue%7D" />
<link rel="stylesheet" href="/browser/devtools/client/debugger/new/test/mochitest/examples/ember/quickstart/dist/assets/vendor.css">
<link rel="stylesheet" href="/browser/devtools/client/debugger/new/test/mochitest/examples/ember/quickstart/dist/assets/quickstart.css">
<link rel="stylesheet" href="/browser/devtools/client/debugger/new/test/mochitest/examples/ember/quickstart/dist/assets/test-support.css">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<div id="ember-testing-container">
<div id="ember-testing"></div>
</div>
<script src="/testem.js" integrity=""></script>
<script src="/browser/devtools/client/debugger/new/test/mochitest/examples/ember/quickstart/dist/assets/vendor.js"></script>
<script src="/browser/devtools/client/debugger/new/test/mochitest/examples/ember/quickstart/dist/assets/test-support.js"></script>
<script src="/browser/devtools/client/debugger/new/test/mochitest/examples/ember/quickstart/dist/assets/quickstart.js"></script>
<script src="/browser/devtools/client/debugger/new/test/mochitest/examples/ember/quickstart/dist/assets/tests.js"></script>
<script>Ember.assert('The tests file was not loaded. Make sure your tests index.html includes "assets/tests.js".', EmberENV.TESTS_FILE_LOADED);</script>
</body>
</html>

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

@ -1,32 +0,0 @@
'use strict';
const EmberApp = require('ember-cli/lib/broccoli/ember-app');
module.exports = function(defaults) {
// debugger;
let app = new EmberApp(defaults, {
// Add options here
sourcemaps: { enabled: true },
babel: {
sourceMaps: "inline",
},
'ember-babel-cli': {
sourceMaps: "inline",
}
});
// Use `app.import` to add additional libraries to the generated
// output files.
//
// If you need to use different assets in different
// environments, specify an object as the first parameter. That
// object's keys should be the environment name and the values
// should be the asset to use in that environment.
//
// If the library that you are including contains AMD or ES6
// modules that you would like to import into your application
// please specify an object with the list of modules as keys
// along with the exports of each module as its value.
return app.toTree();
};

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

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

@ -1,47 +0,0 @@
{
"name": "quickstart",
"version": "0.0.0",
"private": true,
"description": "Small description for quickstart goes here",
"license": "MIT",
"author": "",
"directories": {
"doc": "doc",
"test": "tests"
},
"repository": "",
"scripts": {
"build": "ember build",
"lint:js": "eslint ./*.js app config lib server tests",
"start": "ember serve",
"test": "ember test"
},
"devDependencies": {
"broccoli-asset-rev": "^2.4.5",
"ember-ajax": "^3.0.0",
"ember-cli": "~3.0.2",
"ember-cli-app-version": "^3.0.0",
"ember-cli-babel": "^6.6.0",
"ember-cli-dependency-checker": "^2.0.0",
"ember-cli-eslint": "^4.2.1",
"ember-cli-htmlbars": "^2.0.1",
"ember-cli-htmlbars-inline-precompile": "^1.0.0",
"ember-cli-inject-live-reload": "^1.4.1",
"ember-cli-qunit": "^4.1.1",
"ember-cli-shims": "^1.2.0",
"ember-cli-sri": "^2.1.0",
"ember-cli-uglify": "^2.0.0",
"ember-data": "~3.0.0",
"ember-export-application-global": "^2.0.0",
"ember-load-initializers": "^1.0.0",
"ember-maybe-import-regenerator": "^0.1.6",
"ember-resolver": "^4.0.0",
"ember-source": "~3.0.0",
"ember-welcome-page": "^3.0.0",
"eslint-plugin-ember": "^5.0.0",
"loader.js": "^4.2.3"
},
"engines": {
"node": "^4.5 || 6.* || >= 7.*"
}
}

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

@ -1,3 +0,0 @@
# http://www.robotstxt.org
User-agent: *
Disallow:

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

@ -1,24 +0,0 @@
module.exports = {
test_page: 'tests/index.html?hidepassed',
disable_watching: true,
launch_in_ci: [
'Chrome'
],
launch_in_dev: [
'Chrome'
],
browser_args: {
Chrome: {
mode: 'ci',
args: [
// --no-sandbox is needed when running Chrome inside a container
process.env.TRAVIS ? '--no-sandbox' : null,
'--disable-gpu',
'--headless',
'--remote-debugging-port=0',
'--window-size=1440,900'
].filter(Boolean)
}
}
};

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

@ -1,33 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Quickstart Tests</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
{{content-for "head"}}
{{content-for "test-head"}}
<link rel="stylesheet" href="{{rootURL}}assets/vendor.css">
<link rel="stylesheet" href="{{rootURL}}assets/quickstart.css">
<link rel="stylesheet" href="{{rootURL}}assets/test-support.css">
{{content-for "head-footer"}}
{{content-for "test-head-footer"}}
</head>
<body>
{{content-for "body"}}
{{content-for "test-body"}}
<script src="/testem.js" integrity=""></script>
<script src="{{rootURL}}assets/vendor.js"></script>
<script src="{{rootURL}}assets/test-support.js"></script>
<script src="{{rootURL}}assets/quickstart.js"></script>
<script src="{{rootURL}}assets/tests.js"></script>
{{content-for "body-footer"}}
{{content-for "test-body-footer"}}
</body>
</html>

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

@ -1,8 +0,0 @@
import Application from '../app';
import config from '../config/environment';
import { setApplication } from '@ember/test-helpers';
import { start } from 'ember-qunit';
setApplication(Application.create(config.APP));
start();

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

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

@ -277,7 +277,6 @@ devtools.jar:
skin/images/debugger/folder.svg (themes/images/debugger/folder.svg)
skin/images/debugger/forward.svg (themes/images/debugger/forward.svg)
skin/images/debugger/javascript.svg (themes/images/debugger/javascript.svg)
skin/images/debugger/pause-exceptions.svg (themes/images/debugger/pause-exceptions.svg)
skin/images/debugger/pause.svg (themes/images/debugger/pause.svg)
skin/images/debugger/prettyPrint.svg (themes/images/debugger/prettyPrint.svg)
skin/images/debugger/react.svg (themes/images/debugger/react.svg)

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

@ -93,9 +93,13 @@ ignoreExceptionsItem=Ignore exceptions
# item shown when a user is adding a new breakpoint.
pauseOnUncaughtExceptionsItem=Pause on uncaught exceptions
# LOCALIZATION NOTE (pauseOnExceptionsItem): The pause on exceptions button description
# LOCALIZATION NOTE (pauseOnExceptionsItem2): The pause on exceptions checkbox description
# when the debugger will pause on all exceptions.
pauseOnExceptionsItem=Pause on all exceptions
pauseOnExceptionsItem2=Pause on exceptions
# LOCALIZATION NOTE (ignoreCaughtExceptionsItem): The pause on exceptions checkbox description
# when the debugger will not pause on any caught exception
ignoreCaughtExceptionsItem=Ignore caught exceptions
# LOCALIZATION NOTE (workersHeader): The text to display in the events
# header.

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

@ -52,7 +52,6 @@ pref("devtools.debugger.features.root", true);
pref("devtools.debugger.features.column-breakpoints", false);
pref("devtools.debugger.features.chrome-scopes", false);
pref("devtools.debugger.features.map-scopes", true);
pref("devtools.debugger.features.breakpoints-dropdown", false);
pref("devtools.debugger.features.remove-command-bar-options", false);
pref("devtools.debugger.features.workers", true);
pref("devtools.debugger.features.code-coverage", false);

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

@ -1,7 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path d="M10.483 13.995H5.517l-3.512-3.512V5.516l3.512-3.512h4.966l3.512 3.512v4.967l-3.512 3.512zm4.37-9.042l-3.807-3.805A.503.503 0 0 0 10.691 1H5.309a.503.503 0 0 0-.356.148L1.147 4.953A.502.502 0 0 0 1 5.308v5.383c0 .134.053.262.147.356l3.806 3.806a.503.503 0 0 0 .356.147h5.382a.503.503 0 0 0 .355-.147l3.806-3.806A.502.502 0 0 0 15 10.69V5.308a.502.502 0 0 0-.147-.355z"/>
<path d="M10 10.5a.5.5 0 1 0 1 0v-5a.5.5 0 1 0-1 0v5zM5 10.5a.5.5 0 1 0 1 0v-5a.5.5 0 0 0-1 0v5z"/>
</svg>

До

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

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

@ -395,8 +395,6 @@ nsFrameLoader::FireWillChangeProcessEvent()
return nullptr;
}
JSContext* cx = jsapi.cx();
GlobalObject global(cx, mOwnerContent->GetOwnerGlobal()->GetGlobalJSObject());
MOZ_ASSERT(!global.Failed());
// Set our mBrowserChangingProcessBlockers property to refer to the blockers
// list. We will synchronously dispatch a DOM event to collect this list of
@ -418,7 +416,7 @@ nsFrameLoader::FireWillChangeProcessEvent()
mBrowserChangingProcessBlockers = nullptr;
ErrorResult rv;
RefPtr<Promise> allPromise = Promise::All(global, blockers, rv);
RefPtr<Promise> allPromise = Promise::All(cx, blockers, rv);
return allPromise.forget();
}

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

@ -1226,7 +1226,10 @@ nsGlobalWindowInner::FreeInnerObjects()
mApplicationCache = nullptr;
}
mIndexedDB = nullptr;
if (mIndexedDB) {
mIndexedDB->DisconnectFromWindow(this);
mIndexedDB = nullptr;
}
UnlinkHostObjectURIs();
@ -1520,7 +1523,10 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowInner)
static_cast<nsDOMOfflineResourceList*>(tmp->mApplicationCache.get())->Disconnect();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mApplicationCache)
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexedDB)
if (tmp->mIndexedDB) {
tmp->mIndexedDB->DisconnectFromWindow(tmp);
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexedDB)
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPrincipal)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTabChild)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDoc)
@ -2469,6 +2475,32 @@ nsGlobalWindowInner::NoteCalledRegisterForServiceWorkerScope(const nsACString& a
mClientSource->NoteCalledRegisterForServiceWorkerScope(aScope);
}
void
nsGlobalWindowInner::MigrateStateForDocumentOpen(nsGlobalWindowInner* aOldInner)
{
MOZ_DIAGNOSTIC_ASSERT(aOldInner);
MOZ_DIAGNOSTIC_ASSERT(aOldInner != this);
MOZ_DIAGNOSTIC_ASSERT(mDoc);
// Rebind DETH objects to the new global created by document.open().
// XXX: Is this correct? We should consider if the spec and our
// implementation should change to match other browsers by
// just reusing the current window. (Bug 1449992)
aOldInner->ForEachEventTargetObject(
[&] (DOMEventTargetHelper* aDETH, bool* aDoneOut) {
aDETH->BindToOwner(this->AsInner());
});
// Move the old Performance object from the old window to the new window.
// The Performance object was also rebound in the DETH loop above.
mPerformance = aOldInner->mPerformance.forget();
if (aOldInner->mIndexedDB) {
aOldInner->mIndexedDB->RebindToNewWindow(this);
mIndexedDB = aOldInner->mIndexedDB.forget();
}
}
void
nsGlobalWindowInner::UpdateTopInnerWindow()
{

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

@ -1151,6 +1151,8 @@ private:
CallState ShouldReportForServiceWorkerScopeInternal(const nsACString& aScope,
bool* aResultOut);
void
MigrateStateForDocumentOpen(nsGlobalWindowInner* aOldInner);
public:
// Timeout Functions

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

@ -1721,7 +1721,7 @@ nsGlobalWindowOuter::SetNewDocument(nsIDocument* aDocument,
mContext->WillInitializeContext();
nsGlobalWindowInner *currentInner = GetCurrentInnerWindowInternal();
RefPtr<nsGlobalWindowInner> currentInner = GetCurrentInnerWindowInternal();
if (currentInner && currentInner->mNavigator) {
currentInner->mNavigator->OnNavigation();
@ -1735,6 +1735,9 @@ nsGlobalWindowOuter::SetNewDocument(nsIDocument* aDocument,
nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState);
NS_ASSERTION(!aState || wsh, "What kind of weird state are you giving me here?");
bool handleDocumentOpen = false;
bool doomCurrentInner = false;
JS::Rooted<JSObject*> newInnerGlobal(cx);
if (reUseInnerWindow) {
// We're reusing the current inner window.
@ -1818,32 +1821,13 @@ nsGlobalWindowOuter::SetNewDocument(nsIDocument* aDocument,
if (currentInner && currentInner->GetWrapperPreserveColor()) {
if (oldDoc == aDocument) {
// Make a copy of the old window's performance object on document.open.
// Note that we have to force eager creation of it here, because we need
// to grab the current document channel and whatnot before that changes.
currentInner->AsInner()->CreatePerformanceObjectIfNeeded();
if (currentInner->mPerformance) {
newInnerWindow->mPerformance =
Performance::CreateForMainThread(newInnerWindow->AsInner(),
aDocument->NodePrincipal(),
currentInner->mPerformance->GetDOMTiming(),
currentInner->mPerformance->GetChannel());
}
// Rebind DETH objects to the new global created by document.open().
// XXX: Is this correct? We should consider if the spec and our
// implementation should change to match other browsers by
// just reusing the current window. (Bug 1449992)
currentInner->ForEachEventTargetObject(
[&] (DOMEventTargetHelper* aDETH, bool* aDoneOut) {
aDETH->BindToOwner(newInnerWindow->AsGlobal());
});
handleDocumentOpen = true;
}
// Don't free objects on our current inner window if it's going to be
// held in the bfcache.
if (!currentInner->IsFrozen()) {
currentInner->FreeInnerObjects();
doomCurrentInner = true;
}
}
@ -1994,6 +1978,19 @@ nsGlobalWindowOuter::SetNewDocument(nsIDocument* aDocument,
newInnerWindow->mChromeEventHandler = mChromeEventHandler;
}
// Handle any document.open() logic after we setup the new inner window
// so that any bound DETH objects can see the top window, document, etc.
if (handleDocumentOpen) {
newInnerWindow->MigrateStateForDocumentOpen(currentInner);
}
// We no longer need the old inner window. Start its destruction if
// its not being reused and clear our reference.
if (doomCurrentInner) {
currentInner->FreeInnerObjects();
}
currentInner = nullptr;
// Ask the JS engine to assert that it's valid to access our DocGroup whenever
// it runs JS code for this compartment. We skip the check if this window is
// for chrome JS or an add-on.

2
dom/cache/Cache.cpp поставляемый
Просмотреть файл

@ -630,7 +630,7 @@ Cache::AddAll(const GlobalObject& aGlobal,
new FetchHandler(mActor->GetWorkerHolder(), this,
Move(aRequestList), promise);
RefPtr<Promise> fetchPromise = Promise::All(aGlobal, fetchList, aRv);
RefPtr<Promise> fetchPromise = Promise::All(aGlobal.Context(), fetchList, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}

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

@ -99,34 +99,25 @@ DOMEventTargetHelper::~DOMEventTargetHelper()
void
DOMEventTargetHelper::BindToOwner(nsPIDOMWindowInner* aOwner)
{
BindToOwner(aOwner ? aOwner->AsGlobal() : nullptr);
// Make sure to bind via BindToOwner(nsIGlobalObject*) so
// subclasses can override the method to perform additional
// actions.
nsIGlobalObject* global = aOwner ? aOwner->AsGlobal() : nullptr;
BindToOwner(global);
}
void
DOMEventTargetHelper::BindToOwner(nsIGlobalObject* aOwner)
{
if (mParentObject) {
mParentObject->RemoveEventTargetObject(this);
if (mOwnerWindow) {
mOwnerWindow = nullptr;
}
mParentObject = nullptr;
mHasOrHasHadOwnerWindow = false;
}
if (aOwner) {
mParentObject = aOwner;
aOwner->AddEventTargetObject(this);
// Let's cache the result of this QI for fast access and off main thread usage
mOwnerWindow = nsCOMPtr<nsPIDOMWindowInner>(do_QueryInterface(aOwner)).get();
if (mOwnerWindow) {
mHasOrHasHadOwnerWindow = true;
}
}
BindToOwnerInternal(aOwner);
}
void
DOMEventTargetHelper::BindToOwner(DOMEventTargetHelper* aOther)
{
// Make sure to bind via BindToOwner(nsIGlobalObject*) so
// subclasses can override the method to perform additional
// actions.
if (!aOther) {
BindToOwner(static_cast<nsIGlobalObject*>(nullptr));
return;
@ -355,4 +346,26 @@ DOMEventTargetHelper::MaybeDontKeepAlive()
}
}
void
DOMEventTargetHelper::BindToOwnerInternal(nsIGlobalObject* aOwner)
{
if (mParentObject) {
mParentObject->RemoveEventTargetObject(this);
if (mOwnerWindow) {
mOwnerWindow = nullptr;
}
mParentObject = nullptr;
mHasOrHasHadOwnerWindow = false;
}
if (aOwner) {
mParentObject = aOwner;
aOwner->AddEventTargetObject(this);
// Let's cache the result of this QI for fast access and off main thread usage
mOwnerWindow = nsCOMPtr<nsPIDOMWindowInner>(do_QueryInterface(aOwner)).get();
if (mOwnerWindow) {
mHasOrHasHadOwnerWindow = true;
}
}
}
} // namespace mozilla

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

@ -46,7 +46,10 @@ public:
, mHasOrHasHadOwnerWindow(false)
, mIsKeptAlive(false)
{
BindToOwner(aWindow);
// Be careful not to call the virtual BindToOwner() in a
// constructor.
nsIGlobalObject* global = aWindow ? aWindow->AsGlobal() : nullptr;
BindToOwnerInternal(global);
}
explicit DOMEventTargetHelper(nsIGlobalObject* aGlobalObject)
: mParentObject(nullptr)
@ -54,7 +57,9 @@ public:
, mHasOrHasHadOwnerWindow(false)
, mIsKeptAlive(false)
{
BindToOwner(aGlobalObject);
// Be careful not to call the virtual BindToOwner() in a
// constructor.
BindToOwnerInternal(aGlobalObject);
}
explicit DOMEventTargetHelper(DOMEventTargetHelper* aOther)
: mParentObject(nullptr)
@ -62,7 +67,14 @@ public:
, mHasOrHasHadOwnerWindow(false)
, mIsKeptAlive(false)
{
BindToOwner(aOther);
// Be careful not to call the virtual BindToOwner() in a
// constructor.
if (!aOther) {
BindToOwnerInternal(static_cast<nsIGlobalObject*>(nullptr));
return;
}
BindToOwnerInternal(aOther->GetParentObject());
mHasOrHasHadOwnerWindow = aOther->HasOrHasHadOwner();
}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@ -142,9 +154,20 @@ public:
// Returns the document associated with this event target, if that document is
// the current document of its browsing context. Will return null otherwise.
nsIDocument* GetDocumentIfCurrent() const;
void BindToOwner(nsIGlobalObject* aOwner);
// DETH subclasses may override the BindToOwner(nsIGlobalObject*) method
// to take action when dynamically binding to a new global. This is only
// called on rebind since virtual methods cannot be called from the
// constructor. The other BindToOwner() methods will call into this
// method.
//
// NOTE: Any overrides of BindToOwner() *must* invoke
// DOMEventTargetHelper::BindToOwner(aOwner).
virtual void BindToOwner(nsIGlobalObject* aOwner);
void BindToOwner(nsPIDOMWindowInner* aOwner);
void BindToOwner(DOMEventTargetHelper* aOther);
virtual void DisconnectFromOwner();
using EventTarget::GetParentObject;
virtual nsIGlobalObject* GetOwnerGlobal() const override
@ -189,6 +212,8 @@ protected:
void IgnoreKeepAliveIfHasListenersFor(const nsAString& aType);
void IgnoreKeepAliveIfHasListenersFor(nsAtom* aType);
void BindToOwnerInternal(nsIGlobalObject* aOwner);
private:
// The parent global object. The global will clear this when
// it is destroyed by calling DisconnectFromOwner().

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

@ -72,7 +72,8 @@ async function _eventListenerLeakStep(target, name, extra) {
frame.remove();
frame = null;
// Perform two GC'd to avoid intermittent delayed collection.
// Perform many GC's to avoid intermittent delayed collection.
await new Promise(resolve => SpecialPowers.exactGC(resolve));
await new Promise(resolve => SpecialPowers.exactGC(resolve));
await new Promise(resolve => SpecialPowers.exactGC(resolve));

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

@ -74,6 +74,8 @@ IDBFactory::IDBFactory()
: mOwningObject(nullptr)
, mBackgroundActor(nullptr)
, mInnerWindowID(0)
, mActiveTransactionCount(0)
, mActiveDatabaseCount(0)
, mBackgroundActorFailed(false)
, mPrivateBrowsingMode(false)
{
@ -396,6 +398,9 @@ void
IDBFactory::UpdateActiveTransactionCount(int32_t aDelta)
{
AssertIsOnOwningThread();
MOZ_DIAGNOSTIC_ASSERT(aDelta > 0 ||
(mActiveTransactionCount + aDelta) < mActiveTransactionCount);
mActiveTransactionCount += aDelta;
if (mWindow) {
mWindow->UpdateActiveIndexedDBTransactionCount(aDelta);
}
@ -405,6 +410,9 @@ void
IDBFactory::UpdateActiveDatabaseCount(int32_t aDelta)
{
AssertIsOnOwningThread();
MOZ_DIAGNOSTIC_ASSERT(aDelta > 0 ||
(mActiveDatabaseCount + aDelta) < mActiveDatabaseCount);
mActiveDatabaseCount += aDelta;
if (mWindow) {
mWindow->UpdateActiveIndexedDBDatabaseCount(aDelta);
}
@ -870,6 +878,33 @@ IDBFactory::InitiateRequest(IDBOpenDBRequest* aRequest,
return NS_OK;
}
void
IDBFactory::RebindToNewWindow(nsPIDOMWindowInner* aNewWindow)
{
MOZ_DIAGNOSTIC_ASSERT(aNewWindow);
MOZ_DIAGNOSTIC_ASSERT(mWindow);
MOZ_DIAGNOSTIC_ASSERT(aNewWindow != mWindow);
mWindow->UpdateActiveIndexedDBTransactionCount(-1 * mActiveTransactionCount);
mWindow->UpdateActiveIndexedDBDatabaseCount(-1 * mActiveDatabaseCount);
mWindow = aNewWindow;
mInnerWindowID = aNewWindow->WindowID();
mWindow->UpdateActiveIndexedDBTransactionCount(mActiveTransactionCount);
mWindow->UpdateActiveIndexedDBDatabaseCount(mActiveDatabaseCount);
}
void
IDBFactory::DisconnectFromWindow(nsPIDOMWindowInner* aOldWindow)
{
MOZ_DIAGNOSTIC_ASSERT(aOldWindow);
// If CC unlinks us first, then mWindow might be nullptr
MOZ_DIAGNOSTIC_ASSERT(!mWindow || mWindow == aOldWindow);
mWindow = nullptr;
}
NS_IMPL_CYCLE_COLLECTING_ADDREF(IDBFactory)
NS_IMPL_CYCLE_COLLECTING_RELEASE(IDBFactory)

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

@ -76,6 +76,8 @@ class IDBFactory final
nsCOMPtr<nsIEventTarget> mEventTarget;
uint64_t mInnerWindowID;
uint32_t mActiveTransactionCount;
uint32_t mActiveDatabaseCount;
bool mBackgroundActorFailed;
bool mPrivateBrowsingMode;
@ -225,6 +227,12 @@ public:
SystemCallerGuarantee,
ErrorResult& aRv);
void
RebindToNewWindow(nsPIDOMWindowInner* aNewWindow);
void
DisconnectFromWindow(nsPIDOMWindowInner* aOldWindow);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBFactory)

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

@ -7,6 +7,7 @@ support-files =
bfcache_page1.html
bfcache_page2.html
blob_worker_crash_iframe.html
!/dom/events/test/event_leak_utils.js
error_events_abort_transactions_iframe.html
event_propagation_iframe.html
exceptions_in_events_iframe.html
@ -154,6 +155,7 @@ skip-if = e10s && os == 'win' && os_version == '6.1' # Bug 1342415
[test_deleteDatabase_onblocked.html]
[test_deleteDatabase_onblocked_duringVersionChange.html]
[test_error_events_abort_transactions.html]
[test_event_listener_leaks.html]
[test_event_propagation.html]
[test_event_source.html]
[test_exceptions_in_events.html]

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

@ -0,0 +1,64 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1450358 - Test IDB event listener leak conditions</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/dom/events/test/event_leak_utils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script class="testbody" type="text/javascript">
/* global checkForEventListenerLeaks */
// Manipulate IDB objects in the frame's context.
// Its important here that we create a listener callback from
// the DOM objects back to the frame's global in order to
// exercise the leak condition.
let count = 0;
async function useIDB(contentWindow) {
count += 1;
let db = await new Promise(resolve => {
let r = contentWindow.indexedDB.open("idb-leak-test-" + count, 1.0);
r.onupgradeneeded = evt => {
evt.target.result.createObjectStore("looped");
};
r.onsuccess = evt => {
resolve(evt.target.result);
};
});
let tx = db.transaction("looped", "readwrite");
let store = tx.objectStore("looped");
function spin() {
contentWindow.spinCount += 1;
store.get(0).onsuccess = spin;
}
store.put(0, "purgatory").onsuccess = e => {
contentWindow.putCount += 1;
spin();
};
}
async function runTest() {
try {
await checkForEventListenerLeaks("IDB", useIDB);
} catch (e) {
ok(false, e);
} finally {
SimpleTest.finish();
}
}
SimpleTest.waitForExplicitFinish();
addEventListener("load", runTest, { once: true });
</script>
</pre>
</body>
</html>

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

@ -688,6 +688,23 @@ void AudioContext::DisconnectFromOwner()
DOMEventTargetHelper::DisconnectFromOwner();
}
void
AudioContext::BindToOwner(nsIGlobalObject* aNew)
{
auto scopeExit = MakeScopeExit([&] {
DOMEventTargetHelper::BindToOwner(aNew);
});
if (GetOwner()) {
GetOwner()->RemoveAudioContext(this);
}
nsCOMPtr<nsPIDOMWindowInner> newWindow = do_QueryInterface(aNew);
if (newWindow) {
newWindow->AddAudioContext(this);
}
}
void
AudioContext::Shutdown()
{

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

@ -145,6 +145,7 @@ public:
}
virtual void DisconnectFromOwner() override;
virtual void BindToOwner(nsIGlobalObject* aNew) override;
void Shutdown(); // idempotent

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

@ -57,7 +57,6 @@ AudioNode::AudioNode(AudioContext* aContext,
, mAbstractMainThread(aContext->GetOwnerGlobal()->AbstractMainThreadFor(TaskCategory::Other))
{
MOZ_ASSERT(aContext);
DOMEventTargetHelper::BindToOwner(aContext->GetParentObject());
aContext->RegisterNode(this);
}

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

@ -11,6 +11,7 @@ support-files =
audiovideo.mp4
audioBufferSourceNodeDetached_worker.js
corsServer.sjs
!/dom/events/test/event_leak_utils.js
file_nodeCreationDocumentGone.html
invalid.txt
layouttest-glue.js
@ -152,6 +153,7 @@ skip-if = toolkit == 'android' # bug 1056706
[test_dynamicsCompressorNode.html]
[test_dynamicsCompressorNodePassThrough.html]
[test_dynamicsCompressorNodeWithGain.html]
[test_event_listener_leaks.html]
[test_gainNode.html]
[test_gainNodeInLoop.html]
[test_gainNodePassThrough.html]

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

@ -0,0 +1,47 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1450358 - Test AudioContext event listener leak conditions</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/dom/events/test/event_leak_utils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script class="testbody" type="text/javascript">
// Manipulate AudioContext objects in the frame's context.
// Its important here that we create a listener callback from
// the DOM objects back to the frame's global in order to
// exercise the leak condition.
async function useAudioContext(contentWindow) {
let ctx = new contentWindow.AudioContext();
ctx.onstatechange = e => {
contentWindow.stateChangeCount += 1;
};
let osc = ctx.createOscillator();
osc.type = "sine";
osc.frequency.value = 440;
osc.start();
}
async function runTest() {
try {
await checkForEventListenerLeaks("AudioContext", useAudioContext);
} catch (e) {
ok(false, e);
} finally {
SimpleTest.finish();
}
}
SimpleTest.waitForExplicitFinish();
addEventListener("load", runTest, { once: true });
</script>
</pre>
</body>
</html>

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

@ -135,37 +135,40 @@ Promise::Reject(nsIGlobalObject* aGlobal, JSContext* aCx,
// static
already_AddRefed<Promise>
Promise::All(const GlobalObject& aGlobal,
Promise::All(JSContext* aCx,
const nsTArray<RefPtr<Promise>>& aPromiseList, ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global;
global = do_QueryInterface(aGlobal.GetAsSupports());
JS::Rooted<JSObject*> globalObj(aCx, JS::CurrentGlobalOrNull(aCx));
if (!globalObj) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsCOMPtr<nsIGlobalObject> global = xpc::NativeGlobal(globalObj);
if (!global) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
JSContext* cx = aGlobal.Context();
JS::AutoObjectVector promises(cx);
JS::AutoObjectVector promises(aCx);
if (!promises.reserve(aPromiseList.Length())) {
aRv.NoteJSContextException(cx);
aRv.NoteJSContextException(aCx);
return nullptr;
}
for (auto& promise : aPromiseList) {
JS::Rooted<JSObject*> promiseObj(cx, promise->PromiseObj());
JS::Rooted<JSObject*> promiseObj(aCx, promise->PromiseObj());
// Just in case, make sure these are all in the context compartment.
if (!JS_WrapObject(cx, &promiseObj)) {
aRv.NoteJSContextException(cx);
if (!JS_WrapObject(aCx, &promiseObj)) {
aRv.NoteJSContextException(aCx);
return nullptr;
}
promises.infallibleAppend(promiseObj);
}
JS::Rooted<JSObject*> result(cx, JS::GetWaitForAllPromise(cx, promises));
JS::Rooted<JSObject*> result(aCx, JS::GetWaitForAllPromise(aCx, promises));
if (!result) {
aRv.NoteJSContextException(cx);
aRv.NoteJSContextException(aCx);
return nullptr;
}

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

@ -111,23 +111,26 @@ public:
return mGlobal;
}
// Do the equivalent of Promise.resolve in the current compartment of aCx.
// Errorrs are reported on the ErrorResult; if aRv comes back !Failed(), this
// function MUST return a non-null value.
// Do the equivalent of Promise.resolve in the compartment of aGlobal. The
// compartment of aCx is ignored. Errors are reported on the ErrorResult; if
// aRv comes back !Failed(), this function MUST return a non-null value.
static already_AddRefed<Promise>
Resolve(nsIGlobalObject* aGlobal, JSContext* aCx,
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
// Do the equivalent of Promise.reject in the current compartment of aCx.
// Errorrs are reported on the ErrorResult; if aRv comes back !Failed(), this
// function MUST return a non-null value.
// Do the equivalent of Promise.reject in the compartment of aGlobal. The
// compartment of aCx is ignored. Errors are reported on the ErrorResult; if
// aRv comes back !Failed(), this function MUST return a non-null value.
static already_AddRefed<Promise>
Reject(nsIGlobalObject* aGlobal, JSContext* aCx,
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
// Do the equivalent of Promise.all in the current compartment of aCx. Errors
// are reported on the ErrorResult; if aRv comes back !Failed(), this function
// MUST return a non-null value.
static already_AddRefed<Promise>
All(const GlobalObject& aGlobal,
const nsTArray<RefPtr<Promise>>& aPromiseList, ErrorResult& aRv);
All(JSContext* aCx, const nsTArray<RefPtr<Promise>>& aPromiseList,
ErrorResult& aRv);
void
Then(JSContext* aCx,

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

@ -0,0 +1,64 @@
// Custom *.sjs file specifically for the needs of Bug 1454242
const WIN = `
<html>
<body>
<script type="application/javascript">
let newWin = window.open("http://mochi.test:8888/tests/dom/security/test/general/file_same_site_cookies_toplevel_set_cookie.sjs?loadWinAndSetCookie");
newWin.onload = function() {
newWin.close();
}
</script>
</body>
</html>`;
const DUMMY_WIN = `
<html>
<body>
just a dummy window that sets a same-site=lax cookie
<script type="application/javascript">
window.opener.opener.postMessage({value: 'testSetupComplete'}, '*');
</script>
</body>
</html>`;
const FRAME = `
<html>
<body>
<script type="application/javascript">
let cookie = document.cookie;
// now reset the cookie for the next test
document.cookie = "myKey=;" + "expires=Thu, 01 Jan 1970 00:00:00 GMT";
window.parent.postMessage({value: cookie}, 'http://mochi.test:8888');
</script>
</body>
</html>`;
const SAME_ORIGIN = "http://mochi.test:8888/"
const CROSS_ORIGIN = "http://example.com/";
const PATH = "tests/dom/security/test/general/file_same_site_cookies_redirect.sjs";
function handleRequest(request, response)
{
// avoid confusing cache behaviors
response.setHeader("Cache-Control", "no-cache", false);
if (request.queryString === "loadWin") {
response.write(WIN);
return;
}
if (request.queryString === "loadWinAndSetCookie") {
response.setHeader("Set-Cookie", "myKey=laxSameSiteCookie; samesite=lax", true);
response.write(DUMMY_WIN);
return;
}
if (request.queryString === "checkCookie") {
response.write(FRAME);
return;
}
// we should never get here, but just in case return something unexpected
response.write("D'oh");
}

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

@ -13,6 +13,7 @@ support-files =
file_same_site_cookies_cross_origin_context.sjs
file_same_site_cookies_from_script.sjs
file_same_site_cookies_redirect.sjs
file_same_site_cookies_toplevel_set_cookie.sjs
[test_contentpolicytype_targeted_link_iframe.html]
[test_nosniff.html]
@ -31,3 +32,4 @@ skip-if = toolkit == 'android'
[test_same_site_cookies_cross_origin_context.html]
[test_same_site_cookies_from_script.html]
[test_same_site_cookies_redirect.html]
[test_same_site_cookies_toplevel_set_cookie.html]

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

@ -0,0 +1,57 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1454242: Setting samesite cookie should not rely on NS_IsSameSiteForeign</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<img id="cookieImage">
<iframe id="testframe"></iframe>
<script class="testbody" type="text/javascript">
/*
* Description of the test:
* 1) We load a window from example.com which loads a window from mochi.test
* which then sets a same-site cookie for mochi.test.
* 2) We load an iframe from mochi.test.
* 3) We observe that the cookie within (1) was allowed to be set and
* is available for mochi.test.
*/
SimpleTest.waitForExplicitFinish();
const SAME_ORIGIN = "http://mochi.test:8888/"
const CROSS_ORIGIN = "http://example.com/";
const PATH = "tests/dom/security/test/general/file_same_site_cookies_toplevel_set_cookie.sjs";
let testWin = null;
window.addEventListener("message", receiveMessage);
function receiveMessage(event) {
// once the second window (which sets the cookie) loaded, we get a notification
// that the test setup is correct and we can now try to query the same-site cookie
if (event.data.value === "testSetupComplete") {
ok(true, "cookie setup worked");
let testframe = document.getElementById("testframe");
testframe.src = SAME_ORIGIN + PATH + "?checkCookie";
return;
}
// thie second message is the cookie value from verifying the
// cookie has been set correctly.
is(event.data.value, "myKey=laxSameSiteCookie",
"setting same-site cookie on cross origin top-level page");
window.removeEventListener("message", receiveMessage);
testWin.close();
SimpleTest.finish();
}
// fire up the test
testWin = window.open(CROSS_ORIGIN + PATH + "?loadWin");
</script>
</body>
</html>

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

@ -10,7 +10,6 @@
#include "mozilla/EventDispatcher.h"
#include "mozilla/dom/SVGAnimationElement.h"
#include "mozilla/TaskCategory.h"
#include "nsAutoPtr.h"
#include "nsSMILTimedElement.h"
#include "nsAttrValueInlines.h"
#include "nsSMILAnimationFunction.h"
@ -630,7 +629,7 @@ nsSMILTimedElement::DoSampleAt(nsSMILTime aContainerTime, bool aEndOnly)
: STATE_POSTACTIVE;
stateChanged = true;
if (mElementState == STATE_WAITING) {
mCurrentInterval = new nsSMILInterval(firstInterval);
mCurrentInterval = MakeUnique<nsSMILInterval>(firstInterval);
NotifyNewInterval();
}
}
@ -673,7 +672,7 @@ nsSMILTimedElement::DoSampleAt(nsSMILTime aContainerTime, bool aEndOnly)
if (mCurrentInterval->End()->Time() <= sampleTime) {
nsSMILInterval newInterval;
mElementState =
GetNextInterval(mCurrentInterval, nullptr, nullptr, newInterval)
GetNextInterval(mCurrentInterval.get(), nullptr, nullptr, newInterval)
? STATE_WAITING
: STATE_POSTACTIVE;
if (mClient) {
@ -684,15 +683,15 @@ nsSMILTimedElement::DoSampleAt(nsSMILTime aContainerTime, bool aEndOnly)
FireTimeEventAsync(eSMILEndEvent, 0);
}
mCurrentRepeatIteration = 0;
mOldIntervals.AppendElement(mCurrentInterval.forget());
mOldIntervals.AppendElement(Move(mCurrentInterval));
SampleFillValue();
if (mElementState == STATE_WAITING) {
mCurrentInterval = new nsSMILInterval(newInterval);
mCurrentInterval = MakeUnique<nsSMILInterval>(newInterval);
}
// We are now in a consistent state to dispatch notifications
if (didApplyEarlyEnd) {
NotifyChangedInterval(
mOldIntervals[mOldIntervals.Length() - 1], false, true);
mOldIntervals[mOldIntervals.Length() - 1].get(), false, true);
}
if (mElementState == STATE_WAITING) {
NotifyNewInterval();
@ -768,7 +767,7 @@ nsSMILTimedElement::HandleContainerTimeChange()
// the nsSMILTimeValueSpec we'll check if anything has changed and if not, we
// won't go any further.
if (mElementState == STATE_WAITING || mElementState == STATE_ACTIVE) {
NotifyChangedInterval(mCurrentInterval, false, false);
NotifyChangedInterval(mCurrentInterval.get(), false, false);
}
}
@ -1259,7 +1258,7 @@ nsSMILTimedElement::Traverse(nsCycleCollectionTraversalCallback* aCallback)
{
uint32_t count = mBeginSpecs.Length();
for (uint32_t i = 0; i < count; ++i) {
nsSMILTimeValueSpec* beginSpec = mBeginSpecs[i];
nsSMILTimeValueSpec* beginSpec = mBeginSpecs[i].get();
MOZ_ASSERT(beginSpec,
"null nsSMILTimeValueSpec in list of begin specs");
beginSpec->Traverse(aCallback);
@ -1267,7 +1266,7 @@ nsSMILTimedElement::Traverse(nsCycleCollectionTraversalCallback* aCallback)
count = mEndSpecs.Length();
for (uint32_t j = 0; j < count; ++j) {
nsSMILTimeValueSpec* endSpec = mEndSpecs[j];
nsSMILTimeValueSpec* endSpec = mEndSpecs[j].get();
MOZ_ASSERT(endSpec, "null nsSMILTimeValueSpec in list of end specs");
endSpec->Traverse(aCallback);
}
@ -1281,7 +1280,7 @@ nsSMILTimedElement::Unlink()
// Remove dependencies on other elements
uint32_t count = mBeginSpecs.Length();
for (uint32_t i = 0; i < count; ++i) {
nsSMILTimeValueSpec* beginSpec = mBeginSpecs[i];
nsSMILTimeValueSpec* beginSpec = mBeginSpecs[i].get();
MOZ_ASSERT(beginSpec,
"null nsSMILTimeValueSpec in list of begin specs");
beginSpec->Unlink();
@ -1289,7 +1288,7 @@ nsSMILTimedElement::Unlink()
count = mEndSpecs.Length();
for (uint32_t j = 0; j < count; ++j) {
nsSMILTimeValueSpec* endSpec = mEndSpecs[j];
nsSMILTimeValueSpec* endSpec = mEndSpecs[j].get();
MOZ_ASSERT(endSpec, "null nsSMILTimeValueSpec in list of end specs");
endSpec->Unlink();
}
@ -1323,11 +1322,10 @@ nsSMILTimedElement::SetBeginOrEndSpec(const nsAString& aSpec,
bool hadFailure = false;
while (tokenizer.hasMoreTokens()) {
nsAutoPtr<nsSMILTimeValueSpec>
spec(new nsSMILTimeValueSpec(*this, aIsBegin));
auto spec = MakeUnique<nsSMILTimeValueSpec>(*this, aIsBegin);
nsresult rv = spec->SetSpec(tokenizer.nextToken(), aContextNode);
if (NS_SUCCEEDED(rv)) {
timeSpecsList.AppendElement(spec.forget());
timeSpecsList.AppendElement(Move(spec));
} else {
hadFailure = true;
}
@ -1613,7 +1611,7 @@ nsSMILTimedElement::FilterIntervals()
(i < threshold || !interval->IsDependencyChainLink())) {
interval->Unlink(true /*filtered, not deleted*/);
} else {
filteredList.AppendElement(mOldIntervals[i].forget());
filteredList.AppendElement(Move(mOldIntervals[i]));
}
}
mOldIntervals.Clear();
@ -2089,14 +2087,14 @@ nsSMILTimedElement::UpdateCurrentInterval(bool aForceChangeNotice)
? mCurrentInterval->Begin()
: nullptr;
nsSMILInterval updatedInterval;
if (GetNextInterval(GetPreviousInterval(), mCurrentInterval,
if (GetNextInterval(GetPreviousInterval(), mCurrentInterval.get(),
beginTime, updatedInterval)) {
if (mElementState == STATE_POSTACTIVE) {
MOZ_ASSERT(!mCurrentInterval,
"In postactive state but the interval has been set");
mCurrentInterval = new nsSMILInterval(updatedInterval);
mCurrentInterval = MakeUnique<nsSMILInterval>(updatedInterval);
mElementState = STATE_WAITING;
NotifyNewInterval();
@ -2118,7 +2116,7 @@ nsSMILTimedElement::UpdateCurrentInterval(bool aForceChangeNotice)
}
if (beginChanged || endChanged || aForceChangeNotice) {
NotifyChangedInterval(mCurrentInterval, beginChanged, endChanged);
NotifyChangedInterval(mCurrentInterval.get(), beginChanged, endChanged);
}
}
@ -2132,7 +2130,7 @@ nsSMILTimedElement::UpdateCurrentInterval(bool aForceChangeNotice)
if (!mCurrentInterval->End()->SameTimeAndBase(*mCurrentInterval->Begin()))
{
mCurrentInterval->SetEnd(*mCurrentInterval->Begin());
NotifyChangedInterval(mCurrentInterval, false, true);
NotifyChangedInterval(mCurrentInterval.get(), false, true);
}
// The transition to the postactive state will take place on the next
// sample (along with firing end events, clearing intervals etc.)
@ -2340,7 +2338,7 @@ nsSMILTimedElement::NotifyNewInterval()
}
for (auto iter = mTimeDependents.Iter(); !iter.Done(); iter.Next()) {
nsSMILInterval* interval = mCurrentInterval;
nsSMILInterval* interval = mCurrentInterval.get();
// It's possible that in notifying one new time dependent of a new interval
// that a chain reaction is triggered which results in the original
// interval disappearing. If that's the case we can skip sending further

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

@ -9,6 +9,7 @@
#include "mozilla/EventForwards.h"
#include "mozilla/Move.h"
#include "mozilla/UniquePtr.h"
#include "nsSMILInterval.h"
#include "nsSMILInstanceTime.h"
#include "nsSMILMilestone.h"
@ -352,9 +353,9 @@ public:
protected:
// Typedefs
typedef nsTArray<nsAutoPtr<nsSMILTimeValueSpec> > TimeValueSpecList;
typedef nsTArray<mozilla::UniquePtr<nsSMILTimeValueSpec>> TimeValueSpecList;
typedef nsTArray<RefPtr<nsSMILInstanceTime> > InstanceTimeList;
typedef nsTArray<nsAutoPtr<nsSMILInterval> > IntervalList;
typedef nsTArray<mozilla::UniquePtr<nsSMILInterval>> IntervalList;
typedef nsPtrHashKey<nsSMILTimeValueSpec> TimeValueSpecPtrKey;
typedef nsTHashtable<TimeValueSpecPtrKey> TimeValueSpecHashSet;
@ -557,7 +558,7 @@ protected:
{
if (mCurrentInterval) {
// Transfer ownership to temp var. (This sets mCurrentInterval to null.)
nsAutoPtr<nsSMILInterval> interval(mozilla::Move(mCurrentInterval));
auto interval = mozilla::Move(mCurrentInterval);
interval->Unlink();
}
}
@ -600,7 +601,7 @@ protected:
uint32_t mInstanceSerialIndex;
nsSMILAnimationFunction* mClient;
nsAutoPtr<nsSMILInterval> mCurrentInterval;
mozilla::UniquePtr<nsSMILInterval> mCurrentInterval;
IntervalList mOldIntervals;
uint32_t mCurrentRepeatIteration;
nsSMILMilestone mPrevRegisteredMilestone;

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

@ -954,6 +954,30 @@ WebSocket::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
return WebSocketBinding::Wrap(cx, this, aGivenProto);
}
void
WebSocket::BindToOwner(nsIGlobalObject* aNew)
{
auto scopeExit = MakeScopeExit([&] {
DOMEventTargetHelper::BindToOwner(aNew);
});
// If we're disconnected, then there is no state to update.
if (!mImpl || mImpl->mDisconnectingOrDisconnected) {
return;
}
// Update state on the old window.
if (GetOwner()) {
GetOwner()->UpdateWebSocketCount(-1);
}
// Update state on the new window
nsCOMPtr<nsPIDOMWindowInner> newWindow = do_QueryInterface(aNew);
if (newWindow) {
newWindow->UpdateWebSocketCount(1);
}
}
//---------------------------------------------------------------------------
// WebIDL
//---------------------------------------------------------------------------

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

@ -65,6 +65,9 @@ public:
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
// DOMEventTargetHelper
void BindToOwner(nsIGlobalObject* aNew) override;
public: // static helpers:
// Determine if preferences allow WebSocket

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

@ -1,6 +1,7 @@
[DEFAULT]
skip-if = toolkit == 'android' # bug 982828
support-files =
!/dom/events/test/event_leak_utils.js
file_websocket_basic_wsh.py
file_websocket_hello_wsh.py
file_websocket_http_resource.txt
@ -16,6 +17,8 @@ support-files =
[test_bug1081686.html]
[test_bug1384658.html]
support-files = window_bug1384658.html frame_bug1384658.html file_bug1384658.html
[test_event_listener_leaks.html]
support-files = file_websocket_bigBlob_wsh.py
[test_websocket1.html]
[test_websocket2.html]
[test_websocket3.html]

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

@ -0,0 +1,58 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1450358 - Test WebSocket event listener leak conditions</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/dom/events/test/event_leak_utils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script class="testbody" type="text/javascript">
// Manipulate WebSocket objects in the frame's context.
// Its important here that we create a listener callback from
// the DOM objects back to the frame's global in order to
// exercise the leak condition.
async function useWebSocket(contentWindow) {
const url = "ws://mochi.test:8888/tests/dom/websocket/tests/file_websocket_bigBlob";
let ws = new contentWindow.WebSocket(url);
ws.onmessage = _ => {
contentWindow.messageCount += 1;
};
contentWindow.openCount = 0;
await new Promise((resolve, reject) => {
ws.onopen = _ => {
contentWindow.openCount += 1;
resolve();
};
ws.onerror = e => {
contentWindow.errorCount += 1;
reject("websocket error");
};
});
is(contentWindow.openCount, 1, "open should be received");
}
async function runTest() {
try {
await checkForEventListenerLeaks("WebSocket", useWebSocket);
} catch (e) {
ok(false, e);
} finally {
SimpleTest.finish();
}
}
SimpleTest.waitForExplicitFinish();
addEventListener("load", runTest, { once: true });
</script>
</pre>
</body>
</html>

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

@ -93,7 +93,7 @@ DoGrayscale(IDWriteFontFace *aDWFace, Float ppem)
}
static inline DWRITE_FONT_STRETCH
DWriteFontStretchFromStretch(int16_t aStretch)
DWriteFontStretchFromStretch(uint16_t aStretch)
{
switch (aStretch) {
case NS_FONT_STRETCH_ULTRA_CONDENSED:

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

@ -162,8 +162,6 @@ public:
Tile& GetTile(size_t i) { return mRetainedTiles[i]; }
const nsIntRegion& GetValidRegion() const { return mValidRegion; }
const nsIntRegion& GetPaintedRegion() const { return mPaintedRegion; }
void ClearPaintedRegion() { mPaintedRegion.SetEmpty(); }
// Get and set draw scaling. mResolution affects the resolution at which the
// contents of the buffer are drawn. mResolution has no effect on the
@ -179,7 +177,6 @@ public:
protected:
nsIntRegion mValidRegion;
nsIntRegion mPaintedRegion;
/**
* mRetainedTiles is a rectangular buffer of mTiles.mSize.width x mTiles.mSize.height

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

@ -33,7 +33,6 @@ void
SingleTiledContentClient::UpdatedBuffer(TiledBufferType aType)
{
mForwarder->UseTiledLayerBuffer(this, mTiledBuffer->GetSurfaceDescriptorTiles());
mTiledBuffer->ClearPaintedRegion();
}
/* static */ bool
@ -142,6 +141,7 @@ ClientSingleTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
}
// The dirty region relative to the top-left of the tile.
nsIntRegion tileVisibleRegion = aNewValidRegion.MovedBy(-mTilingOrigin);
nsIntRegion tileDirtyRegion = paintRegion.MovedBy(-mTilingOrigin);
std::vector<RefPtr<TextureClient>> paintClients;
@ -153,6 +153,7 @@ ClientSingleTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
RefPtr<TextureClient> backBuffer =
mTile.GetBackBuffer(mCompositableClient,
tileDirtyRegion,
tileVisibleRegion,
content, mode,
extraPainted,
aFlags,
@ -166,15 +167,18 @@ ClientSingleTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
// Add backbuffer's invalid region to the dirty region to be painted.
// This will be empty if we were able to copy from the front in to the back.
paintRegion.OrWith(mTile.mInvalidBack.MovedBy(mTilingOrigin));
tileDirtyRegion.OrWith(mTile.mInvalidBack);
nsIntRegion tileInvalidRegion = mTile.mInvalidBack;
tileInvalidRegion.AndWith(tileVisibleRegion);
paintRegion.OrWith(tileInvalidRegion.MovedBy(mTilingOrigin));
tileDirtyRegion.OrWith(tileInvalidRegion);
// Mark the region we will be painting and the region we copied from the front buffer as
// needing to be uploaded to the compositor
mTile.mUpdateRect = tileDirtyRegion.GetBounds().Union(extraPainted.GetBounds());
extraPainted.MoveBy(mTilingOrigin);
extraPainted.And(extraPainted, aNewValidRegion);
mPaintedRegion.OrWith(paintRegion);
mPaintedRegion.OrWith(extraPainted);
if (!backBuffer) {
return;
@ -188,10 +192,8 @@ ClientSingleTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
// If the old frontbuffer was discarded then attempt to copy what we
// can from it to the new backbuffer.
bool copiedFromDiscarded = false;
nsIntRegion copyableRegion;
if (discardedFrontBuffer) {
nsIntRegion copyableRegion;
copyableRegion.And(aNewValidRegion, discardedValidRegion);
copyableRegion.SubOut(aDirtyRegion);
@ -254,22 +256,17 @@ ClientSingleTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
// We don't need to repaint valid content that was just copied.
paintRegion.SubOut(copyableRegion);
copiedFromDiscarded = true;
copyableRegion.MoveBy(-mTilingOrigin);
tileDirtyRegion.SubOut(copyableRegion);
}
}
}
if (mode != SurfaceMode::SURFACE_OPAQUE) {
nsIntRegion regionToClear = tileDirtyRegion;
if (copiedFromDiscarded) {
copyableRegion.MoveBy(-mTilingOrigin);
regionToClear.SubOut(copyableRegion);
}
auto clear = CapturedTiledPaintState::Clear{
dt,
dtOnWhite,
regionToClear,
tileDirtyRegion,
};
if (asyncPaint) {

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

@ -59,7 +59,6 @@ public:
}
void ResetPaintedAndValidState() override {
mPaintedRegion.SetEmpty();
mValidRegion.SetEmpty();
mTile.DiscardBuffers();
}
@ -78,16 +77,11 @@ public:
SurfaceDescriptorTiles GetSurfaceDescriptorTiles();
void ClearPaintedRegion() {
mPaintedRegion.SetEmpty();
}
private:
TileClient mTile;
RefPtr<ClientLayerManager> mManager;
nsIntRegion mPaintedRegion;
nsIntRegion mValidRegion;
bool mWasLastPaintProgressive;

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

@ -118,7 +118,6 @@ MultiTiledContentClient::UpdatedBuffer(TiledBufferType aType)
MOZ_ASSERT(aType != LOW_PRECISION_TILED_BUFFER || mHasLowPrecision);
mForwarder->UseTiledLayerBuffer(this, buffer->GetSurfaceDescriptorTiles());
buffer->ClearPaintedRegion();
}
SharedFrameMetricsHelper::SharedFrameMetricsHelper()
@ -522,6 +521,7 @@ CopyFrontToBack(TextureClient* aFront,
void
TileClient::ValidateBackBufferFromFront(const nsIntRegion& aDirtyRegion,
const nsIntRegion& aVisibleRegion,
nsIntRegion& aAddPaintedRegion,
TilePaintFlags aFlags,
std::vector<CapturedTiledPaintState::Copy>* aCopies,
@ -540,6 +540,7 @@ TileClient::ValidateBackBufferFromFront(const nsIntRegion& aDirtyRegion,
nsIntRegion regionToCopy = mInvalidBack;
regionToCopy.Sub(regionToCopy, aDirtyRegion);
regionToCopy.And(regionToCopy, aVisibleRegion);
aAddPaintedRegion = regionToCopy;
@ -557,10 +558,10 @@ TileClient::ValidateBackBufferFromFront(const nsIntRegion& aDirtyRegion,
if (mBackBufferOnWhite) {
MOZ_ASSERT(mFrontBufferOnWhite);
if (CopyFrontToBack(mFrontBufferOnWhite, mBackBufferOnWhite, gfxRectToCopy, aFlags, aCopies, aClients)) {
mInvalidBack.SetEmpty();
mInvalidBack.Sub(mInvalidBack, aVisibleRegion);
}
} else {
mInvalidBack.SetEmpty();
mInvalidBack.Sub(mInvalidBack, aVisibleRegion);
}
}
}
@ -653,6 +654,7 @@ CreateBackBufferTexture(TextureClient* aCurrentTexture,
TextureClient*
TileClient::GetBackBuffer(CompositableClient& aCompositable,
const nsIntRegion& aDirtyRegion,
const nsIntRegion& aVisibleRegion,
gfxContentType aContent,
SurfaceMode aMode,
nsIntRegion& aAddPaintedRegion,
@ -684,9 +686,15 @@ TileClient::GetBackBuffer(CompositableClient& aCompositable,
!mFrontBuffer->IsReadLocked() &&
(aMode != SurfaceMode::SURFACE_COMPONENT_ALPHA || (
mFrontBufferOnWhite && !mFrontBufferOnWhite->IsReadLocked()))) {
// If we had a backbuffer we no longer care about it since we'll
// re-use the front buffer.
DiscardBackBuffer();
// If we had a backbuffer we no longer need it since we can re-use the
// front buffer here. It can be worth it to hold on to the back buffer
// so we don't need to pay the cost of initializing a new back buffer
// later (copying pixels and texture upload). But this could increase
// our memory usage and lead to OOM more frequently from spikes in usage,
// so we have this behavior behind a pref.
if (!gfxPrefs::LayersTileRetainBackBuffer()) {
DiscardBackBuffer();
}
Flip();
} else {
if (!mBackBuffer || mBackBuffer->IsReadLocked()) {
@ -714,7 +722,7 @@ TileClient::GetBackBuffer(CompositableClient& aCompositable,
mInvalidBack = IntRect(IntPoint(), mBackBufferOnWhite->GetSize());
}
ValidateBackBufferFromFront(aDirtyRegion, aAddPaintedRegion, aFlags, aCopies, aClients);
ValidateBackBufferFromFront(aDirtyRegion, aVisibleRegion, aAddPaintedRegion, aFlags, aCopies, aClients);
}
OpenMode lockMode = aFlags & TilePaintFlags::Async ? OpenMode::OPEN_READ_WRITE_ASYNC
@ -1092,7 +1100,6 @@ void ClientMultiTiledLayerBuffer::Update(const nsIntRegion& newValidRegion,
mTiles = newTiles;
mValidRegion = newValidRegion;
mPaintedRegion.OrWith(paintRegion);
}
bool
@ -1120,8 +1127,11 @@ ClientMultiTiledLayerBuffer::ValidateTile(TileClient& aTile,
MOZ_ASSERT(aTile.mAllocator);
}
nsIntRegion offsetScaledDirtyRegion = aDirtyRegion.MovedBy(-aTileOrigin);
offsetScaledDirtyRegion.ScaleRoundOut(mResolution, mResolution);
nsIntRegion tileDirtyRegion = aDirtyRegion.MovedBy(-aTileOrigin);
tileDirtyRegion.ScaleRoundOut(mResolution, mResolution);
nsIntRegion tileVisibleRegion = mNewValidRegion.MovedBy(-aTileOrigin);
tileVisibleRegion.ScaleRoundOut(mResolution, mResolution);
std::vector<CapturedTiledPaintState::Copy> asyncPaintCopies;
std::vector<RefPtr<TextureClient>> asyncPaintClients;
@ -1130,7 +1140,8 @@ ClientMultiTiledLayerBuffer::ValidateTile(TileClient& aTile,
RefPtr<TextureClient> backBufferOnWhite;
RefPtr<TextureClient> backBuffer =
aTile.GetBackBuffer(mCompositableClient,
offsetScaledDirtyRegion,
tileDirtyRegion,
tileVisibleRegion,
content, mode,
extraPainted,
aFlags,
@ -1140,22 +1151,28 @@ ClientMultiTiledLayerBuffer::ValidateTile(TileClient& aTile,
// Mark the area we need to paint in the back buffer as invalid in the
// front buffer as they will become out of sync.
aTile.mInvalidFront.OrWith(offsetScaledDirtyRegion);
aTile.mInvalidFront.OrWith(tileDirtyRegion);
// Add backbuffer's invalid region to the dirty region to be painted.
// This will be empty if we were able to copy from the front in to the back.
nsIntRegion invalidBack = aTile.mInvalidBack;
invalidBack.MoveBy(aTileOrigin);
invalidBack.ScaleInverseRoundOut(mResolution, mResolution);
invalidBack.AndWith(mNewValidRegion);
aDirtyRegion.OrWith(invalidBack);
offsetScaledDirtyRegion.OrWith(aTile.mInvalidBack);
// Add the backbuffer's invalid region intersected with the visible region to the
// dirty region we will be painting. This will be empty if we are able to copy
// from the front into the back.
nsIntRegion tileInvalidRegion = aTile.mInvalidBack;
tileInvalidRegion.AndWith(tileVisibleRegion);
aTile.mUpdateRect = offsetScaledDirtyRegion.GetBounds().Union(extraPainted.GetBounds());
nsIntRegion invalidRegion = tileInvalidRegion;
invalidRegion.MoveBy(aTileOrigin);
invalidRegion.ScaleInverseRoundOut(mResolution, mResolution);
tileDirtyRegion.OrWith(tileInvalidRegion);
aDirtyRegion.OrWith(invalidRegion);
// Mark the region we will be painting and the region we copied from the front buffer as
// needing to be uploaded to the compositor
aTile.mUpdateRect = tileDirtyRegion.GetBounds().Union(extraPainted.GetBounds());
// Add the region we copied from the front buffer into the painted region
extraPainted.MoveBy(aTileOrigin);
extraPainted.And(extraPainted, mNewValidRegion);
mPaintedRegion.Or(mPaintedRegion, extraPainted);
if (!backBuffer) {
return false;
@ -1182,7 +1199,7 @@ ClientMultiTiledLayerBuffer::ValidateTile(TileClient& aTile,
auto clear = CapturedTiledPaintState::Clear{
dt,
dtOnWhite,
offsetScaledDirtyRegion
tileDirtyRegion
};
gfx::Tile paintTile;
@ -1220,7 +1237,7 @@ ClientMultiTiledLayerBuffer::ValidateTile(TileClient& aTile,
mTilingOrigin.y = std::min(mTilingOrigin.y, paintTile.mTileOrigin.y);
// The new buffer is now validated, remove the dirty region from it.
aTile.mInvalidBack.SubOut(offsetScaledDirtyRegion);
aTile.mInvalidBack.SubOut(tileDirtyRegion);
aTile.Flip();

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

@ -128,6 +128,7 @@ struct TileClient
*/
TextureClient* GetBackBuffer(CompositableClient&,
const nsIntRegion& aDirtyRegion,
const nsIntRegion& aVisibleRegion,
gfxContentType aContent, SurfaceMode aMode,
nsIntRegion& aAddPaintedRegion,
TilePaintFlags aFlags,
@ -170,6 +171,7 @@ private:
// Copies dirty pixels from the front buffer into the back buffer,
// and records the copied region in aAddPaintedRegion.
void ValidateBackBufferFromFront(const nsIntRegion &aDirtyRegion,
const nsIntRegion& aVisibleRegion,
nsIntRegion& aAddPaintedRegion,
TilePaintFlags aFlags,
std::vector<CapturedTiledPaintState::Copy>* aCopies,
@ -382,7 +384,6 @@ public:
void* aCallbackData) override;
void ResetPaintedAndValidState() override {
mPaintedRegion.SetEmpty();
mValidRegion.SetEmpty();
mTiles.mSize.width = 0;
mTiles.mSize.height = 0;

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

@ -584,15 +584,6 @@ struct DIGroup
PaintItemRange(aGrouper, aStartItem, aEndItem, context, recorder);
if (aStartItem->Frame()->PresContext()->GetPaintFlashing()) {
context->SetMatrix(Matrix());
float r = float(rand()) / RAND_MAX;
float g = float(rand()) / RAND_MAX;
float b = float(rand()) / RAND_MAX;
dt->FillRect(gfx::Rect(0, 0, dtSize.width, dtSize.height), gfx::ColorPattern(gfx::Color(r, g, b, 0.5)));
dt->FlushItem(IntRect(IntPoint(0, 0), dtSize));
}
// XXX: set this correctly perhaps using aItem->GetOpaqueRegion(aDisplayListBuilder, &snapped).Contains(paintBounds);?
bool isOpaque = false;

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

@ -9,6 +9,8 @@
#define GFX_FONT_PROPERTY_TYPES_H
#include <cstdint>
#include <cmath>
#include "mozilla/Assertions.h"
/*
* This file is separate from gfxFont.h so that layout can include it
@ -18,113 +20,314 @@
namespace mozilla {
/**
* A type that will in future encode a value as fixed point.
* Generic template for font property type classes that use a fixed-point
* internal representation.
* Template parameters:
* T - the integer type to use as the internal representation (e.g. uint16_t)
* * NOTE that T must NOT be plain /int/, as that would result in
* ambiguity between constructors from /int/ and /T/, which mean
* different things.
* FractionBits - number of bits to use for the fractional part
* Min, Max - [inclusive] limits to the range of values that may be stored
* Values are constructed from and exposed as floating-point, but stored
* internally as fixed point, so there will be a quantization effect on
* fractional values, depending on the number of fractional bits used.
* Using (16-bit) fixed-point types rather than floats for these style
* attributes reduces the memory footprint of gfxFontEntry and gfxFontStyle;
* it will also tend to reduce the number of distinct font instances that
* get created, particularly when styles are animated or set to arbitrary
* values (e.g. by sliders in the UI), which should reduce pressure on
* graphics resources and improve cache hit rates.
*/
class FontFixedPointValue
template<class T,unsigned FractionBits,int Min,int Max>
class FontPropertyValue
{
public:
// Ugh. We need a default constructor to allow this type to be used in the
// union in nsCSSValue. Furthermore we need the default and copy
// union in nsCSSValue. Furthermore we need the default and copy
// constructors to be "trivial" (i.e. the compiler implemented defaults that
// do no initialization).
// Annoyingly it seems we can't make the default implementations constexpr
// (at least in clang). We'd like to do that to allow Thin() et. al. below
// Annoyingly we can't make the default implementations constexpr (at least
// in clang). That would be nice to do in order to allow the methods of
// subclasses that always return the same value (e.g., FontWeight::Thin())
// to also be constexpr. :/
FontFixedPointValue() = default;
FontFixedPointValue(const FontFixedPointValue& aOther) = default;
FontPropertyValue() = default;
explicit FontPropertyValue(const FontPropertyValue& aOther) = default;
FontPropertyValue& operator= (const FontPropertyValue& aOther) = default;
// Not currently encoded, but it will be in future
explicit FontFixedPointValue(int16_t aValue)
: mEncoded(aValue)
{}
explicit FontFixedPointValue(int32_t aValue)
: mEncoded(aValue)
{}
explicit FontFixedPointValue(float aValue)
: mEncoded(int16_t(aValue))
{}
float ToFloat() const {
return float(mEncoded);
bool operator==(const FontPropertyValue& aOther) const
{
return mValue == aOther.mValue;
}
bool operator!=(const FontPropertyValue& aOther) const
{
return mValue != aOther.mValue;
}
bool operator<(const FontPropertyValue& aOther) const
{
return mValue < aOther.mValue;
}
bool operator>(const FontPropertyValue& aOther) const
{
return mValue > aOther.mValue;
}
bool operator<=(const FontPropertyValue& aOther) const
{
return mValue <= aOther.mValue;
}
bool operator>=(const FontPropertyValue& aOther) const
{
return mValue >= aOther.mValue;
}
int16_t ToIntRounded() const {
return mEncoded;
// The difference between two values, returned as a raw floating-point number
// (which might not be a valid property value in its own right).
float operator-(const FontPropertyValue& aOther) const
{
return (mValue - aOther.mValue) * kInverseScale;
}
bool operator==(const FontFixedPointValue& aOther) const {
return mEncoded == aOther.mEncoded;
}
bool operator!=(const FontFixedPointValue& aOther) const {
return mEncoded != aOther.mEncoded;
}
bool operator<(const FontFixedPointValue& aOther) const {
return mEncoded < aOther.mEncoded;
}
bool operator<=(const FontFixedPointValue& aOther) const {
return mEncoded <= aOther.mEncoded;
}
bool operator>=(const FontFixedPointValue& aOther) const {
return mEncoded >= aOther.mEncoded;
}
bool operator>(const FontFixedPointValue& aOther) const {
return mEncoded > aOther.mEncoded;
}
int16_t ForHash() const {
return mEncoded;
/// Return the raw internal representation, for purposes of hashing.
T ForHash() const
{
return mValue;
}
protected:
int16_t mEncoded;
typedef T internal_type;
// Construct from a floating-point or integer value, checking that it is
// within the allowed range and converting to fixed-point representation.
explicit FontPropertyValue(float aValue)
: mValue(std::round(aValue * kScale))
{
MOZ_ASSERT(aValue >= kMin && aValue <= kMax);
}
explicit FontPropertyValue(int aValue)
: mValue(aValue << kFractionBits)
{
MOZ_ASSERT(aValue >= Min && aValue <= Max);
}
// Construct directly from a fixed-point value of type T, with no check;
// note that there may be special "flag" values that are outside the normal
// min/max range (e.g. for font-style:italic, distinct from oblique angle).
explicit FontPropertyValue(T aValue)
: mValue(aValue)
{
}
// This is protected as it may not be the most appropriate accessor for a
// given instance to expose. It's up to each individual property to provide
// public accessors that forward to this as required.
float ToFloat() const { return mValue * kInverseScale; }
int ToIntRounded() const { return (mValue + kPointFive) >> FractionBits; }
static constexpr float kScale = float(1u << FractionBits);
static constexpr float kInverseScale = 1.0f / kScale;
static constexpr float kMin = float(Min);
static constexpr float kMax = float(Max);
static const unsigned kFractionBits = FractionBits;
// Constant representing 0.5 in the internal representation (note this
// assumes that kFractionBits is greater than zero!)
static const T kPointFive = 1u << (kFractionBits - 1);
T mValue;
};
class FontWeight : public FontFixedPointValue
/**
* font-weight: range 1..1000, fractional values permitted; keywords
* 'normal', 'bold' aliased to 400, 700 respectively; relative keywords
* 'lighter', 'bolder' (not currently handled here).
*
* We use an unsigned 10.6 fixed-point value (range 0.0 - 1023.984375)
*/
class FontWeight final : public FontPropertyValue<uint16_t,6,1,1000>
{
public:
// Ugh, to get union in nsCSSValue compiling
// See comment in FontPropertyValue regarding requirement for a trivial
// default constructor.
FontWeight() = default;
FontWeight(const FontWeight& aOther) = default;
// Not currently encoded, but it will be in future
explicit FontWeight(int16_t aValue)
: FontFixedPointValue(aValue)
{}
explicit FontWeight(int32_t aValue)
: FontFixedPointValue(aValue)
{}
explicit FontWeight(float aValue)
: FontFixedPointValue(int16_t(aValue))
{}
bool operator==(const FontWeight& aOther) const
: FontPropertyValue(aValue)
{
return mEncoded == aOther.mEncoded;
}
/// The "distance" between two font weights
float operator-(const FontWeight& aOther) const {
return this->ToFloat() - aOther.ToFloat();
/**
* CSS font weights can have fractional values, but this constructor exists
* for convenience when writing constants such as FontWeight(700) in code.
*/
explicit FontWeight(int aValue)
: FontPropertyValue(aValue)
{
}
static FontWeight Thin() {
return FontWeight{100};
static FontWeight Normal()
{
return FontWeight(kNormal);
}
static FontWeight Normal() {
return FontWeight{400};
static FontWeight Thin()
{
return FontWeight(kThin);
}
static FontWeight Bold() {
return FontWeight{700};
static FontWeight Bold()
{
return FontWeight(kBold);
}
bool IsNormal() const { return mValue == kNormal; }
bool IsBold() const { return mValue >= kBoldThreshold; }
float ToFloat() const { return FontPropertyValue::ToFloat(); }
int ToIntRounded() const { return FontPropertyValue::ToIntRounded(); }
private:
explicit FontWeight(internal_type aValue)
: FontPropertyValue(aValue)
{
}
static const internal_type kNormal = 400u << kFractionBits;
static const internal_type kBold = 700u << kFractionBits;
static const internal_type kBoldThreshold = 600u << kFractionBits;
static const internal_type kThin = 100u << kFractionBits;
static const internal_type kExtraBold = 900u << kFractionBits;
};
/**
* font-stretch is represented as a percentage relative to 'normal'.
*
* css-fonts says the value must be >= 0%, and normal is 100%. Keywords
* from ultra-condensed to ultra-expanded are aliased to percentages
* from 50% to 200%; values outside that range are unlikely to be common,
* but could occur.
*
* Like font-weight, we use an unsigned 10.6 fixed-point value (range
* 0.0 - 1023.984375).
*
* We arbitrarily limit here to 1000%. (If that becomes a problem, we
* could reduce the number of fractional bits and increase the limit.)
*/
class FontStretch final : public FontPropertyValue<uint16_t,6,0,1000>
{
public:
// See comment in FontPropertyValue regarding requirement for a trivial
// default constructor.
FontStretch() = default;
explicit FontStretch(float aPercent)
: FontPropertyValue(aPercent)
{
}
static FontStretch Normal()
{
return FontStretch(kNormal);
}
static FontStretch UltraCondensed()
{
return FontStretch(kUltraCondensed);
}
static FontStretch ExtraCondensed()
{
return FontStretch(kExtraCondensed);
}
static FontStretch Condensed()
{
return FontStretch(kCondensed);
}
static FontStretch SemiCondensed()
{
return FontStretch(kSemiCondensed);
}
static FontStretch SemiExpanded()
{
return FontStretch(kSemiExpanded);
}
static FontStretch Expanded()
{
return FontStretch(kExpanded);
}
static FontStretch ExtraExpanded()
{
return FontStretch(kExtraExpanded);
}
static FontStretch UltraExpanded()
{
return FontStretch(kUltraExpanded);
}
bool IsNormal() const { return mValue == kNormal; }
float Percentage() const { return ToFloat(); }
private:
static const internal_type kUltraCondensed = 50u << kFractionBits;
static const internal_type kExtraCondensed = (62u << kFractionBits) + kPointFive;
static const internal_type kCondensed = 75u << kFractionBits;
static const internal_type kSemiCondensed = (87u << kFractionBits) + kPointFive;
static const internal_type kNormal = 100u << kFractionBits;
static const internal_type kSemiExpanded = (112u << kFractionBits) + kPointFive;
static const internal_type kExpanded = 125u << kFractionBits;
static const internal_type kExtraExpanded = 150u << kFractionBits;
static const internal_type kUltraExpanded = 200u << kFractionBits;
};
/**
* font-style: normal | italic | oblique <angle>?
* values of <angle> below -90 or above 90 not permitted
* - Use a signed 8.8 fixed-point value
* (representable range -128.0 - 127.99609375)
* - Define min value (-128.0) as meaning 'normal'
* - Define max value (127.99609375) as 'italic'
* - Other values represent 'oblique <angle>'
* - Note that 'oblique 0deg' is distinct from 'normal' (should it be?)
*/
class FontStyle final : public FontPropertyValue<int16_t,8,-90,90>
{
public:
// See comment in FontPropertyValue regarding requirement for a trivial
// default constructor.
FontStyle() = default;
static FontStyle Normal()
{
return FontStyle(kNormal);
}
static FontStyle Italic()
{
return FontStyle(kItalic);
}
static FontStyle Oblique(float aAngle = 14.0f)
{
return FontStyle(aAngle);
}
bool IsNormal() const { return mValue == kNormal; }
bool IsItalic() const { return mValue == kItalic; }
bool IsOblique() const { return mValue != kItalic && mValue != kNormal; }
float ObliqueAngle() const
{
// It's not meaningful to get the oblique angle from a style that is
// actually 'normal' or 'italic'.
MOZ_ASSERT(!IsItalic() && !IsNormal());
return ToFloat();
}
private:
explicit FontStyle(float aAngle)
: FontPropertyValue(aAngle)
{
}
static const int16_t kNormal = INT16_MIN;
static const int16_t kItalic = INT16_MAX;
};
} // namespace mozilla

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

@ -21,7 +21,7 @@
#include <dwrite.h>
static inline DWRITE_FONT_STRETCH
DWriteFontStretchFromStretch(int16_t aStretch)
DWriteFontStretchFromStretch(uint16_t aStretch)
{
switch (aStretch) {
case NS_FONT_STRETCH_ULTRA_CONDENSED:
@ -47,8 +47,8 @@ DWriteFontStretchFromStretch(int16_t aStretch)
}
}
static inline int16_t
FontStretchFromDWriteStretch(DWRITE_FONT_STRETCH aStretch)
static inline uint16_t
FontStretchFromDWriteStretch(DWRITE_FONT_STRETCH aStretch)
{
switch (aStretch) {
case DWRITE_FONT_STRETCH_ULTRA_CONDENSED:

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

@ -958,7 +958,7 @@ gfxDWriteFontList::GetDefaultFontForPlatform(const gfxFontStyle *aStyle)
gfxFontEntry *
gfxDWriteFontList::LookupLocalFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle)
{
gfxFontEntry *lookup;
@ -982,7 +982,7 @@ gfxDWriteFontList::LookupLocalFont(const nsAString& aFontName,
gfxFontEntry *
gfxDWriteFontList::MakePlatformFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle,
const uint8_t* aFontData,
uint32_t aLength)

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

@ -7,6 +7,7 @@
#define GFX_DWRITEFONTLIST_H
#include "mozilla/FontPropertyTypes.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/MemoryReporting.h"
#include "gfxDWriteCommon.h"
#include "dwrite_3.h"
@ -118,10 +119,9 @@ public:
(dwriteStyle == DWRITE_FONT_STYLE_OBLIQUE ?
NS_FONT_STYLE_OBLIQUE : NS_FONT_STYLE_NORMAL));
mStretch = FontStretchFromDWriteStretch(aFont->GetStretch());
uint16_t weight = NS_ROUNDUP(aFont->GetWeight() - 50, 100);
int weight = NS_ROUNDUP(aFont->GetWeight() - 50, 100);
weight = std::max<uint16_t>(100, weight);
weight = std::min<uint16_t>(900, weight);
weight = mozilla::Clamp(weight, 100, 900);
mWeight = FontWeight(weight);
mIsCJK = UNINITIALIZED_VALUE;
@ -141,7 +141,7 @@ public:
gfxDWriteFontEntry(const nsAString& aFaceName,
IDWriteFont *aFont,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle)
: gfxFontEntry(aFaceName), mFont(aFont), mFontFile(nullptr),
mIsSystemFont(false), mForceGDIClassic(false),
@ -168,7 +168,7 @@ public:
IDWriteFontFile *aFontFile,
IDWriteFontFileStream *aFontFileStream,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle)
: gfxFontEntry(aFaceName), mFont(nullptr),
mFontFile(aFontFile), mFontFileStream(aFontFileStream),
@ -405,12 +405,12 @@ public:
virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle);
virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle,
const uint8_t* aFontData,
uint32_t aLength);

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

@ -258,7 +258,7 @@ FT2FontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold
FT2FontEntry*
FT2FontEntry::CreateFontEntry(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle,
const uint8_t* aFontData,
uint32_t aLength)
@ -371,7 +371,7 @@ FTFaceGetWeight(FT_Face aFace)
NS_ASSERTION(result >= 100 && result <= 900, "Invalid weight in font!");
return FontWeight(result);
return FontWeight(int(result));
}
// Used to create the font entry for installed faces on the device,
@ -968,7 +968,7 @@ gfxFT2FontList::AppendFacesFromCachedFaceList(
if (!(end = strchr(beginning, ','))) {
break;
}
int32_t stretch = strtol(beginning, nullptr, 10);
uint32_t stretch = strtoul(beginning, nullptr, 10);
FontListEntry fle(familyName, faceName, aFileName,
weight, stretch, italic, index);
@ -1465,7 +1465,7 @@ gfxFT2FontList::InitFontListForPlatform()
gfxFontEntry*
gfxFT2FontList::LookupLocalFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle)
{
// walk over list of names
@ -1547,7 +1547,7 @@ gfxFT2FontList::GetDefaultFontForPlatform(const gfxFontStyle* aStyle)
gfxFontEntry*
gfxFT2FontList::MakePlatformFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle,
const uint8_t* aFontData,
uint32_t aLength)

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

@ -44,7 +44,7 @@ public:
static FT2FontEntry*
CreateFontEntry(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle,
const uint8_t* aFontData,
uint32_t aLength);
@ -123,12 +123,12 @@ public:
virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle) override;
virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle,
const uint8_t* aFontData,
uint32_t aLength) override;

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

@ -312,7 +312,7 @@ CreateFaceForPattern(FcPattern* aPattern)
gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle,
const uint8_t *aData,
uint32_t aLength,
@ -335,7 +335,7 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName,
gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName,
FcPattern* aFontPattern,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle)
: gfxFontEntry(aFaceName), mFontPattern(aFontPattern),
mFTFace(nullptr), mFTFaceInitialized(false),
@ -1858,7 +1858,7 @@ gfxFcPlatformFontList::GetDefaultFontForPlatform(const gfxFontStyle* aStyle)
gfxFontEntry*
gfxFcPlatformFontList::LookupLocalFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle)
{
nsAutoString keyName(aFontName);
@ -1877,7 +1877,7 @@ gfxFcPlatformFontList::LookupLocalFont(const nsAString& aFontName,
gfxFontEntry*
gfxFcPlatformFontList::MakePlatformFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle,
const uint8_t* aFontData,
uint32_t aLength)

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

@ -95,7 +95,7 @@ public:
// of the font data and the FT_Face
explicit gfxFontconfigFontEntry(const nsAString& aFaceName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle,
const uint8_t *aData,
uint32_t aLength,
@ -105,7 +105,7 @@ public:
explicit gfxFontconfigFontEntry(const nsAString& aFaceName,
FcPattern* aFontPattern,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle);
gfxFontEntry* Clone() const override;
@ -290,12 +290,12 @@ public:
gfxFontEntry*
LookupLocalFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch, uint8_t aStyle) override;
uint16_t aStretch, uint8_t aStyle) override;
gfxFontEntry*
MakePlatformFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle,
const uint8_t* aFontData,
uint32_t aLength) override;

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

@ -4125,7 +4125,7 @@ gfxFontStyle::gfxFontStyle() :
gfxFontStyle::gfxFontStyle(uint8_t aStyle,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
gfxFloat aSize,
nsAtom *aLanguage, bool aExplicitLanguage,
float aSizeAdjust, bool aSystemFont,

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

@ -79,7 +79,7 @@ struct gfxFontStyle {
typedef mozilla::FontWeight FontWeight;
gfxFontStyle();
gfxFontStyle(uint8_t aStyle, FontWeight aWeight, int16_t aStretch,
gfxFontStyle(uint8_t aStyle, FontWeight aWeight, uint16_t aStretch,
gfxFloat aSize, nsAtom *aLanguage, bool aExplicitLanguage,
float aSizeAdjust, bool aSystemFont,
bool aPrinterFont,
@ -142,9 +142,8 @@ struct gfxFontStyle {
// The weight of the font: 100, 200, ... 900.
FontWeight weight;
// The stretch of the font (the sum of various NS_FONT_STRETCH_*
// constants; see gfxFontConstants.h).
int8_t stretch;
// The stretch of the font (NS_FONT_STRETCH_*, see gfxFontConstants.h).
uint8_t stretch;
// The style of font (normal, italic, oblique)
uint8_t style;

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

@ -21,15 +21,15 @@
#define NS_FONT_WEIGHT_BOLD 700
#define NS_FONT_WEIGHT_THIN 100
#define NS_FONT_STRETCH_ULTRA_CONDENSED (-4)
#define NS_FONT_STRETCH_EXTRA_CONDENSED (-3)
#define NS_FONT_STRETCH_CONDENSED (-2)
#define NS_FONT_STRETCH_SEMI_CONDENSED (-1)
#define NS_FONT_STRETCH_NORMAL 0
#define NS_FONT_STRETCH_SEMI_EXPANDED 1
#define NS_FONT_STRETCH_EXPANDED 2
#define NS_FONT_STRETCH_EXTRA_EXPANDED 3
#define NS_FONT_STRETCH_ULTRA_EXPANDED 4
#define NS_FONT_STRETCH_ULTRA_CONDENSED 50
#define NS_FONT_STRETCH_EXTRA_CONDENSED 62
#define NS_FONT_STRETCH_CONDENSED 75
#define NS_FONT_STRETCH_SEMI_CONDENSED 87
#define NS_FONT_STRETCH_NORMAL 100
#define NS_FONT_STRETCH_SEMI_EXPANDED 112
#define NS_FONT_STRETCH_EXPANDED 125
#define NS_FONT_STRETCH_EXTRA_EXPANDED 150
#define NS_FONT_STRETCH_ULTRA_EXPANDED 200
#define NS_FONT_SMOOTHING_AUTO 0
#define NS_FONT_SMOOTHING_GRAYSCALE 1

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

@ -1190,18 +1190,18 @@ StyleDistance(uint32_t aFontStyle, uint32_t aTargetStyle)
return 1; // neither is normal; must be italic vs oblique ==> 1
}
#define REVERSE_STRETCH_DISTANCE 5
#define REVERSE_STRETCH_DISTANCE 200
// stretch distance ==> [0,13]
// stretch distance ==> [0,350]
static inline uint32_t
StretchDistance(int16_t aFontStretch, int16_t aTargetStretch)
StretchDistance(int32_t aFontStretch, int32_t aTargetStretch)
{
int32_t distance = 0;
if (aTargetStretch != aFontStretch) {
// stretch values are in the range -4 .. +4
// if aTargetStretch is positive, we prefer more-positive values;
// if zero or negative, prefer more-negative
if (aTargetStretch > 0) {
// stretch values are in the range 50 .. 200
// if aTargetStretch is >100, we prefer larger values;
// if <=100, prefer smaller
if (aTargetStretch > 100) {
distance = (aFontStretch - aTargetStretch);
} else {
distance = (aTargetStretch - aFontStretch);
@ -1209,7 +1209,7 @@ StretchDistance(int16_t aFontStretch, int16_t aTargetStretch)
// if the computed "distance" here is negative, it means that
// aFontEntry lies in the "non-preferred" direction from aTargetStretch,
// so we treat that as larger than any preferred-direction distance
// (max possible is 4) by adding an extra 5 to the absolute value
// (max possible is 150) by adding an extra 200 to the absolute value
if (distance < 0) {
distance = -distance + REVERSE_STRETCH_DISTANCE;
}
@ -1435,7 +1435,7 @@ gfxFontFamily::CheckForSimpleFamily()
return;
}
int16_t firstStretch = mAvailableFonts[0]->Stretch();
uint16_t firstStretch = mAvailableFonts[0]->Stretch();
gfxFontEntry *faces[4] = { 0 };
for (uint8_t i = 0; i < count; ++i) {

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

@ -142,7 +142,7 @@ public:
virtual nsString RealFaceName();
FontWeight Weight() const { return mWeight; }
int16_t Stretch() const { return mStretch; }
uint16_t Stretch() const { return mStretch; }
bool IsUserFont() const { return mIsDataUserFont || mIsLocalUserFont; }
bool IsLocalUserFont() const { return mIsLocalUserFont; }
@ -150,7 +150,7 @@ public:
bool IsItalic() const { return mStyle == NS_FONT_STYLE_ITALIC; }
bool IsOblique() const { return mStyle == NS_FONT_STYLE_OBLIQUE; }
bool IsUpright() const { return mStyle == NS_FONT_STYLE_NORMAL; }
bool IsBold() const { return mWeight >= FontWeight(600); } // bold == weights 600 and above
bool IsBold() const { return mWeight.IsBold(); } // bold == weights 600 and above
bool IgnoreGDEF() const { return mIgnoreGDEF; }
bool IgnoreGSUB() const { return mIgnoreGSUB; }
@ -405,7 +405,7 @@ public:
uint32_t mNonDefaultSubSpaceFeatures[(int(Script::NUM_SCRIPT_CODES) + 31) / 32];
FontWeight mWeight;
int16_t mStretch;
uint16_t mStretch;
RefPtr<gfxCharacterMap> mCharacterMap;
uint32_t mUVSOffset;

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

@ -445,20 +445,22 @@ gfxGDIFont::FillLogFont(LOGFONTW& aLogFont, gfxFloat aSize)
{
GDIFontEntry *fe = static_cast<GDIFontEntry*>(GetFontEntry());
FontWeight weight;
// Figure out the lfWeight value to use for GDI font selection,
// or zero to use the entry's current LOGFONT value.
LONG weight;
if (fe->IsUserFont()) {
if (fe->IsLocalUserFont()) {
// for local user fonts, don't change the original weight
// in the entry's logfont, because that could alter the
// choice of actual face used (bug 724231)
weight = FontWeight(0);
weight = 0;
} else {
// avoid GDI synthetic bold which occurs when weight
// specified is >= font data weight + 200
weight = mNeedsBold ? FontWeight(700) : FontWeight(200);
weight = mNeedsBold ? 700 : 200;
}
} else {
weight = mNeedsBold ? FontWeight(700) : fe->Weight();
weight = mNeedsBold ? 700 : fe->Weight().ToIntRounded();
}
fe->FillLogFont(&aLogFont, weight, aSize);

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

@ -117,7 +117,7 @@ GDIFontEntry::GDIFontEntry(const nsAString& aFaceName,
gfxWindowsFontType aFontType,
uint8_t aStyle,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
gfxUserFontData *aUserFontData)
: gfxFontEntry(aFaceName),
mFontType(aFontType),
@ -256,7 +256,7 @@ GDIFontEntry::LookupUnscaledFont(HFONT aFont)
void
GDIFontEntry::FillLogFont(LOGFONTW *aLogFont,
FontWeight aWeight,
LONG aWeight,
gfxFloat aSize)
{
memcpy(aLogFont, &mLogFont, sizeof(LOGFONTW));
@ -272,8 +272,8 @@ GDIFontEntry::FillLogFont(LOGFONTW *aLogFont,
// for installed families with no bold face, and for downloaded fonts
// (but NOT for local user fonts, because it could cause a different,
// glyph-incompatible face to be used)
if (aWeight.ToFloat() != 0.0f) {
aLogFont->lfWeight = LONG(aWeight.ToFloat());
if (aWeight != 0) {
aLogFont->lfWeight = aWeight;
}
// for non-local() user fonts, we never want to apply italics here;
@ -396,7 +396,7 @@ GDIFontEntry::CreateFontEntry(const nsAString& aName,
gfxWindowsFontType aFontType,
uint8_t aStyle,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
gfxUserFontData* aUserFontData)
{
// jtdfix - need to set charset, unicode ranges, pitch/family
@ -711,7 +711,7 @@ gfxGDIFontList::EnumFontFamExProc(ENUMLOGFONTEXW *lpelfe,
gfxFontEntry*
gfxGDIFontList::LookupLocalFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle)
{
gfxFontEntry *lookup;
@ -737,7 +737,7 @@ gfxGDIFontList::LookupLocalFont(const nsAString& aFontName,
fe->mIsLocalUserFont = true;
// make the new font entry match the userfont entry style characteristics
fe->mWeight = (aWeight == FontWeight(0) ? FontWeight(400) : aWeight);
fe->mWeight = aWeight;
fe->mStyle = aStyle;
return fe;
@ -803,7 +803,7 @@ FixupSymbolEncodedFont(uint8_t* aFontData, uint32_t aLength)
gfxFontEntry*
gfxGDIFontList::MakePlatformFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle,
const uint8_t* aFontData,
uint32_t aLength)
@ -867,11 +867,9 @@ gfxGDIFontList::MakePlatformFont(const nsAString& aFontName,
// make a new font entry using the unique name
WinUserFontData *winUserFontData = new WinUserFontData(fontRef);
FontWeight w = (aWeight == FontWeight(0) ? FontWeight(400) : aWeight);
GDIFontEntry *fe = GDIFontEntry::CreateFontEntry(uniqueName,
gfxWindowsFontType(isCFF ? GFX_FONT_TYPE_PS_OPENTYPE : GFX_FONT_TYPE_TRUETYPE) /*type*/,
aStyle, w, aStretch, winUserFontData);
aStyle, aWeight, aStretch, winUserFontData);
if (fe) {
fe->mIsDataUserFont = true;

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

@ -115,7 +115,7 @@ public:
nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr) override;
void FillLogFont(LOGFONTW *aLogFont,
FontWeight aWeight,
LONG aWeight,
gfxFloat aSize);
static gfxWindowsFontType DetermineFontType(const NEWTEXTMETRICW& metrics,
@ -170,13 +170,13 @@ public:
gfxWindowsFontType aFontType,
uint8_t aStyle,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
gfxUserFontData* aUserFontData);
// create a font entry for a font referenced by its fullname
static GDIFontEntry* LoadLocalFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle);
gfxWindowsFontType mFontType;
@ -188,7 +188,7 @@ protected:
friend class gfxGDIFont;
GDIFontEntry(const nsAString& aFaceName, gfxWindowsFontType aFontType,
uint8_t aStyle, FontWeight aWeight, int16_t aStretch,
uint8_t aStyle, FontWeight aWeight, uint16_t aStretch,
gfxUserFontData *aUserFontData);
void InitLogFont(const nsAString& aName, gfxWindowsFontType aFontType);
@ -339,12 +339,12 @@ public:
virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle);
virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle,
const uint8_t* aFontData,
uint32_t aLength);

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

@ -132,12 +132,12 @@ public:
gfxFontEntry* LookupLocalFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle) override;
gfxFontEntry* MakePlatformFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle,
const uint8_t* aFontData,
uint32_t aLength) override;

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

@ -1534,7 +1534,7 @@ gfxMacPlatformFontList::AppleWeightToCSSWeight(int32_t aAppleWeight)
gfxFontEntry*
gfxMacPlatformFontList::LookupLocalFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle)
{
nsAutoreleasePool localPool;
@ -1567,7 +1567,7 @@ static void ReleaseData(void *info, const void *data, size_t size)
gfxFontEntry*
gfxMacPlatformFontList::MakePlatformFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle,
const uint8_t* aFontData,
uint32_t aLength)

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

@ -1759,7 +1759,7 @@ gfxPlatform::IsFontFormatSupported(uint32_t aFormatFlags)
gfxFontEntry*
gfxPlatform::LookupLocalFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle)
{
return gfxPlatformFontList::PlatformFontList()->LookupLocalFont(aFontName,
@ -1771,7 +1771,7 @@ gfxPlatform::LookupLocalFont(const nsAString& aFontName,
gfxFontEntry*
gfxPlatform::MakePlatformFont(const nsAString& aFontName,
FontWeight aWeight,
int16_t aStretch,
uint16_t aStretch,
uint8_t aStyle,
const uint8_t* aFontData,
uint32_t aLength)
@ -2730,7 +2730,14 @@ gfxPlatform::UsesOffMainThreadCompositing()
bool
gfxPlatform::UsesTiling() const
{
return gfxPrefs::LayersTilesEnabled();
bool isSkiaPOMTP = XRE_IsContentProcess() &&
GetDefaultContentBackend() == BackendType::SKIA &&
gfxVars::UseOMTP() &&
(gfxPrefs::LayersOMTPPaintWorkers() == -1 ||
gfxPrefs::LayersOMTPPaintWorkers() > 1);
return gfxPrefs::LayersTilesEnabled() ||
(gfxPrefs::LayersTilesEnabledIfSkiaPOMTP() && isSkiaPOMTP);
}
/***

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