Skip to content

dsh-fullscreen-input 1.2.0

Choose a tag to compare

@AL-Yichen AL-Yichen released this 06 Oct 18:38
· 17 commits to main since this release

One-click removal for file references, and a fix for the references that were quietly not coming back.

Added

  • File references can be removed with one click. Reference entries (@path) now carry
    the same "×" the attachments do. Understanding what it does means knowing that a
    reference is not an attachment
    : a non-image file lives in the host as @path text
    inside the draft document plus one occurrences record — it is not in attachmentIds
    at all — so the attachment removal API does nothing for it and the only way to delete it
    is to edit the draft text, which is exactly what the button does. Both shapes have to
    be handled or it destroys content: a reference alone on its line is removed together
    with its newline (leaving no blank line); one mid-sentence removes only itself and
    collapses the two spaces it frees into one (see @a.ts here → see here). After a
    removal, the remaining references are still references — the chips are rebuilt as usual.
    • One deliberate behaviour: no button is drawn when there is no matching text to
      delete.
      If the draft has moved on and that text can no longer be found, there is
      nothing to remove — and a control that silently does nothing is the very thing this
      feature exists to eliminate. It also keeps an image draft from growing a second remove
      control beside the one on its attachment.

Fixed

  • Removing one reference made every other reference lose its identity. This is the most
    serious one, and the reason it only showed up on a real machine: the host takes
    insertReference spans in detect coordinates — a chip is one character
    (U+FFFC) in the detect projection — while the plan is built in clipboard
    coordinates, where a chip is its whole @path. The first chip happens to start at offset
    0, so it lined up; every later one was off by the accumulated "restored path length − 1",
    the host judged the span out of range and refused it, and the restore pass ended — so
    only the first reference came back as a chip and every later one stayed plain text.
    That drift is now accumulated per insertion (the host cancels one unit of it by appending
    a separating space after a chip) and every span is converted to detect coordinates before
    it is handed over.
    • This defect was invisible to the offline tests: the test double treated spans as
      clipboard coordinates and sliced them directly, and returned success unconditionally. It
      now models the real semantics — a document is a sequence of text and chip fragments,
      and a chip is one detect character — so the old code genuinely fails against it
      (applied=[true,false]) and the fix has regression cover.
  • Clicking "×" threw the caret somewhere else, so the next keystroke landed where you
    never pointed.
    Replacing the textarea's value programmatically lets the browser choose
    the caret position: one that was at the end ended up in the middle of the draft, and the
    very next backspace deleted two entirely unrelated references. The caret is now mapped
    through the edit before the write — unmoved before the change, shifted by the length
    difference after it, and parked at the start of the changed range when it was inside —
    and restored once the write has committed. setSelectionRange does not steal focus, so
    clicking through several removals keeps whatever focus you had.
  • A reference alone on its line left a blank line behind when removed. The test only
    looked at the one character either side, and the host appends a separating space after
    a chip — so @a.ts ␠ (common, because the reference had been restored) was read as an
    inline reference, only the reference itself was deleted, and that space stayed behind as
    the blank line the user sees. It now looks at the whole line: if nothing but the
    reference and whitespace shares it, the line goes together with a newline (for the last
    line of the draft, the newline before it).
  • The remove button on a non-image file was invisible. The reference rail is a scroll
    container (overflow-y:auto) and the entry's "×" is absolutely positioned, overflowing
    5px up and to the right; a 32px image card has slack inside its row, but a 22px text chip
    rests flush against the content box, so the button was clipped away — it was in the DOM,
    focusable, and clickable, just not visible
    , which reads as "this entry has no remove
    control". The rail's padding now leaves room for that overflow.

Compatibility

The bundle patch and the dsh manifest are untouched, so existing profiles keep working and a
disable row written against row id fullscreen-input still applies. Settings stored by
earlier versions read back with identical behaviour.

npm shasum (SHA1)  61cb26b6b4ab954650ad00610540f5ea148f1cf4
npm integrity      sha512-ellxdnICAITaq[...]gOSIpNKqz4J6g==
install            dsh plugin --profile web add dsh-fullscreen-input

文件引用可以一键移除了,并修掉了一个「引用悄悄回不来」的问题。

新增

  • 文件引用也能一键移除。 引用条目(@路径)现在和附件一样有「×」。要理解它的行为,得先知道引用不是附件:非图片文件在宿主那里是草稿文档里的 @路径 文本,外加一条 occurrences 记录,attachmentIds 里根本没有它——所以附件的移除接口对它无效,唯一能删掉它的方式就是改草稿文本,按钮做的正是这件事。两种形态都得处理对,否则会毁内容:独占一行的引用连同换行一起删(不留空行),句子中间的引用只删自己,并把让出来的两个空格收成一个(看看 @a.ts 这个文件 → 看看 这个文件)。删掉一个引用之后,其余的引用仍然是引用——chip 会照常重建。
    • 一个刻意保留的行为:引用在这条栏上没有可删的文本时,不会长出按钮。 草稿已经变过、那段文字找不到了,就没有什么可删;一个点了没反应的控件,恰恰是这个功能要消灭的东西。这同时避免了图片草稿多出一个移除入口(图片走的是附件那条路)。

修复

  • 移除一个引用会让其余引用一起失去「引用」身份。 这是本版最严重的一处,也是它只在真机上暴露的原因:宿主给 insertReference 的 span 用的是 detect 坐标——一个 chip 在 detect 投影里只占 1 个字符(U+FFFC)——而计划里的偏移是 clipboard 坐标(一个 chip 是它完整的 @路径)。第一个 chip 恰好从偏移 0 开始,所以对得上;之后每一个都偏大了「已恢复路径长度 − 1」的累加值,宿主判定越界直接拒绝,恢复流程就此中止——于是只有第一个引用变回 chip,其余全部退化成纯文本。现在逐项累加这份漂移(宿主在引用后补分隔空格时反向抵消 1),每个 span 都换算到 detect 坐标再交给宿主。
    • 这个缺陷离线测试原本抓不到:测试替身把 span 当成 clipboard 坐标直接切片,还无条件返回成功。现在替身按真实语义建模——文档是一串「文本片段 / chip 片段」,chip 在 detect 里只占 1 个字符——于是旧代码在它上面会真的失败(applied=[true,false]),这条修复也就有了回归保护。
  • 点「×」会把光标扔到别处,下一次按键因此落在你没指过的地方。 程序化写入替换输入框的值之后,光标位置由浏览器随意决定:光标原本停在末尾,删除后却跑到了草稿中间,于是紧接着的一次退格删掉了两个毫不相干的引用。现在写入前按本次编辑把光标映射好——改动点之前的原地不动、之后的按长度差平移、落在改动区间内的停到区间起点——写入提交后再设回去。setSelectionRange 不抢焦点,连续删几个不会被夺走焦点。
  • 独占一行的引用删掉后会留下一个「空行」。 判据原本只看引用前后的那一个字符,而宿主会主动在 chip 后面补一个分隔空格——于是 @a.ts ␠ 这种(很常见,因为引用被恢复过)被当成了行内引用,只删掉引用本身,那个空格留在行里就成了用户看到的空行。现在改成看整行:只要这一行除了引用与空白没有别的内容,就连同一个换行一起整行删掉(末行则删它前面那个换行,避免留下一行空白)。
  • 非图片文件的移除按钮看不见。 引用条是滚动容器(overflow-y:auto),而条目上的「×」绝对定位、向左上各溢出 5px;32px 的图片卡在行内本来就有余量,22px 的文字 chip 却紧贴内容盒顶边,按钮于是被裁掉——它在 DOM 里、可聚焦、也能点击,就是看不见,看起来像「这个条目没有移除入口」。现在引用条的内边距留出了足够容纳这点溢出的空间。

兼容性

组合包补丁与 dsh manifest 均未改动,所以现有 profile 照常工作,针对 row id fullscreen-input 写的禁用行仍然有效。更早版本存下的设置读回来行为完全一致。