@panda-lingo/goldendict 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # @panda-lingo/goldendict
2
+
3
+ Framework-independent client and `<goldendict-view>` renderer for the
4
+ GoldenDict REST service. The package preserves GoldenDict-ng article markup and
5
+ styles inside a sandboxed iframe while exposing typed browser events and brand
6
+ theme tokens.
7
+
8
+ ```ts
9
+ import {
10
+ DictionaryClient,
11
+ defineGoldendictView,
12
+ } from "@panda-lingo/goldendict";
13
+
14
+ defineGoldendictView();
15
+ const view = document.querySelector("goldendict-view");
16
+ view.client = new DictionaryClient({ baseUrl: "/api/v1" });
17
+ await view.lookup("example");
18
+ ```
19
+
20
+ Importing the package registers `<goldendict-view>` automatically. Call
21
+ `defineGoldendictView("my-dictionary-view")` when a custom tag name is useful.
22
+
23
+ The public API includes:
24
+
25
+ - `DictionaryClient` for dictionary listing and lookup, plus the backend's
26
+ explicitly opt-in server-path load operation.
27
+ - `GoldenDictView` and `defineGoldendictView` for framework-independent use.
28
+ - `GoldenDictTheme`, light/dark token presets, and `themeToCss` for branding.
29
+ - `GOLDENDICT_EVENTS` for lookup, active article, collapse, media, external-link,
30
+ and state notifications.
31
+ - Resource/link helpers for hosts that need to inspect GoldenDict URLs.
32
+
33
+ Dictionary scripts are removed by default (`scriptPolicy = "none"`). The
34
+ explicit `"sandboxed"` policy retains them inside the iframe, which never gets
35
+ `allow-same-origin`. Lookup, media, and external-link events are cancelable so a
36
+ host application can replace the default navigation behavior.
37
+
38
+ In sandboxed mode, external sidecars such as `bres://.../Dictionary-UI.js` are
39
+ routed through the article's `resourceBaseUrl` without changing filename case.
40
+ Because the iframe has an opaque origin, dictionary XHR/fetch requests send
41
+ `Origin: null`; the read-only API must explicitly allow that origin when this
42
+ compatibility mode is enabled. Classic script element loads do not grant the
43
+ dictionary access to the host document.
44
+
45
+ Run the package demo from the workspace root with `npm run dev`. It discovers
46
+ the dictionaries loaded from the backend's configured local paths at startup.
47
+
48
+ GoldenDict-ng CSS and icons are pinned and sync-managed. See
49
+ [`UPGRADING_GOLDENDICT.md`](./UPGRADING_GOLDENDICT.md) for the one-command local
50
+ checkout upgrade flow.
@@ -0,0 +1,10 @@
1
+ # Third-party notices
2
+
3
+ The GoldenDict article styles and icons under `src/styles/vendor` and
4
+ `src/assets/icons` are derived from GoldenDict-ng commit
5
+ `5ad66765aa423d381025566bff990f7d8007be84`.
6
+
7
+ GoldenDict-ng is licensed under GNU GPL version 3 or later. Copyright notices
8
+ and the complete license text are retained in this package's `LICENSE` file.
9
+
10
+ Upstream project: https://github.com/xiaoyifang/goldendict-ng
@@ -0,0 +1,33 @@
1
+ # Updating GoldenDict-ng rendering compatibility
2
+
3
+ Vendored upstream files have an explicit boundary:
4
+
5
+ - `src/styles/vendor/` contains unmodified GoldenDict-ng article CSS.
6
+ - `src/assets/icons/` contains the upstream icons used by that CSS and article HTML.
7
+ - `compatibility/goldendict-ng.json` pins the repository commit and SHA-256 of every copied file.
8
+ - Hand-written browser adapters live elsewhere in `src/` and are never overwritten by sync.
9
+
10
+ To adopt a newer or modified local GoldenDict-ng checkout:
11
+
12
+ ```sh
13
+ npm run sync:goldendict --workspace @panda-lingo/goldendict -- \
14
+ --source /path/to/goldendict-ng
15
+ npm test
16
+ npm run build
17
+ ```
18
+
19
+ The sync command copies only manifest-listed files, records their new checksums,
20
+ and pins the checkout's origin, current Git commit, relevant dirty state, and
21
+ diff hash. This also makes an intentional local modification visible instead of
22
+ mislabeling it as an unmodified upstream commit. Review the vendor and manifest diff.
23
+ If upstream adds a stylesheet or required icon, add its source/target mapping to
24
+ the manifest and expose it from `styles/fidelity.ts` or `assets.ts`; the
25
+ compatibility contract test is intended to make omissions visible.
26
+
27
+ CI and local builds run the target-only checksum check automatically. To also
28
+ verify a checkout matches the currently pinned version:
29
+
30
+ ```sh
31
+ npm run check:goldendict --workspace @panda-lingo/goldendict -- \
32
+ --source /path/to/goldendict-ng
33
+ ```
@@ -0,0 +1,4 @@
1
+ export declare const BUILTIN_ASSET_URLS: Readonly<Record<string, string>>;
2
+ export declare function resolveBuiltinAsset(url: string): string | undefined;
3
+ export declare function rewriteBuiltinAssetUrls(css: string): string;
4
+ //# sourceMappingURL=assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgB/D,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGnE;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK3D"}
@@ -0,0 +1,18 @@
1
+ import type { DictionaryClientOptions, DictionarySummary, LoadDictionaryRequest, LoadDictionaryResponse, LookupOptions, LookupResponse } from "../types";
2
+ export declare class DictionaryApiError extends Error {
3
+ readonly status: number;
4
+ readonly body: unknown;
5
+ constructor(message: string, status: number, body?: unknown);
6
+ }
7
+ export declare class DictionaryClient {
8
+ readonly baseUrl: string;
9
+ private readonly fetchImpl;
10
+ private readonly headers;
11
+ private readonly credentials;
12
+ constructor(options?: DictionaryClientOptions);
13
+ listDictionaries(signal?: AbortSignal): Promise<DictionarySummary[]>;
14
+ loadDictionary(input: LoadDictionaryRequest, signal?: AbortSignal): Promise<LoadDictionaryResponse>;
15
+ lookup(word: string, options?: LookupOptions): Promise<LookupResponse>;
16
+ private request;
17
+ }
18
+ //# sourceMappingURL=dictionary-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dictionary-client.d.ts","sourceRoot":"","sources":["../../src/client/dictionary-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,cAAc,EACf,MAAM,UAAU,CAAC;AAElB,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;gBAEX,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO;CAM5D;AAiDD,qBAAa,gBAAgB;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAC3D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;gBAErC,OAAO,GAAE,uBAA4B;IAW3C,gBAAgB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAQpE,cAAc,CAClB,KAAK,EAAE,qBAAqB,EAC5B,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,sBAAsB,CAAC;IA6B5B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,cAAc,CAAC;YAsBlE,OAAO;CAoCtB"}
@@ -0,0 +1,59 @@
1
+ import { DictionaryClient } from "../client/dictionary-client";
2
+ import type { DictionaryClientOptions, GoldenDictTheme, LookupResponse, ScriptPolicy, ViewState } from "../types";
3
+ export declare class GoldenDictView extends HTMLElement {
4
+ static readonly observedAttributes: string[];
5
+ readonly instanceId: string;
6
+ private readonly frame;
7
+ private readonly statusElement;
8
+ private readonly brandElement;
9
+ private readonly brandImage;
10
+ private readonly brandText;
11
+ private clientValue;
12
+ private requestController?;
13
+ private requestSequence;
14
+ private responseValue?;
15
+ private themeValue;
16
+ private stateValue;
17
+ private dictionaryIdsValue;
18
+ private pendingAnchor?;
19
+ constructor();
20
+ connectedCallback(): void;
21
+ disconnectedCallback(): void;
22
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
23
+ get apiBase(): string;
24
+ set apiBase(value: string);
25
+ get client(): DictionaryClient;
26
+ set client(value: DictionaryClient);
27
+ get theme(): GoldenDictTheme;
28
+ set theme(value: GoldenDictTheme);
29
+ get scriptPolicy(): ScriptPolicy;
30
+ set scriptPolicy(value: ScriptPolicy);
31
+ get dictionaryIds(): readonly string[];
32
+ set dictionaryIds(value: readonly string[]);
33
+ get state(): ViewState;
34
+ get response(): LookupResponse | undefined;
35
+ configureClient(options: DictionaryClientOptions): void;
36
+ lookup(word: string, dictionaryIds?: readonly string[]): Promise<void>;
37
+ setLookupResponse(response: LookupResponse): void;
38
+ abort(): void;
39
+ clear(): void;
40
+ scrollToArticle(dictionaryId: string): void;
41
+ private renderResponse;
42
+ private handleFrameLoaded;
43
+ private readonly handleBridgeMessage;
44
+ private handleLookupMessage;
45
+ private handleMediaMessage;
46
+ private handleExternalLink;
47
+ private openExternal;
48
+ private updateBrand;
49
+ private setState;
50
+ private postCommand;
51
+ private emit;
52
+ }
53
+ export declare function defineGoldendictView(tagName?: string): typeof GoldenDictView;
54
+ declare global {
55
+ interface HTMLElementTagNameMap {
56
+ "goldendict-view": GoldenDictView;
57
+ }
58
+ }
59
+ //# sourceMappingURL=goldendict-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goldendict-view.d.ts","sourceRoot":"","sources":["../../src/element/goldendict-view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE/D,OAAO,KAAK,EAGV,uBAAuB,EAEvB,eAAe,EAEf,cAAc,EAEd,YAAY,EACZ,SAAS,EAEV,MAAM,UAAU,CAAC;AAsClB,qBAAa,cAAe,SAAQ,WAAW;IAC7C,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAMhC;IAEF,QAAQ,CAAC,UAAU,SAAoB;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiB;IAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmB;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;IAC5C,OAAO,CAAC,WAAW,CAAmB;IACtC,OAAO,CAAC,iBAAiB,CAAC,CAAkB;IAC5C,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,aAAa,CAAC,CAAiB;IACvC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,kBAAkB,CAAgB;IAC1C,OAAO,CAAC,aAAa,CAAC,CAAS;;IAyB/B,iBAAiB,IAAI,IAAI;IAQzB,oBAAoB,IAAI,IAAI;IAK5B,wBAAwB,CACtB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI;IAuBP,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,EAExB;IAED,IAAI,MAAM,IAAI,gBAAgB,CAE7B;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,gBAAgB,EAEjC;IAED,IAAI,KAAK,IAAI,eAAe,CAE3B;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,eAAe,EAM/B;IAED,IAAI,YAAY,IAAI,YAAY,CAI/B;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,YAAY,EAEnC;IAED,IAAI,aAAa,IAAI,SAAS,MAAM,EAAE,CAErC;IAED,IAAI,aAAa,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAEzC;IAED,IAAI,KAAK,IAAI,SAAS,CAErB;IAED,IAAI,QAAQ,IAAI,cAAc,GAAG,SAAS,CAEzC;IAED,eAAe,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI;IAIjD,MAAM,CACV,IAAI,EAAE,MAAM,EACZ,aAAa,GAAE,SAAS,MAAM,EAA4B,GACzD,OAAO,CAAC,IAAI,CAAC;IAqChB,iBAAiB,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAKjD,KAAK,IAAI,IAAI;IAKb,KAAK,IAAI,IAAI;IASb,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAI3C,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CA6ClC;IAEF,OAAO,CAAC,mBAAmB;IAoB3B,OAAO,CAAC,kBAAkB;IA0B1B,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,QAAQ;IAiChB,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,IAAI;CAcb;AAED,wBAAgB,oBAAoB,CAClC,OAAO,SAAoB,GAC1B,OAAO,cAAc,CAUvB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,iBAAiB,EAAE,cAAc,CAAC;KACnC;CACF"}
@@ -0,0 +1,7 @@
1
+ export { DictionaryApiError, DictionaryClient } from "./client/dictionary-client";
2
+ export { GoldenDictView, defineGoldendictView, } from "./element/goldendict-view";
3
+ export { GOLDENDICT_SCHEME_SUPPORT, classifyArticleLink, resolveResourceUrl, type ArticleLinkAction, type ResourceContext, } from "./renderer/link-router";
4
+ export { DARK_THEME_TOKENS, LIGHT_THEME_TOKENS, escapeStyleText, resolveThemeMode, themeToCss, } from "./renderer/theme";
5
+ export { GOLDENDICT_EVENTS } from "./types";
6
+ export type * from "./types";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,EACL,cAAc,EACd,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,KAAK,eAAe,GACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,mBAAmB,SAAS,CAAC"}