зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to mozilla-central. a=merge
This commit is contained in:
Коммит
846f00f83f
|
@ -115,3 +115,6 @@ jobs:
|
||||||
mozilla-central:
|
mozilla-central:
|
||||||
- {weekday: 'Monday', hour: 10, minute: 0}
|
- {weekday: 'Monday', hour: 10, minute: 0}
|
||||||
- {weekday: 'Thursday', hour: 10, minute: 0}
|
- {weekday: 'Thursday', hour: 10, minute: 0}
|
||||||
|
mozilla-esr60:
|
||||||
|
- {weekday: 'Monday', hour: 10, minute: 0}
|
||||||
|
- {weekday: 'Thursday', hour: 10, minute: 0}
|
||||||
|
|
|
@ -42,7 +42,7 @@ cpp_quote("//")
|
||||||
cpp_quote("// computedStyle( ")
|
cpp_quote("// computedStyle( ")
|
||||||
cpp_quote("// /* [in] */ unsigned short maxStyleProperties,")
|
cpp_quote("// /* [in] */ unsigned short maxStyleProperties,")
|
||||||
cpp_quote("// /* [out] */ unsigned short *numStyleProperties, ")
|
cpp_quote("// /* [out] */ unsigned short *numStyleProperties, ")
|
||||||
cpp_quote("// /* [in] */ boolean useAlternateView, // If TRUE, returns properites for media as set in nsIDOMDocument::set_alternateViewMediaTypes")
|
cpp_quote("// /* [in] */ boolean useAlternateView, // If TRUE, returns properites for media as set in Document's set_alternateViewMediaTypes")
|
||||||
cpp_quote("// /* [out] */ BSTR *styleProperties, ")
|
cpp_quote("// /* [out] */ BSTR *styleProperties, ")
|
||||||
cpp_quote("// /* [out] */ BSTR *styleValues);")
|
cpp_quote("// /* [out] */ BSTR *styleValues);")
|
||||||
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
|
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
|
||||||
|
@ -52,7 +52,7 @@ cpp_quote("// useAlternateView=TRUE: properties for media types set w/ nsIDOMSi
|
||||||
cpp_quote("//")
|
cpp_quote("//")
|
||||||
cpp_quote("// computedStyleForProperties( ")
|
cpp_quote("// computedStyleForProperties( ")
|
||||||
cpp_quote("// /* [in] */ unsigned short numStyleProperties, ")
|
cpp_quote("// /* [in] */ unsigned short numStyleProperties, ")
|
||||||
cpp_quote("// /* [in] */ boolean useAlternateView, // If TRUE, returns properites for media as set in nsIDOMDocument::set_alternateViewMediaTypes")
|
cpp_quote("// /* [in] */ boolean useAlternateView, // If TRUE, returns properites for media as set in Document's set_alternateViewMediaTypes")
|
||||||
cpp_quote("// /* [in] */ BSTR *styleProperties, ")
|
cpp_quote("// /* [in] */ BSTR *styleProperties, ")
|
||||||
cpp_quote("// /* [out] */ BSTR *styleValues);")
|
cpp_quote("// /* [out] */ BSTR *styleValues);")
|
||||||
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
|
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
|
||||||
|
@ -141,7 +141,7 @@ interface ISimpleDOMNode : IUnknown
|
||||||
|
|
||||||
[propget] HRESULT computedStyle(
|
[propget] HRESULT computedStyle(
|
||||||
[in] unsigned short maxStyleProperties,
|
[in] unsigned short maxStyleProperties,
|
||||||
[in] boolean useAlternateView, // If TRUE, returns properites for media as set in nsIDOMDocument::set_alternateViewMediaTypes
|
[in] boolean useAlternateView, // If TRUE, returns properites for media as set in Document's set_alternateViewMediaTypes
|
||||||
[out, size_is(maxStyleProperties), length_is(*numStyleProperties)] BSTR *styleProperties,
|
[out, size_is(maxStyleProperties), length_is(*numStyleProperties)] BSTR *styleProperties,
|
||||||
[out, size_is(maxStyleProperties), length_is(*numStyleProperties)] BSTR *styleValues,
|
[out, size_is(maxStyleProperties), length_is(*numStyleProperties)] BSTR *styleValues,
|
||||||
[out, retval] unsigned short *numStyleProperties
|
[out, retval] unsigned short *numStyleProperties
|
||||||
|
@ -149,7 +149,7 @@ interface ISimpleDOMNode : IUnknown
|
||||||
|
|
||||||
[propget] HRESULT computedStyleForProperties(
|
[propget] HRESULT computedStyleForProperties(
|
||||||
[in] unsigned short numStyleProperties,
|
[in] unsigned short numStyleProperties,
|
||||||
[in] boolean useAlternateView, // If TRUE, returns properites for media as set in nsIDOMDocument::set_alternateViewMediaTypes
|
[in] boolean useAlternateView, // If TRUE, returns properites for media as set in Document's set_alternateViewMediaTypes
|
||||||
[in, size_is(numStyleProperties), length_is(numStyleProperties)] BSTR *styleProperties,
|
[in, size_is(numStyleProperties), length_is(numStyleProperties)] BSTR *styleProperties,
|
||||||
[out, retval, size_is(numStyleProperties), length_is(numStyleProperties)] BSTR *styleValues
|
[out, retval, size_is(numStyleProperties), length_is(numStyleProperties)] BSTR *styleValues
|
||||||
);
|
);
|
||||||
|
|
|
@ -44,7 +44,6 @@ const nsIAccessibleValue = Ci.nsIAccessibleValue;
|
||||||
|
|
||||||
const nsIObserverService = Ci.nsIObserverService;
|
const nsIObserverService = Ci.nsIObserverService;
|
||||||
|
|
||||||
const nsIDOMDocument = Ci.nsIDOMDocument;
|
|
||||||
const nsIDOMNode = Ci.nsIDOMNode;
|
const nsIDOMNode = Ci.nsIDOMNode;
|
||||||
const nsIDOMWindow = Ci.nsIDOMWindow;
|
const nsIDOMWindow = Ci.nsIDOMWindow;
|
||||||
|
|
||||||
|
|
|
@ -1062,7 +1062,7 @@ function synthClick(aNodeOrID, aCheckerOrEventSeq, aArgs) {
|
||||||
|
|
||||||
this.invoke = function synthClick_invoke() {
|
this.invoke = function synthClick_invoke() {
|
||||||
var targetNode = this.DOMNode;
|
var targetNode = this.DOMNode;
|
||||||
if (targetNode instanceof nsIDOMDocument) {
|
if (targetNode.nodeType == targetNode.DOCUMENT_NODE) {
|
||||||
targetNode =
|
targetNode =
|
||||||
this.DOMNode.body ? this.DOMNode.body : this.DOMNode.documentElement;
|
this.DOMNode.body ? this.DOMNode.body : this.DOMNode.documentElement;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,12 +56,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=441737
|
||||||
// is(docAcc.docType, "HTML",
|
// is(docAcc.docType, "HTML",
|
||||||
// "Wrong type of document!");
|
// "Wrong type of document!");
|
||||||
|
|
||||||
// Test for correct nsIDOMDocument retrieval.
|
// Test for correct Document retrieval.
|
||||||
var domDoc = null;
|
var domDoc = null;
|
||||||
try {
|
try {
|
||||||
domDoc = docAcc.DOMDocument.QueryInterface(nsIDOMDocument);
|
domDoc = docAcc.DOMDocument;
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
ok(domDoc, "no nsIDOMDocument for this doc accessible!");
|
ok(domDoc, "no Document for this doc accessible!");
|
||||||
is(domDoc, document, "Document nodes do not match!");
|
is(domDoc, document, "Document nodes do not match!");
|
||||||
|
|
||||||
// Test for correct nsIDOMWindow retrieval.
|
// Test for correct nsIDOMWindow retrieval.
|
||||||
|
|
|
@ -588,12 +588,8 @@ var AboutNetAndCertErrorListener = {
|
||||||
},
|
},
|
||||||
|
|
||||||
handleEvent(aEvent) {
|
handleEvent(aEvent) {
|
||||||
let doc;
|
// Documents have a null ownerDocument.
|
||||||
if (aEvent.originalTarget instanceof Ci.nsIDOMDocument) {
|
let doc = aEvent.originalTarget.ownerDocument || aEvent.originalTarget;
|
||||||
doc = aEvent.originalTarget;
|
|
||||||
} else {
|
|
||||||
doc = aEvent.originalTarget.ownerDocument;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.isAboutNetError(doc) && !this.isAboutCertError(doc)) {
|
if (!this.isAboutNetError(doc) && !this.isAboutCertError(doc)) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -74,7 +74,7 @@ function focusInChild() {
|
||||||
var id;
|
var id;
|
||||||
if (event.target instanceof Ci.nsIDOMWindow)
|
if (event.target instanceof Ci.nsIDOMWindow)
|
||||||
id = getWindowDocId(event.originalTarget) + "-window";
|
id = getWindowDocId(event.originalTarget) + "-window";
|
||||||
else if (event.target instanceof Ci.nsIDOMDocument)
|
else if (event.target.nodeType == event.target.DOCUMENT_NODE)
|
||||||
id = getWindowDocId(event.originalTarget) + "-document";
|
id = getWindowDocId(event.originalTarget) + "-document";
|
||||||
else
|
else
|
||||||
id = event.originalTarget.id;
|
id = event.originalTarget.id;
|
||||||
|
|
|
@ -966,8 +966,8 @@ this.tabs = class extends ExtensionAPI {
|
||||||
let browser = event.originalTarget;
|
let browser = event.originalTarget;
|
||||||
|
|
||||||
// For non-remote browsers, this event is dispatched on the document
|
// For non-remote browsers, this event is dispatched on the document
|
||||||
// rather than on the <browser>.
|
// rather than on the <browser>. But either way we have a node here.
|
||||||
if (browser instanceof Ci.nsIDOMDocument) {
|
if (browser.nodeType == browser.DOCUMENT_NODE) {
|
||||||
browser = browser.docShell.chromeEventHandler;
|
browser = browser.docShell.chromeEventHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
This is the PDF.js project output, https://github.com/mozilla/pdf.js
|
This is the PDF.js project output, https://github.com/mozilla/pdf.js
|
||||||
|
|
||||||
Current extension version is: 2.0.506
|
Current extension version is: 2.0.517
|
||||||
|
|
||||||
Taken from upstream commit: b7a3a5e7
|
Taken from upstream commit: 7cd6c0fb
|
||||||
|
|
|
@ -1650,8 +1650,8 @@ exports.GlobalWorkerOptions = GlobalWorkerOptions;
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
var pdfjsVersion = '2.0.506';
|
var pdfjsVersion = '2.0.517';
|
||||||
var pdfjsBuild = 'b7a3a5e7';
|
var pdfjsBuild = '7cd6c0fb';
|
||||||
var pdfjsSharedUtil = __w_pdfjs_require__(0);
|
var pdfjsSharedUtil = __w_pdfjs_require__(0);
|
||||||
var pdfjsDisplayAPI = __w_pdfjs_require__(9);
|
var pdfjsDisplayAPI = __w_pdfjs_require__(9);
|
||||||
var pdfjsDisplayTextLayer = __w_pdfjs_require__(17);
|
var pdfjsDisplayTextLayer = __w_pdfjs_require__(17);
|
||||||
|
@ -4929,7 +4929,7 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
|
||||||
}
|
}
|
||||||
return worker.messageHandler.sendWithPromise('GetDocRequest', {
|
return worker.messageHandler.sendWithPromise('GetDocRequest', {
|
||||||
docId,
|
docId,
|
||||||
apiVersion: '2.0.506',
|
apiVersion: '2.0.517',
|
||||||
source: {
|
source: {
|
||||||
data: source.data,
|
data: source.data,
|
||||||
url: source.url,
|
url: source.url,
|
||||||
|
@ -6252,8 +6252,8 @@ var InternalRenderTask = function InternalRenderTaskClosure() {
|
||||||
}();
|
}();
|
||||||
var version, build;
|
var version, build;
|
||||||
{
|
{
|
||||||
exports.version = version = '2.0.506';
|
exports.version = version = '2.0.517';
|
||||||
exports.build = build = 'b7a3a5e7';
|
exports.build = build = '7cd6c0fb';
|
||||||
}
|
}
|
||||||
exports.getDocument = getDocument;
|
exports.getDocument = getDocument;
|
||||||
exports.LoopbackPort = LoopbackPort;
|
exports.LoopbackPort = LoopbackPort;
|
||||||
|
|
|
@ -21103,8 +21103,8 @@ exports.PostScriptCompiler = PostScriptCompiler;
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
var pdfjsVersion = '2.0.506';
|
var pdfjsVersion = '2.0.517';
|
||||||
var pdfjsBuild = 'b7a3a5e7';
|
var pdfjsBuild = '7cd6c0fb';
|
||||||
var pdfjsCoreWorker = __w_pdfjs_require__(20);
|
var pdfjsCoreWorker = __w_pdfjs_require__(20);
|
||||||
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
|
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
|
||||||
|
|
||||||
|
@ -21305,7 +21305,7 @@ var WorkerMessageHandler = {
|
||||||
var cancelXHRs = null;
|
var cancelXHRs = null;
|
||||||
var WorkerTasks = [];
|
var WorkerTasks = [];
|
||||||
let apiVersion = docParams.apiVersion;
|
let apiVersion = docParams.apiVersion;
|
||||||
let workerVersion = '2.0.506';
|
let workerVersion = '2.0.517';
|
||||||
if (apiVersion !== null && apiVersion !== workerVersion) {
|
if (apiVersion !== null && apiVersion !== workerVersion) {
|
||||||
throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
|
throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
|
||||||
}
|
}
|
||||||
|
@ -36238,10 +36238,9 @@ var Type1Parser = function Type1ParserClosure() {
|
||||||
var glyph = this.getToken();
|
var glyph = this.getToken();
|
||||||
length = this.readInt();
|
length = this.readInt();
|
||||||
this.getToken();
|
this.getToken();
|
||||||
data = stream.makeSubStream(stream.pos, length);
|
data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);
|
||||||
lenIV = program.properties.privateData['lenIV'];
|
lenIV = program.properties.privateData['lenIV'];
|
||||||
encoded = this.readCharStrings(data.getBytes(), lenIV);
|
encoded = this.readCharStrings(data, lenIV);
|
||||||
stream.skip(length);
|
|
||||||
this.nextChar();
|
this.nextChar();
|
||||||
token = this.getToken();
|
token = this.getToken();
|
||||||
if (token === 'noaccess') {
|
if (token === 'noaccess') {
|
||||||
|
@ -36260,10 +36259,9 @@ var Type1Parser = function Type1ParserClosure() {
|
||||||
var index = this.readInt();
|
var index = this.readInt();
|
||||||
length = this.readInt();
|
length = this.readInt();
|
||||||
this.getToken();
|
this.getToken();
|
||||||
data = stream.makeSubStream(stream.pos, length);
|
data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);
|
||||||
lenIV = program.properties.privateData['lenIV'];
|
lenIV = program.properties.privateData['lenIV'];
|
||||||
encoded = this.readCharStrings(data.getBytes(), lenIV);
|
encoded = this.readCharStrings(data, lenIV);
|
||||||
stream.skip(length);
|
|
||||||
this.nextChar();
|
this.nextChar();
|
||||||
token = this.getToken();
|
token = this.getToken();
|
||||||
if (token === 'noaccess') {
|
if (token === 'noaccess') {
|
||||||
|
|
|
@ -95,7 +95,7 @@
|
||||||
Object.defineProperty(exports, "__esModule", {
|
Object.defineProperty(exports, "__esModule", {
|
||||||
value: true
|
value: true
|
||||||
});
|
});
|
||||||
exports.moveToEndOfArray = exports.waitOnEventOrTimeout = exports.WaitOnType = exports.animationStarted = exports.normalizeWheelEventDelta = exports.binarySearchFirstItem = exports.watchScroll = exports.scrollIntoView = exports.getOutputScale = exports.approximateFraction = exports.getPageSizeInches = exports.roundToDivide = exports.getVisibleElements = exports.backtrackBeforeAllVisibleElements = exports.parseQueryString = exports.noContextMenuHandler = exports.getPDFFileNameFromURL = exports.ProgressBar = exports.EventBus = exports.NullL10n = exports.TextLayerMode = exports.RendererType = exports.PresentationModeState = exports.cloneObj = exports.isFileSchema = exports.isPortraitOrientation = exports.isValidRotation = exports.VERTICAL_PADDING = exports.SCROLLBAR_PADDING = exports.MAX_AUTO_SCALE = exports.UNKNOWN_SCALE = exports.MAX_SCALE = exports.MIN_SCALE = exports.DEFAULT_SCALE = exports.DEFAULT_SCALE_VALUE = exports.CSS_UNITS = undefined;
|
exports.moveToEndOfArray = exports.waitOnEventOrTimeout = exports.WaitOnType = exports.animationStarted = exports.normalizeWheelEventDelta = exports.binarySearchFirstItem = exports.watchScroll = exports.scrollIntoView = exports.getOutputScale = exports.approximateFraction = exports.getPageSizeInches = exports.roundToDivide = exports.getVisibleElements = exports.backtrackBeforeAllVisibleElements = exports.parseQueryString = exports.noContextMenuHandler = exports.getPDFFileNameFromURL = exports.ProgressBar = exports.EventBus = exports.NullL10n = exports.TextLayerMode = exports.RendererType = exports.PresentationModeState = exports.cloneObj = exports.isPortraitOrientation = exports.isValidRotation = exports.VERTICAL_PADDING = exports.SCROLLBAR_PADDING = exports.MAX_AUTO_SCALE = exports.UNKNOWN_SCALE = exports.MAX_SCALE = exports.MIN_SCALE = exports.DEFAULT_SCALE = exports.DEFAULT_SCALE_VALUE = exports.CSS_UNITS = undefined;
|
||||||
|
|
||||||
var _pdfjsLib = __webpack_require__(1);
|
var _pdfjsLib = __webpack_require__(1);
|
||||||
|
|
||||||
|
@ -397,14 +397,6 @@ function getVisibleElements(scrollEl, views, sortByVisibility = false, horizonta
|
||||||
function noContextMenuHandler(evt) {
|
function noContextMenuHandler(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
}
|
}
|
||||||
function isFileSchema(url) {
|
|
||||||
let i = 0,
|
|
||||||
ii = url.length;
|
|
||||||
while (i < ii && url[i].trim() === '') {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return url.substr(i, 7).toLowerCase() === 'file://';
|
|
||||||
}
|
|
||||||
function isDataSchema(url) {
|
function isDataSchema(url) {
|
||||||
let i = 0,
|
let i = 0,
|
||||||
ii = url.length;
|
ii = url.length;
|
||||||
|
@ -614,7 +606,6 @@ exports.SCROLLBAR_PADDING = SCROLLBAR_PADDING;
|
||||||
exports.VERTICAL_PADDING = VERTICAL_PADDING;
|
exports.VERTICAL_PADDING = VERTICAL_PADDING;
|
||||||
exports.isValidRotation = isValidRotation;
|
exports.isValidRotation = isValidRotation;
|
||||||
exports.isPortraitOrientation = isPortraitOrientation;
|
exports.isPortraitOrientation = isPortraitOrientation;
|
||||||
exports.isFileSchema = isFileSchema;
|
|
||||||
exports.cloneObj = cloneObj;
|
exports.cloneObj = cloneObj;
|
||||||
exports.PresentationModeState = PresentationModeState;
|
exports.PresentationModeState = PresentationModeState;
|
||||||
exports.RendererType = RendererType;
|
exports.RendererType = RendererType;
|
||||||
|
@ -1438,11 +1429,6 @@ let PDFViewerApplication = {
|
||||||
parameters[prop] = args[prop];
|
parameters[prop] = args[prop];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.url && (0, _ui_utils.isFileSchema)(this.url)) {
|
|
||||||
let appConfig = this.appConfig;
|
|
||||||
appConfig.toolbar.download.setAttribute('hidden', 'true');
|
|
||||||
appConfig.secondaryToolbar.downloadButton.setAttribute('hidden', 'true');
|
|
||||||
}
|
|
||||||
let loadingTask = (0, _pdfjsLib.getDocument)(parameters);
|
let loadingTask = (0, _pdfjsLib.getDocument)(parameters);
|
||||||
this.pdfLoadingTask = loadingTask;
|
this.pdfLoadingTask = loadingTask;
|
||||||
loadingTask.onPassword = (updateCallback, reason) => {
|
loadingTask.onPassword = (updateCallback, reason) => {
|
||||||
|
|
|
@ -17,6 +17,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||||
setTimeout: "resource://gre/modules/Timer.jsm",
|
setTimeout: "resource://gre/modules/Timer.jsm",
|
||||||
ServiceWorkerCleanUp: "resource://gre/modules/ServiceWorkerCleanUp.jsm",
|
ServiceWorkerCleanUp: "resource://gre/modules/ServiceWorkerCleanUp.jsm",
|
||||||
OfflineAppCacheHelper: "resource://gre/modules/offlineAppCache.jsm",
|
OfflineAppCacheHelper: "resource://gre/modules/offlineAppCache.jsm",
|
||||||
|
ContextualIdentityService: "resource://gre/modules/ContextualIdentityService.jsm",
|
||||||
});
|
});
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "sas",
|
XPCOMUtils.defineLazyServiceGetter(this, "sas",
|
||||||
|
@ -71,6 +72,12 @@ var Sanitizer = {
|
||||||
*/
|
*/
|
||||||
PREF_TIMESPAN: "privacy.sanitize.timeSpan",
|
PREF_TIMESPAN: "privacy.sanitize.timeSpan",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pref to newTab segregation. If true, on shutdown, the private container
|
||||||
|
* used in about:newtab is cleaned up. Exposed because used in tests.
|
||||||
|
*/
|
||||||
|
PREF_NEWTAB_SEGREGATION: "privacy.usercontext.about_newtab_segregation.enabled",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time span constants corresponding to values of the privacy.sanitize.timeSpan
|
* Time span constants corresponding to values of the privacy.sanitize.timeSpan
|
||||||
* pref. Used to determine how much history to clear, for various items
|
* pref. Used to determine how much history to clear, for various items
|
||||||
|
@ -91,6 +98,11 @@ var Sanitizer = {
|
||||||
*/
|
*/
|
||||||
shouldSanitizeOnShutdown: false,
|
shouldSanitizeOnShutdown: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether we should sanitize the private container for about:newtab.
|
||||||
|
*/
|
||||||
|
shouldSanitizeNewTabContainer: false,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a sanitization dialog to the user.
|
* Shows a sanitization dialog to the user.
|
||||||
*
|
*
|
||||||
|
@ -145,6 +157,17 @@ var Sanitizer = {
|
||||||
{fetchState: () => ({ progress })}
|
{fetchState: () => ({ progress })}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.shouldSanitizeNewTabContainer = Services.prefs.getBoolPref(this.PREF_NEWTAB_SEGREGATION, false);
|
||||||
|
if (this.shouldSanitizeNewTabContainer) {
|
||||||
|
addPendingSanitization("newtab-container", [], {});
|
||||||
|
}
|
||||||
|
|
||||||
|
let i = pendingSanitizations.findIndex(s => s.id == "newtab-container");
|
||||||
|
if (i != -1) {
|
||||||
|
pendingSanitizations.splice(i, 1);
|
||||||
|
sanitizeNewTabSegregation();
|
||||||
|
}
|
||||||
|
|
||||||
// Finally, run the sanitizations that were left pending, because we crashed
|
// Finally, run the sanitizations that were left pending, because we crashed
|
||||||
// before completing them.
|
// before completing them.
|
||||||
for (let {itemsToClear, options} of pendingSanitizations) {
|
for (let {itemsToClear, options} of pendingSanitizations) {
|
||||||
|
@ -272,6 +295,12 @@ var Sanitizer = {
|
||||||
let itemsToClear = getItemsToClearFromPrefBranch(Sanitizer.PREF_SHUTDOWN_BRANCH);
|
let itemsToClear = getItemsToClearFromPrefBranch(Sanitizer.PREF_SHUTDOWN_BRANCH);
|
||||||
addPendingSanitization("shutdown", itemsToClear, {});
|
addPendingSanitization("shutdown", itemsToClear, {});
|
||||||
}
|
}
|
||||||
|
} else if (data == this.PREF_NEWTAB_SEGREGATION) {
|
||||||
|
this.shouldSanitizeNewTabContainer = Services.prefs.getBoolPref(this.PREF_NEWTAB_SEGREGATION, false);
|
||||||
|
removePendingSanitization("newtab-container");
|
||||||
|
if (this.shouldSanitizeNewTabContainer) {
|
||||||
|
addPendingSanitization("newtab-container", [], {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -990,6 +1019,11 @@ async function sanitizeOnShutdown(progress) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Sanitizer.shouldSanitizeNewTabContainer) {
|
||||||
|
sanitizeNewTabSegregation();
|
||||||
|
removePendingSanitization("newtab-container");
|
||||||
|
}
|
||||||
|
|
||||||
if (Sanitizer.shouldSanitizeOnShutdown) {
|
if (Sanitizer.shouldSanitizeOnShutdown) {
|
||||||
// We didn't crash during shutdown sanitization, so annotate it to avoid
|
// We didn't crash during shutdown sanitization, so annotate it to avoid
|
||||||
// sanitizing again on startup.
|
// sanitizing again on startup.
|
||||||
|
@ -1061,6 +1095,14 @@ async function sanitizeSessionPrincipal(principal) {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sanitizeNewTabSegregation() {
|
||||||
|
let identity = ContextualIdentityService.getPrivateIdentity("userContextIdInternal.thumbnail");
|
||||||
|
if (identity) {
|
||||||
|
Services.obs.notifyObservers(null, "clear-origin-attributes-data",
|
||||||
|
JSON.stringify({ userContextId: identity.userContextId }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets an array of items to clear from the given pref branch.
|
* Gets an array of items to clear from the given pref branch.
|
||||||
* @param branch The pref branch to fetch.
|
* @param branch The pref branch to fetch.
|
||||||
|
|
|
@ -11,9 +11,13 @@ do_get_profile();
|
||||||
|
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
ChromeUtils.import("resource:///modules/Sanitizer.jsm");
|
ChromeUtils.import("resource:///modules/Sanitizer.jsm");
|
||||||
|
|
||||||
|
Services.prefs.setBoolPref(Sanitizer.PREF_NEWTAB_SEGREGATION, false);
|
||||||
|
|
||||||
registerCleanupFunction(() => {
|
registerCleanupFunction(() => {
|
||||||
Services.prefs.clearUserPref(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN);
|
Services.prefs.clearUserPref(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN);
|
||||||
Services.prefs.clearUserPref(Sanitizer.PREF_SHUTDOWN_BRANCH + "formdata");
|
Services.prefs.clearUserPref(Sanitizer.PREF_SHUTDOWN_BRANCH + "formdata");
|
||||||
|
Services.prefs.clearUserPref(Sanitizer.PREF_NEWTAB_SEGREGATION);
|
||||||
});
|
});
|
||||||
Services.prefs.setBoolPref(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN, true);
|
Services.prefs.setBoolPref(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN, true);
|
||||||
Services.prefs.setBoolPref(Sanitizer.PREF_SHUTDOWN_BRANCH + "formdata", true);
|
Services.prefs.setBoolPref(Sanitizer.PREF_SHUTDOWN_BRANCH + "formdata", true);
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
This is the debugger.html project output.
|
This is the debugger.html project output.
|
||||||
See https://github.com/devtools-html/debugger.html
|
See https://github.com/devtools-html/debugger.html
|
||||||
|
|
||||||
Version 58
|
Version 60
|
||||||
|
|
||||||
Comparison: https://github.com/devtools-html/debugger.html/compare/release-57...release-58
|
Comparison: https://github.com/devtools-html/debugger.html/compare/release-59...release-60
|
||||||
|
|
||||||
Packages:
|
Packages:
|
||||||
- babel-plugin-transform-es2015-modules-commonjs @6.26.2
|
- babel-plugin-transform-es2015-modules-commonjs @6.26.2
|
||||||
- babel-preset-react @6.24.1
|
- babel-preset-react @6.24.1
|
||||||
- react @16.2.0
|
- react @16.2.0
|
||||||
- react-dom @16.2.0
|
- react-dom @16.2.0
|
||||||
- webpack @3.12.0
|
- webpack @3.11.0
|
||||||
|
|
|
@ -1108,7 +1108,10 @@ html .toggle-button.end.vertical svg {
|
||||||
|
|
||||||
.search-field i.magnifying-glass,
|
.search-field i.magnifying-glass,
|
||||||
.search-field i.sad-face {
|
.search-field i.sad-face {
|
||||||
padding: 6px;
|
padding-top: 5px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
padding-inline-end: 10px;
|
||||||
|
padding-inline-start: 5px;
|
||||||
width: 24px;
|
width: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1118,6 +1121,11 @@ html .toggle-button.end.vertical svg {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-field.big i.sad-face {
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-inline-start: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.search-field .magnifying-glass path,
|
.search-field .magnifying-glass path,
|
||||||
.search-field .magnifying-glass ellipse {
|
.search-field .magnifying-glass ellipse {
|
||||||
stroke: var(--theme-comment);
|
stroke: var(--theme-comment);
|
||||||
|
@ -1134,18 +1142,13 @@ html .toggle-button.end.vertical svg {
|
||||||
.search-field .summary {
|
.search-field .summary {
|
||||||
line-height: 27px;
|
line-height: 27px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding-right: 10px;
|
padding-inline-end: 10px;
|
||||||
color: var(--theme-body-color-inactive);
|
color: var(--theme-body-color-inactive);
|
||||||
align-self: center;
|
align-self: center;
|
||||||
padding-top: 1px;
|
padding-top: 1px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-field.big .summary {
|
|
||||||
padding: 5px 0 5px 0;
|
|
||||||
line-height: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-field .search-nav-buttons {
|
.search-field .search-nav-buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
@ -1261,7 +1264,7 @@ html .toggle-button.end.vertical svg {
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-text-search .search-field .close-btn.big {
|
.project-text-search .search-field .close-btn.big {
|
||||||
margin-top: 6px;
|
margin-top: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-text-search .managed-tree {
|
.project-text-search .managed-tree {
|
||||||
|
@ -3077,7 +3080,7 @@ html[dir="rtl"] .breakpoints-list .breakpoint .breakpoint-line {
|
||||||
max-width: calc(100% - var(--breakpoint-expression-right-clear-space));
|
max-width: calc(100% - var(--breakpoint-expression-right-clear-space));
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding-inline-end: 8px;
|
padding-inline-end: 8px;
|
||||||
cursor: default;
|
cursor: pointer;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -3261,7 +3264,7 @@ html[dir="rtl"] .breakpoints-list .breakpoint .breakpoint-line {
|
||||||
.expression-container__close-btn {
|
.expression-container__close-btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
offset-inline-end: 0px;
|
offset-inline-end: 0px;
|
||||||
top: 0px;
|
top: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.expression-content {
|
.expression-content {
|
||||||
|
@ -4049,6 +4052,7 @@ html .welcomebox .toggle-button-end.collapsed {
|
||||||
position: relative;
|
position: relative;
|
||||||
transition: all 0.15s ease;
|
transition: all 0.15s ease;
|
||||||
min-width: 40px;
|
min-width: 40px;
|
||||||
|
max-width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
margin-inline-start: 3px;
|
margin-inline-start: 3px;
|
||||||
|
|
|
@ -22811,7 +22811,7 @@ function toParsedScopes(children, sourceId) {
|
||||||
return {
|
return {
|
||||||
start: scope.loc.start,
|
start: scope.loc.start,
|
||||||
end: scope.loc.end,
|
end: scope.loc.end,
|
||||||
type: scope.type === "module" ? "block" : scope.type,
|
type: scope.type === "module" || scope.type === "function-body" ? "block" : scope.type,
|
||||||
displayName: scope.displayName,
|
displayName: scope.displayName,
|
||||||
bindings: scope.bindings,
|
bindings: scope.bindings,
|
||||||
children: toParsedScopes(scope.children, sourceId)
|
children: toParsedScopes(scope.children, sourceId)
|
||||||
|
@ -22906,9 +22906,18 @@ function isLetOrConst(node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasLexicalDeclaration(node, parent) {
|
function hasLexicalDeclaration(node, parent) {
|
||||||
|
const nodes = [];
|
||||||
|
if (t.isSwitchStatement(node)) {
|
||||||
|
for (const caseNode of node.cases) {
|
||||||
|
nodes.push(...caseNode.consequent);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nodes.push(...node.body);
|
||||||
|
}
|
||||||
|
|
||||||
const isFunctionBody = t.isFunction(parent, { body: node });
|
const isFunctionBody = t.isFunction(parent, { body: node });
|
||||||
|
|
||||||
return node.body.some(child => isLexicalVariable(child) || !isFunctionBody && child.type === "FunctionDeclaration" || child.type === "ClassDeclaration");
|
return nodes.some(child => isLexicalVariable(child) || t.isClassDeclaration(child) || !isFunctionBody && t.isFunctionDeclaration(child));
|
||||||
}
|
}
|
||||||
function isLexicalVariable(node) {
|
function isLexicalVariable(node) {
|
||||||
return isNode(node, "VariableDeclaration") && isLetOrConst(node);
|
return isNode(node, "VariableDeclaration") && isLetOrConst(node);
|
||||||
|
@ -22973,19 +22982,27 @@ const scopeCollectionVisitor = {
|
||||||
// This ignores Annex B function declaration hoisting, which
|
// This ignores Annex B function declaration hoisting, which
|
||||||
// is probably a fine assumption.
|
// is probably a fine assumption.
|
||||||
state.declarationBindingIds.add(node.id);
|
state.declarationBindingIds.add(node.id);
|
||||||
const fnScope = getVarScope(scope);
|
const refs = [{
|
||||||
scope.bindings[node.id.name] = {
|
type: "fn-decl",
|
||||||
type: fnScope === scope ? "var" : "let",
|
start: fromBabelLocation(node.id.loc.start, state.sourceId),
|
||||||
refs: [{
|
end: fromBabelLocation(node.id.loc.end, state.sourceId),
|
||||||
type: "fn-decl",
|
declaration: {
|
||||||
start: fromBabelLocation(node.id.loc.start, state.sourceId),
|
start: fromBabelLocation(node.loc.start, state.sourceId),
|
||||||
end: fromBabelLocation(node.id.loc.end, state.sourceId),
|
end: fromBabelLocation(node.loc.end, state.sourceId)
|
||||||
declaration: {
|
}
|
||||||
start: fromBabelLocation(node.loc.start, state.sourceId),
|
}];
|
||||||
end: fromBabelLocation(node.loc.end, state.sourceId)
|
|
||||||
}
|
if (scope.type === "block") {
|
||||||
}]
|
scope.bindings[node.id.name] = {
|
||||||
};
|
type: "let",
|
||||||
|
refs
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
getVarScope(scope).bindings[node.id.name] = {
|
||||||
|
type: "var",
|
||||||
|
refs
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scope = pushTempScope(state, "function", (0, _getFunctionName2.default)(node, parentNode), {
|
scope = pushTempScope(state, "function", (0, _getFunctionName2.default)(node, parentNode), {
|
||||||
|
@ -23007,6 +23024,13 @@ const scopeCollectionVisitor = {
|
||||||
refs: []
|
refs: []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t.isBlockStatement(node.body) && hasLexicalDeclaration(node.body, node)) {
|
||||||
|
scope = pushTempScope(state, "function-body", "Function Body", {
|
||||||
|
start: fromBabelLocation(node.body.loc.start, state.sourceId),
|
||||||
|
end: fromBabelLocation(node.body.loc.end, state.sourceId)
|
||||||
|
});
|
||||||
|
}
|
||||||
} else if (t.isClass(node)) {
|
} else if (t.isClass(node)) {
|
||||||
if (t.isIdentifier(node.id)) {
|
if (t.isIdentifier(node.id)) {
|
||||||
// For decorated classes, the AST considers the first the decorator
|
// For decorated classes, the AST considers the first the decorator
|
||||||
|
@ -23075,7 +23099,9 @@ const scopeCollectionVisitor = {
|
||||||
end: fromBabelLocation(node.loc.end, state.sourceId)
|
end: fromBabelLocation(node.loc.end, state.sourceId)
|
||||||
});
|
});
|
||||||
parseDeclarator(node.param, scope, "var", "catch", node, state);
|
parseDeclarator(node.param, scope, "var", "catch", node, state);
|
||||||
} else if (t.isBlockStatement(node) && hasLexicalDeclaration(node, parentNode)) {
|
} else if (t.isBlockStatement(node) &&
|
||||||
|
// Function body's are handled in the function logic above.
|
||||||
|
!t.isFunction(parentNode) && hasLexicalDeclaration(node, parentNode)) {
|
||||||
// Debugger will create new lexical environment for the block.
|
// Debugger will create new lexical environment for the block.
|
||||||
pushTempScope(state, "block", "Block", {
|
pushTempScope(state, "block", "Block", {
|
||||||
start: fromBabelLocation(node.loc.start, state.sourceId),
|
start: fromBabelLocation(node.loc.start, state.sourceId),
|
||||||
|
@ -23199,7 +23225,7 @@ const scopeCollectionVisitor = {
|
||||||
type: "implicit",
|
type: "implicit",
|
||||||
refs: []
|
refs: []
|
||||||
};
|
};
|
||||||
} else if (t.isSwitchStatement(node) && node.cases.some(caseNode => caseNode.consequent.some(child => isLexicalVariable(child)))) {
|
} else if (t.isSwitchStatement(node) && hasLexicalDeclaration(node, parentNode)) {
|
||||||
pushTempScope(state, "block", "Switch", {
|
pushTempScope(state, "block", "Switch", {
|
||||||
start: fromBabelLocation(node.loc.start, state.sourceId),
|
start: fromBabelLocation(node.loc.start, state.sourceId),
|
||||||
end: fromBabelLocation(node.loc.end, state.sourceId)
|
end: fromBabelLocation(node.loc.end, state.sourceId)
|
||||||
|
@ -25012,6 +25038,7 @@ const {
|
||||||
const dispatcher = new WorkerDispatcher();
|
const dispatcher = new WorkerDispatcher();
|
||||||
|
|
||||||
const getOriginalURLs = dispatcher.task("getOriginalURLs");
|
const getOriginalURLs = dispatcher.task("getOriginalURLs");
|
||||||
|
const getOriginalRanges = dispatcher.task("getOriginalRanges");
|
||||||
const getGeneratedRanges = dispatcher.task("getGeneratedRanges", {
|
const getGeneratedRanges = dispatcher.task("getGeneratedRanges", {
|
||||||
queue: true
|
queue: true
|
||||||
});
|
});
|
||||||
|
@ -25035,6 +25062,7 @@ module.exports = {
|
||||||
isOriginalId,
|
isOriginalId,
|
||||||
hasMappedSource,
|
hasMappedSource,
|
||||||
getOriginalURLs,
|
getOriginalURLs,
|
||||||
|
getOriginalRanges,
|
||||||
getGeneratedRanges,
|
getGeneratedRanges,
|
||||||
getGeneratedLocation,
|
getGeneratedLocation,
|
||||||
getAllGeneratedLocations,
|
getAllGeneratedLocations,
|
||||||
|
|
|
@ -417,7 +417,7 @@ function toggleBreakpoint(line, column) {
|
||||||
line,
|
line,
|
||||||
column
|
column
|
||||||
});
|
});
|
||||||
const isEmptyLine = (0, _ast.isEmptyLineInSource)(state, line, selectedSource);
|
const isEmptyLine = (0, _ast.isEmptyLineInSource)(state, line, selectedSource.id);
|
||||||
|
|
||||||
if (!bp && isEmptyLine || bp && bp.loading) {
|
if (!bp && isEmptyLine || bp && bp.loading) {
|
||||||
return;
|
return;
|
||||||
|
@ -434,8 +434,8 @@ function toggleBreakpoint(line, column) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return dispatch(addBreakpoint({
|
return dispatch(addBreakpoint({
|
||||||
sourceId: selectedSource.get("id"),
|
sourceId: selectedSource.id,
|
||||||
sourceUrl: selectedSource.get("url"),
|
sourceUrl: selectedSource.url,
|
||||||
line: line,
|
line: line,
|
||||||
column: column
|
column: column
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -51,7 +51,6 @@ function willNavigate(event) {
|
||||||
await sourceMaps.clearSourceMaps();
|
await sourceMaps.clearSourceMaps();
|
||||||
(0, _wasm.clearWasmStates)();
|
(0, _wasm.clearWasmStates)();
|
||||||
(0, _editor.clearDocuments)();
|
(0, _editor.clearDocuments)();
|
||||||
(0, _editor.removeEditor)();
|
|
||||||
(0, _parser.clearSymbols)();
|
(0, _parser.clearSymbols)();
|
||||||
(0, _parser.clearASTs)();
|
(0, _parser.clearASTs)();
|
||||||
(0, _parser.clearScopes)();
|
(0, _parser.clearScopes)();
|
||||||
|
|
|
@ -41,7 +41,7 @@ async function loadSource(source, {
|
||||||
const id = source.get("id");
|
const id = source.get("id");
|
||||||
|
|
||||||
if ((0, _devtoolsSourceMap.isOriginalId)(id)) {
|
if ((0, _devtoolsSourceMap.isOriginalId)(id)) {
|
||||||
return await sourceMaps.getOriginalSourceText(source.toJS());
|
return sourceMaps.getOriginalSourceText(source.toJS());
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await client.sourceContents(id);
|
const response = await client.sourceContents(id);
|
||||||
|
|
|
@ -211,9 +211,9 @@ const mapStateToProps = state => {
|
||||||
return {
|
return {
|
||||||
selectedLocation: (0, _selectors.getSelectedLocation)(state),
|
selectedLocation: (0, _selectors.getSelectedLocation)(state),
|
||||||
selectedSource,
|
selectedSource,
|
||||||
hasPrettyPrint: !!(0, _selectors.getPrettySource)(state, selectedSource.get("id")),
|
hasPrettyPrint: !!(0, _selectors.getPrettySource)(state, selectedSource.id),
|
||||||
contextMenu: (0, _selectors.getContextMenu)(state),
|
contextMenu: (0, _selectors.getContextMenu)(state),
|
||||||
getFunctionText: line => (0, _function.findFunctionText)(line, selectedSource.toJS(), symbols),
|
getFunctionText: line => (0, _function.findFunctionText)(line, selectedSource, symbols),
|
||||||
getFunctionLocation: line => (0, _ast.findClosestFunction)(symbols, {
|
getFunctionLocation: line => (0, _ast.findClosestFunction)(symbols, {
|
||||||
line,
|
line,
|
||||||
column: Infinity
|
column: Infinity
|
||||||
|
|
|
@ -70,7 +70,7 @@ class EmptyLines extends _react.Component {
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
const selectedSource = (0, _selectors.getSelectedSource)(state);
|
const selectedSource = (0, _selectors.getSelectedSource)(state);
|
||||||
const foundEmptyLines = (0, _selectors.getEmptyLines)(state, selectedSource.toJS());
|
const foundEmptyLines = (0, _selectors.getEmptyLines)(state, selectedSource.id);
|
||||||
return {
|
return {
|
||||||
selectedSource,
|
selectedSource,
|
||||||
emptyLines: selectedSource ? foundEmptyLines : []
|
emptyLines: selectedSource ? foundEmptyLines : []
|
||||||
|
|
|
@ -169,7 +169,7 @@ const mapStateToProps = state => {
|
||||||
breakpoints: (0, _selectors.getVisibleBreakpoints)(state),
|
breakpoints: (0, _selectors.getVisibleBreakpoints)(state),
|
||||||
isPaused: (0, _selectors.isPaused)(state),
|
isPaused: (0, _selectors.isPaused)(state),
|
||||||
contextMenu: (0, _selectors.getContextMenu)(state),
|
contextMenu: (0, _selectors.getContextMenu)(state),
|
||||||
emptyLines: (0, _selectors.getEmptyLines)(state, selectedSource.toJS())
|
emptyLines: (0, _selectors.getEmptyLines)(state, selectedSource.id)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ var _SourceIcon2 = _interopRequireDefault(_SourceIcon);
|
||||||
|
|
||||||
var _Button = require("../shared/Button/index");
|
var _Button = require("../shared/Button/index");
|
||||||
|
|
||||||
|
var _text = require("../../utils/text");
|
||||||
|
|
||||||
var _actions = require("../../actions/index");
|
var _actions = require("../../actions/index");
|
||||||
|
|
||||||
var _actions2 = _interopRequireDefault(_actions);
|
var _actions2 = _interopRequireDefault(_actions);
|
||||||
|
@ -175,7 +177,7 @@ class Tab extends _react.PureComponent {
|
||||||
shouldHide: icon => ["file", "javascript"].includes(icon)
|
shouldHide: icon => ["file", "javascript"].includes(icon)
|
||||||
}), _react2.default.createElement("div", {
|
}), _react2.default.createElement("div", {
|
||||||
className: "filename"
|
className: "filename"
|
||||||
}, (0, _devtoolsModules.getUnicodeUrlPath)(filename)), _react2.default.createElement(_Button.CloseButton, {
|
}, (0, _text.truncateMiddleText)((0, _devtoolsModules.getUnicodeUrlPath)(filename), 30)), _react2.default.createElement(_Button.CloseButton, {
|
||||||
handleClick: onClickClose,
|
handleClick: onClickClose,
|
||||||
tooltip: L10N.getStr("sourceTabs.closeTabButtonTooltip")
|
tooltip: L10N.getStr("sourceTabs.closeTabButtonTooltip")
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -1,198 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", {
|
|
||||||
value: true
|
|
||||||
});
|
|
||||||
|
|
||||||
var _react = require("devtools/client/shared/vendor/react");
|
|
||||||
|
|
||||||
var _react2 = _interopRequireDefault(_react);
|
|
||||||
|
|
||||||
var _reactDom = require("devtools/client/shared/vendor/react-dom");
|
|
||||||
|
|
||||||
var _reactDom2 = _interopRequireDefault(_reactDom);
|
|
||||||
|
|
||||||
var _classnames = require("devtools/client/debugger/new/dist/vendors").vendored["classnames"];
|
|
||||||
|
|
||||||
var _classnames2 = _interopRequireDefault(_classnames);
|
|
||||||
|
|
||||||
var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
|
|
||||||
|
|
||||||
var _Button = require("../shared/Button/index");
|
|
||||||
|
|
||||||
var _breakpoint = require("../../utils/breakpoint/index");
|
|
||||||
|
|
||||||
var _prefs = require("../../utils/prefs");
|
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
||||||
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
|
||||||
function getBreakpointLocation(source, line, column) {
|
|
||||||
const isWasm = source && source.isWasm;
|
|
||||||
const columnVal = _prefs.features.columnBreakpoints && column ? `:${column}` : "";
|
|
||||||
const bpLocation = isWasm ? `0x${line.toString(16).toUpperCase()}` : `${line}${columnVal}`;
|
|
||||||
return bpLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBreakpointText(selectedSource, breakpoint) {
|
|
||||||
const {
|
|
||||||
condition,
|
|
||||||
text,
|
|
||||||
originalText
|
|
||||||
} = breakpoint;
|
|
||||||
|
|
||||||
if (condition) {
|
|
||||||
return condition;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!selectedSource || (0, _devtoolsSourceMap.isGeneratedId)(selectedSource.id) || originalText.length == 0) {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
return originalText;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Breakpoint extends _react.Component {
|
|
||||||
componentDidMount() {
|
|
||||||
this.setupEditor();
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
|
||||||
if (getBreakpointText(this.props.selectedSource, this.props.breakpoint) != getBreakpointText(prevProps.selectedSource, prevProps.breakpoint)) {
|
|
||||||
this.destroyEditor();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setupEditor();
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
this.destroyEditor();
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps) {
|
|
||||||
const prevBreakpoint = this.props.breakpoint;
|
|
||||||
const nextBreakpoint = nextProps.breakpoint;
|
|
||||||
return !prevBreakpoint || this.props.selectedSource != nextProps.selectedSource || prevBreakpoint.text != nextBreakpoint.text || prevBreakpoint.disabled != nextBreakpoint.disabled || prevBreakpoint.condition != nextBreakpoint.condition || prevBreakpoint.hidden != nextBreakpoint.hidden || prevBreakpoint.isCurrentlyPaused != nextBreakpoint.isCurrentlyPaused;
|
|
||||||
}
|
|
||||||
|
|
||||||
destroyEditor() {
|
|
||||||
if (this.editor) {
|
|
||||||
this.editor.destroy();
|
|
||||||
this.editor = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setupEditor() {
|
|
||||||
if (this.editor) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
|
||||||
selectedSource,
|
|
||||||
breakpoint
|
|
||||||
} = this.props;
|
|
||||||
this.editor = (0, _breakpoint.createEditor)(getBreakpointText(selectedSource, breakpoint)); // disables the default search shortcuts
|
|
||||||
// $FlowIgnore
|
|
||||||
|
|
||||||
this.editor._initShortcuts = () => {};
|
|
||||||
|
|
||||||
const node = _reactDom2.default.findDOMNode(this);
|
|
||||||
|
|
||||||
if (node instanceof HTMLElement) {
|
|
||||||
const mountNode = node.querySelector(".breakpoint-label");
|
|
||||||
|
|
||||||
if (node instanceof HTMLElement) {
|
|
||||||
// $FlowIgnore
|
|
||||||
mountNode.innerHTML = "";
|
|
||||||
this.editor.appendToLocalElement(mountNode);
|
|
||||||
this.editor.codeMirror.on("mousedown", (_, e) => e.preventDefault());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderCheckbox() {
|
|
||||||
const {
|
|
||||||
onChange,
|
|
||||||
breakpoint
|
|
||||||
} = this.props;
|
|
||||||
const {
|
|
||||||
disabled
|
|
||||||
} = breakpoint;
|
|
||||||
return _react2.default.createElement("input", {
|
|
||||||
type: "checkbox",
|
|
||||||
className: "breakpoint-checkbox",
|
|
||||||
checked: !disabled,
|
|
||||||
onChange: onChange,
|
|
||||||
onClick: ev => ev.stopPropagation()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
renderText() {
|
|
||||||
const {
|
|
||||||
selectedSource,
|
|
||||||
breakpoint
|
|
||||||
} = this.props;
|
|
||||||
const text = getBreakpointText(selectedSource, breakpoint);
|
|
||||||
return _react2.default.createElement("label", {
|
|
||||||
className: "breakpoint-label",
|
|
||||||
title: text
|
|
||||||
}, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderLineClose() {
|
|
||||||
const {
|
|
||||||
breakpoint,
|
|
||||||
onCloseClick,
|
|
||||||
selectedSource
|
|
||||||
} = this.props;
|
|
||||||
const {
|
|
||||||
location
|
|
||||||
} = breakpoint;
|
|
||||||
let {
|
|
||||||
line,
|
|
||||||
column
|
|
||||||
} = location;
|
|
||||||
|
|
||||||
if (selectedSource && (0, _devtoolsSourceMap.isGeneratedId)(selectedSource.id) && breakpoint.generatedLocation) {
|
|
||||||
line = breakpoint.generatedLocation.line;
|
|
||||||
column = breakpoint.generatedLocation.column;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _react2.default.createElement("div", {
|
|
||||||
className: "breakpoint-line-close"
|
|
||||||
}, _react2.default.createElement("div", {
|
|
||||||
className: "breakpoint-line"
|
|
||||||
}, getBreakpointLocation(breakpoint.source, line, column)), _react2.default.createElement(_Button.CloseButton, {
|
|
||||||
handleClick: onCloseClick,
|
|
||||||
tooltip: L10N.getStr("breakpoints.removeBreakpointTooltip")
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
breakpoint,
|
|
||||||
onClick,
|
|
||||||
onContextMenu
|
|
||||||
} = this.props;
|
|
||||||
const locationId = breakpoint.locationId;
|
|
||||||
const isCurrentlyPaused = breakpoint.isCurrentlyPaused;
|
|
||||||
const isDisabled = breakpoint.disabled;
|
|
||||||
const isConditional = !!breakpoint.condition;
|
|
||||||
return _react2.default.createElement("div", {
|
|
||||||
className: (0, _classnames2.default)({
|
|
||||||
breakpoint,
|
|
||||||
paused: isCurrentlyPaused,
|
|
||||||
disabled: isDisabled,
|
|
||||||
"is-conditional": isConditional
|
|
||||||
}),
|
|
||||||
key: locationId,
|
|
||||||
onClick: onClick,
|
|
||||||
onContextMenu: onContextMenu
|
|
||||||
}, this.renderCheckbox(), this.renderText(), this.renderLineClose());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.default = Breakpoint;
|
|
|
@ -1,212 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", {
|
|
||||||
value: true
|
|
||||||
});
|
|
||||||
|
|
||||||
var _react = require("devtools/client/shared/vendor/react");
|
|
||||||
|
|
||||||
var _react2 = _interopRequireDefault(_react);
|
|
||||||
|
|
||||||
var _classnames = require("devtools/client/debugger/new/dist/vendors").vendored["classnames"];
|
|
||||||
|
|
||||||
var _classnames2 = _interopRequireDefault(_classnames);
|
|
||||||
|
|
||||||
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
|
|
||||||
|
|
||||||
var _immutable = require("devtools/client/shared/vendor/immutable");
|
|
||||||
|
|
||||||
var I = _interopRequireWildcard(_immutable);
|
|
||||||
|
|
||||||
var _reselect = require("devtools/client/debugger/new/dist/vendors").vendored["reselect"];
|
|
||||||
|
|
||||||
var _lodash = require("devtools/client/shared/vendor/lodash");
|
|
||||||
|
|
||||||
var _Breakpoint = require("./Breakpoint");
|
|
||||||
|
|
||||||
var _Breakpoint2 = _interopRequireDefault(_Breakpoint);
|
|
||||||
|
|
||||||
var _SourceIcon = require("../shared/SourceIcon");
|
|
||||||
|
|
||||||
var _SourceIcon2 = _interopRequireDefault(_SourceIcon);
|
|
||||||
|
|
||||||
var _actions = require("../../actions/index");
|
|
||||||
|
|
||||||
var _actions2 = _interopRequireDefault(_actions);
|
|
||||||
|
|
||||||
var _source = require("../../utils/source");
|
|
||||||
|
|
||||||
var _selectors = require("../../selectors/index");
|
|
||||||
|
|
||||||
var _pause = require("../../utils/pause/index");
|
|
||||||
|
|
||||||
var _breakpoint = require("../../utils/breakpoint/index");
|
|
||||||
|
|
||||||
var _BreakpointsContextMenu = require("./BreakpointsContextMenu");
|
|
||||||
|
|
||||||
var _BreakpointsContextMenu2 = _interopRequireDefault(_BreakpointsContextMenu);
|
|
||||||
|
|
||||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
|
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
||||||
|
|
||||||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
|
|
||||||
|
|
||||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
||||||
|
|
||||||
function isCurrentlyPausedAtBreakpoint(frame, why, breakpoint) {
|
|
||||||
if (!frame || !(0, _pause.isInterrupted)(why)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bpId = (0, _breakpoint.makeLocationId)(breakpoint.location);
|
|
||||||
const pausedId = (0, _breakpoint.makeLocationId)(frame.location);
|
|
||||||
return bpId === pausedId;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createExceptionOption(label, value, onChange, className) {
|
|
||||||
return _react2.default.createElement("div", {
|
|
||||||
className: className,
|
|
||||||
onClick: onChange
|
|
||||||
}, _react2.default.createElement("input", {
|
|
||||||
type: "checkbox",
|
|
||||||
checked: value ? "checked" : "",
|
|
||||||
onChange: e => e.stopPropagation() && onChange()
|
|
||||||
}), _react2.default.createElement("div", {
|
|
||||||
className: "breakpoint-exceptions-label"
|
|
||||||
}, label));
|
|
||||||
}
|
|
||||||
|
|
||||||
function sortFilenames(urlA, urlB) {
|
|
||||||
const filenameA = (0, _source.getFilenameFromURL)(urlA);
|
|
||||||
const filenameB = (0, _source.getFilenameFromURL)(urlB);
|
|
||||||
|
|
||||||
if (filenameA > filenameB) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filenameA < filenameB) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Breakpoints extends _react.Component {
|
|
||||||
handleBreakpointCheckbox(breakpoint) {
|
|
||||||
if (breakpoint.loading) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (breakpoint.disabled) {
|
|
||||||
this.props.enableBreakpoint(breakpoint.location);
|
|
||||||
} else {
|
|
||||||
this.props.disableBreakpoint(breakpoint.location);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
selectBreakpoint(breakpoint) {
|
|
||||||
this.props.selectLocation(breakpoint.location);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeBreakpoint(event, breakpoint) {
|
|
||||||
event.stopPropagation();
|
|
||||||
this.props.removeBreakpoint(breakpoint.location);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderBreakpoint(breakpoint) {
|
|
||||||
const {
|
|
||||||
selectedSource
|
|
||||||
} = this.props;
|
|
||||||
return _react2.default.createElement(_Breakpoint2.default, {
|
|
||||||
key: breakpoint.locationId,
|
|
||||||
breakpoint: breakpoint,
|
|
||||||
selectedSource: selectedSource,
|
|
||||||
onClick: () => this.selectBreakpoint(breakpoint),
|
|
||||||
onContextMenu: e => (0, _BreakpointsContextMenu2.default)(_objectSpread({}, this.props, {
|
|
||||||
breakpoint,
|
|
||||||
contextMenuEvent: e
|
|
||||||
})),
|
|
||||||
onChange: () => this.handleBreakpointCheckbox(breakpoint),
|
|
||||||
onCloseClick: ev => this.removeBreakpoint(ev, breakpoint)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
renderExceptionsOptions() {
|
|
||||||
const {
|
|
||||||
breakpoints,
|
|
||||||
shouldPauseOnExceptions,
|
|
||||||
shouldPauseOnCaughtExceptions,
|
|
||||||
pauseOnExceptions
|
|
||||||
} = this.props;
|
|
||||||
const isEmpty = breakpoints.size == 0;
|
|
||||||
const exceptionsBox = createExceptionOption(L10N.getStr("pauseOnExceptionsItem2"), shouldPauseOnExceptions, () => pauseOnExceptions(!shouldPauseOnExceptions, false), "breakpoints-exceptions");
|
|
||||||
const ignoreCaughtBox = createExceptionOption(L10N.getStr("pauseOnCaughtExceptionsItem"), shouldPauseOnCaughtExceptions, () => pauseOnExceptions(true, !shouldPauseOnCaughtExceptions), "breakpoints-exceptions-caught");
|
|
||||||
return _react2.default.createElement("div", {
|
|
||||||
className: (0, _classnames2.default)("breakpoints-exceptions-options", {
|
|
||||||
empty: isEmpty
|
|
||||||
})
|
|
||||||
}, exceptionsBox, shouldPauseOnExceptions ? ignoreCaughtBox : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderBreakpoints() {
|
|
||||||
const {
|
|
||||||
breakpoints
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
if (breakpoints.size == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const groupedBreakpoints = (0, _lodash.groupBy)((0, _lodash.sortBy)([...breakpoints.valueSeq()], bp => bp.location.line), bp => (0, _source.getRawSourceURL)(bp.source.url));
|
|
||||||
return [...Object.keys(groupedBreakpoints).sort(sortFilenames).map(url => {
|
|
||||||
const groupBreakpoints = groupedBreakpoints[url].filter(bp => !bp.hidden && (bp.text || bp.originalText));
|
|
||||||
|
|
||||||
if (!groupBreakpoints.length) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
|
||||||
source
|
|
||||||
} = groupBreakpoints[0];
|
|
||||||
return [_react2.default.createElement("div", {
|
|
||||||
className: "breakpoint-heading",
|
|
||||||
title: url,
|
|
||||||
key: url,
|
|
||||||
onClick: () => this.props.selectSource(source.id)
|
|
||||||
}, _react2.default.createElement(_SourceIcon2.default, {
|
|
||||||
source: source
|
|
||||||
}), (0, _source.getFilename)(source)), ...groupBreakpoints.map(bp => this.renderBreakpoint(bp))];
|
|
||||||
})];
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return _react2.default.createElement("div", {
|
|
||||||
className: "pane breakpoints-list"
|
|
||||||
}, this.renderExceptionsOptions(), this.renderBreakpoints());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateLocation(sources, frame, why, bp) {
|
|
||||||
const source = (0, _selectors.getSourceInSources)(sources, bp.location.sourceId);
|
|
||||||
const isCurrentlyPaused = isCurrentlyPausedAtBreakpoint(frame, why, bp);
|
|
||||||
const locationId = (0, _breakpoint.makeLocationId)(bp.location);
|
|
||||||
|
|
||||||
const localBP = _objectSpread({}, bp, {
|
|
||||||
locationId,
|
|
||||||
isCurrentlyPaused,
|
|
||||||
source
|
|
||||||
});
|
|
||||||
|
|
||||||
return localBP;
|
|
||||||
}
|
|
||||||
|
|
||||||
const _getBreakpoints = (0, _reselect.createSelector)(_selectors.getBreakpoints, _selectors.getSources, _selectors.getTopFrame, _selectors.getPauseReason, (breakpoints, sources, frame, why) => breakpoints.map(bp => updateLocation(sources, frame, why, bp)).filter(bp => bp.source && !bp.source.isBlackBoxed));
|
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
|
||||||
breakpoints: _getBreakpoints(state),
|
|
||||||
selectedSource: (0, _selectors.getSelectedSource)(state)
|
|
||||||
});
|
|
||||||
|
|
||||||
exports.default = (0, _reactRedux.connect)(mapStateToProps, _actions2.default)(Breakpoints);
|
|
|
@ -0,0 +1,196 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
|
||||||
|
var _react = require("devtools/client/shared/vendor/react");
|
||||||
|
|
||||||
|
var _react2 = _interopRequireDefault(_react);
|
||||||
|
|
||||||
|
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
|
||||||
|
|
||||||
|
var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
|
||||||
|
|
||||||
|
var _classnames = require("devtools/client/debugger/new/dist/vendors").vendored["classnames"];
|
||||||
|
|
||||||
|
var _classnames2 = _interopRequireDefault(_classnames);
|
||||||
|
|
||||||
|
var _actions = require("../../../actions/index");
|
||||||
|
|
||||||
|
var _actions2 = _interopRequireDefault(_actions);
|
||||||
|
|
||||||
|
var _BreakpointsContextMenu = require("./BreakpointsContextMenu");
|
||||||
|
|
||||||
|
var _BreakpointsContextMenu2 = _interopRequireDefault(_BreakpointsContextMenu);
|
||||||
|
|
||||||
|
var _Button = require("../../shared/Button/index");
|
||||||
|
|
||||||
|
var _breakpoint = require("../../../utils/breakpoint/index");
|
||||||
|
|
||||||
|
var _prefs = require("../../../utils/prefs");
|
||||||
|
|
||||||
|
var _editor = require("../../../utils/editor/index");
|
||||||
|
|
||||||
|
var _selectors = require("../../../selectors/index");
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
|
||||||
|
|
||||||
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||||
|
|
||||||
|
function getMappedLocation(mappedLocation, selectedSource) {
|
||||||
|
return selectedSource && (0, _devtoolsSourceMap.isGeneratedId)(selectedSource.id) ? mappedLocation.generatedLocation : mappedLocation.location;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Breakpoint extends _react.PureComponent {
|
||||||
|
constructor(...args) {
|
||||||
|
var _temp;
|
||||||
|
|
||||||
|
return _temp = super(...args), this.onContextMenu = e => {
|
||||||
|
(0, _BreakpointsContextMenu2.default)(_objectSpread({}, this.props, {
|
||||||
|
contextMenuEvent: e
|
||||||
|
}));
|
||||||
|
}, this.selectBreakpoint = () => {
|
||||||
|
const {
|
||||||
|
breakpoint,
|
||||||
|
selectSpecificLocation
|
||||||
|
} = this.props;
|
||||||
|
selectSpecificLocation(breakpoint.location);
|
||||||
|
}, this.removeBreakpoint = event => {
|
||||||
|
const {
|
||||||
|
breakpoint,
|
||||||
|
removeBreakpoint
|
||||||
|
} = this.props;
|
||||||
|
event.stopPropagation();
|
||||||
|
removeBreakpoint(breakpoint.location);
|
||||||
|
}, this.handleBreakpointCheckbox = () => {
|
||||||
|
const {
|
||||||
|
breakpoint,
|
||||||
|
enableBreakpoint,
|
||||||
|
disableBreakpoint
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
if (breakpoint.loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (breakpoint.disabled) {
|
||||||
|
enableBreakpoint(breakpoint.location);
|
||||||
|
} else {
|
||||||
|
disableBreakpoint(breakpoint.location);
|
||||||
|
}
|
||||||
|
}, _temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
isCurrentlyPausedAtBreakpoint() {
|
||||||
|
const {
|
||||||
|
frame,
|
||||||
|
breakpoint,
|
||||||
|
selectedSource
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
if (!frame) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bpId = (0, _breakpoint.getLocationWithoutColumn)(getMappedLocation(breakpoint, selectedSource));
|
||||||
|
const frameId = (0, _breakpoint.getLocationWithoutColumn)(getMappedLocation(frame, selectedSource));
|
||||||
|
return bpId == frameId;
|
||||||
|
}
|
||||||
|
|
||||||
|
getBreakpointLocation() {
|
||||||
|
const {
|
||||||
|
breakpoint,
|
||||||
|
source,
|
||||||
|
selectedSource
|
||||||
|
} = this.props;
|
||||||
|
const {
|
||||||
|
column,
|
||||||
|
line
|
||||||
|
} = getMappedLocation(breakpoint, selectedSource);
|
||||||
|
const isWasm = source && source.isWasm;
|
||||||
|
const columnVal = _prefs.features.columnBreakpoints && column ? `:${column}` : "";
|
||||||
|
const bpLocation = isWasm ? `0x${line.toString(16).toUpperCase()}` : `${line}${columnVal}`;
|
||||||
|
return bpLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
getBreakpointText() {
|
||||||
|
const {
|
||||||
|
selectedSource,
|
||||||
|
breakpoint
|
||||||
|
} = this.props;
|
||||||
|
const {
|
||||||
|
condition
|
||||||
|
} = breakpoint;
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
return condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedSource && (0, _devtoolsSourceMap.isGeneratedId)(selectedSource.id)) {
|
||||||
|
return breakpoint.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
return breakpoint.originalText;
|
||||||
|
}
|
||||||
|
|
||||||
|
highlightText() {
|
||||||
|
const text = this.getBreakpointText();
|
||||||
|
const codeMirror = (0, _editor.getCodeMirror)();
|
||||||
|
|
||||||
|
if (!text || !codeMirror) {
|
||||||
|
return {
|
||||||
|
__html: ""
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const node = document.createElement("div");
|
||||||
|
codeMirror.constructor.runMode(text, "application/javascript", node);
|
||||||
|
return {
|
||||||
|
__html: node.innerHTML
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
breakpoint
|
||||||
|
} = this.props;
|
||||||
|
return _react2.default.createElement("div", {
|
||||||
|
className: (0, _classnames2.default)({
|
||||||
|
breakpoint,
|
||||||
|
paused: this.isCurrentlyPausedAtBreakpoint(),
|
||||||
|
disabled: breakpoint.disabled,
|
||||||
|
"is-conditional": !!breakpoint.condition
|
||||||
|
}),
|
||||||
|
onClick: this.selectBreakpoint,
|
||||||
|
onContextMenu: this.onContextMenu
|
||||||
|
}, _react2.default.createElement("input", {
|
||||||
|
type: "checkbox",
|
||||||
|
className: "breakpoint-checkbox",
|
||||||
|
checked: !breakpoint.disabled,
|
||||||
|
onChange: this.handleBreakpointCheckbox,
|
||||||
|
onClick: ev => ev.stopPropagation()
|
||||||
|
}), _react2.default.createElement("label", {
|
||||||
|
className: "breakpoint-label cm-s-mozilla",
|
||||||
|
title: this.getBreakpointText(),
|
||||||
|
dangerouslySetInnerHTML: this.highlightText()
|
||||||
|
}), _react2.default.createElement("div", {
|
||||||
|
className: "breakpoint-line-close"
|
||||||
|
}, _react2.default.createElement("div", {
|
||||||
|
className: "breakpoint-line"
|
||||||
|
}, this.getBreakpointLocation()), _react2.default.createElement(_Button.CloseButton, {
|
||||||
|
handleClick: e => this.removeBreakpoint(e),
|
||||||
|
tooltip: L10N.getStr("breakpoints.removeBreakpointTooltip")
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
frame: (0, _selectors.getTopFrame)(state),
|
||||||
|
selectedSource: (0, _selectors.getSelectedSource)(state)
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, _actions2.default)(Breakpoint);
|
|
@ -0,0 +1,105 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
|
||||||
|
var _react = require("devtools/client/shared/vendor/react");
|
||||||
|
|
||||||
|
var _react2 = _interopRequireDefault(_react);
|
||||||
|
|
||||||
|
var _classnames = require("devtools/client/debugger/new/dist/vendors").vendored["classnames"];
|
||||||
|
|
||||||
|
var _classnames2 = _interopRequireDefault(_classnames);
|
||||||
|
|
||||||
|
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
|
||||||
|
|
||||||
|
var _Breakpoint = require("./Breakpoint");
|
||||||
|
|
||||||
|
var _Breakpoint2 = _interopRequireDefault(_Breakpoint);
|
||||||
|
|
||||||
|
var _SourceIcon = require("../../shared/SourceIcon");
|
||||||
|
|
||||||
|
var _SourceIcon2 = _interopRequireDefault(_SourceIcon);
|
||||||
|
|
||||||
|
var _actions = require("../../../actions/index");
|
||||||
|
|
||||||
|
var _actions2 = _interopRequireDefault(_actions);
|
||||||
|
|
||||||
|
var _source = require("../../../utils/source");
|
||||||
|
|
||||||
|
var _breakpoint = require("../../../utils/breakpoint/index");
|
||||||
|
|
||||||
|
var _selectors = require("../../../selectors/index");
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||||
|
function createExceptionOption(label, value, onChange, className) {
|
||||||
|
return _react2.default.createElement("div", {
|
||||||
|
className: className,
|
||||||
|
onClick: onChange
|
||||||
|
}, _react2.default.createElement("input", {
|
||||||
|
type: "checkbox",
|
||||||
|
checked: value ? "checked" : "",
|
||||||
|
onChange: e => e.stopPropagation() && onChange()
|
||||||
|
}), _react2.default.createElement("div", {
|
||||||
|
className: "breakpoint-exceptions-label"
|
||||||
|
}, label));
|
||||||
|
}
|
||||||
|
|
||||||
|
class Breakpoints extends _react.Component {
|
||||||
|
renderExceptionsOptions() {
|
||||||
|
const {
|
||||||
|
breakpointSources,
|
||||||
|
shouldPauseOnExceptions,
|
||||||
|
shouldPauseOnCaughtExceptions,
|
||||||
|
pauseOnExceptions
|
||||||
|
} = this.props;
|
||||||
|
const isEmpty = breakpointSources.length == 0;
|
||||||
|
const exceptionsBox = createExceptionOption(L10N.getStr("pauseOnExceptionsItem2"), shouldPauseOnExceptions, () => pauseOnExceptions(!shouldPauseOnExceptions, false), "breakpoints-exceptions");
|
||||||
|
const ignoreCaughtBox = createExceptionOption(L10N.getStr("pauseOnCaughtExceptionsItem"), shouldPauseOnCaughtExceptions, () => pauseOnExceptions(true, !shouldPauseOnCaughtExceptions), "breakpoints-exceptions-caught");
|
||||||
|
return _react2.default.createElement("div", {
|
||||||
|
className: (0, _classnames2.default)("breakpoints-exceptions-options", {
|
||||||
|
empty: isEmpty
|
||||||
|
})
|
||||||
|
}, exceptionsBox, shouldPauseOnExceptions ? ignoreCaughtBox : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderBreakpoints() {
|
||||||
|
const {
|
||||||
|
breakpointSources
|
||||||
|
} = this.props;
|
||||||
|
return [...breakpointSources.map(({
|
||||||
|
source,
|
||||||
|
breakpoints
|
||||||
|
}) => [_react2.default.createElement("div", {
|
||||||
|
className: "breakpoint-heading",
|
||||||
|
title: source.url,
|
||||||
|
key: source.url,
|
||||||
|
onClick: () => this.props.selectSource(source.id)
|
||||||
|
}, _react2.default.createElement(_SourceIcon2.default, {
|
||||||
|
source: source
|
||||||
|
}), (0, _source.getFilename)(source)), ...breakpoints.map(breakpoint => _react2.default.createElement(_Breakpoint2.default, {
|
||||||
|
breakpoint: breakpoint,
|
||||||
|
source: source,
|
||||||
|
key: (0, _breakpoint.makeLocationId)(breakpoint.location)
|
||||||
|
}))])];
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return _react2.default.createElement("div", {
|
||||||
|
className: "pane breakpoints-list"
|
||||||
|
}, this.renderExceptionsOptions(), this.renderBreakpoints());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
breakpointSources: (0, _selectors.getBreakpointSources)(state),
|
||||||
|
selectedSource: (0, _selectors.getSelectedSource)(state)
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, _actions2.default)(Breakpoints);
|
15
servo/etc/ci/clean_build_artifacts.sh → devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/moz.build
Executable file → Normal file
15
servo/etc/ci/clean_build_artifacts.sh → devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/moz.build
Executable file → Normal file
|
@ -1,11 +1,14 @@
|
||||||
#!/usr/bin/env bash
|
# vim: set filetype=python:
|
||||||
|
|
||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
# 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
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
set -o errexit
|
DIRS += [
|
||||||
set -o nounset
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
rm -rf target/{debug,release,doc,geckolib}
|
]
|
||||||
|
|
||||||
|
DevToolsModules(
|
||||||
|
'Breakpoint.js',
|
||||||
|
'BreakpointsContextMenu.js',
|
||||||
|
'index.js',
|
||||||
|
)
|
|
@ -28,7 +28,7 @@ var _Svg2 = _interopRequireDefault(_Svg);
|
||||||
|
|
||||||
var _prefs = require("../../utils/prefs");
|
var _prefs = require("../../utils/prefs");
|
||||||
|
|
||||||
var _Breakpoints = require("./Breakpoints");
|
var _Breakpoints = require("./Breakpoints/index");
|
||||||
|
|
||||||
var _Breakpoints2 = _interopRequireDefault(_Breakpoints);
|
var _Breakpoints2 = _interopRequireDefault(_Breakpoints);
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,11 @@
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
DIRS += [
|
DIRS += [
|
||||||
|
'Breakpoints',
|
||||||
'Frames',
|
'Frames',
|
||||||
]
|
]
|
||||||
|
|
||||||
DevToolsModules(
|
DevToolsModules(
|
||||||
'Breakpoint.js',
|
|
||||||
'Breakpoints.js',
|
|
||||||
'BreakpointsContextMenu.js',
|
|
||||||
'CommandBar.js',
|
'CommandBar.js',
|
||||||
'EventListeners.js',
|
'EventListeners.js',
|
||||||
'Expressions.js',
|
'Expressions.js',
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", {
|
|
||||||
value: true
|
|
||||||
});
|
|
||||||
|
|
||||||
var _react = require("devtools/client/shared/vendor/react");
|
|
||||||
|
|
||||||
var _react2 = _interopRequireDefault(_react);
|
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
||||||
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
|
||||||
function CloseButton({
|
|
||||||
handleClick,
|
|
||||||
buttonClass,
|
|
||||||
tooltip
|
|
||||||
}) {
|
|
||||||
return _react2.default.createElement("button", {
|
|
||||||
className: buttonClass ? `close-btn ${buttonClass}` : "close-btn",
|
|
||||||
onClick: handleClick,
|
|
||||||
title: tooltip
|
|
||||||
}, _react2.default.createElement("img", {
|
|
||||||
className: "close"
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.default = CloseButton;
|
|
|
@ -1,54 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", {
|
|
||||||
value: true
|
|
||||||
});
|
|
||||||
|
|
||||||
var _react = require("devtools/client/shared/vendor/react");
|
|
||||||
|
|
||||||
var _react2 = _interopRequireDefault(_react);
|
|
||||||
|
|
||||||
var _classnames = require("devtools/client/debugger/new/dist/vendors").vendored["classnames"];
|
|
||||||
|
|
||||||
var _classnames2 = _interopRequireDefault(_classnames);
|
|
||||||
|
|
||||||
var _Svg = require("devtools/client/debugger/new/dist/vendors").vendored["Svg"];
|
|
||||||
|
|
||||||
var _Svg2 = _interopRequireDefault(_Svg);
|
|
||||||
|
|
||||||
var _CommandBarButton = require("./CommandBarButton");
|
|
||||||
|
|
||||||
var _CommandBarButton2 = _interopRequireDefault(_CommandBarButton);
|
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
||||||
|
|
||||||
/* 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/>. */
|
|
||||||
class PaneToggleButton extends _react.PureComponent {
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
position,
|
|
||||||
collapsed,
|
|
||||||
horizontal,
|
|
||||||
handleClick
|
|
||||||
} = this.props;
|
|
||||||
const title = !collapsed ? L10N.getStr("expandPanes") : L10N.getStr("collapsePanes");
|
|
||||||
return _react2.default.createElement(_CommandBarButton2.default, {
|
|
||||||
className: (0, _classnames2.default)("toggle-button", position, {
|
|
||||||
collapsed,
|
|
||||||
vertical: !horizontal
|
|
||||||
}),
|
|
||||||
onClick: () => handleClick(position, collapsed),
|
|
||||||
title: title
|
|
||||||
}, _react2.default.createElement(_Svg2.default, {
|
|
||||||
name: "togglePanes"
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
PaneToggleButton.defaultProps = {
|
|
||||||
horizontal: false
|
|
||||||
};
|
|
||||||
exports.default = PaneToggleButton;
|
|
|
@ -162,17 +162,17 @@ function isSymbolsLoading(state, source) {
|
||||||
return symbols.hasOwnProperty("loading");
|
return symbols.hasOwnProperty("loading");
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEmptyLineInSource(state, line, selectedSource) {
|
function isEmptyLineInSource(state, line, selectedSourceId) {
|
||||||
const emptyLines = getEmptyLines(state, selectedSource);
|
const emptyLines = getEmptyLines(state, selectedSourceId);
|
||||||
return emptyLines && emptyLines.includes(line);
|
return emptyLines && emptyLines.includes(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEmptyLines(state, source) {
|
function getEmptyLines(state, sourceId) {
|
||||||
if (!source) {
|
if (!sourceId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return state.ast.emptyLines.get(source.id);
|
return state.ast.emptyLines.get(sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPausePoints(state, sourceId) {
|
function getPausePoints(state, sourceId) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
||||||
});
|
});
|
||||||
exports.getSelectedSourceText = exports.getSelectedSource = exports.getSelectedLocation = exports.getSourcesForTabs = exports.getSourceTabs = exports.getTabs = exports.getSources = exports.RelativeSourceRecordClass = exports.SourceRecordClass = undefined;
|
exports.getSelectedSourceText = exports.getSelectedSource = exports.getSelectedLocation = exports.getSourcesForTabs = exports.getSourceTabs = exports.getTabs = exports.getSources = exports.RelativeSourceRecordClass = exports.SourceRecordClass = undefined;
|
||||||
exports.initialSourcesState = initialSourcesState;
|
exports.initialSourcesState = initialSourcesState;
|
||||||
|
exports.createSourceRecord = createSourceRecord;
|
||||||
exports.removeSourceFromTabList = removeSourceFromTabList;
|
exports.removeSourceFromTabList = removeSourceFromTabList;
|
||||||
exports.removeSourcesFromTabList = removeSourcesFromTabList;
|
exports.removeSourcesFromTabList = removeSourcesFromTabList;
|
||||||
exports.getBlackBoxList = getBlackBoxList;
|
exports.getBlackBoxList = getBlackBoxList;
|
||||||
|
@ -68,6 +69,10 @@ const RelativeSourceRecordClass = exports.RelativeSourceRecordClass = new I.Reco
|
||||||
relativeUrl: undefined
|
relativeUrl: undefined
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
function createSourceRecord(source) {
|
||||||
|
return new SourceRecordClass(source);
|
||||||
|
}
|
||||||
|
|
||||||
function update(state = initialSourcesState(), action) {
|
function update(state = initialSourcesState(), action) {
|
||||||
let location = null;
|
let location = null;
|
||||||
|
|
||||||
|
@ -222,7 +227,7 @@ function updateSource(state, source) {
|
||||||
return state.setIn(["sources", source.id], updatedSource);
|
return state.setIn(["sources", source.id], updatedSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
return state.setIn(["sources", source.id], new SourceRecordClass(source));
|
return state.setIn(["sources", source.id], createSourceRecord(source));
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeSourceFromTabList(tabs, url) {
|
function removeSourceFromTabList(tabs, url) {
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.getBreakpointSources = undefined;
|
||||||
|
|
||||||
|
var _lodash = require("devtools/client/shared/vendor/lodash");
|
||||||
|
|
||||||
|
var _reselect = require("devtools/client/debugger/new/dist/vendors").vendored["reselect"];
|
||||||
|
|
||||||
|
var _selectors = require("../selectors/index");
|
||||||
|
|
||||||
|
var _source = require("../utils/source");
|
||||||
|
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||||
|
function getBreakpointsForSource(source, breakpoints) {
|
||||||
|
return breakpoints.valueSeq().filter(bp => bp.location.sourceId == source.id && !bp.hidden && (bp.text || bp.condition)).sortBy(bp => bp.location.line).toJS();
|
||||||
|
}
|
||||||
|
|
||||||
|
function findBreakpointSources(sources, breakpoints) {
|
||||||
|
const sourceIds = (0, _lodash.uniq)(breakpoints.valueSeq().filter(bp => !bp.hidden).map(bp => bp.location.sourceId).toJS());
|
||||||
|
const breakpointSources = sourceIds.map(id => (0, _selectors.getSourceInSources)(sources, id)).filter(source => source && !source.isBlackBoxed);
|
||||||
|
return (0, _lodash.sortBy)(breakpointSources, source => (0, _source.getFilenameFromURL)(source.url));
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getBreakpointSources(breakpoints, sources, selectedSource) {
|
||||||
|
const breakpointSources = findBreakpointSources(sources, breakpoints);
|
||||||
|
return breakpointSources.map(source => ({
|
||||||
|
source,
|
||||||
|
breakpoints: getBreakpointsForSource(source, breakpoints)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
const getBreakpointSources = exports.getBreakpointSources = (0, _reselect.createSelector)(_selectors.getBreakpoints, _selectors.getSources, _getBreakpointSources);
|
|
@ -251,4 +251,13 @@ Object.defineProperty(exports, "getRelativeSources", {
|
||||||
get: function () {
|
get: function () {
|
||||||
return _getRelativeSources.getRelativeSources;
|
return _getRelativeSources.getRelativeSources;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var _breakpointSources = require("./breakpointSources");
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "getBreakpointSources", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _breakpointSources.getBreakpointSources;
|
||||||
|
}
|
||||||
});
|
});
|
|
@ -9,6 +9,7 @@ DIRS += [
|
||||||
|
|
||||||
DevToolsModules(
|
DevToolsModules(
|
||||||
'breakpointAtLocation.js',
|
'breakpointAtLocation.js',
|
||||||
|
'breakpointSources.js',
|
||||||
'getCallStackFrames.js',
|
'getCallStackFrames.js',
|
||||||
'getRelativeSources.js',
|
'getRelativeSources.js',
|
||||||
'inComponent.js',
|
'inComponent.js',
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", {
|
|
||||||
value: true
|
|
||||||
});
|
|
||||||
exports.createEditor = createEditor;
|
|
||||||
|
|
||||||
var _sourceEditor = require("devtools/client/sourceeditor/editor");
|
|
||||||
|
|
||||||
var _sourceEditor2 = _interopRequireDefault(_sourceEditor);
|
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
||||||
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
|
||||||
function createEditor(value) {
|
|
||||||
return new _sourceEditor2.default({
|
|
||||||
mode: "javascript",
|
|
||||||
foldGutter: false,
|
|
||||||
enableCodeFolding: false,
|
|
||||||
readOnly: "nocursor",
|
|
||||||
lineNumbers: false,
|
|
||||||
theme: "mozilla mozilla-breakpoint",
|
|
||||||
styleActiveLine: false,
|
|
||||||
lineWrapping: false,
|
|
||||||
matchBrackets: false,
|
|
||||||
showAnnotationRuler: false,
|
|
||||||
gutters: false,
|
|
||||||
value: value || "",
|
|
||||||
scrollbarStyle: null
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -3,16 +3,7 @@
|
||||||
Object.defineProperty(exports, "__esModule", {
|
Object.defineProperty(exports, "__esModule", {
|
||||||
value: true
|
value: true
|
||||||
});
|
});
|
||||||
exports.findScopeByName = exports.getASTLocation = exports.createEditor = undefined;
|
exports.findScopeByName = exports.getASTLocation = undefined;
|
||||||
|
|
||||||
var _createEditor = require("./create-editor");
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "createEditor", {
|
|
||||||
enumerable: true,
|
|
||||||
get: function () {
|
|
||||||
return _createEditor.createEditor;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var _astBreakpointLocation = require("./astBreakpointLocation");
|
var _astBreakpointLocation = require("./astBreakpointLocation");
|
||||||
|
|
||||||
|
@ -31,6 +22,7 @@ Object.defineProperty(exports, "findScopeByName", {
|
||||||
exports.firstString = firstString;
|
exports.firstString = firstString;
|
||||||
exports.locationMoved = locationMoved;
|
exports.locationMoved = locationMoved;
|
||||||
exports.makeLocationId = makeLocationId;
|
exports.makeLocationId = makeLocationId;
|
||||||
|
exports.getLocationWithoutColumn = getLocationWithoutColumn;
|
||||||
exports.makePendingLocationId = makePendingLocationId;
|
exports.makePendingLocationId = makePendingLocationId;
|
||||||
exports.assertBreakpoint = assertBreakpoint;
|
exports.assertBreakpoint = assertBreakpoint;
|
||||||
exports.assertPendingBreakpoint = assertPendingBreakpoint;
|
exports.assertPendingBreakpoint = assertPendingBreakpoint;
|
||||||
|
@ -77,6 +69,14 @@ function makeLocationId(location) {
|
||||||
return `${sourceId}:${line}:${columnString}`;
|
return `${sourceId}:${line}:${columnString}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getLocationWithoutColumn(location) {
|
||||||
|
const {
|
||||||
|
sourceId,
|
||||||
|
line
|
||||||
|
} = location;
|
||||||
|
return `${sourceId}:${line}`;
|
||||||
|
}
|
||||||
|
|
||||||
function makePendingLocationId(location) {
|
function makePendingLocationId(location) {
|
||||||
assertPendingLocation(location);
|
assertPendingLocation(location);
|
||||||
const {
|
const {
|
||||||
|
|
|
@ -9,6 +9,5 @@ DIRS += [
|
||||||
|
|
||||||
DevToolsModules(
|
DevToolsModules(
|
||||||
'astBreakpointLocation.js',
|
'astBreakpointLocation.js',
|
||||||
'create-editor.js',
|
|
||||||
'index.js',
|
'index.js',
|
||||||
)
|
)
|
||||||
|
|
|
@ -65,6 +65,7 @@ Object.keys(_createEditor).forEach(function (key) {
|
||||||
});
|
});
|
||||||
exports.setEditor = setEditor;
|
exports.setEditor = setEditor;
|
||||||
exports.getEditor = getEditor;
|
exports.getEditor = getEditor;
|
||||||
|
exports.getCodeMirror = getCodeMirror;
|
||||||
exports.removeEditor = removeEditor;
|
exports.removeEditor = removeEditor;
|
||||||
exports.shouldShowPrettyPrint = shouldShowPrettyPrint;
|
exports.shouldShowPrettyPrint = shouldShowPrettyPrint;
|
||||||
exports.shouldShowFooter = shouldShowFooter;
|
exports.shouldShowFooter = shouldShowFooter;
|
||||||
|
@ -103,6 +104,10 @@ function getEditor() {
|
||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCodeMirror() {
|
||||||
|
return editor && editor.codeMirror;
|
||||||
|
}
|
||||||
|
|
||||||
function removeEditor() {
|
function removeEditor() {
|
||||||
editor = null;
|
editor = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ require("codemirror/addon/fold/indent-fold/index");
|
||||||
|
|
||||||
require("codemirror/addon/fold/foldgutter/index");
|
require("codemirror/addon/fold/foldgutter/index");
|
||||||
|
|
||||||
|
require("codemirror/addon/runmode/runmode/index");
|
||||||
|
|
||||||
require("codemirror/addon/selection/active-line/index");
|
require("codemirror/addon/selection/active-line/index");
|
||||||
|
|
||||||
require("codemirror/addon/edit/matchbrackets/index");
|
require("codemirror/addon/edit/matchbrackets/index");
|
||||||
|
|
|
@ -9,6 +9,8 @@ var _parser = require("../../../workers/parser/index");
|
||||||
|
|
||||||
var _locColumn = require("./locColumn");
|
var _locColumn = require("./locColumn");
|
||||||
|
|
||||||
|
var _rangeMetadata = require("./rangeMetadata");
|
||||||
|
|
||||||
var _findGeneratedBindingFromPosition = require("./findGeneratedBindingFromPosition");
|
var _findGeneratedBindingFromPosition = require("./findGeneratedBindingFromPosition");
|
||||||
|
|
||||||
var _buildGeneratedBindingList = require("./buildGeneratedBindingList");
|
var _buildGeneratedBindingList = require("./buildGeneratedBindingList");
|
||||||
|
@ -30,10 +32,11 @@ async function buildMappedScopes(source, frame, scopes, sourceMaps, client) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const generatedAstBindings = (0, _buildGeneratedBindingList.buildGeneratedBindingList)(scopes, generatedAstScopes, frame.this);
|
const generatedAstBindings = (0, _buildGeneratedBindingList.buildGeneratedBindingList)(scopes, generatedAstScopes, frame.this);
|
||||||
|
const originalRanges = await (0, _rangeMetadata.loadRangeMetadata)(source, frame, originalAstScopes, sourceMaps);
|
||||||
const {
|
const {
|
||||||
mappedOriginalScopes,
|
mappedOriginalScopes,
|
||||||
expressionLookup
|
expressionLookup
|
||||||
} = await mapOriginalBindingsToGenerated(source, originalAstScopes, generatedAstBindings, client, sourceMaps);
|
} = await mapOriginalBindingsToGenerated(source, originalRanges, originalAstScopes, generatedAstBindings, client, sourceMaps);
|
||||||
const mappedGeneratedScopes = generateClientScope(scopes, mappedOriginalScopes);
|
const mappedGeneratedScopes = generateClientScope(scopes, mappedOriginalScopes);
|
||||||
return isReliableScope(mappedGeneratedScopes) ? {
|
return isReliableScope(mappedGeneratedScopes) ? {
|
||||||
mappings: expressionLookup,
|
mappings: expressionLookup,
|
||||||
|
@ -41,7 +44,7 @@ async function buildMappedScopes(source, frame, scopes, sourceMaps, client) {
|
||||||
} : null;
|
} : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function mapOriginalBindingsToGenerated(source, originalAstScopes, generatedAstBindings, client, sourceMaps) {
|
async function mapOriginalBindingsToGenerated(source, originalRanges, originalAstScopes, generatedAstBindings, client, sourceMaps) {
|
||||||
const expressionLookup = {};
|
const expressionLookup = {};
|
||||||
const mappedOriginalScopes = [];
|
const mappedOriginalScopes = [];
|
||||||
const cachedSourceMaps = batchScopeMappings(originalAstScopes, source, sourceMaps);
|
const cachedSourceMaps = batchScopeMappings(originalAstScopes, source, sourceMaps);
|
||||||
|
@ -51,7 +54,7 @@ async function mapOriginalBindingsToGenerated(source, originalAstScopes, generat
|
||||||
|
|
||||||
for (const name of Object.keys(item.bindings)) {
|
for (const name of Object.keys(item.bindings)) {
|
||||||
const binding = item.bindings[name];
|
const binding = item.bindings[name];
|
||||||
const result = await findGeneratedBinding(cachedSourceMaps, client, source, name, binding, generatedAstBindings);
|
const result = await findGeneratedBinding(cachedSourceMaps, client, source, name, binding, originalRanges, generatedAstBindings);
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
generatedBindings[name] = result.grip;
|
generatedBindings[name] = result.grip;
|
||||||
|
@ -213,7 +216,14 @@ function generateClientScope(scopes, originalScopes) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function findGeneratedBinding(sourceMaps, client, source, name, originalBinding, generatedAstBindings) {
|
function hasValidIdent(range, pos) {
|
||||||
|
return range.type === "match" || // For declarations, we allow the range on the identifier to be a
|
||||||
|
// more general "contains" to increase the chances of a match.
|
||||||
|
pos.type !== "ref" && range.type === "contains";
|
||||||
|
} // eslint-disable-next-line complexity
|
||||||
|
|
||||||
|
|
||||||
|
async function findGeneratedBinding(sourceMaps, client, source, name, originalBinding, originalRanges, generatedAstBindings) {
|
||||||
// If there are no references to the implicits, then we have no way to
|
// If there are no references to the implicits, then we have no way to
|
||||||
// even attempt to map it back to the original since there is no location
|
// even attempt to map it back to the original since there is no location
|
||||||
// data to use. Bail out instead of just showing it as unmapped.
|
// data to use. Bail out instead of just showing it as unmapped.
|
||||||
|
@ -227,27 +237,43 @@ async function findGeneratedBinding(sourceMaps, client, source, name, originalBi
|
||||||
let genContent = null;
|
let genContent = null;
|
||||||
|
|
||||||
for (const pos of refs) {
|
for (const pos of refs) {
|
||||||
if (originalBinding.type === "import") {
|
const range = (0, _rangeMetadata.findMatchingRange)(originalRanges, pos);
|
||||||
genContent = await (0, _findGeneratedBindingFromPosition.findGeneratedBindingForImportBinding)(sourceMaps, client, source, pos, name, originalBinding.type, generatedAstBindings);
|
|
||||||
} else {
|
if (range && hasValidIdent(range, pos)) {
|
||||||
genContent = await (0, _findGeneratedBindingFromPosition.findGeneratedBindingForStandardBinding)(sourceMaps, client, source, pos, name, originalBinding.type, generatedAstBindings);
|
if (originalBinding.type === "import") {
|
||||||
|
genContent = await (0, _findGeneratedBindingFromPosition.findGeneratedBindingForImportBinding)(sourceMaps, client, source, pos, name, originalBinding.type, generatedAstBindings);
|
||||||
|
} else {
|
||||||
|
genContent = await (0, _findGeneratedBindingFromPosition.findGeneratedBindingForStandardBinding)(sourceMaps, client, source, pos, name, originalBinding.type, generatedAstBindings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pos.type === "class-decl" || pos.type === "class-inner") && source.contentType && source.contentType.match(/\/typescript/)) {
|
if ((pos.type === "class-decl" || pos.type === "class-inner") && source.contentType && source.contentType.match(/\/typescript/)) {
|
||||||
// Resolve to first binding in the range
|
const declRange = (0, _rangeMetadata.findMatchingRange)(originalRanges, pos.declaration);
|
||||||
const declContent = await (0, _findGeneratedBindingFromPosition.findGeneratedBindingForNormalDeclaration)(sourceMaps, client, source, pos, name, originalBinding.type, generatedAstBindings);
|
|
||||||
|
|
||||||
if (declContent) {
|
if (declRange && declRange.type !== "multiple") {
|
||||||
// Prefer the declaration mapping in this case because TS sometimes
|
// Resolve to first binding in the range
|
||||||
// maps class declaration names to "export.Foo = Foo;" or to
|
const declContent = await (0, _findGeneratedBindingFromPosition.findGeneratedBindingForNormalDeclaration)(sourceMaps, client, source, pos, name, originalBinding.type, generatedAstBindings);
|
||||||
// the decorator logic itself
|
|
||||||
genContent = declContent;
|
if (declContent) {
|
||||||
|
// Prefer the declaration mapping in this case because TS sometimes
|
||||||
|
// maps class declaration names to "export.Foo = Foo;" or to
|
||||||
|
// the decorator logic itself
|
||||||
|
genContent = declContent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!genContent && (pos.type === "import-decl" || pos.type === "import-ns-decl")) {
|
if (!genContent && (pos.type === "import-decl" || pos.type === "import-ns-decl")) {
|
||||||
// match the import declaration location
|
const declRange = (0, _rangeMetadata.findMatchingRange)(originalRanges, pos.declaration); // The import declaration should have an original position mapping,
|
||||||
genContent = await (0, _findGeneratedBindingFromPosition.findGeneratedBindingForImportDeclaration)(sourceMaps, client, source, pos, name, originalBinding.type, generatedAstBindings);
|
// but otherwise we don't really have preferences on the range type
|
||||||
|
// because it can have multiple bindings, but we do want to make sure
|
||||||
|
// that all of the bindings that match the range are part of the same
|
||||||
|
// import declaration.
|
||||||
|
|
||||||
|
if (declRange && declRange.singleDeclaration) {
|
||||||
|
// match the import declaration location
|
||||||
|
genContent = await (0, _findGeneratedBindingFromPosition.findGeneratedBindingForImportDeclaration)(sourceMaps, client, source, pos, name, originalBinding.type, generatedAstBindings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (genContent) {
|
if (genContent) {
|
||||||
|
|
|
@ -16,4 +16,5 @@ DevToolsModules(
|
||||||
'locColumn.js',
|
'locColumn.js',
|
||||||
'mappingContains.js',
|
'mappingContains.js',
|
||||||
'positionCmp.js',
|
'positionCmp.js',
|
||||||
|
'rangeMetadata.js',
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.loadRangeMetadata = loadRangeMetadata;
|
||||||
|
exports.findMatchingRange = findMatchingRange;
|
||||||
|
|
||||||
|
var _locColumn = require("./locColumn");
|
||||||
|
|
||||||
|
var _positionCmp = require("./positionCmp");
|
||||||
|
|
||||||
|
var _filtering = require("./filtering");
|
||||||
|
|
||||||
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
|
||||||
|
|
||||||
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||||
|
|
||||||
|
async function loadRangeMetadata(source, frame, originalAstScopes, sourceMaps) {
|
||||||
|
const originalRanges = await sourceMaps.getOriginalRanges(frame.location.sourceId, source.url);
|
||||||
|
const sortedOriginalAstBindings = [];
|
||||||
|
|
||||||
|
for (const item of originalAstScopes) {
|
||||||
|
for (const name of Object.keys(item.bindings)) {
|
||||||
|
for (const ref of item.bindings[name].refs) {
|
||||||
|
sortedOriginalAstBindings.push(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sortedOriginalAstBindings.sort((a, b) => (0, _positionCmp.positionCmp)(a.start, b.start));
|
||||||
|
let i = 0;
|
||||||
|
return originalRanges.map(range => {
|
||||||
|
const bindings = [];
|
||||||
|
|
||||||
|
while (i < sortedOriginalAstBindings.length && (sortedOriginalAstBindings[i].start.line < range.line || sortedOriginalAstBindings[i].start.line === range.line && (0, _locColumn.locColumn)(sortedOriginalAstBindings[i].start) < range.columnStart)) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < sortedOriginalAstBindings.length && sortedOriginalAstBindings[i].start.line === range.line && (0, _locColumn.locColumn)(sortedOriginalAstBindings[i].start) >= range.columnStart && (0, _locColumn.locColumn)(sortedOriginalAstBindings[i].start) < range.columnEnd) {
|
||||||
|
bindings.push(sortedOriginalAstBindings[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
let type = "empty";
|
||||||
|
let singleDeclaration = true;
|
||||||
|
|
||||||
|
if (bindings.length === 1) {
|
||||||
|
const binding = bindings[0];
|
||||||
|
|
||||||
|
if (binding.start.line === range.line && binding.start.column === range.columnStart) {
|
||||||
|
type = "match";
|
||||||
|
} else {
|
||||||
|
type = "contains";
|
||||||
|
}
|
||||||
|
} else if (bindings.length > 1) {
|
||||||
|
type = "multiple";
|
||||||
|
const binding = bindings[0];
|
||||||
|
const declStart = binding.type !== "ref" ? binding.declaration.start : null;
|
||||||
|
singleDeclaration = bindings.every(b => {
|
||||||
|
return declStart && b.type !== "ref" && (0, _positionCmp.positionCmp)(declStart, b.declaration.start) === 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return _objectSpread({
|
||||||
|
type,
|
||||||
|
singleDeclaration
|
||||||
|
}, range);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function findMatchingRange(sortedOriginalRanges, bindingRange) {
|
||||||
|
return (0, _filtering.filterSortedArray)(sortedOriginalRanges, range => {
|
||||||
|
if (range.line < bindingRange.start.line) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (range.line > bindingRange.start.line) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (range.columnEnd <= (0, _locColumn.locColumn)(bindingRange.start)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (range.columnStart > (0, _locColumn.locColumn)(bindingRange.start)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}).pop();
|
||||||
|
}
|
|
@ -466,5 +466,5 @@ function getSourceClassnames(source, sourceMetaData) {
|
||||||
return "blackBox";
|
return "blackBox";
|
||||||
}
|
}
|
||||||
|
|
||||||
return sourceTypes[(0, _sourcesTree.getExtension)(source)] || defaultClassName;
|
return sourceTypes[(0, _sourcesTree.getExtension)(source.url)] || defaultClassName;
|
||||||
}
|
}
|
|
@ -47,8 +47,7 @@ function isDirectory(url) {
|
||||||
return (parts.length === 0 || url.path.slice(-1) === "/" || nodeHasChildren(url)) && url.name != "(index)";
|
return (parts.length === 0 || url.path.slice(-1) === "/" || nodeHasChildren(url)) && url.name != "(index)";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExtension(source) {
|
function getExtension(url = "") {
|
||||||
const url = source.get ? source.get("url") : source.url;
|
|
||||||
const parsedUrl = (0, _url.parse)(url).pathname;
|
const parsedUrl = (0, _url.parse)(url).pathname;
|
||||||
|
|
||||||
if (!parsedUrl) {
|
if (!parsedUrl) {
|
||||||
|
@ -59,7 +58,7 @@ function getExtension(source) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function isNotJavaScript(source) {
|
function isNotJavaScript(source) {
|
||||||
return ["css", "svg", "png"].includes(getExtension(source));
|
return ["css", "svg", "png"].includes(getExtension(source.url));
|
||||||
}
|
}
|
||||||
|
|
||||||
function isInvalidUrl(url, source) {
|
function isInvalidUrl(url, source) {
|
||||||
|
|
|
@ -1,167 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", {
|
|
||||||
value: true
|
|
||||||
});
|
|
||||||
exports.getHistory = exports.waitForState = exports.makeSymbolDeclaration = exports.makeSourceRecord = exports.makeOriginalSource = exports.makeSource = exports.makeFrame = exports.commonLog = exports.createStore = exports.reducers = exports.selectors = exports.actions = undefined;
|
|
||||||
|
|
||||||
var _redux = require("devtools/client/shared/vendor/redux");
|
|
||||||
|
|
||||||
var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
|
|
||||||
|
|
||||||
var _devtoolsSourceMap2 = _interopRequireDefault(_devtoolsSourceMap);
|
|
||||||
|
|
||||||
var _reducers = require("../reducers/index");
|
|
||||||
|
|
||||||
var _reducers2 = _interopRequireDefault(_reducers);
|
|
||||||
|
|
||||||
var _actions = require("../actions/index");
|
|
||||||
|
|
||||||
var _actions2 = _interopRequireDefault(_actions);
|
|
||||||
|
|
||||||
var _selectors = require("../selectors/index");
|
|
||||||
|
|
||||||
var selectors = _interopRequireWildcard(_selectors);
|
|
||||||
|
|
||||||
var _history = require("../test/utils/history");
|
|
||||||
|
|
||||||
var _createStore = require("../actions/utils/create-store");
|
|
||||||
|
|
||||||
var _createStore2 = _interopRequireDefault(_createStore);
|
|
||||||
|
|
||||||
var _immutable = require("devtools/client/shared/vendor/immutable");
|
|
||||||
|
|
||||||
var I = _interopRequireWildcard(_immutable);
|
|
||||||
|
|
||||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
|
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
||||||
|
|
||||||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
|
|
||||||
|
|
||||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @memberof utils/test-head
|
|
||||||
* @static
|
|
||||||
*/
|
|
||||||
function createStore(client, initialState = {}, sourceMapsMock) {
|
|
||||||
return (0, _createStore2.default)({
|
|
||||||
log: false,
|
|
||||||
history: (0, _history.getHistory)(),
|
|
||||||
makeThunkArgs: args => {
|
|
||||||
return _objectSpread({}, args, {
|
|
||||||
client,
|
|
||||||
sourceMaps: sourceMapsMock !== undefined ? sourceMapsMock : _devtoolsSourceMap2.default
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})((0, _redux.combineReducers)(_reducers2.default), initialState);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @memberof utils/test-head
|
|
||||||
* @static
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
function commonLog(msg, data = {}) {
|
|
||||||
console.log(`[INFO] ${msg} ${JSON.stringify(data)}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeFrame({
|
|
||||||
id,
|
|
||||||
sourceId
|
|
||||||
}, opts = {}) {
|
|
||||||
return _objectSpread({
|
|
||||||
id,
|
|
||||||
scope: [],
|
|
||||||
location: {
|
|
||||||
sourceId,
|
|
||||||
line: 4
|
|
||||||
}
|
|
||||||
}, opts);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @memberof utils/test-head
|
|
||||||
* @static
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
function makeSource(name, props = {}) {
|
|
||||||
return _objectSpread({
|
|
||||||
id: name,
|
|
||||||
loadedState: "unloaded",
|
|
||||||
url: `http://localhost:8000/examples/${name}`
|
|
||||||
}, props);
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeOriginalSource(name, props) {
|
|
||||||
const source = makeSource(name, props);
|
|
||||||
return _objectSpread({}, source, {
|
|
||||||
id: `${name}-original`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeSourceRecord(name, props = {}) {
|
|
||||||
return I.Map(makeSource(name, props));
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeFuncLocation(startLine, endLine) {
|
|
||||||
if (!endLine) {
|
|
||||||
endLine = startLine + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
start: {
|
|
||||||
line: startLine
|
|
||||||
},
|
|
||||||
end: {
|
|
||||||
line: endLine
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeSymbolDeclaration(name, start, end, klass) {
|
|
||||||
return {
|
|
||||||
id: `${name}:${start}`,
|
|
||||||
name,
|
|
||||||
location: makeFuncLocation(start, end),
|
|
||||||
klass
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @memberof utils/test-head
|
|
||||||
* @static
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
function waitForState(store, predicate) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
let ret = predicate(store.getState());
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
resolve(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsubscribe = store.subscribe(() => {
|
|
||||||
ret = predicate(store.getState());
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
unsubscribe();
|
|
||||||
resolve(ret);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.actions = _actions2.default;
|
|
||||||
exports.selectors = selectors;
|
|
||||||
exports.reducers = _reducers2.default;
|
|
||||||
exports.createStore = createStore;
|
|
||||||
exports.commonLog = commonLog;
|
|
||||||
exports.makeFrame = makeFrame;
|
|
||||||
exports.makeSource = makeSource;
|
|
||||||
exports.makeOriginalSource = makeOriginalSource;
|
|
||||||
exports.makeSourceRecord = makeSourceRecord;
|
|
||||||
exports.makeSymbolDeclaration = makeSymbolDeclaration;
|
|
||||||
exports.waitForState = waitForState;
|
|
||||||
exports.getHistory = _history.getHistory;
|
|
|
@ -3,7 +3,7 @@
|
||||||
Object.defineProperty(exports, "__esModule", {
|
Object.defineProperty(exports, "__esModule", {
|
||||||
value: true
|
value: true
|
||||||
});
|
});
|
||||||
exports.formatKeyShortcut = undefined;
|
exports.truncateMiddleText = exports.formatKeyShortcut = undefined;
|
||||||
|
|
||||||
var _devtoolsModules = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-modules"];
|
var _devtoolsModules = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-modules"];
|
||||||
|
|
||||||
|
@ -40,5 +40,26 @@ function formatKeyShortcut(shortcut) {
|
||||||
|
|
||||||
return shortcut.replace(/CommandOrControl\+|CmdOrCtrl\+/g, `${L10N.getStr("ctrl")} `).replace(/Shift\+/g, "Shift ");
|
return shortcut.replace(/CommandOrControl\+|CmdOrCtrl\+/g, `${L10N.getStr("ctrl")} `).replace(/Shift\+/g, "Shift ");
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Truncates the received text to the maxLength in the format:
|
||||||
|
* Original: 'this is a very long text and ends here'
|
||||||
|
* Truncated: 'this is a ver...and ends here'
|
||||||
|
* @param {String} sourceText - Source text
|
||||||
|
* @param {Number} maxLength - Max allowed length
|
||||||
|
* @memberof utils/text
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
|
||||||
exports.formatKeyShortcut = formatKeyShortcut;
|
|
||||||
|
function truncateMiddleText(sourceText, maxLength) {
|
||||||
|
let truncatedText = sourceText;
|
||||||
|
|
||||||
|
if (sourceText.length > maxLength) {
|
||||||
|
truncatedText = `${sourceText.substring(0, Math.round(maxLength / 2) - 2)}...${sourceText.substring(sourceText.length - Math.round(maxLength / 2 - 1))}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return truncatedText;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.formatKeyShortcut = formatKeyShortcut;
|
||||||
|
exports.truncateMiddleText = truncateMiddleText;
|
|
@ -89,7 +89,7 @@ function toParsedScopes(children, sourceId) {
|
||||||
return {
|
return {
|
||||||
start: scope.loc.start,
|
start: scope.loc.start,
|
||||||
end: scope.loc.end,
|
end: scope.loc.end,
|
||||||
type: scope.type === "module" ? "block" : scope.type,
|
type: scope.type === "module" || scope.type === "function-body" ? "block" : scope.type,
|
||||||
displayName: scope.displayName,
|
displayName: scope.displayName,
|
||||||
bindings: scope.bindings,
|
bindings: scope.bindings,
|
||||||
children: toParsedScopes(scope.children, sourceId)
|
children: toParsedScopes(scope.children, sourceId)
|
||||||
|
@ -190,10 +190,20 @@ function isLetOrConst(node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasLexicalDeclaration(node, parent) {
|
function hasLexicalDeclaration(node, parent) {
|
||||||
|
const nodes = [];
|
||||||
|
|
||||||
|
if (t.isSwitchStatement(node)) {
|
||||||
|
for (const caseNode of node.cases) {
|
||||||
|
nodes.push(...caseNode.consequent);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nodes.push(...node.body);
|
||||||
|
}
|
||||||
|
|
||||||
const isFunctionBody = t.isFunction(parent, {
|
const isFunctionBody = t.isFunction(parent, {
|
||||||
body: node
|
body: node
|
||||||
});
|
});
|
||||||
return node.body.some(child => isLexicalVariable(child) || !isFunctionBody && child.type === "FunctionDeclaration" || child.type === "ClassDeclaration");
|
return nodes.some(child => isLexicalVariable(child) || t.isClassDeclaration(child) || !isFunctionBody && t.isFunctionDeclaration(child));
|
||||||
}
|
}
|
||||||
|
|
||||||
function isLexicalVariable(node) {
|
function isLexicalVariable(node) {
|
||||||
|
@ -257,19 +267,27 @@ const scopeCollectionVisitor = {
|
||||||
// This ignores Annex B function declaration hoisting, which
|
// This ignores Annex B function declaration hoisting, which
|
||||||
// is probably a fine assumption.
|
// is probably a fine assumption.
|
||||||
state.declarationBindingIds.add(node.id);
|
state.declarationBindingIds.add(node.id);
|
||||||
const fnScope = getVarScope(scope);
|
const refs = [{
|
||||||
scope.bindings[node.id.name] = {
|
type: "fn-decl",
|
||||||
type: fnScope === scope ? "var" : "let",
|
start: fromBabelLocation(node.id.loc.start, state.sourceId),
|
||||||
refs: [{
|
end: fromBabelLocation(node.id.loc.end, state.sourceId),
|
||||||
type: "fn-decl",
|
declaration: {
|
||||||
start: fromBabelLocation(node.id.loc.start, state.sourceId),
|
start: fromBabelLocation(node.loc.start, state.sourceId),
|
||||||
end: fromBabelLocation(node.id.loc.end, state.sourceId),
|
end: fromBabelLocation(node.loc.end, state.sourceId)
|
||||||
declaration: {
|
}
|
||||||
start: fromBabelLocation(node.loc.start, state.sourceId),
|
}];
|
||||||
end: fromBabelLocation(node.loc.end, state.sourceId)
|
|
||||||
}
|
if (scope.type === "block") {
|
||||||
}]
|
scope.bindings[node.id.name] = {
|
||||||
};
|
type: "let",
|
||||||
|
refs
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
getVarScope(scope).bindings[node.id.name] = {
|
||||||
|
type: "var",
|
||||||
|
refs
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scope = pushTempScope(state, "function", (0, _getFunctionName2.default)(node, parentNode), {
|
scope = pushTempScope(state, "function", (0, _getFunctionName2.default)(node, parentNode), {
|
||||||
|
@ -290,6 +308,13 @@ const scopeCollectionVisitor = {
|
||||||
refs: []
|
refs: []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t.isBlockStatement(node.body) && hasLexicalDeclaration(node.body, node)) {
|
||||||
|
scope = pushTempScope(state, "function-body", "Function Body", {
|
||||||
|
start: fromBabelLocation(node.body.loc.start, state.sourceId),
|
||||||
|
end: fromBabelLocation(node.body.loc.end, state.sourceId)
|
||||||
|
});
|
||||||
|
}
|
||||||
} else if (t.isClass(node)) {
|
} else if (t.isClass(node)) {
|
||||||
if (t.isIdentifier(node.id)) {
|
if (t.isIdentifier(node.id)) {
|
||||||
// For decorated classes, the AST considers the first the decorator
|
// For decorated classes, the AST considers the first the decorator
|
||||||
|
@ -359,7 +384,8 @@ const scopeCollectionVisitor = {
|
||||||
end: fromBabelLocation(node.loc.end, state.sourceId)
|
end: fromBabelLocation(node.loc.end, state.sourceId)
|
||||||
});
|
});
|
||||||
parseDeclarator(node.param, scope, "var", "catch", node, state);
|
parseDeclarator(node.param, scope, "var", "catch", node, state);
|
||||||
} else if (t.isBlockStatement(node) && hasLexicalDeclaration(node, parentNode)) {
|
} else if (t.isBlockStatement(node) && // Function body's are handled in the function logic above.
|
||||||
|
!t.isFunction(parentNode) && hasLexicalDeclaration(node, parentNode)) {
|
||||||
// Debugger will create new lexical environment for the block.
|
// Debugger will create new lexical environment for the block.
|
||||||
pushTempScope(state, "block", "Block", {
|
pushTempScope(state, "block", "Block", {
|
||||||
start: fromBabelLocation(node.loc.start, state.sourceId),
|
start: fromBabelLocation(node.loc.start, state.sourceId),
|
||||||
|
@ -489,7 +515,7 @@ const scopeCollectionVisitor = {
|
||||||
type: "implicit",
|
type: "implicit",
|
||||||
refs: []
|
refs: []
|
||||||
};
|
};
|
||||||
} else if (t.isSwitchStatement(node) && node.cases.some(caseNode => caseNode.consequent.some(child => isLexicalVariable(child)))) {
|
} else if (t.isSwitchStatement(node) && hasLexicalDeclaration(node, parentNode)) {
|
||||||
pushTempScope(state, "block", "Switch", {
|
pushTempScope(state, "block", "Switch", {
|
||||||
start: fromBabelLocation(node.loc.start, state.sourceId),
|
start: fromBabelLocation(node.loc.start, state.sourceId),
|
||||||
end: fromBabelLocation(node.loc.end, state.sourceId)
|
end: fromBabelLocation(node.loc.end, state.sourceId)
|
||||||
|
|
|
@ -31,6 +31,8 @@ support-files =
|
||||||
examples/sourcemapped/fixtures/babel-for-loops/output.js.map
|
examples/sourcemapped/fixtures/babel-for-loops/output.js.map
|
||||||
examples/sourcemapped/fixtures/babel-functions/output.js
|
examples/sourcemapped/fixtures/babel-functions/output.js
|
||||||
examples/sourcemapped/fixtures/babel-functions/output.js.map
|
examples/sourcemapped/fixtures/babel-functions/output.js.map
|
||||||
|
examples/sourcemapped/fixtures/babel-lex-and-nonlex/output.js
|
||||||
|
examples/sourcemapped/fixtures/babel-lex-and-nonlex/output.js.map
|
||||||
examples/sourcemapped/fixtures/babel-type-module/output.js
|
examples/sourcemapped/fixtures/babel-type-module/output.js
|
||||||
examples/sourcemapped/fixtures/babel-type-module/output.js.map
|
examples/sourcemapped/fixtures/babel-type-module/output.js.map
|
||||||
examples/sourcemapped/fixtures/babel-type-script/output.js
|
examples/sourcemapped/fixtures/babel-type-script/output.js
|
||||||
|
|
|
@ -25,7 +25,7 @@ add_task(async function() {
|
||||||
let onPaused = waitForPaused(dbg);
|
let onPaused = waitForPaused(dbg);
|
||||||
invokeInTab("mutate");
|
invokeInTab("mutate");
|
||||||
await onPaused;
|
await onPaused;
|
||||||
await waitForLoadedSource(dbg, "script-mutate");
|
await waitForSelectedSource(dbg, "script-mutate");
|
||||||
|
|
||||||
is(
|
is(
|
||||||
getScopeNodeLabel(dbg, 2),
|
getScopeNodeLabel(dbg, 2),
|
||||||
|
|
|
@ -46,7 +46,7 @@ add_task(async function() {
|
||||||
"Block",
|
"Block",
|
||||||
["three", "5"],
|
["three", "5"],
|
||||||
["two", "4"],
|
["two", "4"],
|
||||||
"Block",
|
"Function Body",
|
||||||
["three", "3"],
|
["three", "3"],
|
||||||
["two", "2"],
|
["two", "2"],
|
||||||
"root",
|
"root",
|
||||||
|
@ -73,7 +73,7 @@ add_task(async function() {
|
||||||
["aConst", '"const2"'],
|
["aConst", '"const2"'],
|
||||||
["aLet", '"let2"'],
|
["aLet", '"let2"'],
|
||||||
"Outer:_Outer()",
|
"Outer:_Outer()",
|
||||||
"Block",
|
"Function Body",
|
||||||
["aConst", '"const1"'],
|
["aConst", '"const1"'],
|
||||||
["aLet", '"let1"'],
|
["aLet", '"let1"'],
|
||||||
"Outer()",
|
"Outer()",
|
||||||
|
@ -86,7 +86,7 @@ add_task(async function() {
|
||||||
"babel-line-start-bindings-es6",
|
"babel-line-start-bindings-es6",
|
||||||
{ line: 19, column: 4 },
|
{ line: 19, column: 4 },
|
||||||
[
|
[
|
||||||
"Block",
|
"Function Body",
|
||||||
["<this>", "{\u2026}"],
|
["<this>", "{\u2026}"],
|
||||||
["one", "1"],
|
["one", "1"],
|
||||||
["two", "2"],
|
["two", "2"],
|
||||||
|
@ -102,7 +102,7 @@ add_task(async function() {
|
||||||
"babel-this-arguments-bindings",
|
"babel-this-arguments-bindings",
|
||||||
{ line: 4, column: 4 },
|
{ line: 4, column: 4 },
|
||||||
[
|
[
|
||||||
"Block",
|
"Function Body",
|
||||||
["<this>", '"this-value"'],
|
["<this>", '"this-value"'],
|
||||||
["arrow", "undefined"],
|
["arrow", "undefined"],
|
||||||
"fn",
|
"fn",
|
||||||
|
@ -123,7 +123,7 @@ add_task(async function() {
|
||||||
"arrow",
|
"arrow",
|
||||||
["<this>", '"this-value"'],
|
["<this>", '"this-value"'],
|
||||||
["argArrow", '"arrow-arg"'],
|
["argArrow", '"arrow-arg"'],
|
||||||
"Block",
|
"Function Body",
|
||||||
"arrow()",
|
"arrow()",
|
||||||
"fn",
|
"fn",
|
||||||
["arg", '"arg-value"'],
|
["arg", '"arg-value"'],
|
||||||
|
@ -158,12 +158,12 @@ add_task(async function() {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await breakpointScopes(dbg, "babel-classes", { line: 12, column: 6 }, [
|
await breakpointScopes(dbg, "babel-classes", { line: 12, column: 6 }, [
|
||||||
"Block",
|
"Function Body",
|
||||||
["three", "3"],
|
["three", "3"],
|
||||||
["two", "2"],
|
["two", "2"],
|
||||||
"Class",
|
"Class",
|
||||||
"Another()",
|
"Another()",
|
||||||
"Block",
|
"Function Body",
|
||||||
"Another()",
|
"Another()",
|
||||||
["one", "1"],
|
["one", "1"],
|
||||||
"Thing()",
|
"Thing()",
|
||||||
|
@ -174,7 +174,7 @@ add_task(async function() {
|
||||||
await breakpointScopes(dbg, "babel-for-loops", { line: 5, column: 4 }, [
|
await breakpointScopes(dbg, "babel-for-loops", { line: 5, column: 4 }, [
|
||||||
"For",
|
"For",
|
||||||
["i", "1"],
|
["i", "1"],
|
||||||
"Block",
|
"Function Body",
|
||||||
["i", "0"],
|
["i", "0"],
|
||||||
"Module",
|
"Module",
|
||||||
"root()"
|
"root()"
|
||||||
|
@ -183,7 +183,7 @@ add_task(async function() {
|
||||||
await breakpointScopes(dbg, "babel-for-loops", { line: 9, column: 4 }, [
|
await breakpointScopes(dbg, "babel-for-loops", { line: 9, column: 4 }, [
|
||||||
"For",
|
"For",
|
||||||
["i", '"2"'],
|
["i", '"2"'],
|
||||||
"Block",
|
"Function Body",
|
||||||
["i", "0"],
|
["i", "0"],
|
||||||
"Module",
|
"Module",
|
||||||
"root()"
|
"root()"
|
||||||
|
@ -192,7 +192,7 @@ add_task(async function() {
|
||||||
await breakpointScopes(dbg, "babel-for-loops", { line: 13, column: 4 }, [
|
await breakpointScopes(dbg, "babel-for-loops", { line: 13, column: 4 }, [
|
||||||
"For",
|
"For",
|
||||||
["i", "3"],
|
["i", "3"],
|
||||||
"Block",
|
"Function Body",
|
||||||
["i", "0"],
|
["i", "0"],
|
||||||
"Module",
|
"Module",
|
||||||
"root()"
|
"root()"
|
||||||
|
@ -201,13 +201,13 @@ add_task(async function() {
|
||||||
await breakpointScopes(dbg, "babel-functions", { line: 6, column: 8 }, [
|
await breakpointScopes(dbg, "babel-functions", { line: 6, column: 8 }, [
|
||||||
"arrow",
|
"arrow",
|
||||||
["p3", "undefined"],
|
["p3", "undefined"],
|
||||||
"Block",
|
"Function Body",
|
||||||
"arrow()",
|
"arrow()",
|
||||||
"inner",
|
"inner",
|
||||||
["p2", "undefined"],
|
["p2", "undefined"],
|
||||||
"Function Expression",
|
"Function Expression",
|
||||||
"inner()",
|
"inner()",
|
||||||
"Block",
|
"Function Body",
|
||||||
"inner()",
|
"inner()",
|
||||||
"decl",
|
"decl",
|
||||||
["p1", "undefined"],
|
["p1", "undefined"],
|
||||||
|
@ -268,7 +268,7 @@ add_task(async function() {
|
||||||
await breakpointScopes(dbg, "babel-switches", { line: 7, column: 6 }, [
|
await breakpointScopes(dbg, "babel-switches", { line: 7, column: 6 }, [
|
||||||
"Switch",
|
"Switch",
|
||||||
["val", "2"],
|
["val", "2"],
|
||||||
"Block",
|
"Function Body",
|
||||||
["val", "1"],
|
["val", "1"],
|
||||||
"Module",
|
"Module",
|
||||||
"root()"
|
"root()"
|
||||||
|
@ -279,7 +279,7 @@ add_task(async function() {
|
||||||
["val", "3"],
|
["val", "3"],
|
||||||
"Switch",
|
"Switch",
|
||||||
["val", "2"],
|
["val", "2"],
|
||||||
"Block",
|
"Function Body",
|
||||||
["val", "1"],
|
["val", "1"],
|
||||||
"Module",
|
"Module",
|
||||||
"root()"
|
"root()"
|
||||||
|
@ -290,12 +290,21 @@ add_task(async function() {
|
||||||
["two", "2"],
|
["two", "2"],
|
||||||
"Catch",
|
"Catch",
|
||||||
["err", '"AnError"'],
|
["err", '"AnError"'],
|
||||||
"Block",
|
"Function Body",
|
||||||
["one", "1"],
|
["one", "1"],
|
||||||
"Module",
|
"Module",
|
||||||
"root()"
|
"root()"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
await breakpointScopes(dbg, "babel-lex-and-nonlex", { line: 3, column: 4 }, [
|
||||||
|
"Function Body",
|
||||||
|
"Thing()",
|
||||||
|
"root",
|
||||||
|
"someHelper()",
|
||||||
|
"Module",
|
||||||
|
"root()"
|
||||||
|
]);
|
||||||
|
|
||||||
await breakpointScopes(
|
await breakpointScopes(
|
||||||
dbg,
|
dbg,
|
||||||
"babel-modules-webpack",
|
"babel-modules-webpack",
|
||||||
|
|
|
@ -40,7 +40,7 @@ add_task(async function() {
|
||||||
is(getScopeLabel(dbg, 2), "na");
|
is(getScopeLabel(dbg, 2), "na");
|
||||||
is(getScopeLabel(dbg, 3), "nb");
|
is(getScopeLabel(dbg, 3), "nb");
|
||||||
|
|
||||||
is(getScopeLabel(dbg, 4), "Block");
|
is(getScopeLabel(dbg, 4), "Function Body");
|
||||||
|
|
||||||
await toggleScopeNode(dbg, 4);
|
await toggleScopeNode(dbg, 4);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
<button onclick="babelForOf()">Run babel-for-of</button>
|
<button onclick="babelForOf()">Run babel-for-of</button>
|
||||||
<script src="sourcemapped/fixtures/babel-functions/output.js"></script>
|
<script src="sourcemapped/fixtures/babel-functions/output.js"></script>
|
||||||
<button onclick="babelFunctions()">Run babel-functions</button>
|
<button onclick="babelFunctions()">Run babel-functions</button>
|
||||||
|
<script src="sourcemapped/fixtures/babel-lex-and-nonlex/output.js"></script>
|
||||||
|
<button onclick="babelLexAndNonlex()">Run babel-lex-and-nonlex</button>
|
||||||
<script src="sourcemapped/fixtures/babel-line-start-bindings-es6/output.js"></script>
|
<script src="sourcemapped/fixtures/babel-line-start-bindings-es6/output.js"></script>
|
||||||
<button onclick="babelLineStartBindingsEs6()">Run babel-line-start-bindings-es6</button>
|
<button onclick="babelLineStartBindingsEs6()">Run babel-line-start-bindings-es6</button>
|
||||||
<script src="sourcemapped/fixtures/babel-modules-cjs/output.js"></script>
|
<script src="sourcemapped/fixtures/babel-modules-cjs/output.js"></script>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
export default function root() {
|
||||||
|
function someHelper(){
|
||||||
|
console.log("pause here", root, Thing);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Thing {}
|
||||||
|
|
||||||
|
someHelper();
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
var babelLexAndNonlex =
|
||||||
|
/******/ (function(modules) { // webpackBootstrap
|
||||||
|
/******/ // The module cache
|
||||||
|
/******/ var installedModules = {};
|
||||||
|
/******/
|
||||||
|
/******/ // The require function
|
||||||
|
/******/ function __webpack_require__(moduleId) {
|
||||||
|
/******/
|
||||||
|
/******/ // Check if module is in cache
|
||||||
|
/******/ if(installedModules[moduleId]) {
|
||||||
|
/******/ return installedModules[moduleId].exports;
|
||||||
|
/******/ }
|
||||||
|
/******/ // Create a new module (and put it into the cache)
|
||||||
|
/******/ var module = installedModules[moduleId] = {
|
||||||
|
/******/ i: moduleId,
|
||||||
|
/******/ l: false,
|
||||||
|
/******/ exports: {}
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // Execute the module function
|
||||||
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||||
|
/******/
|
||||||
|
/******/ // Flag the module as loaded
|
||||||
|
/******/ module.l = true;
|
||||||
|
/******/
|
||||||
|
/******/ // Return the exports of the module
|
||||||
|
/******/ return module.exports;
|
||||||
|
/******/ }
|
||||||
|
/******/
|
||||||
|
/******/
|
||||||
|
/******/ // expose the modules object (__webpack_modules__)
|
||||||
|
/******/ __webpack_require__.m = modules;
|
||||||
|
/******/
|
||||||
|
/******/ // expose the module cache
|
||||||
|
/******/ __webpack_require__.c = installedModules;
|
||||||
|
/******/
|
||||||
|
/******/ // define getter function for harmony exports
|
||||||
|
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||||
|
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||||
|
/******/ Object.defineProperty(exports, name, {
|
||||||
|
/******/ configurable: false,
|
||||||
|
/******/ enumerable: true,
|
||||||
|
/******/ get: getter
|
||||||
|
/******/ });
|
||||||
|
/******/ }
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||||
|
/******/ __webpack_require__.n = function(module) {
|
||||||
|
/******/ var getter = module && module.__esModule ?
|
||||||
|
/******/ function getDefault() { return module['default']; } :
|
||||||
|
/******/ function getModuleExports() { return module; };
|
||||||
|
/******/ __webpack_require__.d(getter, 'a', getter);
|
||||||
|
/******/ return getter;
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // Object.prototype.hasOwnProperty.call
|
||||||
|
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||||||
|
/******/
|
||||||
|
/******/ // __webpack_public_path__
|
||||||
|
/******/ __webpack_require__.p = "";
|
||||||
|
/******/
|
||||||
|
/******/ // Load entry module and return exports
|
||||||
|
/******/ return __webpack_require__(__webpack_require__.s = 0);
|
||||||
|
/******/ })
|
||||||
|
/************************************************************************/
|
||||||
|
/******/ ([
|
||||||
|
/* 0 */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
||||||
|
/* harmony export (immutable) */ __webpack_exports__["default"] = root;
|
||||||
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||||
|
|
||||||
|
function root() {
|
||||||
|
function someHelper() {
|
||||||
|
console.log("pause here", root, Thing);
|
||||||
|
}
|
||||||
|
|
||||||
|
var Thing = function Thing() {
|
||||||
|
_classCallCheck(this, Thing);
|
||||||
|
};
|
||||||
|
|
||||||
|
someHelper();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***/ })
|
||||||
|
/******/ ])["default"];
|
||||||
|
//# sourceMappingURL=output.js.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"sources":["webpack:///webpack/bootstrap 683415abc3361bb5ff85","webpack:///./fixtures/babel-lex-and-nonlex/input.js"],"names":["root","someHelper","console","log","Thing"],"mappings":";;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;;;;;;AC7De,SAASA,IAAT,GAAgB;AAC7B,WAASC,UAAT,GAAqB;AACnBC,YAAQC,GAAR,CAAY,YAAZ,EAA0BH,IAA1B,EAAgCI,KAAhC;AACD;;AAH4B,MAKvBA,KALuB;AAAA;AAAA;;AAO7BH;AACD,C","file":"fixtures/babel-lex-and-nonlex/output.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 683415abc3361bb5ff85","export default function root() {\n function someHelper(){\n console.log(\"pause here\", root, Thing);\n }\n\n class Thing {}\n\n someHelper();\n}\n\n\n\n// WEBPACK FOOTER //\n// ./fixtures/babel-lex-and-nonlex/input.js"],"sourceRoot":""}
|
|
@ -437,6 +437,7 @@ const {
|
||||||
const dispatcher = new WorkerDispatcher();
|
const dispatcher = new WorkerDispatcher();
|
||||||
|
|
||||||
const getOriginalURLs = dispatcher.task("getOriginalURLs");
|
const getOriginalURLs = dispatcher.task("getOriginalURLs");
|
||||||
|
const getOriginalRanges = dispatcher.task("getOriginalRanges");
|
||||||
const getGeneratedRanges = dispatcher.task("getGeneratedRanges", {
|
const getGeneratedRanges = dispatcher.task("getGeneratedRanges", {
|
||||||
queue: true
|
queue: true
|
||||||
});
|
});
|
||||||
|
@ -460,6 +461,7 @@ module.exports = {
|
||||||
isOriginalId,
|
isOriginalId,
|
||||||
hasMappedSource,
|
hasMappedSource,
|
||||||
getOriginalURLs,
|
getOriginalURLs,
|
||||||
|
getOriginalRanges,
|
||||||
getGeneratedRanges,
|
getGeneratedRanges,
|
||||||
getGeneratedLocation,
|
getGeneratedLocation,
|
||||||
getAllGeneratedLocations,
|
getAllGeneratedLocations,
|
||||||
|
|
|
@ -1973,6 +1973,7 @@ exports.ArraySet = ArraySet;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
getOriginalURLs,
|
getOriginalURLs,
|
||||||
|
getOriginalRanges,
|
||||||
getGeneratedRanges,
|
getGeneratedRanges,
|
||||||
getGeneratedLocation,
|
getGeneratedLocation,
|
||||||
getAllGeneratedLocations,
|
getAllGeneratedLocations,
|
||||||
|
@ -1993,6 +1994,7 @@ const {
|
||||||
// easier to unit test.
|
// easier to unit test.
|
||||||
self.onmessage = workerHandler({
|
self.onmessage = workerHandler({
|
||||||
getOriginalURLs,
|
getOriginalURLs,
|
||||||
|
getOriginalRanges,
|
||||||
getGeneratedRanges,
|
getGeneratedRanges,
|
||||||
getGeneratedLocation,
|
getGeneratedLocation,
|
||||||
getAllGeneratedLocations,
|
getAllGeneratedLocations,
|
||||||
|
@ -2046,6 +2048,57 @@ async function getOriginalURLs(generatedSource) {
|
||||||
|
|
||||||
const COMPUTED_SPANS = new WeakSet();
|
const COMPUTED_SPANS = new WeakSet();
|
||||||
|
|
||||||
|
const SOURCE_MAPPINGS = new WeakMap();
|
||||||
|
async function getOriginalRanges(sourceId, url) {
|
||||||
|
if (!isOriginalId(sourceId)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const generatedSourceId = originalToGeneratedId(sourceId);
|
||||||
|
const map = await getSourceMap(generatedSourceId);
|
||||||
|
if (!map) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
let mappings = SOURCE_MAPPINGS.get(map);
|
||||||
|
if (!mappings) {
|
||||||
|
mappings = new Map();
|
||||||
|
SOURCE_MAPPINGS.set(map, mappings);
|
||||||
|
}
|
||||||
|
|
||||||
|
let fileMappings = mappings.get(url);
|
||||||
|
if (!fileMappings) {
|
||||||
|
fileMappings = [];
|
||||||
|
mappings.set(url, fileMappings);
|
||||||
|
|
||||||
|
const originalMappings = fileMappings;
|
||||||
|
map.eachMapping(mapping => {
|
||||||
|
if (mapping.source !== url) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const last = originalMappings[originalMappings.length - 1];
|
||||||
|
|
||||||
|
if (last && last.line === mapping.originalLine) {
|
||||||
|
if (last.columnStart < mapping.originalColumn) {
|
||||||
|
last.columnEnd = mapping.originalColumn;
|
||||||
|
} else {
|
||||||
|
// Skip this duplicate original location,
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
originalMappings.push({
|
||||||
|
line: mapping.originalLine,
|
||||||
|
columnStart: mapping.originalColumn,
|
||||||
|
columnEnd: Infinity
|
||||||
|
});
|
||||||
|
}, null, SourceMapConsumer.ORIGINAL_ORDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileMappings;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an original location, find the ranges on the generated file that
|
* Given an original location, find the ranges on the generated file that
|
||||||
* are mapped from the original range containing the location.
|
* are mapped from the original range containing the location.
|
||||||
|
@ -2234,6 +2287,7 @@ function applySourceMap(generatedId, url, code, mappings) {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getOriginalURLs,
|
getOriginalURLs,
|
||||||
|
getOriginalRanges,
|
||||||
getGeneratedRanges,
|
getGeneratedRanges,
|
||||||
getGeneratedLocation,
|
getGeneratedLocation,
|
||||||
getAllGeneratedLocations,
|
getAllGeneratedLocations,
|
||||||
|
|
|
@ -956,7 +956,9 @@ var WasmDisassembler = /** @class */ (function () {
|
||||||
case 30 /* CODE_OPERATOR */:
|
case 30 /* CODE_OPERATOR */:
|
||||||
var operator = reader.result;
|
var operator = reader.result;
|
||||||
if (operator.code == 11 /* end */ && this._indentLevel == 0) {
|
if (operator.code == 11 /* end */ && this._indentLevel == 0) {
|
||||||
// reached of the function, skipping the operator
|
// reached of the function, closing function body
|
||||||
|
this.appendBuffer(" )");
|
||||||
|
this.newLine();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (operator.code) {
|
switch (operator.code) {
|
||||||
|
@ -980,8 +982,7 @@ var WasmDisassembler = /** @class */ (function () {
|
||||||
case 31 /* END_FUNCTION_BODY */:
|
case 31 /* END_FUNCTION_BODY */:
|
||||||
this._funcIndex++;
|
this._funcIndex++;
|
||||||
this._backrefLabels = null;
|
this._backrefLabels = null;
|
||||||
this.appendBuffer(" )");
|
// See case BinaryReaderState.CODE_OPERATOR for closing of body
|
||||||
this.newLine();
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error("Expectected state: " + reader.state);
|
throw new Error("Expectected state: " + reader.state);
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||||
|
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||||
|
|
||||||
|
(function(mod) {
|
||||||
|
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||||
|
mod(require("../../lib/codemirror"));
|
||||||
|
else if (typeof define == "function" && define.amd) // AMD
|
||||||
|
define(["../../lib/codemirror"], mod);
|
||||||
|
else // Plain browser env
|
||||||
|
mod(CodeMirror);
|
||||||
|
})(function(CodeMirror) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
CodeMirror.runMode = function(string, modespec, callback, options) {
|
||||||
|
var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
|
||||||
|
var ie = /MSIE \d/.test(navigator.userAgent);
|
||||||
|
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
|
||||||
|
|
||||||
|
if (callback.appendChild) {
|
||||||
|
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
|
||||||
|
var node = callback, col = 0;
|
||||||
|
node.innerHTML = "";
|
||||||
|
callback = function(text, style) {
|
||||||
|
if (text == "\n") {
|
||||||
|
// Emitting LF or CRLF on IE8 or earlier results in an incorrect display.
|
||||||
|
// Emitting a carriage return makes everything ok.
|
||||||
|
node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text));
|
||||||
|
col = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var content = "";
|
||||||
|
// replace tabs
|
||||||
|
for (var pos = 0;;) {
|
||||||
|
var idx = text.indexOf("\t", pos);
|
||||||
|
if (idx == -1) {
|
||||||
|
content += text.slice(pos);
|
||||||
|
col += text.length - pos;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
col += idx - pos;
|
||||||
|
content += text.slice(pos, idx);
|
||||||
|
var size = tabSize - col % tabSize;
|
||||||
|
col += size;
|
||||||
|
for (var i = 0; i < size; ++i) content += " ";
|
||||||
|
pos = idx + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (style) {
|
||||||
|
var sp = node.appendChild(document.createElement("span"));
|
||||||
|
sp.className = "cm-" + style.replace(/ +/g, " cm-");
|
||||||
|
sp.appendChild(document.createTextNode(content));
|
||||||
|
} else {
|
||||||
|
node.appendChild(document.createTextNode(content));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
|
||||||
|
for (var i = 0, e = lines.length; i < e; ++i) {
|
||||||
|
if (i) callback("\n");
|
||||||
|
var stream = new CodeMirror.StringStream(lines[i]);
|
||||||
|
if (!stream.string && mode.blankLine) mode.blankLine(state);
|
||||||
|
while (!stream.eol()) {
|
||||||
|
var style = mode.token(stream, state);
|
||||||
|
callback(stream.current(), style, i, stream.start, state);
|
||||||
|
stream.start = stream.pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -32,6 +32,7 @@ module.exports = [{
|
||||||
"./codemirror/addon/fold/comment-fold.js",
|
"./codemirror/addon/fold/comment-fold.js",
|
||||||
"./codemirror/addon/fold/xml-fold.js",
|
"./codemirror/addon/fold/xml-fold.js",
|
||||||
"./codemirror/addon/fold/foldgutter.js",
|
"./codemirror/addon/fold/foldgutter.js",
|
||||||
|
"./codemirror/addon/runmode/runmode.js",
|
||||||
"./codemirror/lib/codemirror.js",
|
"./codemirror/lib/codemirror.js",
|
||||||
],
|
],
|
||||||
output: {
|
output: {
|
||||||
|
|
|
@ -613,7 +613,7 @@ previewers.Object = [
|
||||||
isConnected: rawObj.isConnected === true,
|
isConnected: rawObj.isConnected === true,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (rawObj instanceof Ci.nsIDOMDocument && rawObj.location) {
|
if (rawObj.nodeType == rawObj.DOCUMENT_NODE && rawObj.location) {
|
||||||
preview.location = hooks.createValueGrip(rawObj.location.href);
|
preview.location = hooks.createValueGrip(rawObj.location.href);
|
||||||
} else if (obj.class == "DocumentFragment") {
|
} else if (obj.class == "DocumentFragment") {
|
||||||
preview.childNodesLength = rawObj.childNodes.length;
|
preview.childNodesLength = rawObj.childNodes.length;
|
||||||
|
|
|
@ -81,7 +81,6 @@
|
||||||
#include "nsIDocShellTreeOwner.h"
|
#include "nsIDocShellTreeOwner.h"
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
#include "nsIDocumentLoaderFactory.h"
|
#include "nsIDocumentLoaderFactory.h"
|
||||||
#include "nsIDOMDocument.h"
|
|
||||||
#include "nsIDOMNode.h"
|
#include "nsIDOMNode.h"
|
||||||
#include "nsIDOMStorage.h"
|
#include "nsIDOMStorage.h"
|
||||||
#include "nsIDOMWindow.h"
|
#include "nsIDOMWindow.h"
|
||||||
|
@ -552,12 +551,6 @@ nsDocShell::GetInterface(const nsIID& aIID, void** aSink)
|
||||||
aIID.Equals(NS_GET_IID(nsIDOMWindow))) &&
|
aIID.Equals(NS_GET_IID(nsIDOMWindow))) &&
|
||||||
NS_SUCCEEDED(EnsureScriptEnvironment())) {
|
NS_SUCCEEDED(EnsureScriptEnvironment())) {
|
||||||
return mScriptGlobal->QueryInterface(aIID, aSink);
|
return mScriptGlobal->QueryInterface(aIID, aSink);
|
||||||
} else if (aIID.Equals(NS_GET_IID(nsIDOMDocument)) &&
|
|
||||||
NS_SUCCEEDED(EnsureContentViewer())) {
|
|
||||||
nsCOMPtr<nsIDOMDocument> doc =
|
|
||||||
do_QueryInterface(mContentViewer->GetDocument());
|
|
||||||
doc.forget(aSink);
|
|
||||||
return *aSink ? NS_OK : NS_NOINTERFACE;
|
|
||||||
} else if (aIID.Equals(NS_GET_IID(nsIDocument)) &&
|
} else if (aIID.Equals(NS_GET_IID(nsIDocument)) &&
|
||||||
NS_SUCCEEDED(EnsureContentViewer())) {
|
NS_SUCCEEDED(EnsureContentViewer())) {
|
||||||
nsCOMPtr<nsIDocument> doc = mContentViewer->GetDocument();
|
nsCOMPtr<nsIDocument> doc = mContentViewer->GetDocument();
|
||||||
|
|
|
@ -1730,7 +1730,6 @@ NS_INTERFACE_TABLE_HEAD(nsDocument)
|
||||||
NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(nsDocument, nsISupports, nsINode)
|
NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(nsDocument, nsISupports, nsINode)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsINode)
|
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsINode)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDocument)
|
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDocument)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMDocument)
|
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMNode)
|
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMNode)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIScriptObjectPrincipal)
|
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIScriptObjectPrincipal)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, mozilla::dom::EventTarget)
|
NS_INTERFACE_TABLE_ENTRY(nsDocument, mozilla::dom::EventTarget)
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "nsWeakPtr.h"
|
#include "nsWeakPtr.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsIdentifierMapEntry.h"
|
#include "nsIdentifierMapEntry.h"
|
||||||
#include "nsIDOMDocument.h"
|
#include "nsIDOMNode.h"
|
||||||
#include "nsStubDocumentObserver.h"
|
#include "nsStubDocumentObserver.h"
|
||||||
#include "nsIScriptGlobalObject.h"
|
#include "nsIScriptGlobalObject.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
|
@ -130,7 +130,7 @@ private:
|
||||||
|
|
||||||
// Base class for our document implementations.
|
// Base class for our document implementations.
|
||||||
class nsDocument : public nsIDocument,
|
class nsDocument : public nsIDocument,
|
||||||
public nsIDOMDocument,
|
public nsIDOMNode,
|
||||||
public nsSupportsWeakReference,
|
public nsSupportsWeakReference,
|
||||||
public nsIScriptObjectPrincipal,
|
public nsIScriptObjectPrincipal,
|
||||||
public nsIRadioGroupContainer,
|
public nsIRadioGroupContainer,
|
||||||
|
|
|
@ -12,7 +12,6 @@ const nsIProperties = I.nsIProperties;
|
||||||
const nsIFileInputStream = I.nsIFileInputStream;
|
const nsIFileInputStream = I.nsIFileInputStream;
|
||||||
const nsIInputStream = I.nsIInputStream;
|
const nsIInputStream = I.nsIInputStream;
|
||||||
|
|
||||||
const nsIDOMDocument = I.nsIDOMDocument;
|
|
||||||
const nsIDOMNode = I.nsIDOMNode;
|
const nsIDOMNode = I.nsIDOMNode;
|
||||||
|
|
||||||
Cu.importGlobalProperties(["DOMParser", "Element", "XMLSerializer"]);
|
Cu.importGlobalProperties(["DOMParser", "Element", "XMLSerializer"]);
|
||||||
|
|
|
@ -177,7 +177,7 @@ function getParsedDocument(aPath) {
|
||||||
|
|
||||||
function processParsedDocument(doc) {
|
function processParsedDocument(doc) {
|
||||||
Assert.ok(doc.documentElement.localName != "parsererror");
|
Assert.ok(doc.documentElement.localName != "parsererror");
|
||||||
Assert.ok(doc instanceof Ci.nsIDOMDocument);
|
Assert.equal(ChromeUtils.getClassName(doc), "XMLDocument");
|
||||||
|
|
||||||
// Clean out whitespace.
|
// Clean out whitespace.
|
||||||
var walker = doc.createTreeWalker(doc,
|
var walker = doc.createTreeWalker(doc,
|
||||||
|
@ -447,7 +447,7 @@ function do_miscellaneous_tests(doc) {
|
||||||
|
|
||||||
// Requested by smaug: A range involving a comment as a document child.
|
// Requested by smaug: A range involving a comment as a document child.
|
||||||
doc = parser.parseFromString("<!-- foo --><foo/>", "application/xml");
|
doc = parser.parseFromString("<!-- foo --><foo/>", "application/xml");
|
||||||
Assert.ok(doc instanceof Ci.nsIDOMDocument);
|
Assert.equal(ChromeUtils.getClassName(doc), "XMLDocument");
|
||||||
Assert.equal(doc.childNodes.length, 2);
|
Assert.equal(doc.childNodes.length, 2);
|
||||||
baseRange = doc.createRange();
|
baseRange = doc.createRange();
|
||||||
baseRange.setStart(doc.firstChild, 1);
|
baseRange.setStart(doc.firstChild, 1);
|
||||||
|
|
|
@ -8,7 +8,7 @@ function run_test () {
|
||||||
|
|
||||||
var tests = [
|
var tests = [
|
||||||
[ test1, "Unable to parse basic XML document" ],
|
[ test1, "Unable to parse basic XML document" ],
|
||||||
[ test2, "ParseXML doesn't return nsIDOMDocument" ],
|
[ test2, "ParseXML doesn't return Document" ],
|
||||||
[ test3, "ParseXML return value's documentElement is not Element" ],
|
[ test3, "ParseXML return value's documentElement is not Element" ],
|
||||||
[ test4, "" ],
|
[ test4, "" ],
|
||||||
[ test5, "" ],
|
[ test5, "" ],
|
||||||
|
@ -21,7 +21,7 @@ function test1() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function test2() {
|
function test2() {
|
||||||
return (ParseXML("<root/>") instanceof nsIDOMDocument);
|
return (ChromeUtils.getClassName(ParseXML("<root/>")) === "XMLDocument");
|
||||||
}
|
}
|
||||||
|
|
||||||
function test3() {
|
function test3() {
|
||||||
|
|
|
@ -21,16 +21,11 @@ function ConsoleListener() {
|
||||||
ConsoleListener.prototype = {
|
ConsoleListener.prototype = {
|
||||||
observe(aSubject, aTopic, aData) {
|
observe(aSubject, aTopic, aData) {
|
||||||
let obj = aSubject.wrappedJSObject;
|
let obj = aSubject.wrappedJSObject;
|
||||||
if (obj.arguments[0] != 'test') {
|
if (obj.arguments[0] != "test_bug1463614") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._cb) {
|
if (!this._cb || !this._cb(obj)) {
|
||||||
ok(false, "Callback not set!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this._cb(obj)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,10 +52,10 @@ async function runTest() {
|
||||||
let cl = listener.waitFor(obj => {
|
let cl = listener.waitFor(obj => {
|
||||||
return ("timer" in obj) &&
|
return ("timer" in obj) &&
|
||||||
("name" in obj.timer) &&
|
("name" in obj.timer) &&
|
||||||
obj.timer.name == 'test';
|
obj.timer.name == "test_bug1463614";
|
||||||
});
|
});
|
||||||
|
|
||||||
console.time('test');
|
console.time("test_bug1463614");
|
||||||
await cl;
|
await cl;
|
||||||
ok(true, "Console.time received!");
|
ok(true, "Console.time received!");
|
||||||
|
|
||||||
|
@ -68,7 +63,7 @@ async function runTest() {
|
||||||
cl = listener.waitFor(obj => {
|
cl = listener.waitFor(obj => {
|
||||||
return ("timer" in obj) &&
|
return ("timer" in obj) &&
|
||||||
("name" in obj.timer) &&
|
("name" in obj.timer) &&
|
||||||
obj.timer.name == 'test' &&
|
obj.timer.name == "test_bug1463614" &&
|
||||||
("duration" in obj.timer) &&
|
("duration" in obj.timer) &&
|
||||||
obj.timer.duration >= 0 &&
|
obj.timer.duration >= 0 &&
|
||||||
obj.arguments[1] == 1 &&
|
obj.arguments[1] == 1 &&
|
||||||
|
@ -76,7 +71,7 @@ async function runTest() {
|
||||||
obj.arguments[3] == 3 &&
|
obj.arguments[3] == 3 &&
|
||||||
obj.arguments[4] == 4;
|
obj.arguments[4] == 4;
|
||||||
});
|
});
|
||||||
console.timeLog('test', 1, 2, 3, 4);
|
console.timeLog("test_bug1463614", 1, 2, 3, 4);
|
||||||
await cl;
|
await cl;
|
||||||
ok(true, "Console.timeLog received!");
|
ok(true, "Console.timeLog received!");
|
||||||
|
|
||||||
|
@ -84,11 +79,11 @@ async function runTest() {
|
||||||
cl = listener.waitFor(obj => {
|
cl = listener.waitFor(obj => {
|
||||||
return ("timer" in obj) &&
|
return ("timer" in obj) &&
|
||||||
("name" in obj.timer) &&
|
("name" in obj.timer) &&
|
||||||
obj.timer.name == 'test' &&
|
obj.timer.name == "test_bug1463614" &&
|
||||||
("duration" in obj.timer) &&
|
("duration" in obj.timer) &&
|
||||||
obj.timer.duration >= 0;
|
obj.timer.duration >= 0;
|
||||||
});
|
});
|
||||||
console.timeEnd('test');
|
console.timeEnd("test_bug1463614");
|
||||||
await cl;
|
await cl;
|
||||||
ok(true, "Console.timeEnd received!");
|
ok(true, "Console.timeEnd received!");
|
||||||
|
|
||||||
|
@ -96,10 +91,10 @@ async function runTest() {
|
||||||
cl = listener.waitFor(obj => {
|
cl = listener.waitFor(obj => {
|
||||||
return ("timer" in obj) &&
|
return ("timer" in obj) &&
|
||||||
("name" in obj.timer) &&
|
("name" in obj.timer) &&
|
||||||
obj.timer.name == 'test' &&
|
obj.timer.name == "test_bug1463614" &&
|
||||||
("error" in obj.timer);
|
("error" in obj.timer);
|
||||||
});
|
});
|
||||||
console.timeLog('test');
|
console.timeLog("test_bug1463614");
|
||||||
await cl;
|
await cl;
|
||||||
ok(true, "Console.time with error received!");
|
ok(true, "Console.time with error received!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,7 @@ NS_INTERFACE_MAP_BEGIN(IPCBlobInputStream)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIAsyncFileMetadata)
|
NS_INTERFACE_MAP_ENTRY(nsIAsyncFileMetadata)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIInputStreamLength)
|
NS_INTERFACE_MAP_ENTRY(nsIInputStreamLength)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIAsyncInputStreamLength)
|
NS_INTERFACE_MAP_ENTRY(nsIAsyncInputStreamLength)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIIPCBlobInputStream)
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,22 @@ namespace dom {
|
||||||
|
|
||||||
class IPCBlobInputStreamChild;
|
class IPCBlobInputStreamChild;
|
||||||
|
|
||||||
|
#define IPCBLOBINPUTSTREAM_IID \
|
||||||
|
{ 0xbcfa38fc, 0x8b7f, 0x4d79, \
|
||||||
|
{ 0xbe, 0x3a, 0x1e, 0x7b, 0xbe, 0x52, 0x38, 0xcd } }
|
||||||
|
|
||||||
|
class nsIIPCBlobInputStream : public nsISupports
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECLARE_STATIC_IID_ACCESSOR(IPCBLOBINPUTSTREAM_IID)
|
||||||
|
|
||||||
|
virtual nsIInputStream*
|
||||||
|
GetInternalStream() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsIIPCBlobInputStream,
|
||||||
|
IPCBLOBINPUTSTREAM_IID)
|
||||||
|
|
||||||
class IPCBlobInputStream final : public nsIAsyncInputStream
|
class IPCBlobInputStream final : public nsIAsyncInputStream
|
||||||
, public nsIInputStreamCallback
|
, public nsIInputStreamCallback
|
||||||
, public nsICloneableInputStreamWithRange
|
, public nsICloneableInputStreamWithRange
|
||||||
|
@ -27,6 +43,7 @@ class IPCBlobInputStream final : public nsIAsyncInputStream
|
||||||
, public nsIAsyncFileMetadata
|
, public nsIAsyncFileMetadata
|
||||||
, public nsIInputStreamLength
|
, public nsIInputStreamLength
|
||||||
, public nsIAsyncInputStreamLength
|
, public nsIAsyncInputStreamLength
|
||||||
|
, public nsIIPCBlobInputStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
|
@ -49,6 +66,21 @@ public:
|
||||||
void
|
void
|
||||||
LengthReady(int64_t aLength);
|
LengthReady(int64_t aLength);
|
||||||
|
|
||||||
|
// nsIIPCBlobInputStream
|
||||||
|
nsIInputStream*
|
||||||
|
GetInternalStream() const override
|
||||||
|
{
|
||||||
|
if (mRemoteStream) {
|
||||||
|
return mRemoteStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mAsyncRemoteStream) {
|
||||||
|
return mAsyncRemoteStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~IPCBlobInputStream();
|
~IPCBlobInputStream();
|
||||||
|
|
||||||
|
|
|
@ -89,10 +89,26 @@ SerializeInputStreamParent(nsIInputStream* aInputStream, uint64_t aSize,
|
||||||
// Parent to Child we always send a IPCBlobInputStream.
|
// Parent to Child we always send a IPCBlobInputStream.
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
|
|
||||||
|
nsCOMPtr<nsIInputStream> stream = aInputStream;
|
||||||
|
|
||||||
|
// In case this is a IPCBlobInputStream, we don't want to create a loop:
|
||||||
|
// IPCBlobInputStreamParent -> IPCBlobInputStream ->
|
||||||
|
// IPCBlobInputStreamParent. Let's use the underlying inputStream instead.
|
||||||
|
nsCOMPtr<nsIIPCBlobInputStream> ipcBlobInputStream =
|
||||||
|
do_QueryInterface(aInputStream);
|
||||||
|
if (ipcBlobInputStream) {
|
||||||
|
stream = ipcBlobInputStream->GetInternalStream();
|
||||||
|
// If we don't have an underlying stream, it's better to terminate here
|
||||||
|
// instead of sending an 'empty' IPCBlobInputStream actor on the other side,
|
||||||
|
// unable to be used.
|
||||||
|
if (NS_WARN_IF(!stream)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
RefPtr<IPCBlobInputStreamParent> parentActor =
|
RefPtr<IPCBlobInputStreamParent> parentActor =
|
||||||
IPCBlobInputStreamParent::Create(aInputStream, aSize, aChildID, &rv,
|
IPCBlobInputStreamParent::Create(stream, aSize, aChildID, &rv, aManager);
|
||||||
aManager);
|
|
||||||
if (!parentActor) {
|
if (!parentActor) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ typedef double DOMHighResTimeStamp;
|
||||||
typedef unsigned long long nsViewID;
|
typedef unsigned long long nsViewID;
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
interface nsIDOMDocument;
|
|
||||||
interface nsIDOMNode;
|
interface nsIDOMNode;
|
||||||
|
|
||||||
// Needed for raises() in our IDL
|
// Needed for raises() in our IDL
|
||||||
|
|
|
@ -8,7 +8,6 @@ with Files("**"):
|
||||||
BUG_COMPONENT = ("Core", "DOM")
|
BUG_COMPONENT = ("Core", "DOM")
|
||||||
|
|
||||||
XPIDL_SOURCES += [
|
XPIDL_SOURCES += [
|
||||||
'nsIDOMDocument.idl',
|
|
||||||
'nsIDOMNode.idl',
|
'nsIDOMNode.idl',
|
||||||
'nsIDOMNSEditableElement.idl',
|
'nsIDOMNSEditableElement.idl',
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* 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/. */
|
|
||||||
|
|
||||||
#include "nsIDOMNode.idl"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The nsIDOMDocument interface represents the entire HTML or XML document.
|
|
||||||
* Conceptually, it is the root of the document tree, and provides the
|
|
||||||
* primary access to the document's data.
|
|
||||||
* Since elements, text nodes, comments, processing instructions, etc.
|
|
||||||
* cannot exist outside the context of a Document, the nsIDOMDocument
|
|
||||||
* interface also contains the factory methods needed to create these
|
|
||||||
* objects.
|
|
||||||
*
|
|
||||||
* For more information on this interface please see
|
|
||||||
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
[shim(Document), uuid(b15fa0f4-97c1-4388-af62-2ceff7a89bdf)]
|
|
||||||
interface nsIDOMDocument : nsIDOMNode
|
|
||||||
{
|
|
||||||
};
|
|
|
@ -349,7 +349,7 @@ partial interface Document {
|
||||||
[Throws, Func="IsChromeOrXBL", NeedsSubjectPrincipal]
|
[Throws, Func="IsChromeOrXBL", NeedsSubjectPrincipal]
|
||||||
void loadBindingDocument(DOMString documentURL);
|
void loadBindingDocument(DOMString documentURL);
|
||||||
|
|
||||||
// nsIDOMDocumentTouch
|
// Touch bits
|
||||||
// XXXbz I can't find the sane spec for this stuff, so just cribbing
|
// XXXbz I can't find the sane spec for this stuff, so just cribbing
|
||||||
// from our xpidl for now.
|
// from our xpidl for now.
|
||||||
[NewObject, Func="nsGenericHTMLElement::TouchEventsEnabled"]
|
[NewObject, Func="nsGenericHTMLElement::TouchEventsEnabled"]
|
||||||
|
|
29
gfx/2d/2D.h
29
gfx/2d/2D.h
|
@ -473,13 +473,35 @@ public:
|
||||||
*
|
*
|
||||||
* Use IsMapped() to verify whether Map() succeeded or not.
|
* Use IsMapped() to verify whether Map() succeeded or not.
|
||||||
*/
|
*/
|
||||||
class ScopedMap {
|
class ScopedMap final {
|
||||||
public:
|
public:
|
||||||
explicit ScopedMap(DataSourceSurface* aSurface, MapType aType)
|
explicit ScopedMap(DataSourceSurface* aSurface, MapType aType)
|
||||||
: mSurface(aSurface)
|
: mSurface(aSurface)
|
||||||
, mIsMapped(aSurface->Map(aType, &mMap)) {}
|
, mIsMapped(aSurface->Map(aType, &mMap)) {}
|
||||||
|
|
||||||
virtual ~ScopedMap()
|
ScopedMap(ScopedMap&& aOther)
|
||||||
|
: mSurface(Move(aOther.mSurface))
|
||||||
|
, mMap(aOther.mMap)
|
||||||
|
, mIsMapped(aOther.mIsMapped)
|
||||||
|
{
|
||||||
|
aOther.mMap.mData = nullptr;
|
||||||
|
aOther.mIsMapped = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScopedMap& operator=(ScopedMap&& aOther)
|
||||||
|
{
|
||||||
|
if (mIsMapped) {
|
||||||
|
mSurface->Unmap();
|
||||||
|
}
|
||||||
|
mSurface = Move(aOther.mSurface);
|
||||||
|
mMap = aOther.mMap;
|
||||||
|
mIsMapped = aOther.mIsMapped;
|
||||||
|
aOther.mMap.mData = nullptr;
|
||||||
|
aOther.mIsMapped = false;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ScopedMap()
|
||||||
{
|
{
|
||||||
if (mIsMapped) {
|
if (mIsMapped) {
|
||||||
mSurface->Unmap();
|
mSurface->Unmap();
|
||||||
|
@ -507,6 +529,9 @@ public:
|
||||||
bool IsMapped() const { return mIsMapped; }
|
bool IsMapped() const { return mIsMapped; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ScopedMap(const ScopedMap& aOther) = delete;
|
||||||
|
ScopedMap& operator=(const ScopedMap& aOther) = delete;
|
||||||
|
|
||||||
RefPtr<DataSourceSurface> mSurface;
|
RefPtr<DataSourceSurface> mSurface;
|
||||||
MappedSurface mMap;
|
MappedSurface mMap;
|
||||||
bool mIsMapped;
|
bool mIsMapped;
|
||||||
|
|
|
@ -2038,6 +2038,7 @@ gfxFont::DrawOneGlyph(uint32_t aGlyphID, const gfx::Point& aPt,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fontParams.haveColorGlyphs &&
|
if (fontParams.haveColorGlyphs &&
|
||||||
|
!gfxPlatform::GetPlatform()->HasNativeColrFontSupport() &&
|
||||||
RenderColorGlyph(runParams.dt, runParams.context,
|
RenderColorGlyph(runParams.dt, runParams.context,
|
||||||
fontParams.scaledFont,
|
fontParams.scaledFont,
|
||||||
fontParams.drawOptions,
|
fontParams.drawOptions,
|
||||||
|
|
|
@ -737,6 +737,10 @@ public:
|
||||||
return mHasVariationFontSupport;
|
return mHasVariationFontSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HasNativeColrFontSupport() const {
|
||||||
|
return mHasNativeColrFontSupport;
|
||||||
|
}
|
||||||
|
|
||||||
// you probably want to use gfxVars::UseWebRender() instead of this
|
// you probably want to use gfxVars::UseWebRender() instead of this
|
||||||
static bool WebRenderPrefEnabled();
|
static bool WebRenderPrefEnabled();
|
||||||
// you probably want to use gfxVars::UseWebRender() instead of this
|
// you probably want to use gfxVars::UseWebRender() instead of this
|
||||||
|
@ -830,6 +834,10 @@ protected:
|
||||||
// Whether the platform supports rendering OpenType font variations
|
// Whether the platform supports rendering OpenType font variations
|
||||||
bool mHasVariationFontSupport;
|
bool mHasVariationFontSupport;
|
||||||
|
|
||||||
|
// Whether the platform font APIs have native support for COLR fonts.
|
||||||
|
// Set to true during initialization on platforms that implement this.
|
||||||
|
bool mHasNativeColrFontSupport = false;
|
||||||
|
|
||||||
// max character limit for words in word cache
|
// max character limit for words in word cache
|
||||||
int32_t mWordCacheCharLimit;
|
int32_t mWordCacheCharLimit;
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,10 @@ gfxPlatformMac::gfxPlatformMac()
|
||||||
InitBackendPrefs(GetBackendPrefs());
|
InitBackendPrefs(GetBackendPrefs());
|
||||||
|
|
||||||
MacIOSurfaceLib::LoadLibrary();
|
MacIOSurfaceLib::LoadLibrary();
|
||||||
|
|
||||||
|
if (nsCocoaFeatures::OnHighSierraOrLater()) {
|
||||||
|
mHasNativeColrFontSupport = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxPlatformMac::~gfxPlatformMac()
|
gfxPlatformMac::~gfxPlatformMac()
|
||||||
|
|
|
@ -176,18 +176,18 @@ AnimationFrameBuffer::MarkComplete()
|
||||||
return mPending > 0;
|
return mPending > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawableFrameRef
|
imgFrame*
|
||||||
AnimationFrameBuffer::Get(size_t aFrame)
|
AnimationFrameBuffer::Get(size_t aFrame)
|
||||||
{
|
{
|
||||||
// We should not have asked for a frame if we never inserted.
|
// We should not have asked for a frame if we never inserted.
|
||||||
if (mFrames.IsEmpty()) {
|
if (mFrames.IsEmpty()) {
|
||||||
MOZ_ASSERT_UNREACHABLE("Calling Get() when we have no frames");
|
MOZ_ASSERT_UNREACHABLE("Calling Get() when we have no frames");
|
||||||
return DrawableFrameRef();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we don't have that frame, return an empty frame ref.
|
// If we don't have that frame, return an empty frame ref.
|
||||||
if (aFrame >= mFrames.Length()) {
|
if (aFrame >= mFrames.Length()) {
|
||||||
return DrawableFrameRef();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We've got the requested frame because we are not discarding frames. While
|
// We've got the requested frame because we are not discarding frames. While
|
||||||
|
@ -195,13 +195,13 @@ AnimationFrameBuffer::Get(size_t aFrame)
|
||||||
// we want them, it is possible the decoder is behind.
|
// we want them, it is possible the decoder is behind.
|
||||||
if (!mFrames[aFrame]) {
|
if (!mFrames[aFrame]) {
|
||||||
MOZ_ASSERT(MayDiscard());
|
MOZ_ASSERT(MayDiscard());
|
||||||
return DrawableFrameRef();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are advancing on behalf of the animation, we don't expect it to be
|
// If we are advancing on behalf of the animation, we don't expect it to be
|
||||||
// getting any frames (besides the first) until we get the desired frame.
|
// getting any frames (besides the first) until we get the desired frame.
|
||||||
MOZ_ASSERT(aFrame == 0 || mAdvance == 0);
|
MOZ_ASSERT(aFrame == 0 || mAdvance == 0);
|
||||||
return mFrames[aFrame]->DrawableRef();
|
return mFrames[aFrame].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -63,7 +63,7 @@ public:
|
||||||
*
|
*
|
||||||
* @returns The frame, if available.
|
* @returns The frame, if available.
|
||||||
*/
|
*/
|
||||||
DrawableFrameRef Get(size_t aFrame);
|
imgFrame* Get(size_t aFrame);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts a frame into the frame buffer. If it has yet to fully decode the
|
* Inserts a frame into the frame buffer. If it has yet to fully decode the
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
*
|
||||||
|
* 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 mozilla_image_AnimationParams_h
|
||||||
|
#define mozilla_image_AnimationParams_h
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "mozilla/gfx/Rect.h"
|
||||||
|
#include "FrameTimeout.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace image {
|
||||||
|
|
||||||
|
enum class BlendMethod : int8_t {
|
||||||
|
// All color components of the frame, including alpha, overwrite the current
|
||||||
|
// contents of the frame's output buffer region.
|
||||||
|
SOURCE,
|
||||||
|
|
||||||
|
// The frame should be composited onto the output buffer based on its alpha,
|
||||||
|
// using a simple OVER operation.
|
||||||
|
OVER
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class DisposalMethod : int8_t {
|
||||||
|
CLEAR_ALL = -1, // Clear the whole image, revealing what's underneath.
|
||||||
|
NOT_SPECIFIED, // Leave the frame and let the new frame draw on top.
|
||||||
|
KEEP, // Leave the frame and let the new frame draw on top.
|
||||||
|
CLEAR, // Clear the frame's area, revealing what's underneath.
|
||||||
|
RESTORE_PREVIOUS // Restore the previous (composited) frame.
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AnimationParams
|
||||||
|
{
|
||||||
|
gfx::IntRect mBlendRect;
|
||||||
|
FrameTimeout mTimeout;
|
||||||
|
uint32_t mFrameNum;
|
||||||
|
BlendMethod mBlendMethod;
|
||||||
|
DisposalMethod mDisposalMethod;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace image
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // mozilla_image_AnimationParams_h
|
|
@ -134,7 +134,30 @@ AnimationSurfaceProvider::DrawableRef(size_t aFrame)
|
||||||
return DrawableFrameRef();
|
return DrawableFrameRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
return mFrames.Get(aFrame);
|
imgFrame* frame = mFrames.Get(aFrame);
|
||||||
|
if (!frame) {
|
||||||
|
return DrawableFrameRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
return frame->DrawableRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
RawAccessFrameRef
|
||||||
|
AnimationSurfaceProvider::RawAccessRef(size_t aFrame)
|
||||||
|
{
|
||||||
|
MutexAutoLock lock(mFramesMutex);
|
||||||
|
|
||||||
|
if (Availability().IsPlaceholder()) {
|
||||||
|
MOZ_ASSERT_UNREACHABLE("Calling RawAccessRef() on a placeholder");
|
||||||
|
return RawAccessFrameRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
imgFrame* frame = mFrames.Get(aFrame);
|
||||||
|
if (!frame) {
|
||||||
|
return RawAccessFrameRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
return frame->RawAccessRef(/* aOnlyFinished */ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -57,6 +57,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DrawableFrameRef DrawableRef(size_t aFrame) override;
|
DrawableFrameRef DrawableRef(size_t aFrame) override;
|
||||||
|
RawAccessFrameRef RawAccessRef(size_t aFrame) override;
|
||||||
|
|
||||||
// Animation frames are always locked. This is because we only want to release
|
// Animation frames are always locked. This is because we only want to release
|
||||||
// their memory atomically (due to the surface cache discarding them). If they
|
// their memory atomically (due to the surface cache discarding them). If they
|
||||||
|
|
|
@ -283,14 +283,14 @@ Decoder::Telemetry() const
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
Decoder::AllocateFrame(uint32_t aFrameNum,
|
Decoder::AllocateFrame(const gfx::IntSize& aOutputSize,
|
||||||
const gfx::IntSize& aOutputSize,
|
|
||||||
const gfx::IntRect& aFrameRect,
|
const gfx::IntRect& aFrameRect,
|
||||||
gfx::SurfaceFormat aFormat,
|
gfx::SurfaceFormat aFormat,
|
||||||
uint8_t aPaletteDepth)
|
uint8_t aPaletteDepth,
|
||||||
|
const Maybe<AnimationParams>& aAnimParams)
|
||||||
{
|
{
|
||||||
mCurrentFrame = AllocateFrameInternal(aFrameNum, aOutputSize, aFrameRect,
|
mCurrentFrame = AllocateFrameInternal(aOutputSize, aFrameRect, aFormat,
|
||||||
aFormat, aPaletteDepth,
|
aPaletteDepth, aAnimParams,
|
||||||
mCurrentFrame.get());
|
mCurrentFrame.get());
|
||||||
|
|
||||||
if (mCurrentFrame) {
|
if (mCurrentFrame) {
|
||||||
|
@ -302,7 +302,7 @@ Decoder::AllocateFrame(uint32_t aFrameNum,
|
||||||
|
|
||||||
// We should now be on |aFrameNum|. (Note that we're comparing the frame
|
// We should now be on |aFrameNum|. (Note that we're comparing the frame
|
||||||
// number, which is zero-based, with the frame count, which is one-based.)
|
// number, which is zero-based, with the frame count, which is one-based.)
|
||||||
MOZ_ASSERT(aFrameNum + 1 == mFrameCount);
|
MOZ_ASSERT_IF(aAnimParams, aAnimParams->mFrameNum + 1 == mFrameCount);
|
||||||
|
|
||||||
// If we're past the first frame, PostIsAnimated() should've been called.
|
// If we're past the first frame, PostIsAnimated() should've been called.
|
||||||
MOZ_ASSERT_IF(mFrameCount > 1, HasAnimation());
|
MOZ_ASSERT_IF(mFrameCount > 1, HasAnimation());
|
||||||
|
@ -316,18 +316,19 @@ Decoder::AllocateFrame(uint32_t aFrameNum,
|
||||||
}
|
}
|
||||||
|
|
||||||
RawAccessFrameRef
|
RawAccessFrameRef
|
||||||
Decoder::AllocateFrameInternal(uint32_t aFrameNum,
|
Decoder::AllocateFrameInternal(const gfx::IntSize& aOutputSize,
|
||||||
const gfx::IntSize& aOutputSize,
|
|
||||||
const gfx::IntRect& aFrameRect,
|
const gfx::IntRect& aFrameRect,
|
||||||
SurfaceFormat aFormat,
|
SurfaceFormat aFormat,
|
||||||
uint8_t aPaletteDepth,
|
uint8_t aPaletteDepth,
|
||||||
|
const Maybe<AnimationParams>& aAnimParams,
|
||||||
imgFrame* aPreviousFrame)
|
imgFrame* aPreviousFrame)
|
||||||
{
|
{
|
||||||
if (HasError()) {
|
if (HasError()) {
|
||||||
return RawAccessFrameRef();
|
return RawAccessFrameRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aFrameNum != mFrameCount) {
|
uint32_t frameNum = aAnimParams ? aAnimParams->mFrameNum : 0;
|
||||||
|
if (frameNum != mFrameCount) {
|
||||||
MOZ_ASSERT_UNREACHABLE("Allocating frames out of order");
|
MOZ_ASSERT_UNREACHABLE("Allocating frames out of order");
|
||||||
return RawAccessFrameRef();
|
return RawAccessFrameRef();
|
||||||
}
|
}
|
||||||
|
@ -342,7 +343,7 @@ Decoder::AllocateFrameInternal(uint32_t aFrameNum,
|
||||||
bool nonPremult = bool(mSurfaceFlags & SurfaceFlags::NO_PREMULTIPLY_ALPHA);
|
bool nonPremult = bool(mSurfaceFlags & SurfaceFlags::NO_PREMULTIPLY_ALPHA);
|
||||||
if (NS_FAILED(frame->InitForDecoder(aOutputSize, aFrameRect, aFormat,
|
if (NS_FAILED(frame->InitForDecoder(aOutputSize, aFrameRect, aFormat,
|
||||||
aPaletteDepth, nonPremult,
|
aPaletteDepth, nonPremult,
|
||||||
aFrameNum > 0))) {
|
aAnimParams))) {
|
||||||
NS_WARNING("imgFrame::Init should succeed");
|
NS_WARNING("imgFrame::Init should succeed");
|
||||||
return RawAccessFrameRef();
|
return RawAccessFrameRef();
|
||||||
}
|
}
|
||||||
|
@ -353,24 +354,20 @@ Decoder::AllocateFrameInternal(uint32_t aFrameNum,
|
||||||
return RawAccessFrameRef();
|
return RawAccessFrameRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aFrameNum == 1) {
|
if (frameNum == 1) {
|
||||||
MOZ_ASSERT(aPreviousFrame, "Must provide a previous frame when animated");
|
MOZ_ASSERT(aPreviousFrame, "Must provide a previous frame when animated");
|
||||||
aPreviousFrame->SetRawAccessOnly();
|
|
||||||
|
|
||||||
// If we dispose of the first frame by clearing it, then the first frame's
|
// If we dispose of the first frame by clearing it, then the first frame's
|
||||||
// refresh area is all of itself.
|
// refresh area is all of itself.
|
||||||
// RESTORE_PREVIOUS is invalid (assumed to be DISPOSE_CLEAR).
|
// RESTORE_PREVIOUS is invalid (assumed to be DISPOSE_CLEAR).
|
||||||
AnimationData previousFrameData = aPreviousFrame->GetAnimationData();
|
DisposalMethod prevDisposal = aPreviousFrame->GetDisposalMethod();
|
||||||
if (previousFrameData.mDisposalMethod == DisposalMethod::CLEAR ||
|
if (prevDisposal == DisposalMethod::CLEAR ||
|
||||||
previousFrameData.mDisposalMethod == DisposalMethod::CLEAR_ALL ||
|
prevDisposal == DisposalMethod::CLEAR_ALL ||
|
||||||
previousFrameData.mDisposalMethod == DisposalMethod::RESTORE_PREVIOUS) {
|
prevDisposal == DisposalMethod::RESTORE_PREVIOUS) {
|
||||||
mFirstFrameRefreshArea = previousFrameData.mRect;
|
mFirstFrameRefreshArea = aPreviousFrame->GetRect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aFrameNum > 0) {
|
if (frameNum > 0) {
|
||||||
ref->SetRawAccessOnly();
|
|
||||||
|
|
||||||
// Some GIFs are huge but only have a small area that they animate. We only
|
// Some GIFs are huge but only have a small area that they animate. We only
|
||||||
// need to refresh that small area when frame 0 comes around again.
|
// need to refresh that small area when frame 0 comes around again.
|
||||||
mFirstFrameRefreshArea.UnionRect(mFirstFrameRefreshArea, frame->GetRect());
|
mFirstFrameRefreshArea.UnionRect(mFirstFrameRefreshArea, frame->GetRect());
|
||||||
|
@ -453,13 +450,7 @@ Decoder::PostIsAnimated(FrameTimeout aFirstFrameTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Decoder::PostFrameStop(Opacity aFrameOpacity
|
Decoder::PostFrameStop(Opacity aFrameOpacity)
|
||||||
/* = Opacity::SOME_TRANSPARENCY */,
|
|
||||||
DisposalMethod aDisposalMethod
|
|
||||||
/* = DisposalMethod::KEEP */,
|
|
||||||
FrameTimeout aTimeout /* = FrameTimeout::Forever() */,
|
|
||||||
BlendMethod aBlendMethod /* = BlendMethod::OVER */,
|
|
||||||
const Maybe<nsIntRect>& aBlendRect /* = Nothing() */)
|
|
||||||
{
|
{
|
||||||
// We should be mid-frame
|
// We should be mid-frame
|
||||||
MOZ_ASSERT(!IsMetadataDecode(), "Stopping frame during metadata decode");
|
MOZ_ASSERT(!IsMetadataDecode(), "Stopping frame during metadata decode");
|
||||||
|
@ -470,12 +461,11 @@ Decoder::PostFrameStop(Opacity aFrameOpacity
|
||||||
mInFrame = false;
|
mInFrame = false;
|
||||||
mFinishedNewFrame = true;
|
mFinishedNewFrame = true;
|
||||||
|
|
||||||
mCurrentFrame->Finish(aFrameOpacity, aDisposalMethod, aTimeout,
|
mCurrentFrame->Finish(aFrameOpacity, mFinalizeFrames);
|
||||||
aBlendMethod, aBlendRect, mFinalizeFrames);
|
|
||||||
|
|
||||||
mProgress |= FLAG_FRAME_COMPLETE;
|
mProgress |= FLAG_FRAME_COMPLETE;
|
||||||
|
|
||||||
mLoopLength += aTimeout;
|
mLoopLength += mCurrentFrame->GetTimeout();
|
||||||
|
|
||||||
// If we're not sending partial invalidations, then we send an invalidation
|
// If we're not sending partial invalidations, then we send an invalidation
|
||||||
// here when the first frame is complete.
|
// here when the first frame is complete.
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/NotNull.h"
|
#include "mozilla/NotNull.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
|
#include "AnimationParams.h"
|
||||||
#include "DecoderFlags.h"
|
#include "DecoderFlags.h"
|
||||||
#include "Downscaler.h"
|
#include "Downscaler.h"
|
||||||
#include "ImageMetadata.h"
|
#include "ImageMetadata.h"
|
||||||
|
@ -27,6 +28,8 @@ namespace Telemetry {
|
||||||
|
|
||||||
namespace image {
|
namespace image {
|
||||||
|
|
||||||
|
class imgFrame;
|
||||||
|
|
||||||
struct DecoderFinalStatus final
|
struct DecoderFinalStatus final
|
||||||
{
|
{
|
||||||
DecoderFinalStatus(bool aWasMetadataDecode,
|
DecoderFinalStatus(bool aWasMetadataDecode,
|
||||||
|
@ -477,11 +480,7 @@ protected:
|
||||||
// Specify whether this frame is opaque as an optimization.
|
// Specify whether this frame is opaque as an optimization.
|
||||||
// For animated images, specify the disposal, blend method and timeout for
|
// For animated images, specify the disposal, blend method and timeout for
|
||||||
// this frame.
|
// this frame.
|
||||||
void PostFrameStop(Opacity aFrameOpacity = Opacity::SOME_TRANSPARENCY,
|
void PostFrameStop(Opacity aFrameOpacity = Opacity::SOME_TRANSPARENCY);
|
||||||
DisposalMethod aDisposalMethod = DisposalMethod::KEEP,
|
|
||||||
FrameTimeout aTimeout = FrameTimeout::Forever(),
|
|
||||||
BlendMethod aBlendMethod = BlendMethod::OVER,
|
|
||||||
const Maybe<nsIntRect>& aBlendRect = Nothing());
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the decoders when they have a region to invalidate. We may not
|
* Called by the decoders when they have a region to invalidate. We may not
|
||||||
|
@ -510,16 +509,13 @@ protected:
|
||||||
/**
|
/**
|
||||||
* Allocates a new frame, making it our current frame if successful.
|
* Allocates a new frame, making it our current frame if successful.
|
||||||
*
|
*
|
||||||
* The @aFrameNum parameter only exists as a sanity check; it's illegal to
|
|
||||||
* create a new frame anywhere but immediately after the existing frames.
|
|
||||||
*
|
|
||||||
* If a non-paletted frame is desired, pass 0 for aPaletteDepth.
|
* If a non-paletted frame is desired, pass 0 for aPaletteDepth.
|
||||||
*/
|
*/
|
||||||
nsresult AllocateFrame(uint32_t aFrameNum,
|
nsresult AllocateFrame(const gfx::IntSize& aOutputSize,
|
||||||
const gfx::IntSize& aOutputSize,
|
|
||||||
const gfx::IntRect& aFrameRect,
|
const gfx::IntRect& aFrameRect,
|
||||||
gfx::SurfaceFormat aFormat,
|
gfx::SurfaceFormat aFormat,
|
||||||
uint8_t aPaletteDepth = 0);
|
uint8_t aPaletteDepth = 0,
|
||||||
|
const Maybe<AnimationParams>& aAnimParams = Nothing());
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Report that an error was encountered while decoding.
|
/// Report that an error was encountered while decoding.
|
||||||
|
@ -543,11 +539,11 @@ private:
|
||||||
return mInFrame ? mFrameCount - 1 : mFrameCount;
|
return mInFrame ? mFrameCount - 1 : mFrameCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
RawAccessFrameRef AllocateFrameInternal(uint32_t aFrameNum,
|
RawAccessFrameRef AllocateFrameInternal(const gfx::IntSize& aOutputSize,
|
||||||
const gfx::IntSize& aOutputSize,
|
|
||||||
const gfx::IntRect& aFrameRect,
|
const gfx::IntRect& aFrameRect,
|
||||||
gfx::SurfaceFormat aFormat,
|
gfx::SurfaceFormat aFormat,
|
||||||
uint8_t aPaletteDepth,
|
uint8_t aPaletteDepth,
|
||||||
|
const Maybe<AnimationParams>& aAnimParams,
|
||||||
imgFrame* aPreviousFrame);
|
imgFrame* aPreviousFrame);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -70,7 +70,7 @@ public:
|
||||||
Maybe<SurfaceInvalidRect> TakeInvalidRect() override { return Nothing(); }
|
Maybe<SurfaceInvalidRect> TakeInvalidRect() override { return Nothing(); }
|
||||||
|
|
||||||
template <typename... Rest>
|
template <typename... Rest>
|
||||||
nsresult Configure(const DownscalingConfig& aConfig, Rest... aRest)
|
nsresult Configure(const DownscalingConfig& aConfig, const Rest&... aRest)
|
||||||
{
|
{
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Rest>
|
template <typename... Rest>
|
||||||
nsresult Configure(const DownscalingConfig& aConfig, Rest... aRest)
|
nsresult Configure(const DownscalingConfig& aConfig, const Rest&... aRest)
|
||||||
{
|
{
|
||||||
nsresult rv = mNext.Configure(aRest...);
|
nsresult rv = mNext.Configure(aRest...);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
|
|
@ -212,40 +212,30 @@ AnimationState::LoopLength() const
|
||||||
// FrameAnimator implementation.
|
// FrameAnimator implementation.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Maybe<TimeStamp>
|
TimeStamp
|
||||||
FrameAnimator::GetCurrentImgFrameEndTime(AnimationState& aState,
|
FrameAnimator::GetCurrentImgFrameEndTime(AnimationState& aState,
|
||||||
DrawableSurface& aFrames) const
|
FrameTimeout aCurrentTimeout) const
|
||||||
{
|
{
|
||||||
TimeStamp currentFrameTime = aState.mCurrentAnimationFrameTime;
|
if (aCurrentTimeout == FrameTimeout::Forever()) {
|
||||||
Maybe<FrameTimeout> timeout =
|
|
||||||
GetTimeoutForFrame(aState, aFrames, aState.mCurrentAnimationFrameIndex);
|
|
||||||
|
|
||||||
if (timeout.isNothing()) {
|
|
||||||
MOZ_ASSERT(aState.GetHasRequestedDecode() && !aState.GetIsCurrentlyDecoded());
|
|
||||||
return Nothing();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*timeout == FrameTimeout::Forever()) {
|
|
||||||
// We need to return a sentinel value in this case, because our logic
|
// We need to return a sentinel value in this case, because our logic
|
||||||
// doesn't work correctly if we have an infinitely long timeout. We use one
|
// doesn't work correctly if we have an infinitely long timeout. We use one
|
||||||
// year in the future as the sentinel because it works with the loop in
|
// year in the future as the sentinel because it works with the loop in
|
||||||
// RequestRefresh() below.
|
// RequestRefresh() below.
|
||||||
// XXX(seth): It'd be preferable to make our logic work correctly with
|
// XXX(seth): It'd be preferable to make our logic work correctly with
|
||||||
// infinitely long timeouts.
|
// infinitely long timeouts.
|
||||||
return Some(TimeStamp::NowLoRes() +
|
return TimeStamp::NowLoRes() +
|
||||||
TimeDuration::FromMilliseconds(31536000.0));
|
TimeDuration::FromMilliseconds(31536000.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeDuration durationOfTimeout =
|
TimeDuration durationOfTimeout =
|
||||||
TimeDuration::FromMilliseconds(double(timeout->AsMilliseconds()));
|
TimeDuration::FromMilliseconds(double(aCurrentTimeout.AsMilliseconds()));
|
||||||
TimeStamp currentFrameEndTime = currentFrameTime + durationOfTimeout;
|
return aState.mCurrentAnimationFrameTime + durationOfTimeout;
|
||||||
|
|
||||||
return Some(currentFrameEndTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RefreshResult
|
RefreshResult
|
||||||
FrameAnimator::AdvanceFrame(AnimationState& aState,
|
FrameAnimator::AdvanceFrame(AnimationState& aState,
|
||||||
DrawableSurface& aFrames,
|
DrawableSurface& aFrames,
|
||||||
|
RawAccessFrameRef& aCurrentFrame,
|
||||||
TimeStamp aTime)
|
TimeStamp aTime)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aTime <= TimeStamp::Now(),
|
NS_ASSERTION(aTime <= TimeStamp::Now(),
|
||||||
|
@ -306,13 +296,14 @@ FrameAnimator::AdvanceFrame(AnimationState& aState,
|
||||||
// the appropriate notification on the main thread. Make sure we stay in sync
|
// the appropriate notification on the main thread. Make sure we stay in sync
|
||||||
// with AnimationState.
|
// with AnimationState.
|
||||||
MOZ_ASSERT(nextFrameIndex < aState.KnownFrameCount());
|
MOZ_ASSERT(nextFrameIndex < aState.KnownFrameCount());
|
||||||
RawAccessFrameRef nextFrame = GetRawFrame(aFrames, nextFrameIndex);
|
RawAccessFrameRef nextFrame = aFrames.RawAccessRef(nextFrameIndex);
|
||||||
|
|
||||||
// We should always check to see if we have the next frame even if we have
|
// We should always check to see if we have the next frame even if we have
|
||||||
// previously finished decoding. If we needed to redecode (e.g. due to a draw
|
// previously finished decoding. If we needed to redecode (e.g. due to a draw
|
||||||
// failure) we would have discarded all the old frames and may not yet have
|
// failure) we would have discarded all the old frames and may not yet have
|
||||||
// the new ones.
|
// the new ones. DrawableSurface::RawAccessRef promises to only return
|
||||||
if (!nextFrame || !nextFrame->IsFinished()) {
|
// finished frames.
|
||||||
|
if (!nextFrame) {
|
||||||
// Uh oh, the frame we want to show is currently being decoded (partial).
|
// Uh oh, the frame we want to show is currently being decoded (partial).
|
||||||
// Similar to the above case, we could be blocked by network or decoding,
|
// Similar to the above case, we could be blocked by network or decoding,
|
||||||
// and so we should advance our current time rather than risk jumping
|
// and so we should advance our current time rather than risk jumping
|
||||||
|
@ -322,11 +313,7 @@ FrameAnimator::AdvanceFrame(AnimationState& aState,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<FrameTimeout> nextFrameTimeout = GetTimeoutForFrame(aState, aFrames, nextFrameIndex);
|
if (nextFrame->GetTimeout() == FrameTimeout::Forever()) {
|
||||||
// GetTimeoutForFrame can only return none if frame doesn't exist,
|
|
||||||
// but we just got it above.
|
|
||||||
MOZ_ASSERT(nextFrameTimeout.isSome());
|
|
||||||
if (*nextFrameTimeout == FrameTimeout::Forever()) {
|
|
||||||
ret.mAnimationFinished = true;
|
ret.mAnimationFinished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,15 +323,15 @@ FrameAnimator::AdvanceFrame(AnimationState& aState,
|
||||||
MOZ_ASSERT(nextFrameIndex == currentFrameIndex + 1);
|
MOZ_ASSERT(nextFrameIndex == currentFrameIndex + 1);
|
||||||
|
|
||||||
// Change frame
|
// Change frame
|
||||||
if (!DoBlend(aFrames, &ret.mDirtyRect, currentFrameIndex, nextFrameIndex)) {
|
if (!DoBlend(aCurrentFrame, nextFrame, nextFrameIndex, &ret.mDirtyRect)) {
|
||||||
// something went wrong, move on to next
|
// something went wrong, move on to next
|
||||||
NS_WARNING("FrameAnimator::AdvanceFrame(): Compositing of frame failed");
|
NS_WARNING("FrameAnimator::AdvanceFrame(): Compositing of frame failed");
|
||||||
nextFrame->SetCompositingFailed(true);
|
nextFrame->SetCompositingFailed(true);
|
||||||
Maybe<TimeStamp> currentFrameEndTime = GetCurrentImgFrameEndTime(aState, aFrames);
|
aState.mCurrentAnimationFrameTime =
|
||||||
MOZ_ASSERT(currentFrameEndTime.isSome());
|
GetCurrentImgFrameEndTime(aState, aCurrentFrame->GetTimeout());
|
||||||
aState.mCurrentAnimationFrameTime = *currentFrameEndTime;
|
|
||||||
aState.mCurrentAnimationFrameIndex = nextFrameIndex;
|
aState.mCurrentAnimationFrameIndex = nextFrameIndex;
|
||||||
aState.mCompositedFrameRequested = false;
|
aState.mCompositedFrameRequested = false;
|
||||||
|
aCurrentFrame = Move(nextFrame);
|
||||||
aFrames.Advance(nextFrameIndex);
|
aFrames.Advance(nextFrameIndex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -353,9 +340,8 @@ FrameAnimator::AdvanceFrame(AnimationState& aState,
|
||||||
nextFrame->SetCompositingFailed(false);
|
nextFrame->SetCompositingFailed(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<TimeStamp> currentFrameEndTime = GetCurrentImgFrameEndTime(aState, aFrames);
|
aState.mCurrentAnimationFrameTime =
|
||||||
MOZ_ASSERT(currentFrameEndTime.isSome());
|
GetCurrentImgFrameEndTime(aState, aCurrentFrame->GetTimeout());
|
||||||
aState.mCurrentAnimationFrameTime = *currentFrameEndTime;
|
|
||||||
|
|
||||||
// If we can get closer to the current time by a multiple of the image's loop
|
// If we can get closer to the current time by a multiple of the image's loop
|
||||||
// time, we should. We can only do this if we're done decoding; otherwise, we
|
// time, we should. We can only do this if we're done decoding; otherwise, we
|
||||||
|
@ -392,6 +378,7 @@ FrameAnimator::AdvanceFrame(AnimationState& aState,
|
||||||
// Set currentAnimationFrameIndex at the last possible moment
|
// Set currentAnimationFrameIndex at the last possible moment
|
||||||
aState.mCurrentAnimationFrameIndex = nextFrameIndex;
|
aState.mCurrentAnimationFrameIndex = nextFrameIndex;
|
||||||
aState.mCompositedFrameRequested = false;
|
aState.mCompositedFrameRequested = false;
|
||||||
|
aCurrentFrame = Move(nextFrame);
|
||||||
aFrames.Advance(nextFrameIndex);
|
aFrames.Advance(nextFrameIndex);
|
||||||
|
|
||||||
// If we're here, we successfully advanced the frame.
|
// If we're here, we successfully advanced the frame.
|
||||||
|
@ -451,11 +438,12 @@ FrameAnimator::RequestRefresh(AnimationState& aState,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RawAccessFrameRef currentFrame =
|
||||||
|
result.Surface().RawAccessRef(aState.mCurrentAnimationFrameIndex);
|
||||||
|
|
||||||
// only advance the frame if the current time is greater than or
|
// only advance the frame if the current time is greater than or
|
||||||
// equal to the current frame's end time.
|
// equal to the current frame's end time.
|
||||||
Maybe<TimeStamp> currentFrameEndTime =
|
if (!currentFrame) {
|
||||||
GetCurrentImgFrameEndTime(aState, result.Surface());
|
|
||||||
if (currentFrameEndTime.isNothing()) {
|
|
||||||
MOZ_ASSERT(gfxPrefs::ImageMemAnimatedDiscardable());
|
MOZ_ASSERT(gfxPrefs::ImageMemAnimatedDiscardable());
|
||||||
MOZ_ASSERT(aState.GetHasRequestedDecode() && !aState.GetIsCurrentlyDecoded());
|
MOZ_ASSERT(aState.GetHasRequestedDecode() && !aState.GetIsCurrentlyDecoded());
|
||||||
MOZ_ASSERT(aState.mCompositedFrameInvalid);
|
MOZ_ASSERT(aState.mCompositedFrameInvalid);
|
||||||
|
@ -465,6 +453,9 @@ FrameAnimator::RequestRefresh(AnimationState& aState,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TimeStamp currentFrameEndTime =
|
||||||
|
GetCurrentImgFrameEndTime(aState, currentFrame->GetTimeout());
|
||||||
|
|
||||||
// If nothing has accessed the composited frame since the last time we
|
// If nothing has accessed the composited frame since the last time we
|
||||||
// advanced, then there is no point in continuing to advance the animation.
|
// advanced, then there is no point in continuing to advance the animation.
|
||||||
// This has the effect of freezing the animation while not in view.
|
// This has the effect of freezing the animation while not in view.
|
||||||
|
@ -473,28 +464,29 @@ FrameAnimator::RequestRefresh(AnimationState& aState,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*currentFrameEndTime <= aTime) {
|
while (currentFrameEndTime <= aTime) {
|
||||||
TimeStamp oldFrameEndTime = *currentFrameEndTime;
|
TimeStamp oldFrameEndTime = currentFrameEndTime;
|
||||||
|
|
||||||
RefreshResult frameRes = AdvanceFrame(aState, result.Surface(), aTime);
|
RefreshResult frameRes = AdvanceFrame(aState, result.Surface(),
|
||||||
|
currentFrame, aTime);
|
||||||
|
|
||||||
// Accumulate our result for returning to callers.
|
// Accumulate our result for returning to callers.
|
||||||
ret.Accumulate(frameRes);
|
ret.Accumulate(frameRes);
|
||||||
|
|
||||||
currentFrameEndTime = GetCurrentImgFrameEndTime(aState, result.Surface());
|
// currentFrame was updated by AdvanceFrame so it is still current.
|
||||||
// AdvanceFrame can't advance to a frame that doesn't exist yet.
|
currentFrameEndTime =
|
||||||
MOZ_ASSERT(currentFrameEndTime.isSome());
|
GetCurrentImgFrameEndTime(aState, currentFrame->GetTimeout());
|
||||||
|
|
||||||
// If we didn't advance a frame, and our frame end time didn't change,
|
// If we didn't advance a frame, and our frame end time didn't change,
|
||||||
// then we need to break out of this loop & wait for the frame(s)
|
// then we need to break out of this loop & wait for the frame(s)
|
||||||
// to finish downloading.
|
// to finish downloading.
|
||||||
if (!frameRes.mFrameAdvanced && (*currentFrameEndTime == oldFrameEndTime)) {
|
if (!frameRes.mFrameAdvanced && currentFrameEndTime == oldFrameEndTime) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advanced to the correct frame, the composited frame is now valid to be drawn.
|
// Advanced to the correct frame, the composited frame is now valid to be drawn.
|
||||||
if (*currentFrameEndTime > aTime) {
|
if (currentFrameEndTime > aTime) {
|
||||||
aState.mCompositedFrameInvalid = false;
|
aState.mCompositedFrameInvalid = false;
|
||||||
ret.mDirtyRect = IntRect(IntPoint(0,0), mSize);
|
ret.mDirtyRect = IntRect(IntPoint(0,0), mSize);
|
||||||
}
|
}
|
||||||
|
@ -509,6 +501,13 @@ FrameAnimator::GetCompositedFrame(AnimationState& aState)
|
||||||
{
|
{
|
||||||
aState.mCompositedFrameRequested = true;
|
aState.mCompositedFrameRequested = true;
|
||||||
|
|
||||||
|
// If we have a composited version of this frame, return that.
|
||||||
|
if (!aState.mCompositedFrameInvalid && mLastCompositedFrameIndex >= 0 &&
|
||||||
|
(uint32_t(mLastCompositedFrameIndex) == aState.mCurrentAnimationFrameIndex)) {
|
||||||
|
return LookupResult(DrawableSurface(mCompositingFrame->DrawableRef()),
|
||||||
|
MatchType::EXACT);
|
||||||
|
}
|
||||||
|
|
||||||
LookupResult result =
|
LookupResult result =
|
||||||
SurfaceCache::Lookup(ImageKey(mImage),
|
SurfaceCache::Lookup(ImageKey(mImage),
|
||||||
RasterSurfaceKey(mSize,
|
RasterSurfaceKey(mSize,
|
||||||
|
@ -525,13 +524,6 @@ FrameAnimator::GetCompositedFrame(AnimationState& aState)
|
||||||
return LookupResult(MatchType::PENDING);
|
return LookupResult(MatchType::PENDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a composited version of this frame, return that.
|
|
||||||
if (mLastCompositedFrameIndex >= 0 &&
|
|
||||||
(uint32_t(mLastCompositedFrameIndex) == aState.mCurrentAnimationFrameIndex)) {
|
|
||||||
return LookupResult(DrawableSurface(mCompositingFrame->DrawableRef()),
|
|
||||||
MatchType::EXACT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise return the raw frame. DoBlend is required to ensure that we only
|
// Otherwise return the raw frame. DoBlend is required to ensure that we only
|
||||||
// hit this case if the frame is not paletted and doesn't require compositing.
|
// hit this case if the frame is not paletted and doesn't require compositing.
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
@ -553,21 +545,6 @@ FrameAnimator::GetCompositedFrame(AnimationState& aState)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<FrameTimeout>
|
|
||||||
FrameAnimator::GetTimeoutForFrame(AnimationState& aState,
|
|
||||||
DrawableSurface& aFrames,
|
|
||||||
uint32_t aFrameNum) const
|
|
||||||
{
|
|
||||||
RawAccessFrameRef frame = GetRawFrame(aFrames, aFrameNum);
|
|
||||||
if (frame) {
|
|
||||||
AnimationData data = frame->GetAnimationData();
|
|
||||||
return Some(data.mTimeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(aState.mHasRequestedDecode && !aState.mIsCurrentlyDecoded);
|
|
||||||
return Nothing();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
DoCollectSizeOfCompositingSurfaces(const RawAccessFrameRef& aSurface,
|
DoCollectSizeOfCompositingSurfaces(const RawAccessFrameRef& aSurface,
|
||||||
SurfaceMemoryCounterType aType,
|
SurfaceMemoryCounterType aType,
|
||||||
|
@ -615,64 +592,44 @@ FrameAnimator::CollectSizeOfCompositingSurfaces(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RawAccessFrameRef
|
|
||||||
FrameAnimator::GetRawFrame(DrawableSurface& aFrames, uint32_t aFrameNum) const
|
|
||||||
{
|
|
||||||
// Seek to the frame we want. If seeking fails, it means we couldn't get the
|
|
||||||
// frame we're looking for, so we bail here to avoid returning the wrong frame
|
|
||||||
// to the caller.
|
|
||||||
if (NS_FAILED(aFrames.Seek(aFrameNum))) {
|
|
||||||
return RawAccessFrameRef(); // Not available yet.
|
|
||||||
}
|
|
||||||
|
|
||||||
return aFrames->RawAccessRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
// DoBlend gets called when the timer for animation get fired and we have to
|
// DoBlend gets called when the timer for animation get fired and we have to
|
||||||
// update the composited frame of the animation.
|
// update the composited frame of the animation.
|
||||||
bool
|
bool
|
||||||
FrameAnimator::DoBlend(DrawableSurface& aFrames,
|
FrameAnimator::DoBlend(const RawAccessFrameRef& aPrevFrame,
|
||||||
IntRect* aDirtyRect,
|
const RawAccessFrameRef& aNextFrame,
|
||||||
uint32_t aPrevFrameIndex,
|
uint32_t aNextFrameIndex,
|
||||||
uint32_t aNextFrameIndex)
|
IntRect* aDirtyRect)
|
||||||
{
|
{
|
||||||
RawAccessFrameRef prevFrame = GetRawFrame(aFrames, aPrevFrameIndex);
|
MOZ_ASSERT(aPrevFrame && aNextFrame, "Should have frames here");
|
||||||
RawAccessFrameRef nextFrame = GetRawFrame(aFrames, aNextFrameIndex);
|
|
||||||
|
|
||||||
MOZ_ASSERT(prevFrame && nextFrame, "Should have frames here");
|
DisposalMethod prevDisposalMethod = aPrevFrame->GetDisposalMethod();
|
||||||
|
bool prevHasAlpha = aPrevFrame->FormatHasAlpha();
|
||||||
AnimationData prevFrameData = prevFrame->GetAnimationData();
|
if (prevDisposalMethod == DisposalMethod::RESTORE_PREVIOUS &&
|
||||||
if (prevFrameData.mDisposalMethod == DisposalMethod::RESTORE_PREVIOUS &&
|
|
||||||
!mCompositingPrevFrame) {
|
!mCompositingPrevFrame) {
|
||||||
prevFrameData.mDisposalMethod = DisposalMethod::CLEAR;
|
prevDisposalMethod = DisposalMethod::CLEAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
IntRect prevRect = prevFrameData.mBlendRect
|
IntRect prevRect = aPrevFrame->GetBoundedBlendRect();
|
||||||
? prevFrameData.mRect.Intersect(*prevFrameData.mBlendRect)
|
|
||||||
: prevFrameData.mRect;
|
|
||||||
|
|
||||||
bool isFullPrevFrame = prevRect.IsEqualRect(0, 0, mSize.width, mSize.height);
|
bool isFullPrevFrame = prevRect.IsEqualRect(0, 0, mSize.width, mSize.height);
|
||||||
|
|
||||||
// Optimization: DisposeClearAll if the previous frame is the same size as
|
// Optimization: DisposeClearAll if the previous frame is the same size as
|
||||||
// container and it's clearing itself
|
// container and it's clearing itself
|
||||||
if (isFullPrevFrame &&
|
if (isFullPrevFrame &&
|
||||||
(prevFrameData.mDisposalMethod == DisposalMethod::CLEAR)) {
|
(prevDisposalMethod == DisposalMethod::CLEAR)) {
|
||||||
prevFrameData.mDisposalMethod = DisposalMethod::CLEAR_ALL;
|
prevDisposalMethod = DisposalMethod::CLEAR_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationData nextFrameData = nextFrame->GetAnimationData();
|
DisposalMethod nextDisposalMethod = aNextFrame->GetDisposalMethod();
|
||||||
|
bool nextHasAlpha = aNextFrame->FormatHasAlpha();
|
||||||
IntRect nextRect = nextFrameData.mBlendRect
|
|
||||||
? nextFrameData.mRect.Intersect(*nextFrameData.mBlendRect)
|
|
||||||
: nextFrameData.mRect;
|
|
||||||
|
|
||||||
|
IntRect nextRect = aNextFrame->GetBoundedBlendRect();
|
||||||
bool isFullNextFrame = nextRect.IsEqualRect(0, 0, mSize.width, mSize.height);
|
bool isFullNextFrame = nextRect.IsEqualRect(0, 0, mSize.width, mSize.height);
|
||||||
|
|
||||||
if (!nextFrame->GetIsPaletted()) {
|
if (!aNextFrame->GetIsPaletted()) {
|
||||||
// Optimization: Skip compositing if the previous frame wants to clear the
|
// Optimization: Skip compositing if the previous frame wants to clear the
|
||||||
// whole image
|
// whole image
|
||||||
if (prevFrameData.mDisposalMethod == DisposalMethod::CLEAR_ALL) {
|
if (prevDisposalMethod == DisposalMethod::CLEAR_ALL) {
|
||||||
aDirtyRect->SetRect(0, 0, mSize.width, mSize.height);
|
aDirtyRect->SetRect(0, 0, mSize.width, mSize.height);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -680,15 +637,15 @@ FrameAnimator::DoBlend(DrawableSurface& aFrames,
|
||||||
// Optimization: Skip compositing if this frame is the same size as the
|
// Optimization: Skip compositing if this frame is the same size as the
|
||||||
// container and it's fully drawing over prev frame (no alpha)
|
// container and it's fully drawing over prev frame (no alpha)
|
||||||
if (isFullNextFrame &&
|
if (isFullNextFrame &&
|
||||||
(nextFrameData.mDisposalMethod != DisposalMethod::RESTORE_PREVIOUS) &&
|
(nextDisposalMethod != DisposalMethod::RESTORE_PREVIOUS) &&
|
||||||
!nextFrameData.mHasAlpha) {
|
!nextHasAlpha) {
|
||||||
aDirtyRect->SetRect(0, 0, mSize.width, mSize.height);
|
aDirtyRect->SetRect(0, 0, mSize.width, mSize.height);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate area that needs updating
|
// Calculate area that needs updating
|
||||||
switch (prevFrameData.mDisposalMethod) {
|
switch (prevDisposalMethod) {
|
||||||
default:
|
default:
|
||||||
MOZ_FALLTHROUGH_ASSERT("Unexpected DisposalMethod");
|
MOZ_FALLTHROUGH_ASSERT("Unexpected DisposalMethod");
|
||||||
case DisposalMethod::NOT_SPECIFIED:
|
case DisposalMethod::NOT_SPECIFIED:
|
||||||
|
@ -705,7 +662,7 @@ FrameAnimator::DoBlend(DrawableSurface& aFrames,
|
||||||
// Calc area that needs to be redrawn (the combination of previous and
|
// Calc area that needs to be redrawn (the combination of previous and
|
||||||
// this frame)
|
// this frame)
|
||||||
// XXX - This could be done with multiple framechanged calls
|
// XXX - This could be done with multiple framechanged calls
|
||||||
// Having prevFrame way at the top of the image, and nextFrame
|
// Having aPrevFrame way at the top of the image, and aNextFrame
|
||||||
// way at the bottom, and both frames being small, we'd be
|
// way at the bottom, and both frames being small, we'd be
|
||||||
// telling framechanged to refresh the whole image when only two
|
// telling framechanged to refresh the whole image when only two
|
||||||
// small areas are needed.
|
// small areas are needed.
|
||||||
|
@ -747,8 +704,6 @@ FrameAnimator::DoBlend(DrawableSurface& aFrames,
|
||||||
needToBlankComposite = true;
|
needToBlankComposite = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationData compositingFrameData = mCompositingFrame->GetAnimationData();
|
|
||||||
|
|
||||||
// More optimizations possible when next frame is not transparent
|
// More optimizations possible when next frame is not transparent
|
||||||
// But if the next frame has DisposalMethod::RESTORE_PREVIOUS,
|
// But if the next frame has DisposalMethod::RESTORE_PREVIOUS,
|
||||||
// this "no disposal" optimization is not possible,
|
// this "no disposal" optimization is not possible,
|
||||||
|
@ -756,8 +711,7 @@ FrameAnimator::DoBlend(DrawableSurface& aFrames,
|
||||||
// needs to be stored in compositingFrame, so it can be
|
// needs to be stored in compositingFrame, so it can be
|
||||||
// copied into compositingPrevFrame later.
|
// copied into compositingPrevFrame later.
|
||||||
bool doDisposal = true;
|
bool doDisposal = true;
|
||||||
if (!nextFrameData.mHasAlpha &&
|
if (!nextHasAlpha && nextDisposalMethod != DisposalMethod::RESTORE_PREVIOUS) {
|
||||||
nextFrameData.mDisposalMethod != DisposalMethod::RESTORE_PREVIOUS) {
|
|
||||||
if (isFullNextFrame) {
|
if (isFullNextFrame) {
|
||||||
// Optimization: No need to dispose prev.frame when
|
// Optimization: No need to dispose prev.frame when
|
||||||
// next frame is full frame and not transparent.
|
// next frame is full frame and not transparent.
|
||||||
|
@ -777,46 +731,42 @@ FrameAnimator::DoBlend(DrawableSurface& aFrames,
|
||||||
|
|
||||||
if (doDisposal) {
|
if (doDisposal) {
|
||||||
// Dispose of previous: clear, restore, or keep (copy)
|
// Dispose of previous: clear, restore, or keep (copy)
|
||||||
switch (prevFrameData.mDisposalMethod) {
|
switch (prevDisposalMethod) {
|
||||||
case DisposalMethod::CLEAR:
|
case DisposalMethod::CLEAR:
|
||||||
if (needToBlankComposite) {
|
if (needToBlankComposite) {
|
||||||
// If we just created the composite, it could have anything in its
|
// If we just created the composite, it could have anything in its
|
||||||
// buffer. Clear whole frame
|
// buffer. Clear whole frame
|
||||||
ClearFrame(compositingFrameData.mRawData,
|
ClearFrame(mCompositingFrame.Data(),
|
||||||
compositingFrameData.mRect);
|
mCompositingFrame->GetRect());
|
||||||
} else {
|
} else {
|
||||||
// Only blank out previous frame area (both color & Mask/Alpha)
|
// Only blank out previous frame area (both color & Mask/Alpha)
|
||||||
ClearFrame(compositingFrameData.mRawData,
|
ClearFrame(mCompositingFrame.Data(),
|
||||||
compositingFrameData.mRect,
|
mCompositingFrame->GetRect(),
|
||||||
prevRect);
|
prevRect);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DisposalMethod::CLEAR_ALL:
|
case DisposalMethod::CLEAR_ALL:
|
||||||
ClearFrame(compositingFrameData.mRawData,
|
ClearFrame(mCompositingFrame.Data(),
|
||||||
compositingFrameData.mRect);
|
mCompositingFrame->GetRect());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DisposalMethod::RESTORE_PREVIOUS:
|
case DisposalMethod::RESTORE_PREVIOUS:
|
||||||
// It would be better to copy only the area changed back to
|
// It would be better to copy only the area changed back to
|
||||||
// compositingFrame.
|
// compositingFrame.
|
||||||
if (mCompositingPrevFrame) {
|
if (mCompositingPrevFrame) {
|
||||||
AnimationData compositingPrevFrameData =
|
CopyFrameImage(mCompositingPrevFrame.Data(),
|
||||||
mCompositingPrevFrame->GetAnimationData();
|
mCompositingPrevFrame->GetRect(),
|
||||||
|
mCompositingFrame.Data(),
|
||||||
CopyFrameImage(compositingPrevFrameData.mRawData,
|
mCompositingFrame->GetRect());
|
||||||
compositingPrevFrameData.mRect,
|
|
||||||
compositingFrameData.mRawData,
|
|
||||||
compositingFrameData.mRect);
|
|
||||||
|
|
||||||
// destroy only if we don't need it for this frame's disposal
|
// destroy only if we don't need it for this frame's disposal
|
||||||
if (nextFrameData.mDisposalMethod !=
|
if (nextDisposalMethod != DisposalMethod::RESTORE_PREVIOUS) {
|
||||||
DisposalMethod::RESTORE_PREVIOUS) {
|
|
||||||
mCompositingPrevFrame.reset();
|
mCompositingPrevFrame.reset();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ClearFrame(compositingFrameData.mRawData,
|
ClearFrame(mCompositingFrame.Data(),
|
||||||
compositingFrameData.mRect);
|
mCompositingFrame->GetRect());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -832,44 +782,44 @@ FrameAnimator::DoBlend(DrawableSurface& aFrames,
|
||||||
// Note: Frame 1 never gets into DoBlend(), so (aNextFrameIndex - 1)
|
// Note: Frame 1 never gets into DoBlend(), so (aNextFrameIndex - 1)
|
||||||
// will always be a valid frame number.
|
// will always be a valid frame number.
|
||||||
if (mLastCompositedFrameIndex != int32_t(aNextFrameIndex - 1)) {
|
if (mLastCompositedFrameIndex != int32_t(aNextFrameIndex - 1)) {
|
||||||
if (isFullPrevFrame && !prevFrame->GetIsPaletted()) {
|
if (isFullPrevFrame && !aPrevFrame->GetIsPaletted()) {
|
||||||
// Just copy the bits
|
// Just copy the bits
|
||||||
CopyFrameImage(prevFrameData.mRawData,
|
CopyFrameImage(aPrevFrame.Data(),
|
||||||
prevRect,
|
prevRect,
|
||||||
compositingFrameData.mRawData,
|
mCompositingFrame.Data(),
|
||||||
compositingFrameData.mRect);
|
mCompositingFrame->GetRect());
|
||||||
} else {
|
} else {
|
||||||
if (needToBlankComposite) {
|
if (needToBlankComposite) {
|
||||||
// Only blank composite when prev is transparent or not full.
|
// Only blank composite when prev is transparent or not full.
|
||||||
if (prevFrameData.mHasAlpha || !isFullPrevFrame) {
|
if (prevHasAlpha || !isFullPrevFrame) {
|
||||||
ClearFrame(compositingFrameData.mRawData,
|
ClearFrame(mCompositingFrame.Data(),
|
||||||
compositingFrameData.mRect);
|
mCompositingFrame->GetRect());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DrawFrameTo(prevFrameData.mRawData, prevFrameData.mRect,
|
DrawFrameTo(aPrevFrame.Data(), aPrevFrame->GetRect(),
|
||||||
prevFrameData.mPaletteDataLength,
|
aPrevFrame.PaletteDataLength(),
|
||||||
prevFrameData.mHasAlpha,
|
prevHasAlpha,
|
||||||
compositingFrameData.mRawData,
|
mCompositingFrame.Data(),
|
||||||
compositingFrameData.mRect,
|
mCompositingFrame->GetRect(),
|
||||||
prevFrameData.mBlendMethod,
|
aPrevFrame->GetBlendMethod(),
|
||||||
prevFrameData.mBlendRect);
|
aPrevFrame->GetBlendRect());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (needToBlankComposite) {
|
} else if (needToBlankComposite) {
|
||||||
// If we just created the composite, it could have anything in its
|
// If we just created the composite, it could have anything in its
|
||||||
// buffers. Clear them
|
// buffers. Clear them
|
||||||
ClearFrame(compositingFrameData.mRawData,
|
ClearFrame(mCompositingFrame.Data(),
|
||||||
compositingFrameData.mRect);
|
mCompositingFrame->GetRect());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the frame we are composing wants the previous image restored after
|
// Check if the frame we are composing wants the previous image restored after
|
||||||
// it is done. Don't store it (again) if last frame wanted its image restored
|
// it is done. Don't store it (again) if last frame wanted its image restored
|
||||||
// too
|
// too
|
||||||
if ((nextFrameData.mDisposalMethod == DisposalMethod::RESTORE_PREVIOUS) &&
|
if ((nextDisposalMethod == DisposalMethod::RESTORE_PREVIOUS) &&
|
||||||
(prevFrameData.mDisposalMethod != DisposalMethod::RESTORE_PREVIOUS)) {
|
(prevDisposalMethod != DisposalMethod::RESTORE_PREVIOUS)) {
|
||||||
// We are storing the whole image.
|
// We are storing the whole image.
|
||||||
// It would be better if we just stored the area that nextFrame is going to
|
// It would be better if we just stored the area that aNextFrame is going to
|
||||||
// overwrite.
|
// overwrite.
|
||||||
if (!mCompositingPrevFrame) {
|
if (!mCompositingPrevFrame) {
|
||||||
RefPtr<imgFrame> newFrame = new imgFrame;
|
RefPtr<imgFrame> newFrame = new imgFrame;
|
||||||
|
@ -883,25 +833,22 @@ FrameAnimator::DoBlend(DrawableSurface& aFrames,
|
||||||
mCompositingPrevFrame = newFrame->RawAccessRef();
|
mCompositingPrevFrame = newFrame->RawAccessRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationData compositingPrevFrameData =
|
CopyFrameImage(mCompositingFrame.Data(),
|
||||||
mCompositingPrevFrame->GetAnimationData();
|
mCompositingFrame->GetRect(),
|
||||||
|
mCompositingPrevFrame.Data(),
|
||||||
CopyFrameImage(compositingFrameData.mRawData,
|
mCompositingPrevFrame->GetRect());
|
||||||
compositingFrameData.mRect,
|
|
||||||
compositingPrevFrameData.mRawData,
|
|
||||||
compositingPrevFrameData.mRect);
|
|
||||||
|
|
||||||
mCompositingPrevFrame->Finish();
|
mCompositingPrevFrame->Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
// blit next frame into it's correct spot
|
// blit next frame into it's correct spot
|
||||||
DrawFrameTo(nextFrameData.mRawData, nextFrameData.mRect,
|
DrawFrameTo(aNextFrame.Data(), aNextFrame->GetRect(),
|
||||||
nextFrameData.mPaletteDataLength,
|
aNextFrame.PaletteDataLength(),
|
||||||
nextFrameData.mHasAlpha,
|
nextHasAlpha,
|
||||||
compositingFrameData.mRawData,
|
mCompositingFrame.Data(),
|
||||||
compositingFrameData.mRect,
|
mCompositingFrame->GetRect(),
|
||||||
nextFrameData.mBlendMethod,
|
aNextFrame->GetBlendMethod(),
|
||||||
nextFrameData.mBlendRect);
|
aNextFrame->GetBlendRect());
|
||||||
|
|
||||||
// Tell the image that it is fully 'downloaded'.
|
// Tell the image that it is fully 'downloaded'.
|
||||||
mCompositingFrame->Finish();
|
mCompositingFrame->Finish();
|
||||||
|
@ -970,7 +917,7 @@ nsresult
|
||||||
FrameAnimator::DrawFrameTo(const uint8_t* aSrcData, const IntRect& aSrcRect,
|
FrameAnimator::DrawFrameTo(const uint8_t* aSrcData, const IntRect& aSrcRect,
|
||||||
uint32_t aSrcPaletteLength, bool aSrcHasAlpha,
|
uint32_t aSrcPaletteLength, bool aSrcHasAlpha,
|
||||||
uint8_t* aDstPixels, const IntRect& aDstRect,
|
uint8_t* aDstPixels, const IntRect& aDstRect,
|
||||||
BlendMethod aBlendMethod, const Maybe<IntRect>& aBlendRect)
|
BlendMethod aBlendMethod, const IntRect& aBlendRect)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(aSrcData);
|
NS_ENSURE_ARG_POINTER(aSrcData);
|
||||||
NS_ENSURE_ARG_POINTER(aDstPixels);
|
NS_ENSURE_ARG_POINTER(aDstPixels);
|
||||||
|
@ -1067,8 +1014,8 @@ FrameAnimator::DrawFrameTo(const uint8_t* aSrcData, const IntRect& aSrcRect,
|
||||||
auto op = aBlendMethod == BlendMethod::SOURCE ? PIXMAN_OP_SRC
|
auto op = aBlendMethod == BlendMethod::SOURCE ? PIXMAN_OP_SRC
|
||||||
: PIXMAN_OP_OVER;
|
: PIXMAN_OP_OVER;
|
||||||
|
|
||||||
if (aBlendMethod == BlendMethod::OVER || !aBlendRect ||
|
if (aBlendMethod == BlendMethod::OVER ||
|
||||||
(aBlendMethod == BlendMethod::SOURCE && aSrcRect.IsEqualEdges(*aBlendRect))) {
|
(aBlendMethod == BlendMethod::SOURCE && aSrcRect.IsEqualEdges(aBlendRect))) {
|
||||||
// We don't need to do anything clever. (Or, in the case where no blend
|
// We don't need to do anything clever. (Or, in the case where no blend
|
||||||
// rect was specified, we can't.)
|
// rect was specified, we can't.)
|
||||||
pixman_image_composite32(op,
|
pixman_image_composite32(op,
|
||||||
|
@ -1093,10 +1040,10 @@ FrameAnimator::DrawFrameTo(const uint8_t* aSrcData, const IntRect& aSrcRect,
|
||||||
src,
|
src,
|
||||||
nullptr,
|
nullptr,
|
||||||
dst,
|
dst,
|
||||||
aBlendRect->X(), aBlendRect->Y(),
|
aBlendRect.X(), aBlendRect.Y(),
|
||||||
0, 0,
|
0, 0,
|
||||||
aBlendRect->X(), aBlendRect->Y(),
|
aBlendRect.X(), aBlendRect.Y(),
|
||||||
aBlendRect->Width(), aBlendRect->Height());
|
aBlendRect.Width(), aBlendRect.Height());
|
||||||
}
|
}
|
||||||
|
|
||||||
pixman_image_unref(src);
|
pixman_image_unref(src);
|
||||||
|
|
|
@ -343,37 +343,31 @@ private: // methods
|
||||||
* @param aTime the time that the animation should advance to. This will
|
* @param aTime the time that the animation should advance to. This will
|
||||||
* typically be <= TimeStamp::Now().
|
* typically be <= TimeStamp::Now().
|
||||||
*
|
*
|
||||||
|
* @param aCurrentFrame the currently displayed frame of the animation. If
|
||||||
|
* we advance, it will replace aCurrentFrame with the
|
||||||
|
* new current frame we advanced to.
|
||||||
|
*
|
||||||
* @returns a RefreshResult that shows whether the frame was successfully
|
* @returns a RefreshResult that shows whether the frame was successfully
|
||||||
* advanced, and its resulting dirty rect.
|
* advanced, and its resulting dirty rect.
|
||||||
*/
|
*/
|
||||||
RefreshResult AdvanceFrame(AnimationState& aState,
|
RefreshResult AdvanceFrame(AnimationState& aState,
|
||||||
DrawableSurface& aFrames,
|
DrawableSurface& aFrames,
|
||||||
|
RawAccessFrameRef& aCurrentFrame,
|
||||||
TimeStamp aTime);
|
TimeStamp aTime);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the @aIndex-th frame in the frame index, ignoring results of blending.
|
|
||||||
*/
|
|
||||||
RawAccessFrameRef GetRawFrame(DrawableSurface& aFrames,
|
|
||||||
uint32_t aFrameNum) const;
|
|
||||||
|
|
||||||
/// @return the given frame's timeout if it is available
|
|
||||||
Maybe<FrameTimeout> GetTimeoutForFrame(AnimationState& aState,
|
|
||||||
DrawableSurface& aFrames,
|
|
||||||
uint32_t aFrameNum) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the time the frame we're currently displaying is supposed to end.
|
* Get the time the frame we're currently displaying is supposed to end.
|
||||||
*
|
*
|
||||||
* In the error case (like if the requested frame is not currently
|
* In the error case (like if the requested frame is not currently
|
||||||
* decoded), returns None().
|
* decoded), returns None().
|
||||||
*/
|
*/
|
||||||
Maybe<TimeStamp> GetCurrentImgFrameEndTime(AnimationState& aState,
|
TimeStamp GetCurrentImgFrameEndTime(AnimationState& aState,
|
||||||
DrawableSurface& aFrames) const;
|
FrameTimeout aCurrentTimeout) const;
|
||||||
|
|
||||||
bool DoBlend(DrawableSurface& aFrames,
|
bool DoBlend(const RawAccessFrameRef& aPrevFrame,
|
||||||
gfx::IntRect* aDirtyRect,
|
const RawAccessFrameRef& aNextFrame,
|
||||||
uint32_t aPrevFrameIndex,
|
uint32_t aNextFrameIndex,
|
||||||
uint32_t aNextFrameIndex);
|
gfx::IntRect* aDirtyRect);
|
||||||
|
|
||||||
/** Clears an area of <aFrame> with transparent black.
|
/** Clears an area of <aFrame> with transparent black.
|
||||||
*
|
*
|
||||||
|
@ -413,7 +407,7 @@ private: // methods
|
||||||
uint32_t aSrcPaletteLength, bool aSrcHasAlpha,
|
uint32_t aSrcPaletteLength, bool aSrcHasAlpha,
|
||||||
uint8_t* aDstPixels, const gfx::IntRect& aDstRect,
|
uint8_t* aDstPixels, const gfx::IntRect& aDstRect,
|
||||||
BlendMethod aBlendMethod,
|
BlendMethod aBlendMethod,
|
||||||
const Maybe<gfx::IntRect>& aBlendRect);
|
const gfx::IntRect& aBlendRect);
|
||||||
|
|
||||||
private: // data
|
private: // data
|
||||||
//! A weak pointer to our owning image.
|
//! A weak pointer to our owning image.
|
||||||
|
|
|
@ -110,6 +110,15 @@ protected:
|
||||||
/// index of the desired frame.
|
/// index of the desired frame.
|
||||||
virtual DrawableFrameRef DrawableRef(size_t aFrame) = 0;
|
virtual DrawableFrameRef DrawableRef(size_t aFrame) = 0;
|
||||||
|
|
||||||
|
/// @return an eagerly computed raw access reference to a surface. For
|
||||||
|
/// dynamically generated animation surfaces, @aFrame specifies the 0-based
|
||||||
|
/// index of the desired frame.
|
||||||
|
virtual RawAccessFrameRef RawAccessRef(size_t aFrame)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT_UNREACHABLE("Surface provider does not support raw access!");
|
||||||
|
return RawAccessFrameRef();
|
||||||
|
}
|
||||||
|
|
||||||
/// @return true if this ISurfaceProvider is locked. (@see SetLocked())
|
/// @return true if this ISurfaceProvider is locked. (@see SetLocked())
|
||||||
/// Should only be called from SurfaceCache code as it relies on SurfaceCache
|
/// Should only be called from SurfaceCache code as it relies on SurfaceCache
|
||||||
/// for synchronization.
|
/// for synchronization.
|
||||||
|
@ -199,6 +208,18 @@ public:
|
||||||
return mDrawableRef ? NS_OK : NS_ERROR_FAILURE;
|
return mDrawableRef ? NS_OK : NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RawAccessFrameRef RawAccessRef(size_t aFrame)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mHaveSurface, "Trying to get on an empty DrawableSurface?");
|
||||||
|
|
||||||
|
if (!mProvider) {
|
||||||
|
MOZ_ASSERT_UNREACHABLE("Trying to get on a static DrawableSurface?");
|
||||||
|
return RawAccessFrameRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
return mProvider->RawAccessRef(aFrame);
|
||||||
|
}
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
if (!mProvider) {
|
if (!mProvider) {
|
||||||
|
|
|
@ -70,7 +70,7 @@ public:
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template <typename... Rest>
|
template <typename... Rest>
|
||||||
nsresult Configure(const DeinterlacingConfig<PixelType>& aConfig, Rest... aRest)
|
nsresult Configure(const DeinterlacingConfig<PixelType>& aConfig, const Rest&... aRest)
|
||||||
{
|
{
|
||||||
nsresult rv = mNext.Configure(aRest...);
|
nsresult rv = mNext.Configure(aRest...);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
@ -360,7 +360,7 @@ public:
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template <typename... Rest>
|
template <typename... Rest>
|
||||||
nsresult Configure(const RemoveFrameRectConfig& aConfig, Rest... aRest)
|
nsresult Configure(const RemoveFrameRectConfig& aConfig, const Rest&... aRest)
|
||||||
{
|
{
|
||||||
nsresult rv = mNext.Configure(aRest...);
|
nsresult rv = mNext.Configure(aRest...);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
@ -590,7 +590,7 @@ public:
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template <typename... Rest>
|
template <typename... Rest>
|
||||||
nsresult Configure(const ADAM7InterpolatingConfig& aConfig, Rest... aRest)
|
nsresult Configure(const ADAM7InterpolatingConfig& aConfig, const Rest&... aRest)
|
||||||
{
|
{
|
||||||
nsresult rv = mNext.Configure(aRest...);
|
nsresult rv = mNext.Configure(aRest...);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
|
|
@ -75,10 +75,11 @@ SurfaceSink::Configure(const SurfaceConfig& aConfig)
|
||||||
// XXX(seth): Once every Decoder subclass uses SurfacePipe, we probably want
|
// XXX(seth): Once every Decoder subclass uses SurfacePipe, we probably want
|
||||||
// to allocate the frame directly here and get rid of Decoder::AllocateFrame
|
// to allocate the frame directly here and get rid of Decoder::AllocateFrame
|
||||||
// altogether.
|
// altogether.
|
||||||
nsresult rv = aConfig.mDecoder->AllocateFrame(aConfig.mFrameNum,
|
nsresult rv = aConfig.mDecoder->AllocateFrame(surfaceSize,
|
||||||
surfaceSize,
|
|
||||||
frameRect,
|
frameRect,
|
||||||
aConfig.mFormat);
|
aConfig.mFormat,
|
||||||
|
/* aPaletteDepth */ 0,
|
||||||
|
aConfig.mAnimParams);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -127,11 +128,11 @@ PalettedSurfaceSink::Configure(const PalettedSurfaceConfig& aConfig)
|
||||||
// XXX(seth): Once every Decoder subclass uses SurfacePipe, we probably want
|
// XXX(seth): Once every Decoder subclass uses SurfacePipe, we probably want
|
||||||
// to allocate the frame directly here and get rid of Decoder::AllocateFrame
|
// to allocate the frame directly here and get rid of Decoder::AllocateFrame
|
||||||
// altogether.
|
// altogether.
|
||||||
nsresult rv = aConfig.mDecoder->AllocateFrame(aConfig.mFrameNum,
|
nsresult rv = aConfig.mDecoder->AllocateFrame(aConfig.mOutputSize,
|
||||||
aConfig.mOutputSize,
|
|
||||||
aConfig.mFrameRect,
|
aConfig.mFrameRect,
|
||||||
aConfig.mFormat,
|
aConfig.mFormat,
|
||||||
aConfig.mPaletteDepth);
|
aConfig.mPaletteDepth,
|
||||||
|
aConfig.mAnimParams);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#include "mozilla/Variant.h"
|
#include "mozilla/Variant.h"
|
||||||
#include "mozilla/gfx/2D.h"
|
#include "mozilla/gfx/2D.h"
|
||||||
|
|
||||||
|
#include "AnimationParams.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace image {
|
namespace image {
|
||||||
|
|
||||||
|
@ -775,10 +777,10 @@ struct SurfaceConfig
|
||||||
{
|
{
|
||||||
using Filter = SurfaceSink;
|
using Filter = SurfaceSink;
|
||||||
Decoder* mDecoder; /// Which Decoder to use to allocate the surface.
|
Decoder* mDecoder; /// Which Decoder to use to allocate the surface.
|
||||||
uint32_t mFrameNum; /// Which frame of animation this surface is for.
|
|
||||||
gfx::IntSize mOutputSize; /// The size of the surface.
|
gfx::IntSize mOutputSize; /// The size of the surface.
|
||||||
gfx::SurfaceFormat mFormat; /// The surface format (BGRA or BGRX).
|
gfx::SurfaceFormat mFormat; /// The surface format (BGRA or BGRX).
|
||||||
bool mFlipVertically; /// If true, write the rows from bottom to top.
|
bool mFlipVertically; /// If true, write the rows from bottom to top.
|
||||||
|
Maybe<AnimationParams> mAnimParams; /// Given for animated images.
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -803,12 +805,12 @@ struct PalettedSurfaceConfig
|
||||||
{
|
{
|
||||||
using Filter = PalettedSurfaceSink;
|
using Filter = PalettedSurfaceSink;
|
||||||
Decoder* mDecoder; /// Which Decoder to use to allocate the surface.
|
Decoder* mDecoder; /// Which Decoder to use to allocate the surface.
|
||||||
uint32_t mFrameNum; /// Which frame of animation this surface is for.
|
|
||||||
gfx::IntSize mOutputSize; /// The logical size of the surface.
|
gfx::IntSize mOutputSize; /// The logical size of the surface.
|
||||||
gfx::IntRect mFrameRect; /// The surface subrect which contains data.
|
gfx::IntRect mFrameRect; /// The surface subrect which contains data.
|
||||||
gfx::SurfaceFormat mFormat; /// The surface format (BGRA or BGRX).
|
gfx::SurfaceFormat mFormat; /// The surface format (BGRA or BGRX).
|
||||||
uint8_t mPaletteDepth; /// The palette depth of this surface.
|
uint8_t mPaletteDepth; /// The palette depth of this surface.
|
||||||
bool mFlipVertically; /// If true, write the rows from bottom to top.
|
bool mFlipVertically; /// If true, write the rows from bottom to top.
|
||||||
|
Maybe<AnimationParams> mAnimParams; /// Given for animated images.
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -70,8 +70,6 @@ public:
|
||||||
*
|
*
|
||||||
* @param aDecoder The decoder whose current frame the SurfacePipe will write
|
* @param aDecoder The decoder whose current frame the SurfacePipe will write
|
||||||
* to.
|
* to.
|
||||||
* @param aFrameNum Which frame the SurfacePipe will write to. This will be 0
|
|
||||||
* for non-animated images.
|
|
||||||
* @param aInputSize The original size of the image.
|
* @param aInputSize The original size of the image.
|
||||||
* @param aOutputSize The size the SurfacePipe should output. Must be the same
|
* @param aOutputSize The size the SurfacePipe should output. Must be the same
|
||||||
* as @aInputSize or smaller. If smaller, the image will be
|
* as @aInputSize or smaller. If smaller, the image will be
|
||||||
|
@ -79,6 +77,7 @@ public:
|
||||||
* @param aFrameRect The portion of the image that actually contains data.
|
* @param aFrameRect The portion of the image that actually contains data.
|
||||||
* @param aFormat The surface format of the image; generally B8G8R8A8 or
|
* @param aFormat The surface format of the image; generally B8G8R8A8 or
|
||||||
* B8G8R8X8.
|
* B8G8R8X8.
|
||||||
|
* @param aAnimParams Extra parameters used by animated images.
|
||||||
* @param aFlags Flags enabling or disabling various functionality for the
|
* @param aFlags Flags enabling or disabling various functionality for the
|
||||||
* SurfacePipe; see the SurfacePipeFlags documentation for more
|
* SurfacePipe; see the SurfacePipeFlags documentation for more
|
||||||
* information.
|
* information.
|
||||||
|
@ -89,11 +88,11 @@ public:
|
||||||
*/
|
*/
|
||||||
static Maybe<SurfacePipe>
|
static Maybe<SurfacePipe>
|
||||||
CreateSurfacePipe(Decoder* aDecoder,
|
CreateSurfacePipe(Decoder* aDecoder,
|
||||||
uint32_t aFrameNum,
|
|
||||||
const nsIntSize& aInputSize,
|
const nsIntSize& aInputSize,
|
||||||
const nsIntSize& aOutputSize,
|
const nsIntSize& aOutputSize,
|
||||||
const nsIntRect& aFrameRect,
|
const nsIntRect& aFrameRect,
|
||||||
gfx::SurfaceFormat aFormat,
|
gfx::SurfaceFormat aFormat,
|
||||||
|
const Maybe<AnimationParams>& aAnimParams,
|
||||||
SurfacePipeFlags aFlags)
|
SurfacePipeFlags aFlags)
|
||||||
{
|
{
|
||||||
const bool deinterlace = bool(aFlags & SurfacePipeFlags::DEINTERLACE);
|
const bool deinterlace = bool(aFlags & SurfacePipeFlags::DEINTERLACE);
|
||||||
|
@ -125,8 +124,8 @@ public:
|
||||||
ADAM7InterpolatingConfig interpolatingConfig;
|
ADAM7InterpolatingConfig interpolatingConfig;
|
||||||
RemoveFrameRectConfig removeFrameRectConfig { aFrameRect };
|
RemoveFrameRectConfig removeFrameRectConfig { aFrameRect };
|
||||||
DownscalingConfig downscalingConfig { aInputSize, aFormat };
|
DownscalingConfig downscalingConfig { aInputSize, aFormat };
|
||||||
SurfaceConfig surfaceConfig { aDecoder, aFrameNum, aOutputSize,
|
SurfaceConfig surfaceConfig { aDecoder, aOutputSize, aFormat,
|
||||||
aFormat, flipVertically };
|
flipVertically, aAnimParams };
|
||||||
|
|
||||||
Maybe<SurfacePipe> pipe;
|
Maybe<SurfacePipe> pipe;
|
||||||
|
|
||||||
|
@ -181,13 +180,12 @@ public:
|
||||||
*
|
*
|
||||||
* @param aDecoder The decoder whose current frame the SurfacePipe will write
|
* @param aDecoder The decoder whose current frame the SurfacePipe will write
|
||||||
* to.
|
* to.
|
||||||
* @param aFrameNum Which frame the SurfacePipe will write to. This will be 0
|
|
||||||
* for non-animated images.
|
|
||||||
* @param aInputSize The original size of the image.
|
* @param aInputSize The original size of the image.
|
||||||
* @param aFrameRect The portion of the image that actually contains data.
|
* @param aFrameRect The portion of the image that actually contains data.
|
||||||
* @param aFormat The surface format of the image; generally B8G8R8A8 or
|
* @param aFormat The surface format of the image; generally B8G8R8A8 or
|
||||||
* B8G8R8X8.
|
* B8G8R8X8.
|
||||||
* @param aPaletteDepth The palette depth of the image.
|
* @param aPaletteDepth The palette depth of the image.
|
||||||
|
* @param aAnimParams Extra parameters used by animated images.
|
||||||
* @param aFlags Flags enabling or disabling various functionality for the
|
* @param aFlags Flags enabling or disabling various functionality for the
|
||||||
* SurfacePipe; see the SurfacePipeFlags documentation for more
|
* SurfacePipe; see the SurfacePipeFlags documentation for more
|
||||||
* information.
|
* information.
|
||||||
|
@ -198,11 +196,11 @@ public:
|
||||||
*/
|
*/
|
||||||
static Maybe<SurfacePipe>
|
static Maybe<SurfacePipe>
|
||||||
CreatePalettedSurfacePipe(Decoder* aDecoder,
|
CreatePalettedSurfacePipe(Decoder* aDecoder,
|
||||||
uint32_t aFrameNum,
|
|
||||||
const nsIntSize& aInputSize,
|
const nsIntSize& aInputSize,
|
||||||
const nsIntRect& aFrameRect,
|
const nsIntRect& aFrameRect,
|
||||||
gfx::SurfaceFormat aFormat,
|
gfx::SurfaceFormat aFormat,
|
||||||
uint8_t aPaletteDepth,
|
uint8_t aPaletteDepth,
|
||||||
|
const Maybe<AnimationParams>& aAnimParams,
|
||||||
SurfacePipeFlags aFlags)
|
SurfacePipeFlags aFlags)
|
||||||
{
|
{
|
||||||
const bool deinterlace = bool(aFlags & SurfacePipeFlags::DEINTERLACE);
|
const bool deinterlace = bool(aFlags & SurfacePipeFlags::DEINTERLACE);
|
||||||
|
@ -211,9 +209,9 @@ public:
|
||||||
|
|
||||||
// Construct configurations for the SurfaceFilters.
|
// Construct configurations for the SurfaceFilters.
|
||||||
DeinterlacingConfig<uint8_t> deinterlacingConfig { progressiveDisplay };
|
DeinterlacingConfig<uint8_t> deinterlacingConfig { progressiveDisplay };
|
||||||
PalettedSurfaceConfig palettedSurfaceConfig { aDecoder, aFrameNum, aInputSize,
|
PalettedSurfaceConfig palettedSurfaceConfig { aDecoder, aInputSize, aFrameRect,
|
||||||
aFrameRect, aFormat, aPaletteDepth,
|
aFormat, aPaletteDepth,
|
||||||
flipVertically };
|
flipVertically, aAnimParams };
|
||||||
|
|
||||||
Maybe<SurfacePipe> pipe;
|
Maybe<SurfacePipe> pipe;
|
||||||
|
|
||||||
|
@ -229,7 +227,7 @@ public:
|
||||||
private:
|
private:
|
||||||
template <typename... Configs>
|
template <typename... Configs>
|
||||||
static Maybe<SurfacePipe>
|
static Maybe<SurfacePipe>
|
||||||
MakePipe(Configs... aConfigs)
|
MakePipe(const Configs&... aConfigs)
|
||||||
{
|
{
|
||||||
auto pipe = MakeUnique<typename detail::FilterPipeline<Configs...>::Type>();
|
auto pipe = MakeUnique<typename detail::FilterPipeline<Configs...>::Type>();
|
||||||
nsresult rv = pipe->Configure(aConfigs...);
|
nsresult rv = pipe->Configure(aConfigs...);
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче