Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  sw_inter_sw_postmessage.js   Sprache: JAVA

 
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */


let bc = new BroadcastChannel("inter-sw-postmessage");
let myId = /\/sw-(.)+$/.exec(registration.scope)[1];
// If we are being imported by the generated script from
// `sw_always_updating_inter_sw_postmessage.sjs`, there will be a "version"
// global and it starts counting from 1.
let myVersion = "version" in globalThis ? globalThis.version : 0;
let myFullId = `${myId}#${myVersion}`;

onactivate = function () {
  bc.postMessage(`${myId}:version-activated:${myVersion}`);
};

function extractId(urlStr) {
  if (!urlStr) {
    return urlStr;
  }
  const qIndex = urlStr.indexOf("?");
  if (qIndex >= 0) {
    return urlStr.substring(qIndex + 1);
  }
  if (urlStr.endsWith("/empty_with_utils.html")) {
    return "helper";
  }
  return urlStr;
}

function describeSource(source) {
  // Note that WindowProxy is impossible here, so we don't check it.
  if (source === null) {
    return "null";
  } else if (source instanceof MessagePort) {
    return "port";
  } else if (source instanceof WindowClient) {
    return `wc-${extractId(source.url)}`;
  } else if (source instanceof Client) {
    return `c-${extractId(source.url)}`;
  } else if (source instanceof ServiceWorker) {
    return `sw-${extractId(source.scriptURL)}`;
  } else {
    return "unexpected";
  }
}

let lastPostMessageSource = null;
globalThis.onmessage = async function handle_message(evt) {
  console.log(myId, "received postMessage");
  lastPostMessageSource = evt.source;
  bc.postMessage(
    `${myId}:received-post-message-from:${describeSource(evt.source)}`
  );
};

/**
 * Map a target descriptor onto something we can postMessage.  Possible options
 * and the resulting target:
 * - `last-source`: The `.source` property of the most recent event received via
 *   `globalThis.onmessage`.
 * - `reg-sw-ID`: The active ServiceWorker found on a registration whose
 *   scriptURL ends with `?ID`.  This allows us to distinguish between multiple
 *   (non-self-updating) ServiceWorkers on the same registration because each SW
 *   can be given a distinct script path via the `?ID` suffix.  But it does not
 *   work for self-updating ServiceWorkers where the only difference is the
 *   version identifier embedded in the script itself.
 */

async function resolveTarget(descriptor) {
  if (descriptor === "last-source") {
    return lastPostMessageSource;
  } else if (descriptor.startsWith("reg-")) {
    const registrations = await navigator.serviceWorker.getRegistrations();
    let filterFunc;
    if (descriptor.startsWith("reg-sw-")) {
      const descriptorId = /^reg-sw-(.+)$/.exec(descriptor)[1];
      console.log(
        "Looking for registration with id",
        descriptorId,
        "across",
        registrations.length,
        "registrations"
      );
      filterFunc = sw => {
        if (sw) {
          console.log("checking SW", sw.scriptURL);
        }
        return extractId(sw?.scriptURL) === descriptorId;
      };
    } else {
      throw new Error(`Target selector '${descriptor}' not understood`);
    }

    for (const reg of registrations) {
      console.log("Reg scriptURL", reg.active?.scriptURL);
      if (filterFunc(reg.active)) {
        return reg.active;
      } else if (filterFunc(reg.waiting)) {
        return reg.waiting;
      } else if (filterFunc(reg.installing)) {
        return reg.installing;
      }
    }
    throw new Error("No registration matches found!");
  }
  throw new Error(`Target selector '${descriptor}' not understood`);
}

/**
 * Map a registration descriptor onto a registration.  Options:
 * - `scope-ID`: The registration with a scope ending with `/sw-ID`.
 */

async function resolveRegistration(descriptor) {
  if (descriptor.startsWith("sw-")) {
    const registrations = await navigator.serviceWorker.getRegistrations();

    const scopeSuffix = `/${descriptor}`;
    for (const reg of registrations) {
      if (reg.scope.endsWith(scopeSuffix)) {
        return reg;
      }
    }

    throw new Error("No registration matches found!");
  }
  throw new Error(`Registration selector '${descriptor}' not understood`);
}

bc.onmessage = async function handle_bc(evt) {
  // Split the message into colon-delimited commands of the form:
  // <who should do the thing>:<the command>:<the target of the command>
  if (typeof evt?.data !== "string") {
    return;
  }
  const pieces = evt?.data?.split(":");
  if (
    !pieces ||
    pieces.length < 2 ||
    (pieces[0] !== myId && pieces[0] !== myFullId)
  ) {
    return;
  }

  const cmd = pieces[1];
  try {
    if (cmd === "post-message-to") {
      const target = await resolveTarget(pieces[2]);
      target.postMessage("yo!");
    } else if (cmd === "update-reg") {
      const reg = await resolveRegistration(pieces[2]);
      reg.update();
    } else if (cmd === "install-reg") {
      const installId = pieces[2];
      const scope = `sw-${installId}`;
      const script = `sw_inter_sw_postmessage.js?${installId}`;
      await navigator.serviceWorker.register(script, {
        scope,
      });
      bc.postMessage(`${myId}:registered:${installId}`);
    } else if (cmd === "workerref-hang") {
      const topic = pieces[2];
      globalThis.WorkerTestUtils.holdStrongWorkerRefUntilMainThreadObserverNotified(
        topic
      );
      bc.postMessage(`${myId}:workerref-hung:${topic}`);
    } else if (cmd === "block") {
      const topic = pieces[2];
      globalThis.WorkerTestUtils.blockUntilMainThreadObserverNotified(
        topic,
        // This callback is invoked once the observer has been registered.
        () => {
          bc.postMessage(`${myId}:blocking:${topic}`);
        }
      );
    } else if (cmd === "notify-observer") {
      const topic = pieces[2];
      globalThis.WorkerTestUtils.notifyObserverOnMainThread(topic);
      bc.postMessage(`${myId}:notified-observer:${topic}`);
    }
  } catch (ex) {
    console.error(ex);
    bc.postMessage({
      error: ex + "",
      myId,
      processing: evt?.data,
    });
  }
};

Messung V0.5
C=95 H=97 G=95

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge