article-content-renderer-vue2 0.5.1 → 0.5.2

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 CHANGED
@@ -403,6 +403,52 @@ function handleArticleButtonClick(payload: ArticleButtonClickPayload): void {
403
403
  }
404
404
  ```
405
405
 
406
+ ## resourceQuestion:描述与底部文本
407
+
408
+ 资源问题统一使用 `<div class="acp-resource-question" role="group">` 容器,按“图片(可选)→ 标题 → 描述 → 选项 → 底部文本(可选)”的顺序渲染。描述读取文章 JSON 中的 `resourceQuestion.attrs.description`,有内容时显示在标题下方;保留换行并按纯文本展示。
409
+
410
+ 通过组件 Prop `resourceQuestionFooterText` 传入问题底部的文本:
411
+
412
+ ```vue
413
+ <ArticleContentRenderer
414
+ :document="article"
415
+ resource-question-footer-text="请选择一个选项,继续阅读后续内容。"
416
+ />
417
+ ```
418
+
419
+ 也可以绑定响应式变量:
420
+
421
+ ```vue
422
+ <ArticleContentRenderer
423
+ :document="article"
424
+ :resource-question-footer-text="questionFooterText"
425
+ />
426
+ ```
427
+
428
+ `questionFooterText` 由使用方在 `data` 中声明并更新。该 Prop 默认为空字符串,对当前组件内所有可见的问题生效,在选项下方显示;不传、空字符串或纯空白时不创建底部文本节点。文本保留换行,HTML 标签会作为文字显示。它只影响展示,不写入文章 JSON,也不改变点击、解锁或滚动逻辑。
429
+
430
+ 两个 Demo 的解锁面板均提供“问题底部文本”输入框,可直接编辑并查看效果。样式可通过 `.acp-resource-question__description` 和 `.acp-resource-question__footer` 覆盖。
431
+
432
+ ## resourceQuestion.image:问题图片
433
+
434
+ 资源问题支持可选的 `attrs.image`,例如在问题的 `attrs` 中加入:
435
+
436
+ ```json
437
+ "image": {
438
+ "src": "https://example.com/question.png",
439
+ "alt": "问题配图",
440
+ "title": "图片说明",
441
+ "width": 800,
442
+ "height": 400
443
+ }
444
+ ```
445
+
446
+ `src` 必填;`alt`、`title` 和尺寸均可省略,尺寸必须是 1–10000 的整数。图片显示在问题标题上方,宽度适应容器,高度按比例缩放,不裁剪;尺寸属性用于保留原始比例。没有图片时省略整个 `image` 属性,旧版无图片文章仍然兼容。
447
+
448
+ 问题图片支持 HTTP(S)、相对路径和 PNG/JPEG/WebP/GIF/AVIF/BMP 的 Base64 data URL,沿用 `imageBaseUrl` 的默认前缀替换规则。渲染器直接展示 JSON 中的图片快照,浏览器会正常加载图片地址,不会因此请求问题接口或新的文章 JSON。Demo 的“载入解锁示例”包含问题图片。
449
+
450
+ 如果出现 `/content/.../attrs/image:Property "image" is not allowed.`,说明所使用的渲染器或协议仍未支持该字段,需同步更新协议文件、校验器和渲染器。
451
+
406
452
  ## revealedKeys:解锁隐藏内容
407
453
 
408
454
  `revealedKeys` 是由使用方维护的 `string[]`,默认值为 `[]`,通过 `:revealed-keys="revealedKeys"` 传给组件。数组中的字符串与问题节点的 `attrs.revealKey` 精确匹配,表示页面允许显示该问题之后的内容。
@@ -621,6 +667,7 @@ type OnAnchorNavigate = (
621
667
  | `protocolVersion` | `number` | `1` | 协议适配器版本 |
622
668
  | `strict` | `boolean` | `false` | 校验失败时是否停止整篇正文渲染 |
623
669
  | `revealedKeys` | `string[]` | `[]` | 宿主允许的解锁标识;选项点击不自动修改 |
670
+ | `resourceQuestionFooterText` | `string` | `""` | 在每个可见资源问题的选项下方展示的纯文本,支持动态更新;空白时不显示 |
624
671
  | `articleKey` | `string \| number` | `undefined` | 文章版本或加载代次,变化时取消旧定位;宿主仍须重置解锁状态 |
625
672
  | `scrollContainer` | `HTMLElement \| (() => HTMLElement \| null)` | `undefined` | 目标滚动容器,省略时滚动页面 |
626
673
  | `scrollOffset` | `number` | `0` | 定位时顶部遮挡偏移,单位 px |
@@ -735,7 +782,7 @@ interface RenderIssue {
735
782
  - 同一张表格的每一行必须具有相同列数。
736
783
  - 未知节点、mark、属性和越界值会被报告。
737
784
 
738
- 普通链接和 articleButton 允许 `http:`、`https:`、`mailto:`、`tel:`、相对路径和页面锚点。图片允许 `http:`、`https:`、`blob:` 和相对路径。危险协议会被拦截。
785
+ 普通链接和 articleButton 允许 `http:`、`https:`、`mailto:`、`tel:`、相对路径和页面锚点。正文 image 节点允许 `http:`、`https:`、`blob:` 和相对路径。资源问题的 `attrs.image` 按其独立协议允许 HTTP(S)、相对路径及指定光栅格式的 Base64 data URL,不接受 `blob:` 或 SVG data URL。危险协议会被拦截。
739
786
 
740
787
  ## Vue 2 顶层渲染结构
741
788
 
@@ -1 +1 @@
1
- :root{--acp-color-text: inherit;--acp-color-muted: #667085;--acp-color-border: #d0d5dd;--acp-color-surface: #f8fafc;--acp-color-accent: #2563eb;--acp-color-accent-hover: #1d4ed8;--acp-color-on-accent: #ffffff;--acp-radius: .375rem;--acp-spacing-block: 1rem;--acp-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace}.acp-paragraph,.acp-heading,.acp-blockquote,.acp-list,.acp-code-block,.acp-horizontal-rule,.acp-image,.acp-article-button,.acp-table-wrapper{box-sizing:border-box}.acp-paragraph,.acp-heading,.acp-blockquote,.acp-list,.acp-code-block,.acp-horizontal-rule,.acp-image,.acp-table-wrapper{margin-block:0 var(--acp-spacing-block)}.acp-paragraph:first-child,.acp-heading:first-child,.acp-blockquote:first-child,.acp-list:first-child,.acp-code-block:first-child,.acp-horizontal-rule:first-child,.acp-image:first-child,.acp-table-wrapper:first-child{margin-block-start:0}.acp-paragraph{color:var(--acp-color-text)}.acp-blockquote{margin-inline:0;padding-inline-start:1rem;border-inline-start:.25rem solid var(--acp-color-border);color:var(--acp-color-muted)}.acp-list{padding-inline-start:1.5rem}.acp-list-item>:last-child{margin-block-end:0}.acp-code-block{overflow-x:auto;padding:1rem;border-radius:var(--acp-radius);background:var(--acp-color-surface);font-family:var(--acp-font-mono);white-space:pre}.acp-mark--code{padding:.1em .25em;border-radius:calc(var(--acp-radius) / 2);background:var(--acp-color-surface);font-family:var(--acp-font-mono)}.acp-horizontal-rule{border:0;border-block-start:1px solid var(--acp-color-border)}.acp-image{display:flex;width:100%}.acp-image--left{justify-content:flex-start}.acp-image--center{justify-content:center}.acp-image--right{justify-content:flex-end}.acp-image__element{display:block;max-width:100%;height:auto}.acp-image-row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--acp-image-gap, 1rem);align-items:start}.acp-image-row>.acp-image{min-width:0}.acp-resource-question{min-inline-size:0;margin:0 0 var(--acp-spacing-block);padding:1rem;border:1px solid var(--acp-color-border);border-radius:var(--acp-radius);color:var(--acp-color-text)}.acp-resource-question__title{padding-inline:.25rem;font-size:1.125em;font-weight:600;white-space:pre-wrap;overflow-wrap:anywhere}.acp-resource-question__description,.acp-resource-question__placeholder{margin:0 0 .75rem;color:var(--acp-color-muted);white-space:pre-wrap;overflow-wrap:anywhere}.acp-resource-question__options{display:grid;gap:.5rem}.acp-resource-question__option{padding:.75rem 1rem;border:1px solid var(--acp-color-border);border-radius:var(--acp-radius);background:var(--acp-color-surface);color:inherit;font:inherit;text-align:start;white-space:pre-wrap;overflow-wrap:anywhere;cursor:pointer}.acp-resource-question__option:hover{border-color:var(--acp-color-accent)}.acp-resource-question__option:focus-visible,.acp-paragraph[data-anchor-id]:focus,.acp-heading[data-anchor-id]:focus{outline:2px solid var(--acp-color-accent);outline-offset:3px}.acp-link,.acp-article-button--text,.acp-article-button--link{color:var(--acp-color-accent);text-decoration:underline;text-underline-offset:.15em}.acp-link:hover,.acp-article-button--text:hover,.acp-article-button--link:hover{color:var(--acp-color-accent-hover)}.acp-link--disabled{cursor:not-allowed;opacity:.55}.acp-article-button{display:inline-flex;align-items:center;justify-content:center;margin-block:0 var(--acp-spacing-block);cursor:pointer}.acp-article-button--button{min-height:2.5rem;padding:.5rem 1rem;border-radius:var(--acp-radius);background:var(--acp-color-accent);color:var(--acp-color-on-accent);text-decoration:none}.acp-article-button--button:hover{background:var(--acp-color-accent-hover)}.acp-article-button--disabled{cursor:not-allowed;opacity:.55}.acp-table-wrapper{width:100%;overflow-x:auto}.acp-table{width:100%;border-collapse:collapse}.acp-table-cell{padding:.625rem .75rem;border:1px solid var(--acp-color-border);vertical-align:top}.acp-table-cell>:last-child{margin-block-end:0}.acp-render-error{padding:.75rem 1rem;border:1px solid #fda29b;border-radius:var(--acp-radius);background:#fffbfa;color:#b42318}
1
+ :root{--acp-color-text: inherit;--acp-color-muted: #667085;--acp-color-border: #d0d5dd;--acp-color-surface: #f8fafc;--acp-color-accent: #2563eb;--acp-color-accent-hover: #1d4ed8;--acp-color-on-accent: #ffffff;--acp-radius: .375rem;--acp-spacing-block: 1rem;--acp-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace}.acp-paragraph,.acp-heading,.acp-blockquote,.acp-list,.acp-code-block,.acp-horizontal-rule,.acp-image,.acp-article-button,.acp-table-wrapper{box-sizing:border-box}.acp-paragraph,.acp-heading,.acp-blockquote,.acp-list,.acp-code-block,.acp-horizontal-rule,.acp-image,.acp-table-wrapper{margin-block:0 var(--acp-spacing-block)}.acp-paragraph:first-child,.acp-heading:first-child,.acp-blockquote:first-child,.acp-list:first-child,.acp-code-block:first-child,.acp-horizontal-rule:first-child,.acp-image:first-child,.acp-table-wrapper:first-child{margin-block-start:0}.acp-paragraph{color:var(--acp-color-text)}.acp-blockquote{margin-inline:0;padding-inline-start:1rem;border-inline-start:.25rem solid var(--acp-color-border);color:var(--acp-color-muted)}.acp-list{padding-inline-start:1.5rem}.acp-list-item>:last-child{margin-block-end:0}.acp-code-block{overflow-x:auto;padding:1rem;border-radius:var(--acp-radius);background:var(--acp-color-surface);font-family:var(--acp-font-mono);white-space:pre}.acp-mark--code{padding:.1em .25em;border-radius:calc(var(--acp-radius) / 2);background:var(--acp-color-surface);font-family:var(--acp-font-mono)}.acp-horizontal-rule{border:0;border-block-start:1px solid var(--acp-color-border)}.acp-image{display:flex;width:100%}.acp-image--left{justify-content:flex-start}.acp-image--center{justify-content:center}.acp-image--right{justify-content:flex-end}.acp-image__element{display:block;max-width:100%;height:auto}.acp-image-row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--acp-image-gap, 1rem);align-items:start}.acp-image-row>.acp-image{min-width:0}.acp-resource-question{min-inline-size:0;margin:0 0 var(--acp-spacing-block);padding:1rem;border:1px solid var(--acp-color-border);border-radius:var(--acp-radius);color:var(--acp-color-text)}.acp-resource-question__image{display:block;width:100%;max-width:100%;height:auto;margin-block-end:.75rem}.acp-resource-question__title{margin-block-end:.75rem;font-size:1.125em;font-weight:600;white-space:pre-wrap;overflow-wrap:anywhere}.acp-resource-question__description,.acp-resource-question__placeholder{margin:0 0 .75rem;color:var(--acp-color-muted);white-space:pre-wrap;overflow-wrap:anywhere}.acp-resource-question__options{display:grid;gap:.5rem}.acp-resource-question__footer{margin:.75rem 0 0;color:var(--acp-color-muted);font-size:.875em;white-space:pre-wrap;overflow-wrap:anywhere}.acp-resource-question__option{padding:.75rem 1rem;border:1px solid var(--acp-color-border);border-radius:var(--acp-radius);background:var(--acp-color-surface);color:inherit;font:inherit;text-align:start;white-space:pre-wrap;overflow-wrap:anywhere;cursor:pointer}.acp-resource-question__option:hover{border-color:var(--acp-color-accent)}.acp-resource-question__option:focus-visible,.acp-paragraph[data-anchor-id]:focus,.acp-heading[data-anchor-id]:focus{outline:2px solid var(--acp-color-accent);outline-offset:3px}.acp-link,.acp-article-button--text,.acp-article-button--link{color:var(--acp-color-accent);text-decoration:underline;text-underline-offset:.15em}.acp-link:hover,.acp-article-button--text:hover,.acp-article-button--link:hover{color:var(--acp-color-accent-hover)}.acp-link--disabled{cursor:not-allowed;opacity:.55}.acp-article-button{display:inline-flex;align-items:center;justify-content:center;margin-block:0 var(--acp-spacing-block);cursor:pointer}.acp-article-button--button{min-height:2.5rem;padding:.5rem 1rem;border-radius:var(--acp-radius);background:var(--acp-color-accent);color:var(--acp-color-on-accent);text-decoration:none}.acp-article-button--button:hover{background:var(--acp-color-accent-hover)}.acp-article-button--disabled{cursor:not-allowed;opacity:.55}.acp-table-wrapper{width:100%;overflow-x:auto}.acp-table{width:100%;border-collapse:collapse}.acp-table-cell{padding:.625rem .75rem;border:1px solid var(--acp-color-border);vertical-align:top}.acp-table-cell>:last-child{margin-block-end:0}.acp-render-error{padding:.75rem 1rem;border:1px solid #fda29b;border-radius:var(--acp-radius);background:#fffbfa;color:#b42318}