Repository: electron/electron
Pull request: feat: ServiceWorkerMain.scriptURL

#### Description of Change

Adds `scriptURL` property to `ServiceWorkerMain`. This is equivalent to the [`scriptURL`](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL) property available in renderers.

This was omitted initially as it wasn't available on a public interface. I've since landed a CL to move it to the public `ServiceWorkerVersionBaseInfo` struct.
https://chromium-review.googlesource.com/c/chromium/src/+/6243058

#### Checklist
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->

- [x] PR description included and stakeholders cc'd
- [ ] `npm test` passes
- [x] tests are [changed or added](https://github.com/electron/electron/blob/main/docs/development/testing.md)
- [x] relevant documentation, tutorials, templates and examples are changed or added
- [x] [PR release notes](https://github.com/electron/clerk/blob/main/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/main/README.md#examples).

#### Release Notes

Notes: Added `scriptURL` property to `ServiceWorkerMain`.


Changed files:
filename: docs/api/service-worker-main.md
patch: @@ -46,6 +46,10 @@ An [`IpcMainServiceWorker`](ipc-main-service-worker.md) instance scoped to the s
 
 A `string` representing the scope URL of the service worker.
 
+#### `serviceWorker.scriptURL` _Readonly_ _Experimental_
+
+A `string` representing the script URL of the service worker.
+
 #### `serviceWorker.versionId` _Readonly_ _Experimental_
 
 A `number` representing the ID of the specific version of the service worker script in its scope.

filename: shell/browser/api/electron_api_service_worker_main.cc
patch: @@ -282,6 +282,12 @@ GURL ServiceWorkerMain::ScopeURL() const {
   return version_info()->scope;
 }
 
+GURL ServiceWorkerMain::ScriptURL() const {
+  if (version_destroyed_)
+    return {};
+  return version_info()->script_url;
+}
+
 // static
 gin::Handle<ServiceWorkerMain> ServiceWorkerMain::New(v8::Isolate* isolate) {
   return gin::Handle<ServiceWorkerMain>();
@@ -330,6 +336,7 @@ void ServiceWorkerMain::FillObjectTemplate(
                  &ServiceWorkerMain::CountExternalRequestsForTest)
       .SetProperty("versionId", &ServiceWorkerMain::VersionID)
       .SetProperty("scope", &ServiceWorkerMain::ScopeURL)
+      .SetProperty("scriptURL", &ServiceWorkerMain::ScriptURL)
       .Build();
 }
 

filename: shell/browser/api/electron_api_service_worker_main.h
patch: @@ -147,6 +147,7 @@ class ServiceWorkerMain final
 
   int64_t VersionID() const;
   GURL ScopeURL() const;
+  GURL ScriptURL() const;
 
   // Version ID unique only to the StoragePartition.
   int64_t version_id_;

filename: spec/api-service-worker-main-spec.ts
patch: @@ -314,6 +314,17 @@ describe('ServiceWorkerMain module', () => {
     });
   });
 
+  describe("'scriptURL' property", () => {
+    it('matches the expected value', async () => {
+      loadWorkerScript();
+      const serviceWorker = await waitForServiceWorker();
+      expect(serviceWorker).to.not.be.undefined();
+      if (!serviceWorker) return;
+      expect(serviceWorker).to.have.property('scriptURL').that.is.a('string');
+      expect(serviceWorker.scriptURL).to.equal(`${baseUrl}/sw.js`);
+    });
+  });
+
   describe('ipc', () => {
     beforeEach(() => {
       registerPreload('preload-tests.js');