noraneko · drops

dl.f3liz.casa/drop を読んでいます

std-settings

about:nora:settings のこの drop の箱を待って、その中に置き場所を返す

uuid 60f9cb39-c9a8-420e-8f05-07aaecc17bb2

install

Press inside noraneko. It catches the link, opens its settings with this uuid, downloads the xpi, checks the sha256 and the registry's signature, and shows you everything below again before anything runs.

install in noraneko In another browser this is a plain link to the xpi. Stock Firefox will refuse it as unverified; paste the uuid into about:nora:settings in noraneko instead.

who

gh/nyanrus

what is served

lib · std-settings@noraneko.app · version 1.0.2 · 2553 bytes sha256 b7be6c03f4bc0104adce46e8e3b9ea07af502b00b8f75575690aa8021d6efd9c built from drops/std-settings/src @ 59b96c854c (2026-09-14T07:24:00Z) served at https://dl.f3liz.casa/drop/60f9cb39-c9a8-420e-8f05-07aaecc17bb2/

in the registry

drops/std-settings/ @ 59b96c854c — この版が出てきた木 library: 直接入れるものではなく、これを [deps] に書いた drop に付いてくる

the source, as it is

These come from source.json next to the manifest — the same text the xpi carries under source/, and dl checks its sha256 against the signed manifest before handing it over. Not a copy of the repository: what you read and what runs came out of the same build. 1 files; press one to open it.

lib/index.ts · 53 lines
// SPDX-License-Identifier: MPL-2.0

// std-settings: 設定の頁に、この drop の一枚を置くときの作法。
//
// about:nora:settings は、入っている drop ごとに空の箱(`#nora-drop-<uuid>`)を置く。
// 頁のほうは preact で描かれるので、actor が先に着くことがある -- だから
// **出てくるのを待つ**。
//
// 待ちかたを timeout にしていないのは、「この drop の箱が無い頁」(まだ入っていない、
// あるいは頁の作りが変わった)と「まだ描かれていない」を、待ち時間で見分けようと
// すると必ず間違うから。出てこなければ、ただ何も置かれないだけで、見張りは drop を
// 外すときに一緒に外れる。

import type { MountAt } from "std-preact-xul";

/** 見張りを片づけ台帳に載せるのに要るぶんの ctx.io */
export interface IoDeferLike {
  defer(fn: () => void): void;
}

/**
 * この drop の箱の中に、host を置く場所を返す。箱が出てこないまま drop が外れたら
 * `null`(何も置かない)。
 *
 * `id` は、その host に付ける id(drop の anchor が言ったもの)。
 */
export function settingsPlace(io: IoDeferLike, uuid: string, id?: string): Promise<MountAt | null> {
  if (uuid === "") {
    console.warn('[std-settings] at: "settings": この drop の uuid が分からない');
    return Promise.resolve(null);
  }
  const boxId = `nora-drop-${uuid}`;
  const at = (el: Element | null): MountAt | null =>
    el ? ({ parent: el, tag: "html:div", id } as MountAt) : null;

  const found = document.getElementById(boxId);
  if (found) return Promise.resolve(at(found));

  return new Promise((resolve) => {
    const watch = new MutationObserver(() => {
      const el = document.getElementById(boxId);
      if (!el) return;
      watch.disconnect();
      resolve(at(el));
    });
    watch.observe(document.documentElement, { childList: true, subtree: true });
    io.defer(() => {
      watch.disconnect();
      resolve(null);
    });
  });
}

What a drop is, how it reaches you, and what it is not: f3liz.casa/noraneko/drops/. Served by https://dl.f3liz.casa/drop, signed by https://github.com/f3liz-casa/noraneko-registry/.github/workflows/verify-and-sign.yml@refs/heads/main.

This page is built when you ask for it, out of what https://dl.f3liz.casa/drop is serving right now (2026-09-23T08:38:28.032Z). Drafted by Shiro, an AI assistant, sitting next to nyanrus.