Open Bug 1578286 Opened 5 years ago Updated 2 years ago

[meta] Deprecate background pages in favor of service workers

Categories

(WebExtensions :: General, task, P3)

task

Tracking

(Not tracked)

People

(Reporter: zombie, Unassigned)

References

(Depends on 1 open bug, Blocks 1 open bug)

Details

(Keywords: meta)

Attachments

(2 obsolete files)

We haven't yet decided if and when we'll deprecate and remove background pages, but this bug is for tracking all the other bugs that might depend on that decision, either to be implemented or closed once that happens.

Please file any specific use cases you may find that don't currently have a solution using service workers as blocking this bug so that we can track them.

Blocks: 1394303
Depends on: 1580254
Depends on: 1524595

Be aware that there exist users like me who set dom.serviceWorkers.enabled=false as a workaround for Firefox not having proper UI for operating site service workers permission in an opt-in mode with a task manager for listing and killing/revoking them.

I advise either exempting addons from that (since sites are non-persistent by default, while addons are persistent by default) or adding a second about:config key which determines whether that also applies to extensions and defaults to "allow in extensions when disallowed in content".

Depends on: 1638604

The audio constructor also does not work in service worker.

https://bugs.chromium.org/p/chromium/issues/detail?id=1131236

Attachment #9223855 - Attachment is obsolete: true
Attachment #9223856 - Attachment is obsolete: true

Sorry I mistakenly posted incomplete comments and broken attachments...

Some codes of my addons look to depend on the DOM of the background page:

  1. Tracking dynamic changes of the dark mode and animation mode with CSS media query.
  2. Calculating dimensions of a new popup window.

Is there any help to do these operations with the manifest v3?

Tracking dynamic changes of the dark mode and animation mode with CSS media query

Some of my addons register listeners for window.matchMedia('(prefers-color-scheme: dark)') to set colors for the SVG icons shown on Firefox UI: the toolbar button, the sidebar panel switcher, and context menu item. Currently we cannot apply better theme-matching fill color for SVG icons automatically with context-fill (see also the bug 1367042), and there is no way to get the visible icon color of the default theme via browser.theme.getCurrent() on the dark mode (see also the bug 1435216 and the bug 1542044), so one of my addon watches changes of the theme and the dark mode and apply calculated color dynamically.

And there is another usecase of a CSS media query. I use window.matchMedia('(prefers-reduced-motion: reduce)') to determine I should reduce some animation effects based on platform configurations. One of my addon applies an animation with a duration, and another related operation need to be done with same duration. Because the animation is disabled when prefers-reduced-motion is reduced, I need to change the duration of the related operation also.

Calculating dimensions of a new popup window

Some my addon open popup windows via browser.windows.create({ type: 'popup' }) to show custom dialog windows. To determine the best size and position of the dialog, I need to calculate actual width and height of the popup window before it really appear in the screen. So some my addons use the background page to try rendering of the popup contents at first, and open a popup window based on the calculated dimensitons:

This is because it is not allowed to open a window outside the viewport (see also a past discussion about this point).

I also utilize background page DOM for one of my extensions (not published). Basically I have a tiled image that is scrambled. I use a canvas and a set of operations to unscramble the image. I suppose I might be able to do this with ImageBitmaps alone, I'd have to take a close look at the implementation.

For reference, function is:

async function fixPageBlob(pageBlob, page) {
  let bitmap = await createImageBitmap(pageBlob);
  let canvas = document.createElement('canvas');
  let ctx = canvas.getContext('2d');
  canvas.width = page.width;
  canvas.height = page.height;
  for (let o of page.ops) {
    ctx.drawImage(bitmap, o['sx'], o['sy'], 128, 128, o['dx'], o['dy'], 128, 128);
  }
  return canvas.toDataURL().split(';')[1].split(',')[1];
}

I suppose I might be able to do this with ImageBitmaps alone

Edit: Looks like ImageBitmaps can't be converted to Blobs? Guess I can't do it with them alone..

