mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 15:25:52 +00:00
Bug 1625930: Apply ResourceWatcher to source map. r=ochameau
Depends on D78240 Differential Revision: https://phabricator.services.mozilla.com/D78241
This commit is contained in:
parent
d1f58c00a9
commit
80b6400e07
@ -27,7 +27,6 @@ class SourceMapURLService {
|
||||
this._pendingURLSubscriptions = new Map();
|
||||
this._urlToIDMap = new Map();
|
||||
this._mapsById = new Map();
|
||||
this._listeningStylesheetFront = null;
|
||||
this._sourcesLoading = null;
|
||||
this._runningCallback = false;
|
||||
|
||||
@ -205,13 +204,16 @@ class SourceMapURLService {
|
||||
this._pendingURLSubscriptions.clear();
|
||||
this._urlToIDMap.clear();
|
||||
|
||||
if (this._listeningStylesheetFront) {
|
||||
this._listeningStylesheetFront.off(
|
||||
"stylesheet-added",
|
||||
this._onNewStyleSheet
|
||||
try {
|
||||
this._toolbox.resourceWatcher.unwatchResources(
|
||||
[this._toolbox.resourceWatcher.TYPES.STYLESHEET],
|
||||
{ onAvailable: this._onResourceAvailable }
|
||||
);
|
||||
this._listeningStylesheetFront = null;
|
||||
} catch (e) {
|
||||
// If unwatchResources is called before finishing process of watchResources,
|
||||
// it throws an error during stopping listener.
|
||||
}
|
||||
|
||||
this._sourcesLoading = null;
|
||||
}
|
||||
|
||||
@ -426,39 +428,17 @@ class SourceMapURLService {
|
||||
return;
|
||||
}
|
||||
|
||||
this._onResourceAvailable = async ({ resource }) => {
|
||||
if (this._sourcesLoading === sourcesLoading) {
|
||||
this._onNewStyleSheet(resource.styleSheet);
|
||||
}
|
||||
};
|
||||
|
||||
await Promise.all([
|
||||
(async () => {
|
||||
if (!this._target.hasActor("styleSheets")) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const front = await this._target.getFront("stylesheets");
|
||||
|
||||
if (this._listeningStylesheetFront) {
|
||||
this._listeningStylesheetFront.off(
|
||||
"stylesheet-added",
|
||||
this._onNewStyleSheet
|
||||
);
|
||||
}
|
||||
this._listeningStylesheetFront = front;
|
||||
this._listeningStylesheetFront.on(
|
||||
"stylesheet-added",
|
||||
this._onNewStyleSheet
|
||||
);
|
||||
|
||||
const sheets = await front.getStyleSheets();
|
||||
if (this._sourcesLoading === sourcesLoading) {
|
||||
// If we've cleared the state since starting this request,
|
||||
// we don't want to populate these.
|
||||
for (const sheet of sheets) {
|
||||
this._onNewStyleSheet(sheet);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
// Ignore any protocol-based errors.
|
||||
}
|
||||
})(),
|
||||
this._toolbox.resourceWatcher.watchResources(
|
||||
[this._toolbox.resourceWatcher.TYPES.STYLESHEET],
|
||||
{ onAvailable: this._onResourceAvailable }
|
||||
),
|
||||
(async () => {
|
||||
const { threadFront } = this._toolbox;
|
||||
if (!threadFront) {
|
||||
|
@ -333,6 +333,10 @@ class EventEmitter {
|
||||
EventEmitter.emit(this, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
count(...args) {
|
||||
return EventEmitter.count(this, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = EventEmitter;
|
||||
|
@ -14,12 +14,20 @@ module.exports = async function({ targetFront, onAvailable }) {
|
||||
}
|
||||
|
||||
const styleSheetsFront = await targetFront.getFront("stylesheets");
|
||||
const styleSheets = await styleSheetsFront.getStyleSheets();
|
||||
onAvailable(styleSheets.map(styleSheet => toResource(styleSheet, false)));
|
||||
try {
|
||||
const styleSheets = await styleSheetsFront.getStyleSheets();
|
||||
onAvailable(styleSheets.map(styleSheet => toResource(styleSheet, false)));
|
||||
|
||||
styleSheetsFront.on("stylesheet-added", (styleSheet, isNew) => {
|
||||
onAvailable([toResource(styleSheet, isNew)]);
|
||||
});
|
||||
styleSheetsFront.on("stylesheet-added", (styleSheet, isNew) => {
|
||||
onAvailable([toResource(styleSheet, isNew)]);
|
||||
});
|
||||
} catch (e) {
|
||||
// There are cases that the stylesheet front was destroyed already when/while calling
|
||||
// methods of stylesheet.
|
||||
// Especially, since source map url service starts to watch the stylesheet resources
|
||||
// lazily, the possibility will be extended.
|
||||
console.warn("fetching stylesheets failed", e);
|
||||
}
|
||||
};
|
||||
|
||||
function toResource(styleSheet, isNew) {
|
||||
|
@ -70,7 +70,11 @@ class ResourceWatcher {
|
||||
* existing resources.
|
||||
*/
|
||||
async watchResources(resources, options) {
|
||||
const { onAvailable, ignoreExistingResources = false } = options;
|
||||
const {
|
||||
onAvailable,
|
||||
onDestroyed,
|
||||
ignoreExistingResources = false,
|
||||
} = options;
|
||||
|
||||
// Cache the Watcher once for all, the first time we call `watch()`.
|
||||
// This `watcher` attribute may be then used in any function of the ResourceWatcher after this.
|
||||
@ -95,8 +99,16 @@ class ResourceWatcher {
|
||||
await this._watchAllTargets();
|
||||
|
||||
for (const resource of resources) {
|
||||
await this._startListening(resource);
|
||||
this._registerListeners(resource, options);
|
||||
// If we are registering the first listener, so start listening from the server about
|
||||
// this one resource.
|
||||
if (this._availableListeners.count(resource) === 0) {
|
||||
await this._startListening(resource);
|
||||
}
|
||||
this._availableListeners.on(resource, onAvailable);
|
||||
|
||||
if (onDestroyed) {
|
||||
this._destroyedListeners.on(resource, onDestroyed);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignoreExistingResources) {
|
||||
@ -112,16 +124,24 @@ class ResourceWatcher {
|
||||
const { onAvailable, onDestroyed } = options;
|
||||
|
||||
for (const resource of resources) {
|
||||
this._availableListeners.off(resource, onAvailable);
|
||||
if (onDestroyed) {
|
||||
this._destroyedListeners.off(resource, onDestroyed);
|
||||
}
|
||||
this._stopListening(resource);
|
||||
|
||||
const hadAtLeastOneListener =
|
||||
this._availableListeners.count(resource) > 0;
|
||||
this._availableListeners.off(resource, onAvailable);
|
||||
if (
|
||||
hadAtLeastOneListener &&
|
||||
this._availableListeners.count(resource) === 0
|
||||
) {
|
||||
this._stopListening(resource);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop watching for targets if we removed the last listener.
|
||||
let listeners = 0;
|
||||
for (const count of this._listenerCount) {
|
||||
for (const count of this._listenerCount.values()) {
|
||||
listeners += count;
|
||||
}
|
||||
if (listeners <= 0) {
|
||||
@ -129,20 +149,6 @@ class ResourceWatcher {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listeners to watch for a given type of resource.
|
||||
*
|
||||
* @param {Object}
|
||||
* - {Function} onAvailable: mandatory
|
||||
* - {Function} onDestroyed: optional
|
||||
*/
|
||||
_registerListeners(resource, { onAvailable, onDestroyed }) {
|
||||
this._availableListeners.on(resource, onAvailable);
|
||||
if (onDestroyed) {
|
||||
this._destroyedListeners.on(resource, onDestroyed);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start watching for all already existing and future targets.
|
||||
*
|
||||
|
@ -28,8 +28,8 @@ const TESTS = {
|
||||
hasMethod(emitter, "on") &&
|
||||
hasMethod(emitter, "off") &&
|
||||
hasMethod(emitter, "once") &&
|
||||
!hasMethod(emitter, "decorate") &&
|
||||
!hasMethod(emitter, "count"),
|
||||
hasMethod(emitter, "count") &&
|
||||
!hasMethod(emitter, "decorate"),
|
||||
`Event Emitter ${
|
||||
isAnEmitter ? "instance" : "mixin"
|
||||
} has the expected methods.`
|
||||
|
Loading…
Reference in New Issue
Block a user