fix(brand): force visible platform-brand footer on published pages
Inject serve-time CSS so author styles cannot hide TKMind · 智趣 with low opacity, which made pages like weather.html look brandless. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,6 +1,20 @@
|
||||
export const MINDSPACE_PAGE_TAG_ATTR = 'data-mindspace-page-tag';
|
||||
export const MINDSPACE_PAGE_TAG_PLATFORM_BRAND = 'platform-brand';
|
||||
export const PLATFORM_BRAND_TEXT = 'TKMind · 智趣';
|
||||
export const PLATFORM_BRAND_STYLE_ID = 'mindspace-platform-brand-style';
|
||||
|
||||
const PLATFORM_BRAND_VISIBILITY_STYLE = `<style id="${PLATFORM_BRAND_STYLE_ID}">
|
||||
[data-mindspace-page-tag="${MINDSPACE_PAGE_TAG_PLATFORM_BRAND}"] {
|
||||
display: block !important;
|
||||
opacity: 1 !important;
|
||||
visibility: visible !important;
|
||||
color: #9aa3a0 !important;
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
letter-spacing: 0.08em !important;
|
||||
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
</style>`;
|
||||
|
||||
const PLATFORM_BRAND_INNER_RE = /(?:TKMind\s*·\s*智趣|contact@tkmind\.(?:ai|cn)|📧[^<]*tkmind)/i;
|
||||
const SIMPLE_BRAND_ELEMENT_RE =
|
||||
@@ -49,6 +63,20 @@ export function ensurePlatformBrandFooter(html) {
|
||||
return `${normalized}\n${footer}`;
|
||||
}
|
||||
|
||||
/** Override author CSS that hides the platform brand line (e.g. opacity 0.25). */
|
||||
export function injectPlatformBrandVisibilityStyle(html) {
|
||||
const source = String(html ?? '');
|
||||
if (!hasPlatformBrandMarker(source) || source.includes(PLATFORM_BRAND_STYLE_ID)) return source;
|
||||
if (/<\/head>/i.test(source)) {
|
||||
return source.replace(/<\/head>/i, `${PLATFORM_BRAND_VISIBILITY_STYLE}\n</head>`);
|
||||
}
|
||||
return `${PLATFORM_BRAND_VISIBILITY_STYLE}${source}`;
|
||||
}
|
||||
|
||||
export function preparePublishedPlatformBrand(html) {
|
||||
return injectPlatformBrandVisibilityStyle(ensurePlatformBrandFooter(html));
|
||||
}
|
||||
|
||||
export function prepareHtmlPageBrandMarkers(html) {
|
||||
return ensurePlatformBrandPageTags(html);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ import {
|
||||
MINDSPACE_PAGE_TAG_PLATFORM_BRAND,
|
||||
ensurePlatformBrandFooter,
|
||||
ensurePlatformBrandPageTags,
|
||||
injectPlatformBrandVisibilityStyle,
|
||||
normalizePlatformBrandHtml,
|
||||
PLATFORM_BRAND_STYLE_ID,
|
||||
prepareHtmlPageBrandMarkers,
|
||||
} from './mindspace-page-tag.mjs';
|
||||
|
||||
@@ -30,6 +32,15 @@ test('prepareHtmlPageBrandMarkers keeps existing marker', () => {
|
||||
assert.equal(result.match(new RegExp(MINDSPACE_PAGE_TAG_ATTR, 'g'))?.length, 1);
|
||||
});
|
||||
|
||||
test('injectPlatformBrandVisibilityStyle adds readable brand css', () => {
|
||||
const html =
|
||||
'<html><head><style>.footer p{color:rgba(255,255,255,0.25)}</style></head><body>' +
|
||||
`<p data-mindspace-page-tag="platform-brand">TKMind · 智趣</p></body></html>`;
|
||||
const result = injectPlatformBrandVisibilityStyle(html);
|
||||
assert.match(result, new RegExp(`id="${PLATFORM_BRAND_STYLE_ID}"`));
|
||||
assert.match(result, /opacity:\s*1 !important/);
|
||||
});
|
||||
|
||||
test('ensurePlatformBrandFooter appends brand line when marker is missing', () => {
|
||||
const html = '<html><body><main>content</main></body></html>';
|
||||
const result = ensurePlatformBrandFooter(html);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import crypto from 'node:crypto';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { ensurePlatformBrandFooter } from './mindspace-page-tag.mjs';
|
||||
import { preparePublishedPlatformBrand } from './mindspace-page-tag.mjs';
|
||||
|
||||
const INLINE_SCRIPT_PATTERN = /<script\b(?![^>]*\bsrc\b)[^>]*>([\s\S]*?)<\/script>/gi;
|
||||
|
||||
@@ -68,7 +68,7 @@ export function decorateMindSpacePublishedHtml({
|
||||
}
|
||||
|
||||
try {
|
||||
nextHtml = ensurePlatformBrandFooter(nextHtml);
|
||||
nextHtml = preparePublishedPlatformBrand(nextHtml);
|
||||
nextHtml = injectOgTags(nextHtml, {
|
||||
origin: context.origin,
|
||||
pageUrl: context.pageUrl,
|
||||
|
||||
@@ -102,7 +102,7 @@ description: 在专属 MindSpace 目录生成可公开访问的静态 HTML 报
|
||||
<p data-mindspace-page-tag="platform-brand">TKMind · 智趣</p>
|
||||
```
|
||||
|
||||
带 `data-mindspace-page-tag` 的区域为平台固定信息:用户在编辑模式中不可见、不可改;预览与发布后正常显示。
|
||||
带 `data-mindspace-page-tag` 的区域为平台固定信息:用户在编辑模式中不可见、不可改;预览与发布后正常显示。**禁止**把该行 CSS 透明度设过低(如 `opacity: 0.25`),否则页内看不见品牌。
|
||||
|
||||
## 按需附带文件下载(Word / PDF)
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ export function buildPageGenerateAgentPrompt(intent, { wantsDocx = false } = {})
|
||||
' - `<meta name="description" content="一句话摘要">`',
|
||||
' - `<meta name="mindspace-cover" content=\'{"tag":"主题","accent":"#主色","accent2":"#辅色","subtitle":"卖点","cover":"assets/hero.jpg"}\'>`',
|
||||
' tag/accent/subtitle 必须与页面主题一致;有 hero 图时 cover 指向同目录 raster 图(jpg/png)。',
|
||||
'6. 页脚加 `<p data-mindspace-page-tag="platform-brand">TKMind · 智趣</p>`(必须,禁止省略或用邮箱/tkmind.ai 代替)。',
|
||||
'6. 页脚加 `<p data-mindspace-page-tag="platform-brand">TKMind · 智趣</p>`(必须;禁止省略、不要用邮箱/tkmind.ai,也不要把该行 opacity 设太低导致看不见)。',
|
||||
'7. 回复里只给一个正式域名链接;没有落盘或缺少上述元数据就不要发链接。',
|
||||
'',
|
||||
buildCurrentTimeAgentPrefix({ timezone: scheduleTimezone }),
|
||||
|
||||
Reference in New Issue
Block a user