mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
013fb0680e
@ -132,6 +132,8 @@ AboutRedirector::NewChannel(nsIURI* aURI,
|
||||
nsIChannel** result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
NS_ENSURE_ARG_POINTER(aLoadInfo);
|
||||
|
||||
NS_ASSERTION(result, "must not be null");
|
||||
|
||||
nsAutoCString path = GetAboutModuleName(aURI);
|
||||
@ -172,26 +174,22 @@ AboutRedirector::NewChannel(nsIURI* aURI,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If tempURI links to an external URI (i.e. something other than
|
||||
// chrome:// or resource://) then set the LOAD_REPLACE flag on the
|
||||
// channel which forces the channel owner to reflect the displayed
|
||||
// chrome:// or resource://) then set the result principal URI on the
|
||||
// load info which forces the channel prncipal to reflect the displayed
|
||||
// URL rather then being the systemPrincipal.
|
||||
bool isUIResource = false;
|
||||
rv = NS_URIChainHasFlags(tempURI, nsIProtocolHandler::URI_IS_UI_RESOURCE,
|
||||
&isUIResource);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsLoadFlags loadFlags = isUIResource
|
||||
? static_cast<nsLoadFlags>(nsIChannel::LOAD_NORMAL)
|
||||
: static_cast<nsLoadFlags>(nsIChannel::LOAD_REPLACE);
|
||||
|
||||
rv = NS_NewChannelInternal(getter_AddRefs(tempChannel),
|
||||
tempURI,
|
||||
aLoadInfo,
|
||||
nullptr, // aLoadGroup
|
||||
nullptr, // aCallbacks
|
||||
loadFlags);
|
||||
aLoadInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!isUIResource) {
|
||||
aLoadInfo->SetResultPrincipalURI(tempURI);
|
||||
}
|
||||
tempChannel->SetOriginalURI(aURI);
|
||||
|
||||
NS_ADDREF(*result = tempChannel);
|
||||
|
@ -4,6 +4,6 @@ support-files =
|
||||
dummy_page.html
|
||||
|
||||
[browser_PreviewProvider.js]
|
||||
skip-if = os == 'linux' # bug 1343150
|
||||
skip-if = os == 'linux' || os == 'win' # bug 1343150
|
||||
[browser_remotenewtab_pageloads.js]
|
||||
[browser_newtab_overrides.js]
|
||||
|
@ -1,5 +1,5 @@
|
||||
This is the PDF.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 1.8.450
|
||||
Current extension version is: 1.8.467
|
||||
|
||||
Taken from upstream commit: 20975134
|
||||
Taken from upstream commit: 679ffc84
|
||||
|
@ -3656,8 +3656,8 @@ var _UnsupportedManager = function UnsupportedManagerClosure() {
|
||||
}();
|
||||
var version, build;
|
||||
{
|
||||
exports.version = version = '1.8.450';
|
||||
exports.build = build = '20975134';
|
||||
exports.version = version = '1.8.467';
|
||||
exports.build = build = '679ffc84';
|
||||
}
|
||||
exports.getDocument = getDocument;
|
||||
exports.LoopbackPort = LoopbackPort;
|
||||
@ -4659,8 +4659,8 @@ if (!_util.globalScope.PDFJS) {
|
||||
}
|
||||
var PDFJS = _util.globalScope.PDFJS;
|
||||
{
|
||||
PDFJS.version = '1.8.450';
|
||||
PDFJS.build = '20975134';
|
||||
PDFJS.version = '1.8.467';
|
||||
PDFJS.build = '679ffc84';
|
||||
}
|
||||
PDFJS.pdfBug = false;
|
||||
if (PDFJS.verbosity !== undefined) {
|
||||
@ -10007,8 +10007,8 @@ exports.TilingPattern = TilingPattern;
|
||||
"use strict";
|
||||
|
||||
|
||||
var pdfjsVersion = '1.8.450';
|
||||
var pdfjsBuild = '20975134';
|
||||
var pdfjsVersion = '1.8.467';
|
||||
var pdfjsBuild = '679ffc84';
|
||||
var pdfjsSharedUtil = __w_pdfjs_require__(0);
|
||||
var pdfjsDisplayGlobal = __w_pdfjs_require__(8);
|
||||
var pdfjsDisplayAPI = __w_pdfjs_require__(3);
|
||||
|
122
browser/extensions/pdfjs/content/build/pdf.worker.js
vendored
122
browser/extensions/pdfjs/content/build/pdf.worker.js
vendored
@ -1454,7 +1454,7 @@ var Dict = function DictClosure() {
|
||||
return nonSerializable;
|
||||
};
|
||||
function Dict(xref) {
|
||||
this.map = Object.create(null);
|
||||
this._map = Object.create(null);
|
||||
this.xref = xref;
|
||||
this.objId = null;
|
||||
this.suppressEncryption = false;
|
||||
@ -1468,32 +1468,32 @@ var Dict = function DictClosure() {
|
||||
var value;
|
||||
var xref = this.xref,
|
||||
suppressEncryption = this.suppressEncryption;
|
||||
if (typeof (value = this.map[key1]) !== 'undefined' || key1 in this.map || typeof key2 === 'undefined') {
|
||||
if (typeof (value = this._map[key1]) !== 'undefined' || key1 in this._map || typeof key2 === 'undefined') {
|
||||
return xref ? xref.fetchIfRef(value, suppressEncryption) : value;
|
||||
}
|
||||
if (typeof (value = this.map[key2]) !== 'undefined' || key2 in this.map || typeof key3 === 'undefined') {
|
||||
if (typeof (value = this._map[key2]) !== 'undefined' || key2 in this._map || typeof key3 === 'undefined') {
|
||||
return xref ? xref.fetchIfRef(value, suppressEncryption) : value;
|
||||
}
|
||||
value = this.map[key3] || null;
|
||||
value = this._map[key3] || null;
|
||||
return xref ? xref.fetchIfRef(value, suppressEncryption) : value;
|
||||
},
|
||||
getAsync: function Dict_getAsync(key1, key2, key3) {
|
||||
var value;
|
||||
var xref = this.xref,
|
||||
suppressEncryption = this.suppressEncryption;
|
||||
if (typeof (value = this.map[key1]) !== 'undefined' || key1 in this.map || typeof key2 === 'undefined') {
|
||||
if (typeof (value = this._map[key1]) !== 'undefined' || key1 in this._map || typeof key2 === 'undefined') {
|
||||
if (xref) {
|
||||
return xref.fetchIfRefAsync(value, suppressEncryption);
|
||||
}
|
||||
return Promise.resolve(value);
|
||||
}
|
||||
if (typeof (value = this.map[key2]) !== 'undefined' || key2 in this.map || typeof key3 === 'undefined') {
|
||||
if (typeof (value = this._map[key2]) !== 'undefined' || key2 in this._map || typeof key3 === 'undefined') {
|
||||
if (xref) {
|
||||
return xref.fetchIfRefAsync(value, suppressEncryption);
|
||||
}
|
||||
return Promise.resolve(value);
|
||||
}
|
||||
value = this.map[key3] || null;
|
||||
value = this._map[key3] || null;
|
||||
if (xref) {
|
||||
return xref.fetchIfRefAsync(value, suppressEncryption);
|
||||
}
|
||||
@ -1516,36 +1516,36 @@ var Dict = function DictClosure() {
|
||||
return value;
|
||||
},
|
||||
getRaw: function Dict_getRaw(key) {
|
||||
return this.map[key];
|
||||
return this._map[key];
|
||||
},
|
||||
getKeys: function Dict_getKeys() {
|
||||
return Object.keys(this.map);
|
||||
return Object.keys(this._map);
|
||||
},
|
||||
set: function Dict_set(key, value) {
|
||||
this.map[key] = value;
|
||||
this._map[key] = value;
|
||||
},
|
||||
has: function Dict_has(key) {
|
||||
return key in this.map;
|
||||
return key in this._map;
|
||||
},
|
||||
forEach: function Dict_forEach(callback) {
|
||||
for (var key in this.map) {
|
||||
for (var key in this._map) {
|
||||
callback(key, this.get(key));
|
||||
}
|
||||
}
|
||||
};
|
||||
Dict.empty = new Dict(null);
|
||||
Dict.merge = function Dict_merge(xref, dictArray) {
|
||||
var mergedDict = new Dict(xref);
|
||||
for (var i = 0, ii = dictArray.length; i < ii; i++) {
|
||||
var dict = dictArray[i];
|
||||
Dict.merge = function (xref, dictArray) {
|
||||
let mergedDict = new Dict(xref);
|
||||
for (let i = 0, ii = dictArray.length; i < ii; i++) {
|
||||
let dict = dictArray[i];
|
||||
if (!isDict(dict)) {
|
||||
continue;
|
||||
}
|
||||
for (var keyName in dict.map) {
|
||||
if (mergedDict.map[keyName]) {
|
||||
for (let keyName in dict._map) {
|
||||
if (mergedDict._map[keyName] !== undefined) {
|
||||
continue;
|
||||
}
|
||||
mergedDict.map[keyName] = dict.map[keyName];
|
||||
mergedDict._map[keyName] = dict._map[keyName];
|
||||
}
|
||||
}
|
||||
return mergedDict;
|
||||
@ -22751,86 +22751,83 @@ var FileSpec = function FileSpecClosure() {
|
||||
};
|
||||
return FileSpec;
|
||||
}();
|
||||
var ObjectLoader = function () {
|
||||
let ObjectLoader = function () {
|
||||
function mayHaveChildren(value) {
|
||||
return (0, _primitives.isRef)(value) || (0, _primitives.isDict)(value) || (0, _util.isArray)(value) || (0, _primitives.isStream)(value);
|
||||
}
|
||||
function addChildren(node, nodesToVisit) {
|
||||
var value;
|
||||
if ((0, _primitives.isDict)(node) || (0, _primitives.isStream)(node)) {
|
||||
var map;
|
||||
if ((0, _primitives.isDict)(node)) {
|
||||
map = node.map;
|
||||
} else {
|
||||
map = node.dict.map;
|
||||
}
|
||||
for (var key in map) {
|
||||
value = map[key];
|
||||
if (mayHaveChildren(value)) {
|
||||
nodesToVisit.push(value);
|
||||
let dict = (0, _primitives.isDict)(node) ? node : node.dict;
|
||||
let dictKeys = dict.getKeys();
|
||||
for (let i = 0, ii = dictKeys.length; i < ii; i++) {
|
||||
let rawValue = dict.getRaw(dictKeys[i]);
|
||||
if (mayHaveChildren(rawValue)) {
|
||||
nodesToVisit.push(rawValue);
|
||||
}
|
||||
}
|
||||
} else if ((0, _util.isArray)(node)) {
|
||||
for (var i = 0, ii = node.length; i < ii; i++) {
|
||||
value = node[i];
|
||||
for (let i = 0, ii = node.length; i < ii; i++) {
|
||||
let value = node[i];
|
||||
if (mayHaveChildren(value)) {
|
||||
nodesToVisit.push(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function ObjectLoader(obj, keys, xref) {
|
||||
this.obj = obj;
|
||||
function ObjectLoader(dict, keys, xref) {
|
||||
this.dict = dict;
|
||||
this.keys = keys;
|
||||
this.xref = xref;
|
||||
this.refSet = null;
|
||||
this.capability = null;
|
||||
}
|
||||
ObjectLoader.prototype = {
|
||||
load: function ObjectLoader_load() {
|
||||
var keys = this.keys;
|
||||
load() {
|
||||
this.capability = (0, _util.createPromiseCapability)();
|
||||
if (!(this.xref.stream instanceof _chunked_stream.ChunkedStream) || this.xref.stream.getMissingChunks().length === 0) {
|
||||
this.capability.resolve();
|
||||
return this.capability.promise;
|
||||
}
|
||||
let { keys, dict } = this;
|
||||
this.refSet = new _primitives.RefSet();
|
||||
var nodesToVisit = [];
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
nodesToVisit.push(this.obj[keys[i]]);
|
||||
let nodesToVisit = [];
|
||||
for (let i = 0, ii = keys.length; i < ii; i++) {
|
||||
let rawValue = dict.getRaw(keys[i]);
|
||||
if (rawValue !== undefined) {
|
||||
nodesToVisit.push(rawValue);
|
||||
}
|
||||
}
|
||||
this._walk(nodesToVisit);
|
||||
return this.capability.promise;
|
||||
},
|
||||
_walk: function ObjectLoader_walk(nodesToVisit) {
|
||||
var nodesToRevisit = [];
|
||||
var pendingRequests = [];
|
||||
_walk(nodesToVisit) {
|
||||
let nodesToRevisit = [];
|
||||
let pendingRequests = [];
|
||||
while (nodesToVisit.length) {
|
||||
var currentNode = nodesToVisit.pop();
|
||||
let currentNode = nodesToVisit.pop();
|
||||
if ((0, _primitives.isRef)(currentNode)) {
|
||||
if (this.refSet.has(currentNode)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
var ref = currentNode;
|
||||
this.refSet.put(ref);
|
||||
this.refSet.put(currentNode);
|
||||
currentNode = this.xref.fetch(currentNode);
|
||||
} catch (e) {
|
||||
if (!(e instanceof _util.MissingDataException)) {
|
||||
throw e;
|
||||
} catch (ex) {
|
||||
if (!(ex instanceof _util.MissingDataException)) {
|
||||
throw ex;
|
||||
}
|
||||
nodesToRevisit.push(currentNode);
|
||||
pendingRequests.push({
|
||||
begin: e.begin,
|
||||
end: e.end
|
||||
begin: ex.begin,
|
||||
end: ex.end
|
||||
});
|
||||
}
|
||||
}
|
||||
if (currentNode && currentNode.getBaseStreams) {
|
||||
var baseStreams = currentNode.getBaseStreams();
|
||||
var foundMissingData = false;
|
||||
for (var i = 0; i < baseStreams.length; i++) {
|
||||
var stream = baseStreams[i];
|
||||
let baseStreams = currentNode.getBaseStreams();
|
||||
let foundMissingData = false;
|
||||
for (let i = 0, ii = baseStreams.length; i < ii; i++) {
|
||||
let stream = baseStreams[i];
|
||||
if (stream.getMissingChunks && stream.getMissingChunks().length) {
|
||||
foundMissingData = true;
|
||||
pendingRequests.push({
|
||||
@ -22847,14 +22844,13 @@ var ObjectLoader = function () {
|
||||
}
|
||||
if (pendingRequests.length) {
|
||||
this.xref.stream.manager.requestRanges(pendingRequests).then(() => {
|
||||
nodesToVisit = nodesToRevisit;
|
||||
for (var i = 0; i < nodesToRevisit.length; i++) {
|
||||
var node = nodesToRevisit[i];
|
||||
for (let i = 0, ii = nodesToRevisit.length; i < ii; i++) {
|
||||
let node = nodesToRevisit[i];
|
||||
if ((0, _primitives.isRef)(node)) {
|
||||
this.refSet.remove(node);
|
||||
}
|
||||
}
|
||||
this._walk(nodesToVisit);
|
||||
this._walk(nodesToRevisit);
|
||||
}, this.capability.reject);
|
||||
return;
|
||||
}
|
||||
@ -27469,7 +27465,7 @@ var Annotation = function AnnotationClosure() {
|
||||
if (!resources) {
|
||||
return;
|
||||
}
|
||||
var objectLoader = new _obj.ObjectLoader(resources.map, keys, resources.xref);
|
||||
let objectLoader = new _obj.ObjectLoader(resources, keys, resources.xref);
|
||||
return objectLoader.load().then(function () {
|
||||
return resources;
|
||||
});
|
||||
@ -29006,7 +29002,7 @@ var Page = function PageClosure() {
|
||||
this.resourcesPromise = this.pdfManager.ensure(this, 'resources');
|
||||
}
|
||||
return this.resourcesPromise.then(() => {
|
||||
var objectLoader = new _obj.ObjectLoader(this.resources.map, keys, this.xref);
|
||||
let objectLoader = new _obj.ObjectLoader(this.resources, keys, this.xref);
|
||||
return objectLoader.load();
|
||||
});
|
||||
},
|
||||
@ -39780,8 +39776,8 @@ exports.Type1Parser = Type1Parser;
|
||||
"use strict";
|
||||
|
||||
|
||||
var pdfjsVersion = '1.8.450';
|
||||
var pdfjsBuild = '20975134';
|
||||
var pdfjsVersion = '1.8.467';
|
||||
var pdfjsBuild = '679ffc84';
|
||||
var pdfjsCoreWorker = __w_pdfjs_require__(17);
|
||||
;
|
||||
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
|
||||
|
@ -876,6 +876,7 @@ var PDFViewerApplication = {
|
||||
l10n: null,
|
||||
pageRotation: 0,
|
||||
isInitialViewSet: false,
|
||||
downloadComplete: false,
|
||||
viewerPrefs: {
|
||||
sidebarViewOnLoad: _pdf_sidebar.SidebarView.NONE,
|
||||
pdfBugEnabled: false,
|
||||
@ -891,6 +892,7 @@ var PDFViewerApplication = {
|
||||
url: '',
|
||||
baseUrl: '',
|
||||
externalServices: DefaultExternalServices,
|
||||
_boundEvents: {},
|
||||
initialize: function pdfViewInitialize(appConfig) {
|
||||
this.preferences = this.externalServices.createPreferences();
|
||||
configure(_pdfjsLib.PDFJS);
|
||||
@ -1204,7 +1206,9 @@ var PDFViewerApplication = {
|
||||
this.pdfDocumentProperties.setDocument(null, null);
|
||||
}
|
||||
this.store = null;
|
||||
this.pageRotation = 0;
|
||||
this.isInitialViewSet = false;
|
||||
this.downloadComplete = false;
|
||||
this.pdfSidebar.reset();
|
||||
this.pdfOutlineViewer.reset();
|
||||
this.pdfAttachmentViewer.reset();
|
||||
@ -1247,7 +1251,6 @@ var PDFViewerApplication = {
|
||||
this.pdfDocumentProperties.setFileSize(args.length);
|
||||
}
|
||||
}
|
||||
this.downloadComplete = false;
|
||||
let loadingTask = (0, _pdfjsLib.getDocument)(parameters);
|
||||
this.pdfLoadingTask = loadingTask;
|
||||
loadingTask.onPassword = (updateCallback, reason) => {
|
||||
@ -1373,12 +1376,10 @@ var PDFViewerApplication = {
|
||||
this.pdfLinkService.setDocument(pdfDocument, baseDocumentUrl);
|
||||
this.pdfDocumentProperties.setDocument(pdfDocument, this.url);
|
||||
let pdfViewer = this.pdfViewer;
|
||||
pdfViewer.currentScale = scale;
|
||||
pdfViewer.setDocument(pdfDocument);
|
||||
let firstPagePromise = pdfViewer.firstPagePromise;
|
||||
let pagesPromise = pdfViewer.pagesPromise;
|
||||
let onePageRendered = pdfViewer.onePageRendered;
|
||||
this.pageRotation = 0;
|
||||
let pdfThumbnailViewer = this.pdfThumbnailViewer;
|
||||
pdfThumbnailViewer.setDocument(pdfDocument);
|
||||
firstPagePromise.then(pdfPage => {
|
||||
@ -1618,8 +1619,11 @@ var PDFViewerApplication = {
|
||||
}
|
||||
this.forceRendering();
|
||||
},
|
||||
rotatePages: function pdfViewRotatePages(delta) {
|
||||
var pageNumber = this.page;
|
||||
rotatePages(delta) {
|
||||
if (!this.pdfDocument) {
|
||||
return;
|
||||
}
|
||||
let pageNumber = this.page;
|
||||
this.pageRotation = (this.pageRotation + 360 + delta) % 360;
|
||||
this.pdfViewer.pagesRotation = this.pageRotation;
|
||||
this.pdfThumbnailViewer.pagesRotation = this.pageRotation;
|
||||
@ -1632,12 +1636,14 @@ var PDFViewerApplication = {
|
||||
}
|
||||
this.pdfPresentationMode.request();
|
||||
},
|
||||
bindEvents: function pdfViewBindEvents() {
|
||||
var eventBus = this.eventBus;
|
||||
bindEvents() {
|
||||
let eventBus = this.eventBus;
|
||||
this._boundEvents.beforePrint = this.beforePrint.bind(this);
|
||||
this._boundEvents.afterPrint = this.afterPrint.bind(this);
|
||||
eventBus.on('resize', webViewerResize);
|
||||
eventBus.on('hashchange', webViewerHashchange);
|
||||
eventBus.on('beforeprint', this.beforePrint.bind(this));
|
||||
eventBus.on('afterprint', this.afterPrint.bind(this));
|
||||
eventBus.on('beforeprint', this._boundEvents.beforePrint);
|
||||
eventBus.on('afterprint', this._boundEvents.afterPrint);
|
||||
eventBus.on('pagerendered', webViewerPageRendered);
|
||||
eventBus.on('textlayerrendered', webViewerTextLayerRendered);
|
||||
eventBus.on('updateviewarea', webViewerUpdateViewarea);
|
||||
@ -1665,23 +1671,75 @@ var PDFViewerApplication = {
|
||||
eventBus.on('find', webViewerFind);
|
||||
eventBus.on('findfromurlhash', webViewerFindFromUrlHash);
|
||||
},
|
||||
bindWindowEvents: function pdfViewBindWindowEvents() {
|
||||
var eventBus = this.eventBus;
|
||||
bindWindowEvents() {
|
||||
let eventBus = this.eventBus;
|
||||
this._boundEvents.windowResize = () => {
|
||||
eventBus.dispatch('resize');
|
||||
};
|
||||
this._boundEvents.windowHashChange = () => {
|
||||
eventBus.dispatch('hashchange', { hash: document.location.hash.substring(1) });
|
||||
};
|
||||
this._boundEvents.windowBeforePrint = () => {
|
||||
eventBus.dispatch('beforeprint');
|
||||
};
|
||||
this._boundEvents.windowAfterPrint = () => {
|
||||
eventBus.dispatch('afterprint');
|
||||
};
|
||||
window.addEventListener('wheel', webViewerWheel);
|
||||
window.addEventListener('click', webViewerClick);
|
||||
window.addEventListener('keydown', webViewerKeyDown);
|
||||
window.addEventListener('resize', function windowResize() {
|
||||
eventBus.dispatch('resize');
|
||||
});
|
||||
window.addEventListener('hashchange', function windowHashChange() {
|
||||
eventBus.dispatch('hashchange', { hash: document.location.hash.substring(1) });
|
||||
});
|
||||
window.addEventListener('beforeprint', function windowBeforePrint() {
|
||||
eventBus.dispatch('beforeprint');
|
||||
});
|
||||
window.addEventListener('afterprint', function windowAfterPrint() {
|
||||
eventBus.dispatch('afterprint');
|
||||
});
|
||||
window.addEventListener('resize', this._boundEvents.windowResize);
|
||||
window.addEventListener('hashchange', this._boundEvents.windowHashChange);
|
||||
window.addEventListener('beforeprint', this._boundEvents.windowBeforePrint);
|
||||
window.addEventListener('afterprint', this._boundEvents.windowAfterPrint);
|
||||
},
|
||||
unbindEvents() {
|
||||
let eventBus = this.eventBus;
|
||||
eventBus.off('resize', webViewerResize);
|
||||
eventBus.off('hashchange', webViewerHashchange);
|
||||
eventBus.off('beforeprint', this._boundEvents.beforePrint);
|
||||
eventBus.off('afterprint', this._boundEvents.afterPrint);
|
||||
eventBus.off('pagerendered', webViewerPageRendered);
|
||||
eventBus.off('textlayerrendered', webViewerTextLayerRendered);
|
||||
eventBus.off('updateviewarea', webViewerUpdateViewarea);
|
||||
eventBus.off('pagechanging', webViewerPageChanging);
|
||||
eventBus.off('scalechanging', webViewerScaleChanging);
|
||||
eventBus.off('sidebarviewchanged', webViewerSidebarViewChanged);
|
||||
eventBus.off('pagemode', webViewerPageMode);
|
||||
eventBus.off('namedaction', webViewerNamedAction);
|
||||
eventBus.off('presentationmodechanged', webViewerPresentationModeChanged);
|
||||
eventBus.off('presentationmode', webViewerPresentationMode);
|
||||
eventBus.off('openfile', webViewerOpenFile);
|
||||
eventBus.off('print', webViewerPrint);
|
||||
eventBus.off('download', webViewerDownload);
|
||||
eventBus.off('firstpage', webViewerFirstPage);
|
||||
eventBus.off('lastpage', webViewerLastPage);
|
||||
eventBus.off('nextpage', webViewerNextPage);
|
||||
eventBus.off('previouspage', webViewerPreviousPage);
|
||||
eventBus.off('zoomin', webViewerZoomIn);
|
||||
eventBus.off('zoomout', webViewerZoomOut);
|
||||
eventBus.off('pagenumberchanged', webViewerPageNumberChanged);
|
||||
eventBus.off('scalechanged', webViewerScaleChanged);
|
||||
eventBus.off('rotatecw', webViewerRotateCw);
|
||||
eventBus.off('rotateccw', webViewerRotateCcw);
|
||||
eventBus.off('documentproperties', webViewerDocumentProperties);
|
||||
eventBus.off('find', webViewerFind);
|
||||
eventBus.off('findfromurlhash', webViewerFindFromUrlHash);
|
||||
this._boundEvents.beforePrint = null;
|
||||
this._boundEvents.afterPrint = null;
|
||||
},
|
||||
unbindWindowEvents() {
|
||||
window.removeEventListener('wheel', webViewerWheel);
|
||||
window.removeEventListener('click', webViewerClick);
|
||||
window.removeEventListener('keydown', webViewerKeyDown);
|
||||
window.removeEventListener('resize', this._boundEvents.windowResize);
|
||||
window.removeEventListener('hashchange', this._boundEvents.windowHashChange);
|
||||
window.removeEventListener('beforeprint', this._boundEvents.windowBeforePrint);
|
||||
window.removeEventListener('afterprint', this._boundEvents.windowAfterPrint);
|
||||
this._boundEvents.windowResize = null;
|
||||
this._boundEvents.windowHashChange = null;
|
||||
this._boundEvents.windowBeforePrint = null;
|
||||
this._boundEvents.windowAfterPrint = null;
|
||||
}
|
||||
};
|
||||
var validateFileURL;
|
||||
|
@ -53,7 +53,7 @@ if test "$GCC_USE_GNU_LD"; then
|
||||
EXPAND_LIBS_ORDER_STYLE=)
|
||||
LDFLAGS="$_SAVE_LDFLAGS"
|
||||
if test -z "$EXPAND_LIBS_ORDER_STYLE"; then
|
||||
if AC_TRY_COMMAND(${CC-cc} ${DSO_LDOPTS} ${LDFLAGS} -o ${DLL_PREFIX}conftest${DLL_SUFFIX} -Wl,--verbose 2> /dev/null | sed -n '/^===/,/^===/p' | grep '\.text'); then
|
||||
if AC_TRY_COMMAND(${CC-cc} ${DSO_LDOPTS} ${LDFLAGS} -o conftest -Wl,--verbose 2> /dev/null | sed -n '/^===/,/^===/p' | grep '\.text'); then
|
||||
EXPAND_LIBS_ORDER_STYLE=linkerscript
|
||||
else
|
||||
EXPAND_LIBS_ORDER_STYLE=none
|
||||
|
1
caps/tests/mochitest/file_bug1367586-followon.html
Normal file
1
caps/tests/mochitest/file_bug1367586-followon.html
Normal file
@ -0,0 +1 @@
|
||||
<body>Follow-on navigation content</body>
|
5
caps/tests/mochitest/file_bug1367586-redirect.sjs
Normal file
5
caps/tests/mochitest/file_bug1367586-redirect.sjs
Normal file
@ -0,0 +1,5 @@
|
||||
function handleRequest(aRequest, aResponse) {
|
||||
aResponse.setStatusLine(aRequest.httpVersion, 302, "Moved");
|
||||
aResponse.setHeader("Location", "http://mochi.test:8888/tests/caps/tests/mochitest/file_bug1367586-target.html");
|
||||
aResponse.write("To be redirected to target");
|
||||
}
|
6
caps/tests/mochitest/file_bug1367586-target.html
Normal file
6
caps/tests/mochitest/file_bug1367586-target.html
Normal file
@ -0,0 +1,6 @@
|
||||
<head><script>
|
||||
window.addEventListener("pageshow", function(event) {
|
||||
parent.ok(!event.persisted, "Should not load from bfcache");
|
||||
});
|
||||
</script></head>
|
||||
<body>Redirect target content</body>
|
@ -1,5 +1,8 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
file_bug1367586-followon.html
|
||||
file_bug1367586-redirect.sjs
|
||||
file_bug1367586-target.html
|
||||
file_data.txt
|
||||
file_disableScript.html
|
||||
!/js/xpconnect/tests/mochitest/file_empty.html
|
||||
@ -8,5 +11,6 @@ support-files =
|
||||
[test_bug292789.html]
|
||||
[test_bug423375.html]
|
||||
[test_bug470804.html]
|
||||
[test_bug1367586.html]
|
||||
[test_disallowInheritPrincipal.html]
|
||||
[test_extensionURL.html]
|
||||
|
50
caps/tests/mochitest/test_bug1367586.html
Normal file
50
caps/tests/mochitest/test_bug1367586.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1367586
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1367586</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="load-frame"></iframe>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var frm = document.getElementById("load-frame");
|
||||
var step = 0;
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
frm.contentWindow.location = "http://mochi.test:8888/tests/caps/tests/mochitest/file_bug1367586-redirect.sjs";
|
||||
frm.addEventListener("load", function() {
|
||||
++step;
|
||||
SimpleTest.executeSoon((function(_step, _frm) {
|
||||
switch (_step) {
|
||||
case 1:
|
||||
is(_frm.contentWindow.location.href, "http://mochi.test:8888/tests/caps/tests/mochitest/file_bug1367586-target.html",
|
||||
"Redirected to the expected target in step 1");
|
||||
_frm.contentWindow.location = "http://mochi.test:8888/tests/caps/tests/mochitest/file_bug1367586-followon.html";
|
||||
break;
|
||||
case 2:
|
||||
is(_frm.contentWindow.location.href, "http://mochi.test:8888/tests/caps/tests/mochitest/file_bug1367586-followon.html",
|
||||
"Navigated to the expected URL in step 2");
|
||||
_frm.contentWindow.history.back();
|
||||
break;
|
||||
case 3:
|
||||
is(_frm.contentWindow.location.href, "http://mochi.test:8888/tests/caps/tests/mochitest/file_bug1367586-target.html",
|
||||
"Seeing the correct URL when navigating back in step 3");
|
||||
SimpleTest.finish();
|
||||
break;
|
||||
}
|
||||
}).bind(window, step, frm));
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -105,6 +105,8 @@ nsChromeProtocolHandler::NewChannel2(nsIURI* aURI,
|
||||
nsresult rv;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
NS_ENSURE_ARG_POINTER(aLoadInfo);
|
||||
|
||||
NS_PRECONDITION(aResult, "Null out param");
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -145,6 +147,12 @@ nsChromeProtocolHandler::NewChannel2(nsIURI* aURI,
|
||||
return rv;
|
||||
}
|
||||
|
||||
// We don't want to allow the inner protocol handler modify the result principal URI
|
||||
// since we want either |aURI| or anything pre-set by upper layers to prevail.
|
||||
nsCOMPtr<nsIURI> savedResultPrincipalURI;
|
||||
rv = aLoadInfo->GetResultPrincipalURI(getter_AddRefs(savedResultPrincipalURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = NS_NewChannelInternal(getter_AddRefs(result),
|
||||
resolvedURI,
|
||||
aLoadInfo);
|
||||
@ -168,9 +176,8 @@ nsChromeProtocolHandler::NewChannel2(nsIURI* aURI,
|
||||
|
||||
// Make sure that the channel remembers where it was
|
||||
// originally loaded from.
|
||||
nsLoadFlags loadFlags = 0;
|
||||
result->GetLoadFlags(&loadFlags);
|
||||
result->SetLoadFlags(loadFlags & ~nsIChannel::LOAD_REPLACE);
|
||||
rv = aLoadInfo->SetResultPrincipalURI(savedResultPrincipalURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = result->SetOriginalURI(aURI);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -26,6 +26,7 @@ AboutURL.prototype = {
|
||||
newChannel: function (aURI, aLoadInfo) {
|
||||
let chan = Services.io.newChannelFromURIWithLoadInfo(this.uri, aLoadInfo);
|
||||
chan.owner = Services.scriptSecurityManager.getSystemPrincipal();
|
||||
chan.originalURI = aURI;
|
||||
return chan;
|
||||
},
|
||||
|
||||
|
@ -152,6 +152,7 @@ nsAboutRedirector::NewChannel(nsIURI* aURI,
|
||||
nsIChannel** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
NS_ENSURE_ARG_POINTER(aLoadInfo);
|
||||
NS_ASSERTION(aResult, "must not be null");
|
||||
|
||||
nsAutoCString path;
|
||||
@ -168,9 +169,14 @@ nsAboutRedirector::NewChannel(nsIURI* aURI,
|
||||
rv = NS_NewURI(getter_AddRefs(tempURI), kRedirMap[i].url);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = NS_NewChannelInternal(getter_AddRefs(tempChannel),
|
||||
tempURI,
|
||||
aLoadInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If tempURI links to an external URI (i.e. something other than
|
||||
// chrome:// or resource://) then set the LOAD_REPLACE flag on the
|
||||
// channel which forces the channel owner to reflect the displayed
|
||||
// chrome:// or resource://) then set result principal URI on the
|
||||
// load info which forces the channel principal to reflect the displayed
|
||||
// URL rather then being the systemPrincipal.
|
||||
bool isUIResource = false;
|
||||
rv = NS_URIChainHasFlags(tempURI, nsIProtocolHandler::URI_IS_UI_RESOURCE,
|
||||
@ -179,17 +185,9 @@ nsAboutRedirector::NewChannel(nsIURI* aURI,
|
||||
|
||||
bool isAboutBlank = NS_IsAboutBlank(tempURI);
|
||||
|
||||
nsLoadFlags loadFlags = isUIResource || isAboutBlank
|
||||
? static_cast<nsLoadFlags>(nsIChannel::LOAD_NORMAL)
|
||||
: static_cast<nsLoadFlags>(nsIChannel::LOAD_REPLACE);
|
||||
|
||||
rv = NS_NewChannelInternal(getter_AddRefs(tempChannel),
|
||||
tempURI,
|
||||
aLoadInfo,
|
||||
nullptr, // aLoadGroup
|
||||
nullptr, // aCallbacks
|
||||
loadFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!isUIResource && !isAboutBlank) {
|
||||
aLoadInfo->SetResultPrincipalURI(tempURI);
|
||||
}
|
||||
|
||||
tempChannel->SetOriginalURI(aURI);
|
||||
|
||||
|
@ -1272,6 +1272,7 @@ nsDocShell::LoadURI(nsIURI* aURI,
|
||||
|
||||
nsCOMPtr<nsIURI> referrer;
|
||||
nsCOMPtr<nsIURI> originalURI;
|
||||
Maybe<nsCOMPtr<nsIURI>> resultPrincipalURI;
|
||||
bool loadReplace = false;
|
||||
nsCOMPtr<nsIInputStream> postStream;
|
||||
nsCOMPtr<nsIInputStream> headersStream;
|
||||
@ -1300,6 +1301,7 @@ nsDocShell::LoadURI(nsIURI* aURI,
|
||||
if (aLoadInfo) {
|
||||
aLoadInfo->GetReferrer(getter_AddRefs(referrer));
|
||||
aLoadInfo->GetOriginalURI(getter_AddRefs(originalURI));
|
||||
GetMaybeResultPrincipalURI(aLoadInfo, resultPrincipalURI);
|
||||
aLoadInfo->GetLoadReplace(&loadReplace);
|
||||
nsDocShellInfoLoadType lt = nsIDocShellLoadInfo::loadNormal;
|
||||
aLoadInfo->GetLoadType(<);
|
||||
@ -1570,6 +1572,7 @@ nsDocShell::LoadURI(nsIURI* aURI,
|
||||
|
||||
return InternalLoad(aURI,
|
||||
originalURI,
|
||||
resultPrincipalURI,
|
||||
loadReplace,
|
||||
referrer,
|
||||
referrerPolicy,
|
||||
@ -5419,7 +5422,7 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, const char16_t* aURL,
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(errorPageURI), errorPageUrl);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return InternalLoad(errorPageURI, nullptr, false, nullptr,
|
||||
return InternalLoad(errorPageURI, nullptr, Nothing(), false, nullptr,
|
||||
mozilla::net::RP_Unset,
|
||||
nsContentUtils::GetSystemPrincipal(), nullptr,
|
||||
INTERNAL_LOAD_FLAGS_NONE, EmptyString(),
|
||||
@ -5474,6 +5477,7 @@ nsDocShell::Reload(uint32_t aReloadFlags)
|
||||
nsAutoString srcdoc;
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
nsCOMPtr<nsIURI> originalURI;
|
||||
nsCOMPtr<nsIURI> resultPrincipalURI;
|
||||
bool loadReplace = false;
|
||||
|
||||
nsIPrincipal* triggeringPrincipal = doc->NodePrincipal();
|
||||
@ -5494,6 +5498,11 @@ nsDocShell::Reload(uint32_t aReloadFlags)
|
||||
if (httpChan) {
|
||||
httpChan->GetOriginalURI(getter_AddRefs(originalURI));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = chan->GetLoadInfo();
|
||||
if (loadInfo) {
|
||||
loadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(triggeringPrincipal, "Need a valid triggeringPrincipal");
|
||||
@ -5503,8 +5512,13 @@ nsDocShell::Reload(uint32_t aReloadFlags)
|
||||
nsCOMPtr<nsIURI> currentURI = mCurrentURI;
|
||||
nsCOMPtr<nsIURI> referrerURI = mReferrerURI;
|
||||
uint32_t referrerPolicy = mReferrerPolicy;
|
||||
|
||||
// Reload always rewrites result principal URI.
|
||||
Maybe<nsCOMPtr<nsIURI>> emplacedResultPrincipalURI;
|
||||
emplacedResultPrincipalURI.emplace(Move(resultPrincipalURI));
|
||||
rv = InternalLoad(currentURI,
|
||||
originalURI,
|
||||
emplacedResultPrincipalURI,
|
||||
loadReplace,
|
||||
referrerURI,
|
||||
referrerPolicy,
|
||||
@ -9623,8 +9637,11 @@ nsDocShell::CopyFavicon(nsIURI* aOldURI,
|
||||
class InternalLoadEvent : public Runnable
|
||||
{
|
||||
public:
|
||||
InternalLoadEvent(nsDocShell* aDocShell, nsIURI* aURI,
|
||||
nsIURI* aOriginalURI, bool aLoadReplace,
|
||||
InternalLoadEvent(nsDocShell* aDocShell,
|
||||
nsIURI* aURI,
|
||||
nsIURI* aOriginalURI,
|
||||
Maybe<nsCOMPtr<nsIURI>> const& aResultPrincipalURI,
|
||||
bool aLoadReplace,
|
||||
nsIURI* aReferrer, uint32_t aReferrerPolicy,
|
||||
nsIPrincipal* aTriggeringPrincipal,
|
||||
nsIPrincipal* aPrincipalToInherit, uint32_t aFlags,
|
||||
@ -9637,6 +9654,7 @@ public:
|
||||
, mDocShell(aDocShell)
|
||||
, mURI(aURI)
|
||||
, mOriginalURI(aOriginalURI)
|
||||
, mResultPrincipalURI(aResultPrincipalURI)
|
||||
, mLoadReplace(aLoadReplace)
|
||||
, mReferrer(aReferrer)
|
||||
, mReferrerPolicy(aReferrerPolicy)
|
||||
@ -9661,7 +9679,7 @@ public:
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
return mDocShell->InternalLoad(mURI, mOriginalURI,
|
||||
return mDocShell->InternalLoad(mURI, mOriginalURI, mResultPrincipalURI,
|
||||
mLoadReplace,
|
||||
mReferrer,
|
||||
mReferrerPolicy,
|
||||
@ -9682,6 +9700,7 @@ private:
|
||||
RefPtr<nsDocShell> mDocShell;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIURI> mOriginalURI;
|
||||
Maybe<nsCOMPtr<nsIURI>> mResultPrincipalURI;
|
||||
bool mLoadReplace;
|
||||
nsCOMPtr<nsIURI> mReferrer;
|
||||
uint32_t mReferrerPolicy;
|
||||
@ -9728,6 +9747,7 @@ nsDocShell::CreatePrincipalFromReferrer(nsIURI* aReferrer,
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::InternalLoad(nsIURI* aURI,
|
||||
nsIURI* aOriginalURI,
|
||||
Maybe<nsCOMPtr<nsIURI>> const& aResultPrincipalURI,
|
||||
bool aLoadReplace,
|
||||
nsIURI* aReferrer,
|
||||
uint32_t aReferrerPolicy,
|
||||
@ -10063,6 +10083,7 @@ nsDocShell::InternalLoad(nsIURI* aURI,
|
||||
loadInfo->SetSendReferrer(!(aFlags &
|
||||
INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER));
|
||||
loadInfo->SetOriginalURI(aOriginalURI);
|
||||
SetMaybeResultPrincipalURI(loadInfo, aResultPrincipalURI);
|
||||
loadInfo->SetLoadReplace(aLoadReplace);
|
||||
loadInfo->SetTriggeringPrincipal(aTriggeringPrincipal);
|
||||
loadInfo->SetInheritPrincipal(
|
||||
@ -10110,6 +10131,7 @@ nsDocShell::InternalLoad(nsIURI* aURI,
|
||||
if (NS_SUCCEEDED(rv) && targetDocShell) {
|
||||
rv = targetDocShell->InternalLoad(aURI,
|
||||
aOriginalURI,
|
||||
aResultPrincipalURI,
|
||||
aLoadReplace,
|
||||
aReferrer,
|
||||
aReferrerPolicy,
|
||||
@ -10206,8 +10228,8 @@ nsDocShell::InternalLoad(nsIURI* aURI,
|
||||
|
||||
// Do this asynchronously
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new InternalLoadEvent(this, aURI, aOriginalURI, aLoadReplace,
|
||||
aReferrer, aReferrerPolicy,
|
||||
new InternalLoadEvent(this, aURI, aOriginalURI, aResultPrincipalURI,
|
||||
aLoadReplace, aReferrer, aReferrerPolicy,
|
||||
aTriggeringPrincipal, principalToInherit,
|
||||
aFlags, aTypeHint, aPostData, aHeadersData,
|
||||
aLoadType, aSHEntry, aFirstParty, aSrcdoc,
|
||||
@ -10590,8 +10612,8 @@ nsDocShell::InternalLoad(nsIURI* aURI,
|
||||
|
||||
if (browserChrome3 && aCheckForPrerender) {
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new InternalLoadEvent(this, aURI, aOriginalURI, aLoadReplace,
|
||||
aReferrer, aReferrerPolicy,
|
||||
new InternalLoadEvent(this, aURI, aOriginalURI, aResultPrincipalURI,
|
||||
aLoadReplace, aReferrer, aReferrerPolicy,
|
||||
aTriggeringPrincipal, principalToInherit,
|
||||
aFlags, aTypeHint, aPostData, aHeadersData,
|
||||
aLoadType, aSHEntry, aFirstParty, aSrcdoc,
|
||||
@ -10740,7 +10762,7 @@ nsDocShell::InternalLoad(nsIURI* aURI,
|
||||
nsINetworkPredictor::PREDICT_LOAD, attrs, nullptr);
|
||||
|
||||
nsCOMPtr<nsIRequest> req;
|
||||
rv = DoURILoad(aURI, aOriginalURI, aLoadReplace, aReferrer,
|
||||
rv = DoURILoad(aURI, aOriginalURI, aResultPrincipalURI, aLoadReplace, aReferrer,
|
||||
!(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER),
|
||||
aReferrerPolicy,
|
||||
aTriggeringPrincipal, principalToInherit, aTypeHint,
|
||||
@ -10819,6 +10841,7 @@ nsDocShell::GetInheritedPrincipal(bool aConsiderCurrentDocument)
|
||||
nsresult
|
||||
nsDocShell::DoURILoad(nsIURI* aURI,
|
||||
nsIURI* aOriginalURI,
|
||||
Maybe<nsCOMPtr<nsIURI>> const& aResultPrincipalURI,
|
||||
bool aLoadReplace,
|
||||
nsIURI* aReferrerURI,
|
||||
bool aSendReferrer,
|
||||
@ -11134,6 +11157,12 @@ nsDocShell::DoURILoad(nsIURI* aURI,
|
||||
|
||||
if (aOriginalURI) {
|
||||
channel->SetOriginalURI(aOriginalURI);
|
||||
// The LOAD_REPLACE flag and its handling here will be removed as part
|
||||
// of bug 1319110. For now preserve its restoration here to not break
|
||||
// any code expecting it being set specially on redirected channels.
|
||||
// If the flag has originally been set to change result of
|
||||
// NS_GetFinalChannelURI it won't have any effect and also won't cause
|
||||
// any harm.
|
||||
if (aLoadReplace) {
|
||||
uint32_t loadFlags;
|
||||
channel->GetLoadFlags(&loadFlags);
|
||||
@ -11144,6 +11173,12 @@ nsDocShell::DoURILoad(nsIURI* aURI,
|
||||
channel->SetOriginalURI(aURI);
|
||||
}
|
||||
|
||||
if (aResultPrincipalURI) {
|
||||
// Unconditionally override, we want the replay to be equal to what has
|
||||
// been captured.
|
||||
loadInfo->SetResultPrincipalURI(aResultPrincipalURI.ref());
|
||||
}
|
||||
|
||||
if (aTypeHint && *aTypeHint) {
|
||||
channel->SetContentType(nsDependentCString(aTypeHint));
|
||||
mContentTypeHint = aTypeHint;
|
||||
@ -12364,6 +12399,7 @@ nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel,
|
||||
// Get the post data & referrer
|
||||
nsCOMPtr<nsIInputStream> inputStream;
|
||||
nsCOMPtr<nsIURI> originalURI;
|
||||
nsCOMPtr<nsIURI> resultPrincipalURI;
|
||||
bool loadReplace = false;
|
||||
nsCOMPtr<nsIURI> referrerURI;
|
||||
uint32_t referrerPolicy = mozilla::net::RP_Unset;
|
||||
@ -12411,6 +12447,8 @@ nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel,
|
||||
triggeringPrincipal = loadInfo->TriggeringPrincipal();
|
||||
}
|
||||
|
||||
loadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
|
||||
|
||||
// For now keep storing just the principal in the SHEntry.
|
||||
if (!principalToInherit) {
|
||||
if (loadInfo->GetLoadingSandboxed()) {
|
||||
@ -12443,6 +12481,7 @@ nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel,
|
||||
mDynamicallyCreated);
|
||||
|
||||
entry->SetOriginalURI(originalURI);
|
||||
entry->SetResultPrincipalURI(resultPrincipalURI);
|
||||
entry->SetLoadReplace(loadReplace);
|
||||
entry->SetReferrerURI(referrerURI);
|
||||
entry->SetReferrerPolicy(referrerPolicy);
|
||||
@ -12556,6 +12595,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType)
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsCOMPtr<nsIURI> originalURI;
|
||||
nsCOMPtr<nsIURI> resultPrincipalURI;
|
||||
bool loadReplace = false;
|
||||
nsCOMPtr<nsIInputStream> postData;
|
||||
nsCOMPtr<nsIURI> referrerURI;
|
||||
@ -12569,6 +12609,8 @@ nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType)
|
||||
NS_ENSURE_SUCCESS(aEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(aEntry->GetOriginalURI(getter_AddRefs(originalURI)),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(aEntry->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI)),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(aEntry->GetLoadReplace(&loadReplace),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(aEntry->GetReferrerURI(getter_AddRefs(referrerURI)),
|
||||
@ -12656,8 +12698,11 @@ nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType)
|
||||
// aSourceDocShell was introduced. According to spec we should be passing
|
||||
// the source browsing context that was used when the history entry was
|
||||
// first created. bug 947716 has been created to address this issue.
|
||||
Maybe<nsCOMPtr<nsIURI>> emplacedResultPrincipalURI;
|
||||
emplacedResultPrincipalURI.emplace(Move(resultPrincipalURI));
|
||||
rv = InternalLoad(uri,
|
||||
originalURI,
|
||||
emplacedResultPrincipalURI,
|
||||
loadReplace,
|
||||
referrerURI,
|
||||
referrerPolicy,
|
||||
@ -14210,6 +14255,7 @@ nsDocShell::OnLinkClickSync(nsIContent* aContent,
|
||||
|
||||
nsresult rv = InternalLoad(clonedURI, // New URI
|
||||
nullptr, // Original URI
|
||||
Nothing(), // Let the protocol handler assign it
|
||||
false, // LoadReplace
|
||||
referer, // Referer URI
|
||||
refererPolicy, // Referer policy
|
||||
|
@ -371,6 +371,7 @@ protected:
|
||||
// If aLoadReplace is true, LOAD_REPLACE flag will be set to the nsIChannel.
|
||||
nsresult DoURILoad(nsIURI* aURI,
|
||||
nsIURI* aOriginalURI,
|
||||
mozilla::Maybe<nsCOMPtr<nsIURI>> const& aResultPrincipalURI,
|
||||
bool aLoadReplace,
|
||||
nsIURI* aReferrer,
|
||||
bool aSendReferrer,
|
||||
|
@ -10,9 +10,61 @@
|
||||
#include "nsIURI.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
GetMaybeResultPrincipalURI(nsIDocShellLoadInfo* aLoadInfo, Maybe<nsCOMPtr<nsIURI>>& aRPURI)
|
||||
{
|
||||
if (!aLoadInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
bool isSome;
|
||||
rv = aLoadInfo->GetResultPrincipalURIIsSome(&isSome);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
aRPURI.reset();
|
||||
|
||||
if (!isSome) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = aLoadInfo->GetResultPrincipalURI(getter_AddRefs(uri));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
aRPURI.emplace(Move(uri));
|
||||
}
|
||||
|
||||
void
|
||||
SetMaybeResultPrincipalURI(nsIDocShellLoadInfo* aLoadInfo, Maybe<nsCOMPtr<nsIURI>> const& aRPURI)
|
||||
{
|
||||
if (!aLoadInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
rv = aLoadInfo->SetResultPrincipalURI(aRPURI.refOr(nullptr));
|
||||
Unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
|
||||
rv = aLoadInfo->SetResultPrincipalURIIsSome(aRPURI.isSome());
|
||||
Unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
|
||||
} // mozilla
|
||||
|
||||
nsDocShellLoadInfo::nsDocShellLoadInfo()
|
||||
: mLoadReplace(false)
|
||||
: mResultPrincipalURIIsSome(false)
|
||||
, mLoadReplace(false)
|
||||
, mInheritPrincipal(false)
|
||||
, mPrincipalIsExplicit(false)
|
||||
, mSendReferrer(true)
|
||||
@ -68,6 +120,37 @@ nsDocShellLoadInfo::SetOriginalURI(nsIURI* aOriginalURI)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShellLoadInfo::GetResultPrincipalURI(nsIURI** aResultPrincipalURI)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResultPrincipalURI);
|
||||
|
||||
*aResultPrincipalURI = mResultPrincipalURI;
|
||||
NS_IF_ADDREF(*aResultPrincipalURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShellLoadInfo::SetResultPrincipalURI(nsIURI* aResultPrincipalURI)
|
||||
{
|
||||
mResultPrincipalURI = aResultPrincipalURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShellLoadInfo::GetResultPrincipalURIIsSome(bool* aIsSome)
|
||||
{
|
||||
*aIsSome = mResultPrincipalURIIsSome;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShellLoadInfo::SetResultPrincipalURIIsSome(bool aIsSome)
|
||||
{
|
||||
mResultPrincipalURIIsSome = aIsSome;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShellLoadInfo::GetLoadReplace(bool* aLoadReplace)
|
||||
{
|
||||
|
@ -33,7 +33,9 @@ protected:
|
||||
protected:
|
||||
nsCOMPtr<nsIURI> mReferrer;
|
||||
nsCOMPtr<nsIURI> mOriginalURI;
|
||||
nsCOMPtr<nsIURI> mResultPrincipalURI;
|
||||
nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
|
||||
bool mResultPrincipalURIIsSome;
|
||||
bool mLoadReplace;
|
||||
bool mInheritPrincipal;
|
||||
bool mPrincipalIsExplicit;
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
%{ C++
|
||||
#include "js/TypeDecls.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
class nsPresContext;
|
||||
class nsIPresShell;
|
||||
%}
|
||||
@ -20,6 +21,7 @@ class nsIPresShell;
|
||||
|
||||
[ptr] native nsPresContext(nsPresContext);
|
||||
[ptr] native nsIPresShell(nsIPresShell);
|
||||
[ref] native MaybeURI(mozilla::Maybe<nsCOMPtr<nsIURI>>);
|
||||
|
||||
interface nsIURI;
|
||||
interface nsIChannel;
|
||||
@ -127,6 +129,10 @@ interface nsIDocShell : nsIDocShellTreeItem
|
||||
* @param aOriginalURI - The URI to set as the originalURI on the channel
|
||||
* that does the load. If null, aURI will be set as
|
||||
* the originalURI.
|
||||
* @param aResultPrincipalURI - The URI to be set to loadInfo.resultPrincipalURI
|
||||
* When Nothing, there will be no change
|
||||
* When Some, the principal URI will overwrite even
|
||||
* with a null value.
|
||||
* @param aLoadReplace - If set LOAD_REPLACE flag will be set on the
|
||||
* channel. aOriginalURI is null, this argument is
|
||||
* ignored.
|
||||
@ -174,6 +180,7 @@ interface nsIDocShell : nsIDocShellTreeItem
|
||||
*/
|
||||
[noscript]void internalLoad(in nsIURI aURI,
|
||||
in nsIURI aOriginalURI,
|
||||
[const] in MaybeURI aResultPrincipalURI,
|
||||
in boolean aLoadReplace,
|
||||
in nsIURI aReferrer,
|
||||
in unsigned long aReferrerPolicy,
|
||||
|
@ -31,6 +31,16 @@ interface nsIDocShellLoadInfo : nsISupports
|
||||
*/
|
||||
attribute nsIURI originalURI;
|
||||
|
||||
/**
|
||||
* Result principal URL from nsILoadInfo, may be null. Valid only if
|
||||
* the "IsSome" part is true (has the same meaning as isSome()
|
||||
* on mozilla::Maybe.)
|
||||
*
|
||||
* In C++ please use Get/SetMaybeResultPrincipalURI helper functions.
|
||||
*/
|
||||
attribute nsIURI resultPrincipalURI;
|
||||
attribute boolean resultPrincipalURIIsSome;
|
||||
|
||||
/**
|
||||
* loadReplace flag to be passed to nsIDocShell.internalLoad.
|
||||
*/
|
||||
@ -123,3 +133,22 @@ interface nsIDocShellLoadInfo : nsISupports
|
||||
*/
|
||||
attribute nsIURI baseURI;
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* Helper function allowing convenient work with mozilla::Maybe in C++, hiding
|
||||
* resultPrincipalURI and resultPrincipalURIIsSome attributes from the consumer.
|
||||
*/
|
||||
void
|
||||
GetMaybeResultPrincipalURI(nsIDocShellLoadInfo* aLoadInfo, Maybe<nsCOMPtr<nsIURI>>& aRPURI);
|
||||
void
|
||||
SetMaybeResultPrincipalURI(nsIDocShellLoadInfo* aLoadInfo, Maybe<nsCOMPtr<nsIURI>> const& aRPURI);
|
||||
|
||||
} // mozilla
|
||||
|
||||
%}
|
||||
|
@ -49,6 +49,12 @@ interface nsISHEntry : nsISupports
|
||||
*/
|
||||
attribute nsIURI originalURI;
|
||||
|
||||
/**
|
||||
* URL as stored from nsILoadInfo.resultPrincipalURI. See nsILoadInfo
|
||||
* for more details.
|
||||
*/
|
||||
attribute nsIURI resultPrincipalURI;
|
||||
|
||||
/**
|
||||
* This flag remembers whether channel has LOAD_REPLACE set.
|
||||
*/
|
||||
|
@ -137,6 +137,21 @@ nsSHEntry::SetOriginalURI(nsIURI* aOriginalURI)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetResultPrincipalURI(nsIURI** aResultPrincipalURI)
|
||||
{
|
||||
*aResultPrincipalURI = mResultPrincipalURI;
|
||||
NS_IF_ADDREF(*aResultPrincipalURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetResultPrincipalURI(nsIURI* aResultPrincipalURI)
|
||||
{
|
||||
mResultPrincipalURI = aResultPrincipalURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetLoadReplace(bool* aLoadReplace)
|
||||
{
|
||||
|
@ -47,6 +47,7 @@ private:
|
||||
// See nsSHEntry.idl for comments on these members.
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIURI> mOriginalURI;
|
||||
nsCOMPtr<nsIURI> mResultPrincipalURI;
|
||||
nsCOMPtr<nsIURI> mReferrerURI;
|
||||
uint32_t mReferrerPolicy;
|
||||
nsString mTitle;
|
||||
|
@ -6,7 +6,7 @@ pref(dom.animations-api.core.enabled,true) load 1216842-3.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1216842-4.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1216842-5.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1216842-6.html
|
||||
skip-if(webrender) pref(dom.animations-api.core.enabled,true) load 1272475-1.html # see bug 1367994
|
||||
pref(dom.animations-api.core.enabled,true) load 1272475-1.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1272475-2.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1278485-1.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1277272-1.html
|
||||
|
@ -352,7 +352,7 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
|
||||
nsLayoutUtils::GetContainingBlockForClientRect(targetFrame),
|
||||
nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS
|
||||
);
|
||||
intersectionRect = Some(targetFrame->GetVisualOverflowRect());
|
||||
intersectionRect = Some(targetFrame->GetRectRelativeToSelf());
|
||||
|
||||
nsIFrame* containerFrame = nsLayoutUtils::GetCrossDocParentFrame(targetFrame);
|
||||
while (containerFrame && containerFrame != rootFrame) {
|
||||
|
@ -569,8 +569,14 @@ nsAttrAndChildArray::IndexOfAttr(nsIAtom* aLocalName, int32_t aNamespaceID) cons
|
||||
uint32_t slotCount = AttrSlotCount();
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
// This should be the common case so lets make an optimized loop
|
||||
for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) {
|
||||
// Note that here we don't check for AttrSlotIsTaken() in the loop
|
||||
// condition for the sake of performance because comparing aLocalName
|
||||
// against null would fail in the loop body (since Equals() just compares
|
||||
// the raw pointer value of aLocalName to what AttrSlotIsTaken() would be
|
||||
// checking.
|
||||
for (i = 0; i < slotCount; ++i) {
|
||||
if (ATTRS(mImpl)[i].mName.Equals(aLocalName)) {
|
||||
MOZ_ASSERT(AttrSlotIsTaken(i), "sanity check");
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -101,6 +101,10 @@ public:
|
||||
}
|
||||
|
||||
// Faster comparison in the case we know the namespace is null
|
||||
// Note that some callers such as nsAttrAndChildArray::IndexOfAttr() will
|
||||
// call this function on nsAttrName structs with 0 mBits, so no attempt
|
||||
// must be made to do anything with mBits besides comparing it with the
|
||||
// incoming aAtom argument.
|
||||
bool Equals(nsIAtom* aAtom) const
|
||||
{
|
||||
return reinterpret_cast<uintptr_t>(aAtom) == mBits;
|
||||
|
@ -6049,6 +6049,10 @@ nsDocument::CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value*
|
||||
bool
|
||||
nsDocument::IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject)
|
||||
{
|
||||
if (!nsContentUtils::IsWebComponentsEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx, aObject);
|
||||
|
||||
JSAutoCompartment ac(aCx, obj);
|
||||
@ -6056,15 +6060,6 @@ nsDocument::IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject)
|
||||
nsCOMPtr<nsPIDOMWindowInner> window =
|
||||
do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(global));
|
||||
|
||||
bool enabled =
|
||||
nsContentUtils::IsWebComponentsEnabled() ||
|
||||
// Check for the webcomponents permission. See Bug 1181555.
|
||||
IsWebComponentsEnabled(window);
|
||||
|
||||
if (!enabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIDocument* doc = window ? window->GetExtantDoc() : nullptr;
|
||||
if (doc && doc->IsStyledByServo()) {
|
||||
NS_WARNING("stylo: Web Components not supported yet");
|
||||
@ -6077,21 +6072,11 @@ nsDocument::IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject)
|
||||
bool
|
||||
nsDocument::IsWebComponentsEnabled(dom::NodeInfo* aNodeInfo)
|
||||
{
|
||||
nsIDocument* doc = aNodeInfo->GetDocument();
|
||||
|
||||
bool enabled = nsContentUtils::IsWebComponentsEnabled();
|
||||
if (!enabled) {
|
||||
// Use GetScopeObject() here so that data documents work the same way as the
|
||||
// main document they're associated with.
|
||||
nsCOMPtr<nsPIDOMWindowInner> window =
|
||||
do_QueryInterface(doc->GetScopeObject());
|
||||
enabled = IsWebComponentsEnabled(window);
|
||||
}
|
||||
|
||||
if (!enabled) {
|
||||
if (!nsContentUtils::IsWebComponentsEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIDocument* doc = aNodeInfo->GetDocument();
|
||||
if (doc->IsStyledByServo()) {
|
||||
NS_WARNING("stylo: Web Components not supported yet");
|
||||
return false;
|
||||
@ -6100,26 +6085,6 @@ nsDocument::IsWebComponentsEnabled(dom::NodeInfo* aNodeInfo)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocument::IsWebComponentsEnabled(nsPIDOMWindowInner* aWindow)
|
||||
{
|
||||
if (aWindow) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPermissionManager> permMgr =
|
||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
uint32_t perm;
|
||||
rv = permMgr->TestPermissionFromWindow(
|
||||
aWindow, "moz-extremely-unstable-and-will-change-webcomponents", &perm);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
return perm == nsIPermissionManager::ALLOW_ACTION;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::ScheduleSVGForPresAttrEvaluation(nsSVGElement* aSVG)
|
||||
{
|
||||
|
@ -1395,9 +1395,6 @@ private:
|
||||
void UpdatePossiblyStaleDocumentState();
|
||||
static bool CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value* aVp);
|
||||
|
||||
// Check whether web components are enabled for the given window.
|
||||
static bool IsWebComponentsEnabled(nsPIDOMWindowInner* aWindow);
|
||||
|
||||
public:
|
||||
virtual already_AddRefed<mozilla::dom::CustomElementRegistry>
|
||||
GetCustomElementRegistry() override;
|
||||
|
@ -3446,12 +3446,27 @@ def getConditionList(idlobj, cxName, objName):
|
||||
|
||||
objName is the name of the object that we're working with, because some of
|
||||
our test functions want that.
|
||||
|
||||
The return value is a pair. The first element is a possibly-empty CGList
|
||||
of conditions. The second element, if not None, is a CGThing for som code
|
||||
that needs to run before the list of conditions can be evaluated.
|
||||
"""
|
||||
conditions = []
|
||||
conditionSetup = None
|
||||
pref = idlobj.getExtendedAttribute("Pref")
|
||||
if pref:
|
||||
assert isinstance(pref, list) and len(pref) == 1
|
||||
conditions.append('Preferences::GetBool("%s")' % pref[0])
|
||||
conditionSetup = CGGeneric(fill(
|
||||
"""
|
||||
static bool sPrefValue;
|
||||
static bool sPrefCacheSetUp = false;
|
||||
if (!sPrefCacheSetUp) {
|
||||
sPrefCacheSetUp = true;
|
||||
Preferences::AddBoolVarCache(&sPrefValue, "${prefName}");
|
||||
}
|
||||
""",
|
||||
prefName=pref[0]))
|
||||
conditions.append("sPrefValue")
|
||||
if idlobj.getExtendedAttribute("ChromeOnly"):
|
||||
conditions.append("nsContentUtils::ThreadsafeIsSystemCaller(%s)" % cxName)
|
||||
func = idlobj.getExtendedAttribute("Func")
|
||||
@ -3461,7 +3476,8 @@ def getConditionList(idlobj, cxName, objName):
|
||||
if idlobj.getExtendedAttribute("SecureContext"):
|
||||
conditions.append("mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(%s, %s)" % (cxName, objName))
|
||||
|
||||
return CGList((CGGeneric(cond) for cond in conditions), " &&\n")
|
||||
return (CGList((CGGeneric(cond) for cond in conditions), " &&\n"),
|
||||
conditionSetup)
|
||||
|
||||
|
||||
class CGConstructorEnabled(CGAbstractMethod):
|
||||
@ -3505,13 +3521,14 @@ class CGConstructorEnabled(CGAbstractMethod):
|
||||
"!NS_IsMainThread()")
|
||||
body.append(exposedInWorkerCheck)
|
||||
|
||||
conditions = getConditionList(iface, "aCx", "aObj")
|
||||
(conditions, conditionsSetup) = getConditionList(iface, "aCx", "aObj")
|
||||
|
||||
# We should really have some conditions
|
||||
assert len(body) or len(conditions)
|
||||
|
||||
conditionsWrapper = ""
|
||||
if len(conditions):
|
||||
body.append(conditionsSetup);
|
||||
conditionsWrapper = CGWrapper(conditions,
|
||||
pre="return ",
|
||||
post=";\n",
|
||||
@ -13328,7 +13345,12 @@ class CGDictionary(CGThing):
|
||||
return false;
|
||||
}
|
||||
"""))
|
||||
conditions = getConditionList(member, "cx", "*object")
|
||||
(conditions, conditionsSetup) = getConditionList(member, "cx", "*object")
|
||||
if conditionsSetup is not None:
|
||||
raise TypeError("We don't support Pref annotations on dictionary "
|
||||
"members. If we start to, we need to make sure all "
|
||||
"the variable names conditionsSetup uses for a "
|
||||
"given dictionary are unique.")
|
||||
if len(conditions) != 0:
|
||||
setTempValue = CGIfElseWrapper(conditions.define(),
|
||||
setTempValue,
|
||||
@ -13444,7 +13466,12 @@ class CGDictionary(CGThing):
|
||||
if member.canHaveMissingValue():
|
||||
# Only do the conversion if we have a value
|
||||
conversion = CGIfWrapper(conversion, "%s.WasPassed()" % memberLoc)
|
||||
conditions = getConditionList(member, "cx", "obj")
|
||||
(conditions, conditionsSetup) = getConditionList(member, "cx", "obj")
|
||||
if conditionsSetup is not None:
|
||||
raise TypeError("We don't support Pref annotations on dictionary "
|
||||
"members. If we start to, we need to make sure all "
|
||||
"the variable names conditionsSetup uses for a "
|
||||
"given dictionary are unique.")
|
||||
if len(conditions) != 0:
|
||||
conversion = CGIfWrapper(conversion, conditions.define())
|
||||
return conversion
|
||||
|
@ -2872,8 +2872,15 @@ nsTextEditorState::UpdateOverlayTextVisibility(bool aNotify)
|
||||
mPreviewVisibility = valueIsEmpty && !previewValue.IsEmpty();
|
||||
mPlaceholderVisibility = valueIsEmpty && previewValue.IsEmpty();
|
||||
|
||||
if (mPlaceholderVisibility &&
|
||||
!Preferences::GetBool("dom.placeholder.show_on_focus", true)) {
|
||||
static bool sPrefCached = false;
|
||||
static bool sPrefShowOnFocus = true;
|
||||
if (!sPrefCached) {
|
||||
sPrefCached = true;
|
||||
Preferences::AddBoolVarCache(&sPrefShowOnFocus,
|
||||
"dom.placeholder.show_on_focus", true);
|
||||
}
|
||||
|
||||
if (mPlaceholderVisibility && !sPrefShowOnFocus) {
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mTextCtrlElement);
|
||||
mPlaceholderVisibility = !nsContentUtils::IsFocusedContent(content);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ support-files =
|
||||
[test_multiple_register_different_scope.html]
|
||||
[test_subscription_change.html]
|
||||
[test_data.html]
|
||||
skip-if = os == "win" && !debug # Bug 1373346
|
||||
[test_try_registering_offline_disabled.html]
|
||||
[test_serviceworker_lifetime.html]
|
||||
[test_error_reporting.html]
|
||||
|
@ -9,10 +9,13 @@
|
||||
#include "GeckoProfiler.h" // for PROFILER_LABEL
|
||||
#include "client/ClientLayerManager.h" // for ClientLayerManager, etc
|
||||
#include "gfxContext.h" // for gfxContext
|
||||
#include "gfx2DGlue.h"
|
||||
#include "gfxRect.h" // for gfxRect
|
||||
#include "gfxPrefs.h" // for gfxPrefs
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
||||
#include "mozilla/gfx/2D.h" // for DrawTarget
|
||||
#include "mozilla/gfx/DrawEventRecorder.h"
|
||||
#include "mozilla/gfx/InlineTranslator.h"
|
||||
#include "mozilla/gfx/Matrix.h" // for Matrix
|
||||
#include "mozilla/gfx/Rect.h" // for Rect, IntRect
|
||||
#include "mozilla/gfx/Types.h" // for Float, etc
|
||||
@ -21,7 +24,7 @@
|
||||
#include "nsCOMPtr.h" // for already_AddRefed
|
||||
#include "nsISupportsImpl.h" // for Layer::AddRef, etc
|
||||
#include "nsRect.h" // for mozilla::gfx::IntRect
|
||||
#include "gfx2DGlue.h"
|
||||
#include "PaintThread.h"
|
||||
#include "ReadbackProcessor.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -29,45 +32,102 @@ namespace layers {
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
void
|
||||
ClientPaintedLayer::PaintThebes(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates)
|
||||
bool
|
||||
ClientPaintedLayer::EnsureContentClient()
|
||||
{
|
||||
PROFILER_LABEL("ClientPaintedLayer", "PaintThebes",
|
||||
js::ProfileEntry::Category::GRAPHICS);
|
||||
if (!mContentClient) {
|
||||
mContentClient = ContentClient::CreateContentClient(
|
||||
ClientManager()->AsShadowForwarder());
|
||||
|
||||
NS_ASSERTION(ClientManager()->InDrawing(),
|
||||
"Can only draw in drawing phase");
|
||||
|
||||
mContentClient->BeginPaint();
|
||||
|
||||
uint32_t flags = RotatedContentBuffer::PAINT_CAN_DRAW_ROTATED;
|
||||
#ifndef MOZ_IGNORE_PAINT_WILL_RESAMPLE
|
||||
if (ClientManager()->CompositorMightResample()) {
|
||||
flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE;
|
||||
}
|
||||
if (!(flags & RotatedContentBuffer::PAINT_WILL_RESAMPLE)) {
|
||||
if (MayResample()) {
|
||||
flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE;
|
||||
if (!mContentClient) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
PaintState state =
|
||||
mContentClient->BeginPaintBuffer(this, flags);
|
||||
SubtractFromValidRegion(state.mRegionToInvalidate);
|
||||
|
||||
if (!state.mRegionToDraw.IsEmpty() && !ClientManager()->GetPaintedLayerCallback()) {
|
||||
mContentClient->Connect();
|
||||
ClientManager()->AsShadowForwarder()->Attach(mContentClient, this);
|
||||
MOZ_ASSERT(mContentClient->GetForwarder());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ClientPaintedLayer::CanRecordLayer(ReadbackProcessor* aReadback)
|
||||
{
|
||||
// If we don't have a paint thread, this is either not the content
|
||||
// process or the pref is disabled.
|
||||
if (!PaintThread::Get()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Not supported yet
|
||||
if (aReadback && UsedForReadback()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we have mask layers, we have to render those first
|
||||
// In this case, don't record for now.
|
||||
if (GetMaskLayer()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return GetAncestorMaskLayerCount() == 0;
|
||||
}
|
||||
|
||||
void
|
||||
ClientPaintedLayer::UpdateContentClient(PaintState& aState)
|
||||
{
|
||||
Mutated();
|
||||
|
||||
AddToValidRegion(aState.mRegionToDraw);
|
||||
|
||||
ContentClientRemote *contentClientRemote =
|
||||
static_cast<ContentClientRemote *>(mContentClient.get());
|
||||
MOZ_ASSERT(contentClientRemote->GetIPCHandle());
|
||||
|
||||
// Hold(this) ensures this layer is kept alive through the current transaction
|
||||
// The ContentClient assumes this layer is kept alive (e.g., in CreateBuffer),
|
||||
// so deleting this Hold for whatever reason will break things.
|
||||
ClientManager()->Hold(this);
|
||||
contentClientRemote->Updated(aState.mRegionToDraw,
|
||||
mVisibleRegion.ToUnknownRegion(),
|
||||
aState.mDidSelfCopy);
|
||||
}
|
||||
|
||||
bool
|
||||
ClientPaintedLayer::UpdatePaintRegion(PaintState& aState)
|
||||
{
|
||||
SubtractFromValidRegion(aState.mRegionToInvalidate);
|
||||
|
||||
if (!aState.mRegionToDraw.IsEmpty() && !ClientManager()->GetPaintedLayerCallback()) {
|
||||
ClientManager()->SetTransactionIncomplete();
|
||||
mContentClient->EndPaint(nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
// The area that became invalid and is visible needs to be repainted
|
||||
// (this could be the whole visible area if our buffer switched
|
||||
// from RGB to RGBA, because we might need to repaint with
|
||||
// subpixel AA)
|
||||
aState.mRegionToInvalidate.And(aState.mRegionToInvalidate,
|
||||
GetLocalVisibleRegion().ToUnknownRegion());
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ClientPaintedLayer::ReplayPaintedLayer(DrawEventRecorderMemory* aRecorder)
|
||||
{
|
||||
LayerIntRegion visibleRegion = GetVisibleRegion();
|
||||
mContentClient->BeginPaint();
|
||||
|
||||
uint32_t flags = GetPaintFlags();
|
||||
|
||||
PaintState state =
|
||||
mContentClient->BeginPaintBuffer(this, flags);
|
||||
if (!UpdatePaintRegion(state)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The area that became invalid and is visible needs to be repainted
|
||||
// (this could be the whole visible area if our buffer switched
|
||||
// from RGB to RGBA, because we might need to repaint with
|
||||
// subpixel AA)
|
||||
state.mRegionToInvalidate.And(state.mRegionToInvalidate,
|
||||
GetLocalVisibleRegion().ToUnknownRegion());
|
||||
|
||||
bool didUpdate = false;
|
||||
RotatedContentBuffer::DrawIterator iter;
|
||||
while (DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(state, &iter)) {
|
||||
@ -77,7 +137,77 @@ ClientPaintedLayer::PaintThebes(nsTArray<ReadbackProcessor::Update>* aReadbackUp
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
SetAntialiasingFlags(this, target);
|
||||
|
||||
// Draw all the things into the actual content client
|
||||
// This shouldn't exist in the future. For now, its just testing
|
||||
// to make sure we properly record and can replay all the draw
|
||||
// commands
|
||||
std::istream& stream = aRecorder->GetInputStream();
|
||||
InlineTranslator translator(target, nullptr);
|
||||
translator.TranslateRecording(stream);
|
||||
|
||||
mContentClient->ReturnDrawTargetToBuffer(target);
|
||||
didUpdate = true;
|
||||
}
|
||||
|
||||
// ending paint w/o any readback updates
|
||||
// TODO: Fix me
|
||||
mContentClient->EndPaint(nullptr);
|
||||
|
||||
if (didUpdate) {
|
||||
UpdateContentClient(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
ClientPaintedLayer::GetPaintFlags()
|
||||
{
|
||||
uint32_t flags = RotatedContentBuffer::PAINT_CAN_DRAW_ROTATED;
|
||||
#ifndef MOZ_IGNORE_PAINT_WILL_RESAMPLE
|
||||
if (ClientManager()->CompositorMightResample()) {
|
||||
flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE;
|
||||
}
|
||||
if (!(flags & RotatedContentBuffer::PAINT_WILL_RESAMPLE)) {
|
||||
if (MayResample()) {
|
||||
flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return flags;
|
||||
}
|
||||
|
||||
void
|
||||
ClientPaintedLayer::PaintThebes(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates)
|
||||
{
|
||||
PROFILER_LABEL("ClientPaintedLayer", "PaintThebes",
|
||||
js::ProfileEntry::Category::GRAPHICS);
|
||||
|
||||
NS_ASSERTION(ClientManager()->InDrawing(),
|
||||
"Can only draw in drawing phase");
|
||||
|
||||
mContentClient->BeginPaint();
|
||||
|
||||
uint32_t flags = GetPaintFlags();
|
||||
|
||||
PaintState state =
|
||||
mContentClient->BeginPaintBuffer(this, flags);
|
||||
if (!UpdatePaintRegion(state)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool didUpdate = false;
|
||||
RotatedContentBuffer::DrawIterator iter;
|
||||
while (DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(state, &iter)) {
|
||||
if (!target || !target->IsValid()) {
|
||||
if (target) {
|
||||
mContentClient->ReturnDrawTargetToBuffer(target);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
SetAntialiasingFlags(this, target);
|
||||
|
||||
RefPtr<gfxContext> ctx = gfxContext::CreatePreservingTransformOrNull(target);
|
||||
@ -99,36 +229,89 @@ ClientPaintedLayer::PaintThebes(nsTArray<ReadbackProcessor::Update>* aReadbackUp
|
||||
mContentClient->EndPaint(aReadbackUpdates);
|
||||
|
||||
if (didUpdate) {
|
||||
Mutated();
|
||||
|
||||
AddToValidRegion(state.mRegionToDraw);
|
||||
|
||||
ContentClientRemote* contentClientRemote = static_cast<ContentClientRemote*>(mContentClient.get());
|
||||
MOZ_ASSERT(contentClientRemote->GetIPCHandle());
|
||||
|
||||
// Hold(this) ensures this layer is kept alive through the current transaction
|
||||
// The ContentClient assumes this layer is kept alive (e.g., in CreateBuffer),
|
||||
// so deleting this Hold for whatever reason will break things.
|
||||
ClientManager()->Hold(this);
|
||||
contentClientRemote->Updated(state.mRegionToDraw,
|
||||
mVisibleRegion.ToUnknownRegion(),
|
||||
state.mDidSelfCopy);
|
||||
UpdateContentClient(state);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<DrawEventRecorderMemory>
|
||||
ClientPaintedLayer::RecordPaintedLayer()
|
||||
{
|
||||
LayerIntRegion visibleRegion = GetVisibleRegion();
|
||||
LayerIntRect bounds = visibleRegion.GetBounds();
|
||||
LayerIntSize size = bounds.Size();
|
||||
|
||||
if (visibleRegion.IsEmpty()) {
|
||||
if (gfxPrefs::LayersDump()) {
|
||||
printf_stderr("PaintedLayer %p skipping\n", this);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIntRegion regionToPaint;
|
||||
regionToPaint.Sub(mVisibleRegion.ToUnknownRegion(), GetValidRegion());
|
||||
|
||||
if (regionToPaint.IsEmpty()) {
|
||||
// Do we ever have to do anything if the region to paint is empty
|
||||
// but we have a painted layer callback?
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!ClientManager()->GetPaintedLayerCallback()) {
|
||||
ClientManager()->SetTransactionIncomplete();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// I know this is slow and we should probably use DrawTargetCapture
|
||||
// But for now, the recording draw target / replay should actually work
|
||||
// Replay for WR happens in Moz2DIMageRenderer
|
||||
IntSize imageSize(size.ToUnknownSize());
|
||||
|
||||
// DrawTargetRecording also plays back the commands while
|
||||
// recording, hence the dummy DT. DummyDT will actually have
|
||||
// the drawn painted layer.
|
||||
RefPtr<DrawEventRecorderMemory> recorder =
|
||||
MakeAndAddRef<DrawEventRecorderMemory>();
|
||||
RefPtr<DrawTarget> dummyDt =
|
||||
Factory::CreateDrawTarget(gfx::BackendType::SKIA, imageSize, gfx::SurfaceFormat::B8G8R8A8);
|
||||
|
||||
RefPtr<DrawTarget> dt =
|
||||
Factory::CreateRecordingDrawTarget(recorder, dummyDt, imageSize);
|
||||
|
||||
dt->ClearRect(Rect(0, 0, imageSize.width, imageSize.height));
|
||||
dt->SetTransform(Matrix().PreTranslate(-bounds.x, -bounds.y));
|
||||
RefPtr<gfxContext> ctx = gfxContext::CreatePreservingTransformOrNull(dt);
|
||||
MOZ_ASSERT(ctx); // already checked the target above
|
||||
|
||||
ClientManager()->GetPaintedLayerCallback()(this,
|
||||
ctx,
|
||||
visibleRegion.ToUnknownRegion(),
|
||||
visibleRegion.ToUnknownRegion(),
|
||||
DrawRegionClip::DRAW,
|
||||
nsIntRegion(),
|
||||
ClientManager()->GetPaintedLayerCallbackData());
|
||||
|
||||
return recorder.forget();
|
||||
}
|
||||
|
||||
void
|
||||
ClientPaintedLayer::RenderLayerWithReadback(ReadbackProcessor *aReadback)
|
||||
{
|
||||
RenderMaskLayers(this);
|
||||
|
||||
if (!mContentClient) {
|
||||
mContentClient = ContentClient::CreateContentClient(ClientManager()->AsShadowForwarder());
|
||||
if (!mContentClient) {
|
||||
|
||||
if (CanRecordLayer(aReadback)) {
|
||||
RefPtr<DrawEventRecorderMemory> recorder = RecordPaintedLayer();
|
||||
if (recorder) {
|
||||
if (!EnsureContentClient()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ReplayPaintedLayer(recorder);
|
||||
return;
|
||||
}
|
||||
mContentClient->Connect();
|
||||
ClientManager()->AsShadowForwarder()->Attach(mContentClient, this);
|
||||
MOZ_ASSERT(mContentClient->GetForwarder());
|
||||
}
|
||||
|
||||
if (!EnsureContentClient()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsTArray<ReadbackProcessor::Update> readbackUpdates;
|
||||
|
@ -19,8 +19,11 @@
|
||||
#include "mozilla/layers/PLayerTransaction.h" // for PaintedLayerAttributes
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
namespace gfx {
|
||||
class DrawEventRecorderMemory;
|
||||
};
|
||||
|
||||
namespace layers {
|
||||
class CompositableClient;
|
||||
class ShadowableLayer;
|
||||
class SpecificLayerAttributes;
|
||||
@ -109,6 +112,15 @@ public:
|
||||
|
||||
protected:
|
||||
void PaintThebes(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates);
|
||||
void RecordThebes();
|
||||
bool CanRecordLayer(ReadbackProcessor* aReadback);
|
||||
bool HasMaskLayers();
|
||||
already_AddRefed<gfx::DrawEventRecorderMemory> RecordPaintedLayer();
|
||||
void ReplayPaintedLayer(DrawEventRecorderMemory* aRecorder);
|
||||
bool EnsureContentClient();
|
||||
uint32_t GetPaintFlags();
|
||||
void UpdateContentClient(PaintState& aState);
|
||||
bool UpdatePaintRegion(PaintState& aState);
|
||||
|
||||
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include <vector>
|
||||
#include "GeckoProfiler.h" // for GeckoProfiler
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
#include "ProfilerMarkerPayload.h" // for LayerTranslationPayload
|
||||
#include "ProfilerMarkerPayload.h" // for LayerTranslationMarkerPayload
|
||||
#endif
|
||||
|
||||
#define CULLING_LOG(...)
|
||||
@ -102,7 +102,7 @@ PrintUniformityInfo(Layer* aLayer)
|
||||
Point translation = transform.As2D().GetTranslation();
|
||||
PROFILER_MARKER_PAYLOAD(
|
||||
"LayerTranslation",
|
||||
MakeUnique<LayerTranslationPayload>(aLayer, translation));
|
||||
MakeUnique<LayerTranslationMarkerPayload>(aLayer, translation));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1765,7 +1765,7 @@ InsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
PROFILER_MARKER_PAYLOAD(
|
||||
"VsyncTimestamp",
|
||||
MakeUnique<VsyncPayload>(aVsyncTimestamp));
|
||||
MakeUnique<VsyncMarkerPayload>(aVsyncTimestamp));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ AnimationState::UpdateState(bool aAnimationFinished,
|
||||
DefaultSurfaceFlags(),
|
||||
PlaybackType::eAnimated));
|
||||
|
||||
return UpdateStateInternal(result, aAnimationFinished, aSize);
|
||||
return UpdateStateInternal(result, aAnimationFinished, aSize, aAllowInvalidation);
|
||||
}
|
||||
|
||||
const gfx::IntRect
|
||||
|
@ -182,11 +182,13 @@ MessageLoop::MessageLoop(Type type, nsIThread* aThread)
|
||||
#endif // OS_WIN
|
||||
transient_hang_timeout_(0),
|
||||
permanent_hang_timeout_(0),
|
||||
next_sequence_num_(0),
|
||||
mEventTarget(new EventTarget(this)) {
|
||||
next_sequence_num_(0) {
|
||||
DCHECK(!current()) << "should only have one message loop per thread";
|
||||
get_tls_ptr().Set(this);
|
||||
|
||||
// Must initialize after current() is initialized.
|
||||
mEventTarget = new EventTarget(this);
|
||||
|
||||
switch (type_) {
|
||||
case TYPE_MOZILLA_PARENT:
|
||||
MOZ_RELEASE_ASSERT(!aThread);
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/nsRedirectHistoryEntry.h"
|
||||
#include "URIUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
@ -346,6 +347,13 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo,
|
||||
sandboxedLoadingPrincipalInfo = sandboxedLoadingPrincipalInfoTemp;
|
||||
}
|
||||
|
||||
OptionalURIParams optionalResultPrincipalURI = mozilla::void_t();
|
||||
nsCOMPtr<nsIURI> resultPrincipalURI;
|
||||
Unused << aLoadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
|
||||
if (resultPrincipalURI) {
|
||||
SerializeURI(resultPrincipalURI, optionalResultPrincipalURI);
|
||||
}
|
||||
|
||||
nsTArray<RedirectHistoryEntryInfo> redirectChainIncludingInternalRedirects;
|
||||
for (const nsCOMPtr<nsIRedirectHistoryEntry>& redirectEntry :
|
||||
aLoadInfo->RedirectChainIncludingInternalRedirects()) {
|
||||
@ -368,6 +376,7 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo,
|
||||
triggeringPrincipalInfo,
|
||||
principalToInheritInfo,
|
||||
sandboxedLoadingPrincipalInfo,
|
||||
optionalResultPrincipalURI,
|
||||
aLoadInfo->GetSecurityFlags(),
|
||||
aLoadInfo->InternalContentPolicyType(),
|
||||
static_cast<uint32_t>(aLoadInfo->GetTainting()),
|
||||
@ -434,6 +443,12 @@ LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> resultPrincipalURI;
|
||||
if (loadInfoArgs.resultPrincipalURI().type() != OptionalURIParams::Tvoid_t) {
|
||||
resultPrincipalURI = DeserializeURI(loadInfoArgs.resultPrincipalURI());
|
||||
NS_ENSURE_TRUE(resultPrincipalURI, NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
||||
RedirectHistoryArray redirectChainIncludingInternalRedirects;
|
||||
for (const RedirectHistoryEntryInfo& entryInfo :
|
||||
loadInfoArgs.redirectChainIncludingInternalRedirects()) {
|
||||
@ -456,6 +471,7 @@ LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs,
|
||||
triggeringPrincipal,
|
||||
principalToInherit,
|
||||
sandboxedLoadingPrincipal,
|
||||
resultPrincipalURI,
|
||||
loadInfoArgs.securityFlags(),
|
||||
loadInfoArgs.contentPolicyType(),
|
||||
static_cast<LoadTainting>(loadInfoArgs.tainting()),
|
||||
|
@ -248,6 +248,7 @@ def main(argv):
|
||||
options.exclude += ['debug/bug1160182.js']
|
||||
options.exclude += ['xdr/incremental-encoder.js']
|
||||
options.exclude += ['xdr/bug1186973.js'] # Bug 1369785
|
||||
options.exclude += ['xdr/relazify.js']
|
||||
options.exclude += ['basic/werror.js']
|
||||
|
||||
# Prevent code coverage test that expects coverage
|
||||
|
10
js/src/jit-test/tests/bug1366925.js
Normal file
10
js/src/jit-test/tests/bug1366925.js
Normal file
@ -0,0 +1,10 @@
|
||||
// JS shell shutdown ordering
|
||||
|
||||
// Avoid crashing with --no-threads
|
||||
if (helperThreadCount() == 0)
|
||||
quit();
|
||||
|
||||
evalInWorker(`
|
||||
var lfGlobal = newGlobal();
|
||||
lfGlobal.offThreadCompileScript(\`{ let x; throw 42; }\`);
|
||||
`);
|
@ -1496,8 +1496,12 @@ IonBuilder::visitBlock(const CFGBlock* cfgblock, MBasicBlock* mblock)
|
||||
mblock->setHitCount(script()->getHitCount(mblock->pc()));
|
||||
|
||||
// Optimization to move a predecessor that only has this block as successor
|
||||
// just before this block.
|
||||
if (mblock->numPredecessors() == 1 && mblock->getPredecessor(0)->numSuccessors() == 1) {
|
||||
// just before this block. Skip this optimization if the previous block is
|
||||
// not part of the same function, as we might have to backtrack on inlining
|
||||
// failures.
|
||||
if (mblock->numPredecessors() == 1 && mblock->getPredecessor(0)->numSuccessors() == 1 &&
|
||||
!mblock->getPredecessor(0)->outerResumePoint())
|
||||
{
|
||||
graph().removeBlockFromList(mblock->getPredecessor(0));
|
||||
graph().addBlock(mblock->getPredecessor(0));
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ DefaultJitOptions::DefaultJitOptions()
|
||||
SET_DEFAULT(checkRangeAnalysis, false);
|
||||
|
||||
// Toggles whether IonBuilder fallbacks to a call if we fail to inline.
|
||||
SET_DEFAULT(disableInlineBacktracking, true);
|
||||
SET_DEFAULT(disableInlineBacktracking, false);
|
||||
|
||||
// Toggles whether Alignment Mask Analysis is globally disabled.
|
||||
SET_DEFAULT(disableAma, false);
|
||||
|
@ -403,14 +403,6 @@ AS_BIN=$AS
|
||||
AR_EXTRACT='$(AR) x'
|
||||
AS='$(CC)'
|
||||
AS_DASH_C_FLAG='-c'
|
||||
DLL_PREFIX=lib
|
||||
LIB_PREFIX=lib
|
||||
RUST_LIB_PREFIX=lib
|
||||
DLL_SUFFIX=.so
|
||||
OBJ_SUFFIX=o
|
||||
LIB_SUFFIX=a
|
||||
RUST_LIB_SUFFIX=a
|
||||
IMPORT_LIB_SUFFIX=
|
||||
DIRENT_INO=d_ino
|
||||
MOZ_USER_DIR=".mozilla"
|
||||
|
||||
@ -561,7 +553,6 @@ case "$target" in
|
||||
MOZ_OPTIMIZE_FLAGS="-O3 -fno-stack-protector"
|
||||
CFLAGS="$CFLAGS -fno-common"
|
||||
CXXFLAGS="$CXXFLAGS -fno-common -stdlib=libc++"
|
||||
DLL_SUFFIX=".dylib"
|
||||
DSO_LDOPTS=''
|
||||
STRIP="$STRIP -x -S"
|
||||
LDFLAGS="$LDFLAGS -lobjc"
|
||||
@ -633,7 +624,6 @@ case "$target" in
|
||||
*-mingw*)
|
||||
DSO_CFLAGS=
|
||||
DSO_PIC_CFLAGS=
|
||||
DLL_SUFFIX=.dll
|
||||
RC=rc.exe
|
||||
if test -n "$GNU_CC" -o -n "$CLANG_CC"; then
|
||||
CC="$CC -mwindows"
|
||||
@ -652,8 +642,6 @@ case "$target" in
|
||||
# mingw doesn't require kernel32, user32, and advapi32 explicitly
|
||||
LIBS="$LIBS -lgdi32 -lwinmm -lwsock32"
|
||||
MOZ_FIX_LINK_PATHS=
|
||||
DLL_PREFIX=
|
||||
IMPORT_LIB_SUFFIX=a
|
||||
|
||||
WIN32_CONSOLE_EXE_LDFLAGS=-mconsole
|
||||
WIN32_GUI_EXE_LDFLAGS=-mwindows
|
||||
@ -670,13 +658,6 @@ case "$target" in
|
||||
RANLIB='echo not_ranlib'
|
||||
STRIP='echo not_strip'
|
||||
PKG_SKIP_STRIP=1
|
||||
OBJ_SUFFIX=obj
|
||||
LIB_SUFFIX=lib
|
||||
RUST_LIB_SUFFIX=lib
|
||||
DLL_PREFIX=
|
||||
LIB_PREFIX=
|
||||
RUST_LIB_PREFIX=
|
||||
IMPORT_LIB_SUFFIX=lib
|
||||
MKSHLIB='$(LINK) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
|
||||
MKCSHLIB='$(LINK) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
|
||||
WIN32_SUBSYSTEM_VERSION=6.01
|
||||
@ -849,13 +830,11 @@ case "$target" in
|
||||
CFLAGS="$CFLAGS -Dunix"
|
||||
CXXFLAGS="$CXXFLAGS -Dunix"
|
||||
if $CC -E - -dM </dev/null | grep __ELF__ >/dev/null; then
|
||||
DLL_SUFFIX=".so"
|
||||
DSO_PIC_CFLAGS='-fPIC -DPIC'
|
||||
DSO_LDOPTS='-shared'
|
||||
BIN_FLAGS='-Wl,--export-dynamic'
|
||||
else
|
||||
DSO_PIC_CFLAGS='-fPIC -DPIC'
|
||||
DLL_SUFFIX=".so.1.0"
|
||||
DSO_LDOPTS='-shared'
|
||||
fi
|
||||
# This will fail on a.out systems prior to 1.5.1_ALPHA.
|
||||
@ -867,7 +846,6 @@ case "$target" in
|
||||
;;
|
||||
|
||||
*-openbsd*)
|
||||
DLL_SUFFIX=".so.1.0"
|
||||
DSO_CFLAGS=''
|
||||
DSO_PIC_CFLAGS='-fPIC'
|
||||
DSO_LDOPTS='-shared -fPIC'
|
||||
@ -2102,16 +2080,7 @@ AC_SUBST(MKCSHLIB)
|
||||
AC_SUBST(DSO_CFLAGS)
|
||||
AC_SUBST(DSO_PIC_CFLAGS)
|
||||
AC_SUBST(DSO_LDOPTS)
|
||||
AC_SUBST(LIB_PREFIX)
|
||||
AC_SUBST(RUST_LIB_PREFIX)
|
||||
AC_SUBST(DLL_PREFIX)
|
||||
AC_SUBST(DLL_SUFFIX)
|
||||
AC_DEFINE_UNQUOTED(MOZ_DLL_SUFFIX, "$DLL_SUFFIX")
|
||||
AC_SUBST(LIB_SUFFIX)
|
||||
AC_SUBST(RUST_LIB_SUFFIX)
|
||||
AC_SUBST(OBJ_SUFFIX)
|
||||
AC_SUBST(BIN_SUFFIX)
|
||||
AC_SUBST(IMPORT_LIB_SUFFIX)
|
||||
AC_SUBST(USE_N32)
|
||||
AC_SUBST(CC_VERSION)
|
||||
AC_SUBST(MOZ_LINKER)
|
||||
|
@ -3360,19 +3360,7 @@ WorkerMain(void* arg)
|
||||
WorkerInput* input = (WorkerInput*) arg;
|
||||
MOZ_ASSERT(!!input->parentRuntime != !!input->siblingContext);
|
||||
|
||||
JSContext* cx = nullptr;
|
||||
|
||||
auto guard = mozilla::MakeScopeExit([&] {
|
||||
if (cx)
|
||||
JS_DestroyContext(cx);
|
||||
if (input->siblingContext) {
|
||||
cooperationState->numThreads--;
|
||||
CooperativeYield();
|
||||
}
|
||||
js_delete(input);
|
||||
});
|
||||
|
||||
cx = input->parentRuntime
|
||||
JSContext* cx = input->parentRuntime
|
||||
? JS_NewContext(8L * 1024L * 1024L, 2L * 1024L * 1024L, input->parentRuntime)
|
||||
: JS_NewCooperativeContext(input->siblingContext);
|
||||
if (!cx)
|
||||
@ -3382,6 +3370,16 @@ WorkerMain(void* arg)
|
||||
if (!sc)
|
||||
return;
|
||||
|
||||
auto guard = mozilla::MakeScopeExit([&] {
|
||||
if (cx)
|
||||
JS_DestroyContext(cx);
|
||||
if (input->siblingContext) {
|
||||
cooperationState->numThreads--;
|
||||
CooperativeYield();
|
||||
}
|
||||
js_delete(input);
|
||||
});
|
||||
|
||||
if (input->parentRuntime)
|
||||
sc->isWorker = true;
|
||||
JS_SetContextPrivate(cx, sc.get());
|
||||
|
@ -920,8 +920,8 @@ nsJARChannel::OnDownloadComplete(MemoryDownloader* aDownloader,
|
||||
uint32_t loadFlags;
|
||||
channel->GetLoadFlags(&loadFlags);
|
||||
if (loadFlags & LOAD_REPLACE) {
|
||||
mLoadFlags |= LOAD_REPLACE;
|
||||
|
||||
// Update our URI to reflect any redirects that happen during
|
||||
// the HTTP request.
|
||||
if (!mOriginalURI) {
|
||||
SetOriginalURI(mJarURI);
|
||||
}
|
||||
@ -943,6 +943,9 @@ nsJARChannel::OnDownloadComplete(MemoryDownloader* aDownloader,
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(status) && channel) {
|
||||
// In case the load info object has changed during a redirect,
|
||||
// grab it from the target channel.
|
||||
channel->GetLoadInfo(getter_AddRefs(mLoadInfo));
|
||||
// Grab the security info from our base channel
|
||||
channel->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
|
||||
|
||||
|
@ -934,6 +934,9 @@ pref("accessibility.AOM.enabled", false);
|
||||
// See bug 781791.
|
||||
pref("accessibility.delay_plugins", false);
|
||||
pref("accessibility.delay_plugin_time", 10000);
|
||||
|
||||
// The COM handler used for Windows e10s performance and live regions
|
||||
pref("accessibility.handler.enabled", true);
|
||||
#endif
|
||||
|
||||
pref("focusmanager.testmode", false);
|
||||
|
@ -131,6 +131,74 @@ include('build/moz.configure/headers.configure',
|
||||
include('build/moz.configure/warnings.configure',
|
||||
when='--enable-compile-environment')
|
||||
|
||||
option(env='SO_VERSION', nargs=1, help='Shared library version for OpenBSD systems')
|
||||
|
||||
@depends(target, target_is_windows, target_is_darwin, building_with_gcc, 'SO_VERSION')
|
||||
def library_name_info(target, is_windows, is_darwin, building_with_gcc, so_version):
|
||||
dll_prefix = 'lib'
|
||||
dll_suffix = '.so'
|
||||
lib_prefix = 'lib'
|
||||
lib_suffix = 'a'
|
||||
rust_lib_prefix = 'lib'
|
||||
rust_lib_suffix = 'a'
|
||||
obj_suffix = 'o'
|
||||
import_lib_suffix = ''
|
||||
|
||||
if is_windows:
|
||||
dll_prefix = ''
|
||||
dll_suffix = '.dll'
|
||||
|
||||
rust_lib_prefix = ''
|
||||
rust_lib_suffix = 'lib'
|
||||
|
||||
# It's OK if we're doing an artifact build and building_with_gcc is
|
||||
# inaccurate. Artifact builds with mingw ought to be pretty rare anyway.
|
||||
if building_with_gcc:
|
||||
import_lib_suffix = 'a'
|
||||
else:
|
||||
import_lib_suffix = 'lib'
|
||||
lib_prefix = ''
|
||||
lib_suffix = 'lib'
|
||||
obj_suffix = 'obj'
|
||||
elif is_darwin:
|
||||
dll_suffix = '.dylib'
|
||||
elif target.kernel == 'OpenBSD':
|
||||
if so_version:
|
||||
dll_suffix = '.so.%s' % so_version
|
||||
else:
|
||||
dll_suffix = '.so.1.0'
|
||||
|
||||
assert dll_suffix[0] == '.'
|
||||
assert obj_suffix[0] != '.'
|
||||
assert lib_suffix[0] != '.'
|
||||
assert rust_lib_suffix[0] != '.'
|
||||
|
||||
return namespace(
|
||||
dll_prefix=dll_prefix,
|
||||
dll_suffix=dll_suffix,
|
||||
|
||||
lib_prefix=lib_prefix,
|
||||
lib_suffix=lib_suffix,
|
||||
|
||||
rust_lib_prefix=rust_lib_prefix,
|
||||
rust_lib_suffix=rust_lib_suffix,
|
||||
|
||||
obj_suffix=obj_suffix,
|
||||
import_lib_suffix=import_lib_suffix,
|
||||
)
|
||||
|
||||
set_config('DLL_PREFIX', library_name_info.dll_prefix)
|
||||
set_config('DLL_SUFFIX', library_name_info.dll_suffix)
|
||||
set_config('LIB_PREFIX', library_name_info.lib_prefix)
|
||||
set_config('LIB_SUFFIX', library_name_info.lib_suffix)
|
||||
set_config('RUST_LIB_PREFIX', library_name_info.rust_lib_prefix)
|
||||
set_config('RUST_LIB_SUFFIX', library_name_info.rust_lib_suffix)
|
||||
set_config('OBJ_SUFFIX', library_name_info.obj_suffix)
|
||||
# Lots of compilation tests depend on this variable being present.
|
||||
add_old_configure_assignment('OBJ_SUFFIX', library_name_info.obj_suffix)
|
||||
set_config('IMPORT_LIB_SUFFIX', library_name_info.import_lib_suffix)
|
||||
set_define('MOZ_DLL_SUFFIX', depends(library_name_info)(lambda lni: '"%s"' % lni.dll_suffix))
|
||||
|
||||
include(include_project_configure)
|
||||
|
||||
@depends('--help')
|
||||
|
@ -274,6 +274,7 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
|
||||
, mTriggeringPrincipal(rhs.mTriggeringPrincipal)
|
||||
, mPrincipalToInherit(rhs.mPrincipalToInherit)
|
||||
, mSandboxedLoadingPrincipal(rhs.mSandboxedLoadingPrincipal)
|
||||
, mResultPrincipalURI(rhs.mResultPrincipalURI)
|
||||
, mLoadingContext(rhs.mLoadingContext)
|
||||
, mSecurityFlags(rhs.mSecurityFlags)
|
||||
, mInternalContentPolicyType(rhs.mInternalContentPolicyType)
|
||||
@ -307,6 +308,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
|
||||
nsIPrincipal* aTriggeringPrincipal,
|
||||
nsIPrincipal* aPrincipalToInherit,
|
||||
nsIPrincipal* aSandboxedLoadingPrincipal,
|
||||
nsIURI* aResultPrincipalURI,
|
||||
nsSecurityFlags aSecurityFlags,
|
||||
nsContentPolicyType aContentPolicyType,
|
||||
LoadTainting aTainting,
|
||||
@ -334,6 +336,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
|
||||
: mLoadingPrincipal(aLoadingPrincipal)
|
||||
, mTriggeringPrincipal(aTriggeringPrincipal)
|
||||
, mPrincipalToInherit(aPrincipalToInherit)
|
||||
, mResultPrincipalURI(aResultPrincipalURI)
|
||||
, mSecurityFlags(aSecurityFlags)
|
||||
, mInternalContentPolicyType(aContentPolicyType)
|
||||
, mTainting(aTainting)
|
||||
@ -1009,5 +1012,19 @@ LoadInfo::GetIsTopLevelLoad(bool *aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LoadInfo::GetResultPrincipalURI(nsIURI **aURI)
|
||||
{
|
||||
NS_IF_ADDREF(*aURI = mResultPrincipalURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LoadInfo::SetResultPrincipalURI(nsIURI *aURI)
|
||||
{
|
||||
mResultPrincipalURI = aURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
@ -94,6 +94,7 @@ private:
|
||||
nsIPrincipal* aTriggeringPrincipal,
|
||||
nsIPrincipal* aPrincipalToInherit,
|
||||
nsIPrincipal* aSandboxedLoadingPrincipal,
|
||||
nsIURI* aResultPrincipalURI,
|
||||
nsSecurityFlags aSecurityFlags,
|
||||
nsContentPolicyType aContentPolicyType,
|
||||
LoadTainting aTainting,
|
||||
@ -143,6 +144,7 @@ private:
|
||||
nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipalToInherit;
|
||||
nsCOMPtr<nsIPrincipal> mSandboxedLoadingPrincipal;
|
||||
nsCOMPtr<nsIURI> mResultPrincipalURI;
|
||||
nsWeakPtr mLoadingContext;
|
||||
nsSecurityFlags mSecurityFlags;
|
||||
nsContentPolicyType mInternalContentPolicyType;
|
||||
|
@ -325,6 +325,17 @@ nsFileStreamBase::DoOpen()
|
||||
PRFileDesc* fd;
|
||||
nsresult rv;
|
||||
|
||||
if (mOpenParams.ioFlags & PR_CREATE_FILE) {
|
||||
nsCOMPtr<nsIFile> parent;
|
||||
mOpenParams.localFile->GetParent(getter_AddRefs(parent));
|
||||
|
||||
// Result doesn't need to be checked. If the file's parent path does not
|
||||
// exist, make it. If it does exist, do nothing.
|
||||
if (parent) {
|
||||
Unused << parent->Create(nsIFile::DIRECTORY_TYPE, 0644);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (mBehaviorFlags & nsIFileInputStream::SHARE_DELETE) {
|
||||
nsCOMPtr<nsILocalFileWin> file = do_QueryInterface(mOpenParams.localFile);
|
||||
|
@ -11,6 +11,7 @@ interface nsIDOMDocument;
|
||||
interface nsINode;
|
||||
interface nsIPrincipal;
|
||||
interface nsIRedirectHistoryEntry;
|
||||
interface nsIURI;
|
||||
%{C++
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
@ -752,6 +753,14 @@ interface nsILoadInfo : nsISupports
|
||||
*/
|
||||
[infallible] readonly attribute boolean isTopLevelLoad;
|
||||
|
||||
/**
|
||||
* If this is non-null, this property represents two things: (1) the
|
||||
* URI to be used for the principal if the channel with this loadinfo
|
||||
* gets a principal based on URI and (2) the URI to use for a document
|
||||
* created from the channel with this loadinfo.
|
||||
*/
|
||||
attribute nsIURI resultPrincipalURI;
|
||||
|
||||
/**
|
||||
* Returns the null principal of the resulting resource if the SEC_SANDBOXED
|
||||
* flag is set. Otherwise returns null. This is used by
|
||||
|
@ -184,11 +184,17 @@ NS_NewChannelInternal(nsIChannel **outChannel,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
nsLoadFlags channelLoadFlags = 0;
|
||||
channel->GetLoadFlags(&channelLoadFlags);
|
||||
// Will be removed when we remove LOAD_REPLACE altogether
|
||||
// This check is trying to catch protocol handlers that still
|
||||
// try to set the LOAD_REPLACE flag.
|
||||
MOZ_DIAGNOSTIC_ASSERT(!(channelLoadFlags & nsIChannel::LOAD_REPLACE));
|
||||
#endif
|
||||
|
||||
if (aLoadFlags != nsIRequest::LOAD_NORMAL) {
|
||||
// Retain the LOAD_REPLACE load flag if set.
|
||||
nsLoadFlags normalLoadFlags = 0;
|
||||
channel->GetLoadFlags(&normalLoadFlags);
|
||||
rv = channel->SetLoadFlags(aLoadFlags | (normalLoadFlags & nsIChannel::LOAD_REPLACE));
|
||||
rv = channel->SetLoadFlags(aLoadFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
@ -263,11 +269,17 @@ NS_NewChannelInternal(nsIChannel **outChannel,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
nsLoadFlags channelLoadFlags = 0;
|
||||
channel->GetLoadFlags(&channelLoadFlags);
|
||||
// Will be removed when we remove LOAD_REPLACE altogether
|
||||
// This check is trying to catch protocol handlers that still
|
||||
// try to set the LOAD_REPLACE flag.
|
||||
MOZ_DIAGNOSTIC_ASSERT(!(channelLoadFlags & nsIChannel::LOAD_REPLACE));
|
||||
#endif
|
||||
|
||||
if (aLoadFlags != nsIRequest::LOAD_NORMAL) {
|
||||
// Retain the LOAD_REPLACE load flag if set.
|
||||
nsLoadFlags normalLoadFlags = 0;
|
||||
channel->GetLoadFlags(&normalLoadFlags);
|
||||
rv = channel->SetLoadFlags(aLoadFlags | (normalLoadFlags & nsIChannel::LOAD_REPLACE));
|
||||
rv = channel->SetLoadFlags(aLoadFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
@ -1886,12 +1898,15 @@ nsresult
|
||||
NS_GetFinalChannelURI(nsIChannel *channel, nsIURI **uri)
|
||||
{
|
||||
*uri = nullptr;
|
||||
nsLoadFlags loadFlags = 0;
|
||||
nsresult rv = channel->GetLoadFlags(&loadFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (loadFlags & nsIChannel::LOAD_REPLACE) {
|
||||
return channel->GetURI(uri);
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
|
||||
if (loadInfo) {
|
||||
nsCOMPtr<nsIURI> resultPrincipalURI;
|
||||
loadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
|
||||
if (resultPrincipalURI) {
|
||||
resultPrincipalURI.forget(uri);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return channel->GetOriginalURI(uri);
|
||||
|
@ -781,11 +781,10 @@ nsresult NS_URIChainHasFlags(nsIURI *uri,
|
||||
already_AddRefed<nsIURI> NS_GetInnermostURI(nsIURI *aURI);
|
||||
|
||||
/**
|
||||
* Get the "final" URI for a channel. This is either the same as GetURI or
|
||||
* GetOriginalURI, depending on whether this channel has
|
||||
* nsIChanel::LOAD_REPLACE set. For channels without that flag set, the final
|
||||
* URI is the original URI, while for ones with the flag the final URI is the
|
||||
* channel URI.
|
||||
* Get the "final" URI for a channel. This is either channel's load info
|
||||
* resultPrincipalURI, if set, or GetOriginalURI. In most cases (but not all) load
|
||||
* info resultPrincipalURI, if set, corresponds to URI of the channel if it's required
|
||||
* to represent the actual principal for the channel.
|
||||
*/
|
||||
nsresult NS_GetFinalChannelURI(nsIChannel *channel, nsIURI **uri);
|
||||
|
||||
|
@ -41,6 +41,7 @@ struct LoadInfoArgs
|
||||
PrincipalInfo triggeringPrincipalInfo;
|
||||
OptionalPrincipalInfo principalToInheritInfo;
|
||||
OptionalPrincipalInfo sandboxedLoadingPrincipalInfo;
|
||||
OptionalURIParams resultPrincipalURI;
|
||||
uint32_t securityFlags;
|
||||
uint32_t contentPolicyType;
|
||||
uint32_t tainting;
|
||||
|
@ -251,7 +251,20 @@ nsFileUploadContentStream::OnCopyComplete()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsFileChannel::nsFileChannel(nsIURI *uri)
|
||||
: mFileURI(uri)
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFileChannel::Init()
|
||||
{
|
||||
NS_ENSURE_STATE(mLoadInfo);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
rv = nsBaseChannel::Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If we have a link file, we should resolve its target right away.
|
||||
// This is to protect against a same origin attack where the same link file
|
||||
// can point to different resources right after the first resource is loaded.
|
||||
@ -264,24 +277,24 @@ nsFileChannel::nsFileChannel(nsIURI *uri)
|
||||
#endif
|
||||
nsCOMPtr<nsIFile> resolvedFile;
|
||||
bool symLink;
|
||||
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(uri);
|
||||
if (fileURL &&
|
||||
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(mFileURI);
|
||||
if (fileURL &&
|
||||
NS_SUCCEEDED(fileURL->GetFile(getter_AddRefs(file))) &&
|
||||
NS_SUCCEEDED(file->IsSymlink(&symLink)) &&
|
||||
NS_SUCCEEDED(file->IsSymlink(&symLink)) &&
|
||||
symLink &&
|
||||
#ifdef XP_WIN
|
||||
NS_SUCCEEDED(file->GetTarget(fileTarget)) &&
|
||||
NS_SUCCEEDED(NS_NewLocalFile(fileTarget, PR_TRUE,
|
||||
NS_SUCCEEDED(NS_NewLocalFile(fileTarget, true,
|
||||
getter_AddRefs(resolvedFile))) &&
|
||||
#else
|
||||
NS_SUCCEEDED(file->GetNativeTarget(fileTarget)) &&
|
||||
NS_SUCCEEDED(NS_NewNativeLocalFile(fileTarget, PR_TRUE,
|
||||
NS_SUCCEEDED(NS_NewNativeLocalFile(fileTarget, true,
|
||||
getter_AddRefs(resolvedFile))) &&
|
||||
#endif
|
||||
NS_SUCCEEDED(NS_NewFileURI(getter_AddRefs(targetURI),
|
||||
resolvedFile, nullptr))) {
|
||||
NS_SUCCEEDED(NS_NewFileURI(getter_AddRefs(targetURI),
|
||||
resolvedFile, nullptr))) {
|
||||
// Make an effort to match up the query strings.
|
||||
nsCOMPtr<nsIURL> origURL = do_QueryInterface(uri);
|
||||
nsCOMPtr<nsIURL> origURL = do_QueryInterface(mFileURI);
|
||||
nsCOMPtr<nsIURL> targetURL = do_QueryInterface(targetURI);
|
||||
nsAutoCString queryString;
|
||||
if (origURL && targetURL && NS_SUCCEEDED(origURL->GetQuery(queryString))) {
|
||||
@ -289,13 +302,13 @@ nsFileChannel::nsFileChannel(nsIURI *uri)
|
||||
}
|
||||
|
||||
SetURI(targetURI);
|
||||
SetOriginalURI(uri);
|
||||
nsLoadFlags loadFlags = 0;
|
||||
GetLoadFlags(&loadFlags);
|
||||
SetLoadFlags(loadFlags | nsIChannel::LOAD_REPLACE);
|
||||
SetOriginalURI(mFileURI);
|
||||
mLoadInfo->SetResultPrincipalURI(targetURI);
|
||||
} else {
|
||||
SetURI(uri);
|
||||
SetURI(mFileURI);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsFileChannel::~nsFileChannel()
|
||||
|
@ -22,6 +22,8 @@ public:
|
||||
|
||||
explicit nsFileChannel(nsIURI *uri);
|
||||
|
||||
nsresult Init();
|
||||
|
||||
protected:
|
||||
~nsFileChannel();
|
||||
|
||||
@ -40,6 +42,7 @@ protected:
|
||||
private:
|
||||
nsCOMPtr<nsIInputStream> mUploadStream;
|
||||
int64_t mUploadLength;
|
||||
nsCOMPtr<nsIURI> mFileURI;
|
||||
};
|
||||
|
||||
#endif // !nsFileChannel_h__
|
||||
|
@ -190,6 +190,8 @@ nsFileProtocolHandler::NewChannel2(nsIURI* uri,
|
||||
nsILoadInfo* aLoadInfo,
|
||||
nsIChannel** result)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsFileChannel *chan;
|
||||
if (IsNeckoChild()) {
|
||||
chan = new mozilla::net::FileChannelChild(uri);
|
||||
@ -200,14 +202,16 @@ nsFileProtocolHandler::NewChannel2(nsIURI* uri,
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(chan);
|
||||
|
||||
nsresult rv = chan->Init();
|
||||
// set the loadInfo on the new channel ; must do this
|
||||
// before calling Init() on it, since it needs the load
|
||||
// info be already set.
|
||||
rv = chan->SetLoadInfo(aLoadInfo);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(chan);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// set the loadInfo on the new channel
|
||||
rv = chan->SetLoadInfo(aLoadInfo);
|
||||
rv = chan->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(chan);
|
||||
return rv;
|
||||
|
@ -3021,6 +3021,70 @@ void HttpBaseChannel::AssertPrivateBrowsingId()
|
||||
}
|
||||
#endif
|
||||
|
||||
already_AddRefed<nsILoadInfo>
|
||||
HttpBaseChannel::CloneLoadInfoForRedirect(nsIURI * newURI, uint32_t redirectFlags)
|
||||
{
|
||||
// make a copy of the loadinfo, append to the redirectchain
|
||||
// this will be set on the newly created channel for the redirect target.
|
||||
if (!mLoadInfo) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadInfo> newLoadInfo =
|
||||
static_cast<mozilla::LoadInfo*>(mLoadInfo.get())->Clone();
|
||||
|
||||
nsContentPolicyType contentPolicyType = mLoadInfo->GetExternalContentPolicyType();
|
||||
if (contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT ||
|
||||
contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) {
|
||||
nsCOMPtr<nsIPrincipal> nullPrincipalToInherit = NullPrincipal::Create();
|
||||
newLoadInfo->SetPrincipalToInherit(nullPrincipalToInherit);
|
||||
}
|
||||
|
||||
// re-compute the origin attributes of the loadInfo if it's top-level load.
|
||||
bool isTopLevelDoc =
|
||||
newLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_DOCUMENT;
|
||||
|
||||
if (isTopLevelDoc) {
|
||||
nsCOMPtr<nsILoadContext> loadContext;
|
||||
NS_QueryNotificationCallbacks(this, loadContext);
|
||||
OriginAttributes docShellAttrs;
|
||||
if (loadContext) {
|
||||
loadContext->GetOriginAttributes(docShellAttrs);
|
||||
}
|
||||
|
||||
OriginAttributes attrs = newLoadInfo->GetOriginAttributes();
|
||||
|
||||
MOZ_ASSERT(docShellAttrs.mUserContextId == attrs.mUserContextId,
|
||||
"docshell and necko should have the same userContextId attribute.");
|
||||
MOZ_ASSERT(docShellAttrs.mInIsolatedMozBrowser == attrs.mInIsolatedMozBrowser,
|
||||
"docshell and necko should have the same inIsolatedMozBrowser attribute.");
|
||||
MOZ_ASSERT(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId,
|
||||
"docshell and necko should have the same privateBrowsingId attribute.");
|
||||
|
||||
attrs = docShellAttrs;
|
||||
attrs.SetFirstPartyDomain(true, newURI);
|
||||
newLoadInfo->SetOriginAttributes(attrs);
|
||||
}
|
||||
|
||||
// Leave empty, we want a 'clean ground' when creating the new channel.
|
||||
// This will be ensured to be either set by the protocol handler or set
|
||||
// to the redirect target URI properly after the channel creation.
|
||||
newLoadInfo->SetResultPrincipalURI(nullptr);
|
||||
|
||||
bool isInternalRedirect =
|
||||
(redirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
|
||||
nsIChannelEventSink::REDIRECT_STS_UPGRADE));
|
||||
|
||||
nsCString remoteAddress;
|
||||
Unused << GetRemoteAddress(remoteAddress);
|
||||
nsCOMPtr<nsIRedirectHistoryEntry> entry =
|
||||
new nsRedirectHistoryEntry(GetURIPrincipal(), mReferrer, remoteAddress);
|
||||
|
||||
newLoadInfo->AppendRedirectHistoryEntry(entry, isInternalRedirect);
|
||||
|
||||
return newLoadInfo.forget();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsHttpChannel::nsITraceableChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -3170,10 +3234,33 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
|
||||
bool preserveMethod,
|
||||
uint32_t redirectFlags)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
LOG(("HttpBaseChannel::SetupReplacementChannel "
|
||||
"[this=%p newChannel=%p preserveMethod=%d]",
|
||||
this, newChannel, preserveMethod));
|
||||
|
||||
// Ensure the channel's loadInfo's result principal URI so that it's
|
||||
// either non-null or updated to the redirect target URI.
|
||||
// We must do this because in case the loadInfo's result principal URI
|
||||
// is null, it would be taken from OriginalURI of the channel. But we
|
||||
// overwrite it with the whole redirect chain first URI before opening
|
||||
// the target channel, hence the information would be lost.
|
||||
// If the protocol handler that created the channel wants to use
|
||||
// the originalURI of the channel as the principal URI, this fulfills
|
||||
// that request - newURI is the original URI of the channel.
|
||||
nsCOMPtr<nsILoadInfo> newLoadInfo = newChannel->GetLoadInfo();
|
||||
if (newLoadInfo) {
|
||||
nsCOMPtr<nsIURI> resultPrincipalURI;
|
||||
rv = newLoadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!resultPrincipalURI) {
|
||||
rv = newLoadInfo->SetResultPrincipalURI(newURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t newLoadFlags = mLoadFlags | LOAD_REPLACE;
|
||||
// if the original channel was using SSL and this channel is not using
|
||||
// SSL, then no need to inhibit persistent caching. however, if the
|
||||
@ -3182,7 +3269,7 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
|
||||
// since we force set INHIBIT_PERSISTENT_CACHING on all HTTPS channels,
|
||||
// we only need to check if the original channel was using SSL.
|
||||
bool usingSSL = false;
|
||||
nsresult rv = mURI->SchemeIs("https", &usingSSL);
|
||||
rv = mURI->SchemeIs("https", &usingSSL);
|
||||
if (NS_SUCCEEDED(rv) && usingSSL)
|
||||
newLoadFlags &= ~INHIBIT_PERSISTENT_CACHING;
|
||||
|
||||
@ -3207,62 +3294,6 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
|
||||
}
|
||||
}
|
||||
|
||||
// make a copy of the loadinfo, append to the redirectchain
|
||||
// and set it on the new channel
|
||||
if (mLoadInfo) {
|
||||
nsCOMPtr<nsILoadInfo> newLoadInfo =
|
||||
static_cast<mozilla::LoadInfo*>(mLoadInfo.get())->Clone();
|
||||
|
||||
nsContentPolicyType contentPolicyType = mLoadInfo->GetExternalContentPolicyType();
|
||||
if (contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT ||
|
||||
contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) {
|
||||
nsCOMPtr<nsIPrincipal> nullPrincipalToInherit = NullPrincipal::Create();
|
||||
newLoadInfo->SetPrincipalToInherit(nullPrincipalToInherit);
|
||||
}
|
||||
|
||||
// re-compute the origin attributes of the loadInfo if it's top-level load.
|
||||
bool isTopLevelDoc =
|
||||
newLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_DOCUMENT;
|
||||
|
||||
if (isTopLevelDoc) {
|
||||
nsCOMPtr<nsILoadContext> loadContext;
|
||||
NS_QueryNotificationCallbacks(this, loadContext);
|
||||
OriginAttributes docShellAttrs;
|
||||
if (loadContext) {
|
||||
loadContext->GetOriginAttributes(docShellAttrs);
|
||||
}
|
||||
|
||||
OriginAttributes attrs = newLoadInfo->GetOriginAttributes();
|
||||
|
||||
MOZ_ASSERT(docShellAttrs.mUserContextId == attrs.mUserContextId,
|
||||
"docshell and necko should have the same userContextId attribute.");
|
||||
MOZ_ASSERT(docShellAttrs.mInIsolatedMozBrowser == attrs.mInIsolatedMozBrowser,
|
||||
"docshell and necko should have the same inIsolatedMozBrowser attribute.");
|
||||
MOZ_ASSERT(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId,
|
||||
"docshell and necko should have the same privateBrowsingId attribute.");
|
||||
|
||||
attrs = docShellAttrs;
|
||||
attrs.SetFirstPartyDomain(true, newURI);
|
||||
newLoadInfo->SetOriginAttributes(attrs);
|
||||
}
|
||||
|
||||
bool isInternalRedirect =
|
||||
(redirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
|
||||
nsIChannelEventSink::REDIRECT_STS_UPGRADE));
|
||||
nsCString remoteAddress;
|
||||
Unused << GetRemoteAddress(remoteAddress);
|
||||
nsCOMPtr<nsIRedirectHistoryEntry> entry =
|
||||
new nsRedirectHistoryEntry(GetURIPrincipal(), mReferrer, remoteAddress);
|
||||
|
||||
newLoadInfo->AppendRedirectHistoryEntry(entry, isInternalRedirect);
|
||||
newChannel->SetLoadInfo(newLoadInfo);
|
||||
}
|
||||
else {
|
||||
// the newChannel was created with a dummy loadInfo, we should clear
|
||||
// it in case the original channel does not have a loadInfo
|
||||
newChannel->SetLoadInfo(nullptr);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
|
||||
if (!httpChannel)
|
||||
return NS_OK; // no other options to set
|
||||
|
@ -432,6 +432,9 @@ protected:
|
||||
void AssertPrivateBrowsingId();
|
||||
#endif
|
||||
|
||||
// Called before we create the redirect target channel.
|
||||
already_AddRefed<nsILoadInfo> CloneLoadInfoForRedirect(nsIURI *newURI, uint32_t redirectFlags);
|
||||
|
||||
friend class PrivateBrowsingChannel<HttpBaseChannel>;
|
||||
friend class InterceptFailedOnStop;
|
||||
|
||||
|
@ -1506,9 +1506,10 @@ HttpChannelChild::SetupRedirect(nsIURI* uri,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIChannel> newChannel;
|
||||
nsCOMPtr<nsILoadInfo> redirectLoadInfo = CloneLoadInfoForRedirect(uri, redirectFlags);
|
||||
rv = NS_NewChannelInternal(getter_AddRefs(newChannel),
|
||||
uri,
|
||||
mLoadInfo,
|
||||
redirectLoadInfo,
|
||||
nullptr, // aLoadGroup
|
||||
nullptr, // aCallbacks
|
||||
nsIRequest::LOAD_NORMAL,
|
||||
|
@ -2788,6 +2788,8 @@ nsHttpChannel::StartRedirectChannelToURI(nsIURI *upgradedURI, uint32_t flags)
|
||||
LOG(("nsHttpChannel::StartRedirectChannelToURI()\n"));
|
||||
|
||||
nsCOMPtr<nsIChannel> newChannel;
|
||||
nsCOMPtr<nsILoadInfo> redirectLoadInfo = CloneLoadInfoForRedirect(upgradedURI,
|
||||
flags);
|
||||
|
||||
nsCOMPtr<nsIIOService> ioService;
|
||||
rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
|
||||
@ -2795,7 +2797,7 @@ nsHttpChannel::StartRedirectChannelToURI(nsIURI *upgradedURI, uint32_t flags)
|
||||
|
||||
rv = NS_NewChannelInternal(getter_AddRefs(newChannel),
|
||||
upgradedURI,
|
||||
mLoadInfo,
|
||||
redirectLoadInfo,
|
||||
nullptr, // aLoadGroup
|
||||
nullptr, // aCallbacks
|
||||
nsIRequest::LOAD_NORMAL,
|
||||
@ -5679,22 +5681,23 @@ nsHttpChannel::ContinueProcessRedirectionAfterFallback(nsresult rv)
|
||||
rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIChannel> newChannel;
|
||||
rv = NS_NewChannelInternal(getter_AddRefs(newChannel),
|
||||
mRedirectURI,
|
||||
mLoadInfo,
|
||||
nullptr, // aLoadGroup
|
||||
nullptr, // aCallbacks
|
||||
nsIRequest::LOAD_NORMAL,
|
||||
ioService);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uint32_t redirectFlags;
|
||||
if (nsHttp::IsPermanentRedirect(mRedirectType))
|
||||
redirectFlags = nsIChannelEventSink::REDIRECT_PERMANENT;
|
||||
else
|
||||
redirectFlags = nsIChannelEventSink::REDIRECT_TEMPORARY;
|
||||
|
||||
nsCOMPtr<nsIChannel> newChannel;
|
||||
nsCOMPtr<nsILoadInfo> redirectLoadInfo = CloneLoadInfoForRedirect(mRedirectURI, redirectFlags);
|
||||
rv = NS_NewChannelInternal(getter_AddRefs(newChannel),
|
||||
mRedirectURI,
|
||||
redirectLoadInfo,
|
||||
nullptr, // aLoadGroup
|
||||
nullptr, // aCallbacks
|
||||
nsIRequest::LOAD_NORMAL,
|
||||
ioService);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = SetupReplacementChannel(mRedirectURI, newChannel,
|
||||
!rewriteToGET, redirectFlags);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -33,6 +33,10 @@ protected:
|
||||
const nsACString& aPathname,
|
||||
nsACString& aResult) override;
|
||||
|
||||
// |result| is an inout param. On entry to this function, *result
|
||||
// is expected to be non-null and already addrefed. This function
|
||||
// may release the object stored in *result on entry and write
|
||||
// a new pointer to an already addrefed channel to *result.
|
||||
virtual MOZ_MUST_USE nsresult SubstituteChannel(nsIURI* uri,
|
||||
nsILoadInfo* aLoadInfo,
|
||||
nsIChannel** result) override;
|
||||
|
@ -246,6 +246,8 @@ SubstitutingProtocolHandler::NewChannel2(nsIURI* uri,
|
||||
nsIChannel** result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(uri);
|
||||
NS_ENSURE_ARG_POINTER(aLoadInfo);
|
||||
|
||||
nsAutoCString spec;
|
||||
nsresult rv = ResolveURI(uri, spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -254,12 +256,18 @@ SubstitutingProtocolHandler::NewChannel2(nsIURI* uri,
|
||||
rv = NS_NewURI(getter_AddRefs(newURI), spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We don't want to allow the inner protocol handler to modify the result
|
||||
// principal URI since we want either |uri| or anything pre-set by upper
|
||||
// layers to prevail.
|
||||
nsCOMPtr<nsIURI> savedResultPrincipalURI;
|
||||
rv = aLoadInfo->GetResultPrincipalURI(getter_AddRefs(savedResultPrincipalURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = NS_NewChannelInternal(result, newURI, aLoadInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsLoadFlags loadFlags = 0;
|
||||
(*result)->GetLoadFlags(&loadFlags);
|
||||
(*result)->SetLoadFlags(loadFlags & ~nsIChannel::LOAD_REPLACE);
|
||||
rv = aLoadInfo->SetResultPrincipalURI(savedResultPrincipalURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = (*result)->SetOriginalURI(uri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -877,6 +877,10 @@ nsMultiMixedConv::SendStart()
|
||||
|
||||
mPartChannel->SetContentDisposition(mContentDisposition);
|
||||
|
||||
// Each part of a multipart/replace response can be used
|
||||
// for the top level document. We must inform upper layers
|
||||
// about this by setting the LOAD_REPLACE flag so that certain
|
||||
// state assertions are evaluated as positive.
|
||||
nsLoadFlags loadFlags = 0;
|
||||
mPartChannel->GetLoadFlags(&loadFlags);
|
||||
loadFlags |= nsIChannel::LOAD_REPLACE;
|
||||
|
@ -232,9 +232,6 @@ function test_load_replace() {
|
||||
file = do_get_file("data/system_root.lnk", false);
|
||||
var chan = new_file_channel(file);
|
||||
|
||||
// The LOAD_REPLACE flag should be set
|
||||
do_check_eq(chan.loadFlags & chan.LOAD_REPLACE, chan.LOAD_REPLACE);
|
||||
|
||||
// The original URI path should differ from the URI path
|
||||
do_check_neq(chan.URI.path, chan.originalURI.path);
|
||||
|
||||
|
@ -502,14 +502,6 @@ AS_BIN=$AS
|
||||
AR_EXTRACT='$(AR) x'
|
||||
AS='$(CC)'
|
||||
AS_DASH_C_FLAG='-c'
|
||||
DLL_PREFIX=lib
|
||||
LIB_PREFIX=lib
|
||||
RUST_LIB_PREFIX=lib
|
||||
DLL_SUFFIX=.so
|
||||
OBJ_SUFFIX=o
|
||||
LIB_SUFFIX=a
|
||||
RUST_LIB_SUFFIX=a
|
||||
IMPORT_LIB_SUFFIX=
|
||||
DIRENT_INO=d_ino
|
||||
MOZ_USER_DIR=".mozilla"
|
||||
|
||||
@ -815,7 +807,6 @@ case "$target" in
|
||||
MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -o $@'
|
||||
MOZ_OPTIMIZE_FLAGS="-O3"
|
||||
CXXFLAGS="$CXXFLAGS -stdlib=libc++"
|
||||
DLL_SUFFIX=".dylib"
|
||||
DSO_LDOPTS=''
|
||||
STRIP_FLAGS="$STRIP_FLAGS -x -S"
|
||||
# Ensure that if we're targeting iOS an SDK was provided.
|
||||
@ -906,7 +897,6 @@ case "$target" in
|
||||
*-mingw*)
|
||||
DSO_CFLAGS=
|
||||
DSO_PIC_CFLAGS=
|
||||
DLL_SUFFIX=.dll
|
||||
RC=rc.exe
|
||||
# certain versions of cygwin's makedepend barf on the
|
||||
# #include <string> vs -I./dist/include/string issue so don't use it
|
||||
@ -928,10 +918,6 @@ case "$target" in
|
||||
# mingw doesn't require kernel32, user32, and advapi32 explicitly
|
||||
LIBS="$LIBS -luuid -lgdi32 -lwinmm -lwsock32 -luserenv -lsecur32"
|
||||
MOZ_FIX_LINK_PATHS=
|
||||
DLL_PREFIX=
|
||||
IMPORT_LIB_SUFFIX=a
|
||||
RUST_LIB_PREFIX=
|
||||
RUST_LIB_SUFFIX=lib
|
||||
|
||||
WIN32_CONSOLE_EXE_LDFLAGS=-mconsole
|
||||
WIN32_GUI_EXE_LDFLAGS=-mwindows
|
||||
@ -952,13 +938,6 @@ case "$target" in
|
||||
RANLIB='echo not_ranlib'
|
||||
STRIP='echo not_strip'
|
||||
PKG_SKIP_STRIP=1
|
||||
OBJ_SUFFIX=obj
|
||||
LIB_SUFFIX=lib
|
||||
RUST_LIB_SUFFIX=lib
|
||||
DLL_PREFIX=
|
||||
LIB_PREFIX=
|
||||
RUST_LIB_PREFIX=
|
||||
IMPORT_LIB_SUFFIX=lib
|
||||
MKSHLIB='$(LINK) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
|
||||
MKCSHLIB='$(LINK) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
|
||||
WIN32_SUBSYSTEM_VERSION=6.01
|
||||
@ -1157,13 +1136,11 @@ case "$target" in
|
||||
CFLAGS="$CFLAGS -Dunix"
|
||||
CXXFLAGS="$CXXFLAGS -Dunix"
|
||||
if $CC -E - -dM </dev/null | grep __ELF__ >/dev/null; then
|
||||
DLL_SUFFIX=".so"
|
||||
DSO_PIC_CFLAGS='-fPIC -DPIC'
|
||||
DSO_LDOPTS='-shared'
|
||||
BIN_FLAGS='-Wl,--export-dynamic'
|
||||
else
|
||||
DSO_PIC_CFLAGS='-fPIC -DPIC'
|
||||
DLL_SUFFIX=".so.1.0"
|
||||
DSO_LDOPTS='-shared'
|
||||
fi
|
||||
# This will fail on a.out systems prior to 1.5.1_ALPHA.
|
||||
@ -1175,11 +1152,6 @@ case "$target" in
|
||||
;;
|
||||
|
||||
*-openbsd*)
|
||||
if test "$SO_VERSION"; then
|
||||
DLL_SUFFIX=".so.$SO_VERSION"
|
||||
else
|
||||
DLL_SUFFIX=".so.1.0"
|
||||
fi
|
||||
if test -z "$X11BASE"; then
|
||||
X11BASE=/usr/X11R6
|
||||
fi
|
||||
@ -5271,16 +5243,7 @@ AC_SUBST(MKCSHLIB)
|
||||
AC_SUBST(DSO_CFLAGS)
|
||||
AC_SUBST(DSO_PIC_CFLAGS)
|
||||
AC_SUBST(DSO_LDOPTS)
|
||||
AC_SUBST(LIB_PREFIX)
|
||||
AC_SUBST(RUST_LIB_PREFIX)
|
||||
AC_SUBST(DLL_PREFIX)
|
||||
AC_SUBST(DLL_SUFFIX)
|
||||
AC_DEFINE_UNQUOTED(MOZ_DLL_SUFFIX, "$DLL_SUFFIX")
|
||||
AC_SUBST(LIB_SUFFIX)
|
||||
AC_SUBST(RUST_LIB_SUFFIX)
|
||||
AC_SUBST(OBJ_SUFFIX)
|
||||
AC_SUBST(BIN_SUFFIX)
|
||||
AC_SUBST(IMPORT_LIB_SUFFIX)
|
||||
AC_SUBST(USE_N32)
|
||||
AC_SUBST(CC_VERSION)
|
||||
AC_SUBST(NS_ENABLE_TSF)
|
||||
|
@ -229,6 +229,20 @@ class LcovFile(object):
|
||||
# LF:<number of instrumented lines>
|
||||
# LH:<number of lines with a non-zero execution count>
|
||||
# end_of_record
|
||||
PREFIX_TYPES = {
|
||||
'TN': 0,
|
||||
'SF': 0,
|
||||
'FN': 1,
|
||||
'FNDA': 1,
|
||||
'FNF': 0,
|
||||
'FNH': 0,
|
||||
'BRDA': 3,
|
||||
'BRF': 0,
|
||||
'BRH': 0,
|
||||
'DA': 2,
|
||||
'LH': 0,
|
||||
'LF': 0,
|
||||
}
|
||||
|
||||
def __init__(self, lcov_fh):
|
||||
# These are keyed by source file because output will split sources (at
|
||||
@ -267,14 +281,10 @@ class LcovFile(object):
|
||||
|
||||
# We occasionally end up with multi-line scripts in data:
|
||||
# uris that will trip up the parser, just skip them for now.
|
||||
if colon < 0 or prefix not in ('TN', 'SF', 'FN', 'FNDA', 'FNF',
|
||||
'FNH', 'BRDA', 'BRF', 'BRH', 'DA',
|
||||
'LF', 'LH'):
|
||||
if colon < 0 or prefix not in self.PREFIX_TYPES:
|
||||
continue
|
||||
if prefix not in ('SF', 'TN'):
|
||||
args = line[(colon + 1):].split(',')
|
||||
else:
|
||||
args = line[(colon + 1):],
|
||||
|
||||
args = line[(colon + 1):].split(',', self.PREFIX_TYPES[prefix])
|
||||
|
||||
def try_convert(a):
|
||||
try:
|
||||
|
@ -83,6 +83,22 @@ LH:8
|
||||
end_of_record
|
||||
"""
|
||||
|
||||
fn_with_multiple_commas = """TN:Compartment_5f7f5c30251800
|
||||
SF:resource://gre/modules/osfile.jsm
|
||||
FN:1,function,name,with,commas
|
||||
FNDA:1,function,name,with,commas
|
||||
FNF:1
|
||||
FNH:1
|
||||
BRDA:9,0,61,1
|
||||
BRF:1
|
||||
BRH:1
|
||||
DA:9,1
|
||||
DA:24,1
|
||||
LF:2
|
||||
LH:2
|
||||
end_of_record
|
||||
"""
|
||||
|
||||
class TestLcovParser(unittest.TestCase):
|
||||
|
||||
def get_lcov(self, lcov_string):
|
||||
@ -112,6 +128,9 @@ class TestLcovParser(unittest.TestCase):
|
||||
output = self.parser_roundtrip(multiple_records, True)
|
||||
self.assertEqual(multiple_records, output)
|
||||
|
||||
def test_multiple_commas(self):
|
||||
output = self.parser_roundtrip(fn_with_multiple_commas, True)
|
||||
self.assertEqual(fn_with_multiple_commas, output)
|
||||
|
||||
multiple_included_files = """//@line 1 "foo.js"
|
||||
bazfoobar
|
||||
|
@ -328,6 +328,7 @@ jsreftest:
|
||||
android-4.3-arm7-api-15/debug: 100
|
||||
android.*: 40
|
||||
windows.*: 2
|
||||
linux64-ccov/.*: 5
|
||||
linux64-qr/.*: 4
|
||||
macosx.*: 2
|
||||
default: 3
|
||||
|
@ -33,7 +33,8 @@ config = {
|
||||
],
|
||||
"channel_names": ["beta-dev", "beta-dev-localtest", "beta-dev-cdntest"],
|
||||
"rules_to_update": ["firefox-beta-dev-cdntest", "firefox-beta-dev-localtest"],
|
||||
"publish_rules": ["firefox-beta"],
|
||||
"publish_rules": ["firefox-beta"],
|
||||
"schedule_asap": True,
|
||||
},
|
||||
"release-dev": {
|
||||
"version_regex": r"^\d+\.\d+(\.\d+)?$",
|
||||
|
@ -28,7 +28,7 @@ config = {
|
||||
"mar_channel_ids": [],
|
||||
"channel_names": ["beta", "beta-localtest", "beta-cdntest"],
|
||||
"rules_to_update": ["firefox-beta-cdntest", "firefox-beta-localtest"],
|
||||
"publish_rules": ["firefox-beta"],
|
||||
"publish_rules": [32],
|
||||
},
|
||||
},
|
||||
"balrog_use_dummy_suffix": False,
|
||||
|
@ -31,7 +31,7 @@ config = {
|
||||
"mar_channel_ids": [],
|
||||
"channel_names": ["aurora", "aurora-localtest", "aurora-cdntest"],
|
||||
"rules_to_update": ["devedition-cdntest", "devedition-localtest"],
|
||||
"publish_rules": ["devedition"],
|
||||
"publish_rules": [10],
|
||||
},
|
||||
},
|
||||
"balrog_use_dummy_suffix": False,
|
||||
|
@ -28,7 +28,7 @@ config = {
|
||||
"mar_channel_ids": [],
|
||||
"channel_names": ["esr", "esr-localtest", "esr-cdntest"],
|
||||
"rules_to_update": ["esr52-cdntest", "esr52-localtest"],
|
||||
"publish_rules": ["esr52"],
|
||||
"publish_rules": [521],
|
||||
},
|
||||
},
|
||||
"balrog_use_dummy_suffix": False,
|
||||
|
@ -30,7 +30,8 @@ config = {
|
||||
],
|
||||
"channel_names": ["beta", "beta-localtest", "beta-cdntest"],
|
||||
"rules_to_update": ["firefox-beta-cdntest", "firefox-beta-localtest"],
|
||||
"publish_rules": ["firefox-beta"],
|
||||
"publish_rules": [32],
|
||||
"schedule_asap": True,
|
||||
},
|
||||
"release": {
|
||||
"version_regex": r"^\d+\.\d+(\.\d+)?$",
|
||||
@ -40,7 +41,7 @@ config = {
|
||||
"mar_channel_ids": [],
|
||||
"channel_names": ["release", "release-localtest", "release-cdntest"],
|
||||
"rules_to_update": ["firefox-release-cdntest", "firefox-release-localtest"],
|
||||
"publish_rules": ["firefox-release"],
|
||||
"publish_rules": [145],
|
||||
},
|
||||
},
|
||||
"balrog_use_dummy_suffix": False,
|
||||
|
@ -14,7 +14,6 @@ import sys
|
||||
import signal
|
||||
import socket
|
||||
import subprocess
|
||||
import telnetlib
|
||||
import time
|
||||
import tempfile
|
||||
|
||||
@ -262,12 +261,6 @@ class AndroidEmulatorTest(BlobUploadMixin, TestingMixin, EmulatorMixin, VCSMixin
|
||||
self.info('stderr: %s' % str(err.strip()))
|
||||
return out
|
||||
|
||||
def _telnet_cmd(self, telnet, command):
|
||||
telnet.write('%s\n' % command)
|
||||
result = telnet.read_until('OK', 10)
|
||||
self.info('%s: %s' % (command, result))
|
||||
return result
|
||||
|
||||
def _verify_adb(self):
|
||||
self.info('Verifying adb connectivity')
|
||||
self._run_with_timeout(180, [self.adb_path, 'wait-for-device'])
|
||||
@ -287,37 +280,6 @@ class AndroidEmulatorTest(BlobUploadMixin, TestingMixin, EmulatorMixin, VCSMixin
|
||||
return True
|
||||
return False
|
||||
|
||||
def _telnet_to_emulator(self):
|
||||
port = self.emulator["emulator_port"]
|
||||
telnet_ok = False
|
||||
try:
|
||||
tn = telnetlib.Telnet('localhost', port, 10)
|
||||
if tn is not None:
|
||||
self.info('Connected to port %d' % port)
|
||||
res = tn.read_until('OK', 10)
|
||||
self.info(res)
|
||||
self._telnet_cmd(tn, 'avd status')
|
||||
self._telnet_cmd(tn, 'redir list')
|
||||
self._telnet_cmd(tn, 'network status')
|
||||
tn.write('quit\n')
|
||||
tn.read_all()
|
||||
telnet_ok = True
|
||||
else:
|
||||
self.warning('Unable to connect to port %d' % port)
|
||||
except socket.error, e:
|
||||
self.info('Trying again after socket error: %s' % str(e))
|
||||
pass
|
||||
except EOFError:
|
||||
self.info('Trying again after EOF')
|
||||
pass
|
||||
except:
|
||||
self.info('Trying again after unexpected exception')
|
||||
pass
|
||||
finally:
|
||||
if tn is not None:
|
||||
tn.close()
|
||||
return telnet_ok
|
||||
|
||||
def _verify_emulator(self):
|
||||
adb_ok = self._verify_adb()
|
||||
if not adb_ok:
|
||||
@ -331,10 +293,6 @@ class AndroidEmulatorTest(BlobUploadMixin, TestingMixin, EmulatorMixin, VCSMixin
|
||||
if not boot_ok:
|
||||
self.warning('Unable to verify Android boot completion')
|
||||
return False
|
||||
telnet_ok = self._retry(4, 30, self._telnet_to_emulator, "Verify telnet to emulator")
|
||||
if not telnet_ok:
|
||||
self.warning('Unable to telnet to emulator on port %d' % self.emulator["emulator_port"])
|
||||
return False
|
||||
return True
|
||||
|
||||
def _verify_emulator_and_restart_on_fail(self):
|
||||
@ -672,7 +630,7 @@ class AndroidEmulatorTest(BlobUploadMixin, TestingMixin, EmulatorMixin, VCSMixin
|
||||
|
||||
def verify_emulator(self):
|
||||
'''
|
||||
Check to see if the emulator can be contacted via adb and telnet.
|
||||
Check to see if the emulator can be contacted via adb.
|
||||
If any communication attempt fails, kill the emulator, re-launch, and re-check.
|
||||
'''
|
||||
self.mkdir_p(self.query_abs_dirs()['abs_blob_upload_dir'])
|
||||
|
@ -13,6 +13,7 @@ A script publish a release to Balrog.
|
||||
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
sys.path.insert(1, os.path.dirname(os.path.dirname(sys.path[0])))
|
||||
from mozharness.base.vcs.vcsbase import MercurialScript
|
||||
@ -74,7 +75,7 @@ class PublishBalrog(MercurialScript, BuildbotMixin):
|
||||
:return: list
|
||||
"""
|
||||
return [(n, c) for n, c in self.config["update_channels"].items() if
|
||||
n in self.config["channels"]]
|
||||
n in self.config["channels"]]
|
||||
|
||||
def query_repos(self):
|
||||
"""Build a list of repos to clone."""
|
||||
@ -84,7 +85,6 @@ class PublishBalrog(MercurialScript, BuildbotMixin):
|
||||
super(PublishBalrog, self).pull(
|
||||
repos=self.query_repos())
|
||||
|
||||
|
||||
def submit_to_balrog(self):
|
||||
for _, channel_config in self.query_channel_configs():
|
||||
self._submit_to_balrog(channel_config)
|
||||
@ -107,13 +107,21 @@ class PublishBalrog(MercurialScript, BuildbotMixin):
|
||||
])
|
||||
for r in channel_config["publish_rules"]:
|
||||
cmd.extend(["--rules", r])
|
||||
if self.config.get("schedule_at"):
|
||||
if channel_config.get("schedule_asap"):
|
||||
# RC releases going to the beta channel have no ETA set for the
|
||||
# RC-to-beta push. The corresponding task is scheduled after we
|
||||
# resolve the push-to-beta human decision task, so we can schedule
|
||||
# it ASAP plus some additional 30m to avoid retry() to fail.
|
||||
schedule_at = datetime.utcnow() + timedelta(minutes=30)
|
||||
cmd.extend(["--schedule-at", schedule_at.isoformat()])
|
||||
elif self.config.get("schedule_at"):
|
||||
cmd.extend(["--schedule-at", self.config["schedule_at"]])
|
||||
if self.config.get("background_rate"):
|
||||
cmd.extend(["--background-rate", str(self.config["background_rate"])])
|
||||
|
||||
self.retry(lambda: self.run_command(cmd, halt_on_failure=True))
|
||||
|
||||
|
||||
# __main__ {{{1
|
||||
if __name__ == '__main__':
|
||||
PublishBalrog().run_and_exit()
|
||||
|
@ -104624,6 +104624,12 @@
|
||||
{}
|
||||
]
|
||||
],
|
||||
"intersection-observer/bounding-box.html": [
|
||||
[
|
||||
"/intersection-observer/bounding-box.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"intersection-observer/client-rect.html": [
|
||||
[
|
||||
"/intersection-observer/client-rect.html",
|
||||
@ -192591,6 +192597,10 @@
|
||||
"4f94c4236168ed722f71d81bd957e0da72b29c71",
|
||||
"support"
|
||||
],
|
||||
"intersection-observer/bounding-box.html": [
|
||||
"0deef078368d11e2a55ef0988d50f548587a4c57",
|
||||
"testharness"
|
||||
],
|
||||
"intersection-observer/client-rect.html": [
|
||||
"acec9a4f59ebee1840950cf766a45676490eef84",
|
||||
"testharness"
|
||||
|
@ -0,0 +1,2 @@
|
||||
[bounding-box.html]
|
||||
type: testharness
|
@ -1,3 +1,2 @@
|
||||
[edge-inclusive-intersection.html]
|
||||
type: testharness
|
||||
disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1359317
|
||||
|
@ -1,3 +1,2 @@
|
||||
[unclipped-root.html]
|
||||
type: testharness
|
||||
disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1359317
|
||||
|
@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="./resources/intersection-observer-test-utils.js"></script>
|
||||
|
||||
<style>
|
||||
pre, #log {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 200px;
|
||||
}
|
||||
#root {
|
||||
overflow: visible;
|
||||
height: 200px;
|
||||
width: 160px;
|
||||
border: 7px solid black;
|
||||
}
|
||||
#target {
|
||||
margin: 10px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
padding: 10px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="root">
|
||||
<div id="target" style="transform: translateY(300px)"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var entries = [];
|
||||
var target;
|
||||
|
||||
runTestCycle(function() {
|
||||
target = document.getElementById("target");
|
||||
assert_true(!!target, "target exists");
|
||||
var root = document.getElementById("root");
|
||||
assert_true(!!root, "root exists");
|
||||
var observer = new IntersectionObserver(function(changes) {
|
||||
entries = entries.concat(changes)
|
||||
}, {root: root});
|
||||
observer.observe(target);
|
||||
entries = entries.concat(observer.takeRecords());
|
||||
assert_equals(entries.length, 0, "No initial notifications.");
|
||||
runTestCycle(step0, "First rAF.");
|
||||
}, "Test that the target's border bounding box is used to calculate intersection.");
|
||||
|
||||
function step0() {
|
||||
var targetBounds = clientBounds(target);
|
||||
target.style.transform = "translateY(195px)";
|
||||
runTestCycle(step1, "target.style.transform = 'translateY(195px)'");
|
||||
checkLastEntry(entries, 0, targetBounds.concat(0, 0, 0, 0, 8, 182, 8, 222, false));
|
||||
}
|
||||
|
||||
function step1() {
|
||||
var targetBounds = clientBounds(target);
|
||||
target.style.transform = "";
|
||||
checkLastEntry(entries, 1, targetBounds.concat(25, 145, 220, 222, 8, 182, 8, 222, true));
|
||||
}
|
||||
</script>
|
@ -748,6 +748,7 @@ this.Extension = class extends ExtensionData {
|
||||
this.parentMessageManager = null;
|
||||
|
||||
this.id = addonData.id;
|
||||
this.version = addonData.version;
|
||||
this.baseURI = NetUtil.newURI(this.getURL("")).QueryInterface(Ci.nsIURL);
|
||||
this.principal = this.createPrincipal();
|
||||
|
||||
@ -855,7 +856,7 @@ this.Extension = class extends ExtensionData {
|
||||
}
|
||||
|
||||
readLocaleFile(locale) {
|
||||
return StartupCache.locales.get([this.id, locale],
|
||||
return StartupCache.locales.get([this.id, this.version, locale],
|
||||
() => super.readLocaleFile(locale))
|
||||
.then(result => {
|
||||
this.localeData.messages.set(locale, result);
|
||||
@ -863,7 +864,7 @@ this.Extension = class extends ExtensionData {
|
||||
}
|
||||
|
||||
parseManifest() {
|
||||
return StartupCache.manifests.get([this.id, Locale.getLocale()],
|
||||
return StartupCache.manifests.get([this.id, this.version, Locale.getLocale()],
|
||||
() => super.parseManifest());
|
||||
}
|
||||
|
||||
|
@ -109,12 +109,15 @@ class EmbeddedExtension {
|
||||
* An object with the following properties:
|
||||
* @param {string} containerAddonParams.id
|
||||
* The Add-on id of the Legacy Extension which will contain the embedded webextension.
|
||||
* @param {string} containerAddonParams.version
|
||||
* The add-on version.
|
||||
* @param {nsIURI} containerAddonParams.resourceURI
|
||||
* The nsIURI of the Legacy Extension container add-on.
|
||||
*/
|
||||
constructor({id, resourceURI}) {
|
||||
constructor({id, resourceURI, version}) {
|
||||
this.addonId = id;
|
||||
this.resourceURI = resourceURI;
|
||||
this.version = version;
|
||||
|
||||
// Setup status flag.
|
||||
this.started = false;
|
||||
@ -139,6 +142,7 @@ class EmbeddedExtension {
|
||||
this.extension = new Extension({
|
||||
id: this.addonId,
|
||||
resourceURI: embeddedExtensionURI,
|
||||
version: this.version,
|
||||
});
|
||||
|
||||
// This callback is register to the "startup" event, emitted by the Extension instance
|
||||
@ -227,11 +231,11 @@ EmbeddedExtensionManager = {
|
||||
}
|
||||
},
|
||||
|
||||
getEmbeddedExtensionFor({id, resourceURI}) {
|
||||
getEmbeddedExtensionFor({id, resourceURI, version}) {
|
||||
let embeddedExtension = this.embeddedExtensionsByAddonId.get(id);
|
||||
|
||||
if (!embeddedExtension) {
|
||||
embeddedExtension = new EmbeddedExtension({id, resourceURI});
|
||||
embeddedExtension = new EmbeddedExtension({id, resourceURI, version});
|
||||
// Keep track of the embedded extension instance.
|
||||
this.embeddedExtensionsByAddonId.set(id, embeddedExtension);
|
||||
}
|
||||
|
@ -31,8 +31,8 @@ mozProtocolHandler.prototype = {
|
||||
|
||||
newChannel2(uri, loadInfo) {
|
||||
let realURL = NetUtil.newURI(this.urlToLoad);
|
||||
let channel = Services.io.newChannelFromURIWithLoadInfo(realURL, loadInfo)
|
||||
channel.loadFlags |= Ci.nsIChannel.LOAD_REPLACE;
|
||||
let channel = Services.io.newChannelFromURIWithLoadInfo(realURL, loadInfo);
|
||||
loadInfo.resultPrincipalURI = realURL;
|
||||
return channel;
|
||||
},
|
||||
|
||||
|
@ -175,8 +175,29 @@ var SessionHistoryInternal = {
|
||||
entry.originalURI = shEntry.originalURI.spec;
|
||||
}
|
||||
|
||||
if (shEntry.resultPrincipalURI) {
|
||||
entry.resultPrincipalURI = shEntry.resultPrincipalURI.spec;
|
||||
|
||||
// For downgrade compatibility we store the loadReplace property as it
|
||||
// would be stored before result principal URI introduction so that
|
||||
// the old code can still create URL based principals for channels
|
||||
// correctly. When resultPrincipalURI is non-null and not equal to
|
||||
// channel's orignalURI in the new code, it's equal to setting
|
||||
// LOAD_REPLACE in the old code. Note that we only do 'the best we can'
|
||||
// here to derivate the 'old' loadReplace flag value.
|
||||
entry.loadReplace = entry.resultPrincipalURI != entry.originalURI;
|
||||
} else {
|
||||
// We want to store the property to let the backward compatibility code,
|
||||
// when reading the stored session, work. When this property is undefined
|
||||
// that code will derive the result principal URI from the load replace
|
||||
// flag.
|
||||
entry.resultPrincipalURI = null;
|
||||
}
|
||||
|
||||
if (shEntry.loadReplace) {
|
||||
entry.loadReplace = shEntry.loadReplace;
|
||||
// Storing under a new property name, since it has changed its meaning
|
||||
// with the result principal URI introduction.
|
||||
entry.loadReplace2 = shEntry.loadReplace;
|
||||
}
|
||||
|
||||
if (shEntry.srcdocData)
|
||||
@ -368,8 +389,17 @@ var SessionHistoryInternal = {
|
||||
if (entry.originalURI) {
|
||||
shEntry.originalURI = Utils.makeURI(entry.originalURI);
|
||||
}
|
||||
if (entry.loadReplace) {
|
||||
shEntry.loadReplace = entry.loadReplace;
|
||||
if (typeof entry.resultPrincipalURI === "undefined" && entry.loadReplace) {
|
||||
// This is backward compatibility code for stored sessions saved prior to
|
||||
// introduction of the resultPrincipalURI property. The equivalent of this
|
||||
// property non-null value used to be the URL while the LOAD_REPLACE flag
|
||||
// was set.
|
||||
shEntry.resultPrincipalURI = shEntry.URI;
|
||||
} else if (entry.resultPrincipalURI) {
|
||||
shEntry.resultPrincipalURI = Utils.makeURI(entry.resultPrincipalURI);
|
||||
}
|
||||
if (entry.loadReplace2) {
|
||||
shEntry.loadReplace = entry.loadReplace2;
|
||||
}
|
||||
if (entry.isSrcdocEntry)
|
||||
shEntry.srcdocData = entry.srcdocData;
|
||||
|
@ -10,16 +10,18 @@
|
||||
#include "Layers.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
ProfilerMarkerPayload::ProfilerMarkerPayload(UniqueProfilerBacktrace aStack)
|
||||
: mStack(mozilla::Move(aStack))
|
||||
: mStack(Move(aStack))
|
||||
{}
|
||||
|
||||
ProfilerMarkerPayload::ProfilerMarkerPayload(const mozilla::TimeStamp& aStartTime,
|
||||
const mozilla::TimeStamp& aEndTime,
|
||||
ProfilerMarkerPayload::ProfilerMarkerPayload(const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime,
|
||||
UniqueProfilerBacktrace aStack)
|
||||
: mStartTime(aStartTime)
|
||||
, mEndTime(aEndTime)
|
||||
, mStack(mozilla::Move(aStack))
|
||||
, mStack(Move(aStack))
|
||||
{}
|
||||
|
||||
ProfilerMarkerPayload::~ProfilerMarkerPayload()
|
||||
@ -27,7 +29,7 @@ ProfilerMarkerPayload::~ProfilerMarkerPayload()
|
||||
}
|
||||
|
||||
void
|
||||
ProfilerMarkerPayload::streamCommonProps(const char* aMarkerType,
|
||||
ProfilerMarkerPayload::StreamCommonProps(const char* aMarkerType,
|
||||
SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
@ -51,30 +53,30 @@ ProfilerMarkerPayload::streamCommonProps(const char* aMarkerType,
|
||||
}
|
||||
}
|
||||
|
||||
ProfilerMarkerTracing::ProfilerMarkerTracing(const char* aCategory,
|
||||
TracingKind aKind)
|
||||
TracingMarkerPayload::TracingMarkerPayload(const char* aCategory,
|
||||
TracingKind aKind)
|
||||
: mCategory(aCategory)
|
||||
, mKind(aKind)
|
||||
{
|
||||
}
|
||||
|
||||
ProfilerMarkerTracing::ProfilerMarkerTracing(const char* aCategory,
|
||||
TracingKind aKind,
|
||||
UniqueProfilerBacktrace aCause)
|
||||
TracingMarkerPayload::TracingMarkerPayload(const char* aCategory,
|
||||
TracingKind aKind,
|
||||
UniqueProfilerBacktrace aCause)
|
||||
: mCategory(aCategory)
|
||||
, mKind(aKind)
|
||||
{
|
||||
if (aCause) {
|
||||
SetStack(mozilla::Move(aCause));
|
||||
SetStack(Move(aCause));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ProfilerMarkerTracing::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
TracingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
{
|
||||
streamCommonProps("tracing", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
StreamCommonProps("tracing", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
|
||||
if (GetCategory()) {
|
||||
aWriter.StringProperty("category", GetCategory());
|
||||
@ -88,8 +90,8 @@ ProfilerMarkerTracing::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
}
|
||||
|
||||
GPUMarkerPayload::GPUMarkerPayload(
|
||||
const mozilla::TimeStamp& aCpuTimeStart,
|
||||
const mozilla::TimeStamp& aCpuTimeEnd,
|
||||
const TimeStamp& aCpuTimeStart,
|
||||
const TimeStamp& aCpuTimeEnd,
|
||||
uint64_t aGpuTimeStart,
|
||||
uint64_t aGpuTimeEnd)
|
||||
|
||||
@ -105,7 +107,7 @@ GPUMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
{
|
||||
streamCommonProps("gpu_timer_query", aWriter, aProcessStartTime,
|
||||
StreamCommonProps("gpu_timer_query", aWriter, aProcessStartTime,
|
||||
aUniqueStacks);
|
||||
|
||||
aWriter.DoubleProperty("cpustart",
|
||||
@ -116,27 +118,12 @@ GPUMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
aWriter.IntProperty("gpuend", (int)mGpuTimeEnd);
|
||||
}
|
||||
|
||||
ProfilerMarkerImagePayload::ProfilerMarkerImagePayload(gfxASurface *aImg)
|
||||
: mImg(aImg)
|
||||
{ }
|
||||
|
||||
void
|
||||
ProfilerMarkerImagePayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
{
|
||||
streamCommonProps("innerHTML", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
// TODO: Finish me
|
||||
//aWriter.NameValue("innerHTML", "<img src=''/>");
|
||||
}
|
||||
|
||||
IOMarkerPayload::IOMarkerPayload(const char* aSource,
|
||||
const char* aFilename,
|
||||
const mozilla::TimeStamp& aStartTime,
|
||||
const mozilla::TimeStamp& aEndTime,
|
||||
const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime,
|
||||
UniqueProfilerBacktrace aStack)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime,
|
||||
mozilla::Move(aStack)),
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime, Move(aStack)),
|
||||
mSource(aSource)
|
||||
{
|
||||
mFilename = aFilename ? strdup(aFilename) : nullptr;
|
||||
@ -152,7 +139,7 @@ IOMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
{
|
||||
streamCommonProps("io", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
StreamCommonProps("io", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
aWriter.StringProperty("source", mSource);
|
||||
if (mFilename != nullptr) {
|
||||
aWriter.StringProperty("filename", mFilename);
|
||||
@ -160,7 +147,7 @@ IOMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
}
|
||||
|
||||
UserTimingMarkerPayload::UserTimingMarkerPayload(const nsAString& aName,
|
||||
const mozilla::TimeStamp& aStartTime)
|
||||
const TimeStamp& aStartTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aStartTime, nullptr)
|
||||
, mEntryType("mark")
|
||||
, mName(aName)
|
||||
@ -168,8 +155,8 @@ UserTimingMarkerPayload::UserTimingMarkerPayload(const nsAString& aName,
|
||||
}
|
||||
|
||||
UserTimingMarkerPayload::UserTimingMarkerPayload(const nsAString& aName,
|
||||
const mozilla::TimeStamp& aStartTime,
|
||||
const mozilla::TimeStamp& aEndTime)
|
||||
const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime, nullptr)
|
||||
, mEntryType("measure")
|
||||
, mName(aName)
|
||||
@ -185,14 +172,14 @@ UserTimingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
{
|
||||
streamCommonProps("UserTiming", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
StreamCommonProps("UserTiming", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
aWriter.StringProperty("name", NS_ConvertUTF16toUTF8(mName).get());
|
||||
aWriter.StringProperty("entryType", mEntryType);
|
||||
}
|
||||
|
||||
DOMEventMarkerPayload::DOMEventMarkerPayload(const nsAString& aType, uint16_t aPhase,
|
||||
const mozilla::TimeStamp& aStartTime,
|
||||
const mozilla::TimeStamp& aEndTime)
|
||||
const TimeStamp& aStartTime,
|
||||
const TimeStamp& aEndTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime, nullptr)
|
||||
, mType(aType)
|
||||
, mPhase(aPhase)
|
||||
@ -208,7 +195,7 @@ DOMEventMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
{
|
||||
streamCommonProps("DOMEvent", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
StreamCommonProps("DOMEvent", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
aWriter.StringProperty("type", NS_ConvertUTF16toUTF8(mType).get());
|
||||
aWriter.IntProperty("phase", mPhase);
|
||||
}
|
||||
@ -219,18 +206,18 @@ ProfilerJSEventMarker(const char *event)
|
||||
PROFILER_MARKER(event);
|
||||
}
|
||||
|
||||
LayerTranslationPayload::LayerTranslationPayload(mozilla::layers::Layer* aLayer,
|
||||
mozilla::gfx::Point aPoint)
|
||||
: ProfilerMarkerPayload(mozilla::TimeStamp::Now(), mozilla::TimeStamp::Now(), nullptr)
|
||||
LayerTranslationMarkerPayload::LayerTranslationMarkerPayload(layers::Layer* aLayer,
|
||||
gfx::Point aPoint)
|
||||
: ProfilerMarkerPayload(TimeStamp::Now(), TimeStamp::Now(), nullptr)
|
||||
, mLayer(aLayer)
|
||||
, mPoint(aPoint)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LayerTranslationPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
LayerTranslationMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
{
|
||||
const size_t bufferSize = 32;
|
||||
char buffer[bufferSize];
|
||||
@ -242,31 +229,16 @@ LayerTranslationPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
aWriter.StringProperty("category", "LayerTranslation");
|
||||
}
|
||||
|
||||
TouchDataPayload::TouchDataPayload(const mozilla::ScreenIntPoint& aPoint)
|
||||
: ProfilerMarkerPayload(mozilla::TimeStamp::Now(), mozilla::TimeStamp::Now(), nullptr)
|
||||
{
|
||||
mPoint = aPoint;
|
||||
}
|
||||
|
||||
void
|
||||
TouchDataPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
{
|
||||
aWriter.IntProperty("x", mPoint.x);
|
||||
aWriter.IntProperty("y", mPoint.y);
|
||||
}
|
||||
|
||||
VsyncPayload::VsyncPayload(mozilla::TimeStamp aVsyncTimestamp)
|
||||
VsyncMarkerPayload::VsyncMarkerPayload(TimeStamp aVsyncTimestamp)
|
||||
: ProfilerMarkerPayload(aVsyncTimestamp, aVsyncTimestamp, nullptr)
|
||||
, mVsyncTimestamp(aVsyncTimestamp)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
VsyncPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
VsyncMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
{
|
||||
aWriter.DoubleProperty("vsync",
|
||||
(mVsyncTimestamp - aProcessStartTime).ToMilliseconds());
|
||||
@ -275,11 +247,11 @@ VsyncPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
|
||||
void
|
||||
GCSliceMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aProcessStartTime,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
{
|
||||
MOZ_ASSERT(mTimingJSON);
|
||||
streamCommonProps("GCSlice", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
StreamCommonProps("GCSlice", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
if (mTimingJSON) {
|
||||
aWriter.SplicedJSONProperty("timings", mTimingJSON.get());
|
||||
} else {
|
||||
@ -289,11 +261,11 @@ GCSliceMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
|
||||
void
|
||||
GCMajorMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aProcessStartTime,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
{
|
||||
MOZ_ASSERT(mTimingJSON);
|
||||
streamCommonProps("GCMajor", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
StreamCommonProps("GCMajor", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
if (mTimingJSON) {
|
||||
aWriter.SplicedJSONProperty("timings", mTimingJSON.get());
|
||||
} else {
|
||||
@ -303,11 +275,11 @@ GCMajorMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
|
||||
void
|
||||
GCMinorMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aProcessStartTime,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
{
|
||||
MOZ_ASSERT(mTimingData);
|
||||
streamCommonProps("GCMinor", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
StreamCommonProps("GCMinor", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
if (mTimingData) {
|
||||
aWriter.SplicedJSONProperty("nurseryTimings", mTimingData.get());
|
||||
} else {
|
||||
|
@ -76,7 +76,7 @@ Thread::GetCurrentId()
|
||||
}
|
||||
|
||||
static void
|
||||
FillInRegs(Registers& aRegs, ucontext_t* aContext)
|
||||
PopulateRegsFromContext(Registers& aRegs, ucontext_t* aContext)
|
||||
{
|
||||
aRegs.mContext = aContext;
|
||||
mcontext_t& mcontext = aContext->uc_mcontext;
|
||||
@ -86,10 +86,12 @@ FillInRegs(Registers& aRegs, ucontext_t* aContext)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]);
|
||||
aRegs.mLR = 0;
|
||||
#elif defined(GP_ARCH_amd64)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]);
|
||||
aRegs.mLR = 0;
|
||||
#elif defined(GP_ARCH_arm)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.arm_pc);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.arm_sp);
|
||||
@ -359,7 +361,7 @@ Sampler::SuspendAndSampleAndResumeThread(PSLockRef aLock,
|
||||
|
||||
// Extract the current register values.
|
||||
Registers regs;
|
||||
FillInRegs(regs, &sSigHandlerCoordinator->mUContext);
|
||||
PopulateRegsFromContext(regs, &sSigHandlerCoordinator->mUContext);
|
||||
aProcessRegs(regs);
|
||||
|
||||
//----------------------------------------------------------------//
|
||||
@ -523,13 +525,18 @@ PlatformInit(PSLockRef aLock)
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
Registers::SyncPopulate(ucontext_t* aContext)
|
||||
{
|
||||
MOZ_ASSERT(aContext);
|
||||
#if defined(HAVE_NATIVE_UNWIND)
|
||||
// Context used by synchronous samples. It's safe to have a single one because
|
||||
// only one synchronous sample can be taken at a time (due to
|
||||
// profiler_get_backtrace()'s PSAutoLock).
|
||||
ucontext_t sSyncUContext;
|
||||
|
||||
if (!getcontext(aContext)) {
|
||||
FillInRegs(*this, aContext);
|
||||
void
|
||||
Registers::SyncPopulate()
|
||||
{
|
||||
if (!getcontext(&sSyncUContext)) {
|
||||
PopulateRegsFromContext(*this, &sSyncUContext);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -120,6 +120,7 @@ Sampler::SuspendAndSampleAndResumeThread(PSLockRef aLock,
|
||||
regs.mPC = reinterpret_cast<Address>(state.REGISTER_FIELD(ip));
|
||||
regs.mSP = reinterpret_cast<Address>(state.REGISTER_FIELD(sp));
|
||||
regs.mFP = reinterpret_cast<Address>(state.REGISTER_FIELD(bp));
|
||||
regs.mLR = 0;
|
||||
|
||||
aProcessRegs(regs);
|
||||
}
|
||||
@ -192,6 +193,7 @@ PlatformInit(PSLockRef aLock)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(HAVE_NATIVE_UNWIND)
|
||||
void
|
||||
Registers::SyncPopulate()
|
||||
{
|
||||
@ -207,5 +209,7 @@ Registers::SyncPopulate()
|
||||
);
|
||||
mPC = reinterpret_cast<Address>(__builtin_extract_return_addr(
|
||||
__builtin_return_address(0)));
|
||||
mLR = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -38,6 +38,23 @@ Thread::GetCurrentId()
|
||||
return GetCurrentThreadId();
|
||||
}
|
||||
|
||||
static void
|
||||
PopulateRegsFromContext(Registers& aRegs, CONTEXT* aContext)
|
||||
{
|
||||
#if defined(GP_ARCH_amd64)
|
||||
aRegs.mPC = reinterpret_cast<Address>(aContext->Rip);
|
||||
aRegs.mSP = reinterpret_cast<Address>(aContext->Rsp);
|
||||
aRegs.mFP = reinterpret_cast<Address>(aContext->Rbp);
|
||||
#elif defined(GP_ARCH_x86)
|
||||
aRegs.mPC = reinterpret_cast<Address>(aContext->Eip);
|
||||
aRegs.mSP = reinterpret_cast<Address>(aContext->Esp);
|
||||
aRegs.mFP = reinterpret_cast<Address>(aContext->Ebp);
|
||||
#else
|
||||
#error "bad arch"
|
||||
#endif
|
||||
aRegs.mLR = 0;
|
||||
}
|
||||
|
||||
class PlatformData
|
||||
{
|
||||
public:
|
||||
@ -139,16 +156,7 @@ Sampler::SuspendAndSampleAndResumeThread(PSLockRef aLock,
|
||||
// platform-linux-android.cpp for details.
|
||||
|
||||
Registers regs;
|
||||
#if defined(GP_ARCH_amd64)
|
||||
regs.mPC = reinterpret_cast<Address>(context.Rip);
|
||||
regs.mSP = reinterpret_cast<Address>(context.Rsp);
|
||||
regs.mFP = reinterpret_cast<Address>(context.Rbp);
|
||||
#else
|
||||
regs.mPC = reinterpret_cast<Address>(context.Eip);
|
||||
regs.mSP = reinterpret_cast<Address>(context.Esp);
|
||||
regs.mFP = reinterpret_cast<Address>(context.Ebp);
|
||||
#endif
|
||||
|
||||
PopulateRegsFromContext(regs, &context);
|
||||
aProcessRegs(regs);
|
||||
|
||||
//----------------------------------------------------------------//
|
||||
@ -264,20 +272,13 @@ PlatformInit(PSLockRef aLock)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(HAVE_NATIVE_UNWIND)
|
||||
void
|
||||
Registers::SyncPopulate()
|
||||
{
|
||||
CONTEXT context;
|
||||
RtlCaptureContext(&context);
|
||||
|
||||
#if defined(GP_ARCH_amd64)
|
||||
mPC = reinterpret_cast<Address>(context.Rip);
|
||||
mSP = reinterpret_cast<Address>(context.Rsp);
|
||||
mFP = reinterpret_cast<Address>(context.Rbp);
|
||||
#elif defined(GP_ARCH_x86)
|
||||
mPC = reinterpret_cast<Address>(context.Eip);
|
||||
mSP = reinterpret_cast<Address>(context.Esp);
|
||||
mFP = reinterpret_cast<Address>(context.Ebp);
|
||||
#endif
|
||||
PopulateRegsFromContext(*this, &context);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -628,26 +628,19 @@ static const char* const kMainThreadName = "GeckoMain";
|
||||
// BEGIN sampling/unwinding code
|
||||
|
||||
// The registers used for stack unwinding and a few other sampling purposes.
|
||||
// The ctor does nothing; users are responsible for filling in the fields.
|
||||
class Registers
|
||||
{
|
||||
public:
|
||||
Registers()
|
||||
: mPC(nullptr)
|
||||
, mSP(nullptr)
|
||||
, mFP(nullptr)
|
||||
, mLR(nullptr)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
, mContext(nullptr)
|
||||
#endif
|
||||
{}
|
||||
Registers() {}
|
||||
|
||||
// Fills in mContext, mPC, mSP, mFP, and mLR for a synchronous sample.
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
void SyncPopulate(ucontext_t* aContext);
|
||||
#else
|
||||
#if defined(HAVE_NATIVE_UNWIND)
|
||||
// Fills in mPC, mSP, mFP, mLR, and mContext for a synchronous sample.
|
||||
void SyncPopulate();
|
||||
#endif
|
||||
|
||||
void Clear() { memset(this, 0, sizeof(*this)); }
|
||||
|
||||
// These fields are filled in by
|
||||
// SamplerThread::SuspendAndSampleAndResumeThread() for periodic and
|
||||
// backtrace samples, and by SyncPopulate() for synchronous samples.
|
||||
@ -2834,14 +2827,10 @@ profiler_get_backtrace()
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
|
||||
Registers regs;
|
||||
|
||||
#if defined(HAVE_NATIVE_UNWIND)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
ucontext_t context;
|
||||
regs.SyncPopulate(&context);
|
||||
#else
|
||||
regs.SyncPopulate();
|
||||
#endif
|
||||
#else
|
||||
regs.Clear();
|
||||
#endif
|
||||
|
||||
auto buffer = MakeUnique<ProfileBuffer>(PROFILER_GET_BACKTRACE_ENTRIES);
|
||||
@ -2975,7 +2964,7 @@ profiler_tracing(const char* aCategory, const char* aMarkerName,
|
||||
return;
|
||||
}
|
||||
|
||||
auto payload = MakeUnique<ProfilerMarkerTracing>(aCategory, aKind);
|
||||
auto payload = MakeUnique<TracingMarkerPayload>(aCategory, aKind);
|
||||
racy_profiler_add_marker(aMarkerName, Move(payload));
|
||||
}
|
||||
|
||||
@ -2991,7 +2980,7 @@ profiler_tracing(const char* aCategory, const char* aMarkerName,
|
||||
}
|
||||
|
||||
auto payload =
|
||||
MakeUnique<ProfilerMarkerTracing>(aCategory, aKind, Move(aCause));
|
||||
MakeUnique<TracingMarkerPayload>(aCategory, aKind, Move(aCause));
|
||||
racy_profiler_add_marker(aMarkerName, Move(payload));
|
||||
}
|
||||
|
||||
|
@ -30,20 +30,9 @@ class SpliceableJSONWriter;
|
||||
|
||||
namespace mozilla {
|
||||
class MallocAllocPolicy;
|
||||
class TimeStamp;
|
||||
template <class T,
|
||||
size_t MinInlineCapacity,
|
||||
class AllocPolicy>
|
||||
class Vector;
|
||||
|
||||
namespace dom {
|
||||
class Promise;
|
||||
} // namespace dom
|
||||
|
||||
template <class T, size_t MinInlineCapacity, class AllocPolicy> class Vector;
|
||||
} // namespace mozilla
|
||||
|
||||
class nsIProfilerStartParams;
|
||||
|
||||
enum TracingKind {
|
||||
TRACING_EVENT,
|
||||
TRACING_INTERVAL_START,
|
||||
@ -59,61 +48,52 @@ struct ProfilerBacktraceDestructor
|
||||
using UniqueProfilerBacktrace =
|
||||
mozilla::UniquePtr<ProfilerBacktrace, ProfilerBacktraceDestructor>;
|
||||
|
||||
#if !defined(MOZ_GECKO_PROFILER)
|
||||
#if defined(MOZ_GECKO_PROFILER)
|
||||
|
||||
// Use these for functions below that must be visible whether the profiler is
|
||||
// enabled or not. When the profiler is disabled they are static inline
|
||||
// functions (with a simple return value if they are non-void) that should be
|
||||
// optimized away during compilation.
|
||||
#define PROFILER_FUNC(decl, rv) static inline decl { return rv; }
|
||||
#define PROFILER_FUNC_VOID(decl) static inline void decl {}
|
||||
#define PROFILER_FUNC(decl, rv) decl;
|
||||
#define PROFILER_FUNC_VOID(decl) void decl;
|
||||
|
||||
// Insert an RAII object in this scope to enter a pseudo stack frame. Any
|
||||
// samples collected in this scope will contain this label in their pseudo
|
||||
// stack. The name_space and info arguments must be string literals.
|
||||
// Use PROFILER_LABEL_DYNAMIC if you want to add additional / dynamic
|
||||
// information to the pseudo stack frame.
|
||||
#define PROFILER_LABEL(name_space, info, category) do {} while (0)
|
||||
// Uncomment this to turn on systrace or build with
|
||||
// ac_add_options --enable-systace
|
||||
//#define MOZ_USE_SYSTRACE
|
||||
#ifdef MOZ_USE_SYSTRACE
|
||||
# ifndef ATRACE_TAG
|
||||
# define ATRACE_TAG ATRACE_TAG_ALWAYS
|
||||
# endif
|
||||
// We need HAVE_ANDROID_OS to be defined for Trace.h.
|
||||
// If its not set we will set it temporary and remove it.
|
||||
# ifndef HAVE_ANDROID_OS
|
||||
# define HAVE_ANDROID_OS
|
||||
# define REMOVE_HAVE_ANDROID_OS
|
||||
# endif
|
||||
// Android source code will include <cutils/trace.h> before this. There is no
|
||||
// HAVE_ANDROID_OS defined in Firefox OS build at that time. Enabled it globally
|
||||
// will cause other build break. So atrace_begin and atrace_end are not defined.
|
||||
// It will cause a build-break when we include <utils/Trace.h>. Use undef
|
||||
// _LIBS_CUTILS_TRACE_H will force <cutils/trace.h> to define atrace_begin and
|
||||
// atrace_end with defined HAVE_ANDROID_OS again. Then there is no build-break.
|
||||
# undef _LIBS_CUTILS_TRACE_H
|
||||
# include <utils/Trace.h>
|
||||
# define PROFILER_PLATFORM_TRACING(name) \
|
||||
android::ScopedTrace \
|
||||
PROFILER_APPEND_LINE_NUMBER(scopedTrace)(ATRACE_TAG, name);
|
||||
# ifdef REMOVE_HAVE_ANDROID_OS
|
||||
# undef HAVE_ANDROID_OS
|
||||
# undef REMOVE_HAVE_ANDROID_OS
|
||||
# endif
|
||||
#else
|
||||
# define PROFILER_PLATFORM_TRACING(name)
|
||||
#endif
|
||||
|
||||
// Similar to PROFILER_LABEL, PROFILER_LABEL_FUNC will push/pop the enclosing
|
||||
// functon name as the pseudostack label.
|
||||
#define PROFILER_LABEL_FUNC(category) do {} while (0)
|
||||
|
||||
// Enter a pseudo stack frame in this scope and associate it with an
|
||||
// additional string.
|
||||
// This macro generates an RAII object. This RAII object stores the dynamicStr
|
||||
// pointer in a field; it does not copy the string. This means that the string
|
||||
// you pass to this macro needs to live at least until the end of the current
|
||||
// scope.
|
||||
// If the profiler samples the current thread and walks the pseudo stack while
|
||||
// this RAII object is on the stack, it will copy the supplied string into the
|
||||
// profile buffer. So there's one string copy operation, and it happens at
|
||||
// sample time.
|
||||
// Compare this to the plain PROFILER_LABEL macro, which only accepts literal
|
||||
// strings: When the pseudo stack frames generated by PROFILER_LABEL are
|
||||
// sampled, no string copy needs to be made because the profile buffer can
|
||||
// just store the raw pointers to the literal strings. Consequently,
|
||||
// PROFILER_LABEL frames take up considerably less space in the profile buffer
|
||||
// than PROFILER_LABEL_DYNAMIC frames.
|
||||
#define PROFILER_LABEL_DYNAMIC(name_space, info, category, dynamicStr) \
|
||||
do {} while (0)
|
||||
|
||||
// Insert a marker in the profile timeline. This is useful to delimit something
|
||||
// important happening such as the first paint. Unlike profiler_label that are
|
||||
// only recorded if a sample is collected while it is active, marker will always
|
||||
// be collected.
|
||||
#define PROFILER_MARKER(marker_name) do {} while (0)
|
||||
|
||||
// Like PROFILER_MARKER, but with an additional payload.
|
||||
//
|
||||
// Note: this is deliberately not defined when MOZ_GECKO_PROFILER is undefined.
|
||||
// This macro should not be used in that case -- i.e. all uses of this macro
|
||||
// should be guarded by a MOZ_GECKO_PROFILER check -- because payload creation
|
||||
// requires allocation, which is something we should not do in builds that
|
||||
// don't contain the profiler.
|
||||
//#define PROFILER_MARKER_PAYLOAD(marker_name, payload) /* undefined */
|
||||
|
||||
#else // defined(MOZ_GECKO_PROFILER)
|
||||
#define PROFILER_APPEND_LINE_NUMBER_PASTE(id, line) id ## line
|
||||
#define PROFILER_APPEND_LINE_NUMBER_EXPAND(id, line) \
|
||||
PROFILER_APPEND_LINE_NUMBER_PASTE(id, line)
|
||||
#define PROFILER_APPEND_LINE_NUMBER(id) \
|
||||
PROFILER_APPEND_LINE_NUMBER_EXPAND(id, __LINE__)
|
||||
|
||||
#if defined(__GNUC__) || defined(_MSC_VER)
|
||||
# define PROFILER_FUNCTION_NAME __FUNCTION__
|
||||
@ -122,34 +102,76 @@ using UniqueProfilerBacktrace =
|
||||
# define PROFILER_FUNCTION_NAME __func__
|
||||
#endif
|
||||
|
||||
#define PROFILER_FUNC(decl, rv) decl;
|
||||
#define PROFILER_FUNC_VOID(decl) void decl;
|
||||
|
||||
// we want the class and function name but can't easily get that using preprocessor macros
|
||||
// __func__ doesn't have the class name and __PRETTY_FUNCTION__ has the parameters
|
||||
|
||||
// Insert an RAII object in this scope to enter a pseudo stack frame. Any
|
||||
// samples collected in this scope will contain this label in their pseudo
|
||||
// stack. The name_space and info arguments must be string literals.
|
||||
// Use PROFILER_LABEL_DYNAMIC if you want to add additional / dynamic
|
||||
// information to the pseudo stack frame.
|
||||
#define PROFILER_LABEL(name_space, info, category) \
|
||||
PROFILER_PLATFORM_TRACING(name_space "::" info) \
|
||||
mozilla::AutoProfilerLabel \
|
||||
PROFILER_APPEND_LINE_NUMBER(profiler_raii)(name_space "::" info, nullptr, \
|
||||
__LINE__, category)
|
||||
|
||||
// Similar to PROFILER_LABEL, PROFILER_LABEL_FUNC will push/pop the enclosing
|
||||
// functon name as the pseudostack label.
|
||||
#define PROFILER_LABEL_FUNC(category) \
|
||||
PROFILER_PLATFORM_TRACING(PROFILER_FUNCTION_NAME) \
|
||||
mozilla::AutoProfilerLabel \
|
||||
PROFILER_APPEND_LINE_NUMBER(profiler_raii)(PROFILER_FUNCTION_NAME, nullptr, \
|
||||
__LINE__, category)
|
||||
|
||||
// Similar to PROFILER_LABEL, but with an additional string. The inserted RAII
|
||||
// object stores the dynamicStr pointer in a field; it does not copy the string.
|
||||
// This means that the string you pass to this macro needs to live at least
|
||||
// until the end of the current scope.
|
||||
//
|
||||
// If the profiler samples the current thread and walks the pseudo stack while
|
||||
// this RAII object is on the stack, it will copy the supplied string into the
|
||||
// profile buffer. So there's one string copy operation, and it happens at
|
||||
// sample time.
|
||||
//
|
||||
// Compare this to the plain PROFILER_LABEL macro, which only accepts literal
|
||||
// strings: When the pseudo stack frames generated by PROFILER_LABEL are
|
||||
// sampled, no string copy needs to be made because the profile buffer can
|
||||
// just store the raw pointers to the literal strings. Consequently,
|
||||
// PROFILER_LABEL frames take up considerably less space in the profile buffer
|
||||
// than PROFILER_LABEL_DYNAMIC frames.
|
||||
#define PROFILER_LABEL_DYNAMIC(name_space, info, category, dynamicStr) \
|
||||
PROFILER_PLATFORM_TRACING(name_space "::" info) \
|
||||
mozilla::AutoProfilerLabel \
|
||||
PROFILER_APPEND_LINE_NUMBER(profiler_raii)(name_space "::" info, dynamicStr, \
|
||||
__LINE__, category)
|
||||
|
||||
// Insert a marker in the profile timeline. This is useful to delimit something
|
||||
// important happening such as the first paint. Unlike labels, which are only
|
||||
// recorded in the profile buffer if a sample is collected while the label is
|
||||
// on the pseudostack, markers will always be recorded in the profile buffer.
|
||||
#define PROFILER_MARKER(marker_name) profiler_add_marker(marker_name)
|
||||
|
||||
// Like PROFILER_MARKER, but with an additional payload.
|
||||
#define PROFILER_MARKER_PAYLOAD(marker_name, payload) \
|
||||
profiler_add_marker(marker_name, payload)
|
||||
|
||||
#else // defined(MOZ_GECKO_PROFILER)
|
||||
|
||||
#define PROFILER_FUNC(decl, rv) static inline decl { return rv; }
|
||||
#define PROFILER_FUNC_VOID(decl) static inline void decl {}
|
||||
|
||||
#define PROFILER_LABEL(name_space, info, category) do {} while (0)
|
||||
#define PROFILER_LABEL_FUNC(category) do {} while (0)
|
||||
#define PROFILER_LABEL_DYNAMIC(name_space, info, category, dynamicStr) \
|
||||
do {} while (0)
|
||||
|
||||
#define PROFILER_MARKER(marker_name) do {} while (0)
|
||||
|
||||
// Note: this is deliberately not defined when MOZ_GECKO_PROFILER is undefined.
|
||||
// This macro should not be used in that case -- i.e. all uses of this macro
|
||||
// should be guarded by a MOZ_GECKO_PROFILER check -- because payload creation
|
||||
// requires allocation, which is something we should not do in builds that
|
||||
// don't contain the profiler.
|
||||
//#define PROFILER_MARKER_PAYLOAD(marker_name, payload) /* undefined */
|
||||
|
||||
#endif // defined(MOZ_GECKO_PROFILER)
|
||||
|
||||
// Higher-order macro containing all the feature info in one place. Define
|
||||
@ -415,7 +437,6 @@ PROFILER_FUNC_VOID(profiler_suspend_and_sample_thread(int aThreadId,
|
||||
# undef min
|
||||
#endif
|
||||
|
||||
class nsISupports;
|
||||
class ProfilerMarkerPayload;
|
||||
|
||||
// This exists purely for AutoProfilerLabel. See the comment on the
|
||||
@ -428,44 +449,6 @@ void profiler_add_marker(const char* aMarkerName);
|
||||
void profiler_add_marker(const char* aMarkerName,
|
||||
mozilla::UniquePtr<ProfilerMarkerPayload> aPayload);
|
||||
|
||||
#define PROFILER_APPEND_LINE_NUMBER_PASTE(id, line) id ## line
|
||||
#define PROFILER_APPEND_LINE_NUMBER_EXPAND(id, line) \
|
||||
PROFILER_APPEND_LINE_NUMBER_PASTE(id, line)
|
||||
#define PROFILER_APPEND_LINE_NUMBER(id) \
|
||||
PROFILER_APPEND_LINE_NUMBER_EXPAND(id, __LINE__)
|
||||
|
||||
// Uncomment this to turn on systrace or build with
|
||||
// ac_add_options --enable-systace
|
||||
//#define MOZ_USE_SYSTRACE
|
||||
#ifdef MOZ_USE_SYSTRACE
|
||||
# ifndef ATRACE_TAG
|
||||
# define ATRACE_TAG ATRACE_TAG_ALWAYS
|
||||
# endif
|
||||
// We need HAVE_ANDROID_OS to be defined for Trace.h.
|
||||
// If its not set we will set it temporary and remove it.
|
||||
# ifndef HAVE_ANDROID_OS
|
||||
# define HAVE_ANDROID_OS
|
||||
# define REMOVE_HAVE_ANDROID_OS
|
||||
# endif
|
||||
// Android source code will include <cutils/trace.h> before this. There is no
|
||||
// HAVE_ANDROID_OS defined in Firefox OS build at that time. Enabled it globally
|
||||
// will cause other build break. So atrace_begin and atrace_end are not defined.
|
||||
// It will cause a build-break when we include <utils/Trace.h>. Use undef
|
||||
// _LIBS_CUTILS_TRACE_H will force <cutils/trace.h> to define atrace_begin and
|
||||
// atrace_end with defined HAVE_ANDROID_OS again. Then there is no build-break.
|
||||
# undef _LIBS_CUTILS_TRACE_H
|
||||
# include <utils/Trace.h>
|
||||
# define PROFILER_PLATFORM_TRACING(name) \
|
||||
android::ScopedTrace \
|
||||
PROFILER_APPEND_LINE_NUMBER(scopedTrace)(ATRACE_TAG, name);
|
||||
# ifdef REMOVE_HAVE_ANDROID_OS
|
||||
# undef HAVE_ANDROID_OS
|
||||
# undef REMOVE_HAVE_ANDROID_OS
|
||||
# endif
|
||||
#else
|
||||
# define PROFILER_PLATFORM_TRACING(name)
|
||||
#endif
|
||||
|
||||
#if !defined(ARCH_ARMV6)
|
||||
# define PROFILER_DEFAULT_ENTRIES 1000000
|
||||
#else
|
||||
|
@ -1,10 +1,11 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- 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 PROFILER_MARKERS_H
|
||||
#define PROFILER_MARKERS_H
|
||||
#ifndef ProfilerMarkerPayload_h
|
||||
#define ProfilerMarkerPayload_h
|
||||
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
@ -25,18 +26,11 @@ class Layer;
|
||||
class SpliceableJSONWriter;
|
||||
class UniqueStacks;
|
||||
|
||||
/**
|
||||
* This is an abstract object that can be implied to supply
|
||||
* data to be attached with a profiler marker. Most data inserted
|
||||
* into a profile is stored in a circular buffer. This buffer
|
||||
* typically wraps around and overwrites most entries. Because
|
||||
* of this, this structure is designed to defer the work of
|
||||
* prepare the payload only when 'preparePayload' is called.
|
||||
*
|
||||
* Note when implementing that this object is typically constructed
|
||||
* on a particular thread but 'preparePayload' and the destructor
|
||||
* is called from the main thread.
|
||||
*/
|
||||
// This is an abstract class that can be implemented to supply data to be
|
||||
// attached with a profiler marker.
|
||||
//
|
||||
// When subclassing this, note that the destructor can be called on any thread,
|
||||
// i.e. not necessarily on the thread that created the object.
|
||||
class ProfilerMarkerPayload
|
||||
{
|
||||
public:
|
||||
@ -45,14 +39,8 @@ public:
|
||||
const mozilla::TimeStamp& aEndTime,
|
||||
UniqueProfilerBacktrace aStack = nullptr);
|
||||
|
||||
/**
|
||||
* Called from the main thread
|
||||
*/
|
||||
virtual ~ProfilerMarkerPayload();
|
||||
|
||||
/**
|
||||
* Called from the main thread
|
||||
*/
|
||||
virtual void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) = 0;
|
||||
@ -60,28 +48,28 @@ public:
|
||||
mozilla::TimeStamp GetStartTime() const { return mStartTime; }
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Called from the main thread
|
||||
*/
|
||||
void streamCommonProps(const char* aMarkerType,
|
||||
void StreamCommonProps(const char* aMarkerType,
|
||||
SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks);
|
||||
|
||||
void SetStack(UniqueProfilerBacktrace aStack) { mStack = mozilla::Move(aStack); }
|
||||
void SetStack(UniqueProfilerBacktrace aStack)
|
||||
{
|
||||
mStack = mozilla::Move(aStack);
|
||||
}
|
||||
|
||||
private:
|
||||
mozilla::TimeStamp mStartTime;
|
||||
mozilla::TimeStamp mEndTime;
|
||||
UniqueProfilerBacktrace mStack;
|
||||
mozilla::TimeStamp mStartTime;
|
||||
mozilla::TimeStamp mEndTime;
|
||||
UniqueProfilerBacktrace mStack;
|
||||
};
|
||||
|
||||
class ProfilerMarkerTracing : public ProfilerMarkerPayload
|
||||
class TracingMarkerPayload : public ProfilerMarkerPayload
|
||||
{
|
||||
public:
|
||||
ProfilerMarkerTracing(const char* aCategory, TracingKind aKind);
|
||||
ProfilerMarkerTracing(const char* aCategory, TracingKind aKind,
|
||||
UniqueProfilerBacktrace aCause);
|
||||
TracingMarkerPayload(const char* aCategory, TracingKind aKind);
|
||||
TracingMarkerPayload(const char* aCategory, TracingKind aKind,
|
||||
UniqueProfilerBacktrace aCause);
|
||||
|
||||
const char *GetCategory() const { return mCategory; }
|
||||
TracingKind GetKind() const { return mKind; }
|
||||
@ -95,19 +83,6 @@ private:
|
||||
TracingKind mKind;
|
||||
};
|
||||
|
||||
class ProfilerMarkerImagePayload : public ProfilerMarkerPayload
|
||||
{
|
||||
public:
|
||||
explicit ProfilerMarkerImagePayload(gfxASurface *aImg);
|
||||
|
||||
virtual void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) override;
|
||||
|
||||
private:
|
||||
RefPtr<gfxASurface> mImg;
|
||||
};
|
||||
|
||||
class IOMarkerPayload : public ProfilerMarkerPayload
|
||||
{
|
||||
public:
|
||||
@ -163,14 +138,12 @@ private:
|
||||
nsString mName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains the translation applied to a 2d layer so we can
|
||||
* track the layer position at each frame.
|
||||
*/
|
||||
class LayerTranslationPayload : public ProfilerMarkerPayload
|
||||
// Contains the translation applied to a 2d layer so we can track the layer
|
||||
// position at each frame.
|
||||
class LayerTranslationMarkerPayload : public ProfilerMarkerPayload
|
||||
{
|
||||
public:
|
||||
LayerTranslationPayload(mozilla::layers::Layer* aLayer,
|
||||
LayerTranslationMarkerPayload(mozilla::layers::Layer* aLayer,
|
||||
mozilla::gfx::Point aPoint);
|
||||
|
||||
virtual void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
@ -184,32 +157,12 @@ private:
|
||||
|
||||
#include "Units.h" // For ScreenIntPoint
|
||||
|
||||
/**
|
||||
* Tracks when touch events are processed by gecko, not when
|
||||
* the touch actually occured in gonk/android.
|
||||
*/
|
||||
class TouchDataPayload : public ProfilerMarkerPayload
|
||||
// Tracks when a vsync occurs according to the HardwareComposer.
|
||||
class VsyncMarkerPayload : public ProfilerMarkerPayload
|
||||
{
|
||||
public:
|
||||
explicit TouchDataPayload(const mozilla::ScreenIntPoint& aPoint);
|
||||
virtual ~TouchDataPayload() {}
|
||||
|
||||
virtual void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) override;
|
||||
|
||||
private:
|
||||
mozilla::ScreenIntPoint mPoint;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tracks when a vsync occurs according to the HardwareComposer.
|
||||
*/
|
||||
class VsyncPayload : public ProfilerMarkerPayload
|
||||
{
|
||||
public:
|
||||
explicit VsyncPayload(mozilla::TimeStamp aVsyncTimestamp);
|
||||
virtual ~VsyncPayload() {}
|
||||
explicit VsyncMarkerPayload(mozilla::TimeStamp aVsyncTimestamp);
|
||||
virtual ~VsyncMarkerPayload() {}
|
||||
|
||||
virtual void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aProcessStartTime,
|
||||
@ -299,5 +252,4 @@ private:
|
||||
JS::UniqueChars mTimingData;
|
||||
};
|
||||
|
||||
|
||||
#endif // PROFILER_MARKERS_H
|
||||
#endif // ProfilerMarkerPayload_h
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/PProfilerParent.h"
|
||||
|
||||
class nsIProfilerStartParams;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ProfilerParentTracker;
|
||||
|
@ -322,22 +322,22 @@ TEST(GeckoProfiler, Pause)
|
||||
|
||||
// A class that keeps track of how many instances have been created, streamed,
|
||||
// and destroyed.
|
||||
class GTestPayload : public ProfilerMarkerPayload
|
||||
class GTestMarkerPayload : public ProfilerMarkerPayload
|
||||
{
|
||||
public:
|
||||
explicit GTestPayload(int aN)
|
||||
explicit GTestMarkerPayload(int aN)
|
||||
: mN(aN)
|
||||
{
|
||||
sNumCreated++;
|
||||
}
|
||||
|
||||
virtual ~GTestPayload() { sNumDestroyed++; }
|
||||
virtual ~GTestMarkerPayload() { sNumDestroyed++; }
|
||||
|
||||
virtual void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aStartTime,
|
||||
UniqueStacks& aUniqueStacks) override
|
||||
{
|
||||
streamCommonProps("gtest", aWriter, aStartTime, aUniqueStacks);
|
||||
StreamCommonProps("gtest", aWriter, aStartTime, aUniqueStacks);
|
||||
char buf[64];
|
||||
SprintfLiteral(buf, "gtest-%d", mN);
|
||||
aWriter.IntProperty(buf, mN);
|
||||
@ -348,16 +348,16 @@ private:
|
||||
int mN;
|
||||
|
||||
public:
|
||||
// The number of GTestPayload instances that have been created, streamed, and
|
||||
// destroyed.
|
||||
// The number of GTestMarkerPayload instances that have been created,
|
||||
// streamed, and destroyed.
|
||||
static int sNumCreated;
|
||||
static int sNumStreamed;
|
||||
static int sNumDestroyed;
|
||||
};
|
||||
|
||||
int GTestPayload::sNumCreated = 0;
|
||||
int GTestPayload::sNumStreamed = 0;
|
||||
int GTestPayload::sNumDestroyed = 0;
|
||||
int GTestMarkerPayload::sNumCreated = 0;
|
||||
int GTestMarkerPayload::sNumStreamed = 0;
|
||||
int GTestMarkerPayload::sNumDestroyed = 0;
|
||||
|
||||
TEST(GeckoProfiler, Markers)
|
||||
{
|
||||
@ -382,15 +382,15 @@ TEST(GeckoProfiler, Markers)
|
||||
|
||||
profiler_add_marker("M1");
|
||||
profiler_add_marker("M2",
|
||||
MakeUnique<ProfilerMarkerTracing>("C", TRACING_EVENT));
|
||||
MakeUnique<TracingMarkerPayload>("C", TRACING_EVENT));
|
||||
PROFILER_MARKER("M3");
|
||||
PROFILER_MARKER_PAYLOAD(
|
||||
"M4",
|
||||
MakeUnique<ProfilerMarkerTracing>("C", TRACING_EVENT,
|
||||
profiler_get_backtrace()));
|
||||
MakeUnique<TracingMarkerPayload>("C", TRACING_EVENT,
|
||||
profiler_get_backtrace()));
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
PROFILER_MARKER_PAYLOAD("M5", MakeUnique<GTestPayload>(i));
|
||||
PROFILER_MARKER_PAYLOAD("M5", MakeUnique<GTestMarkerPayload>(i));
|
||||
}
|
||||
|
||||
// Sleep briefly to ensure a sample is taken and the pending markers are
|
||||
@ -402,11 +402,11 @@ TEST(GeckoProfiler, Markers)
|
||||
|
||||
UniquePtr<char[]> profile = w.WriteFunc()->CopyData();
|
||||
|
||||
// The GTestPayloads should have been created and streamed, but not yet
|
||||
// The GTestMarkerPayloads should have been created and streamed, but not yet
|
||||
// destroyed.
|
||||
ASSERT_TRUE(GTestPayload::sNumCreated == 10);
|
||||
ASSERT_TRUE(GTestPayload::sNumStreamed == 10);
|
||||
ASSERT_TRUE(GTestPayload::sNumDestroyed == 0);
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumCreated == 10);
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumStreamed == 10);
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumDestroyed == 0);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
char buf[64];
|
||||
SprintfLiteral(buf, "\"gtest-%d\"", i);
|
||||
@ -415,11 +415,11 @@ TEST(GeckoProfiler, Markers)
|
||||
|
||||
profiler_stop();
|
||||
|
||||
// The GTestPayloads should have been destroyed.
|
||||
ASSERT_TRUE(GTestPayload::sNumDestroyed == 10);
|
||||
// The GTestMarkerPayloads should have been destroyed.
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumDestroyed == 10);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
PROFILER_MARKER_PAYLOAD("M5", MakeUnique<GTestPayload>(i));
|
||||
PROFILER_MARKER_PAYLOAD("M5", MakeUnique<GTestMarkerPayload>(i));
|
||||
}
|
||||
|
||||
profiler_start(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
|
||||
@ -429,10 +429,10 @@ TEST(GeckoProfiler, Markers)
|
||||
|
||||
profiler_stop();
|
||||
|
||||
// The second set of GTestPayloads should not have been streamed.
|
||||
ASSERT_TRUE(GTestPayload::sNumCreated == 20);
|
||||
ASSERT_TRUE(GTestPayload::sNumStreamed == 10);
|
||||
ASSERT_TRUE(GTestPayload::sNumDestroyed == 20);
|
||||
// The second set of GTestMarkerPayloads should not have been streamed.
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumCreated == 20);
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumStreamed == 10);
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumDestroyed == 20);
|
||||
}
|
||||
|
||||
TEST(GeckoProfiler, Time)
|
||||
|
@ -93,6 +93,18 @@ public:
|
||||
// @return True if the array is empty or false otherwise.
|
||||
bool IsEmpty() const { return mArray.IsEmpty(); }
|
||||
|
||||
// This method provides direct, readonly access to the array elements.
|
||||
// @return A pointer to the first element of the array. If the array is
|
||||
// empty, then this pointer must not be dereferenced.
|
||||
const elem_type* Elements() const
|
||||
{
|
||||
return mArray.Elements();
|
||||
}
|
||||
elem_type* Elements()
|
||||
{
|
||||
return mArray.Elements();
|
||||
}
|
||||
|
||||
// This method provides direct access to an element of the array. The given
|
||||
// index must be within the array bounds. If the underlying array may change
|
||||
// during iteration, use an iterator instead of this function.
|
||||
@ -251,7 +263,8 @@ public:
|
||||
}
|
||||
|
||||
// See nsTArray::RemoveElementsBy.
|
||||
void RemoveElementsBy(const std::function<bool(const elem_type&)>& aPredicate)
|
||||
template <typename Predicate>
|
||||
void RemoveElementsBy(Predicate aPredicate)
|
||||
{
|
||||
index_type i = 0;
|
||||
mArray.RemoveElementsBy([&](const elem_type& aItem) {
|
||||
@ -361,7 +374,7 @@ public:
|
||||
elem_type& GetNext()
|
||||
{
|
||||
NS_ASSERTION(HasMore(), "iterating beyond end of array");
|
||||
return base_type::mArray.ElementAt(base_type::mPosition++);
|
||||
return base_type::mArray.Elements()[base_type::mPosition++];
|
||||
}
|
||||
};
|
||||
|
||||
@ -390,7 +403,7 @@ public:
|
||||
elem_type& GetNext()
|
||||
{
|
||||
NS_ASSERTION(HasMore(), "iterating beyond end of array");
|
||||
return base_type::mArray.ElementAt(base_type::mPosition++);
|
||||
return base_type::mArray.Elements()[base_type::mPosition++];
|
||||
}
|
||||
|
||||
private:
|
||||
@ -426,7 +439,7 @@ public:
|
||||
elem_type& GetNext()
|
||||
{
|
||||
NS_ASSERTION(HasMore(), "iterating beyond start of array");
|
||||
return base_type::mArray.ElementAt(--base_type::mPosition);
|
||||
return base_type::mArray.Elements()[--base_type::mPosition];
|
||||
}
|
||||
|
||||
// Removes the element at the current iterator position.
|
||||
|
Loading…
Reference in New Issue
Block a user