@linxin666/dsh-remote-web-ui 0.3.23 → 0.3.24
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/lib/client.js +149 -19
- package/lib/client.js.map +1 -1
- package/lib/index.js +43 -10
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +13 -18
- package/lib/types/client/mobile-adapt.d.ts.map +1 -1
- package/lib/types/client/mobile-adapt.js +40 -6
- package/lib/types/client/plugin-card-seat.d.ts +97 -0
- package/lib/types/client/plugin-card-seat.d.ts.map +1 -0
- package/lib/types/client/plugin-card-seat.js +141 -0
- package/lib/types/console-output.d.ts +41 -0
- package/lib/types/console-output.d.ts.map +1 -0
- package/lib/types/console-output.js +89 -0
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +5 -12
- package/package.json +1 -1
- package/src/client/index.ts +13 -17
- package/src/client/mobile-adapt.ts +39 -5
- package/src/client/plugin-card-seat.ts +185 -0
- package/src/console-output.ts +97 -0
- package/src/update.ts +5 -10
package/lib/client.js
CHANGED
|
@@ -4496,7 +4496,7 @@ window.__ModuleLoader__.load({
|
|
|
4496
4496
|
/** The building package's version, when the bundle carries it. */
|
|
4497
4497
|
function bakedVersion() {
|
|
4498
4498
|
try {
|
|
4499
|
-
return "0.3.
|
|
4499
|
+
return "0.3.24";
|
|
4500
4500
|
} catch {
|
|
4501
4501
|
return;
|
|
4502
4502
|
}
|
|
@@ -4580,6 +4580,12 @@ window.__ModuleLoader__.load({
|
|
|
4580
4580
|
const COMPACT_CLASS = "dsh-remote-compact-picker";
|
|
4581
4581
|
/** Body class while the header actions are seated in the tabs row. */
|
|
4582
4582
|
const HEADER_SEATED_CLASS = "dsh-remote-header-seated";
|
|
4583
|
+
/**
|
|
4584
|
+
* Width the seated header actions paint over the tabs row, as a CSS variable
|
|
4585
|
+
* on <html>. The row caps its own width with it (see the v80 rules) instead of
|
|
4586
|
+
* reserving the space with padding.
|
|
4587
|
+
*/
|
|
4588
|
+
const HEADER_RESERVE_VAR = "--dsh-remote-header-actions-reserve";
|
|
4583
4589
|
/** Locale-dependent fast path for the official picker cells (zh/en). */
|
|
4584
4590
|
const PICKER_CELL_PATTERN = {
|
|
4585
4591
|
model: /模型|Model/,
|
|
@@ -4678,6 +4684,9 @@ window.__ModuleLoader__.load({
|
|
|
4678
4684
|
"[class$=\"_composerSeat\"] [class$=\"_frame\"] [class$=\"_card\"]{max-width:none;width:100%}",
|
|
4679
4685
|
`body.${HEADER_SEATED_CLASS} [class$="_header"] [class$="_titleCluster"] [class$="_headerActions"]{position:absolute;left:0;top:0;margin:0;display:flex;align-items:center;gap:6px;flex:none;z-index:2}`,
|
|
4680
4686
|
"[class$=\"_header\"] [class$=\"_tabs\"] [class*=\"_tab\"]{font-size:12px;white-space:nowrap}",
|
|
4687
|
+
`body.${HEADER_SEATED_CLASS} [class$="_header"] [class$="_tabs"]{max-width:max(0px,calc(100% - var(${HEADER_RESERVE_VAR},0px)));overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-webkit-overflow-scrolling:touch;padding-bottom:2px;margin-bottom:-2px}`,
|
|
4688
|
+
`body.${HEADER_SEATED_CLASS} [class$="_header"] [class$="_tabs"]::-webkit-scrollbar{display:none}`,
|
|
4689
|
+
`body.${HEADER_SEATED_CLASS} [class$="_header"] [class$="_tabs"] > [class*="_tab"]{flex:0 0 auto}`,
|
|
4681
4690
|
`body.${ACTIVE_CLASS} [class$=\"_detailsCol\"]{display:none !important}`,
|
|
4682
4691
|
`body.${ACTIVE_CLASS} [data-dsh-plugin=\"ssh\"],`,
|
|
4683
4692
|
`body.${ACTIVE_CLASS} [data-dsh-plugin=\"skill-explorer\"],`,
|
|
@@ -5096,7 +5105,9 @@ window.__ModuleLoader__.load({
|
|
|
5096
5105
|
let dx = translate !== null ? parseFloat(translate[1] ?? "0") : 0;
|
|
5097
5106
|
let dy = translate !== null ? parseFloat(translate[2] ?? "0") : 0;
|
|
5098
5107
|
const actionsRect = actions.getBoundingClientRect();
|
|
5099
|
-
const
|
|
5108
|
+
const headerRect = header.getBoundingClientRect();
|
|
5109
|
+
const headerStyle = getComputedStyle(header);
|
|
5110
|
+
const rightDiff = headerRect.right - (parseFloat(headerStyle.paddingRight) || 0) - (parseFloat(headerStyle.borderRightWidth) || 0) - actionsRect.right;
|
|
5100
5111
|
if (Math.abs(rightDiff) >= .5) dx = Math.round((dx + rightDiff) * 10) / 10;
|
|
5101
5112
|
const tabBottom = textBottom(tabBtn);
|
|
5102
5113
|
if (tabBottom !== null) {
|
|
@@ -5113,10 +5124,12 @@ window.__ModuleLoader__.load({
|
|
|
5113
5124
|
const next = `translate(${dx}px, ${dy}px)`;
|
|
5114
5125
|
if (actions.style.transform !== next) actions.style.transform = next;
|
|
5115
5126
|
const reserve = `${Math.ceil(actionsRect.width) + 8}px`;
|
|
5116
|
-
|
|
5127
|
+
const rootStyle = document.documentElement.style;
|
|
5128
|
+
if (rootStyle.getPropertyValue(HEADER_RESERVE_VAR) !== reserve) rootStyle.setProperty(HEADER_RESERVE_VAR, reserve);
|
|
5117
5129
|
}
|
|
5118
5130
|
function unseatHeaderActions() {
|
|
5119
5131
|
document.body.classList.remove(HEADER_SEATED_CLASS);
|
|
5132
|
+
document.documentElement.style.removeProperty(HEADER_RESERVE_VAR);
|
|
5120
5133
|
const header = document.querySelector("[class$=\"_header\"]");
|
|
5121
5134
|
const tabs = header !== null ? header.querySelector("[class$=\"_tabs\"]") : null;
|
|
5122
5135
|
const actions = header !== null ? header.querySelector("[class$=\"_titleCluster\"] [class$=\"_headerActions\"]") : null;
|
|
@@ -5425,6 +5438,129 @@ window.__ModuleLoader__.load({
|
|
|
5425
5438
|
};
|
|
5426
5439
|
}
|
|
5427
5440
|
//#endregion
|
|
5441
|
+
//#region src/client/plugin-card-seat.ts
|
|
5442
|
+
/**
|
|
5443
|
+
* Family plugin-card seat.
|
|
5444
|
+
*
|
|
5445
|
+
* A family plugin contributes its settings card to whichever plugin-card seat
|
|
5446
|
+
* the running host actually renders:
|
|
5447
|
+
*
|
|
5448
|
+
* - `web-ui.plugin.item` — the list seat declared by the dsh-web-settings
|
|
5449
|
+
* group section (this family's own first-level "Web UI plugins" section);
|
|
5450
|
+
* - `settings.plugin.item` — the official keyed seat of the harness's
|
|
5451
|
+
* `ui-settings-plugins` tab, keyed by the settings namespace the card edits.
|
|
5452
|
+
*
|
|
5453
|
+
* SEAT SELECTION IS NOT A DECLARATION PROBE. The official `ui-settings-plugins`
|
|
5454
|
+
* row belongs to the harness bundle and its `configurable` tab always declares
|
|
5455
|
+
* `settings.plugin.item` before any external plugin's `apply()` runs, so
|
|
5456
|
+
* "is the official seat declared?" answers yes even in the deployment whose
|
|
5457
|
+
* whole point is the family group. Choosing on that probe sends every family
|
|
5458
|
+
* card to the official Plugins tab and leaves the group's own section
|
|
5459
|
+
* permanently empty — the family of reports where the section renders its
|
|
5460
|
+
* heading and zero cards.
|
|
5461
|
+
*
|
|
5462
|
+
* The signal that actually distinguishes the two deployments is whether
|
|
5463
|
+
* dsh-web-settings is loaded: it is the package that owns the group section and
|
|
5464
|
+
* it publishes the `webUiSettings` service during `apply()`, which every
|
|
5465
|
+
* family plugin already reads for its settings scope. Group loaded -> the family
|
|
5466
|
+
* seat; group absent -> the official seat.
|
|
5467
|
+
*
|
|
5468
|
+
* The decision is re-evaluated on every `slots/changed` because the group may
|
|
5469
|
+
* apply after this plugin (the family aggregate orders it first, a profile that
|
|
5470
|
+
* installs the group separately need not): the initial contribution goes to the
|
|
5471
|
+
* official seat, then moves to the family seat the moment the group's section
|
|
5472
|
+
* registers. The entry is disposed before the replacement is registered, so a
|
|
5473
|
+
* card is never in two seats at once.
|
|
5474
|
+
*
|
|
5475
|
+
* The shared tree has no client-SDK dependency, so this module reads its
|
|
5476
|
+
* context through the structural shape below; callers pass the plugin's own
|
|
5477
|
+
* `ctx`.
|
|
5478
|
+
*/
|
|
5479
|
+
/** The family list seat key. */
|
|
5480
|
+
const FAMILY_PLUGIN_CARD_SEAT = "web-ui.plugin.item";
|
|
5481
|
+
/** The official keyed plugin-card seat key. */
|
|
5482
|
+
const OFFICIAL_PLUGIN_CARD_SEAT = "settings.plugin.item";
|
|
5483
|
+
/** The service dsh-web-settings publishes while it is loaded. */
|
|
5484
|
+
const FAMILY_GROUP_SERVICE = "webUiSettings";
|
|
5485
|
+
/**
|
|
5486
|
+
* Whether the family group (dsh-web-settings) is loaded in this page. The
|
|
5487
|
+
* service is the group package's own contract, so the probe cannot be fooled
|
|
5488
|
+
* by a harness release that starts declaring the official seat differently.
|
|
5489
|
+
*/
|
|
5490
|
+
function familyGroupLoaded(ctx) {
|
|
5491
|
+
const get = ctx.get;
|
|
5492
|
+
if (typeof get !== "function") return false;
|
|
5493
|
+
try {
|
|
5494
|
+
return get.call(ctx, FAMILY_GROUP_SERVICE) !== void 0;
|
|
5495
|
+
} catch {
|
|
5496
|
+
return false;
|
|
5497
|
+
}
|
|
5498
|
+
}
|
|
5499
|
+
/** Report a refused registration instead of leaving the user with no card. */
|
|
5500
|
+
function warnRefusedSeat(seat, error) {
|
|
5501
|
+
try {
|
|
5502
|
+
console.warn(`[dsh-web] plugin card registration into "${seat}" was refused; the card will not render`, error);
|
|
5503
|
+
} catch {}
|
|
5504
|
+
}
|
|
5505
|
+
/**
|
|
5506
|
+
* Contribute one family plugin card to the seat this host renders, following
|
|
5507
|
+
* the group if it loads later. The entry is disposed and re-registered on a
|
|
5508
|
+
* seat change, never duplicated.
|
|
5509
|
+
* @param ctx - client context (its slot registry decides the seat).
|
|
5510
|
+
* @param seat - the card contribution.
|
|
5511
|
+
*/
|
|
5512
|
+
function installPluginCard(ctx, seat) {
|
|
5513
|
+
const slots = ctx.slots;
|
|
5514
|
+
const component = seat.component;
|
|
5515
|
+
const inject = seat.inject;
|
|
5516
|
+
let dispose;
|
|
5517
|
+
let current;
|
|
5518
|
+
/**
|
|
5519
|
+
* Re-entrancy latch. The registry emits a change event synchronously from
|
|
5520
|
+
* inside both `register` and the previous entry's disposer, so an unguarded
|
|
5521
|
+
* reconcile would re-enter itself mid-move and register the card twice into
|
|
5522
|
+
* the seat it is leaving ("already has an entry for key ...").
|
|
5523
|
+
*/
|
|
5524
|
+
let reconciling = false;
|
|
5525
|
+
/** Reconcile the contribution with the currently live seat (no-op when unchanged). */
|
|
5526
|
+
const reconcile = () => {
|
|
5527
|
+
if (reconciling) return;
|
|
5528
|
+
const target = familyGroupLoaded(ctx) ? FAMILY_PLUGIN_CARD_SEAT : OFFICIAL_PLUGIN_CARD_SEAT;
|
|
5529
|
+
if (current === target) return;
|
|
5530
|
+
reconciling = true;
|
|
5531
|
+
const previous = dispose;
|
|
5532
|
+
dispose = void 0;
|
|
5533
|
+
current = void 0;
|
|
5534
|
+
previous?.();
|
|
5535
|
+
try {
|
|
5536
|
+
dispose = slots.register(target === "web-ui.plugin.item" ? {
|
|
5537
|
+
name: FAMILY_PLUGIN_CARD_SEAT,
|
|
5538
|
+
id: seat.id,
|
|
5539
|
+
...seat.order === void 0 ? {} : { order: seat.order },
|
|
5540
|
+
...seat.label === void 0 ? {} : { label: seat.label },
|
|
5541
|
+
locale: seat.locale,
|
|
5542
|
+
...seat.inject === void 0 ? {} : { inject }
|
|
5543
|
+
} : {
|
|
5544
|
+
name: OFFICIAL_PLUGIN_CARD_SEAT,
|
|
5545
|
+
key: seat.namespace,
|
|
5546
|
+
locale: seat.locale,
|
|
5547
|
+
...seat.inject === void 0 ? {} : { inject }
|
|
5548
|
+
}, component);
|
|
5549
|
+
current = target;
|
|
5550
|
+
} catch (error) {
|
|
5551
|
+
warnRefusedSeat(target, error);
|
|
5552
|
+
} finally {
|
|
5553
|
+
reconciling = false;
|
|
5554
|
+
}
|
|
5555
|
+
};
|
|
5556
|
+
if (typeof ctx.on === "function") try {
|
|
5557
|
+
ctx.on("slots/changed", () => {
|
|
5558
|
+
reconcile();
|
|
5559
|
+
});
|
|
5560
|
+
} catch {}
|
|
5561
|
+
reconcile();
|
|
5562
|
+
}
|
|
5563
|
+
//#endregion
|
|
5428
5564
|
//#region src/client/index.ts
|
|
5429
5565
|
/**
|
|
5430
5566
|
* Remote control — browser half. Registers the `remote` dictionaries, the
|
|
@@ -5525,23 +5661,17 @@ window.__ModuleLoader__.load({
|
|
|
5525
5661
|
};
|
|
5526
5662
|
});
|
|
5527
5663
|
const remoteSettings = new RemoteSettingsCardController(settingsScope);
|
|
5528
|
-
ctx
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
inject: () => remoteSettings.inject()
|
|
5536
|
-
}, RemoteSettingsCard);
|
|
5537
|
-
return () => {
|
|
5538
|
-
remoteSettings.dispose();
|
|
5539
|
-
unregister();
|
|
5540
|
-
};
|
|
5541
|
-
} catch {
|
|
5542
|
-
return () => {};
|
|
5543
|
-
}
|
|
5664
|
+
installPluginCard(ctx, {
|
|
5665
|
+
namespace: REMOTE_WEB_UI_NS,
|
|
5666
|
+
id: "remote-web-ui",
|
|
5667
|
+
order: 90,
|
|
5668
|
+
locale: NS,
|
|
5669
|
+
inject: () => remoteSettings.inject(),
|
|
5670
|
+
component: RemoteSettingsCard
|
|
5544
5671
|
});
|
|
5672
|
+
ctx.effect(() => () => {
|
|
5673
|
+
remoteSettings.dispose();
|
|
5674
|
+
}, "remote-web-ui: settings card");
|
|
5545
5675
|
let disposeRuntime;
|
|
5546
5676
|
const syncRuntime = () => {
|
|
5547
5677
|
if (enabled() && disposeRuntime === void 0) disposeRuntime = ctx.effect(() => {
|