I also use canvas in my background page to convert favicons to 16x16 to take less memory space, for my Bookmark Search Plus 2 extension (until FF makes favicons available directly on bookmark APIs ... https://bugzilla.mozilla.org/show_bug.cgi?id=1411120).
This is when new bookmarks get created.
Doing that in sidebar would be a bad idea since:

  • there can be multiple sidebars running at same time
  • or no sidebar active when the add-on is hidden, which makes things difficult then to access any DOM related function
    Note that ImageBitmaps don't really do the job that I need, in particular to convert to a Base64 data: URI.

So need Canvas to work in a service worker if background pages get deprecated, or an alternate way available to do the same things in a service worker.

Thank you, aaFn.

Snippet for code being used:

const CvtCanvas = document.createElement('canvas'); // For image conversion to 16 x 16 and to Base64 URI
CvtCanvas.height = 16;
CvtCanvas.width = 16;
const CvtCtx = CvtCanvas.getContext("2d");
CvtCtx.imageSmoothingEnabled = false;
CvtCtx.imageSmoothingQuality = "high";
const CvtImageData = CvtCtx.createImageData(16, 16);
const CvtIDData = CvtImageData.data;
const CvtImage = new Image(16, 16);
CvtImage.onload = convertOnLoad;
CvtImage.onerror = errorCvtOnLoad;
const CvtCanvas2 = document.createElement('canvas'); // For loading a favicon to downscale
const CvtCtx2 = CvtCanvas2.getContext("2d");
/*
 * Convert and store image in 16x16, triggered by end of CvtImage.src load
 * 
 * Uses global variables cvtUri and destCvtBnId
 */
function convertOnLoad () {
  let nh = CvtImage.naturalHeight;
  let nw = CvtImage.naturalWidth;
  let convertedUri;
  if ((nh > 0) && (nw > 0) && ((nh != 16) || (nw != 16))) {
	try {
	  if ((nh > 16) && (nw > 16)) { // Downscale and get URI
		let srcIDData;
		CvtCanvas2.height = nh;
		CvtCanvas2.width = nw;
		CvtCtx2.drawImage(CvtImage, 0, 0);
		srcIDData = CvtCtx2.getImageData(0, 0, nw, nh).data;

		// Downscale into CvtImageData .. avoid FF canvas native algo, not really good
		downscaleImg(srcIDData, CvtIDData, nh, nw);

		// Put CvtImage into CvtCtx and get base64 uri
		CvtCtx.putImageData(CvtImageData, 0, 0);
		convertedUri = CvtCanvas.toDataURL();
	  }
	  else { // Only get URI
		CvtCtx.clearRect(0, 0, 16, 16);
		CvtCtx.drawImage(CvtImage, 0, 0, 16, 16);
		convertedUri = CvtCanvas.toDataURL();
	  }
	}
	catch (error) { // Error on rescale, keep original
	  let title = curBNList[destCvtBnId].title;
	  console.log("convertOnLoad error: "+error.type+" for "+cvtUri+" - "+destCvtBnId+" - "+title);
	  convertedUri = cvtUri;
	}
  }
  else { // Cannot rescale or no need to, keep original
	convertedUri = cvtUri;
  }

Would it be possible / reasonable for Firefox to use service workers, but provide extensions with an explicit API to create a background page (or some other kind of a perma-hidden moz-extension tab)?

SingleFile and SingleFileZ use the DOM API (mainly DOMParser and XHR) in background pages. Replacing background pages with service workers would mostly kill these extensions. This has been discussed here for Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=1051597.

About Comment 8, it seems that https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas would be a solution to alleviate the problem, but this would require to become first a full supported feature (cf. https://bugzilla.mozilla.org/show_bug.cgi?id=1390089).

=> Deprecating background pages would require to ship it in standard, if I interpret well.

Thanks, aaFn.

Is there any plans to support Audio in the background service ? In my extension I load podcasts and let the audio play in the background. Most of the other features can be refactor to events and states, but Audio is a big limitation for me.

Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: