rimecms 0.25.5 → 0.25.7
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.
|
@@ -130,8 +130,8 @@ export type PanelConfig = {
|
|
|
130
130
|
};
|
|
131
131
|
/** a relative path from the "static" directory or an external url
|
|
132
132
|
* @example
|
|
133
|
-
* // for static/
|
|
134
|
-
* css : '/
|
|
133
|
+
* // for static/assets/custom.css
|
|
134
|
+
* css : '/assets/custom.css'
|
|
135
135
|
*/
|
|
136
136
|
css?: string;
|
|
137
137
|
};
|
|
@@ -152,8 +152,8 @@ export const init = async ({ force, name: incomingName, skipInstall }) => {
|
|
|
152
152
|
async function copyAssets() {
|
|
153
153
|
try {
|
|
154
154
|
const currentDir = path.dirname(fileURLToPath(import.meta.url));
|
|
155
|
-
await mkdir(path.resolve(process.cwd(), 'static/panel/fonts'), { recursive: true });
|
|
156
|
-
await cp(path.join(currentDir, '../../../../panel/fonts'), path.resolve(process.cwd(), 'static/panel/fonts'), {
|
|
155
|
+
await mkdir(path.resolve(process.cwd(), 'static/assets/panel/fonts'), { recursive: true });
|
|
156
|
+
await cp(path.join(currentDir, '../../../../panel/fonts'), path.resolve(process.cwd(), 'static/assets/panel/fonts'), {
|
|
157
157
|
recursive: true
|
|
158
158
|
});
|
|
159
159
|
logger.info('[✓] Copied assets');
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
@font-face {
|
|
2
2
|
font-family: 'Lora';
|
|
3
|
-
src: url('/panel/fonts/Lora-Italic-VariableFont_wght.ttf') format('truetype');
|
|
3
|
+
src: url('/assets/panel/fonts/Lora-Italic-VariableFont_wght.ttf') format('truetype');
|
|
4
4
|
font-weight: 100 1000;
|
|
5
5
|
font-style: Italic;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
@font-face {
|
|
9
9
|
font-family: 'Lora';
|
|
10
|
-
src: url('/panel/fonts/Lora-VariableFont_wght.ttf') format('truetype');
|
|
10
|
+
src: url('/assets/panel/fonts/Lora-VariableFont_wght.ttf') format('truetype');
|
|
11
11
|
font-weight: 100 1000;
|
|
12
12
|
font-style: normal;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
@font-face {
|
|
16
16
|
font-family: 'Chivo';
|
|
17
|
-
src: url('/panel/fonts/ChivoMono-Italic-VariableFont_wght.ttf') format('truetype');
|
|
17
|
+
src: url('/assets/panel/fonts/ChivoMono-Italic-VariableFont_wght.ttf') format('truetype');
|
|
18
18
|
font-weight: 100 1000;
|
|
19
19
|
font-style: Italic;
|
|
20
20
|
}
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
--rz-font-scale: 0.8;
|
|
24
24
|
|
|
25
25
|
--rz-font-sans:
|
|
26
|
-
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif,
|
|
27
|
-
'Segoe UI Emoji', 'Segoe UI Symbol';
|
|
26
|
+
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif,
|
|
27
|
+
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
|
|
28
28
|
--rz-font-mono: 'SFMono-Regular', Consolas, Liberation Mono, Menlo, Courier, monospace;
|
|
29
29
|
--rz-font-serif: 'Lora';
|
|
30
30
|
|
package/dist/util/string.js
CHANGED
|
@@ -174,6 +174,7 @@ export const sanitize = (value) => {
|
|
|
174
174
|
return value || '';
|
|
175
175
|
if (!parser)
|
|
176
176
|
parser = Parser();
|
|
177
|
+
const WHITESPACE_MARKER = '\uE000';
|
|
177
178
|
const decode = (value) => value
|
|
178
179
|
.replace(/&/g, '&')
|
|
179
180
|
.replace(/"/g, '"')
|
|
@@ -182,12 +183,20 @@ export const sanitize = (value) => {
|
|
|
182
183
|
.replace(/'/g, "'")
|
|
183
184
|
.replace(/'/g, "'")
|
|
184
185
|
.replace(/&/g, '&');
|
|
186
|
+
const encodeTextSpace = (html) => html
|
|
187
|
+
.split(/(<[^>]*>)/g)
|
|
188
|
+
.map((segment) => segment.startsWith('<') && segment.endsWith('>')
|
|
189
|
+
? segment
|
|
190
|
+
: segment.replace(/ /g, WHITESPACE_MARKER))
|
|
191
|
+
.join('');
|
|
192
|
+
const restoreWhitespace = (str) => str.replace(new RegExp(WHITESPACE_MARKER, 'g'), ' ');
|
|
185
193
|
// Decode multiple levels of encoding on input
|
|
186
194
|
let decodedValue = value;
|
|
187
195
|
while (decodedValue.match(/&|"|<|>|'|'|&/)) {
|
|
188
196
|
decodedValue = decode(decodedValue);
|
|
189
197
|
}
|
|
190
|
-
const
|
|
198
|
+
const protectedInput = encodeTextSpace(decodedValue);
|
|
199
|
+
const { root } = parser.parseFromString(protectedInput);
|
|
191
200
|
const allowedTags = new Set(['strong', 'b', 'em', 'i', 'u', 'br', 'a']);
|
|
192
201
|
const dangerousTags = new Set(['script', 'style', 'iframe', 'object', 'embed', 'svg']);
|
|
193
202
|
const eventHandlers = /^on[a-z]+$/i;
|
|
@@ -197,7 +206,7 @@ export const sanitize = (value) => {
|
|
|
197
206
|
return '';
|
|
198
207
|
// Handle text nodes
|
|
199
208
|
if (node.nodeName === '#text') {
|
|
200
|
-
return node.nodeValue || '';
|
|
209
|
+
return (node.nodeValue || '').replace(new RegExp(WHITESPACE_MARKER, 'g'), ' ');
|
|
201
210
|
}
|
|
202
211
|
// Handle comment nodes - remove them
|
|
203
212
|
if (node.nodeName === '#comment') {
|
|
@@ -260,5 +269,5 @@ export const sanitize = (value) => {
|
|
|
260
269
|
return '';
|
|
261
270
|
};
|
|
262
271
|
const sanitized = root.children ? root.children.map(processNode).join('') : '';
|
|
263
|
-
return decode(sanitized);
|
|
272
|
+
return decode(restoreWhitespace(sanitized));
|
|
264
273
|
};
|