File size: 4,339 Bytes
494c9e4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | import {
DEFAULT_EXCLUDE_GENERATED_PATTERNS_TEXT,
DEFAULT_EXCLUDE_PROMPT_PATTERNS_TEXT,
EXCLUDE_GENERATED_PATTERNS_ENABLED_STORAGE_KEY,
EXCLUDE_GENERATED_PATTERNS_STORAGE_KEY,
EXCLUDE_PROMPT_PATTERNS_ENABLED_STORAGE_KEY,
EXCLUDE_PROMPT_PATTERNS_STORAGE_KEY,
} from './attributionExcludePromptPatternsStorage';
type BindExcludePatternsUiStorageKeys = {
textKey: string;
enabledKey: string;
};
type BindExcludePatternsUiOptions = {
storageKeys: BindExcludePatternsUiStorageKeys;
textInput: HTMLInputElement | HTMLTextAreaElement | null;
enableCheckbox: HTMLInputElement | null;
/** 列表在失焦提交后、或使能变化后触发(如 inspector.reapply) */
onEffectiveChange: () => void;
/** 键从未写入(`null`)时填充,与持久化 `''`(用户清空)区分 */
defaultTextWhenKeyAbsent?: string;
};
export type BindExcludePromptPatternsUiOptions = Omit<BindExcludePatternsUiOptions, 'storageKeys' | 'defaultTextWhenKeyAbsent'>;
/**
* 从 localStorage 回填、同步文本框禁用态、绑定持久化与回调(多组 key 共用实现)。
*/
function bindExcludePatternsUi(options: BindExcludePatternsUiOptions): void {
const { storageKeys, textInput, enableCheckbox, onEffectiveChange, defaultTextWhenKeyAbsent } = options;
const { textKey, enabledKey } = storageKeys;
try {
const savedExclude = localStorage.getItem(textKey);
if (textInput) {
if (savedExclude !== null) {
textInput.value = savedExclude;
} else if (defaultTextWhenKeyAbsent !== undefined) {
textInput.value = defaultTextWhenKeyAbsent;
}
}
const savedEnabled = localStorage.getItem(enabledKey);
if (enableCheckbox) {
enableCheckbox.checked = savedEnabled === null ? true : savedEnabled === '1';
}
} catch {
// 读取失败则保持 HTML 默认
}
function syncTextInputDisabled(): void {
if (!textInput) return;
textInput.disabled = !enableCheckbox?.checked;
}
syncTextInputDisabled();
enableCheckbox?.addEventListener('change', () => {
try {
if (textInput) {
localStorage.setItem(textKey, textInput.value);
}
localStorage.setItem(enabledKey, enableCheckbox.checked ? '1' : '0');
} catch {
/* ignore */
}
syncTextInputDisabled();
onEffectiveChange();
});
textInput?.addEventListener('blur', () => {
try {
localStorage.setItem(textKey, textInput.value);
} catch {
/* ignore */
}
onEffectiveChange();
});
window.addEventListener('storage', (event: StorageEvent) => {
if (event.storageArea !== localStorage) return;
const k = event.key;
if (k !== textKey && k !== enabledKey) {
return;
}
if (k === textKey && textInput) textInput.value = event.newValue ?? '';
if (k === enabledKey && enableCheckbox) {
enableCheckbox.checked = event.newValue === null ? true : event.newValue === '1';
}
syncTextInputDisabled();
onEffectiveChange();
});
}
/**
* Exclude prompt patterns:Attribution 与 Generate & Attribute 页共用,storage 见 {@link attributionExcludePromptPatternsStorage}。
*/
export function bindExcludePromptPatternsUi(options: BindExcludePromptPatternsUiOptions): void {
bindExcludePatternsUi({
storageKeys: {
textKey: EXCLUDE_PROMPT_PATTERNS_STORAGE_KEY,
enabledKey: EXCLUDE_PROMPT_PATTERNS_ENABLED_STORAGE_KEY,
},
...options,
defaultTextWhenKeyAbsent: DEFAULT_EXCLUDE_PROMPT_PATTERNS_TEXT,
});
}
/** Exclude generated patterns:仅 Generate & Attribute 页绑定;storage 键见 {@link attributionExcludePromptPatternsStorage}。 */
export function bindExcludeGeneratedPatternsUi(options: BindExcludePromptPatternsUiOptions): void {
bindExcludePatternsUi({
storageKeys: {
textKey: EXCLUDE_GENERATED_PATTERNS_STORAGE_KEY,
enabledKey: EXCLUDE_GENERATED_PATTERNS_ENABLED_STORAGE_KEY,
},
...options,
defaultTextWhenKeyAbsent: DEFAULT_EXCLUDE_GENERATED_PATTERNS_TEXT,
});
}
|