Skip to content

Commit abdc7f5

Browse files
committed
fix(decaporg#7401, decaporg#7415): resolve visual editing issues
1 parent 4f88b2d commit abdc7f5

File tree

3 files changed

+21
-8
lines changed

3 files changed

+21
-8
lines changed

jest.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module.exports = {
1010
'\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
1111
'^#home-directory$': 'clean-stack/home-directory.js',
1212
},
13+
modulePathIgnorePatterns: ['.nx', 'dist'],
1314
snapshotSerializers: ['@emotion/jest/serializer'],
1415
transformIgnorePatterns: [
1516
'node_modules/(?!copy-text-to-clipboard|clean-stack|escape-string-regexp)',

packages/decap-cms-core/src/lib/stega.ts

+19-8
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,20 @@ function getNestedFields(f?: CmsField): CmsField[] {
3838
* For markdown fields, encode each paragraph separately
3939
*/
4040
function encodeString(value: string, { fields, path }: EncodeContext): string {
41-
const stega = vercelStegaEncode({ decap: path });
42-
const isMarkdown = fields[0]?.widget === 'markdown';
43-
44-
if (isMarkdown && value.includes('\n\n')) {
41+
const [field] = fields;
42+
if (!field) return value;
43+
const { widget } = field;
44+
if (widget === 'string' || widget === 'text') {
45+
if ('visualEditing' in field && field.visualEditing === false) return value;
46+
const stega = vercelStegaEncode({ decap: path });
47+
return value + stega;
48+
}
49+
if (widget === 'markdown') {
50+
const stega = vercelStegaEncode({ decap: path });
4551
const blocks = value.split(/(\n\n+)/);
4652
return blocks.map(block => (block.trim() ? block + stega : block)).join('');
4753
}
48-
return value + stega;
54+
return value;
4955
}
5056

5157
/**
@@ -102,16 +108,21 @@ function encodeMap(
102108
return newMap;
103109
}
104110

111+
/**
112+
* Cache for encoded values to prevent re-encoding unchanged values
113+
* across keystrokes. The cache is keyed by path.
114+
*/
115+
const encodingCache = new Map();
116+
105117
/**
106118
* Main entry point for encoding steganographic data into entry values
107119
* Uses a visitor pattern with caching to handle recursive structures
108120
*/
109121
export function encodeEntry(value: unknown, fields: List<ImmutableMap<string, unknown>>) {
110122
const plainFields = fields.toJS() as CmsField[];
111-
const cache = new Map();
112123

113124
function visit(value: unknown, fields: CmsField[], path = '') {
114-
const cached = cache.get(path);
125+
const cached = encodingCache.get(path);
115126
if (cached === value) return value;
116127

117128
const ctx: EncodeContext = { fields, path, visit };
@@ -126,7 +137,7 @@ export function encodeEntry(value: unknown, fields: List<ImmutableMap<string, un
126137
result = value;
127138
}
128139

129-
cache.set(path, result);
140+
encodingCache.set(path, result);
130141
return result;
131142
}
132143

packages/decap-cms-core/src/types/redux.ts

+1
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ export interface CmsFieldStringOrText {
248248
// This is the default widget, so declaring its type is optional.
249249
widget?: 'string' | 'text';
250250
default?: string;
251+
visualEditing?: boolean;
251252
}
252253

253254
export interface CmsFieldMeta {

0 commit comments

Comments
 (0)