зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland. a=merge CLOSED TREE
This commit is contained in:
Коммит
e7030b9e50
|
@ -94,44 +94,66 @@
|
|||
accesskey="&detailsProgressiveDisclosure.accesskey;"
|
||||
control="detailsExpander"/>
|
||||
</hbox>
|
||||
<listbox id="itemList" rows="7" collapsed="true" persist="collapsed">
|
||||
<listitem label="&itemHistoryAndDownloads.label;"
|
||||
type="checkbox"
|
||||
accesskey="&itemHistoryAndDownloads.accesskey;"
|
||||
preference="privacy.cpd.history"
|
||||
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
|
||||
<listitem label="&itemFormSearchHistory.label;"
|
||||
type="checkbox"
|
||||
accesskey="&itemFormSearchHistory.accesskey;"
|
||||
preference="privacy.cpd.formdata"
|
||||
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
|
||||
<listitem label="&itemCookies.label;"
|
||||
type="checkbox"
|
||||
accesskey="&itemCookies.accesskey;"
|
||||
preference="privacy.cpd.cookies"
|
||||
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
|
||||
<listitem label="&itemCache.label;"
|
||||
type="checkbox"
|
||||
accesskey="&itemCache.accesskey;"
|
||||
preference="privacy.cpd.cache"
|
||||
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
|
||||
<listitem label="&itemActiveLogins.label;"
|
||||
type="checkbox"
|
||||
accesskey="&itemActiveLogins.accesskey;"
|
||||
preference="privacy.cpd.sessions"
|
||||
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
|
||||
<listitem label="&itemOfflineApps.label;"
|
||||
type="checkbox"
|
||||
accesskey="&itemOfflineApps.accesskey;"
|
||||
preference="privacy.cpd.offlineApps"
|
||||
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
|
||||
<listitem label="&itemSitePreferences.label;"
|
||||
type="checkbox"
|
||||
accesskey="&itemSitePreferences.accesskey;"
|
||||
preference="privacy.cpd.siteSettings"
|
||||
noduration="true"
|
||||
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
|
||||
</listbox>
|
||||
|
||||
<vbox id="itemList" collapsed="true" persist="collapsed">
|
||||
<groupbox orient="horizontal">
|
||||
<caption><label>&historySection.label;</label></caption>
|
||||
<grid flex="1">
|
||||
<columns>
|
||||
<column style="width: &sanitizePrefs2.column.width;"/>
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<checkbox label="&itemHistoryAndDownloads.label;"
|
||||
accesskey="&itemHistoryAndDownloads.accesskey;"
|
||||
preference="privacy.cpd.history"
|
||||
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
|
||||
<checkbox label="&itemCookies.label;"
|
||||
accesskey="&itemCookies.accesskey;"
|
||||
preference="privacy.cpd.cookies"
|
||||
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
|
||||
</row>
|
||||
<row>
|
||||
<checkbox label="&itemActiveLogins.label;"
|
||||
accesskey="&itemActiveLogins.accesskey;"
|
||||
preference="privacy.cpd.sessions"
|
||||
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
|
||||
<checkbox label="&itemCache.label;"
|
||||
accesskey="&itemCache.accesskey;"
|
||||
preference="privacy.cpd.cache"
|
||||
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
|
||||
</row>
|
||||
<row>
|
||||
<checkbox label="&itemFormSearchHistory.label;"
|
||||
accesskey="&itemFormSearchHistory.accesskey;"
|
||||
preference="privacy.cpd.formdata"
|
||||
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</groupbox>
|
||||
<groupbox orient="horizontal">
|
||||
<caption><label>&dataSection.label;</label></caption>
|
||||
<grid flex="1">
|
||||
<columns>
|
||||
<column style="width: &sanitizePrefs2.column.width;"/>
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<checkbox label="&itemSitePreferences.label;"
|
||||
accesskey="&itemSitePreferences.accesskey;"
|
||||
preference="privacy.cpd.siteSettings"
|
||||
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
|
||||
<checkbox label="&itemOfflineApps.label;"
|
||||
accesskey="&itemOfflineApps.accesskey;"
|
||||
preference="privacy.cpd.offlineApps"
|
||||
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</groupbox>
|
||||
</vbox>
|
||||
</vbox>
|
||||
</dialog>
|
||||
|
|
|
@ -194,7 +194,7 @@ var gSanitizePromptDialog = {
|
|||
* Check if all of the history items have been selected like the default status.
|
||||
*/
|
||||
hasNonSelectedItems() {
|
||||
let checkboxes = document.querySelectorAll("#itemList > [preference]");
|
||||
let checkboxes = document.querySelectorAll("checkbox[preference]");
|
||||
for (let i = 0; i < checkboxes.length; ++i) {
|
||||
let pref = Preferences.get(checkboxes[i].getAttribute("preference"));
|
||||
if (!pref.value)
|
||||
|
|
|
@ -31,9 +31,9 @@ skip-if = (verify && !debug && (os == 'win'))
|
|||
[browser_tabswitch.js]
|
||||
[browser_toolbariconcolor_restyles.js]
|
||||
[browser_urlbar_keyed_search.js]
|
||||
skip-if = (os == 'linux') || (os == 'win' && debug) || (verify && (os == 'win')) # Disabled on Linux and Windows debug due to perma failures. Bug 1392320.
|
||||
skip-if = (os == 'linux') || (os == 'win' && debug) || (os == 'win' && bits == 32) # Disabled on Linux and Windows debug due to perma failures. Bug 1392320. Disabled on Win32 because of intermittent OOM failures (bug 1448241).
|
||||
[browser_urlbar_search.js]
|
||||
skip-if = (debug || ccov) && (os == 'linux' || os == 'win') || (verify && (os == 'win')) # Disabled on Linux and Windows debug and ccov due to intermittent timeouts. Bug 1414126, bug 1426611.
|
||||
skip-if = (debug || ccov) && (os == 'linux' || os == 'win') || (os == 'win' && bits == 32) # Disabled on Linux and Windows debug and ccov due to intermittent timeouts. Bug 1414126, bug 1426611. Disabled on Win32 because of intermittent OOM failures (bug 1448241).
|
||||
[browser_window_resize.js]
|
||||
[browser_windowclose.js]
|
||||
[browser_windowopen.js]
|
||||
|
|
|
@ -362,12 +362,12 @@ add_task(async function test_cannot_clear_history() {
|
|||
wh.onload = function() {
|
||||
// Check that the relevant checkboxes are enabled
|
||||
var cb = this.win.document.querySelectorAll(
|
||||
"#itemList > [preference='privacy.cpd.formdata']");
|
||||
"checkbox[preference='privacy.cpd.formdata']");
|
||||
ok(cb.length == 1 && !cb[0].disabled, "There is formdata, checkbox to " +
|
||||
"clear formdata should be enabled.");
|
||||
|
||||
cb = this.win.document.querySelectorAll(
|
||||
"#itemList > [preference='privacy.cpd.history']");
|
||||
"checkbox[preference='privacy.cpd.history']");
|
||||
ok(cb.length == 1 && !cb[0].disabled, "There is history, checkbox to " +
|
||||
"clear history should be enabled.");
|
||||
|
||||
|
@ -398,7 +398,7 @@ add_task(async function test_no_formdata_history_to_clear() {
|
|||
"formdata checkbox checked");
|
||||
|
||||
var cb = this.win.document.querySelectorAll(
|
||||
"#itemList > [preference='privacy.cpd.history']");
|
||||
"checkbox[preference='privacy.cpd.history']");
|
||||
ok(cb.length == 1 && !cb[0].disabled && cb[0].checked,
|
||||
"There is no history, but history checkbox should always be enabled " +
|
||||
"and will be checked from previous preference.");
|
||||
|
@ -422,7 +422,7 @@ add_task(async function test_form_entries() {
|
|||
"dialog where you could not clear formdata.");
|
||||
|
||||
var cb = this.win.document.querySelectorAll(
|
||||
"#itemList > [preference='privacy.cpd.formdata']");
|
||||
"checkbox[preference='privacy.cpd.formdata']");
|
||||
|
||||
info("There exists formEntries so the checkbox should be in sync with the pref.");
|
||||
is(cb.length, 1, "There is only one checkbox for form data");
|
||||
|
@ -708,7 +708,7 @@ WindowHelper.prototype = {
|
|||
checkPrefCheckbox(aPrefName, aCheckState) {
|
||||
var pref = "privacy.cpd." + aPrefName;
|
||||
var cb = this.win.document.querySelectorAll(
|
||||
"#itemList > [preference='" + pref + "']");
|
||||
"checkbox[preference='" + pref + "']");
|
||||
is(cb.length, 1, "found checkbox for " + pref + " preference");
|
||||
if (cb[0].checked != aCheckState)
|
||||
cb[0].click();
|
||||
|
@ -718,7 +718,7 @@ WindowHelper.prototype = {
|
|||
* Makes sure all the checkboxes are checked.
|
||||
*/
|
||||
_checkAllCheckboxesCustom(check) {
|
||||
var cb = this.win.document.querySelectorAll("#itemList > [preference]");
|
||||
var cb = this.win.document.querySelectorAll("checkbox[preference]");
|
||||
ok(cb.length > 1, "found checkboxes for preferences");
|
||||
for (var i = 0; i < cb.length; ++i) {
|
||||
var pref = this.win.Preferences.get(cb[i].getAttribute("preference"));
|
||||
|
|
|
@ -4,17 +4,17 @@
|
|||
|
||||
/*** Downloads Panel ***/
|
||||
|
||||
richlistitem[type="download"] {
|
||||
#downloadsListBox > richlistitem {
|
||||
-moz-binding: url('chrome://browser/content/downloads/download.xml#download');
|
||||
}
|
||||
|
||||
richlistitem[type="download"]:not([selected]) button {
|
||||
#downloadsListBox > richlistitem:not([selected]) button {
|
||||
/* Only focus buttons in the selected item. */
|
||||
-moz-user-focus: none;
|
||||
}
|
||||
|
||||
richlistitem[type="download"].download-state[state="1"]:not([exists]) > .downloadButtonArea,
|
||||
richlistitem[type="download"].download-state[state="1"]:not([exists]) > toolbarseparator {
|
||||
#downloadsListBox > richlistitem.download-state[state="1"]:not([exists]) > .downloadButtonArea,
|
||||
#downloadsListBox > richlistitem.download-state[state="1"]:not([exists]) > toolbarseparator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -49,15 +49,15 @@ richlistitem[type="download"].download-state[state="1"]:not([exists]) > toolbars
|
|||
*
|
||||
* We might be able to do away with this workaround once bug 653881 is fixed.
|
||||
*/
|
||||
richlistitem.download {
|
||||
#downloadsRichListBox > richlistitem {
|
||||
-moz-binding: none;
|
||||
}
|
||||
|
||||
richlistitem.download[active] {
|
||||
#downloadsRichListBox > richlistitem[active] {
|
||||
-moz-binding: url("chrome://browser/content/downloads/download.xml#download");
|
||||
}
|
||||
|
||||
richlistitem.download button {
|
||||
#downloadsRichListBox > richlistitem button {
|
||||
/* These buttons should never get focus, as that would "disable"
|
||||
the downloads view controller (it's only used when the richlistbox
|
||||
is focused). */
|
||||
|
|
|
@ -15,9 +15,6 @@
|
|||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl">
|
||||
<binding id="translationbar" extends="chrome://global/content/bindings/notification.xml#notification">
|
||||
<resources>
|
||||
<stylesheet src="chrome://global/skin/notification.css"/>
|
||||
</resources>
|
||||
<content>
|
||||
<xul:hbox anonid="details" align="center" flex="1">
|
||||
<xul:image class="translate-infobar-element messageImage"
|
||||
|
|
|
@ -10,11 +10,6 @@
|
|||
xmlns:xbl="http://www.mozilla.org/xbl">
|
||||
|
||||
<binding id="autocomplete-profile-listitem-base" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
|
||||
<resources>
|
||||
<stylesheet src="chrome://formautofill-shared/skin/autocomplete-item.css"/>
|
||||
<stylesheet src="chrome://formautofill/skin/autocomplete-item.css"/>
|
||||
</resources>
|
||||
|
||||
<implementation implements="nsIDOMXULSelectControlItemElement">
|
||||
<constructor>
|
||||
</constructor>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
%filter substitution
|
||||
|
||||
%define item richlistitem.download
|
||||
%define item #downloadsRichListBox > richlistitem
|
||||
%define itemFocused @item@[selected]
|
||||
|
||||
/*** View and outer controls ***/
|
||||
|
@ -17,7 +17,7 @@
|
|||
|
||||
/*** List items ***/
|
||||
|
||||
#downloadsRichListBox > richlistitem.download {
|
||||
@item@ {
|
||||
height: var(--downloads-item-height);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
%define keyfocus #downloadsPanel[keyfocus]
|
||||
%define notKeyfocus #downloadsPanel:not([keyfocus])
|
||||
%define item richlistitem[type="download"]
|
||||
%define item #downloadsListBox > richlistitem
|
||||
%define itemFinished @item@[state="1"]
|
||||
%define itemNotFinished @item@:not([state="1"])
|
||||
%define itemFocused #downloadsListBox:focus > @item@[selected]
|
||||
|
@ -112,17 +112,17 @@
|
|||
/*** List items and similar elements in the summary ***/
|
||||
|
||||
#downloadsSummary,
|
||||
richlistitem[type="download"] {
|
||||
@item@ {
|
||||
height: var(--downloads-item-height);
|
||||
}
|
||||
|
||||
richlistitem[type="download"] {
|
||||
@item@ {
|
||||
border-bottom: 1px solid var(--panel-separator-color);
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
richlistitem[type="download"]:last-child {
|
||||
@item@:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -1031,7 +1031,7 @@ endif # HOST_RUST_PROGRAMS
|
|||
|
||||
$(SOBJS):
|
||||
$(REPORT_BUILD)
|
||||
$(AS) -o $@ $(SFLAGS) $($(notdir $<)_FLAGS) -c $<
|
||||
$(AS) $(ASOUTOPTION)$@ $(SFLAGS) $($(notdir $<)_FLAGS) -c $<
|
||||
|
||||
$(CPPOBJS):
|
||||
$(REPORT_BUILD_VERBOSE)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
This is the debugger.html project output.
|
||||
See https://github.com/devtools-html/debugger.html
|
||||
|
||||
Version 68
|
||||
Version 69
|
||||
|
||||
Comparison: https://github.com/devtools-html/debugger.html/compare/release-67...release-68
|
||||
Comparison: https://github.com/devtools-html/debugger.html/compare/release-68...release-69
|
||||
|
||||
Packages:
|
||||
- babel-plugin-transform-es2015-modules-commonjs @6.26.2
|
||||
|
|
|
@ -1777,6 +1777,16 @@ menuseparator {
|
|||
fill: var(--theme-textbox-box-shadow);
|
||||
}
|
||||
|
||||
.source-icon.vue {
|
||||
background: url("chrome://devtools/skin/images/debugger/vuejs.svg") 1px 1px no-repeat;
|
||||
background-size: 15px;
|
||||
}
|
||||
|
||||
.source-icon.angular {
|
||||
background: url("chrome://devtools/skin/images/debugger/angular.svg") 1px 1px no-repeat;
|
||||
background-size: 13px 13px;
|
||||
}
|
||||
|
||||
.source-icon.blackBox {
|
||||
mask: url("chrome://devtools/skin/images/debugger/blackBox.svg") no-repeat;
|
||||
mask-size: 100%;
|
||||
|
|
|
@ -1181,6 +1181,7 @@ exports.isAwaitExpression = isAwaitExpression;
|
|||
exports.isYieldExpression = isYieldExpression;
|
||||
exports.isObjectShorthand = isObjectShorthand;
|
||||
exports.getObjectExpressionValue = getObjectExpressionValue;
|
||||
exports.getCode = getCode;
|
||||
exports.getVariableNames = getVariableNames;
|
||||
exports.getComments = getComments;
|
||||
exports.getSpecifiers = getSpecifiers;
|
||||
|
@ -1241,6 +1242,10 @@ function getObjectExpressionValue(node) {
|
|||
return shouldWrap ? `(${code})` : code;
|
||||
}
|
||||
|
||||
function getCode(node) {
|
||||
return (0, _generator2.default)(node).code;
|
||||
}
|
||||
|
||||
function getVariableNames(path) {
|
||||
if (t.isObjectProperty(path.node) && !isFunction(path.node.value)) {
|
||||
if (path.node.key.type === "StringLiteral") {
|
||||
|
@ -1533,10 +1538,14 @@ function extractSymbol(path, symbols) {
|
|||
}
|
||||
|
||||
if (t.isClassDeclaration(path)) {
|
||||
const { loc, superClass } = path.node;
|
||||
symbols.classes.push({
|
||||
name: path.node.id.name,
|
||||
parent: path.node.superClass,
|
||||
location: path.node.loc
|
||||
parent: superClass ? {
|
||||
name: t.isMemberExpression(superClass) ? (0, _helpers.getCode)(superClass) : superClass.name,
|
||||
location: superClass.loc
|
||||
} : null,
|
||||
location: loc
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,9 @@ var parser = _interopRequireWildcard(_parser);
|
|||
|
||||
var _source = require("../../utils/source");
|
||||
|
||||
var _devtoolsModules = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-modules"];
|
||||
var _telemetry = require("devtools/client/shared/telemetry");
|
||||
|
||||
var _telemetry2 = _interopRequireDefault(_telemetry);
|
||||
|
||||
var _defer = require("../../utils/defer");
|
||||
|
||||
|
@ -33,7 +35,7 @@ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj;
|
|||
const requests = new Map(); // Measures the time it takes for a source to load
|
||||
|
||||
const loadSourceHistogram = "DEVTOOLS_DEBUGGER_LOAD_SOURCE_MS";
|
||||
const telemetry = new _devtoolsModules.Telemetry();
|
||||
const telemetry = new _telemetry2.default();
|
||||
|
||||
async function loadSource(source, {
|
||||
sourceMaps,
|
||||
|
|
|
@ -412,16 +412,6 @@ const getSelectedSource = exports.getSelectedSource = (0, _reselect.createSelect
|
|||
return;
|
||||
}
|
||||
|
||||
const source = sources[selectedLocation.sourceId]; // TODO: remove this when the immutable refactor lands in m-c
|
||||
|
||||
if (_devtoolsEnvironment.isTesting) {
|
||||
const testSource = _objectSpread({}, source, {
|
||||
get: field => source[field]
|
||||
});
|
||||
|
||||
return testSource;
|
||||
}
|
||||
|
||||
return source;
|
||||
return sources[selectedLocation.sourceId];
|
||||
});
|
||||
exports.default = update;
|
|
@ -46,7 +46,10 @@ function inComponent(state) {
|
|||
}
|
||||
|
||||
const inReactFile = sourceMetaData.framework == "React";
|
||||
const isComponent = closestClass.parent && ["Component", "PureComponent"].includes(closestClass.parent.name);
|
||||
const {
|
||||
parent
|
||||
} = closestClass;
|
||||
const isComponent = parent && parent.name.includes("Component");
|
||||
|
||||
if (inReactFile && isComponent) {
|
||||
return closestClass.name;
|
||||
|
|
|
@ -37,6 +37,7 @@ DevToolsModules(
|
|||
'source.js',
|
||||
'tabs.js',
|
||||
'task.js',
|
||||
'telemetry.js',
|
||||
'text.js',
|
||||
'timings.js',
|
||||
'ui.js',
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.recordEvent = recordEvent;
|
||||
|
||||
var _telemetry = require("devtools/client/shared/telemetry");
|
||||
|
||||
var _telemetry2 = _interopRequireDefault(_telemetry);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
|
||||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
const telemetry = new _telemetry2.default();
|
||||
/**
|
||||
* @memberof utils/telemetry
|
||||
* @static
|
||||
*/
|
||||
|
||||
function recordEvent(eventName, fields = {}) {
|
||||
let sessionId = -1;
|
||||
|
||||
if (typeof window === "object" && window.parent.frameElement) {
|
||||
sessionId = window.parent.frameElement.getAttribute("session_id");
|
||||
}
|
||||
/* eslint-disable camelcase */
|
||||
|
||||
|
||||
telemetry.recordEvent("devtools.main", eventName, "debugger", null, _objectSpread({
|
||||
session_id: sessionId
|
||||
}, fields));
|
||||
/* eslint-enable camelcase */
|
||||
}
|
|
@ -85,10 +85,17 @@ function extractSymbol(path, symbols) {
|
|||
}
|
||||
|
||||
if (t.isClassDeclaration(path)) {
|
||||
const {
|
||||
loc,
|
||||
superClass
|
||||
} = path.node;
|
||||
symbols.classes.push({
|
||||
name: path.node.id.name,
|
||||
parent: path.node.superClass,
|
||||
location: path.node.loc
|
||||
parent: superClass ? {
|
||||
name: t.isMemberExpression(superClass) ? (0, _helpers.getCode)(superClass) : superClass.name,
|
||||
location: superClass.loc
|
||||
} : null,
|
||||
location: loc
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ exports.isAwaitExpression = isAwaitExpression;
|
|||
exports.isYieldExpression = isYieldExpression;
|
||||
exports.isObjectShorthand = isObjectShorthand;
|
||||
exports.getObjectExpressionValue = getObjectExpressionValue;
|
||||
exports.getCode = getCode;
|
||||
exports.getVariableNames = getVariableNames;
|
||||
exports.getComments = getComments;
|
||||
exports.getSpecifiers = getSpecifiers;
|
||||
|
@ -77,6 +78,10 @@ function getObjectExpressionValue(node) {
|
|||
return shouldWrap ? `(${code})` : code;
|
||||
}
|
||||
|
||||
function getCode(node) {
|
||||
return (0, _generator2.default)(node).code;
|
||||
}
|
||||
|
||||
function getVariableNames(path) {
|
||||
if (t.isObjectProperty(path.node) && !isFunction(path.node.value)) {
|
||||
if (path.node.key.type === "StringLiteral") {
|
||||
|
|
|
@ -56,5 +56,5 @@ add_task(async function() {
|
|||
is(dbg.selectors.getActiveSearch(dbg.getState()), null);
|
||||
|
||||
const selectedSource = dbg.selectors.getSelectedSource(dbg.getState());
|
||||
ok(selectedSource.get("url").includes("switching-01"));
|
||||
ok(selectedSource.url.includes("switching-01"));
|
||||
});
|
||||
|
|
|
@ -49,7 +49,7 @@ add_task(async function() {
|
|||
|
||||
const focusedNode = findElementWithSelector(dbg, ".sources-list .focused");
|
||||
const fourthNode = findElement(dbg, "sourceNode", 4);
|
||||
const selectedSource = getSelectedSource(getState()).get("url");
|
||||
const selectedSource = getSelectedSource(getState()).url;
|
||||
|
||||
ok(fourthNode.classList.contains("focused"), "4th node is focused");
|
||||
ok(selectedSource.includes("nested-source.js"), "nested-source is selected");
|
||||
|
|
|
@ -259,6 +259,7 @@ devtools.jar:
|
|||
skin/images/read-only.svg (themes/images/read-only.svg)
|
||||
|
||||
# Debugger
|
||||
skin/images/debugger/angular.svg (themes/images/debugger/angular.svg)
|
||||
skin/images/debugger/arrow.svg (themes/images/debugger/arrow.svg)
|
||||
skin/images/debugger/back.svg (themes/images/debugger/back.svg)
|
||||
skin/images/debugger/blackBox.svg (themes/images/debugger/blackBox.svg)
|
||||
|
@ -281,6 +282,7 @@ devtools.jar:
|
|||
skin/images/debugger/stepOver.svg (themes/images/debugger/stepOver.svg)
|
||||
skin/images/debugger/tab.svg (themes/images/debugger/tab.svg)
|
||||
skin/images/debugger/typescript.svg (themes/images/debugger/typescript.svg)
|
||||
skin/images/debugger/vuejs.svg (themes/images/debugger/vuejs.svg)
|
||||
|
||||
# Netmonitor
|
||||
content/netmonitor/src/assets/styles/httpi.css (netmonitor/src/assets/styles/httpi.css)
|
||||
|
|
|
@ -65,7 +65,7 @@ async function checkClickOnNode(toolbox, frameLinkNode) {
|
|||
const dbg = await toolbox.getPanelWhenReady("jsdebugger");
|
||||
await waitUntil(() => dbg._selectors.getSelectedSource(dbg._getState()));
|
||||
is(
|
||||
dbg._selectors.getSelectedSource(dbg._getState()).get("url"),
|
||||
dbg._selectors.getSelectedSource(dbg._getState()).url,
|
||||
url,
|
||||
"expected source url"
|
||||
);
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<!-- 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="256px" height="272px" viewBox="0 0 256 272" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
|
||||
<g>
|
||||
<path d="M0.0996108949,45.522179 L125.908171,0.697276265 L255.103502,44.7252918 L234.185214,211.175097 L125.908171,271.140856 L19.3245136,211.971984 L0.0996108949,45.522179 Z" fill="#E23237"></path>
|
||||
<path d="M255.103502,44.7252918 L125.908171,0.697276265 L125.908171,271.140856 L234.185214,211.274708 L255.103502,44.7252918 L255.103502,44.7252918 Z" fill="#B52E31"></path>
|
||||
<path d="M126.107393,32.27393 L126.107393,32.27393 L47.7136187,206.692607 L76.9992218,206.194553 L92.7377432,166.848249 L126.207004,166.848249 L126.306615,166.848249 L163.063035,166.848249 L180.29572,206.692607 L208.286381,207.190661 L126.107393,32.27393 L126.107393,32.27393 Z M126.306615,88.155642 L152.803113,143.5393 L127.402335,143.5393 L126.107393,143.5393 L102.997665,143.5393 L126.306615,88.155642 L126.306615,88.155642 Z" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 1.2 KiB |
|
@ -0,0 +1,31 @@
|
|||
<!-- 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
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 400 400"
|
||||
height="400"
|
||||
width="400"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
version="1.1"><metadata
|
||||
id="metadata8"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs6" /><g
|
||||
transform="matrix(1.3333333,0,0,-1.3333333,0,400)"
|
||||
id="g10"><g
|
||||
transform="translate(178.0626,235.0086)"
|
||||
id="g12"><path
|
||||
id="path14"
|
||||
style="fill:#41b883;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 -22.669,-39.264 -45.338,0 h -75.491 L -22.669,-170.017 75.491,0 Z" /></g><g
|
||||
transform="translate(178.0626,235.0086)"
|
||||
id="g16"><path
|
||||
id="path18"
|
||||
style="fill:#34495e;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 -22.669,-39.264 -45.338,0 H -81.565 L -22.669,-102.01 36.227,0 Z" /></g></g></svg>
|
После Ширина: | Высота: | Размер: 1.4 KiB |
|
@ -63,7 +63,7 @@ async function checkClickOnNode(hud, toolbox, frameLinkNode) {
|
|||
const url = frameLinkNode.getAttribute("data-url");
|
||||
const dbg = toolbox.getPanel("jsdebugger");
|
||||
is(
|
||||
dbg._selectors.getSelectedSource(dbg._getState()).get("url"),
|
||||
dbg._selectors.getSelectedSource(dbg._getState()).url,
|
||||
url,
|
||||
`Debugger is opened at expected source url (${url})`
|
||||
);
|
||||
|
|
|
@ -332,7 +332,7 @@ async function checkClickOnNode(hud, toolbox, frameLinkNode) {
|
|||
|
||||
const dbg = toolbox.getPanel("jsdebugger");
|
||||
is(
|
||||
dbg._selectors.getSelectedSource(dbg._getState()).get("url"),
|
||||
dbg._selectors.getSelectedSource(dbg._getState()).url,
|
||||
url,
|
||||
"expected source url"
|
||||
);
|
||||
|
|
|
@ -472,11 +472,5 @@ AllChildrenIterator::GetPreviousChild()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
StyleChildrenIterator::GetNextChild()
|
||||
{
|
||||
return AllChildrenIterator::GetNextChild();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#define ChildIterator_h
|
||||
|
||||
#include "nsIContent.h"
|
||||
#include "nsIContentInlines.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Iterates over the children on a node. If a child is an insertion point,
|
||||
|
@ -18,8 +20,6 @@
|
|||
* binding's <xbl:content> element.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
class nsIContent;
|
||||
|
||||
|
@ -201,20 +201,34 @@ private:
|
|||
class AllChildrenIterator : private FlattenedChildIterator
|
||||
{
|
||||
public:
|
||||
AllChildrenIterator(const nsIContent* aNode, uint32_t aFlags,
|
||||
bool aStartAtBeginning = true) :
|
||||
FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
|
||||
mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
|
||||
mFlags(aFlags), mPhase(aStartAtBeginning ? eAtBegin : eAtEnd) { }
|
||||
AllChildrenIterator(const nsIContent* aNode,
|
||||
uint32_t aFlags,
|
||||
bool aStartAtBeginning = true)
|
||||
: FlattenedChildIterator(aNode, aFlags, aStartAtBeginning)
|
||||
, mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0)
|
||||
, mFlags(aFlags)
|
||||
, mPhase(aStartAtBeginning ? eAtBegin : eAtEnd)
|
||||
{
|
||||
}
|
||||
|
||||
AllChildrenIterator(AllChildrenIterator&& aOther)
|
||||
: FlattenedChildIterator(std::move(aOther)),
|
||||
mAnonKids(std::move(aOther.mAnonKids)), mAnonKidsIdx(aOther.mAnonKidsIdx),
|
||||
mFlags(aOther.mFlags), mPhase(aOther.mPhase)
|
||||
: FlattenedChildIterator(std::move(aOther))
|
||||
, mAnonKids(std::move(aOther.mAnonKids))
|
||||
, mAnonKidsIdx(aOther.mAnonKidsIdx)
|
||||
, mFlags(aOther.mFlags)
|
||||
, mPhase(aOther.mPhase)
|
||||
#ifdef DEBUG
|
||||
, mMutationGuard(aOther.mMutationGuard)
|
||||
, mMutationGuard(aOther.mMutationGuard)
|
||||
#endif
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
AllChildrenIterator& operator=(AllChildrenIterator&& aOther)
|
||||
{
|
||||
this->~AllChildrenIterator();
|
||||
new (this) AllChildrenIterator(std::move(aOther));
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
~AllChildrenIterator() { MOZ_ASSERT(!mMutationGuard.Mutated(0)); }
|
||||
|
@ -285,16 +299,39 @@ private:
|
|||
class MOZ_NEEDS_MEMMOVABLE_MEMBERS StyleChildrenIterator : private AllChildrenIterator
|
||||
{
|
||||
public:
|
||||
explicit StyleChildrenIterator(const nsIContent* aContent)
|
||||
static nsIContent* GetParent(const nsIContent& aContent)
|
||||
{
|
||||
nsINode* node = aContent.GetFlattenedTreeParentNodeForStyle();
|
||||
return node && node->IsContent() ? node->AsContent() : nullptr;
|
||||
}
|
||||
|
||||
explicit StyleChildrenIterator(const nsIContent* aContent, bool aStartAtBeginning = true)
|
||||
: AllChildrenIterator(aContent,
|
||||
nsIContent::eAllChildren |
|
||||
nsIContent::eSkipDocumentLevelNativeAnonymousContent)
|
||||
nsIContent::eSkipDocumentLevelNativeAnonymousContent,
|
||||
aStartAtBeginning)
|
||||
{
|
||||
MOZ_COUNT_CTOR(StyleChildrenIterator);
|
||||
}
|
||||
|
||||
StyleChildrenIterator(StyleChildrenIterator&& aOther)
|
||||
: AllChildrenIterator(std::move(aOther))
|
||||
{
|
||||
MOZ_COUNT_CTOR(StyleChildrenIterator);
|
||||
}
|
||||
|
||||
StyleChildrenIterator& operator=(StyleChildrenIterator&& aOther)
|
||||
{
|
||||
AllChildrenIterator::operator=(std::move(aOther));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
~StyleChildrenIterator() { MOZ_COUNT_DTOR(StyleChildrenIterator); }
|
||||
|
||||
nsIContent* GetNextChild();
|
||||
using AllChildrenIterator::GetNextChild;
|
||||
using AllChildrenIterator::GetPreviousChild;
|
||||
using AllChildrenIterator::Seek;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef TreeIterator_h
|
||||
#define TreeIterator_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsIContent.h"
|
||||
|
||||
/**
|
||||
* A generic pre-order tree iterator on top of ChildIterator.
|
||||
*
|
||||
* See ChildIterator.h for the kind of iterators you can use as the template
|
||||
* argument for this class.
|
||||
*/
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
template<typename ChildIterator>
|
||||
class MOZ_STACK_CLASS TreeIterator
|
||||
{
|
||||
enum class Direction
|
||||
{
|
||||
Forward,
|
||||
Backwards,
|
||||
};
|
||||
|
||||
template<Direction aDirection>
|
||||
nsIContent* GetNextChild(ChildIterator& aIter)
|
||||
{
|
||||
return aDirection == Direction::Forward
|
||||
? aIter.GetNextChild()
|
||||
: aIter.GetPreviousChild();
|
||||
}
|
||||
|
||||
template<Direction> inline void Advance();
|
||||
template<Direction> inline void AdvanceSkippingChildren();
|
||||
|
||||
public:
|
||||
explicit TreeIterator(nsIContent& aRoot)
|
||||
: mRoot(aRoot)
|
||||
, mCurrent(&aRoot)
|
||||
{
|
||||
}
|
||||
|
||||
nsIContent* GetCurrent() const
|
||||
{
|
||||
return mCurrent;
|
||||
}
|
||||
|
||||
// Note that this keeps the iterator state consistent in case of failure.
|
||||
inline bool Seek(nsIContent&);
|
||||
inline nsIContent* GetNext();
|
||||
inline nsIContent* GetNextSkippingChildren();
|
||||
inline nsIContent* GetPrev();
|
||||
inline nsIContent* GetPrevSkippingChildren();
|
||||
|
||||
private:
|
||||
using IteratorArray = AutoTArray<ChildIterator, 30>;
|
||||
|
||||
nsIContent& mRoot;
|
||||
nsIContent* mCurrent;
|
||||
IteratorArray mParentIterators;
|
||||
};
|
||||
|
||||
template<typename ChildIterator>
|
||||
template<typename TreeIterator<ChildIterator>::Direction aDirection>
|
||||
inline void
|
||||
TreeIterator<ChildIterator>::AdvanceSkippingChildren()
|
||||
{
|
||||
while (true) {
|
||||
if (MOZ_UNLIKELY(mParentIterators.IsEmpty())) {
|
||||
mCurrent = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (nsIContent* nextSibling =
|
||||
GetNextChild<aDirection>(mParentIterators.LastElement())) {
|
||||
mCurrent = nextSibling;
|
||||
return;
|
||||
}
|
||||
mParentIterators.RemoveLastElement();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ChildIterator>
|
||||
inline bool
|
||||
TreeIterator<ChildIterator>::Seek(nsIContent& aContent)
|
||||
{
|
||||
IteratorArray parentIterators;
|
||||
nsIContent* current = &aContent;
|
||||
while (current != &mRoot) {
|
||||
nsIContent* parent = ChildIterator::GetParent(*current);
|
||||
if (!parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ChildIterator children(parent);
|
||||
if (!children.Seek(current)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parentIterators.AppendElement(std::move(children));
|
||||
current = parent;
|
||||
}
|
||||
|
||||
parentIterators.Reverse();
|
||||
|
||||
mParentIterators.Clear();
|
||||
mParentIterators.SwapElements(parentIterators);
|
||||
mCurrent = &aContent;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename ChildIterator>
|
||||
template<typename TreeIterator<ChildIterator>::Direction aDirection>
|
||||
inline void
|
||||
TreeIterator<ChildIterator>::Advance()
|
||||
{
|
||||
MOZ_ASSERT(mCurrent);
|
||||
const bool startAtBeginning = aDirection == Direction::Forward;
|
||||
ChildIterator children(mCurrent, startAtBeginning);
|
||||
if (nsIContent* first = GetNextChild<aDirection>(children)) {
|
||||
mCurrent = first;
|
||||
mParentIterators.AppendElement(std::move(children));
|
||||
return;
|
||||
}
|
||||
|
||||
AdvanceSkippingChildren<aDirection>();
|
||||
}
|
||||
|
||||
template<typename ChildIterator>
|
||||
inline nsIContent*
|
||||
TreeIterator<ChildIterator>::GetNext()
|
||||
{
|
||||
Advance<Direction::Forward>();
|
||||
return GetCurrent();
|
||||
}
|
||||
|
||||
template<typename ChildIterator>
|
||||
inline nsIContent*
|
||||
TreeIterator<ChildIterator>::GetPrev()
|
||||
{
|
||||
Advance<Direction::Backwards>();
|
||||
return GetCurrent();
|
||||
}
|
||||
|
||||
template<typename ChildIterator>
|
||||
inline nsIContent*
|
||||
TreeIterator<ChildIterator>::GetNextSkippingChildren()
|
||||
{
|
||||
AdvanceSkippingChildren<Direction::Forward>();
|
||||
return GetCurrent();
|
||||
}
|
||||
|
||||
template<typename ChildIterator>
|
||||
inline nsIContent*
|
||||
TreeIterator<ChildIterator>::GetPrevSkippingChildren()
|
||||
{
|
||||
AdvanceSkippingChildren<Direction::Backwards>();
|
||||
return GetCurrent();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -104,8 +104,7 @@ WindowNamedPropertiesHandler::getOwnPropDescriptor(JSContext* aCx,
|
|||
}
|
||||
|
||||
// Grab the DOM window.
|
||||
JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, aProxy));
|
||||
nsGlobalWindowInner* win = xpc::WindowOrNull(global);
|
||||
nsGlobalWindowInner* win = xpc::WindowGlobalOrNull(aProxy);
|
||||
if (win->Length() > 0) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> childWin = win->GetChildWindow(str);
|
||||
if (childWin && ShouldExposeChildWindow(str, childWin)) {
|
||||
|
@ -175,7 +174,7 @@ WindowNamedPropertiesHandler::ownPropNames(JSContext* aCx,
|
|||
}
|
||||
|
||||
// Grab the DOM window.
|
||||
nsGlobalWindowInner* win = xpc::WindowOrNull(JS_GetGlobalForObject(aCx, aProxy));
|
||||
nsGlobalWindowInner* win = xpc::WindowGlobalOrNull(aProxy);
|
||||
nsTArray<nsString> names;
|
||||
// The names live on the outer window, which might be null
|
||||
nsGlobalWindowOuter* outer = win->GetOuterWindowInternal();
|
||||
|
|
|
@ -223,6 +223,7 @@ EXPORTS.mozilla.dom += [
|
|||
'Timeout.h',
|
||||
'TimeoutHandler.h',
|
||||
'TimeoutManager.h',
|
||||
'TreeIterator.h',
|
||||
'TreeWalker.h',
|
||||
'WebKitCSSMatrix.h',
|
||||
'WindowOrientationObserver.h',
|
||||
|
|
|
@ -628,6 +628,19 @@ nsAttrAndChildArray::DoSetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet)
|
|||
return MakeMappedUnique(mapped);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAttrAndChildArray::DoUpdateMappedAttrRuleMapper(nsMappedAttributeElement& aElement)
|
||||
{
|
||||
MOZ_ASSERT(mImpl && mImpl->mMappedAttrs, "Should have mapped attrs here!");
|
||||
|
||||
// First two args don't matter if the assert holds.
|
||||
RefPtr<nsMappedAttributes> mapped =
|
||||
GetModifiableMapped(nullptr, nullptr, false);
|
||||
|
||||
mapped->SetRuleMapper(aElement.GetAttributeMappingFunction());
|
||||
|
||||
return MakeMappedUnique(mapped);
|
||||
}
|
||||
|
||||
void
|
||||
nsAttrAndChildArray::Compact()
|
||||
|
|
|
@ -126,6 +126,17 @@ public:
|
|||
return DoSetMappedAttrStyleSheet(aSheet);
|
||||
}
|
||||
|
||||
// Update the rule mapping function on our mapped attributes, if we have any.
|
||||
// We take a nsMappedAttributeElement, not a nsMapRuleToAttributesFunc,
|
||||
// because the latter is defined in a header we can't include here.
|
||||
nsresult UpdateMappedAttrRuleMapper(nsMappedAttributeElement& aElement)
|
||||
{
|
||||
if (!mImpl || !mImpl->mMappedAttrs) {
|
||||
return NS_OK;
|
||||
}
|
||||
return DoUpdateMappedAttrRuleMapper(aElement);
|
||||
}
|
||||
|
||||
void Compact();
|
||||
|
||||
bool CanFitMoreAttrs() const
|
||||
|
@ -224,6 +235,11 @@ private:
|
|||
*/
|
||||
nsresult DoSetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet);
|
||||
|
||||
/**
|
||||
* Guts of UpdateMappedAttrRuleMapper for the case when we have mapped attrs.
|
||||
*/
|
||||
nsresult DoUpdateMappedAttrRuleMapper(nsMappedAttributeElement& aElement);
|
||||
|
||||
struct InternalAttr
|
||||
{
|
||||
nsAttrName mName;
|
||||
|
|
|
@ -2600,12 +2600,7 @@ nsIDocument::IsSynthesized() {
|
|||
bool
|
||||
nsDocument::IsShadowDOMEnabled(JSContext* aCx, JSObject* aObject)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(aCx, aObject);
|
||||
|
||||
JSAutoRealm ar(aCx, obj);
|
||||
JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, obj));
|
||||
nsCOMPtr<nsPIDOMWindowInner> window =
|
||||
do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(global));
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = xpc::WindowGlobalOrNull(aObject);
|
||||
|
||||
nsIDocument* doc = window ? window->GetExtantDoc() : nullptr;
|
||||
if (!doc) {
|
||||
|
|
|
@ -792,8 +792,9 @@ nsChromeOuterWindowProxy::singleton;
|
|||
static JSObject*
|
||||
NewOuterWindowProxy(JSContext *cx, JS::Handle<JSObject*> global, bool isChrome)
|
||||
{
|
||||
MOZ_ASSERT(JS_IsGlobalObject(global));
|
||||
|
||||
JSAutoRealm ar(cx, global);
|
||||
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(global) == global);
|
||||
|
||||
js::WrapperOptions options;
|
||||
options.setClass(&OuterWindowProxyClass);
|
||||
|
@ -1858,7 +1859,7 @@ nsGlobalWindowOuter::SetNewDocument(nsIDocument* aDocument,
|
|||
|
||||
SetWrapper(outerObject);
|
||||
|
||||
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(outerObject) == newInnerGlobal);
|
||||
MOZ_ASSERT(JS::GetNonCCWObjectGlobal(outerObject) == newInnerGlobal);
|
||||
|
||||
// Inform the nsJSContext, which is the canonical holder of the outer.
|
||||
mContext->SetWindowProxy(outerObject);
|
||||
|
|
|
@ -160,7 +160,7 @@ nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx,
|
|||
CycleCollectedJSContext::Get()->MicroTaskLevel());
|
||||
MOZ_ASSERT(mRetValue.isUndefined());
|
||||
|
||||
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aGlobal) == aGlobal);
|
||||
MOZ_ASSERT(JS_IsGlobalObject(aGlobal));
|
||||
if (MOZ_UNLIKELY(!xpc::Scriptability::Get(aGlobal).Allowed())) {
|
||||
mSkip = true;
|
||||
mRv = NS_OK;
|
||||
|
@ -472,8 +472,7 @@ nsJSUtils::CompileModule(JSContext* aCx,
|
|||
|
||||
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
|
||||
MOZ_ASSERT(aSrcBuf.get());
|
||||
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aEvaluationGlobal) ==
|
||||
aEvaluationGlobal);
|
||||
MOZ_ASSERT(JS_IsGlobalObject(aEvaluationGlobal));
|
||||
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx) == aEvaluationGlobal);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(CycleCollectedJSContext::Get() &&
|
||||
|
|
|
@ -56,6 +56,11 @@ public:
|
|||
return mSheet;
|
||||
}
|
||||
|
||||
void SetRuleMapper(nsMapRuleToAttributesFunc aRuleMapper)
|
||||
{
|
||||
mRuleMapper = aRuleMapper;
|
||||
}
|
||||
|
||||
const nsAttrName* NameAt(uint32_t aPos) const
|
||||
{
|
||||
NS_ASSERTION(aPos < mAttrCount, "out-of-bounds");
|
||||
|
|
|
@ -298,7 +298,6 @@ nsRange::nsRange(nsINode* aNode)
|
|||
, mNextStartRef(nullptr)
|
||||
, mNextEndRef(nullptr)
|
||||
, mIsPositioned(false)
|
||||
, mMaySpanAnonymousSubtrees(false)
|
||||
, mIsGenerated(false)
|
||||
, mCalledByJS(false)
|
||||
{
|
||||
|
@ -1147,7 +1146,7 @@ nsRange::IsValidOffset(nsINode* aNode, uint32_t aOffset)
|
|||
|
||||
/* static */
|
||||
nsINode*
|
||||
nsRange::ComputeRootNode(nsINode* aNode, bool aMaySpanAnonymousSubtrees)
|
||||
nsRange::ComputeRootNode(nsINode* aNode)
|
||||
{
|
||||
if (!aNode) {
|
||||
return nullptr;
|
||||
|
@ -1159,36 +1158,30 @@ nsRange::ComputeRootNode(nsINode* aNode, bool aMaySpanAnonymousSubtrees)
|
|||
}
|
||||
|
||||
nsIContent* content = aNode->AsContent();
|
||||
if (!aMaySpanAnonymousSubtrees) {
|
||||
// If the node is in a shadow tree then the ShadowRoot is the root.
|
||||
ShadowRoot* containingShadow = content->GetContainingShadow();
|
||||
if (containingShadow) {
|
||||
return containingShadow;
|
||||
}
|
||||
|
||||
// If the node has a binding parent, that should be the root.
|
||||
// XXXbz maybe only for native anonymous content?
|
||||
nsINode* root = content->GetBindingParent();
|
||||
if (root) {
|
||||
return root;
|
||||
}
|
||||
// If the node is in a shadow tree then the ShadowRoot is the root.
|
||||
if (ShadowRoot* containingShadow = content->GetContainingShadow()) {
|
||||
return containingShadow;
|
||||
}
|
||||
|
||||
// If the node has a binding parent, that should be the root.
|
||||
// XXXbz maybe only for native anonymous content?
|
||||
if (nsINode* root = content->GetBindingParent()) {
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
// Elements etc. must be in document or in document fragment,
|
||||
// text nodes in document, in document fragment or in attribute.
|
||||
nsINode* root = aNode->GetUncomposedDoc();
|
||||
if (root) {
|
||||
if (nsINode* root = aNode->GetUncomposedDoc()) {
|
||||
return root;
|
||||
}
|
||||
|
||||
root = aNode->SubtreeRoot();
|
||||
|
||||
NS_ASSERTION(!root->IsDocument(),
|
||||
NS_ASSERTION(!aNode->SubtreeRoot()->IsDocument(),
|
||||
"GetUncomposedDoc should have returned a doc");
|
||||
|
||||
// We allow this because of backward compatibility.
|
||||
return root;
|
||||
return aNode->SubtreeRoot();
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -1380,7 +1373,7 @@ nsRange::SelectNodesInContainer(nsINode* aContainer,
|
|||
MOZ_ASSERT(aStartContent && aContainer->ComputeIndexOf(aStartContent) != -1);
|
||||
MOZ_ASSERT(aEndContent && aContainer->ComputeIndexOf(aEndContent) != -1);
|
||||
|
||||
nsINode* newRoot = ComputeRootNode(aContainer, mMaySpanAnonymousSubtrees);
|
||||
nsINode* newRoot = ComputeRootNode(aContainer);
|
||||
MOZ_ASSERT(newRoot);
|
||||
if (!newRoot) {
|
||||
return;
|
||||
|
@ -2583,8 +2576,6 @@ nsRange::CloneRange() const
|
|||
{
|
||||
RefPtr<nsRange> range = new nsRange(mOwner);
|
||||
|
||||
range->SetMaySpanAnonymousSubtrees(mMaySpanAnonymousSubtrees);
|
||||
|
||||
range->DoSetRange(mStart.AsRaw(), mEnd.AsRaw(), mRoot);
|
||||
|
||||
return range.forget();
|
||||
|
|
|
@ -120,11 +120,6 @@ public:
|
|||
return mIsPositioned;
|
||||
}
|
||||
|
||||
void SetMaySpanAnonymousSubtrees(bool aMaySpanAnonymousSubtrees)
|
||||
{
|
||||
mMaySpanAnonymousSubtrees = aMaySpanAnonymousSubtrees;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true iff this range is part of a Selection object
|
||||
* and isn't detached.
|
||||
|
@ -389,10 +384,7 @@ public:
|
|||
* fragment. If this returns nullptr, that means aNode can be neither the
|
||||
* start container nor end container of any range.
|
||||
*/
|
||||
static nsINode* ComputeRootNode(nsINode* aNode)
|
||||
{
|
||||
return ComputeRootNode(aNode, false);
|
||||
}
|
||||
static nsINode* ComputeRootNode(nsINode* aNode);
|
||||
|
||||
/**
|
||||
* Return true if aStartContainer/aStartOffset and aEndContainer/aEndOffset
|
||||
|
@ -461,7 +453,7 @@ protected:
|
|||
void UnregisterCommonAncestor(nsINode* aNode, bool aIsUnlinking);
|
||||
nsINode* IsValidBoundary(nsINode* aNode) const
|
||||
{
|
||||
return ComputeRootNode(aNode, mMaySpanAnonymousSubtrees);
|
||||
return ComputeRootNode(aNode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -476,9 +468,6 @@ protected:
|
|||
}
|
||||
static bool IsValidOffset(nsINode* aNode, uint32_t aOffset);
|
||||
|
||||
static nsINode* ComputeRootNode(nsINode* aNode,
|
||||
bool aMaySpanAnonymousSubtrees);
|
||||
|
||||
// CharacterDataChanged set aNotInsertedYet to true to disable an assertion
|
||||
// and suppress re-registering a range common ancestor node since
|
||||
// the new text node of a splitText hasn't been inserted yet.
|
||||
|
@ -566,7 +555,6 @@ protected:
|
|||
RangeBoundary mEnd;
|
||||
|
||||
bool mIsPositioned : 1;
|
||||
bool mMaySpanAnonymousSubtrees : 1;
|
||||
bool mIsGenerated : 1;
|
||||
bool mCalledByJS : 1;
|
||||
};
|
||||
|
|
|
@ -25,7 +25,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558726
|
|||
/** Test for Bug 558726 **/
|
||||
|
||||
function runTest() {
|
||||
is(document.getElementById('test_558726_1').innerHTML, '<select name="selecttest"><option value="0">item 1</option></select>x<input name="test" value="test" type="button">','test_558726_1.innerHTML')
|
||||
is(document.getElementById('test_558726_1').innerHTML, '<select name="selecttest"><option value="0">item 1</option></select>x<input type="button" name="test" value="test">','test_558726_1.innerHTML')
|
||||
is(document.getElementById('test_558726_2').innerHTML, 'y<input><i style="-moz-user-select: none;">z</i>','test_558726_2.innerHTML')
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
|
|
@ -2,13 +2,19 @@
|
|||
<meta charset="utf-8">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
const t = async_test("Test window.find / nsFind");
|
||||
|
||||
function testFindable(isFindable, textToFind, docText, description) {
|
||||
function testFindable(isFindable, textToFind, buildDoc, description) {
|
||||
try{
|
||||
const iframe = document.querySelector("iframe")
|
||||
iframe.contentDocument.documentElement.innerHTML = docText;
|
||||
iframe.contentDocument.documentElement.innerHTML =
|
||||
(typeof buildDoc == "string") ? buildDoc : "";
|
||||
|
||||
if (typeof buildDoc == "function")
|
||||
buildDoc(iframe.contentDocument);
|
||||
|
||||
iframe.contentWindow.getSelection().removeAllRanges();
|
||||
assert_equals(
|
||||
isFindable,
|
||||
|
@ -35,7 +41,7 @@ const BLOCK_LIKE_DISPLAY_VALUES = [
|
|||
"flex",
|
||||
];
|
||||
|
||||
window.runTests = t.step_func_done(function() {
|
||||
let runTests = t.step_func_done(function() {
|
||||
testFindable(true, "me and me", `
|
||||
me <div style="display: contents">and</div> me
|
||||
`, "display: contents");
|
||||
|
@ -77,6 +83,43 @@ window.runTests = t.step_func_done(function() {
|
|||
</div>
|
||||
</div>
|
||||
`);
|
||||
|
||||
testFindable(true, "Shadow text", function(document) {
|
||||
let div = document.createElement("div");
|
||||
div.attachShadow({ mode: "open" }).innerHTML = `
|
||||
Wohoo, this is Shadow text, yay!
|
||||
`;
|
||||
document.documentElement.appendChild(div);
|
||||
}, "In Shadow DOM");
|
||||
|
||||
testFindable(true, "Shadow text", function(document) {
|
||||
let div = document.createElement("div");
|
||||
div.appendChild(document.createTextNode(
|
||||
"Wohoo, this is Shadow text, yay!"
|
||||
));
|
||||
div.attachShadow({ mode: "open" }).innerHTML = `<slot></slot>`;
|
||||
document.documentElement.appendChild(div);
|
||||
}, "Slotted content in Shadow DOM");
|
||||
|
||||
// TODO(emilio): Even though this works (as in, find(..) returns true), the
|
||||
// selection here doesn't end up selecting the shadow content.
|
||||
//
|
||||
// This should work in an ideal world.
|
||||
testFindable(true, "Shadow text", function(document) {
|
||||
let div = document.createElement("div");
|
||||
div.appendChild(document.createTextNode("text, yay!"));
|
||||
div.attachShadow({ mode: "open" }).innerHTML = `This is Shadow <slot></slot>`;
|
||||
document.documentElement.appendChild(div);
|
||||
}, "Mixed shadow and non-shadow text");
|
||||
});
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{"set":[['dom.webcomponents.shadowdom.enabled', true]]},
|
||||
t.step_func(function() {
|
||||
let iframe = document.createElement("iframe");
|
||||
iframe.onload = runTests;
|
||||
iframe.srcdoc = "<!doctype html><html></html>";
|
||||
document.body.appendChild(iframe);
|
||||
}));
|
||||
</script>
|
||||
<iframe onload="runTests()" srcdoc="<!doctype html><html></html>"></iframe>
|
||||
</body>
|
||||
|
|
|
@ -1175,21 +1175,8 @@ XPCOMObjectToJsval(JSContext* cx, JS::Handle<JSObject*> scope,
|
|||
xpcObjectHelper& helper, const nsIID* iid,
|
||||
bool allowNativeWrapper, JS::MutableHandle<JS::Value> rval)
|
||||
{
|
||||
if (!NativeInterface2JSObjectAndThrowIfFailed(cx, scope, rval, helper, iid,
|
||||
allowNativeWrapper)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
JSObject* jsobj = rval.toObjectOrNull();
|
||||
if (jsobj &&
|
||||
js::GetGlobalForObjectCrossCompartment(jsobj) == jsobj) {
|
||||
NS_ASSERTION(js::GetObjectClass(jsobj)->flags & JSCLASS_IS_GLOBAL,
|
||||
"Why did we recreate this wrapper?");
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
return NativeInterface2JSObjectAndThrowIfFailed(cx, scope, rval, helper, iid,
|
||||
allowNativeWrapper);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -2298,9 +2285,8 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg, ErrorResult& aErr
|
|||
const DOMJSClass* domClass = GetDOMClass(aObj);
|
||||
|
||||
// DOM things are always parented to globals.
|
||||
JS::Rooted<JSObject*> oldParent(aCx,
|
||||
js::GetGlobalForObjectCrossCompartment(aObj));
|
||||
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(oldParent) == oldParent);
|
||||
JS::Rooted<JSObject*> oldParent(aCx, JS::GetNonCCWObjectGlobal(aObj));
|
||||
MOZ_ASSERT(JS_IsGlobalObject(oldParent));
|
||||
|
||||
JS::Rooted<JSObject*> newParent(aCx,
|
||||
domClass->mGetAssociatedGlobal(aCx, aObj));
|
||||
|
@ -2430,7 +2416,7 @@ GlobalObject::GlobalObject(JSContext* aCx, JSObject* aObject)
|
|||
}
|
||||
}
|
||||
|
||||
mGlobalJSObject = js::GetGlobalForObjectCrossCompartment(obj);
|
||||
mGlobalJSObject = JS::GetNonCCWObjectGlobal(obj);
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
|
@ -3696,7 +3682,7 @@ GetDesiredProto(JSContext* aCx, const JS::CallArgs& aCallArgs,
|
|||
|
||||
if (protoID != prototypes::id::_ID_Count) {
|
||||
ProtoAndIfaceCache& protoAndIfaceCache =
|
||||
*GetProtoAndIfaceCache(js::GetGlobalForObjectCrossCompartment(newTarget));
|
||||
*GetProtoAndIfaceCache(JS::GetNonCCWObjectGlobal(newTarget));
|
||||
aDesiredProto.set(protoAndIfaceCache.EntrySlotMustExist(protoID));
|
||||
if (newTarget != originalNewTarget) {
|
||||
return JS_WrapObject(aCx, aDesiredProto);
|
||||
|
|
|
@ -196,7 +196,7 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
|
|||
globalObject = win;
|
||||
} else {
|
||||
// No DOM Window. Store the global.
|
||||
JSObject* global = js::GetGlobalForObjectCrossCompartment(realCallback);
|
||||
JSObject* global = JS::GetNonCCWObjectGlobal(realCallback);
|
||||
globalObject = xpc::NativeGlobal(global);
|
||||
MOZ_ASSERT(globalObject);
|
||||
}
|
||||
|
|
|
@ -2234,10 +2234,6 @@ def MakeClearCachedValueNativeName(member):
|
|||
return "ClearCached%sValue" % MakeNativeName(member.identifier.name)
|
||||
|
||||
|
||||
def MakeJSImplClearCachedValueNativeName(member):
|
||||
return "_" + MakeClearCachedValueNativeName(member)
|
||||
|
||||
|
||||
def IDLToCIdentifier(name):
|
||||
return name.replace("-", "_")
|
||||
|
||||
|
@ -2434,17 +2430,6 @@ class MethodDefiner(PropertyDefiner):
|
|||
"flags": "0",
|
||||
"condition": MemberCondition()
|
||||
})
|
||||
elif not unforgeable:
|
||||
for m in clearableCachedAttrs(descriptor):
|
||||
attrName = MakeNativeName(m.identifier.name)
|
||||
self.chrome.append({
|
||||
"name": "_clearCached%sValue" % attrName,
|
||||
"nativeName": MakeJSImplClearCachedValueNativeName(m),
|
||||
"methodInfo": False,
|
||||
"length": "0",
|
||||
"flags": "0",
|
||||
"condition": MemberCondition()
|
||||
})
|
||||
|
||||
self.unforgeable = unforgeable
|
||||
|
||||
|
@ -5409,7 +5394,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||
aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("${sourceDescription}"));
|
||||
return nullptr;
|
||||
}
|
||||
globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
|
||||
globalObj = JS::GetNonCCWObjectGlobal(unwrappedVal);
|
||||
""",
|
||||
sourceDescription=sourceDescription)
|
||||
elif isCallbackReturnValue == "Callback":
|
||||
|
@ -8490,43 +8475,24 @@ class CGAbstractBindingMethod(CGAbstractStaticMethod):
|
|||
CGThing which is already properly indented.
|
||||
|
||||
getThisObj should be code for getting a JSObject* for the binding
|
||||
object. If this is None, we will auto-generate code based on
|
||||
descriptor to do the right thing. "" can be passed in if the
|
||||
binding object is already stored in 'obj'.
|
||||
object. "" can be passed in if the binding object is already stored in
|
||||
'obj'.
|
||||
|
||||
callArgs should be code for getting a JS::CallArgs into a variable
|
||||
called 'args'. This can be "" if there is already such a variable
|
||||
around.
|
||||
"""
|
||||
def __init__(self, descriptor, name, args, unwrapFailureCode=None,
|
||||
getThisObj=None,
|
||||
def __init__(self, descriptor, name, args, getThisObj,
|
||||
callArgs="JS::CallArgs args = JS::CallArgsFromVp(argc, vp);\n"):
|
||||
CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args)
|
||||
|
||||
if unwrapFailureCode is None:
|
||||
self.unwrapFailureCode = 'return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "%s");\n' % descriptor.interface.identifier.name
|
||||
else:
|
||||
self.unwrapFailureCode = unwrapFailureCode
|
||||
self.unwrapFailureCode = 'return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "%s");\n' % descriptor.interface.identifier.name
|
||||
|
||||
if getThisObj == "":
|
||||
self.getThisObj = None
|
||||
else:
|
||||
if getThisObj is None:
|
||||
if descriptor.interface.isOnGlobalProtoChain():
|
||||
ensureCondition = "!args.thisv().isNullOrUndefined() && !args.thisv().isObject()"
|
||||
getThisObj = "args.thisv().isObject() ? &args.thisv().toObject() : js::GetGlobalForObjectCrossCompartment(&args.callee())"
|
||||
else:
|
||||
ensureCondition = "!args.thisv().isObject()"
|
||||
getThisObj = "&args.thisv().toObject()"
|
||||
unwrapFailureCode = self.unwrapFailureCode % {'securityError': 'false'}
|
||||
ensureThisObj = CGIfWrapper(CGGeneric(unwrapFailureCode),
|
||||
ensureCondition)
|
||||
else:
|
||||
ensureThisObj = None
|
||||
self.getThisObj = CGList(
|
||||
[ensureThisObj,
|
||||
CGGeneric("JS::Rooted<JSObject*> obj(cx, %s);\n" %
|
||||
getThisObj)])
|
||||
self.getThisObj = CGGeneric("JS::Rooted<JSObject*> obj(cx, %s);\n" %
|
||||
getThisObj)
|
||||
self.callArgs = callArgs
|
||||
|
||||
def definition_body(self):
|
||||
|
@ -12418,11 +12384,6 @@ class CGDescriptor(CGThing):
|
|||
if descriptor.concrete and descriptor.wrapperCache and not descriptor.proxy:
|
||||
cgThings.append(CGClassObjectMovedHook(descriptor))
|
||||
|
||||
# Generate the _ClearCachedFooValue methods before the property arrays that use them.
|
||||
if descriptor.interface.isJSImplemented():
|
||||
for m in clearableCachedAttrs(descriptor):
|
||||
cgThings.append(CGJSImplClearCachedValueMethod(descriptor, m))
|
||||
|
||||
properties = PropertyArrays(descriptor)
|
||||
cgThings.append(CGGeneric(define=str(properties)))
|
||||
cgThings.append(CGNativeProperties(descriptor, properties))
|
||||
|
@ -13938,11 +13899,7 @@ class CGBindingRoot(CGThing):
|
|||
# interface object might have a ChromeOnly constructor.
|
||||
(desc.interface.hasInterfaceObject() and
|
||||
(desc.interface.isJSImplemented() or
|
||||
(ctor and isChromeOnly(ctor)))) or
|
||||
# JS-implemented interfaces with clearable cached
|
||||
# attrs have chromeonly _clearFoo methods.
|
||||
(desc.interface.isJSImplemented() and
|
||||
any(clearableCachedAttrs(desc))))
|
||||
(ctor and isChromeOnly(ctor)))))
|
||||
|
||||
# XXXkhuey ugly hack but this is going away soon.
|
||||
bindingHeaders['xpcprivate.h'] = webIDLFile.endswith("EventTarget.webidl")
|
||||
|
@ -15130,27 +15087,6 @@ def callbackSetterName(attr, descriptor):
|
|||
descriptor.binaryNameFor(attr.identifier.name))
|
||||
|
||||
|
||||
class CGJSImplClearCachedValueMethod(CGAbstractBindingMethod):
|
||||
def __init__(self, descriptor, attr):
|
||||
if attr.getExtendedAttribute("StoreInSlot"):
|
||||
raise TypeError("[StoreInSlot] is not supported for JS-implemented WebIDL. See bug 1056325.")
|
||||
|
||||
CGAbstractBindingMethod.__init__(self, descriptor,
|
||||
MakeJSImplClearCachedValueNativeName(attr),
|
||||
JSNativeArguments())
|
||||
self.attr = attr
|
||||
|
||||
def generate_code(self):
|
||||
return CGGeneric(fill(
|
||||
"""
|
||||
${bindingNamespace}::${fnName}(self);
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
""",
|
||||
bindingNamespace=toBindingNamespace(self.descriptor.name),
|
||||
fnName=MakeClearCachedValueNativeName(self.attr)))
|
||||
|
||||
|
||||
class CGJSImplGetter(CGJSImplMember):
|
||||
"""
|
||||
Class for generating code for the getters of attributes for a JS-implemented
|
||||
|
|
|
@ -121,7 +121,7 @@ struct PrefableDisablers {
|
|||
// globals; our IDL parser enforces that. So as long as we check our
|
||||
// exposure set before checking "enabled" we will be ok.
|
||||
if (nonExposedGlobals &&
|
||||
IsNonExposedGlobal(cx, js::GetGlobalForObjectCrossCompartment(obj),
|
||||
IsNonExposedGlobal(cx, JS::GetNonCCWObjectGlobal(obj),
|
||||
nonExposedGlobals)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -131,8 +131,7 @@ struct PrefableDisablers {
|
|||
if (secureContext && !IsSecureContextOrObjectIsFromSecureContext(cx, obj)) {
|
||||
return false;
|
||||
}
|
||||
if (enabledFunc &&
|
||||
!enabledFunc(cx, js::GetGlobalForObjectCrossCompartment(obj))) {
|
||||
if (enabledFunc && !enabledFunc(cx, JS::GetNonCCWObjectGlobal(obj))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -1045,6 +1045,12 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
|
|||
(member.getExtendedAttribute("StoreInSlot") or
|
||||
member.getExtendedAttribute("Cached"))) or
|
||||
member.isMaplikeOrSetlike()):
|
||||
if self.isJSImplemented() and not member.isMaplikeOrSetlike():
|
||||
raise WebIDLError("Interface %s is JS-implemented and we "
|
||||
"don't support [Cached] or [StoreInSlot] "
|
||||
"on JS-implemented interfaces" %
|
||||
self.identifier.name,
|
||||
[self.location, member.location])
|
||||
if member.slotIndices is None:
|
||||
member.slotIndices = dict()
|
||||
member.slotIndices[self.identifier.name] = self.totalMembersInSlots
|
||||
|
|
|
@ -23,18 +23,17 @@ TestInterfaceJS.prototype = {
|
|||
this._anyArg = anyArg;
|
||||
this._objectArg = objectArg;
|
||||
this._dictionaryArg = dictionaryArg;
|
||||
this._cachedAttr = 15;
|
||||
},
|
||||
|
||||
get anyArg() { return this._anyArg; },
|
||||
get objectArg() { return this._objectArg; },
|
||||
get dictionaryArg() { return this._dictionaryArg; },
|
||||
getDictionaryArg: function() { return this._dictionaryArg; },
|
||||
get anyAttr() { return this._anyAttr; },
|
||||
set anyAttr(val) { this._anyAttr = val; },
|
||||
get objectAttr() { return this._objectAttr; },
|
||||
set objectAttr(val) { this._objectAttr = val; },
|
||||
get dictionaryAttr() { return this._dictionaryAttr; },
|
||||
set dictionaryAttr(val) { this._dictionaryAttr = val; },
|
||||
getDictionaryAttr: function() { return this._dictionaryAttr; },
|
||||
setDictionaryAttr: function(val) { this._dictionaryAttr = val; },
|
||||
pingPongAny: function(any) { return any; },
|
||||
pingPongObject: function(obj) { return obj; },
|
||||
pingPongObjectOrString: function(objectOrString) { return objectOrString; },
|
||||
|
@ -54,10 +53,6 @@ TestInterfaceJS.prototype = {
|
|||
pingPongNullableUnion: function(x) { return x; },
|
||||
returnBadUnion: function(x) { return 3; },
|
||||
|
||||
get cachedAttr() { return this._cachedAttr; },
|
||||
setCachedAttr: function(n) { this._cachedAttr = n; },
|
||||
clearCachedAttrCache: function () { this.__DOM_IMPL__._clearCachedCachedAttrValue(); },
|
||||
|
||||
testSequenceOverload: function(arg) {},
|
||||
testSequenceUnion: function(arg) {},
|
||||
|
||||
|
|
|
@ -41,12 +41,13 @@ interface TestJSImplInterface {
|
|||
void passNullableByte(byte? arg);
|
||||
void passOptionalNullableByte(optional byte? arg);
|
||||
void passVariadicByte(byte... arg);
|
||||
[Cached, Pure]
|
||||
readonly attribute byte cachedByte;
|
||||
[Cached, Constant]
|
||||
readonly attribute byte cachedConstantByte;
|
||||
[Cached, Pure]
|
||||
attribute byte cachedWritableByte;
|
||||
// [Cached] is not supported in JS-implemented WebIDL.
|
||||
//[Cached, Pure]
|
||||
//readonly attribute byte cachedByte;
|
||||
//[Cached, Constant]
|
||||
//readonly attribute byte cachedConstantByte;
|
||||
//[Cached, Pure]
|
||||
//attribute byte cachedWritableByte;
|
||||
[Affects=Nothing]
|
||||
attribute byte sideEffectFreeByte;
|
||||
[Affects=Nothing, DependsOn=DOMState]
|
||||
|
@ -160,8 +161,9 @@ interface TestJSImplInterface {
|
|||
void passNullableSelf(TestJSImplInterface? arg);
|
||||
attribute TestJSImplInterface nonNullSelf;
|
||||
attribute TestJSImplInterface? nullableSelf;
|
||||
[Cached, Pure]
|
||||
readonly attribute TestJSImplInterface cachedSelf;
|
||||
// [Cached] is not supported in JS-implemented WebIDL.
|
||||
//[Cached, Pure]
|
||||
//readonly attribute TestJSImplInterface cachedSelf;
|
||||
// Optional arguments
|
||||
void passOptionalSelf(optional TestJSImplInterface? arg);
|
||||
void passOptionalNonNullSelf(optional TestJSImplInterface arg);
|
||||
|
@ -230,16 +232,17 @@ interface TestJSImplInterface {
|
|||
void passConsequentialInterface(IndirectlyImplementedInterface arg);
|
||||
|
||||
// Sequence types
|
||||
[Cached, Pure]
|
||||
readonly attribute sequence<long> readonlySequence;
|
||||
[Cached, Pure]
|
||||
readonly attribute sequence<Dict> readonlySequenceOfDictionaries;
|
||||
[Cached, Pure]
|
||||
readonly attribute sequence<Dict>? readonlyNullableSequenceOfDictionaries;
|
||||
[Cached, Pure, Frozen]
|
||||
readonly attribute sequence<long> readonlyFrozenSequence;
|
||||
[Cached, Pure, Frozen]
|
||||
readonly attribute sequence<long>? readonlyFrozenNullableSequence;
|
||||
// [Cached] is not supported in JS-implemented WebIDL.
|
||||
//[Cached, Pure]
|
||||
//readonly attribute sequence<long> readonlySequence;
|
||||
//[Cached, Pure]
|
||||
//readonly attribute sequence<Dict> readonlySequenceOfDictionaries;
|
||||
//[Cached, Pure]
|
||||
//readonly attribute sequence<Dict>? readonlyNullableSequenceOfDictionaries;
|
||||
//[Cached, Pure, Frozen]
|
||||
//readonly attribute sequence<long> readonlyFrozenSequence;
|
||||
//[Cached, Pure, Frozen]
|
||||
//readonly attribute sequence<long>? readonlyFrozenNullableSequence;
|
||||
sequence<long> receiveSequence();
|
||||
sequence<long>? receiveNullableSequence();
|
||||
sequence<long?> receiveSequenceOfNullableInts();
|
||||
|
@ -602,18 +605,19 @@ interface TestJSImplInterface {
|
|||
|
||||
void passDictionary(optional Dict x);
|
||||
void passDictionary2(Dict x);
|
||||
[Cached, Pure]
|
||||
readonly attribute Dict readonlyDictionary;
|
||||
[Cached, Pure]
|
||||
readonly attribute Dict? readonlyNullableDictionary;
|
||||
[Cached, Pure]
|
||||
attribute Dict writableDictionary;
|
||||
[Cached, Pure, Frozen]
|
||||
readonly attribute Dict readonlyFrozenDictionary;
|
||||
[Cached, Pure, Frozen]
|
||||
readonly attribute Dict? readonlyFrozenNullableDictionary;
|
||||
[Cached, Pure, Frozen]
|
||||
attribute Dict writableFrozenDictionary;
|
||||
// [Cached] is not supported in JS-implemented WebIDL.
|
||||
//[Cached, Pure]
|
||||
//readonly attribute Dict readonlyDictionary;
|
||||
//[Cached, Pure]
|
||||
//readonly attribute Dict? readonlyNullableDictionary;
|
||||
//[Cached, Pure]
|
||||
//attribute Dict writableDictionary;
|
||||
//[Cached, Pure, Frozen]
|
||||
//readonly attribute Dict readonlyFrozenDictionary;
|
||||
//[Cached, Pure, Frozen]
|
||||
//readonly attribute Dict? readonlyFrozenNullableDictionary;
|
||||
//[Cached, Pure, Frozen]
|
||||
//attribute Dict writableFrozenDictionary;
|
||||
Dict receiveDictionary();
|
||||
Dict? receiveNullableDictionary();
|
||||
void passOtherDictionary(optional GrandparentDict x);
|
||||
|
@ -854,6 +858,7 @@ interface TestCImplementedInterface2 {
|
|||
[NoInterfaceObject,
|
||||
JSImplementation="@mozilla.org/test-js-impl-interface;2"]
|
||||
interface TestJSImplNoInterfaceObject {
|
||||
[Cached, Pure]
|
||||
readonly attribute byte cachedByte;
|
||||
// [Cached] is not supported in JS-implemented WebIDL.
|
||||
//[Cached, Pure]
|
||||
//readonly attribute byte cachedByte;
|
||||
};
|
||||
|
|
|
@ -20,8 +20,6 @@ support-files =
|
|||
[test_bug862092.html]
|
||||
[test_bug1036214.html]
|
||||
skip-if = debug == false
|
||||
[test_bug963382.html]
|
||||
skip-if = debug == false
|
||||
[test_bug1041646.html]
|
||||
[test_bug1123875.html]
|
||||
[test_barewordGetsWindow.html]
|
||||
|
|
|
@ -48,15 +48,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1036214
|
|||
is(Object.getPrototypeOf(t), TestInterfaceJS.prototype, "Prototype setup works correctly");
|
||||
is(t.anyArg, any, "anyArg is correct");
|
||||
is(t.objectArg, obj, "objectArg is correct");
|
||||
is(t.dictionaryArg.anyMember, 42, "dictionaryArg looks correct");
|
||||
is(t.dictionaryArg.objectMember.answer, 42, "dictionaryArg looks correct");
|
||||
is(t.getDictionaryArg().anyMember, 42, "dictionaryArg looks correct");
|
||||
is(t.getDictionaryArg().objectMember.answer, 42, "dictionaryArg looks correct");
|
||||
t.anyAttr = 2;
|
||||
is(t.anyAttr, 2, "ping-pong any attribute works");
|
||||
t.objAttr = obj2;
|
||||
is(t.objAttr, obj2, "ping-pong object attribute works");
|
||||
t.dictionaryAttr = myDict;
|
||||
is(t.dictionaryAttr.anyMember, 42, "ping-pong dictionary attribute works");
|
||||
is(t.dictionaryAttr.objectMember.answer, 42, "ping-pong dictionary attribute works");
|
||||
t.setDictionaryAttr(myDict);
|
||||
is(t.getDictionaryAttr().anyMember, 42, "ping-pong dictionary works");
|
||||
is(t.getDictionaryAttr().objectMember.answer, 42, "ping-pong dictionary works");
|
||||
|
||||
is(any, t.pingPongAny(any), "ping-pong works with any");
|
||||
is(obj, t.pingPongObject(obj), "ping-pong works with obj");
|
||||
|
@ -88,8 +88,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1036214
|
|||
checkThrows(() => new TestInterfaceJS(undefined, undefined, { innerDictionary: { innerObject: xoObj } }), "inner dict param for constructor");
|
||||
checkThrows(() => t.anyAttr = xoObj, "anyAttr");
|
||||
checkThrows(() => t.objectAttr = xoObj, "objAttr");
|
||||
checkThrows(() => t.dictionaryAttr = { anyMember: xoObj }, "dictionaryAttr any");
|
||||
checkThrows(() => t.dictionaryAttr = { objectMember: xoObj }, "dictionaryAttr object");
|
||||
checkThrows(() => t.setDictionaryAttr({ anyMember: xoObj }), "dictionaryAttr any");
|
||||
checkThrows(() => t.setDictionaryAttr({ objectMember: xoObj }), "dictionaryAttr object");
|
||||
checkThrows(() => t.pingPongAny(xoObj), "pingpong any");
|
||||
checkThrows(() => t.pingPongObject(xoObj), "pingpong obj");
|
||||
checkThrows(() => t.pingPongObjectOrString(xoObj), "pingpong union");
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=963382
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 963382</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for clearing cache attributes in JS-implemented WebIDL implementations. **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, go);
|
||||
|
||||
function go() {
|
||||
var t = new TestInterfaceJS();
|
||||
|
||||
// Test [Cached] attribute clearing.
|
||||
is(t.cachedAttr, 15, "Initial value of number");
|
||||
|
||||
t.setCachedAttr(3);
|
||||
is(t.cachedAttr, 15, "Setting the number on the inner JS object should not affect cached value");
|
||||
|
||||
t.clearCachedAttrCache();
|
||||
is(t.cachedAttr, 3, "Setting the number on the inner JS object should affect cached value after clearing the cache.");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=963382">Mozilla Bug 963382</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -3997,6 +3997,12 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
|
|||
|
||||
CanvasBidiProcessor()
|
||||
: nsBidiPresUtils::BidiProcessor()
|
||||
, mCtx(nullptr)
|
||||
, mFontgrp(nullptr)
|
||||
, mAppUnitsPerDevPixel(0)
|
||||
, mOp(CanvasRenderingContext2D::TextDrawOperation::FILL)
|
||||
, mTextRunFlags()
|
||||
, mDoMeasureBoundingBox(false)
|
||||
{
|
||||
if (Preferences::GetBool(GFX_MISSING_FONTS_NOTIFY_PREF)) {
|
||||
mMissingFonts = new gfxMissingFontRecorder();
|
||||
|
|
|
@ -1012,9 +1012,9 @@ private:
|
|||
realGLboolean mDitherEnabled;
|
||||
realGLboolean mRasterizerDiscardEnabled;
|
||||
realGLboolean mScissorTestEnabled;
|
||||
realGLboolean mDepthTestEnabled;
|
||||
realGLboolean mDepthTestEnabled = 0;
|
||||
realGLboolean mStencilTestEnabled;
|
||||
GLenum mGenerateMipmapHint;
|
||||
GLenum mGenerateMipmapHint = 0;
|
||||
|
||||
bool ValidateCapabilityEnum(GLenum cap, const char* info);
|
||||
realGLboolean* GetStateTrackingSlot(GLenum cap);
|
||||
|
@ -1299,7 +1299,7 @@ protected:
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Vertices Feature (WebGLContextVertices.cpp)
|
||||
GLenum mPrimRestartTypeBytes;
|
||||
GLenum mPrimRestartTypeBytes = 0;
|
||||
|
||||
public:
|
||||
void DrawArrays(GLenum mode, GLint first, GLsizei count) {
|
||||
|
@ -1455,9 +1455,9 @@ protected:
|
|||
template<typename WebGLObjectType>
|
||||
void DeleteWebGLObjectsArray(nsTArray<WebGLObjectType>& array);
|
||||
|
||||
GLuint mActiveTexture;
|
||||
GLenum mDefaultFB_DrawBuffer0;
|
||||
GLenum mDefaultFB_ReadBuffer;
|
||||
GLuint mActiveTexture = 0;
|
||||
GLenum mDefaultFB_DrawBuffer0 = 0;
|
||||
GLenum mDefaultFB_ReadBuffer = 0;
|
||||
|
||||
// glGetError sources:
|
||||
bool mEmitContextLostErrorOnce;
|
||||
|
@ -1470,22 +1470,22 @@ protected:
|
|||
webgl::ShaderValidator* CreateShaderValidator(GLenum shaderType) const;
|
||||
|
||||
// some GL constants
|
||||
uint32_t mGLMaxTextureUnits;
|
||||
uint32_t mGLMaxTextureUnits = 0;
|
||||
|
||||
uint32_t mGLMaxVertexAttribs;
|
||||
uint32_t mGLMaxFragmentUniformVectors;
|
||||
uint32_t mGLMaxVertexUniformVectors;
|
||||
uint32_t mGLMaxVaryingVectors;
|
||||
uint32_t mGLMaxVertexAttribs = 0;
|
||||
uint32_t mGLMaxFragmentUniformVectors = 0;
|
||||
uint32_t mGLMaxVertexUniformVectors = 0;
|
||||
uint32_t mGLMaxVaryingVectors = 0;
|
||||
|
||||
uint32_t mGLMaxTransformFeedbackSeparateAttribs;
|
||||
uint32_t mGLMaxUniformBufferBindings;
|
||||
uint32_t mGLMaxTransformFeedbackSeparateAttribs = 0;
|
||||
uint32_t mGLMaxUniformBufferBindings = 0;
|
||||
|
||||
uint32_t mGLMaxVertexTextureImageUnits;
|
||||
uint32_t mGLMaxFragmentTextureImageUnits;
|
||||
uint32_t mGLMaxCombinedTextureImageUnits;
|
||||
uint32_t mGLMaxVertexTextureImageUnits = 0;
|
||||
uint32_t mGLMaxFragmentTextureImageUnits = 0;
|
||||
uint32_t mGLMaxCombinedTextureImageUnits = 0;
|
||||
|
||||
uint32_t mGLMaxColorAttachments;
|
||||
uint32_t mGLMaxDrawBuffers;
|
||||
uint32_t mGLMaxColorAttachments = 0;
|
||||
uint32_t mGLMaxDrawBuffers = 0;
|
||||
|
||||
uint32_t mGLMaxViewportDims[2];
|
||||
|
||||
|
@ -1500,11 +1500,11 @@ protected:
|
|||
|
||||
// Texture sizes are often not actually the GL values. Let's be explicit that these
|
||||
// are implementation limits.
|
||||
uint32_t mGLMaxTextureSize;
|
||||
uint32_t mGLMaxCubeMapTextureSize;
|
||||
uint32_t mGLMax3DTextureSize;
|
||||
uint32_t mGLMaxArrayTextureLayers;
|
||||
uint32_t mGLMaxRenderbufferSize;
|
||||
uint32_t mGLMaxTextureSize = 0;
|
||||
uint32_t mGLMaxCubeMapTextureSize = 0;
|
||||
uint32_t mGLMax3DTextureSize = 0;
|
||||
uint32_t mGLMaxArrayTextureLayers = 0;
|
||||
uint32_t mGLMaxRenderbufferSize = 0;
|
||||
|
||||
public:
|
||||
GLuint MaxVertexAttribs() const {
|
||||
|
@ -1854,16 +1854,16 @@ protected:
|
|||
WebGLRefPtr<WebGLVertexArray> mDefaultVertexArray;
|
||||
|
||||
// PixelStore parameters
|
||||
uint32_t mPixelStore_UnpackImageHeight;
|
||||
uint32_t mPixelStore_UnpackSkipImages;
|
||||
uint32_t mPixelStore_UnpackRowLength;
|
||||
uint32_t mPixelStore_UnpackSkipRows;
|
||||
uint32_t mPixelStore_UnpackSkipPixels;
|
||||
uint32_t mPixelStore_UnpackAlignment;
|
||||
uint32_t mPixelStore_PackRowLength;
|
||||
uint32_t mPixelStore_PackSkipRows;
|
||||
uint32_t mPixelStore_PackSkipPixels;
|
||||
uint32_t mPixelStore_PackAlignment;
|
||||
uint32_t mPixelStore_UnpackImageHeight = 0;
|
||||
uint32_t mPixelStore_UnpackSkipImages = 0;
|
||||
uint32_t mPixelStore_UnpackRowLength = 0;
|
||||
uint32_t mPixelStore_UnpackSkipRows = 0;
|
||||
uint32_t mPixelStore_UnpackSkipPixels = 0;
|
||||
uint32_t mPixelStore_UnpackAlignment = 0;
|
||||
uint32_t mPixelStore_PackRowLength = 0;
|
||||
uint32_t mPixelStore_PackSkipRows = 0;
|
||||
uint32_t mPixelStore_PackSkipPixels = 0;
|
||||
uint32_t mPixelStore_PackAlignment = 0;
|
||||
|
||||
CheckedUint32 GetUnpackSize(bool isFunc3D, uint32_t width, uint32_t height,
|
||||
uint32_t depth, uint8_t bytesPerPixel);
|
||||
|
@ -1872,10 +1872,10 @@ protected:
|
|||
uint8_t bytesPerPixel, uint32_t* const out_rowStride,
|
||||
uint32_t* const out_endOffset);
|
||||
|
||||
GLenum mPixelStore_ColorspaceConversion;
|
||||
bool mPixelStore_FlipY;
|
||||
bool mPixelStore_PremultiplyAlpha;
|
||||
bool mPixelStore_RequireFastPath;
|
||||
GLenum mPixelStore_ColorspaceConversion = 0;
|
||||
bool mPixelStore_FlipY = false;
|
||||
bool mPixelStore_PremultiplyAlpha = false;
|
||||
bool mPixelStore_RequireFastPath = false;
|
||||
|
||||
////////////////////////////////////
|
||||
class FakeBlackTexture {
|
||||
|
@ -1915,26 +1915,26 @@ protected:
|
|||
uint8_t mGenericVertexAttrib0Data[sizeof(float) * 4];
|
||||
CacheMapInvalidator mGenericVertexAttribTypeInvalidator;
|
||||
|
||||
GLuint mFakeVertexAttrib0BufferObject;
|
||||
size_t mFakeVertexAttrib0BufferObjectSize;
|
||||
bool mFakeVertexAttrib0DataDefined;
|
||||
GLuint mFakeVertexAttrib0BufferObject = 0;
|
||||
size_t mFakeVertexAttrib0BufferObjectSize = 0;
|
||||
bool mFakeVertexAttrib0DataDefined = false;
|
||||
uint8_t mFakeVertexAttrib0Data[sizeof(float) * 4];
|
||||
|
||||
JSObject* GetVertexAttribFloat32Array(JSContext* cx, GLuint index);
|
||||
JSObject* GetVertexAttribInt32Array(JSContext* cx, GLuint index);
|
||||
JSObject* GetVertexAttribUint32Array(JSContext* cx, GLuint index);
|
||||
|
||||
GLint mStencilRefFront;
|
||||
GLint mStencilRefBack;
|
||||
GLuint mStencilValueMaskFront;
|
||||
GLuint mStencilValueMaskBack;
|
||||
GLuint mStencilWriteMaskFront;
|
||||
GLuint mStencilWriteMaskBack;
|
||||
uint8_t mColorWriteMask; // bitmask
|
||||
realGLboolean mDepthWriteMask;
|
||||
GLint mStencilRefFront = 0;
|
||||
GLint mStencilRefBack = 0;
|
||||
GLuint mStencilValueMaskFront = 0;
|
||||
GLuint mStencilValueMaskBack = 0;
|
||||
GLuint mStencilWriteMaskFront = 0;
|
||||
GLuint mStencilWriteMaskBack = 0;
|
||||
uint8_t mColorWriteMask = 0; // bitmask
|
||||
realGLboolean mDepthWriteMask = 0;
|
||||
GLfloat mColorClearValue[4];
|
||||
GLint mStencilClearValue;
|
||||
GLfloat mDepthClearValue;
|
||||
GLint mStencilClearValue = 0;
|
||||
GLfloat mDepthClearValue = 0.0;
|
||||
|
||||
GLint mViewportX;
|
||||
GLint mViewportY;
|
||||
|
@ -1942,7 +1942,7 @@ protected:
|
|||
GLsizei mViewportHeight;
|
||||
bool mAlreadyWarnedAboutViewportLargerThanDest;
|
||||
|
||||
GLfloat mLineWidth;
|
||||
GLfloat mLineWidth = 0.0;
|
||||
|
||||
WebGLContextLossHandler mContextLossHandler;
|
||||
bool mAllowContextRestore;
|
||||
|
@ -1969,13 +1969,13 @@ protected:
|
|||
bool mNeedsFakeNoAlpha;
|
||||
bool mNeedsFakeNoDepth;
|
||||
bool mNeedsFakeNoStencil;
|
||||
bool mNeedsFakeNoStencil_UserFBs;
|
||||
bool mNeedsFakeNoStencil_UserFBs = false;
|
||||
|
||||
mutable uint8_t mDriverColorMask;
|
||||
bool mDriverDepthTest;
|
||||
bool mDriverStencilTest;
|
||||
mutable uint8_t mDriverColorMask = 0;
|
||||
bool mDriverDepthTest = false;
|
||||
bool mDriverStencilTest = false;
|
||||
|
||||
bool mNeedsIndexValidation;
|
||||
bool mNeedsIndexValidation = false;
|
||||
|
||||
const bool mAllowFBInvalidation;
|
||||
|
||||
|
@ -1986,7 +1986,7 @@ protected:
|
|||
const uint8_t mMsaaSamples;
|
||||
mutable gfx::IntSize mRequestedSize;
|
||||
mutable UniquePtr<gl::MozFramebuffer> mDefaultFB;
|
||||
mutable bool mDefaultFB_IsInvalid;
|
||||
mutable bool mDefaultFB_IsInvalid = false;
|
||||
mutable UniquePtr<gl::MozFramebuffer> mResolvedDefaultFB;
|
||||
|
||||
// --
|
||||
|
|
|
@ -122,9 +122,7 @@ private:
|
|||
|
||||
public:
|
||||
StrongGLenum()
|
||||
#ifdef DEBUG
|
||||
: mValue(NonexistantGLenum)
|
||||
#endif
|
||||
{
|
||||
AssertOnceThatEnumValuesAreSorted();
|
||||
}
|
||||
|
|
|
@ -139,6 +139,7 @@ WebGLTexture::WebGLTexture(WebGLContext* webgl, GLuint tex)
|
|||
, mMaxMipmapLevel(1000)
|
||||
, mTexCompareMode(LOCAL_GL_NONE)
|
||||
, mIsResolved(false)
|
||||
, mResolved_FakeBlack(FakeBlackType::None)
|
||||
, mResolved_Swizzle(nullptr)
|
||||
{
|
||||
mContext->mTextures.insertBack(this);
|
||||
|
|
|
@ -53,6 +53,15 @@ public:
|
|||
WebGLVertexAttribData()
|
||||
: mDivisor(0)
|
||||
, mEnabled(false)
|
||||
, mIntegerFunc(false)
|
||||
, mType(0)
|
||||
, mBaseType(0)
|
||||
, mSize(0)
|
||||
, mBytesPerVertex(0)
|
||||
, mNormalized(false)
|
||||
, mStride(0)
|
||||
, mExplicitStride(0)
|
||||
, mByteOffset(0)
|
||||
{
|
||||
VertexAttribPointer(false, nullptr, 4, LOCAL_GL_FLOAT, false, 0, 0);
|
||||
}
|
||||
|
|
|
@ -4832,18 +4832,26 @@ HTMLInputElement::HandleTypeChange(uint8_t aNewType, bool aNotify)
|
|||
// We're no longer an image input. Cancel our image requests, if we have
|
||||
// any.
|
||||
CancelImageRequests(aNotify);
|
||||
} else if (aNotify && mType == NS_FORM_INPUT_IMAGE) {
|
||||
// We just got switched to be an image input; we should see
|
||||
// whether we have an image to load;
|
||||
nsAutoString src;
|
||||
if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
|
||||
// Mark channel as urgent-start before load image if the image load is
|
||||
// initaiated by a user interaction.
|
||||
mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
|
||||
|
||||
LoadImage(src, false, aNotify, eImageLoadType_Normal,
|
||||
mSrcTriggeringPrincipal);
|
||||
// And we should update our mapped attribute mapping function.
|
||||
mAttrsAndChildren.UpdateMappedAttrRuleMapper(*this);
|
||||
} else if (mType == NS_FORM_INPUT_IMAGE) {
|
||||
if (aNotify) {
|
||||
// We just got switched to be an image input; we should see
|
||||
// whether we have an image to load;
|
||||
nsAutoString src;
|
||||
if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
|
||||
// Mark channel as urgent-start before load image if the image load is
|
||||
// initaiated by a user interaction.
|
||||
mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
|
||||
|
||||
LoadImage(src, false, aNotify, eImageLoadType_Normal,
|
||||
mSrcTriggeringPrincipal);
|
||||
}
|
||||
}
|
||||
|
||||
// And we should update our mapped attribute mapping function.
|
||||
mAttrsAndChildren.UpdateMappedAttrRuleMapper(*this);
|
||||
}
|
||||
|
||||
if (mType == NS_FORM_INPUT_PASSWORD && IsInComposedDoc()) {
|
||||
|
@ -5595,18 +5603,14 @@ HTMLInputElement::ParseAttribute(int32_t aNamespaceID,
|
|||
}
|
||||
|
||||
void
|
||||
HTMLInputElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations& aDecls)
|
||||
HTMLInputElement::ImageInputMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations& aDecls)
|
||||
{
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::type);
|
||||
if (value && value->Type() == nsAttrValue::eEnum &&
|
||||
value->GetEnumValue() == NS_FORM_INPUT_IMAGE) {
|
||||
nsGenericHTMLFormElementWithState::MapImageBorderAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLFormElementWithState::MapImageMarginAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLFormElementWithState::MapImageSizeAttributesInto(aAttributes, aDecls);
|
||||
// Images treat align as "float"
|
||||
nsGenericHTMLFormElementWithState::MapImageAlignAttributeInto(aAttributes, aDecls);
|
||||
}
|
||||
nsGenericHTMLFormElementWithState::MapImageBorderAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLFormElementWithState::MapImageMarginAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLFormElementWithState::MapImageSizeAttributesInto(aAttributes, aDecls);
|
||||
// Images treat align as "float"
|
||||
nsGenericHTMLFormElementWithState::MapImageAlignAttributeInto(aAttributes, aDecls);
|
||||
|
||||
nsGenericHTMLFormElementWithState::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
}
|
||||
|
@ -5645,7 +5649,6 @@ HTMLInputElement::IsAttributeMapped(const nsAtom* aAttribute) const
|
|||
{
|
||||
static const MappedAttributeEntry attributes[] = {
|
||||
{ &nsGkAtoms::align },
|
||||
{ &nsGkAtoms::type },
|
||||
{ nullptr },
|
||||
};
|
||||
|
||||
|
@ -5662,7 +5665,15 @@ HTMLInputElement::IsAttributeMapped(const nsAtom* aAttribute) const
|
|||
nsMapRuleToAttributesFunc
|
||||
HTMLInputElement::GetAttributeMappingFunction() const
|
||||
{
|
||||
return &MapAttributesIntoRule;
|
||||
// GetAttributeChangeHint guarantees that changes to mType will trigger a
|
||||
// reframe, and we update the mapping function in our mapped attrs when our
|
||||
// type changes, so it's safe to condition our attribute mapping function on
|
||||
// mType.
|
||||
if (mType == NS_FORM_INPUT_IMAGE) {
|
||||
return &ImageInputMapAttributesIntoRule;
|
||||
}
|
||||
|
||||
return &MapCommonAttributesInto;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1666,8 +1666,8 @@ protected:
|
|||
bool mHasPatternAttribute : 1;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void ImageInputMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
|
||||
/**
|
||||
* Returns true if this input's type will fire a DOM "change" event when it
|
||||
|
|
|
@ -263,8 +263,7 @@ IDBFactory::CreateForJSInternal(JSContext* aCx,
|
|||
MOZ_ASSERT(aPrincipalInfo);
|
||||
MOZ_ASSERT(aPrincipalInfo->type() != PrincipalInfo::T__None);
|
||||
MOZ_ASSERT(aFactory);
|
||||
MOZ_ASSERT(JS_GetGlobalForObject(aCx, aOwningObject) == aOwningObject,
|
||||
"Not a global object!");
|
||||
MOZ_ASSERT(JS_IsGlobalObject(aOwningObject));
|
||||
|
||||
if (aPrincipalInfo->type() != PrincipalInfo::TContentPrincipalInfo &&
|
||||
aPrincipalInfo->type() != PrincipalInfo::TSystemPrincipalInfo) {
|
||||
|
|
|
@ -563,10 +563,13 @@ nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType,
|
|||
*outAllowsInline = false;
|
||||
}
|
||||
nsAutoString violatedDirective;
|
||||
mPolicies[i]->getDirectiveStringForContentType(aContentType, violatedDirective);
|
||||
bool reportSample = false;
|
||||
mPolicies[i]->getDirectiveStringAndReportSampleForContentType(aContentType,
|
||||
violatedDirective,
|
||||
&reportSample);
|
||||
reportInlineViolation(aContentType,
|
||||
aNonce,
|
||||
content,
|
||||
reportSample ? content : EmptyString(),
|
||||
violatedDirective,
|
||||
i,
|
||||
aLineNumber,
|
||||
|
@ -613,13 +616,16 @@ nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType,
|
|||
keyword, nonceOrHash, false)) \
|
||||
{ \
|
||||
nsAutoString violatedDirective; \
|
||||
mPolicies[p]->getDirectiveStringForContentType( \
|
||||
bool reportSample = false; \
|
||||
mPolicies[p]->getDirectiveStringAndReportSampleForContentType( \
|
||||
nsIContentPolicy::TYPE_ ## contentPolicyType, \
|
||||
violatedDirective); \
|
||||
violatedDirective, &reportSample); \
|
||||
this->AsyncReportViolation(selfISupports, nullptr, violatedDirective, p, \
|
||||
NS_LITERAL_STRING(observerTopic), \
|
||||
aSourceFile, aScriptSample, aLineNum, \
|
||||
aColumnNum); \
|
||||
aSourceFile, \
|
||||
reportSample \
|
||||
? aScriptSample : EmptyString(), \
|
||||
aLineNum, aColumnNum); \
|
||||
} \
|
||||
PR_END_MACRO; \
|
||||
break
|
||||
|
@ -1001,7 +1007,7 @@ nsCSPContext::SendReports(
|
|||
report.mCsp_report.mLine_number.Value() = aViolationEventInit.mLineNumber;
|
||||
}
|
||||
|
||||
if (aViolationEventInit.mLineNumber != 0) {
|
||||
if (aViolationEventInit.mColumnNumber != 0) {
|
||||
report.mCsp_report.mColumn_number.Construct();
|
||||
report.mCsp_report.mColumn_number.Value() = aViolationEventInit.mColumnNumber;
|
||||
}
|
||||
|
@ -1265,7 +1271,7 @@ class CSPReportSenderRunnable final : public Runnable
|
|||
rv = blockedURI->SchemeIs("data", &isData);
|
||||
if (NS_SUCCEEDED(rv) && isData) {
|
||||
blockedDataStr.Truncate(40);
|
||||
blockedDataStr.AppendASCII("...");
|
||||
blockedDataStr.AppendASCII("…");
|
||||
}
|
||||
}
|
||||
} else if (blockedString) {
|
||||
|
|
|
@ -482,6 +482,10 @@ nsCSPParser::keywordSource()
|
|||
return CSP_CreateHostSrcFromSelfURI(mSelfURI);
|
||||
}
|
||||
|
||||
if (CSP_IsKeyword(mCurToken, CSP_REPORT_SAMPLE)) {
|
||||
return new nsCSPKeywordSrc(CSP_UTF16KeywordToEnum(mCurToken));
|
||||
}
|
||||
|
||||
if (CSP_IsKeyword(mCurToken, CSP_STRICT_DYNAMIC)) {
|
||||
// make sure strict dynamic is enabled
|
||||
if (!sStrictDynamicEnabled) {
|
||||
|
@ -800,9 +804,10 @@ nsCSPParser::sourceList(nsTArray<nsCSPBaseSrc*>& outSrcs)
|
|||
// Check if the directive contains a 'none'
|
||||
if (isNone) {
|
||||
// If the directive contains no other srcs, then we set the 'none'
|
||||
if (outSrcs.Length() == 0) {
|
||||
if (outSrcs.IsEmpty() ||
|
||||
(outSrcs.Length() == 1 && outSrcs[0]->isReportSample())) {
|
||||
nsCSPKeywordSrc *keyword = new nsCSPKeywordSrc(CSP_NONE);
|
||||
outSrcs.AppendElement(keyword);
|
||||
outSrcs.InsertElementAt(0, keyword);
|
||||
}
|
||||
// Otherwise, we ignore 'none' and report a warning
|
||||
else {
|
||||
|
@ -1150,9 +1155,10 @@ nsCSPParser::directive()
|
|||
|
||||
// If we can not parse any srcs; we let the source expression be the empty set ('none')
|
||||
// see, http://www.w3.org/TR/CSP11/#source-list-parsing
|
||||
if (srcs.Length() == 0) {
|
||||
if (srcs.IsEmpty() ||
|
||||
(srcs.Length() == 1 && srcs[0]->isReportSample())) {
|
||||
nsCSPKeywordSrc *keyword = new nsCSPKeywordSrc(CSP_NONE);
|
||||
srcs.AppendElement(keyword);
|
||||
srcs.InsertElementAt(0, keyword);
|
||||
}
|
||||
|
||||
// If policy contains 'strict-dynamic' invalidate all srcs within script-src.
|
||||
|
|
|
@ -1264,6 +1264,18 @@ nsCSPDirective::getDirName(nsAString& outStr) const
|
|||
outStr.AppendASCII(CSP_CSPDirectiveToString(mDirective));
|
||||
}
|
||||
|
||||
bool
|
||||
nsCSPDirective::hasReportSampleKeyword() const
|
||||
{
|
||||
for (nsCSPBaseSrc* src : mSrcs) {
|
||||
if (src->isReportSample()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* =============== nsCSPChildSrcDirective ============= */
|
||||
|
||||
nsCSPChildSrcDirective::nsCSPChildSrcDirective(CSPDirective aDirective)
|
||||
|
@ -1614,13 +1626,18 @@ nsCSPPolicy::hasDirective(CSPDirective aDir) const
|
|||
* for the ::permits() function family.
|
||||
*/
|
||||
void
|
||||
nsCSPPolicy::getDirectiveStringForContentType(nsContentPolicyType aContentType,
|
||||
nsAString& outDirective) const
|
||||
nsCSPPolicy::getDirectiveStringAndReportSampleForContentType(nsContentPolicyType aContentType,
|
||||
nsAString& outDirective,
|
||||
bool* aReportSample) const
|
||||
{
|
||||
MOZ_ASSERT(aReportSample);
|
||||
*aReportSample = false;
|
||||
|
||||
nsCSPDirective* defaultDir = nullptr;
|
||||
for (uint32_t i = 0; i < mDirectives.Length(); i++) {
|
||||
if (mDirectives[i]->restrictsContentType(aContentType)) {
|
||||
mDirectives[i]->getDirName(outDirective);
|
||||
*aReportSample = mDirectives[i]->hasReportSampleKeyword();
|
||||
return;
|
||||
}
|
||||
if (mDirectives[i]->isDefaultDirective()) {
|
||||
|
@ -1631,6 +1648,7 @@ nsCSPPolicy::getDirectiveStringForContentType(nsContentPolicyType aContentType,
|
|||
// the contentType must be restricted by the default directive
|
||||
if (defaultDir) {
|
||||
defaultDir->getDirName(outDirective);
|
||||
*aReportSample = defaultDir->hasReportSampleKeyword();
|
||||
return;
|
||||
}
|
||||
NS_ASSERTION(false, "Can not query directive string for contentType!");
|
||||
|
|
|
@ -126,6 +126,7 @@ inline CSPDirective CSP_StringToCSPDirective(const nsAString& aDir)
|
|||
macro(CSP_NONE, "'none'") \
|
||||
macro(CSP_NONCE, "'nonce-") \
|
||||
macro(CSP_REQUIRE_SRI_FOR, "require-sri-for") \
|
||||
macro(CSP_REPORT_SAMPLE, "'report-sample'") \
|
||||
macro(CSP_STRICT_DYNAMIC, "'strict-dynamic'")
|
||||
|
||||
enum CSPKeyword {
|
||||
|
@ -238,6 +239,9 @@ class nsCSPBaseSrc {
|
|||
virtual void invalidate() const
|
||||
{ mInvalidated = true; }
|
||||
|
||||
virtual bool isReportSample() const
|
||||
{ return false; }
|
||||
|
||||
protected:
|
||||
// invalidate srcs if 'script-dynamic' is present or also invalidate
|
||||
// unsafe-inline' if nonce- or hash-source specified
|
||||
|
@ -336,6 +340,8 @@ class nsCSPKeywordSrc : public nsCSPBaseSrc {
|
|||
}
|
||||
}
|
||||
|
||||
bool isReportSample() const override
|
||||
{ return mKeyword == CSP_REPORT_SAMPLE; }
|
||||
private:
|
||||
CSPKeyword mKeyword;
|
||||
};
|
||||
|
@ -475,6 +481,8 @@ class nsCSPDirective {
|
|||
|
||||
virtual void getDirName(nsAString& outStr) const;
|
||||
|
||||
bool hasReportSampleKeyword() const;
|
||||
|
||||
protected:
|
||||
CSPDirective mDirective;
|
||||
nsTArray<nsCSPBaseSrc*> mSrcs;
|
||||
|
@ -678,8 +686,9 @@ class nsCSPPolicy {
|
|||
|
||||
void getReportURIs(nsTArray<nsString> &outReportURIs) const;
|
||||
|
||||
void getDirectiveStringForContentType(nsContentPolicyType aContentType,
|
||||
nsAString& outDirective) const;
|
||||
void getDirectiveStringAndReportSampleForContentType(nsContentPolicyType aContentType,
|
||||
nsAString& outDirective,
|
||||
bool* aReportSample) const;
|
||||
|
||||
void getDirectiveAsString(CSPDirective aDir, nsAString& outDirective) const;
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Content-Security-Policy: default-src 'self'; img-src 'none'
|
||||
Content-Security-Policy: default-src 'self' 'report-sample'; img-src 'none' 'report-sample'
|
||||
|
|
|
@ -32,7 +32,7 @@ SpecialPowers.registerConsoleListener(function ConsoleMsgListener(aMsg) {
|
|||
data_uri = "";
|
||||
data_uri = aMsg.message.substr(data_start);
|
||||
// this will either match the elipsis after the URI or the . at the end of the message
|
||||
data_uri = data_uri.substr(0, data_uri.indexOf("."));
|
||||
data_uri = data_uri.substr(0, data_uri.indexOf("…"));
|
||||
if (data_uri == "") {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -29,10 +29,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=548193
|
|||
|
||||
const testfile = "tests/dom/security/test/csp/file_report.html";
|
||||
const reportURI = "http://mochi.test:8888/foo.sjs";
|
||||
const policy = "default-src 'none'; report-uri " + reportURI;
|
||||
const policy = "default-src 'none' 'report-sample'; report-uri " + reportURI;
|
||||
const docUri = "http://mochi.test:8888/tests/dom/security/test/csp/file_testserver.sjs" +
|
||||
"?file=tests/dom/security/test/csp/file_report.html" +
|
||||
"&csp=default-src%20%27none%27%3B%20report-uri%20http%3A//mochi.test%3A8888/foo.sjs";
|
||||
"&csp=default-src%20%27none%27%20%27report-sample%27%3B%20report-uri%20http%3A//mochi.test%3A8888/foo.sjs";
|
||||
|
||||
window.checkResults = function(reportObj) {
|
||||
var cspReport = reportObj["csp-report"];
|
||||
|
@ -52,7 +52,7 @@ window.checkResults = function(reportObj) {
|
|||
|
||||
is(cspReport["violated-directive"], "default-src", "Incorrect violated-directive");
|
||||
|
||||
is(cspReport["original-policy"], "default-src 'none'; report-uri http://mochi.test:8888/foo.sjs",
|
||||
is(cspReport["original-policy"], "default-src 'none' 'report-sample'; report-uri http://mochi.test:8888/foo.sjs",
|
||||
"Incorrect original-policy");
|
||||
|
||||
is(cspReport["source-file"], docUri, "Incorrect source-file");
|
||||
|
|
|
@ -70,7 +70,7 @@ function makeTest(id, expectedJSON, useReportOnlyPolicy, callback) {
|
|||
// set up a new CSP instance for each test.
|
||||
var csp = Cc["@mozilla.org/cspcontext;1"]
|
||||
.createInstance(Ci.nsIContentSecurityPolicy);
|
||||
var policy = "default-src 'none'; " +
|
||||
var policy = "default-src 'none' 'report-sample'; " +
|
||||
"report-uri " + REPORT_SERVER_URI +
|
||||
":" + REPORT_SERVER_PORT +
|
||||
"/test" + id;
|
||||
|
|
|
@ -15,10 +15,11 @@ dictionary TestInterfaceJSUnionableDictionary {
|
|||
interface TestInterfaceJS : EventTarget {
|
||||
readonly attribute any anyArg;
|
||||
readonly attribute object objectArg;
|
||||
[Cached, Pure] readonly attribute TestInterfaceJSDictionary dictionaryArg;
|
||||
TestInterfaceJSDictionary getDictionaryArg();
|
||||
attribute any anyAttr;
|
||||
attribute object objectAttr;
|
||||
[Cached, Pure] attribute TestInterfaceJSDictionary dictionaryAttr;
|
||||
TestInterfaceJSDictionary getDictionaryAttr();
|
||||
void setDictionaryAttr(optional TestInterfaceJSDictionary dict);
|
||||
any pingPongAny(any arg);
|
||||
object pingPongObject(object obj);
|
||||
any pingPongObjectOrString((object or DOMString) objOrString);
|
||||
|
@ -38,11 +39,6 @@ interface TestInterfaceJS : EventTarget {
|
|||
(TestInterfaceJS or long)? pingPongNullableUnion((TestInterfaceJS or long)? something);
|
||||
(Location or TestInterfaceJS) returnBadUnion();
|
||||
|
||||
[Cached, Pure]
|
||||
readonly attribute short cachedAttr;
|
||||
void setCachedAttr(short n);
|
||||
void clearCachedAttrCache();
|
||||
|
||||
// Test for sequence overloading and union behavior
|
||||
void testSequenceOverload(sequence<DOMString> arg);
|
||||
void testSequenceOverload(DOMString arg);
|
||||
|
|
|
@ -903,7 +903,8 @@ Wrap(JSContext *cx, JS::HandleObject existing, JS::HandleObject obj)
|
|||
MOZ_CRASH("There should be no edges from the debuggee to the debugger.");
|
||||
}
|
||||
|
||||
JSObject* originGlobal = js::GetGlobalForObjectCrossCompartment(obj);
|
||||
// Note: the JS engine unwraps CCWs before calling this callback.
|
||||
JSObject* originGlobal = JS::GetNonCCWObjectGlobal(obj);
|
||||
|
||||
const js::Wrapper* wrapper = nullptr;
|
||||
if (IsWorkerDebuggerGlobal(originGlobal) ||
|
||||
|
|
|
@ -894,7 +894,7 @@ GetOrCreateMapEntryForPrototype(JSContext *cx, JS::Handle<JSObject*> proto)
|
|||
// content, and the Window for chrome (whether add-ons are involved or not).
|
||||
JS::Rooted<JSObject*> scope(cx, xpc::GetXBLScopeOrGlobal(cx, proto));
|
||||
NS_ENSURE_TRUE(scope, nullptr);
|
||||
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(scope) == scope);
|
||||
MOZ_ASSERT(JS_IsGlobalObject(scope));
|
||||
|
||||
JS::Rooted<JSObject*> wrappedProto(cx, proto);
|
||||
JSAutoRealm ar(cx, scope);
|
||||
|
|
|
@ -85,7 +85,7 @@ nsXBLProtoImpl::InstallImplementation(nsXBLPrototypeBinding* aPrototypeBinding,
|
|||
GetGlobalForObjectCrossCompartment(targetClassObject));
|
||||
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScopeOrGlobal(cx, globalObject));
|
||||
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
|
||||
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(scopeObject) == scopeObject);
|
||||
MOZ_ASSERT(JS_IsGlobalObject(scopeObject));
|
||||
JSAutoRealm ar(cx, scopeObject);
|
||||
|
||||
// Determine the appropriate property holder.
|
||||
|
|
|
@ -297,7 +297,7 @@ nsXBLProtoImplField::InstallAccessors(JSContext* aCx,
|
|||
JS::Handle<JSObject*> aTargetClassObject)
|
||||
{
|
||||
MOZ_ASSERT(js::IsObjectInContextCompartment(aTargetClassObject, aCx));
|
||||
JS::Rooted<JSObject*> globalObject(aCx, JS_GetGlobalForObject(aCx, aTargetClassObject));
|
||||
JS::Rooted<JSObject*> globalObject(aCx, JS::GetNonCCWObjectGlobal(aTargetClassObject));
|
||||
JS::Rooted<JSObject*> scopeObject(aCx, xpc::GetXBLScopeOrGlobal(aCx, globalObject));
|
||||
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ nsXBLProtoImplMethod::InstallMember(JSContext* aCx,
|
|||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
JS::Rooted<JSObject*> globalObject(aCx, JS_GetGlobalForObject(aCx, aTargetClassObject));
|
||||
JS::Rooted<JSObject*> globalObject(aCx, JS::GetNonCCWObjectGlobal(aTargetClassObject));
|
||||
MOZ_ASSERT(xpc::IsInContentXBLScope(globalObject) ||
|
||||
globalObject == xpc::GetXBLScope(aCx, globalObject));
|
||||
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx) == globalObject);
|
||||
|
|
|
@ -127,7 +127,7 @@ nsXBLProtoImplProperty::InstallMember(JSContext *aCx,
|
|||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
JS::Rooted<JSObject*> globalObject(aCx, JS_GetGlobalForObject(aCx, aTargetClassObject));
|
||||
JS::Rooted<JSObject*> globalObject(aCx, JS::GetNonCCWObjectGlobal(aTargetClassObject));
|
||||
MOZ_ASSERT(xpc::IsInContentXBLScope(globalObject) ||
|
||||
globalObject == xpc::GetXBLScope(aCx, globalObject));
|
||||
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx) == globalObject);
|
||||
|
|
|
@ -93,7 +93,8 @@ NS_NewXMLContentSink(nsIXMLContentSink** aResult,
|
|||
}
|
||||
|
||||
nsXMLContentSink::nsXMLContentSink()
|
||||
: mTextLength(0)
|
||||
: mState(eXMLContentSinkState_InProlog)
|
||||
, mTextLength(0)
|
||||
, mNotifyLevel(0)
|
||||
, mPrettyPrintXML(true)
|
||||
, mPrettyPrintHasSpecialRoot(0)
|
||||
|
|
|
@ -18,6 +18,7 @@ class ForceDiscreteGPUHelperCGL
|
|||
|
||||
public:
|
||||
ForceDiscreteGPUHelperCGL()
|
||||
: mPixelFormatObj(nullptr)
|
||||
{
|
||||
// the code in this function is taken from Chromium, src/ui/gfx/gl/gl_context_cgl.cc, r122013
|
||||
// BSD-style license, (c) The Chromium Authors
|
||||
|
|
|
@ -248,6 +248,7 @@ GetAndInitDisplay(GLLibraryEGL& egl, void* displayType)
|
|||
class AngleErrorReporting {
|
||||
public:
|
||||
AngleErrorReporting()
|
||||
: mFailureId(nullptr)
|
||||
{
|
||||
// No static constructor
|
||||
}
|
||||
|
|
|
@ -247,6 +247,7 @@ TiledTextureImage::TiledTextureImage(GLContext* aGL,
|
|||
, mCurrentImage(0)
|
||||
, mIterationCallback(nullptr)
|
||||
, mIterationCallbackData(nullptr)
|
||||
, mTileSize(0)
|
||||
, mRows(0)
|
||||
, mColumns(0)
|
||||
, mGL(aGL)
|
||||
|
|
|
@ -99,6 +99,7 @@ ScopedBindFramebuffer::UnwrapImpl()
|
|||
|
||||
ScopedBindTextureUnit::ScopedBindTextureUnit(GLContext* aGL, GLenum aTexUnit)
|
||||
: ScopedGLWrapper<ScopedBindTextureUnit>(aGL)
|
||||
, mOldTexUnit(0)
|
||||
{
|
||||
MOZ_ASSERT(aTexUnit >= LOCAL_GL_TEXTURE0);
|
||||
mGL->GetUIntegerv(LOCAL_GL_ACTIVE_TEXTURE, &mOldTexUnit);
|
||||
|
@ -115,6 +116,7 @@ ScopedBindTextureUnit::UnwrapImpl() {
|
|||
|
||||
ScopedTexture::ScopedTexture(GLContext* aGL)
|
||||
: ScopedGLWrapper<ScopedTexture>(aGL)
|
||||
, mTexture(0)
|
||||
{
|
||||
mGL->fGenTextures(1, &mTexture);
|
||||
}
|
||||
|
@ -129,6 +131,7 @@ ScopedTexture::UnwrapImpl()
|
|||
|
||||
ScopedFramebuffer::ScopedFramebuffer(GLContext* aGL)
|
||||
: ScopedGLWrapper<ScopedFramebuffer>(aGL)
|
||||
, mFB(0)
|
||||
{
|
||||
mGL->fGenFramebuffers(1, &mFB);
|
||||
}
|
||||
|
@ -144,6 +147,7 @@ ScopedFramebuffer::UnwrapImpl()
|
|||
|
||||
ScopedRenderbuffer::ScopedRenderbuffer(GLContext* aGL)
|
||||
: ScopedGLWrapper<ScopedRenderbuffer>(aGL)
|
||||
, mRB(0)
|
||||
{
|
||||
mGL->fGenRenderbuffers(1, &mRB);
|
||||
}
|
||||
|
@ -363,6 +367,14 @@ ScopedVertexAttribPointer::ScopedVertexAttribPointer(GLContext* aGL,
|
|||
GLuint buffer,
|
||||
const GLvoid* pointer)
|
||||
: ScopedGLWrapper<ScopedVertexAttribPointer>(aGL)
|
||||
, mAttribEnabled(0)
|
||||
, mAttribSize(0)
|
||||
, mAttribStride(0)
|
||||
, mAttribType(0)
|
||||
, mAttribNormalized(0)
|
||||
, mAttribBufferBinding(0)
|
||||
, mAttribPointer(nullptr)
|
||||
, mBoundBuffer(0)
|
||||
{
|
||||
WrapImpl(index);
|
||||
mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, buffer);
|
||||
|
@ -373,6 +385,14 @@ ScopedVertexAttribPointer::ScopedVertexAttribPointer(GLContext* aGL,
|
|||
ScopedVertexAttribPointer::ScopedVertexAttribPointer(GLContext* aGL,
|
||||
GLuint index)
|
||||
: ScopedGLWrapper<ScopedVertexAttribPointer>(aGL)
|
||||
, mAttribEnabled(0)
|
||||
, mAttribSize(0)
|
||||
, mAttribStride(0)
|
||||
, mAttribType(0)
|
||||
, mAttribNormalized(0)
|
||||
, mAttribBufferBinding(0)
|
||||
, mAttribPointer(nullptr)
|
||||
, mBoundBuffer(0)
|
||||
{
|
||||
WrapImpl(index);
|
||||
}
|
||||
|
@ -428,6 +448,11 @@ ScopedVertexAttribPointer::UnwrapImpl()
|
|||
|
||||
ScopedPackState::ScopedPackState(GLContext* gl)
|
||||
: ScopedGLWrapper<ScopedPackState>(gl)
|
||||
, mAlignment(0)
|
||||
, mPixelBuffer(0)
|
||||
, mRowLength(0)
|
||||
, mSkipPixels(0)
|
||||
, mSkipRows(0)
|
||||
{
|
||||
mGL->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, &mAlignment);
|
||||
|
||||
|
@ -466,6 +491,13 @@ ScopedPackState::UnwrapImpl()
|
|||
|
||||
ResetUnpackState::ResetUnpackState(GLContext* gl)
|
||||
: ScopedGLWrapper<ResetUnpackState>(gl)
|
||||
, mAlignment(0)
|
||||
, mPBO(0)
|
||||
, mRowLength(0)
|
||||
, mImageHeight(0)
|
||||
, mSkipPixels(0)
|
||||
, mSkipRows(0)
|
||||
, mSkipImages(0)
|
||||
{
|
||||
const auto fnReset = [&](GLenum pname, GLuint val, GLuint* const out_old) {
|
||||
mGL->GetUIntegerv(pname, out_old);
|
||||
|
|
|
@ -260,6 +260,15 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag
|
|||
return true;
|
||||
}
|
||||
|
||||
RefPtr<TextureClient>
|
||||
ImageClientSingle::GetForwardedTexture()
|
||||
{
|
||||
if (mBuffers.Length() == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return mBuffers[0].mTextureClient;
|
||||
}
|
||||
|
||||
bool
|
||||
ImageClientSingle::AddTextureClient(TextureClient* aTexture)
|
||||
{
|
||||
|
|
|
@ -73,6 +73,8 @@ public:
|
|||
|
||||
uint32_t GetLastUpdateGenerationCounter() { return mLastUpdateGenerationCounter; }
|
||||
|
||||
virtual RefPtr<TextureClient> GetForwardedTexture() { return nullptr; }
|
||||
|
||||
protected:
|
||||
ImageClient(CompositableForwarder* aFwd, TextureFlags aFlags,
|
||||
CompositableType aType);
|
||||
|
@ -104,6 +106,8 @@ public:
|
|||
|
||||
ImageClientSingle* AsImageClientSingle() override { return this; }
|
||||
|
||||
virtual RefPtr<TextureClient> GetForwardedTexture() override;
|
||||
|
||||
bool IsEmpty() { return mBuffers.IsEmpty(); }
|
||||
|
||||
protected:
|
||||
|
|
|
@ -653,6 +653,8 @@ public:
|
|||
// must only be called from the PaintThread.
|
||||
void DropPaintThreadRef();
|
||||
|
||||
wr::MaybeExternalImageId GetExternalImageKey() { return mExternalImageId; }
|
||||
|
||||
private:
|
||||
static void TextureClientRecycleCallback(TextureClient* aClient, void* aClosure);
|
||||
|
||||
|
|
|
@ -51,6 +51,12 @@ struct OpAddExternalImage {
|
|||
ImageKey key;
|
||||
};
|
||||
|
||||
struct OpAddExternalImageForTexture {
|
||||
ExternalImageId externalImageId;
|
||||
ImageKey key;
|
||||
PTexture texture;
|
||||
};
|
||||
|
||||
struct OpAddCompositorAnimations {
|
||||
CompositorAnimations data;
|
||||
};
|
||||
|
@ -65,15 +71,14 @@ struct OpRemovePipelineIdForCompositable {
|
|||
PipelineId pipelineId;
|
||||
};
|
||||
|
||||
struct OpAddExternalImageIdForCompositable {
|
||||
ExternalImageId externalImageId;
|
||||
CompositableHandle handle;
|
||||
};
|
||||
|
||||
struct OpRemoveExternalImageId {
|
||||
ExternalImageId externalImageId;
|
||||
};
|
||||
|
||||
struct OpReleaseTextureOfImage {
|
||||
ImageKey key;
|
||||
};
|
||||
|
||||
struct OpUpdateAsyncImagePipeline {
|
||||
PipelineId pipelineId;
|
||||
LayoutDeviceRect scBounds;
|
||||
|
@ -86,8 +91,8 @@ struct OpUpdateAsyncImagePipeline {
|
|||
union WebRenderParentCommand {
|
||||
OpAddPipelineIdForCompositable;
|
||||
OpRemovePipelineIdForCompositable;
|
||||
OpAddExternalImageIdForCompositable;
|
||||
OpRemoveExternalImageId;
|
||||
OpReleaseTextureOfImage;
|
||||
OpUpdateAsyncImagePipeline;
|
||||
CompositableOperation;
|
||||
OpAddCompositorAnimations;
|
||||
|
@ -171,6 +176,7 @@ union OpUpdateResource {
|
|||
OpAddFontInstance;
|
||||
OpDeleteFontInstance;
|
||||
OpAddExternalImage;
|
||||
OpAddExternalImageForTexture;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <algorithm>
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/ipc/SharedMemory.h"
|
||||
#include "mozilla/layers/PTextureChild.h"
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -279,6 +280,17 @@ IpcResourceUpdateQueue::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKe
|
|||
mUpdates.AppendElement(layers::OpAddExternalImage(aExtId, aKey));
|
||||
}
|
||||
|
||||
void
|
||||
IpcResourceUpdateQueue::AddExternalImageForTexture(wr::ExternalImageId aExtId,
|
||||
wr::ImageKey aKey,
|
||||
layers::TextureClient* aTexture)
|
||||
{
|
||||
MOZ_ASSERT(aTexture);
|
||||
MOZ_ASSERT(aTexture->GetIPDLActor());
|
||||
MOZ_RELEASE_ASSERT(aTexture->GetIPDLActor()->GetIPCChannel() == mWriter.WrBridge()->GetIPCChannel());
|
||||
mUpdates.AppendElement(layers::OpAddExternalImageForTexture(aExtId, aKey, nullptr, aTexture->GetIPDLActor()));
|
||||
}
|
||||
|
||||
bool
|
||||
IpcResourceUpdateQueue::UpdateImageBuffer(ImageKey aKey,
|
||||
const ImageDescriptor& aDescriptor,
|
||||
|
|
|
@ -37,6 +37,8 @@ public:
|
|||
void Clear();
|
||||
bool IsEmpty() const;
|
||||
|
||||
layers::WebRenderBridgeChild* WrBridge() const { return mShmAllocator; }
|
||||
|
||||
protected:
|
||||
bool AllocChunk();
|
||||
layers::OffsetRange AllocLargeChunk(size_t aSize);
|
||||
|
@ -83,6 +85,10 @@ public:
|
|||
|
||||
void AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey);
|
||||
|
||||
void AddExternalImageForTexture(wr::ExternalImageId aExtId,
|
||||
wr::ImageKey aKey,
|
||||
layers::TextureClient* aTexture);
|
||||
|
||||
bool UpdateImageBuffer(wr::ImageKey aKey,
|
||||
const ImageDescriptor& aDescriptor,
|
||||
Range<uint8_t> aBytes);
|
||||
|
|
|
@ -221,15 +221,6 @@ WebRenderBridgeChild::GetNextExternalImageId()
|
|||
return id.value();
|
||||
}
|
||||
|
||||
wr::ExternalImageId
|
||||
WebRenderBridgeChild::AllocExternalImageIdForCompositable(CompositableClient* aCompositable)
|
||||
{
|
||||
wr::ExternalImageId imageId = GetNextExternalImageId();
|
||||
AddWebRenderParentCommand(
|
||||
OpAddExternalImageIdForCompositable(imageId, aCompositable->GetIPCHandle()));
|
||||
return imageId;
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeChild::DeallocExternalImageId(const wr::ExternalImageId& aImageId)
|
||||
{
|
||||
|
@ -237,6 +228,13 @@ WebRenderBridgeChild::DeallocExternalImageId(const wr::ExternalImageId& aImageId
|
|||
OpRemoveExternalImageId(aImageId));
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeChild::ReleaseTextureOfImage(const wr::ImageKey& aKey)
|
||||
{
|
||||
AddWebRenderParentCommand(
|
||||
OpReleaseTextureOfImage(aKey));
|
||||
}
|
||||
|
||||
struct FontFileDataSink
|
||||
{
|
||||
wr::FontKey* mFontKey;
|
||||
|
|
|
@ -100,9 +100,12 @@ public:
|
|||
const CompositableHandle& aHandlee);
|
||||
void RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId);
|
||||
|
||||
wr::ExternalImageId AllocExternalImageIdForCompositable(CompositableClient* aCompositable);
|
||||
void DeallocExternalImageId(const wr::ExternalImageId& aImageId);
|
||||
|
||||
/// Release TextureClient that is bounded to ImageKey.
|
||||
/// It is used for recycling TextureClient.
|
||||
void ReleaseTextureOfImage(const wr::ImageKey& aKey);
|
||||
|
||||
/**
|
||||
* Clean this up, finishing with SendShutDown() which will cause __delete__
|
||||
* to be sent from the parent side.
|
||||
|
|
|
@ -344,6 +344,15 @@ WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResour
|
|||
}
|
||||
break;
|
||||
}
|
||||
case OpUpdateResource::TOpAddExternalImageForTexture: {
|
||||
const auto& op = cmd.get_OpAddExternalImageForTexture();
|
||||
CompositableTextureHostRef texture;
|
||||
texture = TextureHost::AsTextureHost(op.textureParent());
|
||||
if (!AddExternalImageForTexture(op.externalImageId(), op.key(), texture, aUpdates)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpUpdateResource::TOpAddRawFont: {
|
||||
const auto& op = cmd.get_OpAddRawFont();
|
||||
wr::Vec<uint8_t> bytes;
|
||||
|
@ -426,29 +435,54 @@ WebRenderBridgeParent::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey
|
|||
return true;
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(mExternalImageIds.Get(wr::AsUint64(aExtId)).get());
|
||||
|
||||
RefPtr<WebRenderImageHost> host = mExternalImageIds.Get(wr::AsUint64(aExtId));
|
||||
if (!host) {
|
||||
gfxCriticalNote << "CompositableHost does not exist for extId:" << wr::AsUint64(aExtId);
|
||||
return false;
|
||||
}
|
||||
if (!gfxEnv::EnableWebRenderRecording()) {
|
||||
TextureHost* texture = host->GetAsTextureHostForComposite();
|
||||
if (!texture) {
|
||||
gfxCriticalNote << "TextureHost does not exist for extId:" << wr::AsUint64(aExtId);
|
||||
return false;
|
||||
}
|
||||
WebRenderTextureHost* wrTexture = texture->AsWebRenderTextureHost();
|
||||
if (wrTexture) {
|
||||
wrTexture->PushResourceUpdates(aResources, TextureHost::ADD_IMAGE, keys,
|
||||
wrTexture->GetExternalImageKey());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
dSurf = host->GetAsSurface();
|
||||
gfxCriticalNote << "DataSourceSurface of SharedSurfaces does not exist for extId:" << wr::AsUint64(aExtId);
|
||||
return false;
|
||||
}
|
||||
|
||||
DataSourceSurface::MappedSurface map;
|
||||
if (!dSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
|
||||
gfxCriticalNote << "DataSourceSurface failed to map for Image for extId:" << wr::AsUint64(aExtId);
|
||||
return false;
|
||||
}
|
||||
|
||||
IntSize size = dSurf->GetSize();
|
||||
wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat());
|
||||
wr::Vec<uint8_t> data;
|
||||
data.PushBytes(Range<uint8_t>(map.mData, size.height * map.mStride));
|
||||
aResources.AddImage(keys[0], descriptor, data);
|
||||
dSurf->Unmap();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebRenderBridgeParent::AddExternalImageForTexture(wr::ExternalImageId aExtId,
|
||||
wr::ImageKey aKey,
|
||||
TextureHost* aTexture,
|
||||
wr::TransactionBuilder& aResources)
|
||||
{
|
||||
Range<wr::ImageKey> keys(&aKey, 1);
|
||||
// Check if key is obsoleted.
|
||||
if (keys[0].mNamespace != mIdNamespace) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!aTexture) {
|
||||
gfxCriticalNote << "TextureHost does not exist for extId:" << wr::AsUint64(aExtId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gfxEnv::EnableWebRenderRecording()) {
|
||||
WebRenderTextureHost* wrTexture = aTexture->AsWebRenderTextureHost();
|
||||
if (wrTexture) {
|
||||
wrTexture->PushResourceUpdates(aResources, TextureHost::ADD_IMAGE, keys,
|
||||
wrTexture->GetExternalImageKey());
|
||||
MOZ_ASSERT(!mTextureHosts.Get(wr::AsUint64(aKey), nullptr));
|
||||
mTextureHosts.Put(wr::AsUint64(aKey), CompositableTextureHostRef(aTexture));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
RefPtr<DataSourceSurface> dSurf = aTexture->GetAsSurface();
|
||||
if (!dSurf) {
|
||||
gfxCriticalNote << "TextureHost does not return DataSourceSurface for extId:" << wr::AsUint64(aExtId);
|
||||
return false;
|
||||
|
@ -847,17 +881,16 @@ WebRenderBridgeParent::ProcessWebRenderParentCommands(const InfallibleTArray<Web
|
|||
RemovePipelineIdForCompositable(op.pipelineId(), aTxn);
|
||||
break;
|
||||
}
|
||||
case WebRenderParentCommand::TOpAddExternalImageIdForCompositable: {
|
||||
const OpAddExternalImageIdForCompositable& op = cmd.get_OpAddExternalImageIdForCompositable();
|
||||
AddExternalImageIdForCompositable(op.externalImageId(),
|
||||
op.handle());
|
||||
break;
|
||||
}
|
||||
case WebRenderParentCommand::TOpRemoveExternalImageId: {
|
||||
const OpRemoveExternalImageId& op = cmd.get_OpRemoveExternalImageId();
|
||||
RemoveExternalImageId(op.externalImageId());
|
||||
break;
|
||||
}
|
||||
case WebRenderParentCommand::TOpReleaseTextureOfImage: {
|
||||
const OpReleaseTextureOfImage& op = cmd.get_OpReleaseTextureOfImage();
|
||||
ReleaseTextureOfImage(op.key());
|
||||
break;
|
||||
}
|
||||
case WebRenderParentCommand::TOpUpdateAsyncImagePipeline: {
|
||||
const OpUpdateAsyncImagePipeline& op = cmd.get_OpUpdateAsyncImagePipeline();
|
||||
mAsyncImageManager->UpdateAsyncImagePipeline(op.pipelineId(),
|
||||
|
@ -1064,33 +1097,6 @@ WebRenderBridgeParent::RemovePipelineIdForCompositable(const wr::PipelineId& aPi
|
|||
return;
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeParent::AddExternalImageIdForCompositable(const ExternalImageId& aImageId,
|
||||
const CompositableHandle& aHandle)
|
||||
{
|
||||
if (mDestroyed) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(!mExternalImageIds.Get(wr::AsUint64(aImageId)).get());
|
||||
|
||||
RefPtr<CompositableHost> host = FindCompositable(aHandle);
|
||||
WebRenderImageHost* wrHost = host->AsWebRenderImageHost();
|
||||
|
||||
MOZ_ASSERT(wrHost);
|
||||
if (!wrHost) {
|
||||
gfxCriticalNote << "Incompatible CompositableHost for external image at WebRenderBridgeParent.";
|
||||
}
|
||||
|
||||
if (!wrHost) {
|
||||
return;
|
||||
}
|
||||
|
||||
wrHost->SetWrBridge(this);
|
||||
mExternalImageIds.Put(wr::AsUint64(aImageId), wrHost);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeParent::RemoveExternalImageId(const ExternalImageId& aImageId)
|
||||
{
|
||||
|
@ -1101,18 +1107,27 @@ WebRenderBridgeParent::RemoveExternalImageId(const ExternalImageId& aImageId)
|
|||
uint64_t imageId = wr::AsUint64(aImageId);
|
||||
if (mSharedSurfaceIds.EnsureRemoved(imageId)) {
|
||||
mAsyncImageManager->HoldExternalImage(mPipelineId, mWrEpoch, aImageId);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeParent::ReleaseTextureOfImage(const wr::ImageKey& aKey)
|
||||
{
|
||||
if (mDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
WebRenderImageHost* wrHost = mExternalImageIds.Get(imageId).get();
|
||||
if (!wrHost) {
|
||||
return;
|
||||
uint64_t id = wr::AsUint64(aKey);
|
||||
CompositableTextureHostRef texture;
|
||||
WebRenderTextureHost* wrTexture = nullptr;
|
||||
|
||||
if (mTextureHosts.Get(id, &texture)) {
|
||||
wrTexture = texture->AsWebRenderTextureHost();
|
||||
}
|
||||
|
||||
wrHost->ClearWrBridge();
|
||||
mExternalImageIds.Remove(imageId);
|
||||
|
||||
return;
|
||||
if (wrTexture) {
|
||||
mAsyncImageManager->HoldExternalImage(mPipelineId, mWrEpoch, wrTexture);
|
||||
}
|
||||
mTextureHosts.Remove(id);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
|
@ -1639,10 +1654,14 @@ WebRenderBridgeParent::ClearResources()
|
|||
// Schedule generate frame to clean up Pipeline
|
||||
ScheduleGenerateFrame();
|
||||
// WrFontKeys and WrImageKeys are deleted during WebRenderAPI destruction.
|
||||
for (auto iter = mExternalImageIds.Iter(); !iter.Done(); iter.Next()) {
|
||||
iter.Data()->ClearWrBridge();
|
||||
for (auto iter = mTextureHosts.Iter(); !iter.Done(); iter.Next()) {
|
||||
WebRenderTextureHost* wrTexture = iter.Data()->AsWebRenderTextureHost();
|
||||
MOZ_ASSERT(wrTexture);
|
||||
if (wrTexture) {
|
||||
mAsyncImageManager->HoldExternalImage(mPipelineId, wrEpoch, wrTexture);
|
||||
}
|
||||
}
|
||||
mExternalImageIds.Clear();
|
||||
mTextureHosts.Clear();
|
||||
for (auto iter = mAsyncCompositables.Iter(); !iter.Done(); iter.Next()) {
|
||||
wr::PipelineId pipelineId = wr::AsPipelineId(iter.Key());
|
||||
RefPtr<WebRenderImageHost> host = iter.Data();
|
||||
|
|
|
@ -209,15 +209,19 @@ private:
|
|||
bool AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey,
|
||||
wr::TransactionBuilder& aResources);
|
||||
|
||||
bool AddExternalImageForTexture(wr::ExternalImageId aExtId,
|
||||
wr::ImageKey aKey,
|
||||
TextureHost* aTexture,
|
||||
wr::TransactionBuilder& aResources);
|
||||
|
||||
void AddPipelineIdForCompositable(const wr::PipelineId& aPipelineIds,
|
||||
const CompositableHandle& aHandle,
|
||||
const bool& aAsync);
|
||||
void RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId,
|
||||
wr::TransactionBuilder& aTxn);
|
||||
|
||||
void AddExternalImageIdForCompositable(const ExternalImageId& aImageId,
|
||||
const CompositableHandle& aHandle);
|
||||
void RemoveExternalImageId(const ExternalImageId& aImageId);
|
||||
void ReleaseTextureOfImage(const wr::ImageKey& aKey);
|
||||
|
||||
LayersId GetLayersId() const;
|
||||
void ProcessWebRenderParentCommands(const InfallibleTArray<WebRenderParentCommand>& aCommands,
|
||||
|
@ -291,7 +295,7 @@ private:
|
|||
// destroyed abnormally and Tab move between different windows.
|
||||
std::unordered_set<uint64_t> mActiveAnimations;
|
||||
nsDataHashtable<nsUint64HashKey, RefPtr<WebRenderImageHost>> mAsyncCompositables;
|
||||
nsDataHashtable<nsUint64HashKey, RefPtr<WebRenderImageHost>> mExternalImageIds;
|
||||
nsDataHashtable<nsUint64HashKey, CompositableTextureHostRef> mTextureHosts;
|
||||
nsTHashtable<nsUint64HashKey> mSharedSurfaceIds;
|
||||
|
||||
TimeDuration mVsyncRate;
|
||||
|
|
|
@ -196,20 +196,6 @@ WebRenderImageHost::SetCurrentTextureHost(TextureHost* aTexture)
|
|||
return;
|
||||
}
|
||||
|
||||
if (mWrBridge &&
|
||||
!mUseAsyncImagePipeline &&
|
||||
!!mCurrentTextureHost &&
|
||||
mCurrentTextureHost != aTexture &&
|
||||
mCurrentTextureHost->AsWebRenderTextureHost()) {
|
||||
MOZ_ASSERT(mWrBridge->AsyncImageManager());
|
||||
wr::PipelineId piplineId = mWrBridge->PipelineId();
|
||||
wr::Epoch epoch = mWrBridge->WrEpoch();
|
||||
mWrBridge->AsyncImageManager()->HoldExternalImage(
|
||||
piplineId,
|
||||
epoch,
|
||||
mCurrentTextureHost->AsWebRenderTextureHost());
|
||||
}
|
||||
|
||||
mCurrentTextureHost = aTexture;
|
||||
}
|
||||
|
||||
|
|
|
@ -78,10 +78,6 @@ WebRenderImageData::~WebRenderImageData()
|
|||
{
|
||||
ClearImageKey();
|
||||
|
||||
if (mExternalImageId) {
|
||||
WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
|
||||
}
|
||||
|
||||
if (mPipelineId) {
|
||||
WrBridge()->RemovePipelineIdForCompositable(mPipelineId.ref());
|
||||
}
|
||||
|
@ -95,10 +91,15 @@ WebRenderImageData::ClearImageKey()
|
|||
// key when appropriate.
|
||||
if (mOwnsKey) {
|
||||
mWRManager->AddImageKeyForDiscard(mKey.value());
|
||||
if (mTextureOfImage) {
|
||||
WrBridge()->ReleaseTextureOfImage(mKey.value());
|
||||
mTextureOfImage = nullptr;
|
||||
}
|
||||
}
|
||||
mKey.reset();
|
||||
}
|
||||
mOwnsKey = false;
|
||||
MOZ_ASSERT(!mTextureOfImage);
|
||||
}
|
||||
|
||||
Maybe<wr::ImageKey>
|
||||
|
@ -132,9 +133,7 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer,
|
|||
}
|
||||
|
||||
CreateImageClientIfNeeded();
|
||||
CreateExternalImageIfNeeded();
|
||||
|
||||
if (!mImageClient || !mExternalImageId) {
|
||||
if (!mImageClient) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
|
@ -144,7 +143,8 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer,
|
|||
uint32_t oldCounter = imageClient->GetLastUpdateGenerationCounter();
|
||||
|
||||
bool ret = imageClient->UpdateImage(aContainer, /* unused */0);
|
||||
if (!ret || imageClient->IsEmpty()) {
|
||||
RefPtr<TextureClient> currentTexture = imageClient->GetForwardedTexture();
|
||||
if (!ret || !currentTexture) {
|
||||
// Delete old key
|
||||
ClearImageKey();
|
||||
return Nothing();
|
||||
|
@ -159,8 +159,13 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer,
|
|||
// TODO(nical): noooo... we need to reuse image keys.
|
||||
ClearImageKey();
|
||||
|
||||
wr::MaybeExternalImageId extId = currentTexture->GetExternalImageKey();
|
||||
MOZ_RELEASE_ASSERT(extId.isSome());
|
||||
MOZ_ASSERT(!mTextureOfImage);
|
||||
|
||||
key = WrBridge()->GetNextImageKey();
|
||||
aResources.AddExternalImage(mExternalImageId.value(), key);
|
||||
aResources.AddExternalImageForTexture(extId.ref(), key, currentTexture);
|
||||
mTextureOfImage = currentTexture;
|
||||
mKey = Some(key);
|
||||
mOwnsKey = true;
|
||||
|
||||
|
@ -212,7 +217,6 @@ WebRenderImageData::CreateAsyncImageWebRenderCommands(mozilla::wr::DisplayListBu
|
|||
mContainer = aContainer;
|
||||
}
|
||||
MOZ_ASSERT(!mImageClient);
|
||||
MOZ_ASSERT(!mExternalImageId);
|
||||
|
||||
// Push IFrame for async image pipeline.
|
||||
//
|
||||
|
@ -248,14 +252,6 @@ WebRenderImageData::CreateImageClientIfNeeded()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderImageData::CreateExternalImageIfNeeded()
|
||||
{
|
||||
if (!mExternalImageId) {
|
||||
mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
|
||||
}
|
||||
}
|
||||
|
||||
WebRenderFallbackData::WebRenderFallbackData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem)
|
||||
: WebRenderImageData(aWRManager, aItem)
|
||||
, mInvalid(false)
|
||||
|
|
|
@ -151,9 +151,8 @@ public:
|
|||
|
||||
protected:
|
||||
void ClearImageKey();
|
||||
void CreateExternalImageIfNeeded();
|
||||
|
||||
wr::MaybeExternalImageId mExternalImageId;
|
||||
RefPtr<TextureClient> mTextureOfImage;
|
||||
Maybe<wr::ImageKey> mKey;
|
||||
RefPtr<ImageClient> mImageClient;
|
||||
Maybe<wr::PipelineId> mPipelineId;
|
||||
|
|
|
@ -50,11 +50,11 @@ JSDebugger::AddClass(JS::Handle<JS::Value> global, JSContext* cx)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JSAutoRealm ar(cx, obj);
|
||||
if (JS_GetGlobalForObject(cx, obj) != obj) {
|
||||
if (!JS_IsGlobalObject(obj)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
JSAutoRealm ar(cx, obj);
|
||||
if (!JS_DefineDebuggerObject(cx, obj)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ class JS_FRIEND_API(Wrapper) : public ForwardingProxyHandler
|
|||
|
||||
static JSObject* Renew(JSObject* existing, JSObject* obj, const Wrapper* handler);
|
||||
|
||||
static const Wrapper* wrapperHandler(const JSObject* wrapper);
|
||||
static inline const Wrapper* wrapperHandler(const JSObject* wrapper);
|
||||
|
||||
static JSObject* wrappedObject(JSObject* wrapper);
|
||||
|
||||
|
@ -340,6 +340,20 @@ IsWrapper(const JSObject* obj)
|
|||
return IsProxy(obj) && GetProxyHandler(obj)->family() == &Wrapper::family;
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsCrossCompartmentWrapper(const JSObject* obj)
|
||||
{
|
||||
return IsWrapper(obj) &&
|
||||
(Wrapper::wrapperHandler(obj)->flags() & Wrapper::CROSS_COMPARTMENT);
|
||||
}
|
||||
|
||||
/* static */ inline const Wrapper*
|
||||
Wrapper::wrapperHandler(const JSObject* wrapper)
|
||||
{
|
||||
MOZ_ASSERT(IsWrapper(wrapper));
|
||||
return static_cast<const Wrapper*>(GetProxyHandler(wrapper));
|
||||
}
|
||||
|
||||
// Given a JSObject, returns that object stripped of wrappers. If
|
||||
// stopAtWindowProxy is true, then this returns the WindowProxy if it was
|
||||
// previously wrapped. Otherwise, this returns the first object for which
|
||||
|
|
|
@ -206,14 +206,17 @@ LifoAlloc::getOrCreateChunk(size_t n)
|
|||
// This function is adding a new BumpChunk in which all upcoming allocation
|
||||
// would be made. Thus, we protect against out-of-bounds the last chunk in
|
||||
// which we did our previous allocations.
|
||||
if (!chunks_.empty())
|
||||
chunks_.last()->setRWUntil(Loc::Reserved);
|
||||
auto protectLast = [&]() {
|
||||
if (!chunks_.empty())
|
||||
chunks_.last()->setRWUntil(Loc::Reserved);
|
||||
};
|
||||
|
||||
// Look for existing unused BumpChunks to satisfy the request, and pick the
|
||||
// first one which is large enough, and move it into the list of used
|
||||
// chunks.
|
||||
if (!unused_.empty()) {
|
||||
if (unused_.begin()->canAlloc(n)) {
|
||||
protectLast();
|
||||
chunks_.append(unused_.popFirst());
|
||||
chunks_.last()->setRWUntil(Loc::End);
|
||||
return true;
|
||||
|
@ -225,6 +228,7 @@ LifoAlloc::getOrCreateChunk(size_t n)
|
|||
MOZ_ASSERT(elem->empty());
|
||||
if (elem->canAlloc(n)) {
|
||||
BumpChunkList temp = unused_.splitAfter(i.get());
|
||||
protectLast();
|
||||
chunks_.append(temp.popFirst());
|
||||
unused_.appendAll(std::move(temp));
|
||||
chunks_.last()->setRWUntil(Loc::End);
|
||||
|
@ -241,6 +245,7 @@ LifoAlloc::getOrCreateChunk(size_t n)
|
|||
// The last chunk in which allocations are performed should be protected
|
||||
// with setRWUntil(Loc::End), but this is not necessary here because any new
|
||||
// allocation should be protected as RW already.
|
||||
protectLast();
|
||||
chunks_.append(std::move(newChunk));
|
||||
incrementCurSize(size);
|
||||
return true;
|
||||
|
|
|
@ -69,6 +69,8 @@ using AddDeclaredNamePtr = ParseContext::Scope::AddDeclaredNamePtr;
|
|||
using BindingIter = ParseContext::Scope::BindingIter;
|
||||
using UsedNamePtr = UsedNameTracker::UsedNameMap::Ptr;
|
||||
|
||||
using BindingNameVector = Vector<BindingName, 6>;
|
||||
|
||||
// Read a token. Report an error and return null() if that token doesn't match
|
||||
// to the condition. Do not use MUST_MATCH_TOKEN_INTERNAL directly.
|
||||
#define MUST_MATCH_TOKEN_INTERNAL(cond, modifier, errorReport) \
|
||||
|
@ -1773,7 +1775,7 @@ NewEmptyBindingData(JSContext* cx, LifoAlloc& alloc, uint32_t numBindings)
|
|||
* the location one past the newly-constructed |BindingName|s.
|
||||
*/
|
||||
static MOZ_MUST_USE BindingName*
|
||||
FreshlyInitializeBindings(BindingName* cursor, const Vector<BindingName>& bindings)
|
||||
FreshlyInitializeBindings(BindingName* cursor, const BindingNameVector& bindings)
|
||||
{
|
||||
return std::uninitialized_copy(bindings.begin(), bindings.end(), cursor);
|
||||
}
|
||||
|
@ -1781,9 +1783,9 @@ FreshlyInitializeBindings(BindingName* cursor, const Vector<BindingName>& bindin
|
|||
Maybe<GlobalScope::Data*>
|
||||
NewGlobalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
|
||||
{
|
||||
Vector<BindingName> vars(context);
|
||||
Vector<BindingName> lets(context);
|
||||
Vector<BindingName> consts(context);
|
||||
BindingNameVector vars(context);
|
||||
BindingNameVector lets(context);
|
||||
BindingNameVector consts(context);
|
||||
|
||||
bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
|
||||
for (BindingIter bi = scope.bindings(pc); bi; bi++) {
|
||||
|
@ -1849,10 +1851,10 @@ ParserBase::newGlobalScopeData(ParseContext::Scope& scope)
|
|||
Maybe<ModuleScope::Data*>
|
||||
NewModuleScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
|
||||
{
|
||||
Vector<BindingName> imports(context);
|
||||
Vector<BindingName> vars(context);
|
||||
Vector<BindingName> lets(context);
|
||||
Vector<BindingName> consts(context);
|
||||
BindingNameVector imports(context);
|
||||
BindingNameVector vars(context);
|
||||
BindingNameVector lets(context);
|
||||
BindingNameVector consts(context);
|
||||
|
||||
bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
|
||||
for (BindingIter bi = scope.bindings(pc); bi; bi++) {
|
||||
|
@ -1919,7 +1921,7 @@ ParserBase::newModuleScopeData(ParseContext::Scope& scope)
|
|||
Maybe<EvalScope::Data*>
|
||||
NewEvalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
|
||||
{
|
||||
Vector<BindingName> vars(context);
|
||||
BindingNameVector vars(context);
|
||||
|
||||
for (BindingIter bi = scope.bindings(pc); bi; bi++) {
|
||||
// Eval scopes only contain 'var' bindings. Make all bindings aliased
|
||||
|
@ -1959,9 +1961,9 @@ ParserBase::newEvalScopeData(ParseContext::Scope& scope)
|
|||
Maybe<FunctionScope::Data*>
|
||||
NewFunctionScopeData(JSContext* context, ParseContext::Scope& scope, bool hasParameterExprs, LifoAlloc& alloc, ParseContext* pc)
|
||||
{
|
||||
Vector<BindingName> positionalFormals(context);
|
||||
Vector<BindingName> formals(context);
|
||||
Vector<BindingName> vars(context);
|
||||
BindingNameVector positionalFormals(context);
|
||||
BindingNameVector formals(context);
|
||||
BindingNameVector vars(context);
|
||||
|
||||
bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
|
||||
bool hasDuplicateParams = pc->functionBox()->hasDuplicateParameters;
|
||||
|
@ -2058,7 +2060,7 @@ ParserBase::newFunctionScopeData(ParseContext::Scope& scope, bool hasParameterEx
|
|||
Maybe<VarScope::Data*>
|
||||
NewVarScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
|
||||
{
|
||||
Vector<BindingName> vars(context);
|
||||
BindingNameVector vars(context);
|
||||
|
||||
bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
|
||||
|
||||
|
@ -2099,8 +2101,8 @@ ParserBase::newVarScopeData(ParseContext::Scope& scope)
|
|||
Maybe<LexicalScope::Data*>
|
||||
NewLexicalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
|
||||
{
|
||||
Vector<BindingName> lets(context);
|
||||
Vector<BindingName> consts(context);
|
||||
BindingNameVector lets(context);
|
||||
BindingNameVector consts(context);
|
||||
|
||||
// Unlike other scopes with bindings which are body-level, it is unknown
|
||||
// if pc->sc()->allBindingsClosedOver() is correct at the time of
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "gc/Allocator.h"
|
||||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
#include "gc/GCInternals.h"
|
||||
#include "gc/GCTrace.h"
|
||||
#include "gc/Nursery.h"
|
||||
|
@ -237,7 +239,7 @@ template <typename T, AllowGC allowGC>
|
|||
GCRuntime::tryNewTenuredThing(JSContext* cx, AllocKind kind, size_t thingSize)
|
||||
{
|
||||
// Bump allocate in the arena's current free-list span.
|
||||
T* t = reinterpret_cast<T*>(cx->arenas()->allocateFromFreeList(kind, thingSize));
|
||||
T* t = reinterpret_cast<T*>(cx->freeLists().allocate(kind));
|
||||
if (MOZ_UNLIKELY(!t)) {
|
||||
// Get the next available free list and allocate out of it. This may
|
||||
// acquire a new arena, which will lock the chunk list. If there are no
|
||||
|
@ -347,26 +349,40 @@ GCRuntime::checkIncrementalZoneState(JSContext* cx, T* t)
|
|||
#endif
|
||||
}
|
||||
|
||||
TenuredCell*
|
||||
js::gc::AllocateCellInGC(Zone* zone, AllocKind thingKind)
|
||||
{
|
||||
void* cell = zone->arenas.allocateFromFreeList(thingKind);
|
||||
if (!cell) {
|
||||
AutoEnterOOMUnsafeRegion oomUnsafe;
|
||||
cell = GCRuntime::refillFreeListInGC(zone, thingKind);
|
||||
if (!cell)
|
||||
oomUnsafe.crash(ChunkSize, "Failed not allocate new chunk during GC");
|
||||
}
|
||||
return TenuredCell::fromPointer(cell);
|
||||
}
|
||||
|
||||
|
||||
// /////////// Arena -> Thing Allocator //////////////////////////////////////
|
||||
|
||||
void
|
||||
bool
|
||||
GCRuntime::startBackgroundAllocTaskIfIdle()
|
||||
{
|
||||
AutoLockHelperThreadState helperLock;
|
||||
if (allocTask.isRunningWithLockHeld(helperLock))
|
||||
return;
|
||||
return true;
|
||||
|
||||
// Join the previous invocation of the task. This will return immediately
|
||||
// if the thread has never been started.
|
||||
allocTask.joinWithLockHeld(helperLock);
|
||||
allocTask.startWithLockHeld(helperLock);
|
||||
|
||||
return allocTask.startWithLockHeld(helperLock);
|
||||
}
|
||||
|
||||
/* static */ TenuredCell*
|
||||
GCRuntime::refillFreeListFromAnyThread(JSContext* cx, AllocKind thingKind)
|
||||
{
|
||||
cx->arenas()->checkEmptyFreeList(thingKind);
|
||||
MOZ_ASSERT(cx->freeLists().isEmpty(thingKind));
|
||||
|
||||
if (!cx->helperThread())
|
||||
return refillFreeListFromMainThread(cx, thingKind);
|
||||
|
@ -379,10 +395,10 @@ GCRuntime::refillFreeListFromMainThread(JSContext* cx, AllocKind thingKind)
|
|||
{
|
||||
// It should not be possible to allocate on the main thread while we are
|
||||
// inside a GC.
|
||||
Zone *zone = cx->zone();
|
||||
MOZ_ASSERT(!JS::RuntimeHeapIsBusy(), "allocating while under GC");
|
||||
|
||||
return cx->arenas()->allocateFromArena(zone, thingKind, ShouldCheckThresholds::CheckThresholds);
|
||||
return cx->zone()->arenas.refillFreeListAndAllocate(cx->freeLists(), thingKind,
|
||||
ShouldCheckThresholds::CheckThresholds);
|
||||
}
|
||||
|
||||
/* static */ TenuredCell*
|
||||
|
@ -390,37 +406,37 @@ GCRuntime::refillFreeListFromHelperThread(JSContext* cx, AllocKind thingKind)
|
|||
{
|
||||
// A GC may be happening on the main thread, but zones used by off thread
|
||||
// tasks are never collected.
|
||||
Zone* zone = cx->zone();
|
||||
Zone *zone = cx->zone();
|
||||
MOZ_ASSERT(!zone->wasGCStarted());
|
||||
|
||||
return cx->arenas()->allocateFromArena(zone, thingKind, ShouldCheckThresholds::CheckThresholds);
|
||||
return zone->arenas.refillFreeListAndAllocate(cx->freeLists(), thingKind,
|
||||
ShouldCheckThresholds::CheckThresholds);
|
||||
}
|
||||
|
||||
/* static */ TenuredCell*
|
||||
GCRuntime::refillFreeListInGC(Zone* zone, AllocKind thingKind)
|
||||
{
|
||||
/*
|
||||
* Called by compacting GC to refill a free list while we are in a GC.
|
||||
*/
|
||||
|
||||
zone->arenas.checkEmptyFreeList(thingKind);
|
||||
mozilla::DebugOnly<JSRuntime*> rt = zone->runtimeFromMainThread();
|
||||
// Called by compacting GC to refill a free list while we are in a GC.
|
||||
MOZ_ASSERT(JS::RuntimeHeapIsCollecting());
|
||||
MOZ_ASSERT_IF(!JS::RuntimeHeapIsMinorCollecting(), !rt->gc.isBackgroundSweeping());
|
||||
MOZ_ASSERT_IF(!JS::RuntimeHeapIsMinorCollecting(),
|
||||
!zone->runtimeFromMainThread()->gc.isBackgroundSweeping());
|
||||
|
||||
return zone->arenas.allocateFromArena(zone, thingKind, ShouldCheckThresholds::DontCheckThresholds);
|
||||
return zone->arenas.refillFreeListAndAllocate(zone->arenas.freeLists(), thingKind,
|
||||
ShouldCheckThresholds::DontCheckThresholds);
|
||||
}
|
||||
|
||||
TenuredCell*
|
||||
ArenaLists::allocateFromArena(JS::Zone* zone, AllocKind thingKind,
|
||||
ShouldCheckThresholds checkThresholds)
|
||||
ArenaLists::refillFreeListAndAllocate(FreeLists& freeLists, AllocKind thingKind,
|
||||
ShouldCheckThresholds checkThresholds)
|
||||
{
|
||||
JSRuntime* rt = zone->runtimeFromAnyThread();
|
||||
MOZ_ASSERT(freeLists.isEmpty(thingKind));
|
||||
|
||||
JSRuntime* rt = runtimeFromAnyThread();
|
||||
|
||||
mozilla::Maybe<AutoLockGCBgAlloc> maybeLock;
|
||||
|
||||
// See if we can proceed without taking the GC lock.
|
||||
if (backgroundFinalizeState(thingKind) != BFS_DONE)
|
||||
if (concurrentUse(thingKind) != ConcurrentUse::None)
|
||||
maybeLock.emplace(rt);
|
||||
|
||||
ArenaList& al = arenaLists(thingKind);
|
||||
|
@ -429,7 +445,7 @@ ArenaLists::allocateFromArena(JS::Zone* zone, AllocKind thingKind,
|
|||
// Empty arenas should be immediately freed.
|
||||
MOZ_ASSERT(!arena->isEmpty());
|
||||
|
||||
return allocateFromArenaInner(zone, arena, thingKind);
|
||||
return freeLists.setArenaAndAllocate(arena, thingKind);
|
||||
}
|
||||
|
||||
// Parallel threads have their own ArenaLists, but chunks are shared;
|
||||
|
@ -443,40 +459,46 @@ ArenaLists::allocateFromArena(JS::Zone* zone, AllocKind thingKind,
|
|||
|
||||
// Although our chunk should definitely have enough space for another arena,
|
||||
// there are other valid reasons why Chunk::allocateArena() may fail.
|
||||
arena = rt->gc.allocateArena(chunk, zone, thingKind, checkThresholds, maybeLock.ref());
|
||||
arena = rt->gc.allocateArena(chunk, zone_, thingKind, checkThresholds, maybeLock.ref());
|
||||
if (!arena)
|
||||
return nullptr;
|
||||
|
||||
MOZ_ASSERT(al.isCursorAtEnd());
|
||||
al.insertBeforeCursor(arena);
|
||||
|
||||
return allocateFromArenaInner(zone, arena, thingKind);
|
||||
return freeLists.setArenaAndAllocate(arena, thingKind);
|
||||
}
|
||||
|
||||
inline TenuredCell*
|
||||
ArenaLists::allocateFromArenaInner(JS::Zone* zone, Arena* arena, AllocKind kind)
|
||||
FreeLists::setArenaAndAllocate(Arena* arena, AllocKind kind)
|
||||
{
|
||||
size_t thingSize = Arena::thingSize(kind);
|
||||
#ifdef DEBUG
|
||||
auto old = freeLists_[kind];
|
||||
if (!old->isEmpty())
|
||||
old->getArena()->checkNoMarkedFreeCells();
|
||||
#endif
|
||||
|
||||
setFreeList(kind, arena->getFirstFreeSpan());
|
||||
FreeSpan* span = arena->getFirstFreeSpan();
|
||||
freeLists_[kind] = span;
|
||||
|
||||
if (MOZ_UNLIKELY(zone->wasGCStarted()))
|
||||
zone->runtimeFromAnyThread()->gc.arenaAllocatedDuringGC(zone, arena);
|
||||
TenuredCell* thing = freeList(kind)->allocate(thingSize);
|
||||
if (MOZ_UNLIKELY(arena->zone->wasGCStarted()))
|
||||
arena->arenaAllocatedDuringGC();
|
||||
|
||||
TenuredCell* thing = span->allocate(Arena::thingSize(kind));
|
||||
MOZ_ASSERT(thing); // This allocation is infallible.
|
||||
|
||||
return thing;
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::arenaAllocatedDuringGC(JS::Zone* zone, Arena* arena)
|
||||
Arena::arenaAllocatedDuringGC()
|
||||
{
|
||||
// Ensure that anything allocated during the mark or sweep phases of an
|
||||
// incremental GC will be marked black by pre-marking all free cells in the
|
||||
// arena we are about to allocate from.
|
||||
|
||||
if (zone->needsIncrementalBarrier() || zone->isGCSweeping()) {
|
||||
for (ArenaFreeCellIter iter(arena); !iter.done(); iter.next()) {
|
||||
for (ArenaFreeCellIter iter(this); !iter.done(); iter.next()) {
|
||||
TenuredCell* cell = iter.getCell();
|
||||
MOZ_ASSERT(!cell->isMarkedAny());
|
||||
cell->markBlack();
|
||||
|
@ -484,6 +506,28 @@ GCRuntime::arenaAllocatedDuringGC(JS::Zone* zone, Arena* arena)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::setParallelAtomsAllocEnabled(bool enabled)
|
||||
{
|
||||
atomsZone->arenas.setParallelAllocEnabled(enabled);
|
||||
}
|
||||
|
||||
void
|
||||
ArenaLists::setParallelAllocEnabled(bool enabled)
|
||||
{
|
||||
MOZ_ASSERT(zone_->isAtomsZone());
|
||||
|
||||
static const ConcurrentUse states[2] = {
|
||||
ConcurrentUse::None,
|
||||
ConcurrentUse::ParallelAlloc
|
||||
};
|
||||
|
||||
for (auto kind : AllAllocKinds()) {
|
||||
MOZ_ASSERT(concurrentUse(kind) == states[!enabled]);
|
||||
concurrentUse(kind) = states[enabled];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// /////////// Chunk -> Arena Allocator //////////////////////////////////////
|
||||
|
||||
|
|
|
@ -237,26 +237,63 @@ js::gc::SortedArenaList::toArenaList()
|
|||
return ArenaList(segments[0]);
|
||||
}
|
||||
|
||||
void
|
||||
js::gc::ArenaLists::setFreeList(AllocKind i, FreeSpan* span)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
auto old = freeList(i);
|
||||
if (!old->isEmpty())
|
||||
old->getArena()->checkNoMarkedFreeCells();
|
||||
|
||||
bool
|
||||
js::gc::FreeLists::allEmpty() const
|
||||
{
|
||||
for (auto i : AllAllocKinds()) {
|
||||
if (!isEmpty(i))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::gc::FreeLists::isEmpty(AllocKind kind) const
|
||||
{
|
||||
return freeLists_[kind]->isEmpty();
|
||||
}
|
||||
|
||||
#endif
|
||||
freeLists()[i] = span;
|
||||
|
||||
void
|
||||
js::gc::FreeLists::clear()
|
||||
{
|
||||
for (auto i : AllAllocKinds()) {
|
||||
#ifdef DEBUG
|
||||
auto old = freeLists_[i];
|
||||
if (!old->isEmpty())
|
||||
old->getArena()->checkNoMarkedFreeCells();
|
||||
#endif
|
||||
freeLists_[i] = &emptySentinel;
|
||||
}
|
||||
}
|
||||
|
||||
js::gc::TenuredCell*
|
||||
js::gc::FreeLists::allocate(AllocKind kind)
|
||||
{
|
||||
return freeLists_[kind]->allocate(Arena::thingSize(kind));
|
||||
}
|
||||
|
||||
void
|
||||
js::gc::ArenaLists::clearFreeList(AllocKind i)
|
||||
js::gc::FreeLists::unmarkPreMarkedFreeCells(AllocKind kind)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
auto old = freeList(i);
|
||||
if (!old->isEmpty())
|
||||
old->getArena()->checkNoMarkedFreeCells();
|
||||
#endif
|
||||
freeLists()[i] = &emptySentinel;
|
||||
FreeSpan* freeSpan = freeLists_[kind];
|
||||
if (!freeSpan->isEmpty())
|
||||
freeSpan->getArena()->unmarkPreMarkedFreeCells();
|
||||
}
|
||||
|
||||
JSRuntime*
|
||||
js::gc::ArenaLists::runtime()
|
||||
{
|
||||
return zone_->runtimeFromMainThread();
|
||||
}
|
||||
|
||||
JSRuntime*
|
||||
js::gc::ArenaLists::runtimeFromAnyThread()
|
||||
{
|
||||
return zone_->runtimeFromAnyThread();
|
||||
}
|
||||
|
||||
js::gc::Arena*
|
||||
|
@ -293,7 +330,7 @@ js::gc::ArenaLists::arenaListsAreEmpty() const
|
|||
* The arena cannot be empty if the background finalization is not yet
|
||||
* done.
|
||||
*/
|
||||
if (backgroundFinalizeState(i) != BFS_DONE)
|
||||
if (concurrentUse(i) == ConcurrentUse::BackgroundFinalize)
|
||||
return false;
|
||||
if (!arenaLists(i).isEmpty())
|
||||
return false;
|
||||
|
@ -306,7 +343,7 @@ js::gc::ArenaLists::unmarkAll()
|
|||
{
|
||||
for (auto i : AllAllocKinds()) {
|
||||
/* The background finalization must have stopped at this point. */
|
||||
MOZ_ASSERT(backgroundFinalizeState(i) == BFS_DONE);
|
||||
MOZ_ASSERT(concurrentUse(i) == ConcurrentUse::None);
|
||||
for (Arena* arena = arenaLists(i).head(); arena; arena = arena->next)
|
||||
arena->unmarkAll();
|
||||
}
|
||||
|
@ -315,42 +352,38 @@ js::gc::ArenaLists::unmarkAll()
|
|||
bool
|
||||
js::gc::ArenaLists::doneBackgroundFinalize(AllocKind kind) const
|
||||
{
|
||||
return backgroundFinalizeState(kind) == BFS_DONE;
|
||||
return concurrentUse(kind) != ConcurrentUse::BackgroundFinalize;
|
||||
}
|
||||
|
||||
bool
|
||||
js::gc::ArenaLists::needBackgroundFinalizeWait(AllocKind kind) const
|
||||
{
|
||||
return backgroundFinalizeState(kind) != BFS_DONE;
|
||||
return concurrentUse(kind) == ConcurrentUse::BackgroundFinalize;
|
||||
}
|
||||
|
||||
void
|
||||
js::gc::ArenaLists::clearFreeLists()
|
||||
{
|
||||
for (auto i : AllAllocKinds())
|
||||
clearFreeList(i);
|
||||
}
|
||||
|
||||
bool
|
||||
js::gc::ArenaLists::arenaIsInUse(Arena* arena, AllocKind kind) const
|
||||
{
|
||||
MOZ_ASSERT(arena);
|
||||
return arena == freeList(kind)->getArenaUnchecked();
|
||||
freeLists().clear();
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE js::gc::TenuredCell*
|
||||
js::gc::ArenaLists::allocateFromFreeList(AllocKind thingKind, size_t thingSize)
|
||||
js::gc::ArenaLists::allocateFromFreeList(AllocKind thingKind)
|
||||
{
|
||||
return freeList(thingKind)->allocate(thingSize);
|
||||
return freeLists().allocate(thingKind);
|
||||
}
|
||||
|
||||
void
|
||||
js::gc::ArenaLists::unmarkPreMarkedFreeCells()
|
||||
{
|
||||
for (auto i : AllAllocKinds())
|
||||
freeLists().unmarkPreMarkedFreeCells(i);
|
||||
}
|
||||
|
||||
void
|
||||
js::gc::ArenaLists::checkEmptyFreeLists()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
for (auto i : AllAllocKinds())
|
||||
checkEmptyFreeList(i);
|
||||
#endif
|
||||
MOZ_ASSERT(freeLists().allEmpty());
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -366,10 +399,4 @@ js::gc::ArenaLists::checkEmptyArenaLists()
|
|||
return empty;
|
||||
}
|
||||
|
||||
void
|
||||
js::gc::ArenaLists::checkEmptyFreeList(AllocKind kind)
|
||||
{
|
||||
MOZ_ASSERT(freeList(kind)->isEmpty());
|
||||
}
|
||||
|
||||
#endif // gc_ArenaList_inl_h
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче