зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1501632 - Return an unsubscribe function from SourceMapURLService.prototype.subscribe; r=loganfsmyth.
The SourceMapURLService has a subscribe and an unsubscribe functions to respectively listen and stop listening for source map changes on a given location (url + line + column). The unsubscribe function need to be called with the same parameters as the subscribe function, which means the consumer need to keep a reference to the callback. By making the subscribe function return the unsubscribe function, this makes things a bit easier. Differential Revision: https://phabricator.services.mozilla.com/D9784 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
5165b164ec
Коммит
e1af9012ee
|
@ -324,6 +324,8 @@ SourceMapURLService.prototype._callOneCallback = async function(subscriptionEntr
|
|||
* location. If false, then source maps are disabled
|
||||
* and the generated location should be used; in this
|
||||
* case the remaining arguments should be ignored.
|
||||
* @returns {Function | undefined} An unsubscribe function or undefined if the service
|
||||
* was destroyed.
|
||||
*/
|
||||
SourceMapURLService.prototype.subscribe = function(url, line, column, callback) {
|
||||
if (!this._subscriptions) {
|
||||
|
@ -348,6 +350,8 @@ SourceMapURLService.prototype.subscribe = function(url, line, column, callback)
|
|||
if (this._prefValue) {
|
||||
this._callOneCallback(subscriptionEntry, callback);
|
||||
}
|
||||
|
||||
return () => this.unsubscribe(url, line, column, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -72,6 +72,7 @@ skip-if = os == 'win' || debug # Bug 1282269, 1448084
|
|||
[browser_source_map-init.js]
|
||||
[browser_source_map-inline.js]
|
||||
[browser_source_map-no-race.js]
|
||||
[browser_source_map-pub-sub.js]
|
||||
[browser_source_map-reload.js]
|
||||
[browser_source_map-late-script.js]
|
||||
[browser_target_from_url.js]
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that the source map service subscribe mechanism work as expected.
|
||||
|
||||
"use strict";
|
||||
|
||||
const JS_URL = URL_ROOT + "code_bundle_no_race.js";
|
||||
|
||||
const PAGE_URL = `data:text/html,
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<script src="${JS_URL}"></script>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
const ORIGINAL_URL = "webpack:///code_no_race.js";
|
||||
|
||||
const GENERATED_LINE = 84;
|
||||
const ORIGINAL_LINE = 11;
|
||||
|
||||
add_task(async function() {
|
||||
// Opening the debugger causes the source actors to be created.
|
||||
const toolbox = await openNewTabAndToolbox(PAGE_URL, "jsdebugger");
|
||||
const service = toolbox.sourceMapURLService;
|
||||
|
||||
const cbCalls = [];
|
||||
const cb = (...args) => cbCalls.push(args);
|
||||
const expectedArgs = [true, ORIGINAL_URL, ORIGINAL_LINE, 0];
|
||||
|
||||
const unsubscribe1 = service.subscribe(JS_URL, GENERATED_LINE, 1, cb);
|
||||
await waitForSubscribtionsPromise(service);
|
||||
is(cbCalls.length, 1, "The callback function is called directly when subscribing");
|
||||
Assert.deepEqual(cbCalls[0], expectedArgs, "callback called with expected arguments");
|
||||
|
||||
const unsubscribe2 = service.subscribe(JS_URL, GENERATED_LINE, 1, cb);
|
||||
await waitForSubscribtionsPromise(service);
|
||||
is(cbCalls.length, 2, "Subscribing to the same location twice works");
|
||||
Assert.deepEqual(cbCalls[1], expectedArgs, "callback called with expected arguments");
|
||||
|
||||
info("Manually call the dispatcher to ensure subscribers are called");
|
||||
service._dispatchSubscribersForURL(JS_URL);
|
||||
await waitForSubscribtionsPromise(service);
|
||||
is(cbCalls.length, 4, "both subscribers were called");
|
||||
Assert.deepEqual(cbCalls[2], expectedArgs, "callback called with expected arguments");
|
||||
Assert.deepEqual(cbCalls[2], cbCalls[3], "callbacks were passed the same arguments");
|
||||
|
||||
info("Check unsubscribe functions");
|
||||
unsubscribe1();
|
||||
service._dispatchSubscribersForURL(JS_URL);
|
||||
await waitForSubscribtionsPromise(service);
|
||||
is(cbCalls.length, 5, "Only remainer subscriber callback was called");
|
||||
Assert.deepEqual(cbCalls[4], expectedArgs, "callback called with expected arguments");
|
||||
|
||||
unsubscribe2();
|
||||
service._dispatchSubscribersForURL(JS_URL);
|
||||
await waitForSubscribtionsPromise(service);
|
||||
is(cbCalls.length, 5, "No callbacks were called");
|
||||
});
|
||||
|
||||
async function waitForSubscribtionsPromise(service) {
|
||||
for (const [, subscriptionEntry] of service._subscriptions) {
|
||||
if (subscriptionEntry.promise) {
|
||||
await subscriptionEntry.promise;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -62,16 +62,14 @@ class Frame extends Component {
|
|||
componentWillMount() {
|
||||
if (this.props.sourceMapService) {
|
||||
const { source, line, column } = this.props.frame;
|
||||
this.props.sourceMapService.subscribe(source, line, column,
|
||||
this._locationChanged);
|
||||
this.unsubscribeSourceMapService = this.props.sourceMapService.subscribe(
|
||||
source, line, column, this._locationChanged);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.props.sourceMapService) {
|
||||
const { source, line, column } = this.props.frame;
|
||||
this.props.sourceMapService.unsubscribe(source, line, column,
|
||||
this._locationChanged);
|
||||
if (typeof this.unsubscribeSourceMapService === "function") {
|
||||
this.unsubscribeSourceMapService();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче